task_receipts/client/src/layouts/DesktopLayout.tsx

198 lines
6.6 KiB
TypeScript

import { Box, Typography, IconButton, TextField, Button } from '@mui/material';
import PrintIcon from '@mui/icons-material/Print';
import type { GroupWithTasks, TaskWithSteps, StepWithNotes } from '../types';
import { CreateButtons } from '../components/CreateButtons';
import { ColorPickerButton } from '../components/ColorPickerButton';
import { ScreensaverButton } from '../components/ScreensaverButton';
import { useUserSelection } from '../hooks/useUserSelection';
interface DesktopLayoutProps {
groups: GroupWithTasks[];
selectedGroup?: GroupWithTasks;
selectedTask?: TaskWithSteps;
selectedStep?: StepWithNotes;
onGroupSelect: (group: GroupWithTasks | undefined) => void;
onTaskSelect: (task: TaskWithSteps | undefined) => void;
onStepSelect: (step: StepWithNotes | undefined) => void;
onPrintTask?: (taskId: string, userId: string) => void;
onPrintStep?: (stepId: string, userId: string) => void;
onAddNote?: (content: string) => void;
}
export function DesktopLayout({
groups,
selectedGroup,
selectedTask,
selectedStep,
onGroupSelect,
onTaskSelect,
onStepSelect,
onPrintTask,
onPrintStep,
onAddNote,
}: DesktopLayoutProps) {
const { selectedUser } = useUserSelection();
console.log('DesktopLayout render:', {
groups,
selectedGroup,
selectedTask,
selectedStep,
selectedUser
});
return (
<Box sx={{ display: 'flex', height: '100vh' }}>
{/* Groups panel */}
<Box sx={{ width: 250, borderRight: 1, borderColor: 'divider', p: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="h6">Groups</Typography>
<Box sx={{ display: 'flex', gap: 1 }}>
<ColorPickerButton />
<ScreensaverButton />
<CreateButtons type="group" />
</Box>
</Box>
{/* Groups List */}
{groups.map((group) => (
<Box
key={group.id}
sx={{
p: 2,
cursor: 'pointer',
bgcolor: selectedGroup?.id === group.id ? 'action.selected' : 'transparent',
'&:hover': { bgcolor: 'action.hover' },
}}
onClick={() => onGroupSelect(group)}
>
<Typography>{group.name}</Typography>
</Box>
))}
</Box>
{/* Tasks panel */}
{selectedGroup && (
<Box sx={{ width: 250, borderRight: 1, borderColor: 'divider', p: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="h6">Tasks</Typography>
{selectedGroup.id > 0 && <CreateButtons type="task" parentId={String(selectedGroup.id)} />}
</Box>
{selectedGroup.tasks.map((task) => (
<Box
key={task.id}
sx={{
p: 2,
cursor: 'pointer',
bgcolor: selectedTask?.id === task.id ? 'action.selected' : 'transparent',
'&:hover': { bgcolor: 'action.hover' },
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<Box onClick={() => onTaskSelect(task)} sx={{ flex: 1 }}>
<Typography>{task.name}</Typography>
</Box>
{onPrintTask && selectedUser && (
<IconButton
size="small"
onClick={(e) => {
e.stopPropagation();
onPrintTask(String(task.id), String(selectedUser.id));
}}
>
<PrintIcon />
</IconButton>
)}
</Box>
))}
</Box>
)}
{/* Steps panel */}
{selectedTask && (
<Box sx={{ width: 250, borderRight: 1, borderColor: 'divider', p: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="h6">Steps</Typography>
<CreateButtons type="step" parentId={String(selectedTask.id)} />
</Box>
{selectedTask.steps.map((step) => (
<Box
key={step.id}
sx={{
p: 2,
cursor: 'pointer',
bgcolor: selectedStep?.id === step.id ? 'action.selected' : 'transparent',
'&:hover': { bgcolor: 'action.hover' },
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<Box onClick={() => onStepSelect(step)} sx={{ flex: 1 }}>
<Typography>{step.order}: {step.name}</Typography>
</Box>
{onPrintStep && selectedUser && (
<IconButton
size="small"
onClick={(e) => {
e.stopPropagation();
onPrintStep(String(step.id), String(selectedUser.id));
}}
>
<PrintIcon />
</IconButton>
)}
</Box>
))}
</Box>
)}
{/* Step details panel */}
{selectedStep && (
<Box sx={{ flex: 1, p: 2, overflow: 'auto' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="h6">{selectedStep.name}</Typography>
{onPrintStep && selectedUser && (
<IconButton
onClick={() => onPrintStep(String(selectedStep.id), String(selectedUser.id))}
>
<PrintIcon />
</IconButton>
)}
</Box>
<Typography sx={{ mb: 4 }}>{selectedStep.instructions}</Typography>
<Box sx={{ mb: 4 }}>
<Typography variant="h6" sx={{ mb: 2 }}>
Notes ({selectedStep.notes.length})
</Typography>
{selectedStep.notes.map((note) => (
<Box key={note.id} sx={{ mb: 2 }}>
<Typography variant="subtitle2">{note.user?.name}</Typography>
<Typography>{note.content}</Typography>
</Box>
))}
</Box>
<Box sx={{ mb: 4 }}>
<TextField
fullWidth
multiline
rows={4}
placeholder="Add a note..."
sx={{ mb: 2 }}
/>
{onAddNote && (
<Button variant="contained" onClick={() => onAddNote('New note')}>
Add Note
</Button>
)}
</Box>
</Box>
)}
</Box>
);
}