انتقل إلى المحتوى الرئيسي

المطابخ

صورة المطبخ

هنا الصفحة الخاصة باضافة , تعديل , حذف ورؤية تفاصيل كل المطابخ الي ضفتها

فايلات الفولدر

KitchenRequest.ts;
columns.ts;
useKitchens.ts;
KitchenView.tsx;

KitchenRequest.ts

import { TFunction } from "i18next";
import * as z from "zod";

export const schema = (t: TFunction) =>
z.object({
name: z.string({
required_error: t("pages.kitchens.inputs.name.errors.required"),
}),
hasPrinter: z.boolean().optional(),
isTotalPrint: z.boolean().optional(),
dontPrintInCon: z.boolean().optional(),
printer: z.number().optional(),
});

export type KitchenRequestType = z.infer<ReturnType<typeof schema>>;
  • هذا هو السكيما مال عملية ادخال مطبخ جديد ويا الشروط لكل انبوت سواء كان (String , Number , Boolean)
  • ايضا راح يكون اكو باراميتر الي هو من نوع tFunction علمود ال Localization

columns.ts


export const getColumns = (t: TFunction): ColumnDef<Kitchen>[] => {
return [
{
id: 'id',
accessorKey: "id",
header: t("id"),
size: 10,
enableSorting: true,
meta: {
align: 'center'
},
} ]
  • هذا الفايل اخذت من عندة جزء صغير بس علمود تفهم الفكرة بشكل مبدئي لان فايل ال Columns هو فايل مشترك بين الصفحات اللخ
  • لتقريب فكرة ملف ال Columns انت عندك table بالصفحة وكاعد تعرض بيانات فانت هنا سويت شغلتين
    • سويت Shared Component اسمة InfiniteScrollDataTable هذا راح يخليك تستخدمة باي مكان تحتاج تعرض بيه تيبل وبيه بيانات
    • بحكم سويت واحد داينمك انت محتاج الة اعمدة ونوع البيانات واسمها وتفاصيل لخ تخص كل عمود وقميتة ... لهذا انت راح تسوي فايل اسمة Columns
  • هذا الفايل من اسمة راح تحط كل الاعمدة مالتك وراح تحط اسماء المتغيرات الي كاعد تجيك من الباك وراح تخلي يعرضها بشكل ديناميكي ملاحظة : راح يتم شرح InfiniteScrollDataTable ايضا بفولدر اسمة فايلات مشتركة لانه تم استخدامة باكثر من مكان وراح يتم شرح القيم مال الاعمدة ايضا بنفس الفولدر

useKitchens.ts

// create new kitchen
const createKitchen = useMutation({
mutationFn: CreateKitchen,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["kitchens"],
});
reset(defaultValues);
setSelectedKitchen(null);
setOpenDialog(false);
toast.success(t("successMessage"));
},
onError: (error) => {
const errorMessage = (error as any)?.response?.data?.message;
const errorReason = (error as any)?.response?.data[0]?.reason;
toast.error(t("errorMessage"), {
description: `${errorMessage}${errorReason ? `:${errorReason}` : ""}`,
});
},
});
  • createKitchen : هاي راح تستقبل البيانات من الفورمة الي كاعد يعبي بيها اليوزر البيانات مالتة عن المطبخ وراح تصفر القيم من يصير نجاح بالعملية ويغلق الفورمة مالتك
// ------------------------ //
const openAddDialog = () => {
setSelectedKitchen(null);
setOpenDialog(true);
reset(defaultValues);
};

// ------------------------ //
const onSubmit = (data: KitchenRequestType) => {
const printer = printers?.find(
(printer, index) => index == Number(data.printer)
);
const result = printer
? { name: printer.name, ipAddress: printer.ipAddress, port: printer.port }
: undefined;
const refinedData = {
name: data.name,
isTotalPrint: data.isTotalPrint,
dontPrintInCon: data.dontPrintInCon,
printer: data.hasPrinter ? result : undefined,
};
if (selectedKitchen) {
editKitchenMutation.mutate({ ...refinedData, id: selectedKitchen });
} else {
createKitchen.mutate(refinedData);
}
};
  • openAddDialog : هاي راح تفتح الفورمة مال اضافة مطبخ جديد وتصفر القيم مال المطبخ في حال اكو قديمة
  • onSubmit : هنا راح يبحث عن الطابعة وراح يجيك اذا اكو طابعة راح يدخل الاسم وال IP مالتها والبورت الي اجاه واذا لا راح يحط Undefined
    • ايضا راح يحط البيانات بشكل اوبجكت جديد وراح يجيك اذا المطعم مختارة اذاً راح يعدل عليه واذا لا راح يضيف واحد جديد
