diff --git a/package.json b/package.json index c788ae2..93f218c 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "react-redux": "^8.1.3", "react-router-dom": "^6.15.0", "react-scripts": "5.0.1", - "recharts": "^2.10.4", + "recharts": "^2.13.3", "redux": "^4.2.1", "redux-thunk": "^2.4.2", "typescript": "^4.9.5", diff --git a/src/App.css b/src/App.css index 9fb544f..756c401 100644 --- a/src/App.css +++ b/src/App.css @@ -43,6 +43,11 @@ color: #fff; } +.tt-icon-collapsed { + width: 31.05px; + height: 32px; +} + .isnot { display: none; } @@ -241,15 +246,25 @@ transition: 0.5s; } +.btn-refresh-false:active { + border: 1px solid rgba(249, 158, 44, 1); + color: white; + transition: 0.5s; +} + +.btn-refresh-dark:active { + color: white; + transition: 0.5s; +} + .title { font-family: Inter; font-size: 24px; font-weight: 700; line-height: 28px; - letter-spacing: -0.04em; + letter-spacing: -4%; text-align: left; margin-right: 12px; - color: #bbb; } .filter { @@ -262,9 +277,9 @@ align-items: end; justify-content: space-between; flex-direction: column; + gap: 10px; } - .search-input-false { border: none; outline: none; @@ -541,11 +556,11 @@ border-radius: 8px; border: 1px solid #777777; box-shadow: 0px 1px 3px 0px rgba(20, 22, 41, 0.1); - background: #333; + background: #fff; display: flex; align-items: center; cursor: pointer; - color: #bbb; + color: #0f111c; } .btn-modal-action-false:hover { background: #e6e6e6; @@ -735,32 +750,39 @@ } .card_stat { - font-weight: 500; - font-size: 20px; - padding: 20px; - background: #deeeff; - border-radius: 2px; - width: 200px; - height: 180px; - text-align: center; - -webkit-box-shadow: 0px 0px 12px 1px rgba(34, 60, 80, 0.08); + /* font-weight: 500; */ + /* font-size: 20px; */ + /* padding: 20px; */ + background-color: #deeeff; + /* border-radius: 2px; */ + color: #fff; + width: 156px; + height: 159px; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + gap: 10px; + /* text-align: center; */ + /* -webkit-box-shadow: 0px 0px 12px 1px rgba(34, 60, 80, 0.08); -moz-box-shadow: 0px 0px 12px 1px rgba(34, 60, 80, 0.08); box-shadow: 0px 0px 12px 1px rgba(34, 60, 80, 0.08); cursor: pointer; - transition: 0.4s; -} - -.card_stat:hover { - background: #cfe4fc; + transition: 0.4s; */ } .card_stat span { font-weight: 700; - font-size: 44px; - display: block; - text-align: center; - margin-top: 15px; - color: #464646; + font-size: 28px; + line-height: 40px; + letter-spacing: -2%; +} + +.card_stat p { + font-weight: 500; + font-size: 14px; + line-height: 20px; } .ant-modal-close { @@ -774,6 +796,10 @@ justify-content: space-between; } +.request-radio-group { + margin-left: 20px; +} + .call-requests { background: rgba(246, 137, 0, 1); padding: 3px 5px; @@ -787,11 +813,118 @@ display: none; } -.ant-upload-list-text{ +.ant-upload-list-text { overflow: scroll; height: 50px; } .ant-modal-mask { - background-color: rgba(0, 0, 0, 0.5) !important; /* Используйте нужный вам цвет фона */ -} \ No newline at end of file + background-color: rgba( + 0, + 0, + 0, + 0.5 + ) !important; /* Используйте нужный вам цвет фона */ +} + +.ant-pagination { + position: fixed; + bottom: 90px; + right: 20px; + color: #f99e2c; +} + +.ant-pagination-item-active { + background-color: #f99e2c; + color: white; +} +.ant-pagination .ant-pagination-item-active a { + color: #0f111c; +} + +.ant-pagination .ant-pagination-item-active a:hover { + color: #f99e3c; +} + +.ant-pagination .ant-pagination-item-active { + width: 32px; + height: 32px; + border-color: #d7d8e0; + border-radius: 8px; +} +.ant-pagination .ant-pagination-item-active:hover { + border-color: #f99e3c; +} + +.ant-pagination-prev, +.ant-pagination-next { + width: 40px; + height: 32px; + background-color: #fff; + border: 1px solid #d7d8e0; + border-radius: 8px; + background-color: transparent; +} + +.btn-refresh-dark img { + animation: none; + transition: transform 0.2s linear; +} +.btn-refresh-dark:active img { + animation: spin 1s linear infinite; +} +.btn-refresh-dark img.spin { + animation: spin 1s linear; +} + +.btn-refresh-false img { + animation: none; + transition: transform 0.2s linear; +} +.btn-refresh-false:active img { + animation: spin 1s linear infinite; +} +.btn-refresh-false img.spin { + animation: spin 1s linear; +} + +.ant-btn-default { + color: #0f111c; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(1440deg); + } +} + +@media (max-width: 768px) { + .btn-add { + padding: 7px 10px 7px 10px; + } + .btn-refresh-false { + padding: 7px 10px 7px 10px; + } + .statistics-header { + flex-direction: column; + justify-content: start; + align-items: start; + gap: 16px; + } + .requests-filter { + flex-direction: column; + justify-content: start; + align-items: start; + gap: 16px; + } + .request-radio-group { + margin-left: 0; + } + .profile-statistics { + flex-wrap: wrap; + gap: 10px; + } +} diff --git a/src/App.tsx b/src/App.tsx index 55765e4..6b07ef6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,13 @@ import React, { useCallback, useEffect, useState } from "react"; import "./App.css"; -import { Layout, Menu, ConfigProvider, Dropdown, notification } from "antd"; +import { + Layout, + Menu, + ConfigProvider, + Dropdown, + notification, + Button, +} from "antd"; import { Routes, Route, Navigate, useLocation } from "react-router-dom"; import { mainItems, superItems } from "./Utils/sidebar"; import Login from "./Auth/Login"; @@ -9,6 +16,8 @@ import { LogoutApi } from "./API/auth/Logout"; import { Link } from "react-router-dom"; import { MenuProps } from "antd"; // @ts-ignore +import TT_ELD from "./assets/tticon.svg"; +import collapsedIcon from "./assets/collapsed.png"; import themeBtn from "./assets/theme-btn.svg"; // @ts-ignore import avatar from "./assets/avatar-img.svg"; @@ -44,6 +53,7 @@ import Requests from "./Components/Requests/Requests"; import { callController } from "./API/LayoutApi/callrequests"; import Call from "./Components/CallRequests/Call"; import { dark, light } from "./Utils/styles"; +// import Input from "antd/es/input/Input"; const { Header, Sider, Content } = Layout; const userJSON: any = localStorage.getItem("user"); const userObject = JSON.parse(userJSON); @@ -265,8 +275,9 @@ const App: React.FC = () => { // taskSocket = new WebSocket( // `ws://10.10.10.64:8080/global/?user_id=${admin_id}` // ); + // taskSocket = new WebSocket(`wss://api.tteld.co/global/?user_id=${admin_id}`); taskSocket = new WebSocket( - `wss://api.tteld.co/global/?user_id=${admin_id}` + `wss://ontime-socket.tteld.co/global/?user_id=${admin_id}` ); taskSocket.addEventListener("open", (event) => { @@ -291,6 +302,28 @@ const App: React.FC = () => { connect(); }, []); + useEffect(() => { + const handleResize = () => { + if (window.innerWidth <= 768) { + setCollapsed(true); + } else { + setCollapsed(false); + } + }; + + handleResize(); + + window.addEventListener("resize", handleResize); + + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); + + const toggleCollapsed = () => { + setCollapsed(!collapsed); + }; + // function checkConnection() { // if (!isLive) { // connect(); @@ -354,22 +387,41 @@ const App: React.FC = () => { ) : ( setCollapsed(value)} + onCollapse={toggleCollapsed} style={{ height: "100vh", background: theme === true ? "#202020" : "rgba(20, 22, 41, 1)", }} > -

