useForm.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import fetchApi, { ApiMethods, ApiPaths } from "./../utils/api";
  2. import { FormEventHandler, useState } from "react";
  3. type useFormProps = {
  4. path: ApiPaths;
  5. query?: string;
  6. method: ApiMethods;
  7. };
  8. type FormMessage = {
  9. message: string;
  10. };
  11. type SuccessFormData = {
  12. [k: string]: FormDataEntryValue;
  13. };
  14. type SubmitHandler = FormEventHandler<HTMLFormElement>;
  15. type UseForm = {
  16. error?: FormMessage;
  17. loading: boolean;
  18. submitHandler: SubmitHandler;
  19. success?: FormMessage;
  20. successFormData?: SuccessFormData;
  21. };
  22. const useForm = ({ path, method, query }: useFormProps): UseForm => {
  23. const [error, setError] = useState<FormMessage>();
  24. const [loading, setLoading] = useState(false);
  25. const [success, setSuccess] = useState<FormMessage>();
  26. const [successFormData, setSuccessFormData] = useState<SuccessFormData>();
  27. const submitHandler: FormEventHandler<HTMLFormElement> = async (event) => {
  28. event.preventDefault();
  29. setLoading(true);
  30. const formData = new FormData(event.currentTarget);
  31. const body = Object.fromEntries(formData.entries());
  32. const { error, message } = await fetchApi({
  33. path,
  34. query,
  35. method,
  36. body,
  37. });
  38. if (error) {
  39. setLoading(false);
  40. setError({ message: error });
  41. } else {
  42. setSuccessFormData(body);
  43. setLoading(false);
  44. setSuccess({ message: message || "Success!" });
  45. }
  46. };
  47. return { error, loading, success, submitHandler, successFormData };
  48. };
  49. export default useForm;