chore: update
This commit is contained in:
@@ -70,13 +70,13 @@ export default function MobileShiftView({
|
||||
const dateStr = formatDateISO(date);
|
||||
const dayShifts = shifts.filter((s) => s.date === dateStr);
|
||||
const dots: string[] = [];
|
||||
if (dayShifts.some((s) => s.status === "available"))
|
||||
dots.push("bg-amber-400");
|
||||
if (dayShifts.some((s) => s.status === "registered"))
|
||||
dots.push("bg-green-500");
|
||||
if (dayShifts.some((s) => s.status === "approved_leave"))
|
||||
dots.push("bg-purple-400");
|
||||
if (dayShifts.some((s) => s.status === "absent")) dots.push("bg-red-400");
|
||||
// if (dayShifts.some((s) => s.status === "available"))
|
||||
// dots.push("bg-amber-400");
|
||||
// if (dayShifts.some((s) => s.status === "registered"))
|
||||
// dots.push("bg-green-500");
|
||||
// if (dayShifts.some((s) => s.status === "approved_leave"))
|
||||
// dots.push("bg-purple-400");
|
||||
// if (dayShifts.some((s) => s.status === "absent")) dots.push("bg-red-400");
|
||||
return dots;
|
||||
};
|
||||
|
||||
|
||||
@@ -62,13 +62,13 @@ export default function MonthlyCalendar({
|
||||
const getShiftSummary = (date: Date) => {
|
||||
const dateStr = formatDateISO(date);
|
||||
const dayShifts = shifts.filter((s) => s.date === dateStr);
|
||||
const available = dayShifts.filter((s) => s.status === "available").length;
|
||||
const registered = dayShifts.filter(
|
||||
(s) => s.status === "registered",
|
||||
).length;
|
||||
const leave = dayShifts.filter((s) => s.status === "approved_leave").length;
|
||||
const absent = dayShifts.filter((s) => s.status === "absent").length;
|
||||
return { total: dayShifts.length, available, registered, leave, absent };
|
||||
// const available = dayShifts.filter((s) => s.status === "available").length;
|
||||
// const registered = dayShifts.filter(
|
||||
// (s) => s.status === "registered",
|
||||
// ).length;
|
||||
// const leave = dayShifts.filter((s) => s.status === "approved_leave").length;
|
||||
// const absent = dayShifts.filter((s) => s.status === "absent").length;
|
||||
return { total: dayShifts.length };
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -119,7 +119,7 @@ export default function MonthlyCalendar({
|
||||
{date.getDate()}
|
||||
</span>
|
||||
|
||||
{summary.total > 0 && (
|
||||
{/* {summary.total > 0 && (
|
||||
<div className="mt-2 space-y-1">
|
||||
{summary.available > 0 && (
|
||||
<div className="flex items-center gap-1.5">
|
||||
@@ -154,7 +154,7 @@ export default function MonthlyCalendar({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -50,7 +50,7 @@ export default function ShiftCreateModal({
|
||||
}
|
||||
|
||||
createShift({
|
||||
date: new Date(date),
|
||||
date,
|
||||
startTime,
|
||||
endTime,
|
||||
wage,
|
||||
|
||||
@@ -19,12 +19,12 @@ export default function ShiftDetailModal({
|
||||
|
||||
if (!isOpen || !shift) return null;
|
||||
|
||||
const dept = DEPARTMENTS.find((d) => d.id === shift.department);
|
||||
// const dept = DEPARTMENTS.find((d) => d.id === shift.department);
|
||||
const isManager = user?.role === "manager";
|
||||
const isRegistered = user
|
||||
? shift.registeredStaff.some((s) => s.id === user.id)
|
||||
? shift.registeredStaff!.some((s) => s.id === user.id)
|
||||
: false;
|
||||
const isFull = shift.registeredStaff.length >= shift.maxStaff;
|
||||
const isFull = shift.registeredStaff!.length >= shift.maxStaff;
|
||||
|
||||
const handleRegister = () => {
|
||||
if (!user) return;
|
||||
@@ -47,7 +47,7 @@ export default function ShiftDetailModal({
|
||||
setTimeout(onClose, 1200);
|
||||
};
|
||||
|
||||
const handleManagerUnregister = (staffId: number) => {
|
||||
const handleManagerUnregister = (staffId: string) => {
|
||||
unregisterShift(shift.id, staffId);
|
||||
setSuccess("Đã xóa nhân viên khỏi ca.");
|
||||
};
|
||||
@@ -81,12 +81,12 @@ export default function ShiftDetailModal({
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between border-b border-(--color-border-light) px-5 py-4">
|
||||
<div className="flex items-center gap-3">
|
||||
{dept && <i className={`${dept.icon} text-(--color-primary)`}></i>}
|
||||
{/* {dept && <i className={`${dept.icon} text-(--color-primary)`}></i>} */}
|
||||
<div>
|
||||
<h2 className="text-foreground text-base font-bold">
|
||||
Chi tiết ca làm
|
||||
</h2>
|
||||
<p className="text-xs text-(--color-text-muted)">{dept?.name}</p>
|
||||
{/* <p className="text-xs text-(--color-text-muted)">{dept?.name}</p> */}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
@@ -102,13 +102,13 @@ export default function ShiftDetailModal({
|
||||
{/* Body */}
|
||||
<div className="space-y-4 px-5 py-4">
|
||||
{/* Status badge */}
|
||||
<div className="flex items-center gap-2">
|
||||
{/* <div className="flex items-center gap-2">
|
||||
<span
|
||||
className={`rounded-full px-3 py-1 text-xs font-semibold ${statusColor[shift.status]}`}
|
||||
>
|
||||
{statusLabel[shift.status]}
|
||||
</span>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
{/* Shift info grid */}
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
@@ -141,7 +141,7 @@ export default function ShiftDetailModal({
|
||||
Thời lượng
|
||||
</p>
|
||||
<p className="text-foreground mt-1 text-sm font-bold">
|
||||
{shift.durationHours} giờ
|
||||
{""} giờ
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-xl bg-gray-50 p-3">
|
||||
@@ -157,16 +157,16 @@ export default function ShiftDetailModal({
|
||||
{/* Registered staff */}
|
||||
<div>
|
||||
<p className="mb-2 text-xs font-semibold text-(--color-text-secondary)">
|
||||
Nhân viên đã đăng ký ({shift.registeredStaff.length}/
|
||||
Nhân viên đã đăng ký ({shift.registeredStaff!.length}/
|
||||
{shift.maxStaff})
|
||||
</p>
|
||||
{shift.registeredStaff.length === 0 ? (
|
||||
{(shift.registeredStaff && shift.registeredStaff.length === 0) ? (
|
||||
<p className="text-xs text-(--color-text-muted) italic">
|
||||
Chưa có ai đăng ký
|
||||
</p>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{shift.registeredStaff.map((staff) => (
|
||||
{shift.registeredStaff!.map((staff) => (
|
||||
<div
|
||||
key={staff.id}
|
||||
className="flex items-center justify-between rounded-xl bg-gray-50 px-3 py-2"
|
||||
@@ -176,7 +176,7 @@ export default function ShiftDetailModal({
|
||||
<i className="fa-solid fa-user text-[10px] text-(--color-primary)"></i>
|
||||
</div>
|
||||
<span className="text-foreground text-sm font-medium">
|
||||
{staff.name}
|
||||
{staff.staffId}
|
||||
</span>
|
||||
</div>
|
||||
{isManager && (
|
||||
@@ -212,7 +212,7 @@ export default function ShiftDetailModal({
|
||||
|
||||
{/* Footer actions */}
|
||||
<div className="flex gap-2 border-t border-(--color-border-light) px-5 py-4">
|
||||
{!isRegistered &&
|
||||
{/* {!isRegistered &&
|
||||
!isFull &&
|
||||
shift.status !== "approved_leave" &&
|
||||
shift.status !== "absent" && (
|
||||
@@ -224,7 +224,7 @@ export default function ShiftDetailModal({
|
||||
<i className="fa-solid fa-calendar-plus mr-2"></i>
|
||||
Đăng ký ca
|
||||
</button>
|
||||
)}
|
||||
)} */}
|
||||
{isRegistered && (
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -37,7 +37,7 @@ function formatDateISO(d: Date): string {
|
||||
}
|
||||
|
||||
function isToday(d: Date): boolean {
|
||||
const today = Date.now();
|
||||
const today = new Date(Date.now());
|
||||
return (
|
||||
d.getDate() === today.getDate() &&
|
||||
d.getMonth() === today.getMonth() &&
|
||||
@@ -81,7 +81,7 @@ export default function WeeklySchedule({
|
||||
}, [weekDates, getShiftsForDate]);
|
||||
|
||||
const selectedDateStr = useMemo(() => {
|
||||
const inWeek = weekDates.find((d) => formatDateISO(d) === selectedDate);
|
||||
const inWeek = weekDates.find((d) => d === selectedDate);
|
||||
return inWeek ?? weekDates[0] ?? currentDate;
|
||||
}, [selectedDate, weekDates, currentDate]);
|
||||
|
||||
@@ -215,14 +215,14 @@ export default function WeeklySchedule({
|
||||
<th
|
||||
key={i}
|
||||
className={`border-r border-b border-(--color-border-light) px-2 py-3 text-center text-xs ${
|
||||
isToday(date)
|
||||
isToday(new Date(date))
|
||||
? "bg-(--color-primary)/10 font-bold text-(--color-primary)"
|
||||
: "bg-gray-50 font-semibold text-(--color-text-muted)"
|
||||
}`}
|
||||
>
|
||||
<span className="block uppercase">{DAY_LABELS[i]}</span>
|
||||
<span className="mt-0.5 block text-[11px] font-normal">
|
||||
{formatDateShort(date)}
|
||||
{date}
|
||||
</span>
|
||||
</th>
|
||||
))}
|
||||
@@ -242,8 +242,8 @@ export default function WeeklySchedule({
|
||||
</div>
|
||||
</td>
|
||||
{weekDates.map((date, i) => {
|
||||
const dateStr = formatDateISO(date);
|
||||
const shifts = getShiftsForDate(date);
|
||||
const dateStr = date;
|
||||
const shifts = getShiftsForDate(new Date(date));
|
||||
// .filter(
|
||||
// (s) => s.department === dept.id,
|
||||
// );
|
||||
@@ -251,7 +251,7 @@ export default function WeeklySchedule({
|
||||
<td
|
||||
key={i}
|
||||
className={`border-r border-b border-(--color-border-light) p-1.5 align-top ${
|
||||
isToday(date) ? "bg-(--color-primary)/5" : ""
|
||||
isToday(new Date(date)) ? "bg-(--color-primary)/5" : ""
|
||||
}`}
|
||||
>
|
||||
<div className="flex min-h-20 flex-col gap-1">
|
||||
|
||||
+5
-5
@@ -146,7 +146,7 @@ function generateMockShifts(): ShiftEntity[] {
|
||||
|
||||
// Determine registration status
|
||||
const registered: { id: number; name: string }[] = [];
|
||||
let status: ShiftEntity["status"] = "available";
|
||||
// let status: ShiftEntity["status"] = "available";
|
||||
|
||||
// Past shifts (before April 10) are mostly registered
|
||||
if (day < 10) {
|
||||
@@ -180,12 +180,12 @@ function generateMockShifts(): ShiftEntity[] {
|
||||
date: dateStr,
|
||||
startTime: slot.start,
|
||||
endTime: slot.end,
|
||||
durationHours: slot.hours,
|
||||
// durationHours: slot.hours,
|
||||
wage: slot.wage,
|
||||
department: dept,
|
||||
// department: dept,
|
||||
maxStaff: dept === "bar" ? 3 : 2,
|
||||
registeredStaff: registered,
|
||||
status,
|
||||
// registeredStaff: registered,
|
||||
// status,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -2,7 +2,7 @@
|
||||
export type UserRole = "manager" | "staff" | "customer";
|
||||
|
||||
export interface User {
|
||||
id: number;
|
||||
id: string;
|
||||
name: string;
|
||||
role: UserRole;
|
||||
avatar: string | null;
|
||||
@@ -104,6 +104,12 @@ export interface ShiftEntity {
|
||||
registeredStaff?: ShiftRegistrationEntity[];
|
||||
}
|
||||
|
||||
export interface Department {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
export interface MenuItemEntity {
|
||||
id?: string;
|
||||
name: string;
|
||||
|
||||
Reference in New Issue
Block a user