teamp tou uu giao dien
All checks were successful
Deploy on Master Change / deploy (push) Successful in 49s
All checks were successful
Deploy on Master Change / deploy (push) Successful in 49s
This commit is contained in:
@@ -102,6 +102,15 @@ function App() {
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { staff, logout } = useAuth();
|
const { staff, logout } = useAuth();
|
||||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||||
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(() => {
|
||||||
|
return localStorage.getItem('sc_sidebar_collapsed') === 'true';
|
||||||
|
});
|
||||||
|
|
||||||
|
const toggleSidebarCollapse = () => {
|
||||||
|
const nextVal = !sidebarCollapsed;
|
||||||
|
setSidebarCollapsed(nextVal);
|
||||||
|
localStorage.setItem('sc_sidebar_collapsed', String(nextVal));
|
||||||
|
};
|
||||||
const [myClasses, setMyClasses] = useState<{ id: number; name: string; code: string }[]>(() => {
|
const [myClasses, setMyClasses] = useState<{ id: number; name: string; code: string }[]>(() => {
|
||||||
try {
|
try {
|
||||||
const stored = localStorage.getItem('sc_my_classes_details');
|
const stored = localStorage.getItem('sc_my_classes_details');
|
||||||
@@ -186,13 +195,37 @@ function App() {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<aside className={`sidebar${sidebarOpen ? ' sidebar--open' : ''}`}>
|
<aside className={`sidebar${sidebarOpen ? ' sidebar--open' : ''}${sidebarCollapsed ? ' sidebar--collapsed' : ''}`}>
|
||||||
<div className="brand">
|
<div className="brand">
|
||||||
<img src="/logo.jpeg" alt="Simple Care" className="brand-logo-img" />
|
<img src="/logo.jpeg" alt="Simple Care" className="brand-logo-img" />
|
||||||
<div className="brand-text">
|
<div className="brand-text">
|
||||||
<span className="brand-name">Simple Care</span>
|
<span className="brand-name">Simple Care</span>
|
||||||
<span className="brand-sub">Rikkei Education</span>
|
<span className="brand-sub">Rikkei Education</span>
|
||||||
</div>
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="sidebar-collapse-toggle-pc"
|
||||||
|
onClick={toggleSidebarCollapse}
|
||||||
|
title="Thu gọn menu"
|
||||||
|
style={{
|
||||||
|
background: 'none',
|
||||||
|
border: 'none',
|
||||||
|
color: 'var(--text-muted)',
|
||||||
|
cursor: 'pointer',
|
||||||
|
padding: '4px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginLeft: 'auto',
|
||||||
|
borderRadius: '4px',
|
||||||
|
transition: 'var(--transition)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<line x1="19" y1="12" x2="5" y2="12" />
|
||||||
|
<polyline points="12 19 5 12 12 5" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
@@ -332,7 +365,37 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<main className="main-content">
|
<main className={`main-content${sidebarCollapsed ? ' main-content--full' : ''}`}>
|
||||||
|
{sidebarCollapsed && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="sidebar-expand-btn-pc"
|
||||||
|
onClick={toggleSidebarCollapse}
|
||||||
|
title="Mở rộng menu"
|
||||||
|
style={{
|
||||||
|
position: 'fixed',
|
||||||
|
left: '12px',
|
||||||
|
top: '12px',
|
||||||
|
zIndex: 99,
|
||||||
|
background: '#fff',
|
||||||
|
border: '1px solid var(--border-color)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
width: '32px',
|
||||||
|
height: '32px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
cursor: 'pointer',
|
||||||
|
boxShadow: 'var(--shadow-sm)',
|
||||||
|
transition: 'var(--transition)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<line x1="5" y1="12" x2="19" y2="12" />
|
||||||
|
<polyline points="12 5 19 12 12 19" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
<div className="page-viewport">
|
<div className="page-viewport">
|
||||||
{route.classId ? (
|
{route.classId ? (
|
||||||
<ClassWorkspace
|
<ClassWorkspace
|
||||||
|
|||||||
@@ -192,11 +192,11 @@ export const SeatingTemplatesSection: React.FC = () => {
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))`,
|
gridTemplateColumns: `repeat(${cols}, minmax(72px, 1fr))`,
|
||||||
gap: '6px',
|
gap: '6px',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
maxHeight: '320px',
|
maxHeight: '320px',
|
||||||
overflowY: 'auto',
|
overflow: 'auto',
|
||||||
padding: '4px',
|
padding: '4px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ export const WorkspaceSeatingChart: React.FC<WorkspaceSeatingChartProps> = ({
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
gridTemplateColumns: `repeat(${layout.cols}, minmax(0, 1fr))`,
|
gridTemplateColumns: `repeat(${layout.cols}, minmax(75px, 1fr))`,
|
||||||
gap: '8px',
|
gap: '8px',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
padding: '8px',
|
padding: '8px',
|
||||||
|
|||||||
@@ -87,6 +87,21 @@ body {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
box-shadow: var(--shadow-sm);
|
box-shadow: var(--shadow-sm);
|
||||||
|
transition: transform 0.28s cubic-bezier(.4,0,.2,1), width 0.28s cubic-bezier(.4,0,.2,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar--collapsed {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-collapse-toggle-pc {
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: opacity 0.15s;
|
||||||
|
}
|
||||||
|
.sidebar-collapse-toggle-pc:hover {
|
||||||
|
opacity: 1;
|
||||||
|
color: var(--accent) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar > nav {
|
.sidebar > nav {
|
||||||
@@ -317,6 +332,17 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
transition: margin-left 0.28s cubic-bezier(.4,0,.2,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content--full {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-expand-btn-pc:hover {
|
||||||
|
background: var(--accent-light) !important;
|
||||||
|
border-color: var(--accent) !important;
|
||||||
|
color: var(--accent) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-viewport {
|
.page-viewport {
|
||||||
@@ -4647,7 +4673,24 @@ input:checked + .slider:before {
|
|||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-content {
|
/* On mobile, collapse is handled by sidebar--open toggle, not sidebar--collapsed */
|
||||||
|
.sidebar.sidebar--collapsed {
|
||||||
|
transform: translateX(-110%);
|
||||||
|
}
|
||||||
|
.sidebar.sidebar--collapsed.sidebar--open {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-collapse-toggle-pc {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-expand-btn-pc {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content,
|
||||||
|
.main-content.main-content--full {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
padding: 3.75rem 0.85rem 1rem;
|
padding: 3.75rem 0.85rem 1rem;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user