feat: add booking management, Open Day, unified signup modal
- 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>
This commit is contained in:
71
src/app/admin/_components/NotifyToggle.tsx
Normal file
71
src/app/admin/_components/NotifyToggle.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
"use client";
|
||||
|
||||
import { Bell, CheckCircle2 } from "lucide-react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
|
||||
function Toggle({
|
||||
done,
|
||||
urgent,
|
||||
icon: Icon,
|
||||
label,
|
||||
onToggle,
|
||||
}: {
|
||||
done: boolean;
|
||||
urgent: boolean;
|
||||
icon: LucideIcon;
|
||||
label: string;
|
||||
onToggle: () => void;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onToggle}
|
||||
title={label}
|
||||
className={`relative flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium transition-all ${
|
||||
done
|
||||
? "bg-emerald-500/15 text-emerald-400 border border-emerald-500/30"
|
||||
: urgent
|
||||
? "bg-red-500/15 text-red-400 border border-red-500/30 pulse-urgent"
|
||||
: "bg-neutral-700/50 text-neutral-400 border border-white/10 hover:border-white/25 hover:text-white"
|
||||
}`}
|
||||
>
|
||||
<Icon size={10} />
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export function NotifyToggle({
|
||||
confirmed,
|
||||
reminded,
|
||||
confirmUrgent,
|
||||
reminderUrgent,
|
||||
onToggleConfirm,
|
||||
onToggleReminder,
|
||||
}: {
|
||||
confirmed: boolean;
|
||||
reminded: boolean;
|
||||
confirmUrgent?: boolean;
|
||||
reminderUrgent?: boolean;
|
||||
onToggleConfirm: () => void;
|
||||
onToggleReminder: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Toggle
|
||||
done={confirmed}
|
||||
urgent={confirmUrgent ?? !confirmed}
|
||||
icon={CheckCircle2}
|
||||
label="Подтверждение"
|
||||
onToggle={onToggleConfirm}
|
||||
/>
|
||||
<Toggle
|
||||
done={reminded}
|
||||
urgent={reminderUrgent ?? false}
|
||||
icon={Bell}
|
||||
label="Напоминание"
|
||||
onToggle={onToggleReminder}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user