// ------------ Edit Kitchen ------------- //
const openEditDialog = (id: number) => {
const kitchen = kitchens?.pages
.flatMap((d) => d)
?.find((kit) => kit.id == id);
if (kitchen) {
setSelectedKitchen(kitchen.id);
setOpenDialog(true);
reset({
name: kitchen.name,
isTotalPrint: kitchen.isTotalPrint ? true : false,
dontPrintInCon: kitchen.dontPrintInCon ? true : false,
hasPrinter: kitchen.printer ? true : false,
printer: kitchen.printer
? printers?.findIndex((p) => p == kitchen.printer)
: undefined,
});
}
};
// ------------------------- //

const editKitchenMutation = useMutation({
mutationFn: EdiTKitchen,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["kitchens"],
});
reset(defaultValues);
setSelectedKitchen(null);
setOpenDialog(false);
toast.success(t("successMessage"));
},
onError: (error) => {
const errorMessage = (error as any)?.response?.data?.message;
const errorReason = (error as any)?.response?.data[0]?.reason;
toast.error(t("errorMessage"), {
description: `${errorMessage}${errorReason ? `:${errorReason}` : ""}`,
});
},
});
  • openEditDialog : هنا راح يجيك اذا اكو مطبخ لو لا واذا اكو راح يصفر القيم القديمة وراح يفتح الفورمة مال التعديل وراح يحط البيانات مال المطبخ الي لكاه
  • editKitchenMutation : هنا راح يعبر البيانات من onSubmit وراح يسوي Put Request ومن ينجح راح يصفر القيم وراح يغلق الفورمة مال التعديل ويطلع رسالة نجاح بالتحديث
// --------------- Delete Kitchen -------------- //
const openDeleteDialog = (id: number) => {
const kitchen = kitchens?.pages
.flatMap((d) => d)
?.find((kitchen) => kitchen.id == id);
if (kitchen) {
setSelectedKitchen(id);
setDeleteDialog(true);
}
};
// ----------------------------- //
const deleteKitchenMutation = useMutation({
mutationFn: deleteKitchen,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["kitchens"],
});
setDeleteDialog(false);
setSelectedKitchen(null);
reset(defaultValues);
toast.success(t("successMessage"));
},
onError: (error) => {
const errorMessage = (error as any)?.response?.data?.message;
const errorReason = (error as any)?.response?.data[0]?.reason;
toast.error(t("errorMessage"), {
description: `${errorMessage}${errorReason ? `:${errorReason}` : ""}`,
});
},
});
// ----------------------------- //
const handleDelete = () => {
if (selectedKitchen) {
deleteKitchenMutation.mutate(selectedKitchen);
}
};
  • openDeleteDialog : هنا راح يبحث عن المطبخ اذا اكو راح يفتح Dialog مال تأكيد الحذف
  • handleDelete : هنا اذا اكو مطبخ واليوزر داس حذف راح يفعل دالة الحذف
  • deleteKitchenMutation : هنا الاسطر الخاصة بالحذف الي راح تقوم بعملية الحذف الفعلي وتتواصل ويا الباك ايند وبنجاح عملية الحذف راح يغلق ال Dialog مال الحذف وراح يصفر القيم ويظهر رسالة نجاح على الحذف , وايضا اكيد راح يسوي Refetch بعد ما تم العملية

KitchenView.tsx

const { updateBreadcrumbs } = useBreadcrumbs();
useTitle(t("pages.kitchens.title"));
useEffect(() => {
updateBreadcrumbs([{ label: t("pages.kitchens.title"), link: "/kitchens" }]);
}, [i18n.language]);
//
const columns = useMemo(() => getColumns(t), []);
const hasPrinter = watch("hasPrinter", false);
  • هنا عندي الكود راح يحدث التايتل مال ال Breadcrumbs كل ما يتغير اللغة من عربي الى انكليزي وبالعكس
  • ايضا راح يستخدم ال useMemo علمود يجيب الاعمدة مرة وحدة باول دخولك للصفحة وباقي الوقت هي صاير الها كاش
  • الطابعة حيكون الها دالة ال Watch علمود تتبع القيمة مال الطابعة بشكل مباشر واذا مابيها قيمة راح ترجع false

ملاحظة : باقي اكواد الصفحة معاد استخدامها اكثر من مرة بعدة صفحات لهذا راح يتم الشرح عنها بصفحة منعزلة لتجنب تكرار الشرح ( راح يتم الشرح بفولدر الملفات المشتركة )