chore: update
This commit is contained in:
@@ -44,9 +44,7 @@ export default function MobileShiftView({
|
||||
onShiftClick,
|
||||
}: MobileShiftViewProps) {
|
||||
const { currentDate, shifts, goToNextMonth, goToPrevMonth } = useShift();
|
||||
const [selectedDate, setSelectedDate] = useState<string>(
|
||||
formatDateISO(new Date(2026, 3, 10)),
|
||||
);
|
||||
const [selectedDate, setSelectedDate] = useState<Date>(new Date(2026, 3, 10));
|
||||
|
||||
const calendarDays = useMemo(() => {
|
||||
const year = currentDate.getFullYear();
|
||||
@@ -67,8 +65,7 @@ export default function MobileShiftView({
|
||||
}, [currentDate]);
|
||||
|
||||
const getDotColors = (date: Date): string[] => {
|
||||
const dateStr = formatDateISO(date);
|
||||
const dayShifts = shifts.filter((s) => s.date === dateStr);
|
||||
const dayShifts = shifts.filter((s) => s.date.getDate() === date.getDate());
|
||||
const dots: string[] = [];
|
||||
// if (dayShifts.some((s) => s.status === "available"))
|
||||
// dots.push("bg-amber-400");
|
||||
@@ -81,7 +78,7 @@ export default function MobileShiftView({
|
||||
};
|
||||
|
||||
const selectedShifts = useMemo(() => {
|
||||
return shifts.filter((s) => s.date === selectedDate);
|
||||
return shifts.filter((s) => s.date.getDate() === selectedDate.getDate());
|
||||
}, [shifts, selectedDate]);
|
||||
|
||||
const selectedDateObj = new Date(selectedDate + "T00:00:00");
|
||||
@@ -133,16 +130,15 @@ export default function MobileShiftView({
|
||||
return <div key={`empty-${i}`} className="p-1" />;
|
||||
}
|
||||
|
||||
const dateStr = formatDateISO(date);
|
||||
const today = isToday(date);
|
||||
const selected = dateStr === selectedDate;
|
||||
const selected = date === selectedDate;
|
||||
const dots = getDotColors(date);
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
key={i}
|
||||
onClick={() => setSelectedDate(dateStr)}
|
||||
onClick={() => setSelectedDate(date)}
|
||||
className={`flex cursor-pointer flex-col items-center border-none bg-transparent p-1 transition ${
|
||||
selected ? "rounded-lg bg-(--color-primary)/10" : ""
|
||||
}`}
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { MonthlyCalendarProps } from "./ShiftSchedule.types";
|
||||
|
||||
const DAY_HEADERS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
||||
|
||||
function formatDateISO(d: Date): string {
|
||||
export function formatDateISO(d: Date): string {
|
||||
const y = d.getFullYear();
|
||||
const m = (d.getMonth() + 1).toString().padStart(2, "0");
|
||||
const day = d.getDate().toString().padStart(2, "0");
|
||||
@@ -60,8 +60,7 @@ export default function MonthlyCalendar({
|
||||
}, [currentDate]);
|
||||
|
||||
const getShiftSummary = (date: Date) => {
|
||||
const dateStr = formatDateISO(date);
|
||||
const dayShifts = shifts.filter((s) => s.date === dateStr);
|
||||
const dayShifts = shifts.filter((s) => s.date.getDate() === date.getDate());
|
||||
// const available = dayShifts.filter((s) => s.status === "available").length;
|
||||
// const registered = dayShifts.filter(
|
||||
// (s) => s.status === "registered",
|
||||
@@ -104,7 +103,7 @@ export default function MonthlyCalendar({
|
||||
<button
|
||||
type="button"
|
||||
key={i}
|
||||
onClick={() => onDateSelect?.(formatDateISO(date))}
|
||||
onClick={() => onDateSelect?.(date)}
|
||||
className={`min-h-25 cursor-pointer border-r border-b border-(--color-border-light) bg-transparent p-2 text-left transition hover:bg-gray-50 ${
|
||||
today ? "bg-(--color-primary)/5" : ""
|
||||
}`}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { DEPARTMENTS } from "@/lib/constants";
|
||||
import { useShift } from "@/lib/shift-context";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { formatDateISO } from "./MonthlyCalendar";
|
||||
import type { ShiftCreateModalProps } from "./ShiftSchedule.types";
|
||||
|
||||
export default function ShiftCreateModal({
|
||||
@@ -13,7 +14,7 @@ export default function ShiftCreateModal({
|
||||
}: ShiftCreateModalProps) {
|
||||
const { createShift } = useShift();
|
||||
|
||||
const [date, setDate] = useState(defaultDate ?? "2026-04-10");
|
||||
const [date, setDate] = useState<Date>(new Date(defaultDate ?? "2026-04-10"));
|
||||
const [startTime, setStartTime] = useState("08:00");
|
||||
const [endTime, setEndTime] = useState("12:00");
|
||||
const [department, setDepartment] = useState("bar");
|
||||
@@ -23,7 +24,7 @@ export default function ShiftCreateModal({
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
setDate(defaultDate ?? "2026-04-10");
|
||||
setDate(new Date(defaultDate ?? "2026-04-10"));
|
||||
}
|
||||
}, [defaultDate, isOpen]);
|
||||
|
||||
@@ -97,8 +98,8 @@ export default function ShiftCreateModal({
|
||||
<input
|
||||
title="Date"
|
||||
type="date"
|
||||
value={date}
|
||||
onChange={(e) => setDate(e.target.value)}
|
||||
value={formatDateISO(date)}
|
||||
onChange={(e) => setDate(new Date(e.target.value))}
|
||||
className="text-foreground w-full rounded-xl border border-(--color-border-light) px-3 py-2.5 text-sm transition outline-none focus:border-(--color-primary) focus:ring-1 focus:ring-(--color-primary)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -2,13 +2,13 @@ import type { ShiftEntity } from "@/lib/types";
|
||||
|
||||
export interface WeeklyScheduleProps {
|
||||
onShiftClick: (shift: ShiftEntity) => void;
|
||||
onCreateShift?: (date: string) => void;
|
||||
onCreateShift?: (date: Date) => void;
|
||||
mobileCalendarHeader?: boolean;
|
||||
}
|
||||
|
||||
export interface MonthlyCalendarProps {
|
||||
onShiftClick: (shift: ShiftEntity) => void;
|
||||
onDateSelect?: (date: string) => void;
|
||||
onDateSelect?: (date: Date) => void;
|
||||
}
|
||||
|
||||
export interface MobileShiftViewProps {
|
||||
|
||||
@@ -59,7 +59,7 @@ export default function WeeklySchedule({
|
||||
} = useShift();
|
||||
const weekDates = getWeekDates();
|
||||
|
||||
const [selectedDate, setSelectedDate] = useState<string>(
|
||||
const [selectedDate, setSelectedDate] = useState<Date>(
|
||||
weekDates[0] ?? currentDate,
|
||||
);
|
||||
|
||||
@@ -75,7 +75,7 @@ export default function WeeklySchedule({
|
||||
// dots.push("bg-purple-400");
|
||||
// if (dayShifts.some((s) => s.status === "absent"))
|
||||
// dots.push("bg-rose-400");
|
||||
map[date] = dots.slice(0, 3);
|
||||
map[date.toISOString()] = dots.slice(0, 3);
|
||||
});
|
||||
return map;
|
||||
}, [weekDates, getShiftsForDate]);
|
||||
@@ -113,7 +113,7 @@ export default function WeeklySchedule({
|
||||
<div className="grid grid-cols-7 gap-1">
|
||||
{weekDates.map((date, i) => {
|
||||
const active = date === selectedDateStr;
|
||||
const dots = statusDotsByDate[date] ?? [];
|
||||
const dots = statusDotsByDate[date.toISOString()] ?? [];
|
||||
return (
|
||||
<button
|
||||
key={i}
|
||||
@@ -222,7 +222,7 @@ export default function WeeklySchedule({
|
||||
>
|
||||
<span className="block uppercase">{DAY_LABELS[i]}</span>
|
||||
<span className="mt-0.5 block text-[11px] font-normal">
|
||||
{date}
|
||||
{date.toISOString()}
|
||||
</span>
|
||||
</th>
|
||||
))}
|
||||
|
||||
+6
-6
@@ -155,29 +155,29 @@ function generateMockShifts(): ShiftEntity[] {
|
||||
if (shiftCounter % 7 === 0) {
|
||||
registered.push(staffPool[(staffIdx + 1) % staffPool.length]);
|
||||
}
|
||||
status = "registered";
|
||||
// status = "registered";
|
||||
// Some past shifts have leave/absent
|
||||
if (shiftCounter % 11 === 0) status = "approved_leave";
|
||||
if (shiftCounter % 13 === 0) status = "absent";
|
||||
// if (shiftCounter % 11 === 0) status = "approved_leave";
|
||||
// if (shiftCounter % 13 === 0) status = "absent";
|
||||
}
|
||||
// Current week (April 6-12): mix of registered and available
|
||||
else if (day >= 10 && day <= 12) {
|
||||
if (shiftCounter % 3 === 0) {
|
||||
registered.push(staffPool[shiftCounter % staffPool.length]);
|
||||
status = "registered";
|
||||
// status = "registered";
|
||||
}
|
||||
}
|
||||
// Future shifts: mostly available, some registered
|
||||
else {
|
||||
if (shiftCounter % 5 === 0) {
|
||||
registered.push(staffPool[shiftCounter % staffPool.length]);
|
||||
status = "registered";
|
||||
// status = "registered";
|
||||
}
|
||||
}
|
||||
|
||||
shifts.push({
|
||||
id: "shiftId",
|
||||
date: dateStr,
|
||||
date: new Date(dateStr),
|
||||
startTime: slot.start,
|
||||
endTime: slot.end,
|
||||
// durationHours: slot.hours,
|
||||
|
||||
@@ -50,9 +50,9 @@ interface ShiftContextType {
|
||||
// Helpers
|
||||
getShiftsForDate: (date: Date) => ShiftEntity[];
|
||||
getShiftsForWeek: (weekStart: Date) => ShiftEntity[];
|
||||
getWeekDates: () => string[];
|
||||
getWeekDates: () => Date[];
|
||||
hasConflict: (
|
||||
date: string,
|
||||
date: Date,
|
||||
startTime: string,
|
||||
endTime: string,
|
||||
staffId: string,
|
||||
@@ -195,12 +195,12 @@ export function ShiftProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
// ── Query helpers ───────────────────────────────────────────────────────
|
||||
|
||||
const getWeekDates = useCallback((): string[] => {
|
||||
const getWeekDates = useCallback((): Date[] => {
|
||||
const monday = getMonday(currentDate);
|
||||
return Array.from({ length: 7 }, (_, i) => {
|
||||
const d = new Date(monday);
|
||||
d.setDate(monday.getDate() + i);
|
||||
return d.toISOString();
|
||||
return d;
|
||||
});
|
||||
}, [currentDate]);
|
||||
|
||||
@@ -218,7 +218,7 @@ export function ShiftProvider({ children }: { children: ReactNode }) {
|
||||
const dates = Array.from({ length: 7 }, (_, i) => {
|
||||
const d = new Date(weekStart);
|
||||
d.setDate(weekStart.getDate() + i);
|
||||
return d.toISOString();
|
||||
return d;
|
||||
});
|
||||
return shifts.filter((s) => dates.includes(s.date));
|
||||
},
|
||||
@@ -227,7 +227,7 @@ export function ShiftProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
const hasConflict = useCallback(
|
||||
(
|
||||
date: string,
|
||||
date: Date,
|
||||
startTime: string,
|
||||
endTime: string,
|
||||
staffId: string,
|
||||
@@ -247,7 +247,9 @@ export function ShiftProvider({ children }: { children: ReactNode }) {
|
||||
const getWeeklyBudget = useCallback((): number => {
|
||||
const weekDates = getWeekDates();
|
||||
return shifts
|
||||
.filter((s) => weekDates.includes(s.date) && s.registeredStaff!.length > 0)
|
||||
.filter(
|
||||
(s) => weekDates.includes(s.date) && s.registeredStaff!.length > 0,
|
||||
)
|
||||
.reduce((sum, s) => sum + s.wage * s.registeredStaff!.length, 0);
|
||||
}, [shifts, getWeekDates]);
|
||||
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ export interface ShiftRegistrationEntity {
|
||||
|
||||
export interface ShiftEntity {
|
||||
id: string;
|
||||
date: string;
|
||||
date: Date;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
wage: number;
|
||||
|
||||
Reference in New Issue
Block a user