import React, { useMemo, useRef, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'; import { useIsMobile } from '@/hooks/use-mobile'; type Props = { mediaUrl: string; onMediaUrlChange: (url: string) => void; fileInputRef: React.RefObject; onFileSelected: (file: File) => void; mediaPreview: string | null; }; type PromotionTemplate = { id: string; name: string; description: string; previewUrl?: string; }; const PromotionTemplatesSection: React.FC = ({ mediaUrl, onMediaUrlChange, fileInputRef, onFileSelected, mediaPreview, }) => { const isMobile = useIsMobile(); const templates: PromotionTemplate[] = useMemo( () => [ { id: 'tpl_event_minimal', name: 'Event Minimal', description: 'Cleanes Event-Template mit Fokus auf Titel + Datum.', previewUrl: '/images/templates/event_minimal_preview.png', }, { id: 'tpl_event_bold', name: 'Event Bold', description: 'Große Typo, geeignet für starke Keyvisuals.', previewUrl: '/images/templates/event_bold_preview.png', }, { id: 'tpl_lineup_grid', name: 'Lineup Grid', description: 'Lineup als Grid-Layout, gut für mehrere Artists.', previewUrl: '/images/templates/lineup_grid_preview.png', }, { id: 'tpl_artist_focus', name: 'Artist Focus', description: 'Portrait/Keyvisual im Fokus, Name + Slot unten.', previewUrl: '/images/templates/artist_focus_preview.png', }, { id: 'tpl_artist_story', name: 'Artist Story', description: 'Story-Format mit kurzem Teaser + Social Handles.', previewUrl: '/images/templates/artist_story_preview.png', }, ], [] ); const [eventPromoTemplateId, setEventPromoTemplateId] = useState(templates[0]?.id ?? ''); const [eventLineupTemplateId, setEventLineupTemplateId] = useState(templates[2]?.id ?? ''); const [artistPromoTemplateId, setArtistPromoTemplateId] = useState(templates[3]?.id ?? ''); const importZipInputRef = useRef(null); const [importingTemplate, setImportingTemplate] = useState(false); const selectedEventPromo = templates.find((t) => t.id === eventPromoTemplateId) || null; const selectedEventLineup = templates.find((t) => t.id === eventLineupTemplateId) || null; const selectedArtistPromo = templates.find((t) => t.id === artistPromoTemplateId) || null; const handleImportZip = async (file: File) => { setImportingTemplate(true); try { // Placeholder: Upload to backend endpoint will be added later await new Promise((r) => setTimeout(r, 400)); } finally { setImportingTemplate(false); } }; const TemplateSelect = ({ label, value, onValueChange, selected, }: { label: string; value: string; onValueChange: (next: string) => void; selected: PromotionTemplate | null; }) => { const [open, setOpen] = useState(false); return (
{isMobile ? ( <>
{label}
{templates.map((tpl) => { const isActive = tpl.id === value; return ( ); })}
) : ( )}
Vorschau
{selected?.previewUrl ? ( ) : (
)}
{selected?.name || 'Kein Template gewählt'}
{selected?.description || ''}
); }; return (
Promotion Templates
Sektion 1 – Event-Promotion
onMediaUrlChange(e.target.value)} />
{ const file = e.target.files?.[0]; if (!file) return; onFileSelected(file); }} />
{mediaPreview && (
{mediaPreview.match(/\.mp4$|\.webm$|\.ogg$/i) ? (
)}
Sektion 2 – Event Lineup
Sektion 3 – Artist Promo
{/*
Templates verwalten
*/}
{ const file = e.target.files?.[0]; if (!file) return; await handleImportZip(file); e.target.value = ''; }} />
Dieser Bereich wird später konkretisiert (Templates, Textbausteine, Scheduling etc.).
); }; export default PromotionTemplatesSection;