feat: updade workspace
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Button } from '../components/ui/Button.js';
|
||||
import { createObjective, listUsers } from '../lib/api.js';
|
||||
import { createObjectiveSchema, type CreateObjectiveFormData } from '../schemas/objective.schema.js';
|
||||
|
||||
export function CreateObjective(): JSX.Element {
|
||||
const navigate = useNavigate();
|
||||
const queryClient = useQueryClient();
|
||||
const [fieldErrors, setFieldErrors] = useState<Partial<Record<keyof CreateObjectiveFormData, string>>>({});
|
||||
const { register, handleSubmit } = useForm<CreateObjectiveFormData>({
|
||||
defaultValues: { title: '', description: '', quarter: 'Q2/2026' },
|
||||
});
|
||||
const { data: users = [] } = useQuery({ queryKey: ['users'], queryFn: listUsers });
|
||||
const mutation = useMutation({
|
||||
mutationFn: createObjective,
|
||||
onSuccess: async (objective) => {
|
||||
await queryClient.invalidateQueries({ queryKey: ['objectives'] });
|
||||
navigate(`/objectives/${objective.id}`);
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = handleSubmit((values) => {
|
||||
const parsed = createObjectiveSchema.safeParse(values);
|
||||
if (!parsed.success) {
|
||||
setFieldErrors(Object.fromEntries(parsed.error.issues.map((issue) => [issue.path[0], issue.message])));
|
||||
return;
|
||||
}
|
||||
setFieldErrors({});
|
||||
mutation.mutate(parsed.data);
|
||||
});
|
||||
|
||||
return (
|
||||
<section className="rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
|
||||
<h1 className="mb-6 text-xl font-semibold text-gray-800">Create Objective</h1>
|
||||
<form className="max-w-2xl space-y-4" onSubmit={onSubmit}>
|
||||
<label className="block">
|
||||
<span className="mb-1 block text-sm font-medium text-gray-700">Title</span>
|
||||
<input className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500" {...register('title')} />
|
||||
{fieldErrors.title !== undefined && <span className="mt-1 block text-sm text-orange-600">{fieldErrors.title}</span>}
|
||||
</label>
|
||||
<label className="block">
|
||||
<span className="mb-1 block text-sm font-medium text-gray-700">Description</span>
|
||||
<textarea rows={4} className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500" {...register('description')} />
|
||||
</label>
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<label className="block">
|
||||
<span className="mb-1 block text-sm font-medium text-gray-700">Owner</span>
|
||||
<select className="w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500" {...register('ownerId')}>
|
||||
<option value="">Select owner</option>
|
||||
{users.map((user) => (
|
||||
<option key={user.id} value={user.id}>
|
||||
{user.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{fieldErrors.ownerId !== undefined && <span className="mt-1 block text-sm text-orange-600">{fieldErrors.ownerId}</span>}
|
||||
</label>
|
||||
<label className="block">
|
||||
<span className="mb-1 block text-sm font-medium text-gray-700">Quarter</span>
|
||||
<input className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500" {...register('quarter')} />
|
||||
{fieldErrors.quarter !== undefined && <span className="mt-1 block text-sm text-orange-600">{fieldErrors.quarter}</span>}
|
||||
</label>
|
||||
</div>
|
||||
{mutation.isError && <div className="rounded-lg bg-orange-100 px-3 py-2 text-sm text-orange-700">Unable to create objective.</div>}
|
||||
<Button type="submit" disabled={mutation.isPending}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user