diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2025-08-24 17:51:06 +0100 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2025-08-24 17:51:06 +0100 |
| commit | 5a5de81bec8f18ae0f27d528d862e6cf1438b54a (patch) | |
| tree | b4638a6fe98b4b75b4d67759d307f632905fe6a1 | |
| parent | 215aa87cfce77a4e14dad26eb7b2885c01952b83 (diff) | |
| -rw-r--r-- | web/components/EventListing.vue | 1 | ||||
| -rw-r--r-- | web/layouts/default.vue | 7 | ||||
| -rw-r--r-- | web/pages/conferences.vue | 33 |
3 files changed, 30 insertions, 11 deletions
diff --git a/web/components/EventListing.vue b/web/components/EventListing.vue index 0cc546c..ca200ab 100644 --- a/web/components/EventListing.vue +++ b/web/components/EventListing.vue @@ -75,6 +75,7 @@ const removeFavourite = async () => { await $api(config.public.baseURL + '/favourites', { method: 'DELETE', body: JSON.stringify({ + conferenceId: conferenceStore.id, eventGuid: event.guid, eventId: event.id, }), diff --git a/web/layouts/default.vue b/web/layouts/default.vue index 5f85c38..90cabd5 100644 --- a/web/layouts/default.vue +++ b/web/layouts/default.vue @@ -1,5 +1,5 @@ <script setup lang="ts"> -import { BookHeart, LucideMenu, LucideX } from "lucide-vue-next"; +import { LucideMenu, LucideX, Notebook } from "lucide-vue-next"; import Dialog from "~/components/Dialog.vue"; import EventDetail from "~/components/EventDetail.vue"; import Sidebar from "~/components/Sidebar.vue"; @@ -48,7 +48,7 @@ router.afterEach(() => { <div class="planner-container"> <header> <div class="planner-header"> - <span class="text-icon planner-title" @click="navigateTo('/')"><BookHeart /> confplanner</span> + <span class="text-icon planner-title" @click="navigateTo('/')"><Notebook /> confplanner</span> <NuxtLink class="logout logout-header" @click="logout">Log out {{ authStore.username }} {{ authStore.admin ? '(admin)' : ''}}</NuxtLink> <span class="hamburger" @click="showHamburger = !showHamburger"> <LucideMenu :size="24" v-if="!showHamburger"/> @@ -101,7 +101,6 @@ header { div.planner-header { background-color: var(--color-background-muted); - color: var(--color-text-muted); border-top: 3px solid var(--color-primary); border-bottom: 1px solid var(--color-border); height: 3.5rem; @@ -147,7 +146,7 @@ aside.planner-sidebar { max-width: 300px; position: sticky; align-self: flex-start; - top: calc(4.5rem + 2px); + top: calc(4.5rem + 2px + 3px); } .loading-text { diff --git a/web/pages/conferences.vue b/web/pages/conferences.vue index 993bc66..511de95 100644 --- a/web/pages/conferences.vue +++ b/web/pages/conferences.vue @@ -24,6 +24,12 @@ const config = useRuntimeConfig(); const status = ref('idle' as 'loading' | 'idle') +const refConfirmDeleteDialog = ref<typeof Dialog>(); + +const deleteConferenceId = ref(null as number | null) +const deleteConferenceName = ref(null as string | null) +const deleteAction = ref(false); + const fetchConferences = () => { status.value = 'loading' $api(config.public.baseURL + '/conference', { @@ -42,22 +48,22 @@ const fetchConferences = () => { }) } -const deleteConference = (id: number) => { - // todo make this better +const deleteConference = () => { $api(config.public.baseURL + '/conference', { method: 'DELETE', body: { - id: id + id: deleteConferenceId.value }, onResponse: ({ response }) => { if (!response.ok) { errorStore.setError(response._data.message || 'An unknown error occurred'); } + fetchConferences() }, }) } -const selectConference = async (c) => { +const selectConference = async (c: any) => { setting.value = true conferenceStore.id = c.id try { @@ -77,18 +83,22 @@ onMounted(fetchConferences) <template v-if="!setting"> <Panel title="Conferences" :icon="MapPin"> <span class="loading-text" v-if="status === 'loading'"><Spinner color="var(--color-text-muted)" />Fetching conferences...</span> - <div class="conference-list" v-if="conferences.length > 0 && status !== 'loading'"> + <div class="conference-list" v-if="conferences?.length > 0 && status !== 'loading'"> <template v-for="conference of conferences"> <span class="title">{{ conference.title }}</span> <span>{{ conference.city }}</span> <span>{{ conference.venue }}</span> <span class="actions"> - <Button v-if="authStore.admin" kind="secondary" @click="() => { deleteConference(conference.id) }">Delete</Button> + <Button v-if="authStore.admin" kind="secondary" @click="() => { + deleteConferenceId = conference.id + deleteConferenceName = conference.title + refConfirmDeleteDialog!.show() + }">Delete</Button> <Button @click="() => { selectConference(conference) }">Select</Button> </span> </template> </div> - <p v-if="conferences.length == 0 && status !== 'loading'"> + <p v-if="(conferences == null || conferences?.length == 0) && status !== 'loading'"> There are no conferences to display. </p> </Panel> @@ -102,6 +112,15 @@ onMounted(fetchConferences) <span class="loading-text"><Spinner color="var(--color-text-muted)" />Setting conference...</span> </div> </template> + + <Dialog ref="refConfirmDeleteDialog" title="Delete conference" :confirmation="true" @submit="deleteConference" :fit-contents="true"> + <span>Are you sure you want to delete "{{ deleteConferenceName }}"?</span> + <span>All favourites for all users for this conference will be lost and irrecoverable.</span> + <template v-slot:actions> + <Button kind="secondary" type="button" @click="refConfirmDeleteDialog!.close()">Cancel</Button> + <Button kind="danger" type="submit" :loading="deleteAction">Delete</Button> + </template> + </Dialog> </template> <style> |
