From c259ad3d99203f2b525953c0e1ca21859e98e82b Mon Sep 17 00:00:00 2001 From: Berkay Date: Tue, 24 Jun 2025 21:44:21 +0300 Subject: [PATCH] updated application pages build tested --- .../events/building_parts/supers_events.py | 1 + .../customer/src/hooks/useTableData.ts | 11 + .../multi/buildParts/superuser/CreatePage.tsx | 320 +++++++---- .../multi/buildParts/superuser/ListPage.tsx | 542 ------------------ .../multi/buildParts/superuser/UpdatePage.tsx | 30 +- .../buildParts/superuser/main/ListPage.tsx | 142 +++++ .../buildParts/superuser/main/columns.tsx | 104 ++++ .../buildParts/superuser/main/dataTable.tsx | 129 +++++ .../main/mobilePaginationControls.tsx | 34 ++ .../buildParts/superuser/main/tableForm.tsx | 152 +++++ .../buildParts/superuser/main/tableHeader.tsx | 24 + .../multi/buildParts/superuser/main/types.ts | 15 + .../multi/buildParts/superuser/schema.ts | 93 ++- .../buildParts/superuser/translations.ts | 35 +- .../pages/multi/builds/superuser/ListPage.tsx | 152 ++++- ServicesWeb/customer/src/pages/multi/index.ts | 2 +- 16 files changed, 1087 insertions(+), 699 deletions(-) delete mode 100644 ServicesWeb/customer/src/pages/multi/buildParts/superuser/ListPage.tsx create mode 100644 ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/ListPage.tsx create mode 100644 ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/columns.tsx create mode 100644 ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/dataTable.tsx create mode 100644 ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/mobilePaginationControls.tsx create mode 100644 ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/tableForm.tsx create mode 100644 ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/tableHeader.tsx create mode 100644 ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/types.ts diff --git a/ServicesApi/Builds/Building/events/building_parts/supers_events.py b/ServicesApi/Builds/Building/events/building_parts/supers_events.py index 1914851..1bc5629 100644 --- a/ServicesApi/Builds/Building/events/building_parts/supers_events.py +++ b/ServicesApi/Builds/Building/events/building_parts/supers_events.py @@ -60,6 +60,7 @@ SuperPartsDeleteEvent = Event( def super_parts_list_callable(list_options: PaginateOnly, headers: CommonHeaders): list_options = PaginateOnly(**list_options.model_dump()) # TODO: Pydantic Model must be implemnted for list_options.query + print('list_options', list_options.model_dump()) with Build.new_session() as db_session: BuildParts.set_session(db_session) base_query = BuildParts.query.filter() diff --git a/ServicesWeb/customer/src/hooks/useTableData.ts b/ServicesWeb/customer/src/hooks/useTableData.ts index a4427f7..38b7ace 100644 --- a/ServicesWeb/customer/src/hooks/useTableData.ts +++ b/ServicesWeb/customer/src/hooks/useTableData.ts @@ -63,6 +63,7 @@ export interface UseTableDataProps { mapFormToRequestBody?: (values: TableFormValues) => any; customFormSchema?: z.ZodType; customFormValues?: Record; + baseQuery?: Record; // Base query that will be merged with user query pageField?: keyof TableFormValues; sizeField?: keyof TableFormValues; orderFieldField?: keyof TableFormValues; @@ -77,6 +78,7 @@ export function useTableData({ mapFormToRequestBody, customFormSchema = defaultFormSchema, customFormValues = defaultFormValues, + baseQuery = {}, // Default empty base query pageField = "page" as keyof TableFormValues, sizeField = "size" as keyof TableFormValues, orderFieldField = "orderField" as keyof TableFormValues, @@ -161,6 +163,15 @@ export function useTableData({ query: values[queryField], }; + // Make sure query is not empty if baseQuery has values + if (Object.keys(baseQuery).length > 0) { + if (!requestBody.query || typeof requestBody.query !== "object") { + requestBody.query = {}; + } + // Add baseQuery properties to the query object + Object.assign(requestBody.query, baseQuery); + } + const response = await apiPostFetcher({ url: apiUrl, isNoCache: true, diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/CreatePage.tsx b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/CreatePage.tsx index 2768a7b..7f95166 100644 --- a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/CreatePage.tsx +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/CreatePage.tsx @@ -6,31 +6,18 @@ import { withCache } from "@/components/mutual/context/cache/withCache"; import { Button } from "@/components/mutual/ui/button"; import { Form } from "@/components/mutual/ui/form"; import { getCacheData, setCacheData, clearCacheData } from "@/components/mutual/context/cache/context"; +import { X } from "lucide-react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; -import { buildPartsSchemaCreate, BuildPartsCreateInterface, buildPartsSchema } from "./schema"; -import { buildPartsTranslations, translationsOfPage } from "./translations"; +import { buildPartsSchemaCreate, createEmptyValues } from "./schema"; +import { buildPartsTranslations, translationsOfPage, buildingTranslations } from "./translations"; import { LanguageTypes } from "@/validations/mutual/language/validations"; import { NumberInput } from "@/components/mutual/formInputs/NumberInput"; import { StringInput } from "@/components/mutual/formInputs/StringInput"; import { CheckBoxInput } from "@/components/mutual/formInputs/CheckBoxInput"; -const emptyValues: BuildPartsCreateInterface = { - build_uu_id: null, - address_gov_code: "", - part_no: 0, - part_level: 0, - part_code: "", - part_gross_size: 0, - part_net_size: 0, - default_accessory: "0", - human_livable: true, - due_part_key: "", - part_direction_uu_id: null, -}; - function CreateFromComponentBase({ onlineData, cacheData, @@ -53,17 +40,29 @@ function CreateFromComponentBase({ const language: LanguageTypes = onlineData?.lang || 'en'; const router = useRouter(); const listUrl = `/panel/${activePageUrl?.replace("/create", "")}`; + const [selectedBuilding, setSelectedBuilding] = useState(null); + const [formError, setFormError] = useState(""); const [cacheLoaded, setCacheLoaded] = useState(false); - const form = useForm({ - resolver: zodResolver(buildPartsSchemaCreate), - defaultValues: emptyValues - }); + const form = useForm({ resolver: zodResolver(buildPartsSchemaCreate), defaultValues: createEmptyValues }); + + useEffect(() => { + const checkCacheForSelectedBuild = async () => { + try { + const cachedData = await getCacheData("/build/list"); + if (cachedData && cachedData.build) { + setSelectedBuilding(cachedData.build); + const formValues = form.getValues(); + form.setValue("build_uu_id", cachedData.build.uu_id); + } + } catch (error) { console.error("Error checking cache for selected build:", error) } + }; + checkCacheForSelectedBuild(); + }, [form]); useEffect(() => { const fetchCacheDirectly = async () => { if (!cacheLoaded) { try { - console.log("Directly fetching cache for URL:", activePageUrl); const cachedData = await getCacheData(activePageUrl); if (cachedData) { const formValues = form.getValues(); @@ -102,16 +101,191 @@ function CreateFromComponentBase({ }; const onSubmit = async (data: any) => { + setFormError(""); + if (!data.build_uu_id && selectedBuilding) { data.build_uu_id = selectedBuilding.uu_id } + if (!data.build_uu_id) { + const errorMessage = language === 'en' ? "Missing building ID. Please select a building first." : "Bina ID'si eksik. Lütfen önce bir bina seçin."; + console.error('errorMessage', errorMessage); + setFormError(errorMessage); + return; + } console.log("Form submitted with data:", data); - try { const response = await apiPostFetcher({ url: `/api/parts/create`, isNoCache: true, body: data }); await clearCacheData(activePageUrl); if (clearCache) { clearCache(activePageUrl) } - if (response.success) { form.reset(emptyValues); router.push(listUrl) } - } catch (error) { console.error("Error submitting form:", error) } + if (response.success) { form.reset(createEmptyValues); router.push(listUrl) } + } catch (error) { + console.error("Error submitting form:", error); + setFormError(language === 'en' ? "Error submitting form" : "Form gönderilirken hata oluştu"); + } } + const formComponent = <> +
+ + {/* ----- Basic Information ----- */} + {/* Address Government Code */} + + + {/* ----- Part Identification ----- */} + {/* Part Number */} + + + {/* Part Level */} + + + {/* Part Code */} + + + {/* ----- Size Information ----- */} + {/* Part Gross Size */} + + + {/* Part Net Size */} + + + {/* ----- Additional Properties ----- */} + {/* Default Accessory */} + + + {/* Human Livable */} + + + {/* Due Part Key */} + + + {/* Part Direction UUID */} + + + {/* ----- Submit Button ----- */} + + + + + + const noSelectedBuildingComponent =
+
+ {buildingTranslations[language].noSelectedBuilding} +
+ +
+ + const mainComponent =
+ {/* Header with title and change button */} +
+

+ {buildingTranslations[language].selectedBuilding} +

+ +
+ + {/* Building details grid */} +
+ {/* UUID */} +
+ UUID: + {selectedBuilding.uu_id} +
+ + {/* Building Name */} +
+ {buildingTranslations[language].buildName}: + {selectedBuilding.build_name} +
+ + {/* Building Number */} +
+ {buildingTranslations[language].buildNo}: + {selectedBuilding.build_no} +
+ + {/* Address Code */} +
+ {buildingTranslations[language].buildAddressCode}: + {selectedBuilding.gov_address_code} +
+ + {/* Max Floor */} +
+ {buildingTranslations[language].buildMaxFloor}: + {selectedBuilding.max_floor} +
+
+
+ return (
{/* back to list button */} @@ -119,100 +293,10 @@ function CreateFromComponentBase({

{translationsOfPage[language].title}

-
- - {/* Address Government Code */} - - - {/* Part Number */} - - - {/* Part Level */} - - - {/* Part Code */} - - - {/* Part Gross Size */} - - - {/* Part Net Size */} - - - {/* Default Accessory */} - - - {/* Human Livable */} - - - {/* Due Part Key */} - - - {/* Part Direction UUID */} - - - - - + {/* ===== BUILDING SELECTION SECTION ===== */} + {selectedBuilding ? mainComponent : noSelectedBuildingComponent} + {/* ===== FORM SECTION ===== */} + {selectedBuilding && formComponent} ); } diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/ListPage.tsx b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/ListPage.tsx deleted file mode 100644 index 02a8585..0000000 --- a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/ListPage.tsx +++ /dev/null @@ -1,542 +0,0 @@ -'use client'; -import React from "react"; -import { - useReactTable, - getCoreRowModel, - getSortedRowModel, - getPaginationRowModel, - flexRender, - createColumnHelper, - ColumnDef, -} from "@tanstack/react-table"; -import { buildPartsTranslations } from './translations'; -import { UseFormReturn } from "react-hook-form"; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage -} from "@/components/mutual/ui/form"; -import { Button } from "@/components/mutual/ui/button"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/mutual/ui/select"; -import { API_BASE_URL } from "@/config/config"; -import { useTableData } from "@/hooks/useTableData"; -import { LanguageTypes } from "@/validations/mutual/language/validations"; -import { - Translations, - TableHeaderProps, - LoadingSpinnerProps, - ErrorDisplayProps, - MobilePaginationControlsProps, - DashboardPageProps, -} from "@/validations/mutual/table/validations"; -import LoadingContent from "@/components/mutual/loader/component"; -import { Pencil } from "lucide-react"; -import { useRouter } from "next/navigation"; -import { setCacheData } from "@/components/mutual/context/cache/context"; -import { BuildPartsSchemaInterface } from "./schema"; - -interface DataTableProps { - table: ReturnType; - tableData: BuildPartsSchemaInterface[]; - isLoading: boolean; - handleSortingChange: (columnId: string) => void; - getSortingIcon: (columnId: string) => React.ReactNode; - flexRender: typeof flexRender; - t: Translations; -} - -interface TableFormProps { - form: UseFormReturn; - handleFormSubmit: (e: React.FormEvent) => void; - handleSelectChange: (value: string, field: { onChange: (value: number) => void }) => void; - renderPageOptions: () => { key: string | number; value: string; label: string }[]; - pageSizeOptions: number[]; - apiPagination: { - size: number; - page: number; - totalCount: number; - totalPages: number; - pageCount: number; - }; - handleFirstPage: () => void; - handlePreviousPage: () => void; - handleNextPage: () => void; - isPreviousDisabled: () => boolean; - isNextDisabled: () => boolean; - t: Translations; -} - -const translations: Record = { - en: { - dataTable: 'Data Table', - tableWithApiData: 'Table with API Data', - loading: 'Loading...', - noDataAvailable: 'No data available', - page: 'Page', - size: 'Size', - total: 'Total', - items: 'items', - first: 'First', - previous: 'Previous', - next: 'Next', - selectPage: 'Select page', - selectSize: 'Select size', - actionButtonGroup: 'Actions', - }, - tr: { - dataTable: 'Veri Tablosu', - tableWithApiData: 'API Verili Tablo', - loading: 'Yükleniyor...', - noDataAvailable: 'Veri bulunamadı', - page: 'Sayfa', - size: 'Boyut', - total: 'Toplam', - items: 'öğe', - first: 'İlk', - previous: 'Önceki', - next: 'Sonraki', - selectPage: 'Sayfa seç', - selectSize: 'Boyut seç', - actionButtonGroup: 'Eylemler', - } -}; - -const DataTable: React.FC = React.memo(({ - table, - tableData, - isLoading, - handleSortingChange, - getSortingIcon, - flexRender, - t, -}) => { - return ( -
- {/* Semi-transparent loading overlay that preserves interactivity */} - {isLoading && ( -
- {/* We don't put anything here as we already have the loading indicator in the header */} -
- )} - - - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - ); - })} - - ))} - - - {tableData.length === 0 && !isLoading ? ( - - - - ) : ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => { - return ( - - ); - })} - - )) - )} - -
{t.dataTable}
handleSortingChange(header.column.id)} - aria-sort={header.column.getIsSorted() ? (header.column.getIsSorted() === 'desc' ? 'descending' : 'ascending') : undefined} - scope="col" - > -
- {flexRender(header.column.columnDef.header, header.getContext())} - {getSortingIcon(header.column.id)} -
-
- {t.noDataAvailable} -
- {flexRender(cell.column.columnDef.cell, cell.getContext())} -
-
- ); -}); - -const TableForm: React.FC = ({ - form, - handleFormSubmit, - handleSelectChange, - renderPageOptions, - pageSizeOptions, - apiPagination, - handleFirstPage, - handlePreviousPage, - handleNextPage, - isPreviousDisabled, - isNextDisabled, - t -}) => { - return ( -
-
- -
- ( - - {t.page} - - - - )} - /> -
-
- ( - - {t.size} - - - - )} - /> -
-
-

