theming, date, time localisation, additional features, seeding initial cleanup

This commit is contained in:
mikicvi
2025-09-26 21:12:59 +01:00
parent b89d91ade2
commit 22c462c61c
43 changed files with 2647 additions and 550 deletions
+11 -7
View File
@@ -33,7 +33,7 @@ export function BookingCalendar() {
const [selectedCourt, setSelectedCourt] = useState<string | null>(null);
const formatDate = (date: Date) => {
return date.toLocaleDateString('en-US', {
return date.toLocaleDateString('en-IE', {
weekday: 'long',
year: 'numeric',
month: 'long',
@@ -145,13 +145,17 @@ export function BookingCalendar() {
size='sm'
onClick={() => !isBooked && setSelectedSlot(time)}
disabled={isBooked}
className='relative'
className={`relative transition-all ${
isBooked
? 'opacity-60 cursor-not-allowed bg-muted/50 border-muted text-muted-foreground hover:opacity-75'
: ''
}`}
>
{time}
{isBooked && (
<Badge
variant='destructive'
className='absolute -top-1 -right-1 h-2 w-2 p-0'
variant='secondary'
className='absolute -top-1 -right-1 h-2 w-2 p-0 bg-muted border-muted'
/>
)}
</Button>
@@ -162,9 +166,9 @@ export function BookingCalendar() {
{/* Booking Summary */}
{selectedDate && selectedSlot && selectedCourt && (
<div className='bg-blue-50 border border-blue-200 rounded-lg p-4 space-y-2'>
<h4 className='font-medium text-blue-900'>Booking Summary</h4>
<div className='text-sm text-blue-700 space-y-1'>
<div className='bg-primary/5 border border-primary/20 rounded-lg p-4 space-y-2 dark:bg-primary/10 dark:border-primary/30'>
<h4 className='font-medium text-primary dark:text-primary-foreground'>Booking Summary</h4>
<div className='text-sm text-primary/80 dark:text-primary-foreground/80 space-y-1'>
<div className='flex items-center gap-2'>
<CalendarIcon className='h-3 w-3' />
{formatDate(selectedDate)}
+7 -5
View File
@@ -85,16 +85,16 @@ export function RecentBookings() {
</CardHeader>
<CardContent>
{bookings.length === 0 ? (
<div className='text-sm text-gray-500 text-center py-6'>
<div className='text-sm text-muted-foreground text-center py-6'>
No recent bookings yet. Make your first booking!
</div>
) : (
<div className='space-y-3'>
{bookings.map((booking) => (
<div key={booking.id} className='border rounded-lg p-3 space-y-2'>
<div key={booking.id} className='border border-border rounded-lg p-3 space-y-2'>
<div className='flex items-center justify-between'>
<div className='flex items-center gap-2'>
<MapPin className='h-4 w-4 text-blue-600' />
<MapPin className='h-4 w-4 text-primary' />
<span className='font-medium text-sm'>{booking.court.name}</span>
</div>
<Badge variant={booking.status === 'active' ? 'default' : 'secondary'}>
@@ -102,7 +102,7 @@ export function RecentBookings() {
</Badge>
</div>
<div className='flex items-center gap-4 text-xs text-gray-500'>
<div className='flex items-center gap-4 text-xs text-muted-foreground'>
<div className='flex items-center gap-1'>
<Calendar className='h-3 w-3' />
<span>{formatDate(booking.date)}</span>
@@ -115,7 +115,9 @@ export function RecentBookings() {
</div>
</div>
{booking.notes && <p className='text-xs text-gray-600 italic'>{booking.notes}</p>}
{booking.notes && (
<p className='text-xs text-muted-foreground italic'>{booking.notes}</p>
)}
</div>
))}
</div>
+9 -10
View File
@@ -9,6 +9,7 @@ import { Bell, LogOut, Settings, User, Calendar } from 'lucide-react';
import { useToast } from '@/hooks/use-toast';
import { NotificationBell, AnnouncementsModal } from '@/components/notifications/announcements';
import { UserProfile } from '@/components/user/user-profile';
import { ModeToggle } from '@/components/ui/mode-toggle';
interface DashboardHeaderProps {
user: {
@@ -71,24 +72,22 @@ export function DashboardHeader({ user }: DashboardHeaderProps) {
};
return (
<header className='bg-white/80 backdrop-blur-md border-b border-gray-200 sticky top-0 z-50'>
<header className='bg-background/80 backdrop-blur-md border-b border-border sticky top-0 z-50'>
<div className='container mx-auto px-4'>
<div className='flex items-center justify-between h-16'>
<div className='flex items-center space-x-4'>
<div className='flex items-center space-x-2'>
<Calendar className='h-6 w-6 text-blue-600' />
<h1 className='text-xl font-bold text-gray-900'>TT Booking</h1>
<Calendar className='h-6 w-6 text-primary' />
<h1 className='text-xl font-bold text-foreground'>TT Booking</h1>
</div>
{user.role === 'admin' && (
<Badge variant='secondary' className='bg-purple-100 text-purple-800'>
Admin
</Badge>
)}
{user.role === 'admin' && <Badge variant='secondary'>Admin</Badge>}
</div>
<div className='flex items-center space-x-4'>
<NotificationBell unreadCount={unreadCount} onClick={() => setShowAnnouncements(true)} />
<ModeToggle />
{user.role === 'admin' && (
<Button variant='ghost' size='sm' onClick={() => router.push('/admin')}>
<Settings className='h-4 w-4 mr-2' />
@@ -102,8 +101,8 @@ export function DashboardHeader({ user }: DashboardHeaderProps) {
onClick={() => setShowUserProfile(true)}
className='flex items-center space-x-2'
>
<User className='h-4 w-4 text-gray-600' />
<span className='text-sm text-gray-700'>
<User className='h-4 w-4 text-muted-foreground' />
<span className='text-sm text-foreground'>
{user.name && user.surname ? `${user.name} ${user.surname}` : user.email.split('@')[0]}
</span>
</Button>