Redesign public site, add phase gating and clip submission
- Rebuild landing page and Nominations/Voting/Winners views in the Jayuhime brand style (purple/gold/pastel-rainbow, stars, PageHero banner) - Gate participation by season phase (nominate/clip share the nomination window, vote in the voting window); hide closed/locked pages from nav - Add login-gated clip submission flow (link-based) + voting clip links - Make candidate admin scalable: searchable, filterable, paginated table with modal create/edit and confirm-delete; add delete API/store actions - New reusable Modal and PageHero components, usePhases composable - Segmented top nav and full-size header on admin routes - vite: honor PORT env for preview Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { useAwardsStore } from '../stores/awards'
|
||||
|
||||
/** Teilnahme-Aktionen und die Phase (Timeline-key), an die sie gekoppelt sind. */
|
||||
export type ActionKey = 'nominate' | 'clip' | 'vote'
|
||||
|
||||
export const PHASE_KEY: Record<ActionKey, string> = {
|
||||
nominate: 'nomination',
|
||||
clip: 'nomination', // Clips laufen im selben Fenster wie die Nominierung
|
||||
vote: 'voting',
|
||||
}
|
||||
|
||||
export type PhaseState = 'upcoming' | 'active' | 'done'
|
||||
|
||||
export interface PhaseInfo {
|
||||
state: PhaseState
|
||||
open: boolean
|
||||
startLabel: string
|
||||
endLabel: string
|
||||
}
|
||||
|
||||
function formatDate(date?: string): string {
|
||||
if (!date) return ''
|
||||
const parsed = new Date(`${date}T00:00:00`)
|
||||
return Number.isNaN(parsed.getTime())
|
||||
? date
|
||||
: parsed.toLocaleDateString('de-DE', { day: '2-digit', month: 'long' })
|
||||
}
|
||||
|
||||
export function usePhases() {
|
||||
const store = useAwardsStore()
|
||||
|
||||
function infoForPhaseKey(key?: string): PhaseInfo {
|
||||
const item = store.overview.timeline.find((entry) => entry.key === key)
|
||||
const state = (item?.state ?? 'upcoming') as PhaseState
|
||||
return {
|
||||
state,
|
||||
open: state === 'active',
|
||||
startLabel: formatDate(item?.startsAt),
|
||||
endLabel: formatDate(item?.endsAt),
|
||||
}
|
||||
}
|
||||
|
||||
function phaseInfo(action: ActionKey): PhaseInfo {
|
||||
return infoForPhaseKey(PHASE_KEY[action])
|
||||
}
|
||||
|
||||
return { phaseInfo, infoForPhaseKey }
|
||||
}
|
||||
Reference in New Issue
Block a user