SkateSpots/src/components/AddToCalendar.tsx
shakespeare.diy 1c295e96e2 Improve Create Tour: consistent schedules, calendar export & punk redesign
- Add a unified Schedule section across all four tour categories:
  - Local: choose a fixed session (date+time) or flexible/by-appointment
  - National/International: required departure + optional return trip dates
  - Destruction: existing competition window, now with end>=start validation
- Reuse start-date/end-date tags for every category (parser already supported them)
- Fix datetime handling: dedicated toDateInput/inputToSecs helpers so date and
  datetime-local inputs round-trip correctly (previous mix of toLocalInput +
  type="date" was inconsistent)
- Consistent, logical mandatory-field validation with clear required markers
- Redesign the header into an immersive, category-tinted, grunge-striped banner
  and rebuild the category selector as elegant glowing cards
- New calendar utilities (.ics + Google Calendar) and AddToCalendar component
- TourDetailPage is now fully category-aware (badge, guide label, duration,
  SEO title) with a Schedule card + Add to Calendar for attendees
- TourCard shows the schedule for all categories (time for local sessions)
- Update NIP.md to document start-date/end-date across categories

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-09 22:16:16 +07:00

62 lines
1.8 KiB
TypeScript

import { CalendarPlus, Download, CalendarClock } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
downloadICS,
googleCalendarUrl,
type CalendarEventInput,
} from '@/lib/calendar';
import { cn } from '@/lib/utils';
interface AddToCalendarProps {
event: CalendarEventInput;
/** Accent color for the button (category color). */
color?: string;
className?: string;
}
/**
* Small button that lets attendees drop a tour into their calendar of choice.
* Offers a native .ics download (Apple/Outlook) and a Google Calendar link.
*/
export function AddToCalendar({ event, color = '#06b6d4', className }: AddToCalendarProps) {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
type="button"
variant="outline"
className={cn('gap-2 font-bold', className)}
style={{ borderColor: `${color}55`, color }}
>
<CalendarPlus className="h-4 w-4" />
Add to Calendar
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-52">
<DropdownMenuItem
onClick={() => downloadICS(event)}
className="cursor-pointer"
>
<Download className="h-4 w-4 mr-2" />
Apple / Outlook (.ics)
</DropdownMenuItem>
<DropdownMenuItem asChild className="cursor-pointer">
<a
href={googleCalendarUrl(event)}
target="_blank"
rel="noopener noreferrer"
>
<CalendarClock className="h-4 w-4 mr-2" />
Google Calendar
</a>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}