add print buttons to mobile
This commit is contained in:
parent
95a3a08492
commit
dec4b848b6
@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React + TS</title>
|
||||
<title>Task Receipts</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
@ -89,6 +89,7 @@ export function App() {
|
||||
onTaskSelect={setSelectedTask}
|
||||
onStepSelect={setSelectedStep}
|
||||
onBack={handleBack}
|
||||
onPrintTask={handlePrintTask}
|
||||
onPrintStep={handlePrintStep}
|
||||
onAddNote={handleAddNote}
|
||||
/>
|
||||
|
@ -125,7 +125,7 @@ export function DesktopLayout({
|
||||
}}
|
||||
>
|
||||
<Box onClick={() => onStepSelect(step)} sx={{ flex: 1 }}>
|
||||
<Typography>{step.name}</Typography>
|
||||
<Typography>{step.order}: {step.name}</Typography>
|
||||
</Box>
|
||||
{onPrintStep && selectedUser && (
|
||||
<IconButton
|
||||
|
@ -3,6 +3,7 @@ import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
||||
import PrintIcon from '@mui/icons-material/Print';
|
||||
import type { GroupWithTasks, TaskWithSteps, StepWithNotes } from '../types';
|
||||
import { CreateButtons } from '../components/CreateButtons';
|
||||
import { useUserSelection } from '../hooks/useUserSelection';
|
||||
|
||||
function isGroupView(selectedGroup?: GroupWithTasks) {
|
||||
return !selectedGroup;
|
||||
@ -16,6 +17,10 @@ function isStepView(selectedTask?: TaskWithSteps, selectedStep?: StepWithNotes)
|
||||
return selectedTask && !selectedStep;
|
||||
}
|
||||
|
||||
function isGroupWithTasks(group: any): group is GroupWithTasks {
|
||||
return group && typeof group.id === 'string' && Array.isArray(group.tasks);
|
||||
}
|
||||
|
||||
export function MobileLayout({
|
||||
groups = [],
|
||||
selectedGroup,
|
||||
@ -25,6 +30,7 @@ export function MobileLayout({
|
||||
onTaskSelect,
|
||||
onStepSelect,
|
||||
onBack,
|
||||
onPrintTask,
|
||||
onPrintStep,
|
||||
onAddNote
|
||||
}: {
|
||||
@ -36,9 +42,11 @@ export function MobileLayout({
|
||||
onTaskSelect: (task: TaskWithSteps | undefined) => void;
|
||||
onStepSelect: (step: StepWithNotes | undefined) => void;
|
||||
onBack: () => void;
|
||||
onPrintTask?: (taskId: string, userId: string) => void;
|
||||
onPrintStep?: (stepId: string, userId: string) => void;
|
||||
onAddNote?: (content: string) => void;
|
||||
}) {
|
||||
const { selectedUser } = useUserSelection();
|
||||
const groupList: GroupWithTasks[] = groups;
|
||||
const taskList: TaskWithSteps[] = (selectedGroup?.tasks as TaskWithSteps[]) ?? [];
|
||||
const stepList: StepWithNotes[] = (selectedTask?.steps as StepWithNotes[]) ?? [];
|
||||
@ -61,6 +69,14 @@ export function MobileLayout({
|
||||
<ArrowBackIcon />
|
||||
</IconButton>
|
||||
<Typography variant="h6">{selectedTask.name}</Typography>
|
||||
{onPrintTask && selectedUser && (
|
||||
<IconButton
|
||||
onClick={() => onPrintTask(String(selectedTask.id), String(selectedUser.id))}
|
||||
sx={{ ml: 'auto' }}
|
||||
>
|
||||
<PrintIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
@ -70,9 +86,9 @@ export function MobileLayout({
|
||||
<ArrowBackIcon />
|
||||
</IconButton>
|
||||
<Typography variant="h6">{selectedStep.name}</Typography>
|
||||
{onPrintStep && (
|
||||
{onPrintStep && selectedUser && (
|
||||
<IconButton
|
||||
onClick={() => onPrintStep(String(selectedStep.id), '1')} // TODO: Get real user ID
|
||||
onClick={() => onPrintStep(String(selectedStep.id), String(selectedUser.id))}
|
||||
sx={{ ml: 'auto' }}
|
||||
>
|
||||
<PrintIcon />
|
||||
@ -97,7 +113,7 @@ export function MobileLayout({
|
||||
sx={{
|
||||
p: 2,
|
||||
cursor: 'pointer',
|
||||
bgcolor: selectedGroup?.id === group.id ? 'action.selected' : 'transparent',
|
||||
// no bg color
|
||||
'&:hover': { bgcolor: 'action.hover' },
|
||||
}}
|
||||
onClick={() => onGroupSelect(group)}
|
||||
@ -108,7 +124,7 @@ export function MobileLayout({
|
||||
</>
|
||||
)}
|
||||
|
||||
{isTaskView(selectedGroup, selectedTask) && (
|
||||
{isTaskView(selectedGroup, selectedTask) && isGroupWithTasks(selectedGroup) && (
|
||||
<>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
|
||||
<Typography variant="h6">Tasks</Typography>
|
||||
@ -121,12 +137,28 @@ export function MobileLayout({
|
||||
sx={{
|
||||
p: 2,
|
||||
cursor: 'pointer',
|
||||
bgcolor: selectedTask?.id === task.id ? 'action.selected' : 'transparent',
|
||||
// no bg color
|
||||
'&: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>
|
||||
</Box>
|
||||
{onPrintTask && selectedUser && (
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onPrintTask(String(task.id), String(selectedUser.id));
|
||||
}}
|
||||
>
|
||||
<PrintIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</>
|
||||
@ -146,10 +178,25 @@ export function MobileLayout({
|
||||
p: 2,
|
||||
cursor: 'pointer',
|
||||
bgcolor: selectedStep?.id === step.id ? 'action.selected' : 'transparent',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onClick={() => onStepSelect(step)}
|
||||
>
|
||||
<Typography>{step.name}</Typography>
|
||||
<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>
|
||||
|
@ -24,10 +24,11 @@ export const formatUtils = {
|
||||
* @param startIndex Starting index for numbering (0 for no numbers)
|
||||
* @returns Array of formatted lines
|
||||
*/
|
||||
formatList(items: string[], startIndex: number = 0): string[] {
|
||||
formatList(items: string[], startIndex: number = 0, prefix: string = ''): string[] {
|
||||
return items.map((item, index) => {
|
||||
const num = startIndex > 0 ? `${index + startIndex}: ` : '';
|
||||
return this.formatCheckbox(`${num}${item}`);
|
||||
const body = this.formatCheckbox(`${num}${item}`);
|
||||
return `${prefix}${body}`;
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -37,15 +37,10 @@ export class TestPrinter implements Printer {
|
||||
|
||||
const content = [
|
||||
...formatUtils.formatSection(`Task: ${task.name}`, ''),
|
||||
...taskSteps.map((step, index) =>
|
||||
formatUtils.formatSection(
|
||||
formatUtils.formatStepHeader(step.name, index + 1, task.name, true),
|
||||
step.instructions,
|
||||
'-',
|
||||
true,
|
||||
)
|
||||
).flat(),
|
||||
].join('\n');
|
||||
...formatUtils.formatList(taskSteps.map((step, index) =>
|
||||
formatUtils.formatStepHeader(step.name, index + 1, task.name, true)
|
||||
), 0, '- '),
|
||||
].join('\n') + '\n';
|
||||
|
||||
await fs.writeFile(filename, content);
|
||||
logger.info(`Printed task ${task.id} to ${filename}`);
|
||||
@ -69,7 +64,7 @@ export class TestPrinter implements Printer {
|
||||
const content = formatUtils.formatSection(
|
||||
formatUtils.formatStepHeader(step.name, stepNumber, task?.name),
|
||||
step.instructions
|
||||
).join('\n');
|
||||
).join('\n') + '\n';
|
||||
|
||||
await fs.writeFile(filename, content);
|
||||
logger.info(`Printed step ${step.id} to ${filename}`);
|
||||
|
Loading…
Reference in New Issue
Block a user