dishplanner/frontend/app/components/features/dishes/CreateDishForm.tsx

95 lines
2.9 KiB
TypeScript
Raw Normal View History

2025-10-13 14:57:11 +02:00
import React, { useState } from "react";
2025-11-09 13:09:22 +01:00
import { useNavigate } from "react-router";
import { createDish } from "~/utils/api/dishApi";
import PageTitle from "~/components/ui/PageTitle";
import Alert from "~/components/ui/Alert";
import SolidButton from "~/components/ui/Buttons/SolidButton";
import OutlineLinkButton from "~/components/ui/Buttons/OutlineLinkButton";
2025-10-13 14:57:11 +02:00
import { ChevronLeftIcon } from "@heroicons/react/16/solid";
2025-11-09 13:09:22 +01:00
import Hr from "~/components/ui/Hr"
2025-10-13 14:57:11 +02:00
const CreateDishForm = () => {
2025-11-09 13:09:22 +01:00
const navigate = useNavigate()
2025-10-13 14:57:11 +02:00
const [name, setName] = useState<string>("");
const [error, setError] = useState<string>("");
const [loading, setLoading] = useState(false);
const validateForm = () => {
if (!name.trim()) {
setError("Dish name cannot be empty.");
return false;
}
return true;
};
const submitForm = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
// Validate client-side input
if (!validateForm()) return;
setError("");
setLoading(true);
try {
const result = await createDish(name);
if (result) {
2025-11-09 13:09:22 +01:00
navigate('/dishes')
2025-10-13 14:57:11 +02:00
}
} catch (error: unknown) {
setError(error instanceof Error ? error.message : "An unexpected error occurred.");
} finally {
setLoading(false);
}
}
return (
<div className="px-5">
<div className="flex mb-3">
<PageTitle>Create Dish</PageTitle>
</div>
<form className="space-y-4" onSubmit={ submitForm }>
{ error && (
<Alert type="error">{ error }</Alert>
) }
<div>
<label htmlFor="name" className="block text-sm font-medium">Dish Name</label>
<input
type="text"
id="name"
name="name"
value={ name }
onChange={ (e) => setName(e.target.value) } // Update the name state on change
className="w-full p-2 mb-4 border rounded bg-gray-600 border-secondary text-secondary focus:bg-gray-900"
placeholder="Enter dish name"
/>
</div>
<SolidButton
2025-10-13 14:57:11 +02:00
type="submit"
disabled={ loading }
className={ loading ? "bg-gray-400" : '' }
>
{ loading ? "Saving..." : "Save Changes" }
</SolidButton>
2025-10-13 14:57:11 +02:00
</form>
<Hr />
<OutlineLinkButton
2025-10-13 14:57:11 +02:00
href="/dishes"
className="mt-4 pl-0 mr-0"
icon={ <ChevronLeftIcon/> }
>
Back to dishes
</OutlineLinkButton>
2025-10-13 14:57:11 +02:00
</div>
);
};
export default CreateDishForm;