Skip to content

Commit

Permalink
feat: sstaars check in
Browse files Browse the repository at this point in the history
  • Loading branch information
qin-guan committed Oct 22, 2023
1 parent a719dbd commit 4a94aaa
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 11 deletions.
6 changes: 3 additions & 3 deletions components/app/home/membership-card.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { f7Card, f7CardContent, f7CardFooter, f7SkeletonBlock } from 'framework7-vue'
import { f7Card, f7CardContent, f7CardFooter, f7List, f7SkeletonBlock } from 'framework7-vue'
import type { User } from '~/shared/types'
const { data: user, isLoading: userIsLoading } = useUser()
Expand All @@ -15,9 +15,9 @@ const membershipGradient: Record<Exclude<User['memberType'], null>, string> = {

<template>
<div>
<div v-if="userIsLoading" class="h-55">
<f7List v-if="userIsLoading" inset class="h-64">
<f7SkeletonBlock class="rounded-md" effect="fade" height="100%" />
</div>
</f7List>

<f7Card v-else-if="user" class="m-0!">
<f7CardContent class="h-44 rounded-[16px]" valign="top" :class="membershipGradient[user.memberType!]">
Expand Down
10 changes: 6 additions & 4 deletions components/app/home/news.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { f7BlockTitle, f7Button, f7Card, f7CardContent, f7CardFooter, f7CardHeader, f7SkeletonBlock } from 'framework7-vue'
import { f7BlockTitle, f7Button, f7Card, f7CardContent, f7CardFooter, f7CardHeader, f7List, f7SkeletonBlock } from 'framework7-vue'
const { data: news, isLoading: newsIsLoading } = useNewsArticles()
</script>
Expand All @@ -11,9 +11,11 @@ const { data: news, isLoading: newsIsLoading } = useNewsArticles()
</f7BlockTitle>

<div class="space-y-3">
<template v-if="newsIsLoading">
<f7SkeletonBlock v-for="n in 3" :key="n" class="rounded-md" effect="fade" height="10rem" />
</template>
<f7List v-if="newsIsLoading" inset>
<div class="space-y-3">
<f7SkeletonBlock v-for="n in 3" :key="n" class="rounded-md" effect="fade" height="10rem" />
</div>
</f7List>
<template v-else-if="news">
<span v-if="news.length === 0" class="mt-4 opacity-80">
Nothing exciting is happening right now.
Expand Down
2 changes: 1 addition & 1 deletion components/app/home/page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { f7List, f7Page } from 'framework7-vue'
</div>

<div>
<AppHomeNews />
<LazyAppHomeNews />
</div>
</f7List>
</f7Page>
Expand Down
118 changes: 116 additions & 2 deletions components/app/services/event/page.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,129 @@
<script setup lang="ts">
import { f7Link, f7NavRight, f7Navbar, f7Page } from 'framework7-vue'
import { f7BlockTitle, f7Card, f7Chip, f7Link, f7List, f7ListItem, f7NavRight, f7NavTitle, f7Navbar, f7Page, f7PageContent, f7Searchbar, f7SkeletonBlock, f7Subnavbar } from 'framework7-vue'

Check failure on line 2 in components/app/services/event/page.vue

View workflow job for this annotation

GitHub Actions / ci

'f7PageContent' is defined but never used
import type { VirtualList } from 'framework7/types'
import type { UnwrapRef } from 'vue'
import { useDatabaseList } from 'vuefire'
import { ref as dbRef } from 'firebase/database'
const props = defineProps<{
id: string // Passed by f7router in URL param
}>()
const { $dayjs } = useNuxtApp()
const db = useDatabase()
const { data: checkedInUsersList, pending: checkedInUsersListPending } = useDatabaseList<{ $value: number }>(dbRef(db, props.id))
const { data: event, isLoading: eventIsLoading } = useEvent(props.id)
const attendees = computed(() => {
return event.value?.attendees.map((attendee, index) => ({
...attendee,
index, // Used by f7 virtual list
})) ?? []
})
const checkedInUsers = computed(() => {
const data: Record<string, number> = {} // admissionKey -> timestamp in seconds
for (const item of checkedInUsersList.value)
data[item.id] = item.$value
return data
})
const attendeeVirtualListData = ref<Omit<Partial<VirtualList.VirtualListRenderData>, 'items'> & { items: UnwrapRef<typeof attendees> }>({
items: [],
})
const formattedDateCache = new Map<number, string>()
function formattedDate(date: number) {
if (formattedDateCache.has(date))
return formattedDateCache.get(date)
const data = $dayjs(date * 1000).fromNow()
formattedDateCache.set(date, data)
return data
}
function searchAll(query: string, items: UnwrapRef<typeof attendees>) {
const found = []
for (const idx in items) {
if (items[idx].name.toLowerCase().includes(query.toLowerCase()) || query.trim() === '')
found.push(idx)
}
return found
}
function renderExternal(_: unknown, data: VirtualList.VirtualListRenderData) {
attendeeVirtualListData.value = data
}
</script>

<template>
<f7Page>
<f7Navbar title="SSTAARS">
<f7Navbar>
<f7NavTitle>SSTAARS</f7NavTitle>
<f7NavRight>
<f7Link popup-close>
Close
</f7Link>
</f7NavRight>
<f7Subnavbar :inner="false">
<f7Searchbar search-container=".virtual-list" search-item="li" search-in=".item-title" />
</f7Subnavbar>
</f7Navbar>

<f7List v-if="eventIsLoading || checkedInUsersListPending" inset>
<div class="space-y-2">
<f7SkeletonBlock v-for="n in 2" :key="n" :height="`${n * 100}px`" class="rounded-md" effect="fade" />
</div>
</f7List>

<template v-else-if="event">
<f7BlockTitle large>
{{ event.name }}
</f7BlockTitle>

<f7Card>
<template #header>
<div class="flex justify-between w-full">
<div>
Checked in
</div>
<div class="rounded-md">
{{ checkedInUsersList.length }} / {{ event.attendees.length }}
</div>
</div>
</template>
</f7Card>

<f7BlockTitle>Attendees</f7BlockTitle>

<f7List
strong inset virtual-list :virtual-list-params="{
items: attendees,
searchAll,
renderExternal,
height: 50,
}"
>
<ul>
<f7ListItem
v-for="attendee in attendeeVirtualListData.items" :key="attendee.admissionKey"
:style="`top: ${attendeeVirtualListData.topPosition}px`" :virtual-list-index="attendee.index" :title="attendee.name"
>
<f7Chip v-if="checkedInUsers[attendee.admissionKey]" color="green">
<span class="text-xs!">
{{ formattedDate(checkedInUsers[attendee.admissionKey]) }}
</span>
</f7Chip>
<f7Chip v-else color="red">
Not checked in
</f7Chip>
</f7ListItem>
</ul>
</f7List>
</template>
</f7Page>
</template>
2 changes: 1 addition & 1 deletion composables/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function useEvent(id: MaybeRef<string>) {
const firebaseCurrentUser = useCurrentUser()
const queryClient = useQueryClient()
return useQuery({
queryKey: queryKeyFactory.events,
queryKey: queryKeyFactory.event(toValue(id)),
queryFn: () => $api<EventWithAttendees>(`/api/event/${toValue(id)}`),
enabled: computed(() => !!firebaseCurrentUser.value), // Only run when user exists
placeholderData() {
Expand Down
12 changes: 12 additions & 0 deletions plugins/dayjs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import dayjs from 'dayjs'
import RelativeTime from 'dayjs/plugin/relativeTime'

export default defineNuxtPlugin(() => {
dayjs.extend(RelativeTime)

return {
provide: {
dayjs,
},
}
})

0 comments on commit 4a94aaa

Please sign in to comment.