Files
compras/resources/js/components/inventory-event-actions.tsx
T
2026-11-02 08:08:05 +02:00

126 lines
4.6 KiB
TypeScript

import { useState } from 'react';
import { useForm } from '@inertiajs/react';
import { FormErrors, controlClass } from '@/components/procurement';
import { Button } from '@/components/ui/button';
type Choice = { value: string; label: string };
type Props = {
route: string;
record: { record_key: string; version: number };
choices: Choice[];
today?: string;
data?: Record<string, string | number | boolean | null>;
};
function Confirm({ props, choice }: { props: Props; choice: Choice }) {
const form = useForm({
operation_key: crypto.randomUUID(),
record_key: props.record.record_key,
version: props.record.version,
action: choice.value,
reason: '',
data: {
...props.data,
...(choice.value === 'execute'
? { event_on: props.today ?? '', evidence: '' }
: {}),
},
});
return (
<form
className="mt-3 grid gap-3 md:grid-cols-2"
onSubmit={(e) => {
e.preventDefault();
form.post(props.route);
}}
>
<FormErrors errors={form.errors} />
<label className="grid gap-1 text-sm">
Motivo e evidência da conferência
<textarea
required
minLength={10}
maxLength={4000}
className={controlClass}
value={form.data.reason}
onChange={(e) => form.setData('reason', e.target.value)}
/>
</label>
{choice.value === 'execute' && (
<>
<label className="grid gap-1 text-sm">
Data efectiva do evento
<input
type="date"
required
max={props.today}
className={controlClass}
value={String(form.data.data.event_on ?? '')}
onChange={(e) =>
form.setData('data', {
...form.data.data,
event_on: e.target.value,
})
}
/>
</label>
<label className="grid gap-1 text-sm">
Comprovativo da execução física
<input
required
minLength={10}
maxLength={3000}
className={controlClass}
value={String(form.data.data.evidence ?? '')}
onChange={(e) =>
form.setData('data', {
...form.data.data,
evidence: e.target.value,
})
}
/>
</label>
</>
)}
<Button disabled={form.processing}>{choice.label}</Button>
</form>
);
}
export function InventoryEventActions(props: Props) {
const [selected, setSelected] = useState(
props.choices.length === 1 ? props.choices[0].value : '',
);
if (props.choices.length === 0) return null;
const choice = props.choices.find((option) => option.value === selected);
return (
<details className="mt-4">
<summary className="cursor-pointer text-sm font-medium">
{props.choices.length === 1
? props.choices[0].label
: 'Acções da minha responsabilidade'}
</summary>
{props.choices.length > 1 && (
<label className="mt-3 grid gap-1 text-sm">
Acção
<select
className={controlClass}
value={selected}
onChange={(e) => setSelected(e.target.value)}
>
<option value="">Seleccione a decisão</option>
{props.choices.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</label>
)}
{choice && (
<Confirm key={choice.value} props={props} choice={choice} />
)}
</details>
);
}