Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(admin): events management #7

Merged
merged 31 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ec47dae
wip: events table
Ethan-Chew Oct 8, 2023
97da2ad
feat: create and delete event
Ethan-Chew Oct 9, 2023
d882b2e
feat: event information
Ethan-Chew Oct 9, 2023
7bdd607
fix: attendees import
Ethan-Chew Oct 9, 2023
7b63805
fix: checked-in users
Ethan-Chew Oct 13, 2023
c03767e
feat: add nuxtui login
Ethan-Chew Oct 14, 2023
23e3cb1
feat: add image URL validation
Ethan-Chew Oct 14, 2023
856c4f8
fix: verify image url on server
Ethan-Chew Oct 14, 2023
895a062
feat: update event
Ethan-Chew Oct 15, 2023
1895948
fix: restrictTo exco for update
Ethan-Chew Oct 15, 2023
2732319
fix: resolved most comments
Ethan-Chew Oct 21, 2023
9a54153
fix: removed difference check when updating
Ethan-Chew Oct 23, 2023
5bb8c7f
Merge branch 'main' into feat/nuxtui
Ethan-Chew Oct 24, 2023
1cbe61f
fix: readded pnpm-lock
Ethan-Chew Oct 24, 2023
658acda
fix: update name case
Ethan-Chew Oct 24, 2023
fa07bab
Revert "fix: update name case"
qin-guan Oct 28, 2023
efa799b
fix: lint rules + dep upgrade
qin-guan Oct 28, 2023
6caf032
chore: remote stash
qin-guan Oct 28, 2023
71172b1
fix: reload on scope change
qin-guan Oct 29, 2023
7522edb
chore: remote stash
qin-guan Oct 30, 2023
7c3ccf0
feat: schema update
qin-guan Nov 2, 2023
ad39696
chore: dep upgrade and some fixes
qin-guan Jan 3, 2024
32fe27f
chore: update
qin-guan Jan 5, 2024
8885f74
feat: remove ts-rest, fix type issues, use new persister
qin-guan Jan 6, 2024
69eb3a1
chore: wip
qin-guan Jan 6, 2024
ab0c981
feat: update
qin-guan Jan 6, 2024
da1c371
feat: clean up
qin-guan Jan 6, 2024
f53d606
feat: add buster
qin-guan Jan 6, 2024
5df3ada
Merge branch 'main' into feat/nuxtui
qin-guan Jan 6, 2024
81857d6
chore: lint
qin-guan Jan 6, 2024
14f3eb7
feat: members page
qin-guan Jan 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<NuxtLayout>
<NuxtPage />
</NuxtLayout>

<UNotifications />
</div>
</template>

Expand Down
42 changes: 0 additions & 42 deletions components/admin/common/left-panel.vue

This file was deleted.

103 changes: 103 additions & 0 deletions components/admin/event/create-popup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<script setup lang="ts">
import type { FormSubmitEvent } from '@nuxt/ui/dist/runtime/types'
import { z } from 'zod'

const visible = defineModel<boolean>('visible')
const dayjs = useDayjs()
const toast = useToast()

const schema = z.object({
name: z.string()
.min(1, 'Please enter a name'),
description: z.string(),
location: z.string(),
badgeImage: z.string()
.url('Please enter a URL'),
startDateTime: z.string()
.refine(val => dayjs(val).isAfter(dayjs()), 'Start date must be in the future')
.transform(d => dayjs(d).unix().toString()),
endDateTime: z.string()
.transform(d => dayjs(d).unix().toString()),
}).refine((val) => {
return Number.parseInt(val.startDateTime) < Number.parseInt(val.endDateTime)
}, {
message: 'Event must end after it starts',
path: ['endDateTime'],
})

type Schema = z.output<typeof schema>

const state = reactive({
name: '',
description: '',
location: '',
badgeImage: '',
startDateTime: '',
endDateTime: '',
})

const { mutate: createEventMutate, isPending: createEventIsPending } = useCreateEventMutation()

function createEvent({ data }: FormSubmitEvent<Schema>) {
createEventMutate(data, {
onSuccess() {
visible.value = false
},
onError(err) {
toast.add({
title: err.message,
})
},
})
}
</script>

<template>
<UModal v-model="visible">
<UCard>
<template #header>
<div class="flex justify-between items-start">
<div>
<h1 class="text-xl font-semibold">
Create event
</h1>
<p class="text-sm opacity-80">
Add a new event hosted by SSTAA!
</p>
</div>
<UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" @click="visible = false" />
</div>
</template>

