add missing buttons

This commit is contained in:
Sean Sube 2025-06-14 19:00:59 -05:00
parent 08c41fa0be
commit c6a647202b
No known key found for this signature in database
GPG Key ID: 3EED7B957D362AF1
5 changed files with 117 additions and 36 deletions

View File

@ -4,6 +4,7 @@ import { useTaskData } from './hooks/useTaskData'
import { DesktopLayout } from './layouts/DesktopLayout' import { DesktopLayout } from './layouts/DesktopLayout'
import { MobileLayout } from './layouts/MobileLayout' import { MobileLayout } from './layouts/MobileLayout'
import { StepDetails } from './components/StepDetails' import { StepDetails } from './components/StepDetails'
import type { GroupWithTasks, TaskWithSteps, StepWithNotes } from './types'
const theme = createTheme() const theme = createTheme()
@ -20,6 +21,7 @@ export function App() {
setSelectedTask, setSelectedTask,
setSelectedStep, setSelectedStep,
handlePrintStep, handlePrintStep,
handlePrintTask,
handleAddNote, handleAddNote,
} = useTaskData() } = useTaskData()
@ -46,13 +48,16 @@ export function App() {
<CssBaseline /> <CssBaseline />
{deviceType === 'desktop' ? ( {deviceType === 'desktop' ? (
<DesktopLayout <DesktopLayout
groups={groups as any} groups={groups}
selectedGroup={selectedGroup as any} selectedGroup={selectedGroup}
selectedTask={selectedTask as any} selectedTask={selectedTask}
selectedStep={selectedStep as any} selectedStep={selectedStep}
onGroupSelect={setSelectedGroup as any} onGroupSelect={setSelectedGroup}
onTaskSelect={setSelectedTask as any} onTaskSelect={setSelectedTask}
onStepSelect={setSelectedStep as any} onStepSelect={setSelectedStep}
onPrintTask={handlePrintTask}
onPrintStep={handlePrintStep}
onAddNote={handleAddNote}
/> />
) : ( ) : (
<> <>
@ -65,13 +70,13 @@ export function App() {
/> />
) : ( ) : (
<MobileLayout <MobileLayout
groups={groups as any} groups={groups}
selectedGroup={selectedGroup as any} selectedGroup={selectedGroup}
selectedTask={selectedTask as any} selectedTask={selectedTask}
selectedStep={selectedStep as any} selectedStep={selectedStep}
onGroupSelect={setSelectedGroup as any} onGroupSelect={setSelectedGroup}
onTaskSelect={setSelectedTask as any} onTaskSelect={setSelectedTask}
onStepSelect={setSelectedStep as any} onStepSelect={setSelectedStep}
onBack={handleBack} onBack={handleBack}
/> />
)} )}

View File

@ -1,5 +1,6 @@
import { Box, Typography, Button, TextField, IconButton } from '@mui/material'; import { Box, Typography, Button, TextField, IconButton } from '@mui/material';
import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import PrintIcon from '@mui/icons-material/Print';
import type { StepWithNotes } from '../types'; import type { StepWithNotes } from '../types';
interface StepDetailsProps { interface StepDetailsProps {
@ -16,13 +17,18 @@ export function StepDetails({ step, onPrint, onAddNote, onBack }: StepDetailsPro
<IconButton onClick={onBack} sx={{ mr: 1 }}> <IconButton onClick={onBack} sx={{ mr: 1 }}>
<ArrowBackIcon /> <ArrowBackIcon />
</IconButton> </IconButton>
<Typography variant="h6">{step.name}</Typography> <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flex: 1 }}>
<Typography variant="h6">{step.name}</Typography>
</Box>
<IconButton onClick={onPrint}>
<PrintIcon />
</IconButton>
</Box> </Box>
<Typography sx={{ mb: 4 }}>{step.instructions}</Typography> <Typography sx={{ mb: 4 }}>{step.instructions}</Typography>
<Box sx={{ mb: 4 }}> <Box sx={{ mb: 4 }}>
<Typography variant="h6" sx={{ mb: 2 }}> <Typography variant="h6" sx={{ mb: 2 }}>
Notes Notes ({step.notes.length})
</Typography> </Typography>
{step.notes.map((note) => ( {step.notes.map((note) => (
<Box key={note.id} sx={{ mb: 2 }}> <Box key={note.id} sx={{ mb: 2 }}>
@ -44,10 +50,6 @@ export function StepDetails({ step, onPrint, onAddNote, onBack }: StepDetailsPro
Add Note Add Note
</Button> </Button>
</Box> </Box>
<Button variant="contained" onClick={onPrint}>
Print Step
</Button>
</Box> </Box>
); );
} }

View File

@ -63,9 +63,12 @@ export const CREATE_NOTE = gql`
id id
content content
step_id step_id
user_id
created_at created_at
updated_at updated_at
user {
id
name
}
} }
} }
`; `;

View File

@ -156,9 +156,9 @@ export function useTaskData() {
} }
}; };
const handleAddNote = async (content: string, userId: string) => { const handleAddNote = async (content: string) => {
if (!selectedStep?.id || !userId) { if (!selectedStep?.id) {
console.error('Cannot add note: missing stepId or userId'); console.error('Cannot add note: missing stepId');
return; return;
} }
@ -166,10 +166,10 @@ export function useTaskData() {
await createNote({ await createNote({
variables: { variables: {
content, content,
stepId: selectedStep.id, stepId: String(selectedStep.id),
userId,
}, },
}); });
await refetchStep({ id: String(selectedStep.id) });
} catch (error) { } catch (error) {
console.error('Error adding note:', error); console.error('Error adding note:', error);
} }

View File

@ -1,4 +1,5 @@
import { Box, Typography } from '@mui/material'; import { Box, Typography, IconButton, TextField, Button } from '@mui/material';
import PrintIcon from '@mui/icons-material/Print';
import type { GroupWithTasks, TaskWithSteps, StepWithNotes } from '../types'; import type { GroupWithTasks, TaskWithSteps, StepWithNotes } from '../types';
import { CreateButtons } from '../components/CreateButtons'; import { CreateButtons } from '../components/CreateButtons';
@ -10,6 +11,9 @@ interface DesktopLayoutProps {
onGroupSelect: (group: GroupWithTasks | undefined) => void; onGroupSelect: (group: GroupWithTasks | undefined) => void;
onTaskSelect: (task: TaskWithSteps | undefined) => void; onTaskSelect: (task: TaskWithSteps | undefined) => void;
onStepSelect: (step: StepWithNotes | 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({ export function DesktopLayout({
@ -20,6 +24,9 @@ export function DesktopLayout({
onGroupSelect, onGroupSelect,
onTaskSelect, onTaskSelect,
onStepSelect, onStepSelect,
onPrintTask,
onPrintStep,
onAddNote,
}: DesktopLayoutProps) { }: DesktopLayoutProps) {
return ( return (
<Box sx={{ display: 'flex', height: '100vh' }}> <Box sx={{ display: 'flex', height: '100vh' }}>
@ -62,10 +69,25 @@ export function DesktopLayout({
cursor: 'pointer', cursor: 'pointer',
bgcolor: selectedTask?.id === task.id ? 'action.selected' : 'transparent', bgcolor: selectedTask?.id === task.id ? 'action.selected' : 'transparent',
'&:hover': { bgcolor: 'action.hover' }, '&:hover': { bgcolor: 'action.hover' },
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}} }}
onClick={() => onTaskSelect(task)}
> >
<Typography>{task.name}</Typography> <Box onClick={() => onTaskSelect(task)} sx={{ flex: 1 }}>
<Typography>{task.name}</Typography>
</Box>
{onPrintTask && (
<IconButton
size="small"
onClick={(e) => {
e.stopPropagation();
onPrintTask(String(task.id), '1'); // TODO: Get real user ID
}}
>
<PrintIcon />
</IconButton>
)}
</Box> </Box>
))} ))}
</Box> </Box>
@ -86,10 +108,25 @@ export function DesktopLayout({
cursor: 'pointer', cursor: 'pointer',
bgcolor: selectedStep?.id === step.id ? 'action.selected' : 'transparent', bgcolor: selectedStep?.id === step.id ? 'action.selected' : 'transparent',
'&:hover': { bgcolor: 'action.hover' }, '&:hover': { bgcolor: 'action.hover' },
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}} }}
onClick={() => onStepSelect(step)}
> >
<Typography>{step.name}</Typography> <Box onClick={() => onStepSelect(step)} sx={{ flex: 1 }}>
<Typography>{step.name}</Typography>
</Box>
{onPrintStep && (
<IconButton
size="small"
onClick={(e) => {
e.stopPropagation();
onPrintStep(String(step.id), '1'); // TODO: Get real user ID
}}
>
<PrintIcon />
</IconButton>
)}
</Box> </Box>
))} ))}
</Box> </Box>
@ -97,11 +134,45 @@ export function DesktopLayout({
{/* Step details panel */} {/* Step details panel */}
{selectedStep && ( {selectedStep && (
<Box sx={{ flex: 1, p: 2 }}> <Box sx={{ flex: 1, p: 2, overflow: 'auto' }}>
<Typography variant="h6" sx={{ mb: 2 }}> <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
{selectedStep.name} <Typography variant="h6">{selectedStep.name}</Typography>
</Typography> {onPrintStep && (
<Typography>{selectedStep.instructions}</Typography> <IconButton
onClick={() => onPrintStep(String(selectedStep.id), '1')} // TODO: Get real user 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>
)} )}
</Box> </Box>