- TT ELD -

+

+ {collapsed ? ( + Icon + ) : ( + "TT ELD" + )} +

+ + + { className="site-layout-background" style={{ padding: 0, - background: - theme === true ? "#202020" : "rgba(215, 216, 224, 1)", + background: theme === true ? "#202020" : "#F5F5F8", display: "flex", justifyContent: "end", alignItems: "center", @@ -482,7 +533,7 @@ const App: React.FC = () => { padding: 24, minHeight: "92vh", maxHeight: "calc(90vh - 10px)", - overflowY: "scroll", + overflowY: "auto", background: theme === true ? "#202020" : "#fff", }} > diff --git a/src/Auth/Login.tsx b/src/Auth/Login.tsx index 63ad056..5d74048 100644 --- a/src/Auth/Login.tsx +++ b/src/Auth/Login.tsx @@ -108,10 +108,10 @@ const Login: React.FC = () => { Log In
- Forgot password? + Forgot password?
Don't have an account? - Create one now + Create one now
diff --git a/src/Components/CallRequests/Call.tsx b/src/Components/CallRequests/Call.tsx index 53fd7b0..87adef4 100644 --- a/src/Components/CallRequests/Call.tsx +++ b/src/Components/CallRequests/Call.tsx @@ -1,8 +1,14 @@ import { useEffect, useState } from "react"; import CallTable from "./CallTable"; -import { StepForwardOutlined, StepBackwardOutlined } from "@ant-design/icons"; import { useCallData } from "../../Hooks/CallRequests"; -import { Button, Input, Radio, RadioChangeEvent, Space } from "antd"; +import { + Button, + Input, + Radio, + RadioChangeEvent, + Space, + Typography, +} from "antd"; import { TCall } from "../../types/CallRequests/TCall"; import { TSocket } from "../../types/common/TSocket"; @@ -16,6 +22,8 @@ const Call = ({ socketData }: { socketData: TSocket | undefined }) => { page_size: 10, }); + const theme = localStorage.getItem("theme") === "true" ? true : false; + useEffect(() => { setTableData(data?.data); }, [data]); @@ -74,7 +82,7 @@ const Call = ({ socketData }: { socketData: TSocket | undefined }) => {
-

Call Requests

+ Call Requests
{
- + + {/* - + { let num = e.target.value; @@ -107,14 +113,11 @@ const Call = ({ socketData }: { socketData: TSocket | undefined }) => { } }} /> - + - + */}
); }; diff --git a/src/Components/CallRequests/CallTable.tsx b/src/Components/CallRequests/CallTable.tsx index 3fd9f38..d88c124 100644 --- a/src/Components/CallRequests/CallTable.tsx +++ b/src/Components/CallRequests/CallTable.tsx @@ -81,27 +81,27 @@ const CallTable = ({ { title: "Company", dataIndex: "company", - width: "20%", + // width: "20%", }, { title: "Driver", dataIndex: "driver", - width: "20%", + // width: "20%", }, { title: "Note", dataIndex: "note", - width: "15%", + // width: "15%", }, { title: "Requested at", dataIndex: "time", - width: "15%", + // width: "15%", }, { title: "Actions", dataIndex: "action", - width: "100px", + // width: "100px", render: (text, record) => { return (
@@ -133,6 +133,9 @@ const CallTable = ({ rowClassName={(record, index) => index % 2 === 0 ? "odd-row" : "even-row" } + scroll={{ x: "768px" }} + pagination={{ pageSize: 10, size: "default" }} + bordered />
); diff --git a/src/Components/Companies/AddCompanies.tsx b/src/Components/Companies/AddCompanies.tsx index a6e1d94..42c9135 100644 --- a/src/Components/Companies/AddCompanies.tsx +++ b/src/Components/Companies/AddCompanies.tsx @@ -57,7 +57,7 @@ const AddCompany = ({ > @@ -80,7 +80,7 @@ const AddCompany = ({ }))} /> - - + */} + + + ); diff --git a/src/Components/Companies/Companies.tsx b/src/Components/Companies/Companies.tsx index 3136111..5bc1e07 100644 --- a/src/Components/Companies/Companies.tsx +++ b/src/Components/Companies/Companies.tsx @@ -3,14 +3,13 @@ import AddCompany from "./AddCompanies"; import CompanyTable from "./CompaniesTable"; import { StepForwardOutlined, StepBackwardOutlined } from "@ant-design/icons"; import { useCompanyPaginated } from "../../Hooks/Companies"; -import { Button, Input, Space } from "antd"; +import { Button, Input, Space, Typography } from "antd"; // @ts-ignore import IconSearch from "../../assets/searchIcon.png"; //@ts-ignore import addicon from "../../assets/addiconpng.png"; -import { role } from "../../App"; -const theme = localStorage.getItem("theme") === "true" ? true : false; +import { role } from "../../App"; const Company = () => { const [open, setOpen] = useState(false); @@ -51,11 +50,13 @@ const Company = () => { } }; + const theme = localStorage.getItem("theme") === "true" ? true : false; + return (
{open && }
-

Companies

+ Companies {role !== "Checker" && (
- + {/* - + { let num = e.target.value; @@ -98,14 +96,11 @@ const Company = () => { } }} /> - + - + */}
); }; diff --git a/src/Components/Companies/CompaniesTable.tsx b/src/Components/Companies/CompaniesTable.tsx index fde17df..53ee8f5 100644 --- a/src/Components/Companies/CompaniesTable.tsx +++ b/src/Components/Companies/CompaniesTable.tsx @@ -137,7 +137,13 @@ function CompanyTable({ rowClassName={(record, index) => index % 2 === 0 ? "odd-row" : "even-row" } - size="middle" + size="small" + scroll={{ x: "768px" }} + pagination={{ + pageSize: 10, + size: "default", + }} + bordered /> ); diff --git a/src/Components/Customers/Customers.tsx b/src/Components/Customers/Customers.tsx index 05ccbba..6fe5054 100644 --- a/src/Components/Customers/Customers.tsx +++ b/src/Components/Customers/Customers.tsx @@ -6,8 +6,11 @@ import { useCustomerData } from "../../Hooks/Customers"; //@ts-ignore import addicon from "../../assets/addiconpng.png"; // @ts-ignore +import leftPagination from "../../assets/pagination-left.png"; +import rightPagination from "../../assets/right-pagination.png"; import IconSearch from "../../assets/searchIcon.png"; -import { Button, Input, Space } from "antd"; + +import { Button, Input, Space, Typography } from "antd"; const Customer = () => { const [open, setOpen] = useState(false); @@ -48,11 +51,12 @@ const Customer = () => { }, 1000); }; const theme = localStorage.getItem("theme") === "true" ? true : false; + return (
{open && }
-

Drivers

+ Drivers
- + {/* - + { let num = e.target.value; @@ -88,14 +89,11 @@ const Customer = () => { } }} /> - + - + */} ); }; diff --git a/src/Components/Customers/CustomersTable.tsx b/src/Components/Customers/CustomersTable.tsx index 088bdc8..21c16a7 100644 --- a/src/Components/Customers/CustomersTable.tsx +++ b/src/Components/Customers/CustomersTable.tsx @@ -93,7 +93,13 @@ function CustomerTable({ rowClassName={(record, index) => index % 2 === 0 ? "odd-row" : "even-row" } - pagination={false} + size="middle" + bordered + pagination={{ + pageSize: 10, + size: "default", + }} + scroll={{ x: "768px" }} /> ); diff --git a/src/Components/Profile/ChangePassword.tsx b/src/Components/Profile/ChangePassword.tsx index 6a54a4c..7e7b9d4 100644 --- a/src/Components/Profile/ChangePassword.tsx +++ b/src/Components/Profile/ChangePassword.tsx @@ -12,10 +12,10 @@ const ChangePassword = () => { }; return ( -
+
diff --git a/src/Components/Profile/Profile.tsx b/src/Components/Profile/Profile.tsx index d9e9dfe..befba25 100644 --- a/src/Components/Profile/Profile.tsx +++ b/src/Components/Profile/Profile.tsx @@ -1,4 +1,16 @@ import { useState } from "react"; + +import { + LineChart, + Line, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + Legend, + ResponsiveContainer, +} from "recharts"; + import { TProfilePutParams, prof } from "../../API/LayoutApi/profile"; import { Button, @@ -32,7 +44,7 @@ const Profile = () => { const [range, setRange] = useState(1); const onSubmit = async (value: TProfilePutParams) => { - await prof.profPatch(value) + await prof.profPatch(value); refetch(); }; @@ -62,6 +74,20 @@ const Profile = () => { start_date: startDate, end_date: endDate, }); + + const formatDate = (dateString: string): string => { + const date = new Date(dateString); + return new Intl.DateTimeFormat("en-EN", { + day: "2-digit", + month: "short", + }).format(date); + }; + + const chartData = lineData?.daily_stats.map((stat: any) => ({ + date: formatDate(stat.date), + tasks: stat.number_of_tasks, + })); + return (
@@ -84,40 +110,40 @@ const Profile = () => { onFinish={onSubmit} > - + - + - + - + - + - + - + - + @@ -138,7 +164,7 @@ const Profile = () => { > {data && data.team !== "" && ( - + { >
+
-

- Average:{" "} +

+

Total

+ {lineData?.total_for_period} +

+ {role === "Owner" || role === "Tech Support" + ? "Tasks" + : "Points"} +

+
+
+

Average

{lineData?.avg_stats_for_period} - {role === "Owner" ? "tasks" : "pts"}/day -

-

- Total: {lineData?.total_for_period} - {role === "Owner" ? "tasks" : "pts"} -

-

- Contribution: {lineData?.contribution}% -

+

+ {role === "Owner" || role === "Tech Support" + ? "Tasks a day" + : "Points a day"}{" "} +

+
+
+ + + + + + + + + + + +
+
+

Contribution

+ {lineData?.contribution}% +

+ {" "} + {role === "Owner" || role === "Tech Support" + ? "to Business" + : `to ${data?.team}`}{" "} +

+
+ History} key="2"> { onChange={(e: RadioChangeEvent) => setStatus(e.target.value)} size="middle" value={status} - style={{ marginLeft: 20 }} + className="request-radio-group" > Pending Assigned @@ -109,16 +116,14 @@ const Requests = ({ socketData }: { socketData: TSocket | undefined }) => { setOpenModal={setModalOpen} setRequestData={setRequestData} /> - + + {/* - + { let num = e.target.value; @@ -127,14 +132,11 @@ const Requests = ({ socketData }: { socketData: TSocket | undefined }) => { } }} /> - + - + */}
); }; diff --git a/src/Components/Requests/RequestsTable.tsx b/src/Components/Requests/RequestsTable.tsx index 5b53f6e..e16c6c7 100644 --- a/src/Components/Requests/RequestsTable.tsx +++ b/src/Components/Requests/RequestsTable.tsx @@ -160,6 +160,9 @@ const RequestsTable = ({ rowClassName={(record, index) => index % 2 === 0 ? "odd-row" : "even-row" } + scroll={{ x: "768px" }} + pagination={{ pageSize: 10, size: "default" }} + bordered /> ); diff --git a/src/Components/Services/AddService.tsx b/src/Components/Services/AddService.tsx index 83df7aa..a4eec09 100644 --- a/src/Components/Services/AddService.tsx +++ b/src/Components/Services/AddService.tsx @@ -1,7 +1,7 @@ import { Input, Modal, Form as FormAnt } from "antd"; import { serviceController } from "../../API/LayoutApi/services"; -const AddService = ({ +const AddService = ({ open, setOpen, refetch, @@ -40,16 +40,14 @@ const AddService = ({ > @@ -68,4 +66,4 @@ const AddService = ({ ); }; -export default AddService; \ No newline at end of file +export default AddService; diff --git a/src/Components/Services/ServiceTable.tsx b/src/Components/Services/ServiceTable.tsx index 954021e..79d36f0 100644 --- a/src/Components/Services/ServiceTable.tsx +++ b/src/Components/Services/ServiceTable.tsx @@ -72,6 +72,11 @@ const ServiceTable = ({ rowClassName={(record, index) => index % 2 === 0 ? "odd-row" : "even-row" } + pagination={{ + pageSize: 10, + size: "default", + }} + bordered /> ); diff --git a/src/Components/Services/Services.tsx b/src/Components/Services/Services.tsx index 2b8f84b..3ee19bc 100644 --- a/src/Components/Services/Services.tsx +++ b/src/Components/Services/Services.tsx @@ -5,6 +5,7 @@ import ServiceTable from "./ServiceTable"; //@ts-ignore import addicon from "../../assets/addiconpng.png"; import { role } from "../../App"; +import { Typography } from "antd"; const Service = () => { const { data, isLoading, refetch } = useServiceData(); @@ -12,11 +13,12 @@ const Service = () => { const showModal = () => { setOpen(true); }; + return (
{open && } -
-

Services

+
+ Services {role !== "Checker" && ( diff --git a/src/Components/Statistics/StatisticTable.tsx b/src/Components/Statistics/StatisticTable.tsx index ec4be3b..014317d 100644 --- a/src/Components/Statistics/StatisticTable.tsx +++ b/src/Components/Statistics/StatisticTable.tsx @@ -51,11 +51,13 @@ const StatTable = ({ }, ]} pagination={{ - pageSize: 14, + pageSize: 10, + size: "default", }} rowClassName={(record, index) => index % 2 === 0 ? "odd-row" : "even-row" } + bordered />
); diff --git a/src/Components/Tasks/AddTask.tsx b/src/Components/Tasks/AddTask.tsx index 965b8ae..7c43013 100644 --- a/src/Components/Tasks/AddTask.tsx +++ b/src/Components/Tasks/AddTask.tsx @@ -28,6 +28,9 @@ import ontime from "../../assets/ontimeicon.svg"; import tt from "../../assets/tticon.svg"; //@ts-ignore import addicon from "../../assets/addiconpng.png"; +//ts-ignore +import fileUpload from "../../assets/upload-file.png"; + import AddCustomer from "../Customers/AddCustomer"; import AddDriver from "../Companies/AddDriver"; import TextArea from "antd/es/input/TextArea"; @@ -180,7 +183,7 @@ const AddTask = ({ - + @@ -286,17 +290,7 @@ const AddTask = ({
- - - + + + setTeam(value)} options={teamOptions} /> @@ -284,16 +287,14 @@ const Task = ({ showErrorModal={showErrorModal} setErrorModal={setErrorModal} /> - + {/* - + + { let num = e.target.value; @@ -302,14 +303,12 @@ const Task = ({ } }} /> - + + - + */}
); }; diff --git a/src/Components/Teams/AddTeam.tsx b/src/Components/Teams/AddTeam.tsx index ce890e4..341ae63 100644 --- a/src/Components/Teams/AddTeam.tsx +++ b/src/Components/Teams/AddTeam.tsx @@ -41,7 +41,7 @@ const AddTeam = ({ > diff --git a/src/Components/Teams/TeamTable.tsx b/src/Components/Teams/TeamTable.tsx index 97ac80b..821b2e0 100644 --- a/src/Components/Teams/TeamTable.tsx +++ b/src/Components/Teams/TeamTable.tsx @@ -56,6 +56,8 @@ const TeamTable = ({ dataIndex: "created", }, ]} + pagination={{ pageSize: 10, size: "default" }} + bordered /> ); }; diff --git a/src/Components/Teams/Teams.tsx b/src/Components/Teams/Teams.tsx index edaeb90..c5044f8 100644 --- a/src/Components/Teams/Teams.tsx +++ b/src/Components/Teams/Teams.tsx @@ -1,9 +1,10 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useTeamData } from "../../Hooks/Teams"; import TeamTable from "./TeamTable"; //@ts-ignore import addicon from "../../assets/addiconpng.png"; import AddTeam from "./AddTeam"; +import { Typography } from "antd"; const Team = () => { const { data, isLoading, refetch } = useTeamData({}); @@ -11,11 +12,14 @@ const Team = () => { const showModal = () => { setOpen(true); }; + + const theme = localStorage.getItem("theme") === "true" ? true : false; + return (
{open && }
-

Teams

+ Teams
- - - - + {/* */} +