diff --git a/apps/web/src/common/components/ui/calendar.tsx b/apps/web/src/common/components/ui/calendar.tsx index 0e35cbba..b6f3cfe1 100644 --- a/apps/web/src/common/components/ui/calendar.tsx +++ b/apps/web/src/common/components/ui/calendar.tsx @@ -19,43 +19,42 @@ function Calendar({ showOutsideDays={showOutsideDays} className={cn("p-3", className)} classNames={{ - months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0", + months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0 relative", month: "space-y-4", - caption: "flex justify-center pt-1 relative items-center", + month_caption: "flex justify-center pt-1 relative items-center h-9", caption_label: "text-sm font-medium", - nav: "space-x-1 flex items-center", - nav_button: cn( + nav: "flex items-center", + button_previous: cn( buttonVariants({ variant: "outline" }), - "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100" + "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute left-1 top-1 z-10" ), - nav_button_previous: "absolute left-1", - nav_button_next: "absolute right-1", - table: "w-full border-collapse space-y-1", - head_row: "flex", - head_cell: - "text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]", - row: "flex w-full mt-2", - cell: cn( - "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md", - props.mode === "range" - ? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" - : "[&:has([aria-selected])]:rounded-md" + button_next: cn( + buttonVariants({ variant: "outline" }), + "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute right-1 top-1 z-10" ), - day: cn( + month_grid: "w-full border-collapse space-y-1", + weekdays: "flex", + weekday: + "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]", + week: "flex w-full mt-2", + day: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20", + day_button: cn( buttonVariants({ variant: "ghost" }), - "h-8 w-8 p-0 font-normal aria-selected:opacity-100" + "h-9 w-9 p-0 font-normal aria-selected:opacity-100 hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground" ), - day_range_start: "day-range-start", - day_range_end: "day-range-end", - day_selected: + selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground", - day_today: "bg-accent text-accent-foreground", - day_outside: - "day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground", - day_disabled: "text-muted-foreground opacity-50", - day_range_middle: + today: "bg-accent text-accent-foreground", + outside: + "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30", + disabled: "text-muted-foreground opacity-50", + range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground", - day_hidden: "invisible", + hidden: "invisible", + dropdowns: "flex gap-1", + dropdown: "flex items-center", + dropdown_root: "text-sm font-medium focus:bg-accent p-1 rounded-md", + chevron: "fill-primary", ...classNames, }} components={{ diff --git a/apps/web/src/features/dashboard/ClientDashboard.tsx b/apps/web/src/features/dashboard/ClientDashboard.tsx index 98b40434..6ae459f2 100644 --- a/apps/web/src/features/dashboard/ClientDashboard.tsx +++ b/apps/web/src/features/dashboard/ClientDashboard.tsx @@ -1,9 +1,414 @@ - +import { useState, useMemo } from 'react'; +import { useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; +import { + useListShifts, + useListInvoices, + useListStaff, + useGetBusinessesByUserId, + useGetOrdersByBusinessId +} from '@/dataconnect-generated/react'; +import { dataConnect } from '@/features/auth/firebase'; +import type { RootState } from '@/store/store'; +import DashboardLayout from '@/features/layouts/DashboardLayout'; +import { Card, CardContent, CardHeader, CardTitle } from '@/common/components/ui/card'; +import { Button } from '@/common/components/ui/button'; +import { Badge } from '@/common/components/ui/badge'; +import { Calendar } from '@/common/components/ui/calendar'; +import { + Plus, + FileText, + Users, + TrendingUp, + Clock, + Calendar as CalendarIcon, + ChevronRight, + Star, + MapPin, + ArrowUpRight +} from 'lucide-react'; +import { format, startOfMonth, endOfMonth, isSameDay, parseISO } from 'date-fns'; +import CreateOrderDialog from '@/features/operations/orders/components/CreateOrderDialog'; +import { motion } from 'framer-motion'; +import type { Variants } from 'framer-motion'; const ClientDashboard = () => { - return ( -
+ {todayShifts.length} active {todayShifts.length === 1 ? 'shift' : 'shifts'} today +
++ For {format(today, 'MMMM yyyy')} +
++ Scheduled this month +
++ Currently on shift +
++ {shift.order?.eventName || 'Untitled Event'} +
++ {shift.startTime ? format(new Date(shift.startTime), 'h:mm a') : ''} - {shift.endTime ? format(new Date(shift.endTime), 'h:mm a') : ''} +
++ {shift.location} +
+No shifts scheduled
++ Select a different date or create a new order +
+{worker.fullName}
+