fix
All checks were successful
Deploy on Master Change / deploy (push) Successful in 1m17s

This commit is contained in:
2026-07-13 11:00:17 +07:00
parent 06f2edb195
commit bad51585db
7 changed files with 125 additions and 47 deletions

View File

@@ -53,11 +53,15 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');
const [listSearchQuery, setListSearchQuery] = useState('');
// Detect if this is a class workspace (vs exam) to use API storage
const classRkId = useMemo(() => {
// Parse workspace type and ID for API storage
const workspaceInfo = useMemo(() => {
if (workspaceId.startsWith('class-')) {
const n = Number(workspaceId.replace('class-', ''));
return isNaN(n) ? null : n;
return isNaN(n) ? null : { kind: 'class' as const, id: n };
}
if (workspaceId.startsWith('exam-')) {
const n = Number(workspaceId.replace('exam-', ''));
return isNaN(n) ? null : { kind: 'exam' as const, id: n };
}
return null;
}, [workspaceId]);
@@ -103,58 +107,44 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
}
}
if (classRkId !== null) {
// Load layout từ server theo lớp
apiSeatingLayout.get(classRkId).then((json) => {
if (workspaceInfo !== null) {
const getter = workspaceInfo.kind === 'class'
? apiSeatingLayout.getClass(workspaceInfo.id)
: apiSeatingLayout.getExam(workspaceInfo.id);
getter.then((json) => {
if (json) {
try {
setLayout(JSON.parse(json));
} catch {
setLayout(null);
}
try { setLayout(JSON.parse(json)); } catch { setLayout(null); }
} else {
setLayout(null);
}
}).catch(() => setLayout(null));
} else {
// Exam rooms — vẫn dùng localStorage
const storedLayout = localStorage.getItem(`sc_seating_layout_${workspaceId}`);
if (storedLayout) {
try {
setLayout(JSON.parse(storedLayout));
} catch {
setLayout(null);
}
}
setLayout(null);
}
}, [workspaceId, classRkId]);
}, [workspaceId, workspaceInfo]);
// Save layout — debounce API calls, fallback to localStorage for exam rooms
// Save layout — debounce để tránh gọi API quá nhiều khi kéo thả nhanh
const saveLayout = (newLayout: SeatingLayout | null) => {
setLayout(newLayout);
if (!workspaceInfo) return;
if (classRkId !== null) {
// Debounce để tránh gọi API quá nhiều khi kéo thả nhanh
if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
saveTimerRef.current = setTimeout(() => {
if (newLayout) {
apiSeatingLayout.save(classRkId, JSON.stringify(newLayout)).catch(() => {});
setSaveNotice('Đã lưu sơ đồ chỗ ngồi!');
} else {
apiSeatingLayout.delete(classRkId).catch(() => {});
setSaveNotice('Đã xóa sơ đồ chỗ ngồi!');
}
}, 600);
} else {
// Exam rooms — localStorage
if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
saveTimerRef.current = setTimeout(() => {
if (newLayout) {
localStorage.setItem(`sc_seating_layout_${workspaceId}`, JSON.stringify(newLayout));
setSaveNotice('Đã lưu thay đổi sơ đồ chỗ ngồi!');
const json = JSON.stringify(newLayout);
const saver = workspaceInfo.kind === 'class'
? apiSeatingLayout.saveClass(workspaceInfo.id, json)
: apiSeatingLayout.saveExam(workspaceInfo.id, json);
saver.catch(() => {});
setSaveNotice('Đã lưu sơ đồ chỗ ngồi!');
} else {
localStorage.removeItem(`sc_seating_layout_${workspaceId}`);
const deleter = workspaceInfo.kind === 'class'
? apiSeatingLayout.deleteClass(workspaceInfo.id)
: apiSeatingLayout.deleteExam(workspaceInfo.id);
deleter.catch(() => {});
setSaveNotice('Đã xóa sơ đồ chỗ ngồi!');
}
}
}, 600);
};
useEffect(() => {