Shift and Cycle & Co-Driver modal Info

dilmurod
Dilmurod 3 weeks ago
parent 8188dab2b4
commit e782c49e4b

@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug React in Chrome",
"type": "pwa-chrome",
"request": "launch",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}/src/",
"breakOnLoad": true
}
]
}

@ -1,9 +1,8 @@
import {
TCard,
TGeneralChartData,
TGeneralChartGetParams,
TStat,
TStatCreators,
TStatTeam,
TteamChartData,
} from "../../types/Statistic/TStat";
import instance from "../api";
@ -37,10 +36,6 @@ export type TteamChartGetParams = {
start_date?: string;
end_date?: string;
};
export type TGeneralChartGetParams = {
start_date?: string;
end_date?: string;
};
export const statController = {
async read(filterObject: TStatGetParams) {

@ -16,6 +16,7 @@ import {
RadioChangeEvent,
Select,
theme,
Switch,
} from "antd";
import { companyController } from "../../API/LayoutApi/companies";
import {
@ -157,7 +158,7 @@ const CompanyEdit = () => {
onFinish={onSubmit}
autoComplete="off"
>
<Row gutter={[16, 10]}>
<Row gutter={[16, 16]}>
<Col span={6}>
<Form.Item
wrapperCol={{ span: "100%" }}
@ -188,8 +189,6 @@ const CompanyEdit = () => {
/>
</Form.Item>
</Col>
</Row>
<Row gutter={[16, 10]}>
<Col span={6}>
<Form.Item
wrapperCol={{ span: "100%" }}
@ -199,6 +198,18 @@ const CompanyEdit = () => {
<Input />
</Form.Item>
</Col>
</Row>
<Row gutter={[16, 16]}>
<Col span={6}>
<Form.Item
wrapperCol={{ span: "100%" }}
label="Additional Task Data"
name="needs_extra_info"
valuePropName="checked"
>
<Switch />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
wrapperCol={{ span: "100%" }}

@ -0,0 +1,232 @@
import { Modal, Form, Input, DatePicker, Switch } from "antd";
import { useState } from "react";
import dayjs from "dayjs";
import { TTask } from "../../types/Tasks/TTasks";
interface ShiftAndCoDriverModalProps {
open: boolean;
onOk: (values: any) => void;
onCancel: () => void;
recordTask?: TTask;
}
const ShiftAndCoDriverModal: React.FC<ShiftAndCoDriverModalProps> = ({
open,
onOk,
onCancel,
recordTask,
}) => {
const [form] = Form.useForm();
const [needsCycle, setNeedsCycle] = useState(false);
const [needsDriver, setNeedsDriver] = useState(false);
const [needsPickUp, setNeedsPickUp] = useState(false);
const handleOk = async () => {
try {
const values = await form.validateFields();
const formattedValues = Object.fromEntries(
Object.entries(values).map(([key, value]) => [
key,
dayjs.isDayjs(value) ? value.format("YYYY-MM-DD HH:mm:ss") : value,
])
);
onOk(formattedValues);
form.resetFields();
} catch (err) {
console.log("Validation error:", err);
}
};
return (
<Modal
title="Shift and Cycle & Co-Driver Info"
open={open}
onOk={handleOk}
onCancel={onCancel}
width={700}
>
<Form
form={form}
layout="vertical"
initialValues={{
driver_name: recordTask?.customer?.name,
}}
>
{/* SHIFT INFO */}
<Form.Item
label="Shift Date"
name="shift_date"
rules={[{ required: true, message: "Please select date" }]}
>
<DatePicker
style={{ width: "100%" }}
format="DD MMM YYYY HH:mm:ss"
showTime={{ format: "HH:mm:ss" }}
/>
</Form.Item>
<Form.Item
label="Shift Location"
name="shift_location"
rules={[{ required: true, message: "Please enter location" }]}
>
<Input placeholder="Enter location" />
</Form.Item>
{/* Pick Up */}
<Form.Item label="Pick Up Info">
<Switch
checked={needsPickUp}
onChange={(checked) => {
setNeedsPickUp(checked);
if (!checked) {
form.resetFields(["pickup_date", "cycle_location"]);
}
}}
/>
</Form.Item>
{needsPickUp && (
<>
<Form.Item
label="Pick Up Date"
name="pickup_date"
rules={[{ required: true, message: "Please select date" }]}
>
<DatePicker
style={{ width: "100%" }}
format="DD MMM YYYY HH:mm:ss"
showTime={{ format: "HH:mm:ss" }}
/>
</Form.Item>
<Form.Item
label="Pick Up Location"
name="cycle_location"
rules={[{ required: true, message: "Please enter location" }]}
>
<Input placeholder="Enter location" />
</Form.Item>
</>
)}
{/* Cycle info */}
<Form.Item label="Cycle Info">
<Switch
checked={needsCycle}
onChange={(checked) => {
setNeedsCycle(checked);
if (!checked) {
form.resetFields(["cycle_date", "cycle_location"]);
}
}}
/>
</Form.Item>
{needsCycle && (
<>
<Form.Item
label="Cycle Date"
name="cycle_date"
rules={[{ required: true, message: "Please select date" }]}
>
<DatePicker
style={{ width: "100%" }}
format="DD MMM YYYY HH:mm:ss"
showTime={{ format: "HH:mm:ss" }}
/>
</Form.Item>
<Form.Item
label="Cycle Location"
name="cycle_location"
rules={[{ required: true, message: "Please enter location" }]}
>
<Input placeholder="Enter location" />
</Form.Item>
</>
)}
{/* DRIVER INFO */}
<Form.Item label="CO-Driver Info">
<Switch
checked={needsDriver}
onChange={(checked) => {
setNeedsDriver(checked);
if (!checked) {
form.resetFields([
"driver_name",
"co_driver_name",
"co_driver_pickup_date",
"co_driver_pickup_location",
"co_driver_drop_date",
"co_driver_drop_location",
]);
}
}}
/>
</Form.Item>
{needsDriver && (
<>
<Form.Item label="Driver Name" name="driver_name">
<Input placeholder="Driver name" />
</Form.Item>
<Form.Item label="Co-Driver Name" name="co_driver_name">
<Input placeholder="Co-driver name" />
</Form.Item>
<Form.Item
label="Co-Driver Pick Up Date"
name="co_driver_pickup_date"
rules={[{ required: true, message: "Please select pickup date" }]}
>
<DatePicker
style={{ width: "100%" }}
format="DD MMM YYYY HH:mm:ss"
showTime={{ format: "HH:mm:ss" }}
/>
</Form.Item>
<Form.Item
label="Co-Driver Pick Up Location"
name="co_driver_pickup_location"
rules={[
{ required: true, message: "Please enter pickup location" },
]}
>
<Input placeholder="Enter pickup location" />
</Form.Item>
<Form.Item
label="Co-Driver Drop Date"
name="co_driver_drop_date"
rules={[{ required: true, message: "Please select date" }]}
>
<DatePicker
style={{ width: "100%" }}
format="DD MMM YYYY HH:mm:ss"
showTime={{ format: "HH:mm:ss" }}
/>
</Form.Item>
<Form.Item
label="Co-Driver Drop Location"
name="co_driver_drop_location"
rules={[{ required: true, message: "Please enter location" }]}
>
<Input placeholder="Drop location" />
</Form.Item>
</>
)}
</Form>
</Modal>
);
};
export default ShiftAndCoDriverModal;

@ -21,6 +21,8 @@ import {
ArrowRightOutlined,
CaretRightOutlined,
CloseOutlined,
CopyOutlined,
DatabaseOutlined,
EditOutlined,
ForwardOutlined,
RotateRightOutlined,
@ -62,6 +64,9 @@ import driverIcon from "../../assets/drivericon.png";
// @ts-ignore
import userIcon from "../../assets/userIcon.png";
import ShiftAndCoDriverModal from "./ShiftAndCoDriverModal";
import CopyCard from "./shiftInfoTab";
const TaskModal = ({
modalOpen,
setModalOpen,
@ -87,6 +92,8 @@ const TaskModal = ({
const [teamName, setTeamName] = useState(recordTask?.assigned_to?.name);
const { data, isLoading } = useTaskHistory(recordTask?.id);
const [isModalOpen, setIsModalOpen] = useState(false);
const { token } = theme.useToken();
const handleCancel = () => {
@ -171,7 +178,27 @@ const TaskModal = ({
{
key: "3",
label: <p>Done</p>,
onClick: () => statuspatch("Done"),
onClick: () => {
if (status === "Done") {
statuspatch("Done");
return;
}
if (
recordTask?.service.title === "Break" ||
recordTask?.service.title === "PTI"
) {
statuspatch("Done");
return;
}
if (recordTask?.company?.needs_extra_info === false) {
statuspatch("Done");
return;
}
setIsModalOpen(true);
},
},
];
const getImageSource = (source: string) => {
@ -185,9 +212,20 @@ const TaskModal = ({
}
};
const statuspatch = (status: string) => {
const statuspatch = async (status: string, extraData?: any) => {
setStatus(status);
taskController.taskPatch({ status: status }, recordTask?.id);
try {
const response = await taskController.taskPatch(
{ status: status, ...extraData },
recordTask?.id
);
if (response.status === 400) {
setIsModalOpen(true);
}
} catch (error) {
console.log(error);
}
};
const teampatch = (item: TTeam) => {
@ -395,21 +433,9 @@ const TaskModal = ({
<p className={!themes ? "info" : "info-dark"}>
{pti === false ? "Do" : "No need"}
</p>
{/* <button
style={{
marginLeft: 10,
background: "#cecece",
outline: "none",
border: "1px solid rgba(246, 137, 0, 1)",
padding: 4,
borderRadius: 4,
}}
onClick={(e) => setPti(!pti)}
>
change
</button> */}
<Button
type="primary" // Maxsus bir stil bilan
type="primary"
size="small"
onClick={(e) => setPti(!pti)}
style={{
@ -418,7 +444,6 @@ const TaskModal = ({
color: "#f68900",
outline: "none",
border: "1px solid #f68900",
// padding: 4,
borderRadius: 4,
}}
>
@ -470,6 +495,26 @@ const TaskModal = ({
</Button>
</div>
</TabPane>
<TabPane
tab={
<span
style={{
display: "flex",
alignItems: "center",
}}
>
<span>
<DatabaseOutlined />
</span>
Shift & Driver Data
</span>
}
key="2"
>
<CopyCard recordTask={recordTask} />
</TabPane>
<TabPane
tab={
<span style={{ display: "flex", alignItems: "center" }}>
@ -477,7 +522,7 @@ const TaskModal = ({
Attachments
</span>
}
key="2"
key="3"
>
<div className="info-div">
<p
@ -622,7 +667,7 @@ const TaskModal = ({
History
</span>
}
key="3"
key="4"
>
<div className="info-div">
<p
@ -736,6 +781,16 @@ const TaskModal = ({
</TabPane>
</Tabs>
</div>
<ShiftAndCoDriverModal
recordTask={recordTask}
open={isModalOpen}
onOk={(values) => {
statuspatch("Done", values);
setIsModalOpen(false);
}}
onCancel={() => setIsModalOpen(false)}
/>
</Modal>
);
};

@ -0,0 +1,141 @@
import { Button, Card, message } from "antd";
import { CopyOutlined } from "@ant-design/icons";
import dayjs from "dayjs";
interface CopyCardProps {
recordTask?: any;
}
const CopyCard: React.FC<CopyCardProps> = ({ recordTask }) => {
const formatDateTime = (date?: string) =>
date ? dayjs(date).format("DD MMM YYYY HH:mm:ss") : "—";
const shiftInfo = {
pickUpDate: formatDateTime(recordTask?.pickup_date) || "—",
pickUpLocation: recordTask?.pickup_location || "—",
shiftDate: formatDateTime(recordTask?.shift_date) || "—",
shiftLocation: recordTask?.shift_location || "—",
cycleDate: formatDateTime(recordTask?.cycle_date) || "—",
cycleLocation: recordTask?.cycle_location || "—",
};
const coDriverInfo = {
driverName: recordTask?.driver_name || "—",
coDriverName: recordTask?.co_driver_name || "—",
coDriverPickUpLocation: recordTask?.co_driver_pickup_location || "—",
coDriverPickUpDate:
formatDateTime(recordTask?.co_driver_pickup_date) || "—",
coDriverDropLocation: recordTask?.co_driver_drop_location || "—",
coDriverDropDate: formatDateTime(recordTask?.co_driver_drop_date) || "—",
};
const handleCopy = (text: string) => {
navigator.clipboard
.writeText(text)
.then(() => message.success("Data copied successfully!"))
.catch(() => message.error("Failed to copy!"));
};
const text = `
SHIFT INFO
Shift Date: ${shiftInfo.shiftDate}
Shift Location: ${shiftInfo.shiftLocation}
Pick up Date: ${shiftInfo.pickUpDate}
Pick Up Location: ${shiftInfo.pickUpLocation}
Cycle Date: ${shiftInfo.cycleDate}
Cycle Location: ${shiftInfo.cycleLocation}
CO DRIVER INFO
Driver's name: ${coDriverInfo.driverName}
Co-Driver's name: ${coDriverInfo.coDriverName}
Co-driver pickup date: ${coDriverInfo.coDriverPickUpDate}
Co-driver pickup location: ${coDriverInfo.coDriverPickUpLocation}
Co-driver drop date: ${coDriverInfo.coDriverDropDate}
Co-driver drop location: ${coDriverInfo.coDriverDropLocation}
`.trim();
const textRu = `
ИНФОРМАЦИЯ О СМЕНЕ
Дата пикапа: ${shiftInfo.pickUpDate}
Место пикапа: ${shiftInfo.pickUpLocation}
Дата шифта: ${shiftInfo.shiftDate}
Место шифта: ${shiftInfo.shiftLocation}
Дата сайкла: ${shiftInfo.cycleDate}
Место сайкла: ${shiftInfo.cycleLocation}
ИНФОРМАЦИЯ О СО-ВОДИТЕЛЕ
Имя драйвера: ${coDriverInfo.driverName}
Имя ко-драйвера: ${coDriverInfo.coDriverName}
Время пикапа ко-драйвера: ${coDriverInfo.coDriverPickUpDate}
Место пикапа ко-драйвера: ${coDriverInfo.coDriverPickUpLocation}
Время высадки ко-драйвера: ${coDriverInfo.coDriverDropDate}
Место высадки ко-драйвера: ${coDriverInfo.coDriverDropLocation}
`.trim();
return (
<>
<Card
title="Shift & Co-Driver Info"
extra={
<Button icon={<CopyOutlined />} onClick={() => handleCopy(text)}>
Copy
</Button>
}
style={{ width: "100%", marginBottom: 20 }}
>
<h4>SHIFT INFO</h4>
<p>Shift Date: {shiftInfo.shiftDate}</p>
<p>Shift Location: {shiftInfo.shiftLocation}</p>
<p>Pick up Date: {shiftInfo.pickUpDate}</p>
<p>Pick Up Location: {shiftInfo.pickUpLocation}</p>
<p>Cycle Date: {shiftInfo.cycleDate}</p>
<p>Cycle Location: {shiftInfo.cycleLocation}</p>
<h4>CO-DRIVER INFO</h4>
<p>Driver's name: {coDriverInfo.driverName}</p>
<p>Co-driver's name: {coDriverInfo.coDriverName}</p>
<p>Co-driver pickup date: {coDriverInfo.coDriverPickUpDate}</p>
<p>Co-driver pickup location: {coDriverInfo.coDriverPickUpLocation}</p>
<p>Co-driver drop date: {coDriverInfo.coDriverDropDate}</p>
<p>Co-driver drop location: {coDriverInfo.coDriverDropLocation}</p>
</Card>
<Card
title="Информация о смене"
extra={
<Button icon={<CopyOutlined />} onClick={() => handleCopy(textRu)}>
Copy
</Button>
}
style={{ width: "100%" }}
>
<h4>ИНФОРМАЦИЯ О СМЕНЕ</h4>
<p>Дата шифта: {shiftInfo.shiftDate}</p>
<p>Место шифта: {shiftInfo.shiftLocation}</p>
<p>Дата сайкла: {shiftInfo.cycleDate}</p>
<p>Место сайкла: {shiftInfo.cycleLocation}</p>
<p>Дата пикапа: {shiftInfo.pickUpDate}</p>
<p>Место пикапа: {shiftInfo.pickUpLocation}</p>
<h4>ИНФОРМАЦИЯ О СО-ВОДИТЕЛЕ</h4>
<p>Имя драйвера: {coDriverInfo.driverName}</p>
<p>Имя ко-драйвера: {coDriverInfo.coDriverName}</p>
<p>Место пикапа ко-драйвера: {coDriverInfo.coDriverPickUpLocation}</p>
<p>Время пикапа ко-драйвера {coDriverInfo.coDriverPickUpDate}</p>
<p>Место высадки ко-драйвера:{coDriverInfo.coDriverDropLocation}</p>
<p>Время высадки ко-драйвера: {coDriverInfo.coDriverDropDate}</p>
</Card>
</>
);
};
export default CopyCard;

@ -1,11 +1,13 @@
import {
TGeneralChartGetParams,
TStatCreatorsGetParams,
TteamChartGetParams,
} from "./../../API/LayoutApi/statistic";
import { useQuery } from "react-query";
import { TStatGetParams, statController } from "../../API/LayoutApi/statistic";
import { TGeneralChartData } from "../../types/Statistic/TStat";
import {
TGeneralChartData,
TGeneralChartGetParams,
} from "../../types/Statistic/TStat";
export const useStatsData = ({
search,
@ -85,16 +87,6 @@ export const useTeamChartData = ({
{ refetchOnWindowFocus: false }
);
};
// export const useGeneralChartData = ({
// start_date,
// end_date,
// }: TGeneralChartGetParams) => {
// return useQuery(
// [`stats/general-stats/`, start_date, end_date],
// () => statController.generalChart({ start_date, end_date }),
// { refetchOnWindowFocus: false }
// );
// };
export const useCardData = ({ start_date, end_date }: TStatGetParams) => {
return useQuery(

@ -29,17 +29,6 @@ export type TteamChartData = {
[category: string]: TaskPerformance | string;
};
export type TGeneralDailyStat = {
task_date: string;
total_tasks: number;
completed_tasks: number;
incomplete_tasks: number;
};
export type TGeneralWrapper = {
daily_stats: TGeneralDailyStat[];
};
export type TCard = {
all_tasks: number;
active_tasks: number;

@ -17,6 +17,7 @@ export type TTask = {
in_charge: InCharge;
forwarded_from: { id: number; name: string };
attachment_set?: TAttachment[];
needs_extra_info: boolean;
};
export type TAttachment = {
@ -40,6 +41,7 @@ export interface Company {
id: number;
name: string;
source: string;
needs_extra_info?: boolean;
}
export interface Service {

Loading…
Cancel
Save