Repository: Josieljcc/info-os-fontend
Pull request #14:  Implement order form and inputSelect component + payload adjustments
Author: login: Josuejcs13
Labels: name: enhancement
description: New feature or request
Created: 2025-03-01T19:39:23Z | Merged: 2025-03-29T18:03:28Z

This PR introduces the following changes:

Creation of the formOrder component to handle order submissions.

Implementation of a reusable inputSelect component.

Refactored the order payload structure to align with backend requirements.

Fixed issues related to the endpoint payload to ensure proper data handling.

Reverted and reapplied changes to the formOrder and order page to resolve conflicts after merging with master.


Diff:
diff --git a/src/Pages/home.tsx b/src/Pages/home.tsx
index 37f1240..4905235 100644
--- a/src/Pages/home.tsx
+++ b/src/Pages/home.tsx
@@ -2,8 +2,10 @@ import DrawerClient from "@/components/drawerClient/drawerClient";
 import DrawerEquipment from "@/components/drawerEquipment/drawerEquipment";
 import DrawerPart from "@/components/drawerPart/drawerPart";
 import DrawerService from "@/components/drawerService/drawerService";
-import useAuthentication from "@/hook/useAuthentication";
+
 import { Link } from "react-router-dom";
+import useAuthentication from "@/hook/useAuthentication";
+
 
 const Home = () => {
   useAuthentication();
@@ -15,6 +17,9 @@ const Home = () => {
       <DrawerPart />
       <DrawerService />
       <DrawerEquipment />
+      <Link className="text-white" to={"/order"}>
+        Order
+      </Link>
       <Link className="text-white" to="/technician">
         Listar Técnicos
       </Link>
diff --git a/src/Pages/order.tsx b/src/Pages/order.tsx
new file mode 100644
index 0000000..19c0231
--- /dev/null
+++ b/src/Pages/order.tsx
@@ -0,0 +1,11 @@
+import FormOrder from "@/components/formOrder/formOrder";
+import useAuthentication from "@/hook/useAuthentication";
+
+
+const Order = () => {
+  useAuthentication()
+  
+  return <FormOrder />;
+};
+
+export default Order;
diff --git a/src/Routes/router.tsx b/src/Routes/router.tsx
index feb0e63..cda6168 100644
--- a/src/Routes/router.tsx
+++ b/src/Routes/router.tsx
@@ -3,6 +3,7 @@ import RegisterTechnician from "../Pages/registerTechnician";
 import Login from "../Pages/login";
 
 import Home from "@/Pages/home";
+import Order from "@/Pages/order";
 import ListTechnician from "@/Pages/listTechnician";
 
 const router = createBrowserRouter([
@@ -23,9 +24,13 @@ const router = createBrowserRouter([
     element: <RegisterTechnician />,
   },
   {
-    path: "/technician",
-    element: <ListTechnician/>,
+    path: "/order",
+    element: <Order />,
   },
+  {
+    path: "/technician",    
+    element: <ListTechnician/>,
+  }
 ]);
 
 export default router;
diff --git a/src/components/formEquipment/formEquipment.tsx b/src/components/formEquipment/formEquipment.tsx
index 44e1dc1..9d794ee 100644
--- a/src/components/formEquipment/formEquipment.tsx
+++ b/src/components/formEquipment/formEquipment.tsx
@@ -3,7 +3,7 @@ import Input from "../input/input";
 import equipmentSchema, { EquipmentType } from "@/schemas/equipment";
 import { zodResolver } from "@hookform/resolvers/zod";
 import ButtonPrimary from "../buttonPrimary/buttonPrimary";
-import InputSelect from "../clientSelect/clientSelect";
+import InputSelect, { SelectType } from "../inputSelect/inputSelect";
 import useClient from "@/hook/useClient";
 import { useEffect, useState } from "react";
 import { Client } from "@/types";
@@ -14,7 +14,7 @@ import useEquipment from "@/hook/useEquipment";
 const FormEquipment = () => {
   const [clients, setClients] = useState<Client[]>([]);
 
-  const [clientID, setClientID] = useState<number>(0);
+  const [clientID, setClientID] = useState<number>();
 
   const { registerEquipment } = useEquipment();
 
@@ -39,7 +39,7 @@ const FormEquipment = () => {
   } = methods;
 
   const handleCreateEquipment = (data: EquipmentType) => {
-    registerEquipment(data, clientID);
+    registerEquipment(data, clientID as number);
   };
   return (
     <div className="h-full flex flex-col gap-4 font-medium  w-3/4 md:w-1/2">
@@ -82,8 +82,8 @@ const FormEquipment = () => {
       ) : (
         <InputSelect
           placeholder="Selecione Cliente"
-          clients={clients}
-          setClientID={setClientID}
+          list={clients as SelectType[]}
+          setValue={setClientID}
         />
       )}
 
diff --git a/src/components/formOrder/formOrder.tsx b/src/components/formOrder/formOrder.tsx
new file mode 100644
index 0000000..93736a7
--- /dev/null
+++ b/src/components/formOrder/formOrder.tsx
@@ -0,0 +1,74 @@
+import orderSchema, { OrderType } from "@/schemas/order";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { FormProvider, useForm } from "react-hook-form";
+import Input from "../input/input";
+import ButtonPrimary from "../buttonPrimary/buttonPrimary";
+import InputSelect, { SelectType } from "../inputSelect/inputSelect";
+import useFormOrder from "@/hook/useFormOrder";
+
+
+const FormOrder = () => {
+  
+  const methods = useForm<OrderType>({ resolver: zodResolver(orderSchema) });
+
+  const {clients, parts, 
+    services, setClientId, 
+    setSelectedPartId, setSelectedServiceId, 
+    handleCreateOrder } = useFormOrder()
+
+const {
+    formState: { errors },
+    handleSubmit,
+  } = methods;
+
+  return (
+    <div>
+      <FormProvider {...methods}>
+        <Input
+          formName="date"
+          placeholder="Nome"
+          className="py-8 text-xl placeholder-[#D4D4D8] text-[#D4D4D8]"
+        />
+        {errors.date && (
+          <p className="text-red-500 text-sm">{errors.date.message}</p>
+        )}
+        <Input
+          formName="status"
+          placeholder="Status"
+          className="py-8 text-xl placeholder-[#D4D4D8] text-[#D4D4D8]"
+        />
+        {errors.status && (
+          <p className="text-red-500 text-sm">{errors.status.message}</p>
+        )}
+        <Input
+          formName="comment"
+          placeholder="Comentário"
+          className="py-8 text-xl placeholder-[#D4D4D8] text-[#D4D4D8]"
+        />
+        {errors.comment && (
+          <p className="text-red-500 text-sm">{errors.comment.message}</p>
+        )}
+      </FormProvider>
+      <InputSelect
+        list={services as SelectType[]}
+        placeholder="Serviços"
+        setValue={setSelectedServiceId}
+      />
+        <InputSelect
+        list={parts as SelectType[]}
+        setValue={setSelectedPartId}
+        placeholder="Peças"
+      /> 
+     <InputSelect
+        list={clients}
+        setValue={setClientId}
+        placeholder="Cliente"
+      />  
+      <ButtonPrimary onClick={handleSubmit(handleCreateOrder)}>
+        Criar
+      </ButtonPrimary>
+    </div>
+  );
+};
+
+export default FormOrder;
diff --git a/src/components/formService/formService.tsx b/src/components/formService/formService.tsx
index fd742e3..5ad0e79 100644
--- a/src/components/formService/formService.tsx
+++ b/src/components/formService/formService.tsx
@@ -25,6 +25,14 @@ const FormService = () => {
   return (
     <div className="h-full flex flex-col gap-4 font-medium  w-3/4 md:w-1/2">
       <FormProvider {...methods}>
+        <Input
+          formName="name"
+          placeholder="Nome"
+          className="py-8 text-xl placeholder-[#D4D4D8] text-[#D4D4D8]"
+        />
+        {errors.name && (
+          <p className="text-red-500 text-sm">{errors.name.message}</p>
+        )}
         <Input
           formName="description"
           placeholder="Descrição"
diff --git a/src/components/clientSelect/clientSelect.tsx b/src/components/inputSelect/inputSelect.tsx
similarity index 60%
rename from src/components/clientSelect/clientSelect.tsx
rename to src/components/inputSelect/inputSelect.tsx
index e35fbed..9c89c88 100644
--- a/src/components/clientSelect/clientSelect.tsx
+++ b/src/components/inputSelect/inputSelect.tsx
@@ -6,37 +6,37 @@ import {
   SelectTrigger,
   SelectValue,
 } from "@/components/ui/select";
-import { Client } from "@/types";
 
-type ClientSelectProps = {
-  setClientID: React.Dispatch<React.SetStateAction<number>>;
+type SelectProps = {
+  setValue: React.Dispatch<React.SetStateAction<number | undefined>>;
   placeholder: string;
-  clients: Client[];
+  list?: SelectType[];
   className?: string;
 };
 
-const ClientSelect = ({
-  placeholder,
-  clients,
-  setClientID,
-}: ClientSelectProps) => {
+export type SelectType = {
+  id: number;
+  name: string;
+};
+
+const InputSelect = ({ placeholder, setValue, list = [] }: SelectProps) => {
   return (
     <div>
-      <Select onValueChange={(value) => setClientID(Number(value))}>
+      <Select onValueChange={(value) => setValue(Number(value))}>
         <SelectTrigger className="py-8 px-8 text-xl text-[#D4D4D8] bg-[#52525B] border-2 border-transparent hover:border-blue-500 focus:border-blue-500 focus:outline-none">
           <SelectValue placeholder={placeholder} />
         </SelectTrigger>
         <SelectContent className="bg-[#131314f4] text-white border-none">
           <SelectGroup>
-            {clients?.map((client) => (
+            {list?.map((item) => 
               <SelectItem
                 className="hover:bg-[#29292bf4] py-2"
-                key={client.id}
-                value={String(client.id)}
+                key={item?.id}
+                value={String(item?.id)}
               >
-                {client.name}
+                {item?.name}
               </SelectItem>
-            ))}
+            )}
           </SelectGroup>
         </SelectContent>
       </Select>
@@ -44,4 +44,4 @@ const ClientSelect = ({
   );
 };
 
-export default ClientSelect;
+export default InputSelect;
diff --git a/src/context/userProvider.tsx b/src/context/userProvider.tsx
index 2a8aa8e..d9c3b8d 100644
--- a/src/context/userProvider.tsx
+++ b/src/context/userProvider.tsx
@@ -7,10 +7,14 @@ type UserProviderProps = {
 };
 
 const UserProvider = ({ children }: UserProviderProps) => {
+  const localStorageUser =
+    JSON.parse(localStorage.getItem("user") as string) || {};
+
   const [user, setUser] = useState<User>({
-    email: "",
-    role: role.admin,
-    token: "",
+    id: localStorageUser.id || 0,
+    email: localStorageUser.email || "",
+    role: localStorageUser.role || role.admin,
+    token: localStorageUser.token || "",
   });
 
   const initialState = {
diff --git a/src/hook/useClient.tsx b/src/hook/useClient.tsx
index 6fd6a16..d2b28f0 100644
--- a/src/hook/useClient.tsx
+++ b/src/hook/useClient.tsx
@@ -45,7 +45,7 @@ const useClient = () => {
   const getAllClients = async () => {
     try {
       const response = await axios.get(`${BASE_URL}/client`, header);
-      const data: Client[] = response.data;
+      const data: Client[] = response.data.clients;
       return data;
     } catch (error) {
       const err = error as AxiosError;
diff --git a/src/hook/useFormOrder.tsx b/src/hook/useFormOrder.tsx
new file mode 100644
index 0000000..c1c9739
--- /dev/null
+++ b/src/hook/useFormOrder.tsx
@@ -0,0 +1,81 @@
+import UserContext from "@/context/userContext";
+import { Service, Part, Client } from "@/types";
+import { useState, useContext, useEffect } from "react";
+import useClient from "./useClient";
+import useOrder, { OrderPayload } from "./useOrder";
+import usePart from "./usePart";
+import UseService from "./useService";
+import { OrderType } from "@/schemas/order";
+
+const useFormOrder = () => {
+  const [services, setServices] = useState<Service[]>([]);
+  const [parts, setParts] = useState<Part[]>([]);
+  const [clients, setClients] = useState<Client[]>([]);
+  const [selectedServiceId, setSelectedServiceId] = useState<number>();
+  const [selectedPartId, setSelectedPartId] = useState<number>();
+  const [clientId, setClientId] = useState<number>();
+
+  const { getAllServices } = UseService();
+
+  const { getAllPart } = usePart();
+
+  const { getAllClients } = useClient();
+
+  const { registerOrder } = useOrder();
+
+  const {
+    user: { id: technicianId },
+  } = useContext(UserContext);
+
+  useEffect(() => {
+    const getServices = async () => {
+      const data = await getAllServices();
+      setServices(data as Service[]);
+    };
+    getServices();
+  }, []);
+
+  useEffect(() => {
+    const getParts = async () => {
+      const data = await getAllPart();
+      setParts(data as Part[]);
+    };
+    getParts();
+  }, []);
+
+  useEffect(() => {
+    const getClients = async () => {
+      const data = await getAllClients();
+      setClients(data as Client[]);
+      console.log(clients);
+    };
+    getClients();
+  }, []);
+
+  const handleCreateOrder = (data: OrderType) => {
+    const selectedService = services?.find(
+      (service) => service.id === selectedServiceId
+    );
+    const selectedPart = parts?.find((part) => part.id === selectedPartId);
+    const payLoad: OrderPayload = {
+      ...data,
+      services: [selectedService as Service],
+      parts: [selectedPart as Part],
+      technicianId: String(technicianId),
+      clientId: String(clientId),
+    };
+    registerOrder(payLoad);
+  };
+
+  return {
+    clients,
+    parts,
+    services,
+    handleCreateOrder,
+    setClientId,
+    setSelectedServiceId,
+    setSelectedPartId,
+  };
+};
+
+export default useFormOrder;
diff --git a/src/hook/useOrder.tsx b/src/hook/useOrder.tsx
new file mode 100644
index 0000000..f63a487
--- /dev/null
+++ b/src/hook/useOrder.tsx
@@ -0,0 +1,50 @@
+import { BASE_URL } from "@/constants";
+import UserContext from "@/context/userContext";
+import { notifyPositionMap, notifyType, Part, Service } from "@/types";
+import axios, { AxiosError } from "axios";
+import { useContext } from "react";
+import useNotify from "./useNotify";
+
+export type OrderPayload = {
+  date: string;
+  status: string;
+  comment: string;
+  clientId: string;
+  technicianId: string;
+  services: Service[];
+  parts: Part[];
+};
+
+const useOrder = () => {
+  const {
+    user: { token },
+  } = useContext(UserContext);
+
+  const header = { headers: { Authorization: `Bearer ${token}` } };
+
+  const notify = useNotify();
+
+  const registerOrder = async (payload: OrderPayload) => {
+    const urlRegisterOrder = `${BASE_URL}/order`;
+    try {
+      await axios.post(urlRegisterOrder, payload, header);
+      notify(
+        "Ordem de Serviço Registrada com Sucesso!",
+        notifyPositionMap.topRight,
+        notifyType.success
+      );
+    } catch (error) {
+      const err = error as AxiosError;
+
+      notify(
+        err.message as string,
+        notifyPositionMap.topRight,
+        notifyType.error
+      );
+    }
+  };
+
+  return {registerOrder};
+};
+
+export default useOrder;
diff --git a/src/hook/usePart.tsx b/src/hook/usePart.tsx
index e14dfb2..5052a0d 100644
--- a/src/hook/usePart.tsx
+++ b/src/hook/usePart.tsx
@@ -1,7 +1,7 @@
 import { BASE_URL } from "@/constants";
 import UserContext from "@/context/userContext";
 import { PartType } from "@/schemas/parts";
-import { notifyPositionMap, notifyType } from "@/types";
+import { notifyPositionMap, notifyType, Part } from "@/types";
 import axios, { AxiosError } from "axios";
 import { useContext } from "react";
 import useNotify from "./useNotify";
@@ -43,7 +43,24 @@ const usePart = () => {
     }
   };
 
-  return { registerPart };
+  const getAllPart = async () => {
+    const requestURL = `${BASE_URL}/part`;
+    try {
+      const response = await axios.get(requestURL, header);
+      const data: Part[] = response.data.parts;
+      return data;
+    } catch (error) {
+      const err = error as AxiosError;
+
+      notify(
+        err.message as string,
+        notifyPositionMap.topRight,
+        notifyType.error
+      );
+    }
+  };
+
+  return { registerPart, getAllPart };
 };
 
 export default usePart;
diff --git a/src/hook/useService.tsx b/src/hook/useService.tsx
index feb445a..6f45a33 100644
--- a/src/hook/useService.tsx
+++ b/src/hook/useService.tsx
@@ -1,22 +1,33 @@
 import { BASE_URL } from "@/constants";
 import { ServicesType } from "@/schemas/services";
-import { notifyPositionMap, notifyType } from "@/types";
+import { notifyPositionMap, notifyType, Service } from "@/types";
 import axios, { AxiosError } from "axios";
 import useNotify from "./useNotify";
+import { useContext } from "react";
+import UserContext from "@/context/userContext";
 
 const UseService = () => {
   const notify = useNotify();
 
+  const {
+    user: { token },
+  } = useContext(UserContext);
+
+  const header = {
+    headers: { Authorization: `Bearer ${token}` },
+  };
+
+  const serviceEndpoint = `${BASE_URL}/service`;
+
   const registerService = async (data: ServicesType) => {
     const payload = {
       ...data,
       price: Number(data.price),
       time: Number(data.time),
     };
-    const urlRegister = `${BASE_URL}/service`;
 
     try {
-      await axios.post(urlRegister, payload);
+      await axios.post(serviceEndpoint, payload, header);
 
       notify(
         "Serviço Registrado com Sucesso!",
@@ -34,7 +45,26 @@ const UseService = () => {
     }
   };
 
-  return { registerService };
+  const getAllServices = async () => {
+    if (!token) {
+      return;
+    }
+    try {
+      const response = await axios.get(serviceEndpoint, header);
+      const data: Service[] = response.data.services; 
+      return data;
+    } catch (error) {
+      const err = error as AxiosError;
+
+      notify(
+        err.message as string,
+        notifyPositionMap.topRight,
+        notifyType.error
+      );
+    }
+  };
+
+  return { registerService, getAllServices };
 };
 
 export default UseService;
diff --git a/src/schemas/order.ts b/src/schemas/order.ts
new file mode 100644
index 0000000..8a8ea9a
--- /dev/null
+++ b/src/schemas/order.ts
@@ -0,0 +1,11 @@
+import { z } from "zod";
+
+export type OrderType = z.infer<typeof orderSchema>;
+
+const orderSchema = z.object({
+  date: z.string().min(1, "Data é obrigatória"),
+  status: z.string(),
+  comment: z.string(),
+});
+
+export default orderSchema;
diff --git a/src/schemas/services.ts b/src/schemas/services.ts
index e592030..6a63a01 100644
--- a/src/schemas/services.ts
+++ b/src/schemas/services.ts
@@ -3,6 +3,7 @@ import { z } from "zod";
 export type ServicesType = z.infer<typeof servicesSchema>;
 
 const servicesSchema = z.object({
+  name: z.string().min(1, "Nome é obrigatório"),
   description: z.string(),
   price: z.string().min(1, "Preço é obrigatório"),
   time: z.string().min(1, "Tempo estimado é obrigatório"),
diff --git a/src/types.ts b/src/types.ts
index 93308f2..7c7d230 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -21,6 +21,7 @@ export enum role {
 }
 
 export type User = {
+  id: number;
   token: string;
   email: string;
   role: role;
@@ -34,9 +35,24 @@ export type Client = {
   phone: string;
 };
 
+export type Service = {
+  id: number;
+  name: string;
+  description: string;
+  time: number;
+  price: number;
+};
+
+export type Part = {
+  id: number;
+  name: string;
+  description: string;
+  quantity: number;
+  price: number;
+};
 export type Technician = {
   email: string;
   id: number;
   name: string;
   phone: string;
-};
\ No newline at end of file
+};


Reviews:
user: login: Wesleysoares7
body: Boa!
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-29T17:06:22Z
user: login: Josieljcc
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-29T17:09:41Z
user: login: Josieljcc
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-29T17:57:21Z
user: login: Josieljcc
state: APPROVED
author_association: OWNER
submitted_at: 2025-03-29T18:01:09Z
user: login: Wesleysoares7
body: Boa!
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-29T18:01:43Z
user: login: Wesleysoares7
body: Boa!
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-29T18:03:17Z

Review comments:
diff_hunk: @@ -0,0 +1,28 @@
+import FormOrder from "@/components/formOrder/formOrder";
+import UserContext from "@/context/userContext";
+import { role } from "@/types";
+import { useContext, useEffect } from "react";
+import { useNavigate } from "react-router-dom";
+
+const Order = () => {
+  
+  const { user, setUser } = useContext(UserContext);
+  const navigate = useNavigate();
+  useEffect(() => {
+    const localStorageUser =
+      JSON.parse(localStorage.getItem("user") as string) || {};
+
+    if (
+      user.role === role.client ||
+      localStorageUser?.role === role.client ||
+      (!user.token && !localStorageUser.token)
+    ) {
+      navigate("/login");
+    }
+
+    setUser(localStorageUser);
+  }, []);
path: src/Pages/order.tsx
user: login: Josieljcc
body: Acredito que já existe um hook que faz essa verificação de autenticação.
created_at: 2025-03-29T17:05:04Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,133 @@
+import orderSchema, { OrderType } from "@/schemas/order";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { FormProvider, useForm } from "react-hook-form";
+import Input from "../input/input";
+import ButtonPrimary from "../buttonPrimary/buttonPrimary";
+import UseService from "@/hook/useService";
+import { useContext, useEffect, useState } from "react";
+import { Client, Part, Service } from "@/types";
+import InputSelect, { SelectType } from "../inputSelect/inputSelect";
+import usePart from "@/hook/usePart";
+import useClient from "@/hook/useClient";
+import UserContext from "@/context/userContext";
+import useOrder, { OrderPayload } from "@/hook/useOrder";
+
+const FormOrder = () => {
+  const [services, setServices] = useState<Service[]>([]);
+  const [parts, setParts] = useState<Part[]>([]);
+  const [clients, setClients] = useState<Client[]>([]);
+  const [selectedServiceId, setSelectedServiceId] = useState<number>();
+  const [selectedPartId, setSelectedPartId] = useState<number>();
+  const [clientId, setClientId] = useState<number>();
+
+  const methods = useForm<OrderType>({ resolver: zodResolver(orderSchema) });
+
+  const { getAllServices } = UseService();
+
+  const { getAllPart } = usePart();
+
+  const { getAllClients } = useClient();
+
+  const { registerOrder } = useOrder();
+
+  const {
+    user: { id: technicianId },
+  } = useContext(UserContext);
+
+  useEffect(() => {
+    const getServices = async () => {
+      const data = await getAllServices();
+      setServices(data as Service[]);
+    };
+    getServices();
+  }, []);
+
+  useEffect(() => {
+    const getParts = async () => {
+      const data = await getAllPart();
+      setParts(data as Part[]);
+    };
+    getParts();
+  }, []);
+
+  useEffect(() => {
+    const getClients = async () => {
+      const data = await getAllClients();
+      setClients(data as Client[]);
+      console.log(clients);
+      
+    };
+    getClients();
+  }, []);
+
+  const {
+    formState: { errors },
+    handleSubmit,
+  } = methods;
+
+  const handleCreateOrder = (data: OrderType) => {
+    const selectedService = services?.find(
+      (service) => service.id === selectedServiceId
+    );
+    const selectedPart = parts?.find((part) => part.id === selectedPartId);
+    const payLoad: OrderPayload = {
+      ...data,
+      services: [selectedService as Service],
+      parts: [selectedPart as Part],
+      technicianId: String(technicianId),
+      clientId: String(clientId),
+    };
+    registerOrder(payLoad);
+  };
path: src/components/formOrder/formOrder.tsx
user: login: Josieljcc
body: Muita lógica de negócio dentro do componente, acredito que seria legal criar um hook, useFormOrder para melhor organização do código.
created_at: 2025-03-29T17:07:10Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,86 @@
+import UserContext from "@/context/userContext";
+import { Service, Part, Client } from "@/types";
+import { useState, useContext, useEffect } from "react";
+import useClient from "./useClient";
+import useOrder, { OrderPayload } from "./useOrder";
+import usePart from "./usePart";
+import UseService from "./useService";
+import { OrderType } from "@/schemas/order";
+
+const useFormOrder = () => {
+
+
path: src/hook/useFormOrder.tsx
user: login: Josieljcc
body: ```suggestion
```
created_at: 2025-03-29T17:56:48Z
author_association: OWNER

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-03-29T18:01:03Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=Josieljcc_info-os-fontend&pullRequest=14) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=Josieljcc_info-os-fontend&pullRequest=14&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=Josieljcc_info-os-fontend&pullRequest=14&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=Josieljcc_info-os-fontend&pullRequest=14&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=Josieljcc_info-os-fontend&pullRequest=14&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [2.1% Duplication on New Code](https://sonarcloud.io/component_measures?id=Josieljcc_info-os-fontend&pullRequest=14&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=Josieljcc_info-os-fontend&pullRequest=14)


author_association: NONE