- {t.page}: {apiPagination.page}{" / "} {apiPagination.totalPages} · - {t.size}: {apiPagination.pageCount}{" / "} {apiPagination.size} · - {t.total}: {apiPagination.totalCount} {t.items} -

-
-
- - - - {/* */} -
-
- -
- ); -}; - -const MobilePaginationControls: React.FC = ({ - handlePreviousPage, - handleNextPage, - isPreviousDisabled, - isNextDisabled, - t -}) => { - return ( -
-
- - -
-
- ); -}; - -const TableHeader: React.FC = ({ title, description, isLoading, error, t }) => { - return ( - -
-
-
-

{title}

-

{description}

-
- {/* {isLoading && } */} - {error && } -
-
- ); -}; - -const ErrorDisplay: React.FC = ({ message }) => { - return
{message}
; -}; - -const BuildListPage: React.FC = React.memo((props) => { - // Initialize translation with English as default - const language = props.onlineData?.lang as LanguageTypes || 'en'; - const t = translations[language]; - const searchParams = props.searchParams; - console.log('searchParams', searchParams); - const router = useRouter(); - - const { - form, - tableData, - sorting, - isLoading, - error, - pagination, - apiPagination, - setSorting, - handleSortingChange, - handleSelectChange, - handlePageChange, - handleFirstPage, - handlePreviousPage, - handleNextPage, - getSortingIcon, - handleFormSubmit, - // Disabled states - isPreviousDisabled, - isNextDisabled, - pageSizeOptions, - renderPageOptions, - } = useTableData({ apiUrl: `${API_BASE_URL}/parts/list` }); - - const activePageUrl = props.activePageUrl || ''; - const handleEditRow = async (row: BuildPartsSchemaInterface) => { - try { - // Store the row data in the cache - await setCacheData(`${activePageUrl}/update`, row); - console.log('Row data stored in cache:', row); - - // Navigate to the update form - router.push(`/panel/${activePageUrl}/update`); - } catch (error) { - console.error('Error storing row data in cache:', error); - } - }; - - const actionButtonGroup = (info: any) => ( - - ); - - const columnHelper = createColumnHelper(); - const columns = React.useMemo(() => [ - columnHelper.display({ - id: 'actions', - header: () => {t.actionButtonGroup}, - cell: (info) => { return (actionButtonGroup(info)) } - }), - // columnHelper.accessor('uu_id', { - // cell: info => info.getValue(), - // header: () => {buildPartsTranslations[language].uu_id}, - // footer: info => info.column.id - // }), - // columnHelper.accessor('build_uu_id', { - // cell: info => info.getValue(), - // header: () => {buildPartsTranslations[language].build_uu_id}, - // footer: info => info.column.id - // }), - columnHelper.accessor('address_gov_code', { - cell: info => info.getValue(), - header: () => {buildPartsTranslations[language].address_gov_code}, - footer: info => info.column.id - }), - columnHelper.accessor('part_no', { - cell: info => String(info.getValue()), - header: () => {buildPartsTranslations[language].part_no}, - footer: info => info.column.id - }), - columnHelper.accessor('part_level', { - cell: info => String(info.getValue()), - header: () => {buildPartsTranslations[language].part_level}, - footer: info => info.column.id - }), - columnHelper.accessor('part_code', { - cell: info => info.getValue(), - header: () => {buildPartsTranslations[language].part_code}, - footer: info => info.column.id - }), - columnHelper.accessor('part_gross_size', { - cell: info => String(info.getValue()), - header: () => {buildPartsTranslations[language].part_gross_size}, - footer: info => info.column.id - }), - columnHelper.accessor('part_net_size', { - cell: info => String(info.getValue()), - header: () => {buildPartsTranslations[language].part_net_size}, - footer: info => info.column.id - }), - columnHelper.accessor('default_accessory', { - cell: info => info.getValue(), - header: () => {buildPartsTranslations[language].default_accessory}, - footer: info => info.column.id - }), - columnHelper.accessor('human_livable', { - cell: info => info.getValue() ? 'Yes' : 'No', - header: () => {buildPartsTranslations[language].human_livable}, - footer: info => info.column.id - }), - columnHelper.accessor('due_part_key', { - cell: info => info.getValue(), - header: () => {buildPartsTranslations[language].due_part_key}, - footer: info => info.column.id - }), - columnHelper.accessor('part_direction_uu_id', { - cell: info => info.getValue() || '', - header: () => {buildPartsTranslations[language].part_direction_uu_id}, - footer: info => info.column.id - }), - ], [columnHelper]) as ColumnDef[]; - - const table = useReactTable({ - data: tableData, - columns, - state: { sorting, pagination }, - onSortingChange: setSorting, - getCoreRowModel: getCoreRowModel(), - getSortedRowModel: getSortedRowModel(), - getPaginationRowModel: getPaginationRowModel(), - manualPagination: true, - pageCount: apiPagination.totalPages || 1, - }) - - return ( - isLoading ? : -
- -
- - -
- - - - {/* Mobile pagination controls - only visible on small screens */} - - - -
- ); -}); - -export default BuildListPage; diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/UpdatePage.tsx b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/UpdatePage.tsx index 98cb01f..9615018 100644 --- a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/UpdatePage.tsx +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/UpdatePage.tsx @@ -11,28 +11,13 @@ import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { LanguageTypes } from "@/validations/mutual/language/validations"; -import { buildPartsSchema, BuildPartsInterface } from "./schema"; +import { buildPartsSchema, updateEmptyValues } from "./schema"; import { buildPartsTranslations, translationsOfPage } from "./translations"; import { CheckBoxInput } from "@/components/mutual/formInputs/CheckBoxInput"; import { NumberInput } from "@/components/mutual/formInputs/NumberInput"; import { StringInput } from "@/components/mutual/formInputs/StringInput"; -const emptyValues: BuildPartsInterface = { - uu_id: "", - build_uu_id: null, - address_gov_code: "", - part_no: 0, - part_level: 0, - part_code: "", - part_gross_size: 0, - part_net_size: 0, - default_accessory: "0", - human_livable: true, - due_part_key: "", - part_direction_uu_id: null -}; - function UpdateFromComponentBase({ onlineData, cacheData, @@ -57,11 +42,7 @@ function UpdateFromComponentBase({ const [partUUID, setPartUUID] = useState(""); const router = useRouter(); const listUrl = `/panel/${activePageUrl?.replace("/update", "")}`; - const form = useForm({ - resolver: zodResolver(buildPartsSchema), - mode: "onSubmit", - defaultValues: emptyValues - }); + const form = useForm({ resolver: zodResolver(buildPartsSchema), mode: "onSubmit", defaultValues: updateEmptyValues }); useEffect(() => { const fetchData = async () => { @@ -108,10 +89,7 @@ function UpdateFromComponentBase({ const onSubmit = async (data: any) => { try { console.log('Form data received:', data); - const formattedData = { - ...data, - uuid: partUUID - }; + const formattedData = { ...data, uuid: partUUID }; const response = await apiPostFetcher({ url: `/api/parts/update/${partUUID}`, isNoCache: true, @@ -119,7 +97,7 @@ function UpdateFromComponentBase({ }); await clearCacheData(activePageUrl); if (clearCache) { clearCache(activePageUrl); } - if (response.success) { form.reset(emptyValues); router.push(listUrl) } + if (response.success) { form.reset(updateEmptyValues); router.push(listUrl) } } catch (error) { console.error("Error submitting form:", error); } } diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/ListPage.tsx b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/ListPage.tsx new file mode 100644 index 0000000..94780b5 --- /dev/null +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/ListPage.tsx @@ -0,0 +1,142 @@ +'use client'; +import React from "react"; +import LoadingContent from "@/components/mutual/loader/component"; + +import { useRouter } from "next/navigation"; +import { useReactTable, getCoreRowModel, getSortedRowModel, getPaginationRowModel, flexRender, ColumnDef } from "@tanstack/react-table"; +import { Button } from "@/components/mutual/ui/button"; +import { getCacheData } from "@/components/mutual/context/cache/context"; + +import { API_BASE_URL } from "@/config/config"; +import { useTableData } from "@/hooks/useTableData"; +import { LanguageTypes } from "@/validations/mutual/language/validations"; +import { DashboardPageProps } from "@/validations/mutual/table/validations"; + +import { BuildPartsSchemaInterface, listTranslations } from "../schema"; + +import DataTable from "./dataTable"; +import TableForm from "./tableForm"; +import MobilePaginationControls from "./mobilePaginationControls"; +import TableHeader from "./tableHeader"; +import { columnHelper, retrieveColumns } from "./columns"; + +const BuildListPage: React.FC = React.memo((props) => { + const router = useRouter(); + const activePageUrl = props.activePageUrl || ''; + const language = props.onlineData?.lang as LanguageTypes || 'en'; + const t = listTranslations[language]; + const apiUrl = `${API_BASE_URL}/parts/list`; + + const [selectedBuilding, setSelectedBuilding] = React.useState(null); + + const { + tableData, isLoading, error, form, pagination, apiPagination, setSorting, handleSortingChange, handleSelectChange, + handleFirstPage, handlePreviousPage, handleNextPage, getSortingIcon, handleFormSubmit, + isPreviousDisabled, isNextDisabled, pageSizeOptions, renderPageOptions, sorting, // Disabled states + } = useTableData({ + apiUrl, + mapFormToRequestBody: (values) => { + const requestBody = { + page: values.page, size: values.size, orderField: values.orderField, orderType: values.orderType, + query: selectedBuilding ? { build_uu_id: selectedBuilding.uu_id } : {} + }; return requestBody; + } + }); + + React.useEffect(() => { + const checkCacheForSelectedBuild = async () => { + try { + const cachedData = await getCacheData("/build/list"); + if (cachedData && cachedData.build) { setSelectedBuilding(cachedData.build) } + } catch (error) { console.error("Error checking cache for selected build:", error) } + }; + checkCacheForSelectedBuild(); + }, []); + + React.useEffect(() => { + if (selectedBuilding) { form.setValue("page", 1); form.setValue("query", { build_uu_id: selectedBuilding.uu_id }) } + }, [selectedBuilding, form]); + + + const columnsArray = retrieveColumns(language, activePageUrl, router); + const columns = React.useMemo(() => columnsArray, [columnHelper]) as ColumnDef[]; + + const table = useReactTable({ + data: tableData, + columns, + state: { sorting, pagination }, + onSortingChange: setSorting, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + getPaginationRowModel: getPaginationRowModel(), + manualPagination: true, + pageCount: apiPagination.totalPages || 1, + }) + + const dataTableComponent = + + const noSelectedBuildingComponent =
+
{t.noSelectedBuilding || "No building selected. Please select a building first."}
+ +
+ + return ( + isLoading ? : +
+ +
+ + +
+ + + + {/* Mobile pagination controls - only visible on small screens */} + + + {selectedBuilding ? dataTableComponent : noSelectedBuildingComponent} +
+ ); +}); + +export default BuildListPage; diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/columns.tsx b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/columns.tsx new file mode 100644 index 0000000..c91dd7b --- /dev/null +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/columns.tsx @@ -0,0 +1,104 @@ +import { + useReactTable, + getCoreRowModel, + getSortedRowModel, + getPaginationRowModel, + flexRender, + createColumnHelper, + ColumnDef, +} from "@tanstack/react-table"; +import { BuildPartsSchemaInterface } from "../schema"; +import { buildPartsTranslations, translationsOfPage } from '../translations'; +import { LanguageTypes } from "@/validations/mutual/language/validations"; +import { Button } from "@/components/mutual/ui/button"; +import { Pencil } from "lucide-react"; +import { setCacheData } from "@/components/mutual/context/cache/context"; + +const columnHelper = createColumnHelper(); + +function retrieveColumns(language: LanguageTypes, activePageUrl: string, router: any) { + const handleEditRow = async (row: BuildPartsSchemaInterface) => { + try { + await setCacheData(`${activePageUrl}/update`, row); + router.push(`/panel/${activePageUrl}/update`); + } catch (error) { console.error('Error storing row data in cache:', error) } + }; + const actionButtonGroup = (info: any) => ( + + ); + const columnsArray = [ + columnHelper.display({ + id: 'actions', + header: () => {translationsOfPage[language].actionButtonGroup}, + cell: (info) => { return (actionButtonGroup(info)) } + }), + columnHelper.accessor('address_gov_code', { + cell: info => info.getValue(), + header: () => {buildPartsTranslations[language].address_gov_code}, + footer: info => info.column.id + }), + columnHelper.accessor('part_no', { + cell: info => String(info.getValue()), + header: () => {buildPartsTranslations[language].part_no}, + footer: info => info.column.id + }), + columnHelper.accessor('part_level', { + cell: info => String(info.getValue()), + header: () => {buildPartsTranslations[language].part_level}, + footer: info => info.column.id + }), + columnHelper.accessor('part_code', { + cell: info => info.getValue(), + header: () => {buildPartsTranslations[language].part_code}, + footer: info => info.column.id + }), + columnHelper.accessor('part_gross_size', { + cell: info => String(info.getValue()), + header: () => {buildPartsTranslations[language].part_gross_size}, + footer: info => info.column.id + }), + columnHelper.accessor('part_net_size', { + cell: info => String(info.getValue()), + header: () => {buildPartsTranslations[language].part_net_size}, + footer: info => info.column.id + }), + columnHelper.accessor('default_accessory', { + cell: info => info.getValue(), + header: () => {buildPartsTranslations[language].default_accessory}, + footer: info => info.column.id + }), + columnHelper.accessor('human_livable', { + cell: info => info.getValue() ? 'Yes' : 'No', + header: () => {buildPartsTranslations[language].human_livable}, + footer: info => info.column.id + }), + columnHelper.accessor('due_part_key', { + cell: info => info.getValue(), + header: () => {buildPartsTranslations[language].due_part_key}, + footer: info => info.column.id + }), + columnHelper.accessor('part_direction_uu_id', { + cell: info => info.getValue() || '', + header: () => {buildPartsTranslations[language].part_direction_uu_id}, + footer: info => info.column.id + }), + ] + return columnsArray; +} + +export { + retrieveColumns, + columnHelper +} diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/dataTable.tsx b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/dataTable.tsx new file mode 100644 index 0000000..ed26ef0 --- /dev/null +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/dataTable.tsx @@ -0,0 +1,129 @@ +'use client'; + +import React from "react"; +import { Button } from "@/components/mutual/ui/button"; +import { X } from "lucide-react"; +import { useReactTable } from "@tanstack/react-table"; +import { flexRender } from "@tanstack/react-table"; +import { BuildPartsSchemaInterface } from "../schema"; +import { Translations } from "./types"; + +interface DataTableProps { + table: ReturnType; + tableData: BuildPartsSchemaInterface[]; + isLoading: boolean; + handleSortingChange: (columnId: string) => void; + getSortingIcon: (columnId: string) => React.ReactNode; + flexRender: typeof flexRender; + t: Translations; + selectedBuilding: any | null; + router: any; +} + +const DataTable: React.FC = React.memo(({ + table, + tableData, + isLoading, + handleSortingChange, + getSortingIcon, + flexRender, + t, + selectedBuilding, + router, +}) => { + return ( +
+ {/* Semi-transparent loading overlay that preserves interactivity */} + {isLoading && ( +
+ {/* We don't put anything here as we already have the loading indicator in the header */} +
+ )} + {selectedBuilding && ( +
+
+

{t.selectedBuilding}

+ +
+
+
+ UUID: + {selectedBuilding.uu_id} +
+
+ {t.buildName}: + {selectedBuilding.build_name} +
+
+ {t.buildNo}: + {selectedBuilding.build_no} +
+
+ {t.buildAddressCode}: + {selectedBuilding.gov_address_code} +
+
+ {t.buildMaxFloor}: + {selectedBuilding.max_floor} +
+
+
+ )} + + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + ); + })} + + ))} + + + {tableData.length === 0 && !isLoading ? ( + + + + ) : ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => { + return ( + + ); + })} + + )) + )} + +
{t.dataTable}
handleSortingChange(header.column.id)} + aria-sort={header.column.getIsSorted() ? (header.column.getIsSorted() === 'desc' ? 'descending' : 'ascending') : undefined} + scope="col" + > +
+ {flexRender(header.column.columnDef.header, header.getContext())} + {getSortingIcon(header.column.id)} +
+
+ {t.noDataAvailable} +
+ {flexRender(cell.column.columnDef.cell, cell.getContext())} +
+
+ ); +}); + + +export default DataTable; diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/mobilePaginationControls.tsx b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/mobilePaginationControls.tsx new file mode 100644 index 0000000..aabe650 --- /dev/null +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/mobilePaginationControls.tsx @@ -0,0 +1,34 @@ +import { MobilePaginationControlsProps } from "@/validations/mutual/table/validations"; +import { Button } from "@/components/mutual/ui/button"; + +const MobilePaginationControls: React.FC = ({ + handlePreviousPage, + handleNextPage, + isPreviousDisabled, + isNextDisabled, + t +}) => { + return ( +
+
+ + +
+
+ ); +}; + +export default MobilePaginationControls; diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/tableForm.tsx b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/tableForm.tsx new file mode 100644 index 0000000..d13c4cc --- /dev/null +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/tableForm.tsx @@ -0,0 +1,152 @@ +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage +} from "@/components/mutual/ui/form"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/mutual/ui/select"; +import { UseFormReturn } from "react-hook-form"; +import { Translations } from "./types"; +import { Button } from "@/components/mutual/ui/button"; + +interface TableFormProps { + form: UseFormReturn; + handleFormSubmit: (e: React.FormEvent) => void; + handleSelectChange: (value: string, field: { onChange: (value: number) => void }) => void; + renderPageOptions: () => { key: string | number; value: string; label: string }[]; + pageSizeOptions: number[]; + apiPagination: { + size: number; + page: number; + totalCount: number; + totalPages: number; + pageCount: number; + }; + handleFirstPage: () => void; + handlePreviousPage: () => void; + handleNextPage: () => void; + isPreviousDisabled: () => boolean; + isNextDisabled: () => boolean; + t: Translations; +} + +const TableForm: React.FC = ({ + form, + handleFormSubmit, + handleSelectChange, + renderPageOptions, + pageSizeOptions, + apiPagination, + handleFirstPage, + handlePreviousPage, + handleNextPage, + isPreviousDisabled, + isNextDisabled, + t +}) => { + return ( +
+
+ +
+ ( + + {t.page} + + + + )} + /> +
+
+ ( + + {t.size} + + + + )} + /> +
+
+

