Skip to content

Commit 591e0e5

Browse files
committed
create calendar the user can share
1 parent 662ca62 commit 591e0e5

File tree

11 files changed

+360
-8
lines changed

11 files changed

+360
-8
lines changed

app/Domains/Outputs/OutputTypeEnum.php

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ enum OutputTypeEnum: string
1111

1212
case WebPage = 'web_page';
1313
case EmailOutput = 'email_output';
14+
case CalendarOutput = 'calendar_output';
1415
case ApiOutput = 'api_output';
1516
case EmailReplyOutput = 'email_reply_output';
1617
//leave for scripting

app/Http/Controllers/CalendarController.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22

33
namespace App\Http\Controllers;
44

5+
use App\Domains\Outputs\OutputTypeEnum;
56
use App\Http\Resources\CollectionResource;
67
use App\Http\Resources\EventResource;
78
use App\Models\Collection;
89
use App\Models\Event;
910
use Carbon\Carbon;
10-
use Illuminate\Http\Request;
1111

1212
class CalendarController extends Controller
1313
{
1414
public function show(Collection $collection)
1515
{
16+
//for now if there is no related output we do a 404
17+
if (! $collection->outputs()->where('type', OutputTypeEnum::CalendarOutput)->first()) {
18+
abort(404);
19+
}
20+
1621
// Parse the date from the query string, or use the current date if not provided
1722
$date = request()->input('date') ? Carbon::parse(request()->input('date')) : now();
1823

@@ -26,7 +31,7 @@ public function show(Collection $collection)
2631
->get();
2732

2833
return inertia('Calendar/Show', [
29-
"collection" => new CollectionResource($collection),
34+
'collection' => new CollectionResource($collection),
3035
'events' => EventResource::collection($events),
3136
'startDate' => $startOfCalendar->format('Y-m-d'),
3237
'endDate' => $endOfCalendar->format('Y-m-d'),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\Outputs;
4+
5+
use App\Domains\Outputs\OutputTypeEnum;
6+
use App\Http\Controllers\OutputController;
7+
8+
class CalendarOutputController extends OutputController
9+
{
10+
protected OutputTypeEnum $outputTypeEnum = OutputTypeEnum::CalendarOutput;
11+
12+
protected string $edit_path = 'Outputs/Calendar/Edit';
13+
14+
protected string $show_path = 'Outputs/Calendar/Show';
15+
16+
protected string $create_path = 'Outputs/Calendar/Create';
17+
18+
protected string $info = 'This will use the events in the collection to create a calendar page';
19+
20+
protected string $type = 'Calendar Page';
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script setup>
2+
3+
import {Link} from "@inertiajs/vue3";
4+
import Settings from "@/Pages/Outputs/Components/Settings.vue";
5+
6+
const props = defineProps({
7+
output: Object
8+
})
9+
</script>
10+
11+
<template>
12+
<div class="card rounded-none w-96 shadow-xl border border-neutral">
13+
<div class="card-body">
14+
<Settings :output="output"/>
15+
16+
<div class="card-actions justify-between flex items-center">
17+
<span class="badge badge-default">{{ output.type_formatted}}</span>
18+
<div class="flex justify-end gap-2 items-center">
19+
<Link class="link" :href="route('calendar.show', {
20+
collection: output.collection_id,
21+
})">visit</Link>
22+
<Link :href="route('collections.outputs.calendar_output.edit', {
23+
collection: output.collection_id,
24+
output: output.id
25+
})" class="btn btn-primary rounded-none">Edit</Link>
26+
</div>
27+
</div>
28+
</div>
29+
</div>
30+
</template>
31+
32+
<style scoped>
33+
34+
</style>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<template>
2+
<div class="flex flex-col space-y-8 mt-4">
3+
<div>
4+
<InputLabel value="Title"/>
5+
<input v-model="modelValue.title" type="text" placeholder="Title Here"
6+
class="rounded-none input input-bordered w-full " />
7+
<InputError :message="modelValue.errors.title" />
8+
</div>
9+
10+
<div>
11+
<InputLabel value="Summary"/>
12+
<textarea v-model="modelValue.summary" class="rounded-none textarea textarea-bordered w-full mb-5"
13+
placeholder="This will be shown on the page (optional)" rows="5"></textarea>
14+
<InputError :message="modelValue.errors.summary" />
15+
</div>
16+
<slot></slot>
17+
18+
<div class="form-control w-24">
19+
<label class="label cursor-pointer">
20+
<span class="label-text">Active</span>
21+
<input type="checkbox"
22+
v-model="modelValue.active"
23+
:checked="modelValue.active"
24+
class="checkbox" />
25+
</label>
26+
<InputError :message="modelValue.errors.active" />
27+
</div>
28+
29+
<div class="form-control w-24">
30+
<label class="label cursor-pointer">
31+
<span class="label-text">Public</span>
32+
<input type="checkbox"
33+
v-model="modelValue.public"
34+
:checked="modelValue.public" class="checkbox" />
35+
</label>
36+
<InputError :message="modelValue.errors.public" />
37+
</div>
38+
</div>
39+
</template>
40+
41+
<script setup>
42+
43+
import InputError from "@/Components/InputError.vue";
44+
import InputLabel from "@/Components/InputLabel.vue";
45+
import {ref} from "vue";
46+
47+
const emit = defineEmits(['update:modelValue'])
48+
49+
const props = defineProps({
50+
modelValue: Object
51+
})
52+
53+
54+
55+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<script setup>
2+
import AppLayout from '@/Layouts/AppLayout.vue';
3+
import PrimaryButton from '@/Components/PrimaryButton.vue';
4+
import SecondaryButton from '@/Components/SecondaryButton.vue';
5+
import {ref} from 'vue';
6+
import Intro from '@/Components/Intro.vue';
7+
import SecondaryLink from '@/Components/SecondaryLink.vue';
8+
import Resources from './Components/Resources.vue';
9+
import {useForm} from '@inertiajs/vue3';
10+
import Generate from "@/Pages/Outputs/WebPage/Components/Generate.vue";
11+
import Templates from "@/Components/Templates.vue";
12+
13+
const props = defineProps({
14+
collection: {
15+
type: Object,
16+
required: true,
17+
}
18+
});
19+
20+
const form = useForm({
21+
title: '',
22+
summary: '',
23+
active: false,
24+
public: false,
25+
});
26+
27+
28+
const submit = () => {
29+
form.post(
30+
route('collections.outputs.calendar_output.store', {
31+
collection: props.collection.data.id
32+
}), {
33+
preserveScroll: true,
34+
onSuccess: () => {
35+
form.reset();
36+
}
37+
});
38+
}
39+
</script>
40+
41+
<template>
42+
<AppLayout title="Create Web Page">
43+
44+
<div class="py-12">
45+
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
46+
<div class="overflow-hidden shadow-xl rounded-none p-5">
47+
<Intro></Intro>
48+
49+
<form @submit.prevent="submit" class="p-10 ">
50+
<div class="flex">
51+
<div class="w-3/4 border border-secondary rounded-none p-5">
52+
53+
<Resources
54+
:collection="collection.data"
55+
v-model="form">
56+
57+
</Resources>
58+
59+
<div class="flex justify-end items-center gap-4">
60+
<PrimaryButton type="submit">
61+
Save
62+
</PrimaryButton>
63+
<SecondaryLink :href="route('collections.outputs.index', {
64+
collection: collection.data.id
65+
66+
})">
67+
Cancel
68+
</SecondaryLink>
69+
</div>
70+
</div>
71+
</div>
72+
</form>
73+
</div>
74+
</div>
75+
</div>
76+
</AppLayout>
77+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<script setup>
2+
import AppLayout from '@/Layouts/AppLayout.vue';
3+
import PrimaryButton from '@/Components/PrimaryButton.vue';
4+
import SecondaryButton from '@/Components/SecondaryButton.vue';
5+
import { ref } from 'vue';
6+
import Intro from '@/Components/Intro.vue';
7+
import SecondaryLink from '@/Components/SecondaryLink.vue';
8+
import Resources from './Components/Resources.vue';
9+
import { useForm } from '@inertiajs/vue3';
10+
import {useToast} from "vue-toastification";
11+
import Generate from "@/Pages/Outputs/WebPage/Components/Generate.vue";
12+
import Delete from "@/Pages/Outputs/Components/Delete.vue";
13+
import Templates from "@/Components/Templates.vue";
14+
15+
const toast = useToast();
16+
17+
const props = defineProps({
18+
collection: {
19+
type: Object,
20+
required: true,
21+
},
22+
output: {
23+
type: Object
24+
},
25+
});
26+
27+
const form = useForm({
28+
title: props.output.title,
29+
summary: props.output.summary,
30+
active: props.output.active,
31+
public: props.output.public,
32+
});
33+
34+
35+
const submit = () => {
36+
form.put(
37+
route('collections.outputs.calendar_output.update', {
38+
collection: props.collection.data.id,
39+
output: props.output.id
40+
}), {
41+
preserveScroll: true,
42+
onSuccess: params => {
43+
toast.info("Updated");
44+
}
45+
});
46+
}
47+
</script>
48+
49+
<template>
50+
<AppLayout title="Edit Web Page">
51+
<div class="py-12">
52+
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
53+
<div class="overflow-hidden shadow-xl rounded-none p-5">
54+
<Intro></Intro>
55+
56+
<form @submit.prevent="submit" class="p-10 ">
57+
<div class="flex">
58+
<div class="w-3/4 border border-secondary rounded-none p-5 rounded-lg">
59+
60+
<Resources
61+
v-model="form">
62+
</Resources>
63+
64+
<div class="flex justify-end items-center gap-4">
65+
<PrimaryButton type="submit">
66+
Save
67+
</PrimaryButton>
68+
<SecondaryLink :href="route('collections.outputs.index', {
69+
collection: collection.data.id
70+
71+
})">
72+
Back
73+
</SecondaryLink>
74+
<Delete :output="output"></Delete>
75+
</div>
76+
</div>
77+
</div>
78+
</form>
79+
80+
</div>
81+
</div>
82+
</div>
83+
</AppLayout>
84+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<script setup>
2+
import { useToast } from 'vue-toastification';
3+
import PageLayout from "@/Layouts/PageLayout.vue";
4+
import Chat from "@/Pages/Outputs/WebPage/Components/Chat.vue";
5+
import ChatSlideout from "@/Pages/Outputs/WebPage/Components/ChatSlideout.vue";
6+
import {ref} from "vue";
7+
8+
const toast = useToast();
9+
10+
const props = defineProps({
11+
output: {
12+
type: Object
13+
},
14+
messages: Object
15+
});
16+
17+
const showSlideout = ref(false)
18+
19+
20+
</script>
21+
22+
<template>
23+
<PageLayout :title="output.title">
24+
<div class="mx-auto p-10">
25+
<div class="bg-white rounded-t-lg min-h-screen w-3/4 mx-auto shadow-lg">
26+
<div class="flex justify-start p-2">
27+
<button
28+
class="btn btn-primary flex justify-start gap-3 items-center"
29+
type="button" @click="showSlideout = true">
30+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
31+
<path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z" />
32+
</svg>
33+
34+
<span>chat</span>
35+
</button>
36+
</div>
37+
<article class="prose prose-stone p-10">
38+
<h1>{{ output.data.title }}</h1>
39+
40+
<div v-html="output.data.summary" class="prose prose-xl">
41+
</div>
42+
</article>
43+
</div>
44+
</div>
45+
<ChatSlideout
46+
:messages="messages"
47+
:output="output.data"
48+
@close="showSlideout = false"
49+
:show="showSlideout">
50+
51+
</ChatSlideout>
52+
</PageLayout>
53+
</template>

resources/js/Pages/Outputs/Index.vue

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useToast } from 'vue-toastification';
1212
import WebCard from "@/Pages/Outputs/WebPage/Components/Card.vue";
1313
import EmailCard from "@/Pages/Outputs/EmailOutput/Components/Card.vue";
1414
import ApiCard from "@/Pages/Outputs/ApiOutput/Components/Card.vue";
15+
import CalendarCard from "@/Pages/Outputs/Calendar/Components/Card.vue";
1516
import EmailReplyOutput from "@/Pages/Outputs/EmailReplyOutput/Components/Card.vue";
1617
1718
const toast = useToast();
@@ -69,6 +70,7 @@ const props = defineProps({
6970
<WebCard v-if="output.type === 'web_page'" :output="output"/>
7071
<EmailReplyOutput v-if="output.type === 'email_reply_output'" :output="output"/>
7172
<ApiCard v-if="output.type === 'api_output'" :output="output"/>
73+
<CalendarCard v-if="output.type === 'calendar_output'" :output="output"/>
7274
</template>
7375
</div>
7476
</div>

0 commit comments

Comments
 (0)