-
Notifications
You must be signed in to change notification settings - Fork 8
feat: add fringe events page and API #186
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| <script setup lang="ts"> | ||
| import type { Fringe } from '#shared/types/fringe' | ||
| import { useI18n } from 'vue-i18n' | ||
| import CpContentCard from '~/components/shared/CpContentCard.vue' | ||
|
|
||
| const { t } = useI18n() | ||
|
|
||
| const { data: fringes } = await useFetch<Fringe[]>('/api/fringe') | ||
| const noFringe = computed(() => !fringes.value || fringes.value.length === 0) | ||
| </script> | ||
|
|
||
| <template> | ||
| <main class="mx-auto my-8 max-w-[80vw] w-[1200px]"> | ||
| <section v-if="noFringe"> | ||
| <p class="text-primary-500 text-center"> | ||
| {{ t('noFringe') }} | ||
| </p> | ||
| </section> | ||
| <section | ||
| v-else | ||
| class="gap-4 grid" | ||
| > | ||
| <CpContentCard | ||
| v-for="fringe in fringes" | ||
| :key="fringe.id" | ||
| :item="{ | ||
| id: `fringe-${fringe.id}`, | ||
| title: fringe.title, | ||
| intro: fringe.intro, | ||
| link: fringe.link, | ||
| image: fringe.logo, | ||
| }" | ||
| /> | ||
| </section> | ||
| </main> | ||
| </template> | ||
|
|
||
| <i18n lang="yaml"> | ||
| zh: | ||
| noFringe: "周邊活動目前尚未公布。" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 這個文字我等等去大籌上問問,可能會需要像是:「如果有你有活動,可以到....申請」 |
||
| en: | ||
| noFringe: "Fringe events have not been announced yet." | ||
| </i18n> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { transformGoogleDriveImageUrl } from '../utils/images' | ||
| import { fetchSheet } from '../utils/sheets' | ||
|
|
||
| export default defineEventHandler(async () => { | ||
| const fringeRows = await fetchSheet('fringe') | ||
|
|
||
| const fringes = import.meta.dev ? fringeRows : fringeRows.filter(({ publish }) => publish) | ||
|
|
||
| return fringes.map(({ id, title_zh, title_en, intro_zh, intro_en, link, logo }) => ({ | ||
| id, | ||
| title: { zh: title_zh, en: title_en }, | ||
| intro: { zh: intro_zh, en: intro_en }, | ||
| link, | ||
| logo: transformGoogleDriveImageUrl(logo), | ||
| })) | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| export function transformGoogleDriveImageUrl(source: string) { | ||
| if (source.startsWith('https://drive.google.com/file/d/')) { | ||
| const id = source.split('/')[5] | ||
|
|
||
| return `https://drive.google.com/thumbnail?id=${id}` | ||
| } | ||
|
|
||
| return source | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { z } from 'zod' | ||
|
|
||
| export const FringeRowSchema = z.object({ | ||
| id: z.string(), | ||
| title_zh: z.string(), | ||
| title_en: z.string(), | ||
| intro_zh: z.string(), | ||
| intro_en: z.string(), | ||
| link: z.string(), | ||
| contact: z.string(), | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 或許可以想想怎麼把
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 想確認一下 contact 欄位是什麼意思呢? 是聯絡人嗎?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 對的喔 |
||
| contact_email: z.string(), | ||
| logo: z.string(), | ||
| publish: z.string().transform((val) => val.trim().toLowerCase() === 'true'), | ||
| }) | ||
| export type FringeRow = z.infer<typeof FringeRowSchema> | ||
|
|
||
| export const FringeSchema = z.object({ | ||
| id: z.string(), | ||
| title: z.object({ | ||
| zh: z.string(), | ||
| en: z.string(), | ||
| }), | ||
| intro: z.object({ | ||
| zh: z.string(), | ||
| en: z.string(), | ||
| }), | ||
| link: z.string(), | ||
| logo: z.string(), | ||
| }) | ||
| export type Fringe = z.infer<typeof FringeSchema> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,25 @@ | ||
| import type * as z from 'zod' | ||
| import { FringeRowSchema } from './fringe' | ||
| import { SponsorListRowSchema } from './sponsor' | ||
| import { SponsorshipAddOnSchema, SponsorshipTierSchema } from './sponsorship' | ||
| import { StaffRowSchema } from './staff' | ||
|
|
||
| export type SheetID = typeof SHEET_IDS[number] | ||
|
|
||
| export const SHEET_IDS = Object.freeze(['sponsorship-tiers', 'sponsorship-add-ons-zh', 'sponsorship-add-ons-en', 'sponsor-list', 'staff'] as const) | ||
| export const SHEET_IDS = Object.freeze(['sponsorship-tiers', 'sponsorship-add-ons-zh', 'sponsorship-add-ons-en', 'sponsor-list', 'staff', 'fringe'] as const) | ||
|
Link1515 marked this conversation as resolved.
|
||
| export const SHEET_NAMES = Object.freeze({ | ||
| 'sponsorship-tiers': '贊助方案', | ||
| 'sponsorship-add-ons-zh': '贊助方案加價購(中文)', | ||
| 'sponsorship-add-ons-en': '贊助方案加價購(英文)', | ||
| 'sponsor-list': '贊助列表', | ||
| 'staff': '工作夥伴', | ||
| 'fringe': '周邊資訊', | ||
| } satisfies Record<SheetID, string>) | ||
| export const SHEET_SCHEMAS = Object.freeze({ | ||
| 'sponsorship-tiers': SponsorshipTierSchema, | ||
| 'sponsorship-add-ons-zh': SponsorshipAddOnSchema, | ||
| 'sponsorship-add-ons-en': SponsorshipAddOnSchema, | ||
| 'sponsor-list': SponsorListRowSchema, | ||
| 'staff': StaffRowSchema, | ||
| 'fringe': FringeRowSchema, | ||
| } satisfies Record<SheetID, z.Schema>) | ||
Uh oh!
There was an error while loading. Please reload this page.