Files
platform/src/apps/officer-web/Screens/Dashboard/Automation/NewTask.tsx
T

95 lines
3.9 KiB
TypeScript

import { useState } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { X } from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { useClient } from 'hooks/useClient';
import { usePanelChannel } from 'hooks/usePanelChannel';
import type { AutomationSelection } from './AutomationRightPanel';
type NewTaskProps = {
selection: NonNullable<AutomationSelection>;
};
export const NewTask = ({ selection }: NewTaskProps) => {
const client = useClient();
const qc = useQueryClient();
const [, setSelection] = usePanelChannel<AutomationSelection>('automation:selected-capability', null);
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [submitting, setSubmitting] = useState(false);
const handleCreate = async () => {
const trimmed = name.trim();
if (!trimmed) return;
setSubmitting(true);
try {
const res = await client.post<{ name: string; dirName: string }>(selection.endpoint, { name: trimmed });
await qc.invalidateQueries({ queryKey: [selection.queryKey] });
setSelection({
kind: selection.kind,
endpoint: selection.endpoint,
queryKey: selection.queryKey,
dirName: res.dirName,
isNew: true,
editing: true,
description: description.trim() || undefined,
});
} catch {
toast.error('Failed to create task');
setSubmitting(false);
}
};
return (
<div className="h-full flex flex-col">
<div className="shrink-0 px-4 py-2 border-b border-duck-dark/10 dark:border-foreground/10 bg-background/60 flex items-center gap-2">
<span className="text-sm font-medium text-duck-dark/70 dark:text-foreground/70 flex-1">New Task</span>
<button
onClick={() => setSelection(null)}
className="p-1 rounded hover:bg-duck-dark/10 dark:hover:bg-foreground/10 cursor-pointer transition-colors"
>
<X className="h-3.5 w-3.5 text-duck-dark/50 dark:text-foreground/50" />
</button>
</div>
<div className="flex-1 overflow-y-auto p-6 flex flex-col gap-4">
<div className="flex flex-col gap-1.5">
<label className="text-sm font-medium text-duck-dark/70 dark:text-foreground/70">Name</label>
<input
value={name}
onChange={(ev) => setName(ev.target.value)}
onKeyDown={(ev) => {
if (ev.key === 'Enter') {
ev.preventDefault();
handleCreate();
}
}}
placeholder="Task name..."
autoFocus
className="rounded border border-duck-dark/20 dark:border-foreground/20 bg-background px-3 py-2 text-sm text-duck-dark dark:text-foreground placeholder:text-duck-dark/30 dark:placeholder:text-foreground/30 focus:outline-none focus:ring-1 focus:ring-duck-teal/30"
/>
</div>
<div className="flex flex-col gap-1.5">
<label className="text-sm font-medium text-duck-dark/70 dark:text-foreground/70">Description</label>
<textarea
value={description}
onChange={(ev) => setDescription(ev.target.value)}
placeholder="Describe what this task automates..."
rows={4}
className="rounded border border-duck-dark/20 dark:border-foreground/20 bg-background px-3 py-2 text-sm text-duck-dark dark:text-foreground placeholder:text-duck-dark/30 dark:placeholder:text-foreground/30 focus:outline-none focus:ring-1 focus:ring-duck-teal/30 resize-none"
/>
</div>
<div className="flex justify-end">
<Button
onClick={handleCreate}
disabled={!name.trim() || submitting}
className="bg-duck-teal text-duck-yellow hover:bg-duck-teal/90 cursor-pointer"
>
{submitting ? 'Creating...' : 'Create'}
</Button>
</div>
</div>
</div>
);
};