This commit is contained in:
@@ -40,6 +40,7 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
|
|||||||
// Edit mode for structural changes
|
// Edit mode for structural changes
|
||||||
const [isEditingStructure, setIsEditingStructure] = useState(false);
|
const [isEditingStructure, setIsEditingStructure] = useState(false);
|
||||||
const [dragOverCell, setDragOverCell] = useState<string | null>(null);
|
const [dragOverCell, setDragOverCell] = useState<string | null>(null);
|
||||||
|
const [saveNotice, setSaveNotice] = useState<string | null>(null);
|
||||||
|
|
||||||
// Load templates and layout
|
// Load templates and layout
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -68,12 +69,23 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
|
|||||||
const saveLayout = (newLayout: SeatingLayout | null) => {
|
const saveLayout = (newLayout: SeatingLayout | null) => {
|
||||||
if (newLayout) {
|
if (newLayout) {
|
||||||
localStorage.setItem(`sc_seating_layout_${workspaceId}`, JSON.stringify(newLayout));
|
localStorage.setItem(`sc_seating_layout_${workspaceId}`, JSON.stringify(newLayout));
|
||||||
|
setSaveNotice('Đã lưu thay đổi sơ đồ chỗ ngồi!');
|
||||||
} else {
|
} else {
|
||||||
localStorage.removeItem(`sc_seating_layout_${workspaceId}`);
|
localStorage.removeItem(`sc_seating_layout_${workspaceId}`);
|
||||||
|
setSaveNotice('Đã xóa sơ đồ chỗ ngồi!');
|
||||||
}
|
}
|
||||||
setLayout(newLayout);
|
setLayout(newLayout);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (saveNotice) {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setSaveNotice(null);
|
||||||
|
}, 2000);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}
|
||||||
|
}, [saveNotice]);
|
||||||
|
|
||||||
// Get active seated list
|
// Get active seated list
|
||||||
const seatedStudentIds = useMemo(() => {
|
const seatedStudentIds = useMemo(() => {
|
||||||
if (!layout) return new Set<number>();
|
if (!layout) return new Set<number>();
|
||||||
@@ -395,8 +407,8 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
|
|||||||
borderRadius: 'var(--radius-md)',
|
borderRadius: 'var(--radius-md)',
|
||||||
border: '1px solid var(--border-color)',
|
border: '1px solid var(--border-color)',
|
||||||
alignContent: 'start',
|
alignContent: 'start',
|
||||||
overflowY: 'auto',
|
overflow: 'auto',
|
||||||
minHeight: '400px',
|
minHeight: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{gridItems}
|
{gridItems}
|
||||||
@@ -423,7 +435,7 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', height: '100%', minHeight: '450px' }}>
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', flex: 1, minHeight: 0, height: '100%', overflow: 'hidden' }}>
|
||||||
|
|
||||||
{!layout ? (
|
{!layout ? (
|
||||||
// Empty state: select template or customize
|
// Empty state: select template or customize
|
||||||
@@ -510,10 +522,10 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
// Seating Workspace View
|
// Seating Workspace View
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 300px', gap: '1.5rem', height: '100%' }}>
|
<div style={{ display: 'grid', gridTemplateColumns: '1fr 300px', gap: '1.5rem', flex: 1, minHeight: 0, overflow: 'hidden' }}>
|
||||||
|
|
||||||
{/* Main Seating Panel */}
|
{/* Main Seating Panel */}
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', flex: 1, minHeight: 0, overflow: 'hidden' }}>
|
||||||
{/* Toolbar */}
|
{/* Toolbar */}
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '10px' }}>
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '10px' }}>
|
||||||
<div style={{ display: 'flex', gap: '8px' }}>
|
<div style={{ display: 'flex', gap: '8px' }}>
|
||||||
@@ -554,7 +566,7 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right Panel: Unseated Students list */}
|
{/* Right Panel: Unseated Students list */}
|
||||||
<div style={{ borderLeft: '1px solid var(--border-color)', paddingLeft: '1.5rem', display: 'flex', flexDirection: 'column', gap: '1rem', overflow: 'hidden' }}>
|
<div style={{ borderLeft: '1px solid var(--border-color)', paddingLeft: '1.5rem', display: 'flex', flexDirection: 'column', gap: '1rem', overflow: 'hidden', flex: 1, minHeight: 0 }}>
|
||||||
<div>
|
<div>
|
||||||
<h4 style={{ margin: 0, fontSize: '0.95rem', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
<h4 style={{ margin: 0, fontSize: '0.95rem', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
<span>Chưa vào chỗ</span>
|
<span>Chưa vào chỗ</span>
|
||||||
@@ -633,6 +645,27 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{saveNotice && (
|
||||||
|
<div style={{
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: '24px',
|
||||||
|
right: '24px',
|
||||||
|
background: '#10b981',
|
||||||
|
color: '#fff',
|
||||||
|
padding: '0.65rem 1.25rem',
|
||||||
|
borderRadius: '8px',
|
||||||
|
boxShadow: 'var(--shadow-lg)',
|
||||||
|
fontSize: '0.85rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
zIndex: 1000,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px',
|
||||||
|
}}>
|
||||||
|
<span style={{ fontSize: '1.1rem' }}>✓</span> {saveNotice}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user