"use client"; import { SortDirection } from "@/components/ui/tableSortContext"; import { useAssignCompany, useCompanyFullList, useCustomersQuery, useDeleteCustomerQuery, useResetCustomerPassword, } from "@/hooks/queries"; import { useHybridPagination } from "@/hooks/useHybridPagination"; import { useTableSectionRowAnimations } from "@/hooks/useTableSectionRowAnimations"; import { TAssignCustomerToCompanyCredentials, TCustomer } from "@/lib/api"; import { apiDefaultParams } from "@/constants/Api_Params"; import { buildQueryString, deleteEmptyKeys } from "@/utils/shared"; import { useIsMutating } from "@tanstack/react-query"; import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useForm } from "react-hook-form"; const useCustomerListPresenter = () => { const [isAssignCompanyModalOpen, setIsAssignCompanyModalOpen] = useState(false); const [selectedCompanies, setSelectedCompanies] = useState< TAssignCustomerToCompanyCredentials | undefined >(); const [currentCustomer, setCurrentCustomer] = useState( null, ); const [isModalOpen, setIsModalOpen] = useState(false); const [isResetPasswordModalOpen, setIsResetPasswordModalOpen] = useState(false); const [generatedPassword, setGeneratedPassword] = useState( null, ); const pathName = usePathname(); const searchParams = useSearchParams(); const [params, setParams] = useState>({ ...apiDefaultParams, }); const router = useRouter(); const isMutating = useIsMutating(); const { register: filterRegister, handleSubmit: handleFilterSubmit, reset: filterFormReset, watch, setValue: setFilterValue, } = useForm(); const tableSectionRef = useRef(null); const skeletonTbodyRef = useRef(null); const dataTbodyRef = useRef(null); useEffect(() => { const newParams: Record = { ...apiDefaultParams, offset: 0, limit: 10, }; for (const [key, value] of searchParams.entries()) { newParams[key] = value; } setParams(newParams); filterFormReset(newParams); }, [searchParams, filterFormReset]); const { data, isPending, isError, error } = useCustomersQuery(params); const { pagination, handlePaginationChange, buildFirstPageParams } = useHybridPagination({ meta: data?.meta, params, setParams, isError, error, }); useTableSectionRowAnimations(isPending, data, { tableSectionRef, skeletonTbodyRef, dataTbodyRef, }); const assignCompanyCompaniesQuery = useCompanyFullList({ enabled: isAssignCompanyModalOpen, }); const { mutate: deleteCustomer } = useDeleteCustomerQuery(() => setIsModalOpen(false), ); const { mutate: assignSelectedCompanies } = useAssignCompany( currentCustomer?.id ?? "", () => { setIsAssignCompanyModalOpen(false); }, ); const { mutate: resetCustomerPassword, isPending: isResettingPassword } = useResetCustomerPassword({ successCallback: (password) => setGeneratedPassword(password), }); const openResetPasswordModalForCustomer = useCallback( (customer: TCustomer) => { setCurrentCustomer(customer); setGeneratedPassword(null); setIsResetPasswordModalOpen(true); resetCustomerPassword(customer.id); }, [resetCustomerPassword], ); const closeResetPasswordModal = useCallback(() => { setIsResetPasswordModalOpen(false); setGeneratedPassword(null); }, []); const search = (formData: any) => { const newParams = buildFirstPageParams({ ...params, ...formData }); const cleanedParams = deleteEmptyKeys(newParams); const queryString = new URLSearchParams(cleanedParams).toString(); router.push(`${pathName}?${queryString}`); }; const clearAllFilters = useCallback(() => { filterFormReset({ status: undefined, role: undefined, type: undefined }); router.push(pathName); }, [pathName, router, filterFormReset]); const columns = [ "row", "full name", "email", "created at", "type", "status", "company", "role", "actions", ]; const onConfirmDelete = () => { if (currentCustomer) { deleteCustomer(currentCustomer.id); } }; /** Column label → BSON `sort_by` field. */ const columnSortKeys: Record = { "full name": "full_name", email: "email", "created at": "created_at", type: "type", status: "status", role: "role", }; /** First-click direction per column. */ const columnDefaultOrder: Record = { "full name": "asc", email: "asc", type: "asc", role: "asc", "created at": "desc", }; const sortBy = (params.sort_by as string) ?? "created_at"; const sortOrder = (params.sort_order as SortDirection) ?? "desc"; const handleSortChange = useCallback( (key: string, order: SortDirection) => { const newParams = buildFirstPageParams({ ...params, sort_by: key, sort_order: order, }); const cleanedParams = deleteEmptyKeys(newParams); const queryString = buildQueryString(cleanedParams); router.push(`${pathName}?${queryString}`); }, [buildFirstPageParams, params, pathName, router], ); const customers = data?.data?.customers ?? []; const shouldShowPagination = !isPending && (data?.meta?.pages ?? 1) * (data?.meta?.limit ?? 10) > 10; return { allCustomers: customers, metadata: data?.meta, currentCustomer, columns, columnSortKeys, columnDefaultOrder, sortBy, sortOrder, handleSortChange, isPending, setCurrentCustomer, selectedCompanies, setSelectedCompanies, onConfirmDelete, setIsAssignCompanyModalOpen, isAssignCompanyModalOpen, assignSelectedCompanies, pathName, router, isModalOpen, setIsModalOpen, filterRegister, handleFilterSubmit, search, watch, setFilterValue, isMutating, setParams, assignCompanyCompaniesQuery, shouldShowPagination, clearAllFilters, tableSectionRef, skeletonTbodyRef, dataTbodyRef, pagination, handlePaginationChange, isResetPasswordModalOpen, closeResetPasswordModal, openResetPasswordModalForCustomer, generatedPassword, isResettingPassword, }; }; export default useCustomerListPresenter;