87 lines
2.5 KiB
TypeScript
87 lines
2.5 KiB
TypeScript
import { GridData, ResolvedCell } from "../lib/queries/plan";
|
|
import PlanRangeChips from "./PlanRangeChips";
|
|
|
|
interface Props {
|
|
data: GridData | undefined;
|
|
canEdit: boolean;
|
|
onCellClick: (
|
|
userId: number,
|
|
date: string,
|
|
cell: ResolvedCell | null,
|
|
) => void;
|
|
}
|
|
|
|
const CZECH_WEEKDAYS = ["Ne", "Po", "Út", "St", "Čt", "Pá", "So"];
|
|
|
|
function eachDay(from: string, to: string): string[] {
|
|
const out: string[] = [];
|
|
const a = new Date(from + "T00:00:00.000Z");
|
|
const b = new Date(to + "T00:00:00.000Z");
|
|
for (let d = new Date(a); d <= b; d.setUTCDate(d.getUTCDate() + 1)) {
|
|
out.push(d.toISOString().slice(0, 10));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function czechWeekday(dateStr: string): string {
|
|
return CZECH_WEEKDAYS[new Date(dateStr + "T00:00:00.000Z").getUTCDay()];
|
|
}
|
|
|
|
function isWeekend(dateStr: string): boolean {
|
|
const day = new Date(dateStr + "T00:00:00.000Z").getUTCDay();
|
|
return day === 0 || day === 6;
|
|
}
|
|
|
|
export default function PlanGrid({ data, canEdit, onCellClick }: Props) {
|
|
if (!data)
|
|
return (
|
|
<div className="admin-loading">
|
|
<div className="admin-spinner" />
|
|
</div>
|
|
);
|
|
const days = eachDay(data.date_from, data.date_to);
|
|
const users = data.users;
|
|
|
|
return (
|
|
<div className="plan-grid-wrap">
|
|
<table className="plan-grid">
|
|
<thead>
|
|
<tr>
|
|
<th className="plan-grid-date-col">Datum</th>
|
|
{users.map((u) => (
|
|
<th key={u.id}>{u.full_name}</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{days.map((date) => (
|
|
<tr
|
|
key={date}
|
|
className={isWeekend(date) ? "plan-grid-weekend" : ""}
|
|
>
|
|
<td className="plan-grid-date-col">
|
|
{czechWeekday(date)} {date.slice(8)}.{date.slice(5, 7)}.
|
|
</td>
|
|
{users.map((u) => {
|
|
const cell = data.cells[u.id]?.[date] ?? null;
|
|
const cls = `plan-cell${canEdit ? "" : " plan-cell--readonly"}`;
|
|
return (
|
|
<td key={u.id}>
|
|
<button
|
|
type="button"
|
|
className={cls}
|
|
onClick={() => onCellClick(u.id, date, cell)}
|
|
>
|
|
<PlanRangeChips cell={cell} readonly={!canEdit} />
|
|
</button>
|
|
</td>
|
|
);
|
|
})}
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
}
|