95 lines
3.7 KiB
TypeScript
95 lines
3.7 KiB
TypeScript
import React from 'react';
|
||
import {
|
||
WEEK_DAYS,
|
||
PERIODS,
|
||
getTodayDayOfWeek,
|
||
classAccentColor,
|
||
buildTimetableMap,
|
||
type ActiveClassItem,
|
||
} from './learningUtils';
|
||
|
||
interface LearningTimetableProps {
|
||
classes: ActiveClassItem[];
|
||
onOpenClass: (cls: ActiveClassItem) => void;
|
||
}
|
||
|
||
export const LearningTimetable: React.FC<LearningTimetableProps> = ({ classes, onOpenClass }) => {
|
||
const today = getTodayDayOfWeek();
|
||
const cellMap = buildTimetableMap(classes);
|
||
|
||
return (
|
||
<div className="learning-tkb-wrap">
|
||
<div className="learning-tkb-scroll">
|
||
<table className="learning-tkb">
|
||
<thead>
|
||
<tr>
|
||
<th className="learning-tkb-corner">Ca</th>
|
||
{WEEK_DAYS.map((label, day) => (
|
||
<th
|
||
key={label}
|
||
className={`learning-tkb-dayhead${day === today ? ' learning-tkb-dayhead--today' : ''}`}
|
||
>
|
||
<span>{label}</span>
|
||
{day === today && <em>Hôm nay</em>}
|
||
</th>
|
||
))}
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{PERIODS.map(period => (
|
||
<tr key={period}>
|
||
<td className="learning-tkb-period">
|
||
<span className="learning-tkb-period-num">Ca {period}</span>
|
||
</td>
|
||
{WEEK_DAYS.map((_, day) => {
|
||
const entries = cellMap.get(`${day}-${period}`) || [];
|
||
const isToday = day === today;
|
||
return (
|
||
<td
|
||
key={`${day}-${period}`}
|
||
className={`learning-tkb-cell${isToday ? ' learning-tkb-cell--today' : ''}${
|
||
entries.length ? ' learning-tkb-cell--filled' : ''
|
||
}`}
|
||
>
|
||
{entries.length === 0 ? (
|
||
<span className="learning-tkb-empty">—</span>
|
||
) : (
|
||
<div className="learning-tkb-blocks">
|
||
{entries.map(({ cls, schedule }) => {
|
||
const accent = classAccentColor(cls.classCode);
|
||
return (
|
||
<button
|
||
key={`${cls.rkId}-${schedule.id ?? schedule.dayOfWeek}`}
|
||
type="button"
|
||
className={`learning-tkb-block${schedule.isActive === false ? ' learning-tkb-block--inactive' : ''}`}
|
||
style={{ '--tkb-accent': accent } as React.CSSProperties}
|
||
onClick={() => onOpenClass(cls)}
|
||
title={`${cls.name}\n${schedule.courseName || ''}\n${schedule.startTime}-${schedule.endTime}`}
|
||
>
|
||
<span className="learning-tkb-block-code">{cls.classCode}</span>
|
||
{schedule.courseName && (
|
||
<span className="learning-tkb-block-course">{schedule.courseName}</span>
|
||
)}
|
||
{(schedule.startTime || schedule.endTime) && (
|
||
<span className="learning-tkb-block-time">
|
||
{schedule.startTime}
|
||
{schedule.endTime ? `–${schedule.endTime}` : ''}
|
||
</span>
|
||
)}
|
||
</button>
|
||
);
|
||
})}
|
||
</div>
|
||
)}
|
||
</td>
|
||
);
|
||
})}
|
||
</tr>
|
||
))}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|