198 lines
6.6 KiB
TypeScript
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>
|
|
);
|
|
}
|