- MC registrations: notification toggles (confirm/remind) with urgency - Group bookings: save to DB from BookingModal, admin CRUD at /admin/bookings - Open Day: full event system with schedule grid (halls × time), per-class booking, discount pricing (30 BYN / 20 BYN from 3+), auto-cancel threshold - Unified SignupModal replaces 3 separate forms — consistent fields (name, phone, instagram, telegram), Instagram DM fallback on network error - Centralized /admin/bookings page with 3 tabs (classes, MC, Open Day), collapsible sections, notification toggles, filter chips - Unread booking badge on sidebar + dashboard widget with per-type breakdown - Pricing: contact hint (Instagram/Telegram/phone) on price & rental tabs, admin toggle to show/hide - DB migrations 5-7: group_bookings table, open_day tables, unified fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
159 lines
2.7 KiB
TypeScript
159 lines
2.7 KiB
TypeScript
export interface ClassItem {
|
|
name: string;
|
|
description: string;
|
|
icon: string;
|
|
detailedDescription?: string;
|
|
images?: string[];
|
|
color?: string;
|
|
}
|
|
|
|
export interface RichListItem {
|
|
text: string;
|
|
image?: string;
|
|
link?: string;
|
|
}
|
|
|
|
export interface VictoryItem {
|
|
type?: 'place' | 'nomination' | 'judge';
|
|
place: string;
|
|
category: string;
|
|
competition: string;
|
|
location?: string;
|
|
date?: string;
|
|
image?: string;
|
|
link?: string;
|
|
}
|
|
|
|
export interface TeamMember {
|
|
name: string;
|
|
role: string;
|
|
image: string;
|
|
instagram?: string;
|
|
description?: string;
|
|
experience?: string[];
|
|
victories?: VictoryItem[];
|
|
education?: RichListItem[];
|
|
}
|
|
|
|
export interface FAQItem {
|
|
question: string;
|
|
answer: string;
|
|
}
|
|
|
|
export interface PricingItem {
|
|
name: string;
|
|
price: string;
|
|
note?: string;
|
|
popular?: boolean;
|
|
featured?: boolean;
|
|
}
|
|
|
|
export interface ScheduleClass {
|
|
time: string;
|
|
trainer: string;
|
|
type: string;
|
|
level?: string;
|
|
hasSlots?: boolean;
|
|
recruiting?: boolean;
|
|
groupId?: string;
|
|
}
|
|
|
|
export interface ScheduleDay {
|
|
day: string;
|
|
dayShort: string;
|
|
classes: ScheduleClass[];
|
|
}
|
|
|
|
export interface ScheduleLocation {
|
|
name: string;
|
|
address: string;
|
|
days: ScheduleDay[];
|
|
}
|
|
|
|
export interface MasterClassSlot {
|
|
date: string; // ISO "2026-03-13"
|
|
startTime: string; // "19:00"
|
|
endTime: string; // "21:00"
|
|
}
|
|
|
|
export interface MasterClassItem {
|
|
title: string;
|
|
image: string;
|
|
slots: MasterClassSlot[];
|
|
trainer: string;
|
|
cost: string;
|
|
style: string;
|
|
location?: string;
|
|
description?: string;
|
|
instagramUrl?: string;
|
|
}
|
|
|
|
export interface NewsItem {
|
|
title: string;
|
|
text: string;
|
|
date: string;
|
|
image?: string;
|
|
link?: string;
|
|
}
|
|
|
|
export interface ContactInfo {
|
|
title: string;
|
|
addresses: string[];
|
|
phone: string;
|
|
instagram: string;
|
|
mapEmbedUrl: string;
|
|
workingHours: string;
|
|
}
|
|
|
|
export interface SiteContent {
|
|
meta: {
|
|
title: string;
|
|
description: string;
|
|
};
|
|
hero: {
|
|
headline: string;
|
|
subheadline: string;
|
|
ctaText: string;
|
|
ctaHref: string;
|
|
};
|
|
team: {
|
|
title: string;
|
|
members: TeamMember[];
|
|
};
|
|
about: {
|
|
title: string;
|
|
paragraphs: string[];
|
|
};
|
|
classes: {
|
|
title: string;
|
|
items: ClassItem[];
|
|
};
|
|
faq: {
|
|
title: string;
|
|
items: FAQItem[];
|
|
};
|
|
pricing: {
|
|
title: string;
|
|
subtitle: string;
|
|
items: PricingItem[];
|
|
rentalTitle: string;
|
|
rentalItems: PricingItem[];
|
|
rules: string[];
|
|
showContactHint?: boolean;
|
|
};
|
|
masterClasses: {
|
|
title: string;
|
|
successMessage?: string;
|
|
items: MasterClassItem[];
|
|
};
|
|
schedule: {
|
|
title: string;
|
|
locations: ScheduleLocation[];
|
|
};
|
|
news: {
|
|
title: string;
|
|
items: NewsItem[];
|
|
};
|
|
contact: ContactInfo;
|
|
}
|