+ {t.page}: {apiPagination.page}{" / "} {apiPagination.totalPages} · + {t.size}: {apiPagination.pageCount}{" / "} {apiPagination.size} · + {t.total}: {apiPagination.totalCount} {t.items} +

+
+
+ + + + {/* */} +
+
+ +
+ ); +}; + +export default TableForm; diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/tableHeader.tsx b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/tableHeader.tsx new file mode 100644 index 0000000..a53616a --- /dev/null +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/tableHeader.tsx @@ -0,0 +1,24 @@ +import { TableHeaderProps, ErrorDisplayProps } from "@/validations/mutual/table/validations"; + +const ErrorDisplay: React.FC = ({ message }) => { + return
{message}
; +}; + + +const TableHeader: React.FC = ({ title, description, isLoading, error, t }) => { + return ( + +
+
+
+

{title}

+

{description}

+
+ {/* {isLoading && } */} + {error && } +
+
+ ); +}; + +export default TableHeader; diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/types.ts b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/types.ts new file mode 100644 index 0000000..84671e2 --- /dev/null +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/main/types.ts @@ -0,0 +1,15 @@ +import { Translations as BaseTranslations } from "@/validations/mutual/table/validations"; + +// Extended Translations interface to include building-related translations +interface Translations extends BaseTranslations { + selectedBuilding: string; + buildName: string; + buildNo: string; + buildAddressCode: string; + buildMaxFloor: string; + noSelectedBuilding: string; + selectBuilding: string; + changeBuilding: string; +} + +export type { Translations }; diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/schema.ts b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/schema.ts index 8973e33..aa45103 100644 --- a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/schema.ts +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/schema.ts @@ -1,3 +1,4 @@ +import { LanguageTypes } from "@/validations/mutual/language/validations"; import * as z from "zod"; /** @@ -48,9 +49,99 @@ interface BuildPartsSchemaInterface { part_direction_uu_id: string | null; } +const createEmptyValues: BuildPartsCreateInterface = { + build_uu_id: null, + address_gov_code: "", + part_no: 0, + part_level: 0, + part_code: "", + part_gross_size: 0, + part_net_size: 0, + default_accessory: "0", + human_livable: true, + due_part_key: "", + part_direction_uu_id: null, +}; + +const updateEmptyValues: BuildPartsInterface = { + uu_id: "", + build_uu_id: null, + address_gov_code: "", + part_no: 0, + part_level: 0, + part_code: "", + part_gross_size: 0, + part_net_size: 0, + default_accessory: "0", + human_livable: true, + due_part_key: "", + part_direction_uu_id: null, +}; + +const listTranslations: Record = { + en: { + createNew: "Create New", + createNewBuildPart: "Create New Build Part", + dataTable: "Data Table", + tableWithApiData: "Table with API Data", + loading: "Loading...", + noDataAvailable: "No data available", + page: "Page", + size: "Size", + total: "Total", + items: "items", + first: "First", + previous: "Previous", + next: "Next", + selectPage: "Select page", + selectSize: "Select size", + actionButtonGroup: "Actions", + selectedBuilding: "Selected Building", + buildName: "Building Name", + buildNo: "Building No", + buildAddressCode: "Building Address Code", + buildMaxFloor: "Building Max Floor", + noSelectedBuilding: "No building selected. Please select a building first.", + selectBuilding: "Select Building", + changeBuilding: "Change Building", + }, + tr: { + createNew: "Yeni Oluştur", + createNewBuildPart: "Yeni Bina Parçası Oluştur", + dataTable: "Veri Tablosu", + tableWithApiData: "API Verili Tablo", + loading: "Yükleniyor...", + noDataAvailable: "Veri bulunamadı", + page: "Sayfa", + size: "Boyut", + total: "Toplam", + items: "öğe", + first: "İlk", + previous: "Önceki", + next: "Sonraki", + selectPage: "Sayfa seç", + selectSize: "Boyut seç", + actionButtonGroup: "Eylemler", + selectedBuilding: "Seçilen Bina", + buildName: "Bina Adı", + buildNo: "Bina No", + buildAddressCode: "Bina Adres Kodu", + buildMaxFloor: "Bina Max Kat", + noSelectedBuilding: "Bina seçilmedi. Lütfen önce bir bina seçin.", + selectBuilding: "Bina Seç", + changeBuilding: "Bina Değiştir", + }, +}; + export type { BuildPartsInterface, BuildPartsSchemaInterface, BuildPartsCreateInterface, }; -export { buildPartsSchema, buildPartsSchemaCreate }; +export { + buildPartsSchema, + buildPartsSchemaCreate, + createEmptyValues, + updateEmptyValues, + listTranslations, +}; diff --git a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/translations.ts b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/translations.ts index 9b178c5..dc69127 100644 --- a/ServicesWeb/customer/src/pages/multi/buildParts/superuser/translations.ts +++ b/ServicesWeb/customer/src/pages/multi/buildParts/superuser/translations.ts @@ -1,4 +1,4 @@ -export const buildPartsTranslations = { +const buildPartsTranslations = { tr: { uu_id: "UUID", build_uu_id: "Bina UUID", @@ -29,17 +29,42 @@ export const buildPartsTranslations = { }, }; -export const translationsOfPage = { +const translationsOfPage = { tr: { - title: "Bina Bölümü Oluştur", - updateTitle: "Bina Bölümü Güncelle", + title: "Binaya Daire Oluştur", + updateTitle: "Binanın Dairesini Güncelle", back2List: "Listeye Geri Dön", + actionButtonGroup: "İşlemler", }, en: { title: "Create Building Part", updateTitle: "Update Building Part", back2List: "Back to List", + actionButtonGroup: "Actions", }, }; -export default buildPartsTranslations; +const buildingTranslations = { + en: { + selectedBuilding: "Selected Building", + buildName: "Building Name", + buildNo: "Building No", + buildAddressCode: "Address Code", + buildMaxFloor: "Max Floor", + noSelectedBuilding: "No building selected. Please select a building first.", + selectBuilding: "Select Building", + changeBuilding: "Change Building", + }, + tr: { + selectedBuilding: "Seçili Bina", + buildName: "Bina Adı", + buildNo: "Bina No", + buildAddressCode: "Adres Kodu", + buildMaxFloor: "Maksimum Kat", + noSelectedBuilding: "Bina seçilmedi. Lütfen önce bir bina seçin.", + selectBuilding: "Bina Seç", + changeBuilding: "Binayı Değiştir", + }, +}; + +export { buildPartsTranslations, translationsOfPage, buildingTranslations }; diff --git a/ServicesWeb/customer/src/pages/multi/builds/superuser/ListPage.tsx b/ServicesWeb/customer/src/pages/multi/builds/superuser/ListPage.tsx index 386a939..fc11062 100644 --- a/ServicesWeb/customer/src/pages/multi/builds/superuser/ListPage.tsx +++ b/ServicesWeb/customer/src/pages/multi/builds/superuser/ListPage.tsx @@ -25,17 +25,22 @@ import { API_BASE_URL } from "@/config/config"; import { useTableData } from "@/hooks/useTableData"; import { LanguageTypes } from "@/validations/mutual/language/validations"; import { - Translations, + Translations as BaseTranslations, TableHeaderProps, LoadingSpinnerProps, ErrorDisplayProps, MobilePaginationControlsProps, DashboardPageProps, } from "@/validations/mutual/table/validations"; + +// Extended Translations interface with selectedBuilding property +interface Translations extends BaseTranslations { + selectedBuilding: string; +} import LoadingContent from "@/components/mutual/loader/component"; import { Pencil } from "lucide-react"; import { useRouter } from "next/navigation"; -import { setCacheData } from "@/components/mutual/context/cache/context"; +import { setCacheData, getCacheData, clearCacheData } from "@/components/mutual/context/cache/context"; import { BuildSchemaInterface } from "./schema"; interface DataTableProps { @@ -45,7 +50,11 @@ interface DataTableProps { handleSortingChange: (columnId: string) => void; getSortingIcon: (columnId: string) => React.ReactNode; flexRender: typeof flexRender; - t: Translations; + t: any; + selected: string | null; + setSelected: React.Dispatch>; + activePageUrl: string; + router: ReturnType; } interface TableFormProps { @@ -69,7 +78,7 @@ interface TableFormProps { t: Translations; } -const translations: Record = { +const translations: Record = { en: { dataTable: 'Data Table', tableWithApiData: 'Table with API Data', @@ -85,6 +94,16 @@ const translations: Record = { selectPage: 'Select page', selectSize: 'Select size', actionButtonGroup: 'Actions', + selectedBuilding: 'Selected Building', + buildParts: 'Create Parts', + areas: 'Create Areas', + buildNo: 'Building No', + buildName: 'Building Name', + buildAddress: 'Building Address', + buildAddressCode: 'Building Address Code', + buildMaxFloor: 'Building Max Floor', + clearSelection: 'Clear Selection', + // lands: 'Create Lands', }, tr: { dataTable: 'Veri Tablosu', @@ -101,6 +120,16 @@ const translations: Record = { selectPage: 'Sayfa seç', selectSize: 'Boyut seç', actionButtonGroup: 'Eylemler', + selectedBuilding: 'Seçilen Bina', + buildParts: 'Daire Oluştur', + areas: 'Alanlar Oluştur', + buildNo: 'Bina No', + buildName: 'Bina Adı', + buildAddress: 'Bina Adresi', + buildAddressCode: 'Bina Adres Kodu', + buildMaxFloor: 'Bina Max Kat', + clearSelection: 'Seçimi Temizle', + // lands: 'Alanlar Oluştur', } }; @@ -112,7 +141,32 @@ const DataTable: React.FC = React.memo(({ getSortingIcon, flexRender, t, + selected, + setSelected, + activePageUrl, + router, }) => { + + const handleRowClick = (rowData: BuildSchemaInterface) => { + setSelected(rowData.uu_id); + const selectedData = { + build: rowData, + // build_owner: null // This could be populated if you have owner data + }; + setCacheData(`${activePageUrl}/list`, selectedData); + }; + + const handleClearSelection = async () => { + setSelected(null); + try { + // Use clearCacheData to properly remove the cache entry + await clearCacheData(`${activePageUrl}/list`); + console.log("Cache cleared successfully"); + } catch (error) { + console.error("Error clearing selection cache:", error); + } + }; + return (
{/* Semi-transparent loading overlay that preserves interactivity */} @@ -121,8 +175,64 @@ const DataTable: React.FC = React.memo(({ {/* We don't put anything here as we already have the loading indicator in the header */}
)} + {selected && ( +
+

{t.selectedBuilding}

+
+ {/* 2/3 section for building details */} +
+
+
+ UUID: + {tableData.find(row => row.uu_id === selected)?.uu_id} +
+
+ {t.buildName}: + {tableData.find(row => row.uu_id === selected)?.build_name} +
+
+ {t.buildNo}: + {tableData.find(row => row.uu_id === selected)?.build_no} +
+
+ {t.buildAddressCode}: + {tableData.find(row => row.uu_id === selected)?.gov_address_code} +
+
+ {t.buildMaxFloor}: + {tableData.find(row => row.uu_id === selected)?.max_floor} +
+
+
+ + {/* 1/3 section for action buttons */} +
+ + + +
+
+
+ )} + + {table.getHeaderGroups().map((headerGroup) => ( @@ -154,7 +264,11 @@ const DataTable: React.FC = React.memo(({ ) : ( table.getRowModel().rows.map((row) => ( - + handleRowClick(row.original as BuildSchemaInterface)} + > {row.getVisibleCells().map((cell) => { return (
{t.dataTable}
@@ -343,10 +457,31 @@ const ErrorDisplay: React.FC = ({ message }) => { const BuildListPage: React.FC = React.memo((props) => { // Initialize translation with English as default const language = props.onlineData?.lang as LanguageTypes || 'en'; - + const [selected, setSelected] = React.useState(null); + const [cacheLoaded, setCacheLoaded] = React.useState(false); const t = translations[language]; const router = useRouter(); + // Check for selected build in cache when component mounts + React.useEffect(() => { + const checkCacheForSelectedBuild = async () => { + if (!cacheLoaded) { + try { + const activePageUrl = props.activePageUrl || ''; + const cachedData = await getCacheData(`${activePageUrl}/list`); + if (cachedData && cachedData.build && cachedData.build.uu_id) { + setSelected(cachedData.build.uu_id); + } + setCacheLoaded(true); + } catch (error) { + console.error("Error checking cache for selected build:", error); + setCacheLoaded(true); + } + } + }; + checkCacheForSelectedBuild(); + }, [props.activePageUrl]); + const { form, tableData, @@ -373,6 +508,7 @@ const BuildListPage: React.FC = React.memo((props) => { const activePageUrl = props.activePageUrl || ''; const handleEditRow = async (row: BuildSchemaInterface) => { try { + setSelected(row.uu_id); await setCacheData(`${activePageUrl}/update`, row); router.push(`/panel/${activePageUrl}/update`); } catch (error) { @@ -565,6 +701,10 @@ const BuildListPage: React.FC = React.memo((props) => { getSortingIcon={getSortingIcon} flexRender={flexRender} t={t} + selected={selected} + setSelected={setSelected} + activePageUrl={activePageUrl} + router={router} /> ); diff --git a/ServicesWeb/customer/src/pages/multi/index.ts b/ServicesWeb/customer/src/pages/multi/index.ts index 7a1dee6..4b77f75 100644 --- a/ServicesWeb/customer/src/pages/multi/index.ts +++ b/ServicesWeb/customer/src/pages/multi/index.ts @@ -4,7 +4,7 @@ import TableCardComponentImproved from "@/components/custom/content/TableCardCom import BuildListPage from "./builds/superuser/ListPage"; import CreateFromBuildComponent from "./builds/superuser/CreatePage"; import UpdateFromBuildComponent from "./builds/superuser/UpdatePage"; -import BuildPartsListPage from "./buildParts/superuser/ListPage"; +import BuildPartsListPage from "./buildParts/superuser/main/ListPage"; import CreateFromBuildPartsComponent from "./buildParts/superuser/CreatePage"; import UpdateFromBuildPartsComponent from "./buildParts/superuser/UpdatePage";