chore: update
This commit is contained in:
@@ -4,32 +4,6 @@ import type { ShiftEntity } from "@/lib/types";
|
|||||||
|
|
||||||
import type { ShiftCardProps } from "./ShiftCard.types";
|
import type { ShiftCardProps } from "./ShiftCard.types";
|
||||||
|
|
||||||
const STATUS_STYLES: Record<
|
|
||||||
ShiftEntity["status"],
|
|
||||||
{ bg: string; text: string; label: string }
|
|
||||||
> = {
|
|
||||||
available: {
|
|
||||||
bg: "bg-blue-50 border-blue-200",
|
|
||||||
text: "text-blue-700",
|
|
||||||
label: "Còn trống",
|
|
||||||
},
|
|
||||||
registered: {
|
|
||||||
bg: "bg-blue-100 border-blue-400",
|
|
||||||
text: "text-blue-900",
|
|
||||||
label: "Đã đăng ký",
|
|
||||||
},
|
|
||||||
approved_leave: {
|
|
||||||
bg: "bg-purple-50 border-purple-300",
|
|
||||||
text: "text-purple-700",
|
|
||||||
label: "Nghỉ phép",
|
|
||||||
},
|
|
||||||
absent: {
|
|
||||||
bg: "bg-red-50 border-red-300",
|
|
||||||
text: "text-red-700",
|
|
||||||
label: "Vắng mặt",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function formatWage(wage: number): string {
|
function formatWage(wage: number): string {
|
||||||
if (wage >= 1000) {
|
if (wage >= 1000) {
|
||||||
return `${(wage / 1000).toFixed(0)}k`;
|
return `${(wage / 1000).toFixed(0)}k`;
|
||||||
@@ -42,20 +16,20 @@ export default function ShiftCard({
|
|||||||
compact = false,
|
compact = false,
|
||||||
onClick,
|
onClick,
|
||||||
}: ShiftCardProps) {
|
}: ShiftCardProps) {
|
||||||
const style = STATUS_STYLES[shift.status];
|
console.log(shift);
|
||||||
|
|
||||||
if (compact) {
|
if (compact) {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => onClick?.(shift)}
|
onClick={() => onClick?.(shift)}
|
||||||
className={`w-full cursor-pointer rounded-lg border px-2 py-1.5 text-left text-xs transition-shadow hover:shadow-sm ${style.bg} ${style.text}`}
|
className={`w-full cursor-pointer rounded-lg border px-2 py-1.5 text-left text-xs transition-shadow hover:shadow-sm `}
|
||||||
>
|
>
|
||||||
<p className="font-semibold">
|
<p className="font-semibold">
|
||||||
{shift.startTime} – {shift.endTime}
|
{shift.startTime} – {shift.endTime}
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-0.5 opacity-75">
|
<p className="mt-0.5 opacity-75">
|
||||||
{shift.durationHours}h · {formatWage(shift.wage)}
|
{}h · {formatWage(shift.wage)}
|
||||||
</p>
|
</p>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
@@ -65,7 +39,7 @@ export default function ShiftCard({
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => onClick?.(shift)}
|
onClick={() => onClick?.(shift)}
|
||||||
className={`w-full cursor-pointer rounded-xl border p-3 text-left transition-shadow hover:shadow-md ${style.bg} ${style.text}`}
|
className={`w-full cursor-pointer rounded-xl border p-3 text-left transition-shadow hover:shadow-md `}
|
||||||
>
|
>
|
||||||
<div className="flex items-start justify-between">
|
<div className="flex items-start justify-between">
|
||||||
<div>
|
<div>
|
||||||
@@ -73,25 +47,26 @@ export default function ShiftCard({
|
|||||||
{shift.startTime} – {shift.endTime}
|
{shift.startTime} – {shift.endTime}
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-xs opacity-75">
|
<p className="mt-1 text-xs opacity-75">
|
||||||
{shift.durationHours}h · {formatWage(shift.wage)} VND
|
{}h · {formatWage(shift.wage)} VND
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
className={`rounded-full px-2 py-0.5 text-[10px] font-semibold ${
|
className={`rounded-full px-2 py-0.5 text-[10px] font-semibold ${
|
||||||
shift.status === "available"
|
// shift.status === "available"
|
||||||
? "bg-blue-200 text-blue-800"
|
// ? "bg-blue-200 text-blue-800"
|
||||||
: shift.status === "registered"
|
// : shift.status === "registered"
|
||||||
? "bg-blue-300 text-blue-900"
|
// ? "bg-blue-300 text-blue-900"
|
||||||
: shift.status === "approved_leave"
|
// : shift.status === "approved_leave"
|
||||||
? "bg-purple-200 text-purple-800"
|
// ? "bg-purple-200 text-purple-800"
|
||||||
: "bg-red-200 text-red-800"
|
// : "bg-red-200 text-red-800"
|
||||||
|
""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{style.label}
|
{/* {style.label} */}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{shift.registeredStaff.length > 0 && (
|
{(shift.registeredStaff && shift.registeredStaff.length > 0) && (
|
||||||
<div className="mt-2 border-t border-current/10 pt-2">
|
<div className="mt-2 border-t border-current/10 pt-2">
|
||||||
<p className="text-[10px] font-medium tracking-wide uppercase opacity-60">
|
<p className="text-[10px] font-medium tracking-wide uppercase opacity-60">
|
||||||
Nhân viên ({shift.registeredStaff.length}/{shift.maxStaff})
|
Nhân viên ({shift.registeredStaff.length}/{shift.maxStaff})
|
||||||
@@ -102,18 +77,18 @@ export default function ShiftCard({
|
|||||||
key={s.id}
|
key={s.id}
|
||||||
className="rounded-full bg-white/60 px-2 py-0.5 text-[10px] font-medium"
|
className="rounded-full bg-white/60 px-2 py-0.5 text-[10px] font-medium"
|
||||||
>
|
>
|
||||||
{s.name}
|
{s.staffId}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{shift.status === "available" && shift.registeredStaff.length === 0 && (
|
{/* {shift.status === "available" && shift.registeredStaff.length === 0 && (
|
||||||
<p className="mt-2 text-[10px] italic opacity-50">
|
<p className="mt-2 text-[10px] italic opacity-50">
|
||||||
{shift.maxStaff} vị trí còn trống
|
{shift.maxStaff} vị trí còn trống
|
||||||
</p>
|
</p>
|
||||||
)}
|
)} */}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,9 +218,7 @@ export default function MobileShiftView({
|
|||||||
) : (
|
) : (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{DEPARTMENTS.map((dept) => {
|
{DEPARTMENTS.map((dept) => {
|
||||||
const deptShifts = selectedShifts.filter(
|
const deptShifts = selectedShifts;
|
||||||
(s) => s.department === dept.id,
|
|
||||||
);
|
|
||||||
if (deptShifts.length === 0) return null;
|
if (deptShifts.length === 0) return null;
|
||||||
return (
|
return (
|
||||||
<div key={dept.id}>
|
<div key={dept.id}>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default function WeeklySchedule({
|
|||||||
const map: Record<string, string[]> = {};
|
const map: Record<string, string[]> = {};
|
||||||
weekDates.forEach((date) => {
|
weekDates.forEach((date) => {
|
||||||
const dateStr = formatDateISO(date);
|
const dateStr = formatDateISO(date);
|
||||||
const dayShifts = getShiftsForDate(dateStr);
|
const dayShifts = getShiftsForDate(date);
|
||||||
const dots: string[] = [];
|
const dots: string[] = [];
|
||||||
if (dayShifts.some((s) => s.status === "available"))
|
if (dayShifts.some((s) => s.status === "available"))
|
||||||
dots.push("bg-sky-300");
|
dots.push("bg-sky-300");
|
||||||
@@ -160,9 +160,10 @@ export default function WeeklySchedule({
|
|||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{DEPARTMENTS.map((dept) => {
|
{DEPARTMENTS.map((dept) => {
|
||||||
const deptShifts = getShiftsForDate(selectedDateStr).filter(
|
const deptShifts = getShiftsForDate(selectedDateObj)
|
||||||
(s) => s.department === dept.id,
|
// .filter(
|
||||||
);
|
// (s) => s.department === dept.id,
|
||||||
|
// );
|
||||||
if (deptShifts.length === 0 && !onCreateShift) return null;
|
if (deptShifts.length === 0 && !onCreateShift) return null;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -247,9 +248,10 @@ export default function WeeklySchedule({
|
|||||||
</td>
|
</td>
|
||||||
{weekDates.map((date, i) => {
|
{weekDates.map((date, i) => {
|
||||||
const dateStr = formatDateISO(date);
|
const dateStr = formatDateISO(date);
|
||||||
const shifts = getShiftsForDate(dateStr).filter(
|
const shifts = getShiftsForDate(date)
|
||||||
(s) => s.department === dept.id,
|
// .filter(
|
||||||
);
|
// (s) => s.department === dept.id,
|
||||||
|
// );
|
||||||
return (
|
return (
|
||||||
<td
|
<td
|
||||||
key={i}
|
key={i}
|
||||||
|
|||||||
@@ -208,7 +208,9 @@ export function ShiftProvider({ children }: { children: ReactNode }) {
|
|||||||
|
|
||||||
const getShiftsForDate = useCallback(
|
const getShiftsForDate = useCallback(
|
||||||
(date: Date): ShiftEntity[] => {
|
(date: Date): ShiftEntity[] => {
|
||||||
return shifts.filter((s) => s.date === date);
|
return shifts.filter((s) => {
|
||||||
|
return new Date(s.date).getDate() === date.getDate();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[shifts],
|
[shifts],
|
||||||
);
|
);
|
||||||
|
|||||||
+1
-9
@@ -96,7 +96,7 @@ export interface ShiftRegistrationEntity {
|
|||||||
|
|
||||||
export interface ShiftEntity {
|
export interface ShiftEntity {
|
||||||
id: string;
|
id: string;
|
||||||
date: Date;
|
date: string;
|
||||||
startTime: string;
|
startTime: string;
|
||||||
endTime: string;
|
endTime: string;
|
||||||
wage: number;
|
wage: number;
|
||||||
@@ -104,12 +104,6 @@ export interface ShiftEntity {
|
|||||||
registeredStaff?: ShiftRegistrationEntity[];
|
registeredStaff?: ShiftRegistrationEntity[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Department {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
icon: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MenuItemEntity {
|
export interface MenuItemEntity {
|
||||||
id?: string;
|
id?: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -120,8 +114,6 @@ export interface MenuItemEntity {
|
|||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShiftEntity {}
|
|
||||||
|
|
||||||
export interface EateryEntity {
|
export interface EateryEntity {
|
||||||
id: string;
|
id: string;
|
||||||
ownerId: string;
|
ownerId: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user