<UForm :state="state" :schema="schema" class="space-y-7" @submit="createEvent">
<div class="space-y-5">
<UFormGroup label="Name" name="name">
<UInput v-model="state.name" placeholder="SST Homecoming" />
</UFormGroup>
<UFormGroup label="Description" name="description">
<UTextarea
v-model="state.description"
placeholder="Come back to 1 Technology Drive for our inaugural homecoming!"
/>
</UFormGroup>
<UFormGroup label="Location" name="location">
<UInput v-model="state.location" placeholder="1 Technology Drive, Singapore" />
</UFormGroup>
<UFormGroup label="Badge image" name="badgeImage">
<UInput v-model="state.badgeImage" type="url" placeholder="https://app.sstaa.org/cdn/logo.png" />
</UFormGroup>
<UFormGroup label="Start" name="startDateTime">
<UInput v-model="state.startDateTime" after="" type="datetime-local" />
</UFormGroup>
<UFormGroup label="End" name="endDateTime">
<UInput v-model="state.endDateTime" type="datetime-local" />
</UFormGroup>
</div>

<UButton type="submit" :loading="createEventIsPending">
Create event
</UButton>
</UForm>
</UCard>
</UModal>
</template>
9 changes: 0 additions & 9 deletions components/admin/event/page.vue

This file was deleted.

91 changes: 91 additions & 0 deletions components/admin/event/update-form.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<script setup lang="ts">
import type { FormSubmitEvent } from '@nuxt/ui/dist/runtime/types'
import { z } from 'zod'

const props = defineProps<{
id: string
name: string
description?: string | null
location?: string | null
badgeImage?: string | null
startDateTime: number
endDateTime: number
}>()

const toast = useToast()
const dayjs = useDayjs()

const state = reactive({
name: props.name,
description: props.description ?? '',
location: props.location ?? '',
badgeImage: props.badgeImage ?? '',
startDateTime: dayjs.unix(props.startDateTime).toISOString(),
endDateTime: dayjs.unix(props.endDateTime).toISOString(),
})

const schema = z.object({
name: z.string()
.min(1, 'Please enter a name'),
description: z.string(),
location: z.string(),
badgeImage: z.string()
.url('Please enter a URL'),
startDateTime: z.string()
.refine(val => dayjs(val).isAfter(dayjs()), 'Start date must be in the future')
.transform(d => dayjs(d).unix().toString()),
endDateTime: z.string()
.transform(d => dayjs(d).unix().toString()),
}).refine((val) => {
return dayjs(val.startDateTime).isBefore(val.endDateTime)
}, {
message: 'Event must end after it starts',
path: ['endDateTime'],
})

type Schema = z.output<typeof schema>

const { mutate: updateEventMutate, isPending: updateEventIsPending } = useUpdateEventMutation(props.id)

function updateEvent({ data }: FormSubmitEvent<Schema>) {
updateEventMutate(data, {
onError(err) {
toast.add({
title: err.message,
})
},
})
}
</script>

<template>
<UForm :state="state" :schema="schema" class="space-y-7" @submit="updateEvent">
<div class="space-y-5">
<UFormGroup label="Name" name="name">
<UInput v-model="state.name" placeholder="SST Homecoming" />
</UFormGroup>
<UFormGroup label="Description" name="description">
<UTextarea
v-model="state.description"
placeholder="Come back to 1 Technology Drive for our inaugural homecoming!"
/>
</UFormGroup>
<UFormGroup label="Location" name="location">
<UInput v-model="state.location" placeholder="1 Technology Drive, Singapore" />
</UFormGroup>
<UFormGroup label="Badge image" name="badgeImage">
<UInput v-model="state.badgeImage" type="url" placeholder="https://app.sstaa.org/cdn/logo.png" />
</UFormGroup>
<UFormGroup label="Start" name="startDateTime">
<UInput v-model="state.startDateTime" after="" type="datetime-local" />
</UFormGroup>
<UFormGroup label="End" name="endDateTime">
<UInput v-model="state.endDateTime" type="datetime-local" />
</UFormGroup>
</div>

<UButton type="submit" :loading="updateEventIsPending">
Update
</UButton>
</UForm>
</template>
13 changes: 13 additions & 0 deletions components/admin/forbidden.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<UContainer>
<h1 class="text-3xl">
Forbidden :/
</h1>
<p class="text-lg">
You do not have access to this page. That's all we know.
</p>
<UButton to="/app" target="_blank" size="lg" color="blue">
Return to app
</UButton>
</UContainer>
</template>
70 changes: 0 additions & 70 deletions components/admin/home/events-table.vue

This file was deleted.

21 changes: 0 additions & 21 deletions components/admin/home/forbidden.vue

This file was deleted.

Loading
Loading