driver and updates page search filter

dilmurod
Dilmurod 1 week ago
parent 4ca1f13fcf
commit d130e18a14

@ -9,6 +9,7 @@ export type TCustomerGetParams = {
page?: string | number; page?: string | number;
for_driver_request?: boolean; for_driver_request?: boolean;
is_active?: boolean; is_active?: boolean;
telegram_group_id?: string;
}; };
export type TCustomerByCompanyGetParams = { export type TCustomerByCompanyGetParams = {
@ -36,6 +37,8 @@ export const customerController = {
if (!!filterObject.page_size) params.page_size = filterObject.page_size; if (!!filterObject.page_size) params.page_size = filterObject.page_size;
if (!!filterObject.for_driver_request) if (!!filterObject.for_driver_request)
params.for_driver_request = filterObject.for_driver_request; params.for_driver_request = filterObject.for_driver_request;
if (!!filterObject.telegram_group_id)
params.telegram_group_id = filterObject.telegram_group_id;
const { data } = await instance.get<TPagination<TCustomer[]>>( const { data } = await instance.get<TPagination<TCustomer[]>>(
`customers/`, `customers/`,

@ -24,10 +24,27 @@ export type TUpdatePostParams = {
}; };
export const updateController = { export const updateController = {
async read(status: string, page: number, page_size: number) { async read(
const { data } = await instance.get( status: string,
`shift-updates/?status=${status}&page=${page}&page_size=${page_size}` page: string | number,
); page_size: string | number,
company_name: string,
driver_name: string
) {
const params = new URLSearchParams({
status,
page: String(page),
page_size: String(page_size),
});
if (company_name) {
params.append("company_name", company_name);
}
if (driver_name) {
params.append("driver_name", driver_name);
}
const { data } = await instance.get(`shift-updates/?${params.toString()}`);
return data; return data;
}, },

@ -303,7 +303,6 @@ const App: React.FC = () => {
console.error("WebSocket error:", errorEvent); console.error("WebSocket error:", errorEvent);
}); });
taskSocket.addEventListener("close", () => { taskSocket.addEventListener("close", () => {
console.log("Socket closed → reconnecting…");
setIslive(false); setIslive(false);
}); });
} }

@ -31,11 +31,13 @@ const Customer = () => {
const { token } = theme.useToken(); const { token } = theme.useToken();
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [searchChatId, setSearchChatId] = useState("");
const { data, isLoading, refetch } = useCustomerData({ const { data, isLoading, refetch } = useCustomerData({
name: search, name: search,
is_active: undefined, is_active: undefined,
page_size: pageSize, page_size: pageSize,
page: page, page: page,
telegram_group_id: searchChatId,
}); });
const pageSizeOptions = [15, 20, 30, 40, 50]; const pageSizeOptions = [15, 20, 30, 40, 50];
@ -72,6 +74,16 @@ const Customer = () => {
setSearch(searchText); setSearch(searchText);
}, 1000); }, 1000);
}; };
const handleSearchChatId = (e: React.ChangeEvent<HTMLInputElement>) => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
const searchChatId = e.target.value;
timerRef.current = setTimeout(() => {
setSearchChatId(searchChatId);
}, 1000);
};
const themes = localStorage.getItem("theme") === "true" ? true : false; const themes = localStorage.getItem("theme") === "true" ? true : false;
return ( return (
@ -79,10 +91,7 @@ const Customer = () => {
{open && <AddCustomer open={open} setOpen={setOpen} />} {open && <AddCustomer open={open} setOpen={setOpen} />}
<div className="header d-flex"> <div className="header d-flex">
<Typography className="title">Drivers</Typography> <Typography className="title">Drivers</Typography>
{/* <button className="btn-add d-flex" onClick={showModal}>
<img src={addicon} style={{ marginRight: 8 }} alt="" />
Add Driver
</button> */}
<Button <Button
className="d-flex" className="d-flex"
onClick={showModal} onClick={showModal}
@ -96,22 +105,19 @@ const Customer = () => {
Add Driver Add Driver
</Button> </Button>
</div> </div>
<div className="filter d-flex"> <div className="filter d-flex" style={{ gap: 5 }}>
{/* <div className="search-div"> <div>
<img src={IconSearch} alt="" /> <Input
<input
className={`search-input-${themes}`}
type="text"
placeholder="Search" placeholder="Search"
prefix={<SearchOutlined />}
onChange={handleSearchChange} onChange={handleSearchChange}
/> />
</div> */} </div>
<div> <div>
<Input <Input
// className={`search-input-${themes}`} placeholder="Search Chat ID"
placeholder="Search"
prefix={<SearchOutlined />} prefix={<SearchOutlined />}
onChange={handleSearchChange} onChange={handleSearchChatId}
/> />
</div> </div>
</div> </div>

@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useRef, useState } from "react";
import AddUpdate from "./AddUpdate"; import AddUpdate from "./AddUpdate";
import { Button, Input, Select, Space, Typography, theme } from "antd"; import { Button, Input, Select, Space, Typography, theme } from "antd";
import { import {
@ -6,48 +6,72 @@ import {
PlusOutlined, PlusOutlined,
ReloadOutlined, ReloadOutlined,
RightOutlined, RightOutlined,
SearchOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import UpdateTable from "./UpdateTable"; import UpdateTable from "./UpdateTable";
import { useUpdateData } from "../../Hooks/Update"; import { useUpdateData } from "../../Hooks/Update";
import { useCompanyData } from "../../Hooks/Companies";
import { debounce } from "lodash";
const { Option } = Select;
const Update = () => { const Update = () => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const timerRef = useRef<NodeJS.Timeout | null>(null);
const handleSelectChange = (value: any) => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
timerRef.current = setTimeout(() => {
setStatus(value);
}, 1000);
};
const [status, setStatus] = useState<any>([ const [status, setStatus] = useState<any>([
"New", "New",
"In Progress", "In Progress",
"Paper", "Paper",
"Setup", "Setup",
]); ]);
const { Option } = Select;
const [page, setPage] = useState<number>(1); const [page, setPage] = useState<number>(1);
const [pageSize, setPageSize] = useState<number>(() => { const [pageSize, setPageSize] = useState<number>(() => {
const saved = localStorage.getItem("general_pageSize"); const saved = localStorage.getItem("general_pageSize");
return saved ? Number(saved) : 15; return saved ? Number(saved) : 15;
}); });
const [companyName, setCompanyName] = useState<string>("");
const [company, setCompany] = useState<string>("");
const [driverName, setDriverName] = useState<string>("");
const pageSizeOptions = [15, 20, 30, 40, 50]; const pageSizeOptions = [15, 20, 30, 40, 50];
const handlePageSizeChange = (value: number) => { const handlePageSizeChange = (value: number) => {
setPageSize(value); setPageSize(value);
setPage(1); // Odatda pageSize o'zgarganda sahifani 1 ga qaytaramiz setPage(1);
}; };
const { data, refetch, isLoading } = useUpdateData(status, page, pageSize); const { data, refetch, isLoading } = useUpdateData(
status,
page,
pageSize,
company,
driverName
);
const companyData = useCompanyData({
name: companyName,
});
const debouncedSearch = useCallback(
debounce((val: string, setCompany, setCompanyName) => {
if (val === "") {
setCompany("");
}
setCompanyName(val);
}, 500),
[]
);
const handleSelectChange = useCallback(
debounce((value) => {
setStatus(value);
}, 1000),
[]
);
const handleSearchChange = useCallback(
debounce((value: string) => {
setDriverName(value);
}, 1000),
[]
);
const showModal = () => { const showModal = () => {
setOpen(true); setOpen(true);
@ -77,10 +101,6 @@ const Update = () => {
<div className="header d-flex" style={{ marginBottom: 16 }}> <div className="header d-flex" style={{ marginBottom: 16 }}>
<Typography className="title">Updates</Typography> <Typography className="title">Updates</Typography>
<div className="d-flex"> <div className="d-flex">
{/* <button className="btn-add d-flex" onClick={showModal}>
<img style={{ marginRight: 8 }} src={addicon} alt="" />
Add
</button> */}
<Button <Button
style={{ style={{
marginRight: 10, marginRight: 10,
@ -90,23 +110,10 @@ const Update = () => {
}} }}
className="d-flex" className="d-flex"
onClick={showModal} onClick={showModal}
icon={<PlusOutlined />} // Ant-design ikonkasi icon={<PlusOutlined />}
> >
Add Add
</Button> </Button>
{/* <button
className={`btn-refresh-${false && "dark"} d-flex`}
style={{
backgroundColor: token.colorBgContainer,
color: token.colorText,
}}
onClick={() => {
refetch();
}}
>
<img style={{ marginRight: 8 }} src={refreshicon} alt="" />
Refresh
</button> */}
<Button <Button
className="d-flex" className="d-flex"
style={{ style={{
@ -123,7 +130,7 @@ const Update = () => {
</Button> </Button>
</div> </div>
</div> </div>
<div className="filter d-flex"> <div className="filter d-flex" style={{ gap: 5 }}>
<Select <Select
style={{ width: 260, marginLeft: 10 }} style={{ width: 260, marginLeft: 10 }}
placeholder="Status" placeholder="Status"
@ -137,6 +144,29 @@ const Update = () => {
<Option value="Paper">Paper</Option> <Option value="Paper">Paper</Option>
<Option value="Setup">Setup</Option> <Option value="Setup">Setup</Option>
</Select> </Select>
<Select
style={{ width: 260, marginLeft: 10 }}
showSearch
placeholder="Search Company"
onSearch={(value) =>
debouncedSearch(value, setCompany, setCompanyName)
}
options={companyData?.data?.map((item) => ({
label: item?.name,
value: item?.name,
}))}
filterOption={false}
allowClear
onChange={(v) => setCompany(v)}
/>
<Input
style={{ width: 260, marginLeft: 10 }}
placeholder="Search Driver Name"
prefix={<SearchOutlined />}
onChange={(e) => handleSearchChange(e.target.value)}
/>
</div> </div>
<UpdateTable data={data?.data} refetch={refetch} isLoading={isLoading} /> <UpdateTable data={data?.data} refetch={refetch} isLoading={isLoading} />
<Space style={{ width: "100%", marginTop: 40 }} direction="vertical"> <Space style={{ width: "100%", marginTop: 40 }} direction="vertical">

@ -10,9 +10,18 @@ export const useCustomerData = ({
is_active, is_active,
page_size, page_size,
for_driver_request, for_driver_request,
telegram_group_id,
}: TCustomerGetParams) => { }: TCustomerGetParams) => {
return useQuery( return useQuery(
[`customers/`, name, page, is_active, page_size, for_driver_request], [
`customers/`,
name,
page,
is_active,
page_size,
for_driver_request,
telegram_group_id,
],
() => () =>
customerController.read({ customerController.read({
name, name,
@ -20,6 +29,7 @@ export const useCustomerData = ({
is_active, is_active,
page_size, page_size,
for_driver_request, for_driver_request,
telegram_group_id,
}), }),
{ refetchOnWindowFocus: false } { refetchOnWindowFocus: false }
); );

@ -11,12 +11,15 @@ import { updateController } from "../../API/LayoutApi/update";
export const useUpdateData = ( export const useUpdateData = (
status: string, status: string,
page: number, page: number | string,
page_size: number page_size: number | number,
company_name: string,
driver_name: string
) => { ) => {
return useQuery( return useQuery(
[`shift-updates`, status, page, page_size], [`shift-updates`, status, page, page_size, company_name, driver_name],
() => updateController.read(status, page, page_size), () =>
updateController.read(status, page, page_size, company_name, driver_name),
{ refetchOnWindowFocus: false } { refetchOnWindowFocus: false }
); );
}; };

Loading…
Cancel
Save