add missing buttons
This commit is contained in:
parent
08c41fa0be
commit
c6a647202b
@ -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}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -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>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flex: 1 }}>
|
||||||
<Typography variant="h6">{step.name}</Typography>
|
<Typography variant="h6">{step.name}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
<IconButton onClick={onPrint}>
|
||||||
|
<PrintIcon />
|
||||||
|
</IconButton>
|
||||||
|
</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>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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,11 +69,26 @@ 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)}
|
|
||||||
>
|
>
|
||||||
|
<Box onClick={() => onTaskSelect(task)} sx={{ flex: 1 }}>
|
||||||
<Typography>{task.name}</Typography>
|
<Typography>{task.name}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
{onPrintTask && (
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onPrintTask(String(task.id), '1'); // TODO: Get real user ID
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PrintIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
@ -86,22 +108,71 @@ 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)}
|
|
||||||
>
|
>
|
||||||
|
<Box onClick={() => onStepSelect(step)} sx={{ flex: 1 }}>
|
||||||
<Typography>{step.name}</Typography>
|
<Typography>{step.name}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
{onPrintStep && (
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onPrintStep(String(step.id), '1'); // TODO: Get real user ID
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PrintIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Step details panel */}
|
{/* Step details panel */}
|
||||||
{selectedStep && (
|
{selectedStep && (
|
||||||
<Box sx={{ flex: 1, p: 2 }}>
|
<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 && (
|
||||||
|
<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 }}>
|
<Typography variant="h6" sx={{ mb: 2 }}>
|
||||||
{selectedStep.name}
|
Notes ({selectedStep.notes.length})
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>{selectedStep.instructions}</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>
|
||||||
|
Loading…
Reference in New Issue
Block a user