feat(birthday): upload fields for why-section videos

Replace text src/poster in whyVideos with media upload pickers so
admins can upload video files directly from the CMS instead of
entering raw URLs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-06-05 13:10:59 +01:00
parent 04e13097da
commit 7e592d3af7
3 changed files with 36 additions and 8 deletions

View file

@ -0,0 +1,14 @@
-- 0015: replace text src/poster in birthday_page_why_videos with media FK uploads
ALTER TABLE "birthday_page_why_videos"
ADD COLUMN IF NOT EXISTS "video_id" integer
REFERENCES "media"("id") ON DELETE SET NULL ON UPDATE NO ACTION,
ADD COLUMN IF NOT EXISTS "poster_id" integer
REFERENCES "media"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
-- versions mirror
ALTER TABLE "_birthday_page_v_version_why_videos"
ADD COLUMN IF NOT EXISTS "video_id" integer
REFERENCES "media"("id") ON DELETE SET NULL ON UPDATE NO ACTION,
ADD COLUMN IF NOT EXISTS "poster_id" integer
REFERENCES "media"("id") ON DELETE SET NULL ON UPDATE NO ACTION;

View file

@ -423,11 +423,13 @@ export default async function BirthdayPage() {
items={whyItems.map((i) => ({ title: i.title, description: i.description }))}
reviewVideos={
whyVideos.length > 0
? whyVideos.map((v) => ({
src: v.src as string,
poster: (v.poster as string) ?? null,
label: (v.label as string) ?? null,
}))
? whyVideos
.map((v) => ({
src: mediaUrl(v.video as Media | undefined) ?? (v.src as string) ?? '',
poster: mediaUrl(v.poster as Media | undefined) ?? null,
label: (v.label as string) ?? null,
}))
.filter((v) => v.src)
: undefined
}
/>

View file

@ -130,9 +130,21 @@ export const BirthdayPage: GlobalConfig = {
type: 'array',
label: 'Відео-відгуки у секції "Чому"',
fields: [
{ name: 'src', type: 'text', required: true },
{ name: 'poster', type: 'text' },
{ name: 'label', type: 'text' },
{
name: 'video',
type: 'upload',
relationTo: 'media',
required: true,
label: 'Відео файл',
},
{
name: 'poster',
type: 'upload',
relationTo: 'media',
required: false,
label: 'Постер (обкладинка, опційно)',
},
{ name: 'label', type: 'text', label: 'Підпис (опційно)' },
],
},
// Working hours