Commit 7247d091 authored by Jayawardena K R U S's avatar Jayawardena K R U S

Full Frontend merged Courier Service Web Application

parent ec5215e1
node_modules
/node_modules
.DS_Store
package-lock.json
build
# Courier_Service
{
"name": "currierservice",
"version": "0.1.0",
"private": true,
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-brands-svg-icons": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@material-tailwind/react": "^2.1.1",
"@react-google-maps/api": "^2.19.2",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"autoprefixer": "^10.4.15",
"axios": "^1.5.0",
"flowbite": "^1.8.1",
"fs": "^0.0.1-security",
"html2canvas": "^1.4.1",
"jspdf": "^2.5.1",
"leaflet": "^1.9.4",
"moedim": "^0.5.0",
"qrcode": "^1.5.3",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-leaflet": "^4.2.1",
"react-qr-code": "^2.0.12",
"react-router-dom": "^6.16.0",
"react-scripts": "5.0.1",
"react-table": "^7.8.0",
"recharts": "^2.7.2",
"styled-components": "^5.3.11",
"tab": "^1.0.0",
"tabs": "^0.2.0",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"tailwindcss": "^3.3.2"
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/1.8.1/flowbite.min.css" rel="stylesheet" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<script src="../src/index.js"></script>
<script src="../path/to/flowbite/dist/flowbite.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/1.8.1/flowbite.min.js"></script>
<div id="root"></div>
</body>
</html>
import axios from "axios";
const url = "http://localhost:3001";
const url_ml = "";
const api = axios.create({
baseURL: url, //---http://localhost:8000
});
export const post = async (urlx, data, params = {}, files = []) => {
try {
const formData = new FormData();
files.forEach((file, i) => {
formData.append(`files[${i}]`, file);
});
console.log(files);
Object.entries(data).forEach(([key, value]) => {
formData.append(key, value);
});
const response = await api.post(urlx, formData, {
params,
headers: {
"Content-Type": "multipart/form-data",
},
});
return response.data;
} catch (error) {
console.log(error);
}
};
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Login from "./routes/login";
import "flowbite";
import Dashboard from "./routes/Admindash";
import CreateDelivery from "./routes/DeliveryRoutes/createDelivery";
import UpdateDelivery from "./routes/DeliveryRoutes/updateDelivery";
import ViewDelivery from "./routes/DeliveryRoutes/viewDelivery";
import Orders from "./routes/DeliveryRoutes/orders";
import RoutePlanning from "./routes/DeliveryRoutes/RoutePlanning";
import CustomerHome from "./routes/DamageDetect/CustomerHome";
import Inquiry from "./routes/DamageDetect/inquiry";
import ScanQR from "./routes/DamageDetect/ScanQR";
import PackageStatus from "./routes/DamageDetect/PackageStatus";
import InquiryStatus from "./routes/DamageDetect/InquiryStatus";
import AdminHome from "./routes/DamageDetect/AdminHome";
import PackageDispatch from "./routes/DamageDetect/PackageDispatch";
import PerformanceTrack from "./routes/PerformanceTracking/performancetrack";
import PerformanceTracker from "./routes/PerformanceTracking/performancetracker";
import CustomerCharn from "./routes/PerformanceTracking/customercharn";
import CustomerCharnTable from "./routes/PerformanceTracking/customercharntable";
import CreateOrder from "./routes/PerformanceTracking/createOrder";
import ChurnRank from "./routes/PerformanceTracking/churnRank";
import UpdateOrder from "./routes/PerformanceTracking/updateOrder";
import MoreInfo from "./routes/PerformanceTracking/moreInfo";
import Modal from "./routes/DeliveryRoutes/removePopup";
import DeliveryRank from "./routes/PerformanceTracking/deliveryRank";
import SingleOrder from "./routes/DeliveryRoutes/singleOrder";
import SingleOrderUpdate from "./routes/DeliveryRoutes/singleOrderUpdate";
// Routes: Dilakshi
import Tickets from "./pages/Tickets/Tickets";
import SingleTicket from "./pages/Tickets/SingleTicket";
import ManualTickets from "./pages/Tickets/ManualTickets";
import ViewPack from "./routes/DamageDetect/ViewPackage";
function App() {
return (
<div className="App">
<BrowserRouter>
<Routes>
<Route index path="/" element={<Login />} />
<Route path="/Dashboard" element={<Dashboard />} />
<Route path="/CreateDelivery" element={<CreateDelivery />} />
<Route path="/UpdateDelivery/:id" element={<UpdateDelivery />} />
<Route path="/ViewDelivery/:id" element={<ViewDelivery />} />
<Route path="/Orders" element={<Orders />} />
<Route path="/RoutePlanning" element={<RoutePlanning />} />
<Route path="/CustomerHome" element={<CustomerHome />} />
<Route path="/Inquiry" element={<Inquiry />} />
<Route path="/ScanQR" element={<ScanQR />} />
<Route path="/PackageStatus" element={<PackageStatus />} />
<Route path="/InquiryStatus" element={<InquiryStatus />} />
<Route path="/AdminHome" element={<AdminHome />} />
<Route path="/ViewPack" element={<ViewPack />} />
<Route path="/PackageDispatch" element={<PackageDispatch />} />
<Route path="/tickets" element={<Tickets />} />
<Route path="/SingleOrder/:id" element={<SingleOrder />} />
<Route path="PerformanceTrack" element={<PerformanceTrack />} />
<Route path="PerformanceTracker" element={<PerformanceTracker />} />
<Route path="CustomerChurn" element={<CustomerCharn />} />
<Route path="CustomerChurnTable" element={<CustomerCharnTable />} />
<Route
path="/SingleOrderUpdate/:id"
element={<SingleOrderUpdate />}
/>
<Route path="CreateOrder" element={<CreateOrder />} />
<Route path="ChurnRank" element={<ChurnRank />} />
<Route path="UpdateOrder/:slug" element={<UpdateOrder />} />
<Route path="MoreInfo/:slug" element={<MoreInfo />} />
<Route path="Modal" element={<Modal />} />
<Route path="DeliveryRank" element={<DeliveryRank />} />
{/* Routes: Dilakshi */}
<Route path="/tickets" element={<Tickets />} />
<Route path="/manualTickets" element={<ManualTickets />} />
<Route path="/ticket/:id" element={<SingleTicket />} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
import React, { useEffect, useState } from "react";
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
} from "recharts";
const d = [
{ name: "Jan", Month: 7 },
{ name: "Feb", Month: 10 },
{ name: "Mar", Month: 16 },
{ name: "Apr", Month: 20 },
{ name: "May", Month: 5 },
{ name: "Jun", Month: 12 },
{ name: "Jul", Month: 5 },
{ name: "Aug", Month: 9 },
{ name: "Sep", Month: 1 },
{ name: "Oct", Month: 2 },
{ name: "Nov", Month: 4 },
{ name: "Dec", Month: 5 },
];
const BarChartExample = ({ month }) => {
const [data, setData] = useState([
{ name: "Jan", Month: 7 },
{ name: "Feb", Month: 10 },
{ name: "Mar", Month: 16 },
{ name: "Apr", Month: 20 },
{ name: "May", Month: 5 },
{ name: "Jun", Month: 12 },
{ name: "Jul", Month: 5 },
{ name: "Aug", Month: 9 },
{ name: "Sep", Month: 1 },
{ name: "Oct", Month: 2 },
{ name: "Nov", Month: 4 },
{ name: "Dec", Month: 5 },
]);
useEffect(() => {
console.log(data);
}, [month]);
useEffect(() => {
console.log(month);
if (month != null) {
let newData = d.map((item) => {
console.log(item);
if (item.name == month) {
return {
name: item.name,
Month: item.Month,
};
} else {
return {
name: item.name,
Month: 0,
};
}
});
setData(newData);
}
}, [month]);
return (
<BarChart width={700} height={300} data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey={"Month"} fill="#1565c0" />
</BarChart>
);
};
export default BarChartExample;
import React, { useMemo } from "react";
import { useTable, useGlobalFilter } from "react-table";
const DataTable = ({ data }) => {
// Define the table columns
const columns = useMemo(
() => [
{
Header: "Customer ID",
accessor: "id",
},
{
Header: "Sender Name",
accessor: "sendname",
},
{
Header: "Receiver Name",
accessor: "receivename",
},
{
Header: "Receiver Address",
accessor: "receiveaddress",
},
{
Header: "Province",
accessor: "province",
},
{
Header: "Item Type",
accessor: "item",
},
{
Header: "Predetermines Days",
accessor: "days",
},
// Add more columns as needed
],
[]
);
function setShowPopup(id) {
if (window.confirm("Are you sure you want to remove this item?")) {
setShowPopup(true);
}
}
// Create an instance of the table
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
state,
setGlobalFilter,
} = useTable({ columns, data }, useGlobalFilter);
const { globalFilter } = state;
return (
<div className="w-5/6 side-panel p-5 md:ml-[250px] ml-16">
{/* <div className="w-[100%]"> */}
{/* <div className="flex justify-end">
<input
type="text"
value={globalFilter || ""}
onChange={(e) => setGlobalFilter(e.target.value)}
className="h-8 pl-2 text-lg bg-black/10 top-28 mb-4"
placeholder="Search..."
/><br/><br/>
</div> */}
<form>
<label for="default-search" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
</svg>
</div>
<input type="search" id="default-search" class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Search Orders....." required/>
<button type="submit" class="text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Search</button>
</div>
</form>
<br/>
<div className="relative overflow-x-auto shadow-md sm:rounded-lg">
<table className="w-full text-sm text-left text-black" {...getTableProps()}>
<thead className=" text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()} className="" key={headerGroup.id}>
{headerGroup.headers.map((column) => (
<th
{...column.getHeaderProps()}
className="p-3 border-[1px] border-black/50"
key={column.id}
>
{column.render("Header")}
</th>
))}
<th>Other Informations</th>
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
return (
<tr {...row.getRowProps()} className="border-[1px] border-black/50" key={row.id}>
{row.cells.map((cell) => {
return (
<>
<td
{...cell.getCellProps()}
className="p-3 border-[1px] border-black/50 hover:bg-slate-300"
key={cell.column.id}
>
{cell.render("Cell")}
</td>
</>
);
})}
<td className="flex gap-2 p-1 ">
<a href={`/UpdateOrder/${row.id + 1}`}>
<button class="bg-purple-700 hover:bg-purple-900 text-white font-bold py-2 px-2 rounded mt-3">
Update
</button>
</a>
<button
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-2 rounded mt-3"
onClick={() => setShowPopup(row.id + 1)}
>
Remove
</button>
<a href={`/MoreInfo/${row.id + 1}`}>
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-2 rounded mt-3">
View
</button>
</a>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
{/* </div> */}
</div>
);
};
export default DataTable;
import React, { useMemo } from "react";
import { useTable, useGlobalFilter } from "react-table";
import { MessageDialog } from "./MessageDialog";
import { useState, useEffect } from 'react';
const DataTable2 = ({ data }) => {
const [popUpStatus, setpopUpStatus] = useState(false);
// Define the table columns
const columns = useMemo(
() => [
{
Header: "Customer ID",
accessor: "id",
},
{
Header: "Sender Name",
accessor: "sendname",
},
{
Header: "Sender Address",
accessor: "senderaddress",
},
{
Header: "Province",
accessor: "province",
},
{
Header: "Last Item",
accessor: "lastitem",
},
{
Header: "Feedback",
accessor: "feedback",
},
{
Header: "Churn Status",
accessor: "charnstatus",
},
// Add more columns as needed
],
[]
);
function setShowPopup(id) {
if (window.confirm("Are you sure you want to remove this item?")) {
setShowPopup(true);
}
}
// Create an instance of the table
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
state,
setGlobalFilter,
} = useTable({ columns, data }, useGlobalFilter);
const { globalFilter } = state;
const popUp = () => {
setpopUpStatus(!popUpStatus)
console.log(popUpStatus)
}
return (
<div className="w-5/6 side-panel p-5 md:ml-[250px] ml-16">
{/* // <div className="w-[100%]"> */}
{/* <div className="flex justify-end">
<input
type="text"
value={globalFilter || ""}
onChange={(e) => setGlobalFilter(e.target.value)}
className="h-8 pl-2 text-lg bg-black/10 top-28 mb-4"
placeholder="Search..."
/><br/><br/>
</div> */}
<form>
<label for="default-search" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
</svg>
</div>
<input type="search" id="default-search" class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Search Orders....." required/>
<button type="submit" class="text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Search</button>
</div>
</form>
<br/>
<div className="relative overflow-x-auto shadow-md sm:rounded-lg">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400" {...getTableProps()}>
<thead className=" text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()} className="" key={headerGroup.id}>
{headerGroup.headers.map((column) => (
<th
{...column.getHeaderProps()}
className="p-3 border-[1px] border-black/50"
key={column.id}
>
{column.render("Header")}
</th>
))}
<th classname="p-3 border-[1px] border-black/50">Actions</th>
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
return (
<tr {...row.getRowProps()} className="border-[1px] border-black/50" key={row.id}>
{row.cells.map((cell) => {
return (
<>
<td
{...cell.getCellProps()}
className="p-3 border-[1px] border-black/50 hover:bg-slate-300"
key={cell.column.id}
>
{cell.render("Cell")}
</td>
</>
);
})}
<td className="flex gap-2 p-1 ">
{/* <a href={`/MoreInfo/${row.id + 1}`}> */}
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-2 rounded mt-3" onClick={popUp}>
View
</button>
{popUpStatus &&
<MessageDialog click={true} link={`/MoreInfo/${row.id + 1}`}/>
}
{/* </a> */}
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
};
export default DataTable2;
import React, { useEffect, useState } from 'react';
import { GoogleMap, Marker, InfoWindow } from '@react-google-maps/api';
const Gmap = () => {
const [map, setMap] = useState(null);
const [userLocation, setUserLocation] = useState(null);
// Function to get the user's current location
const getUserLocation = () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
setUserLocation({
lat: position.coords.latitude,
lng: position.coords.longitude,
});
},
(error) => {
console.error(error);
}
);
} else {
console.error('Geolocation is not supported by this browser.');
}
};
// Function to handle when the map is loaded
const handleMapLoad = (map) => {
setMap(map);
};
useEffect(() => {
getUserLocation();
}, []);
return (
<div className="map w-[60%]">
<GoogleMap
onLoad={handleMapLoad}
center={userLocation}
zoom={15}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{userLocation && <Marker position={userLocation} />}
</GoogleMap>
</div>
);
};
export default Gmap;
import React from "react";
import {
Button,
Dialog,
DialogHeader,
DialogBody,
DialogFooter,
Input,
Textarea,
} from "@material-tailwind/react";
export function MessageDialog(args) {
const [open, setOpen] = React.useState(args.click);
const handleOpen = () => setOpen(!open);
const handleExit = () => {
setOpen(false);
};
return (
<>
<Button onClick={handleOpen}>Message Dialog</Button>
<Dialog
open={open}
handler={handleOpen}
className="border border-blue-800"
style={{ width: "30%", height: "45%", margin: "auto" }}
>
<div className="flex items-center justify-between ">
<DialogHeader>Last courier Information</DialogHeader>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
className="mr-3 h-5 w-5 cursor-pointer"
onClick={handleOpen}
>
<path
fillRule="evenodd"
d="M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z"
clipRule="evenodd"
/>
</svg>
</div>
<DialogBody divider className="ml-5">
<div className="grid gap-6">
<div className="text-gray-900">
<strong>Item Type:</strong> {args.type}
</div>
<div>
<strong>Item Status:</strong> {args.status}
</div>
<div>
<strong>onTime:</strong>{" "}
{args.time ? "On Time Delivered" : "Not Delivered On Time"}
</div>
<div>
<strong>Charn Probability: </strong>
<strong style={{ fontSize: "20px", color: "crimson" }}>
{args.prob}
</strong>
</div>
</div>
</DialogBody>
<DialogFooter className="space-x-2">
<Button variant="outlined" color="red" onClick={handleExit}>
Exit
</Button>
</DialogFooter>
</Dialog>
</>
);
}
import React from 'react';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
const data = [
{ name: 'Jan', value: 200, pv: 450, lv: 150, kv: 213},
{ name: 'Feb', value: 350, pv: 270, lv: 470, kv: 531},
{ name: 'Mar', value: 100, pv: 300, lv: 560, kv: 435},
{ name: 'Apr', value: 400, pv: 100, lv: 700, kv: 353},
{ name: 'May', value: 300, pv: 700, lv: 450, kv: 821},
{ name: 'Jun', value: 100, pv: 660, lv: 300, kv: 156},
{ name: 'Jal', value: 250, pv: 750, lv: 250, kv: 213},
{ name: 'Aug', value: 350, pv: 450, lv: 360, kv: 423},
{ name: 'Sep', value: 600, pv: 100, lv: 100, kv: 146},
// Add more data points as needed
];
const MonthlyProgress = () => {
return (
<div className="h-full p-3 w-full justify-center text-center rounded-lg flex flex-col bg-white">
<span className="font-semibold text-slate-900 text-[18px]">Monthly Progress</span>
<div className="mt-3 flex flex-row justify-center items-center">
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis/>
<Tooltip />
<Line type="monotone" dataKey="value" stroke="#8884d8" strokeWidth={2} />
<Line type="monotone" dataKey="pv" stroke="#82ca9d" strokeWidth={2} />
<Line type="monotone" dataKey="lv" stroke="#f0da34" strokeWidth={2} />
<Line type="monotone" dataKey="kv" stroke="#d7002a" strokeWidth={2} />
</LineChart>
</ResponsiveContainer>
</div>
</div>
);
};
export default MonthlyProgress;
This diff is collapsed.
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
.popup {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 20px;
border: 1px solid black;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
import SidePanel from "../components/sidepanel"
export default function Tickets() {
return (
<div className="main-body h-screen w-full bg-slate-100">
<div className="main-body-container h-screen w-full flex flex-row">
<SidePanel />
</div>
</div>
);
}
import React from "react";
import Sidepanel from "../../components/sidepanel";
import bg from '../../images/mainbg1.jpg';
export default class ManualTickets extends React.Component {
constructor(props) {
super(props)
// STATE
this.state = {
tickets: []
}
}
componentDidMount = () => {
fetch("https://api.dcsrp.xyz/v1.0/tickets/manual")
.then(Response => Response.json())
.then(Response => {
console.log(Response)
if (Response.status === "success") {
this.setState({...this.state, tickets: Response.data.tickets})
}
})
}
render() {
return (
<div className="main-body h-screen w-full bg-slate-100">
<img src={bg} alt="" className="object-cover w-[100%] h-[100%] fixed" />
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full bg-white rounded-lg">
<h2 className="flex items-center justify-center pt-4 text-xl uppercase font-bold pb-4 mt-4">Manual Tickets</h2>
<div class="overflow-x-auto">
<table class="min-w-full text-left text-sm font-light">
<thead class="border-b font-medium dark:border-neutral-500">
<tr>
<th scope="col" class="px-6 py-4">#ID</th>
<th scope="col" class="px-6 py-4">Customer's Name</th>
<th scope="col" class="px-6 py-4">Customer's Mobile</th>
<th scope="col" class="px-6 py-4">Status</th>
<th scope="col" class="px-6 py-4">Mode</th>
<th scope="col" class="px-6 py-4">Date</th>
<th scope="col" class="px-6 py-4">Action</th>
</tr>
</thead>
<tbody>
{
this.state.tickets.map((ticket, idx) => {
let date = new Date(ticket.time.created * 1000)
return <tr key={idx} class="border-b transition duration-300 ease-in-out hover:bg-neutral-100 dark:border-neutral-500 dark:hover:bg-neutral-600">
<td class="whitespace-nowrap px-6 py-4 font-medium">{ ticket.id }</td>
<td class="whitespace-nowrap px-6 py-4">{ ticket.customer.name }</td>
<td class="whitespace-nowrap px-6 py-4">{ ticket.customer.mobile }</td>
<td class="whitespace-nowrap px-6 py-4">{ ticket.status }</td>
{ ticket.agent == "auto" && <td class="whitespace-nowrap px-6 py-4">AI</td> }
{ ticket.agent == "manual" && <td class="whitespace-nowrap px-6 py-4">Human</td> }
<td class="whitespace-nowrap px-6 py-4">{ date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() }</td>
<td class="whitespace-nowrap px-6 py-4">
<a href={"/ticket/" + ticket.id }>
<button class="group relative h-8 w-24 overflow-hidden rounded-2xl bg-blue-500 text-sm font-bold text-white">View Ticket
<div class="absolute inset-0 h-full w-full scale-0 rounded-2xl transition-all duration-300 group-hover:scale-100 group-hover:bg-white/30"></div>
</button>
</a>
</td>
</tr>
})
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
);
}
}
import React, { useEffect, useState } from "react"
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPen } from '@fortawesome/free-solid-svg-icons';
import Sidepanel from "../../components/sidepanel";
// IMAGES
import ai from '../../images/ai.gif';
import propic from "../../images/propic.jpg";
import { useParams } from "react-router-dom";
// CLASS: SingleTicket
export default function SingleTicket() {
let { id } = useParams()
const [ticket, setTicket] = useState({})
const [loading, setLoading] = useState(true)
const [ticketMessage, setTicketMessage] = useState("")
useEffect(() => {
/**
* Fetch ticket information and update the local
* state to reflect the information
*/
fetch("https://api.dcsrp.xyz/v1.0/ticket/" + id)
.then(Response => Response.json())
.then(Response => {
console.log(Response)
if (Response.status === "success") {
setTicket(Response.data.ticket)
setLoading(false)
}
})
}, [])
// Handle assign to me
const handleAssignToMe = (event) => {
event.preventDefault();
fetch("https://api.dcsrp.xyz/v1.0/ticket/" + id + "/assign", { method: "POST" })
.then(Response => Response.json())
.then(Response => {
if (Response.status === "success") {
alert("Assigned to me")
window.location.reload()
} else {
alert("Failed to assign ticket")
window.location.reload()
}
})
};
const OnClick_Message = (event) => {
event.preventDefault();
fetch("https://api.dcsrp.xyz/v1.0/ticket/" + id + "/message", {
method: "POST",
body: JSON.stringify({
message: ticketMessage
})
})
.then(Response => Response.json())
.then(Response => {
console.log(Response)
if ( Response.status === "success" ) {
alert("Message sent to customer")
window.location.reload()
} else {
alert("Failed to sent message to customer")
window.location.reload()
}
})
}
// Convert unixtime to date
function convert_date(ts) { return new Date(ts * 1000).toLocaleDateString("en-US") }
function convert_time(ts) {
let date = new Date(ts * 1000)
return date.getHours() + ":" + date.getMinutes()
}
// RENDER TIMELINE
function TimelineItems() {
if ( ticket.timeline != null ) {
return ticket.timeline.map((item) => {
return (
<div className="flex items-center w-full my-6 -ml-1.5" key={ item.id }>
<div className="w-1/12 z-10">
<div className="w-3.5 h-3.5 bg-blue-600 rounded-full"></div>
</div>
<div className="w-11/12">
<p className="text-sm">{ item.description }</p>
<p className="text-xs text-gray-500">{ convert_time(item.time.created)}</p>
</div>
</div>
)
})
}
}
if (loading) {
return "Loading ..."
} else {
return(
<div className="main-body h-screen w-full">
{/* <link href="https://cdn.jsdelivr.net/npm/daisyui@3.6.4/dist/full.css" rel="stylesheet" type="text/css" /> */}
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="flex flex-row w-full overflow-y-auto">
<div className="flex flex-col main-body-container w-4/6 p-5">
{/* GLANCE */}
<div className="w-[100%] p-8 shadow-lg border bg-white border-slate-100 rounded-lg">
<div className="justify-between sm:flex">
<div>
<h5 className="text-xl font-bold text-slate-900">Ticket ID - #{ticket.id}</h5>
</div>
<button className="group relative px-5 py-2 overflow-hidden rounded-2xl bg-green-500 text-sm font-bold text-white" onClick={handleAssignToMe}>Assign to me
<div className="absolute inset-0 h-full w-full scale-0 rounded-2xl transition-all duration-300 group-hover:scale-100 group-hover:bg-white/30"></div>
</button>
</div>
<div className="grid grid-cols-6 w-[80%] mt-2">
<div className="col-span-3 p-3"><p className="text-gray-700 ">Opened Date :<span className="font-semibold"> { convert_date(ticket.time.created) }</span></p></div>
<div className=" col-span-3 p-3"><p className="text-gray-700 ">Update Date :<span className="font-semibold"> { convert_date(ticket.time.updated) }</span></p></div>
<div className=" col-span-3 p-3"><p className="text-gray-700 ">Current Time :<span className="font-semibold"> { convert_time(ticket.time.created) }</span></p></div>
<div className=" col-span-3 p-3"><p className="text-gray-700">Status :<span className="font-semibold"> { ticket.status }</span></p></div>
<div className=" col-span-6 p-3"><p className="text-gray-700 ">Question : </p></div>
</div>
<div className="border shadow-md text-gray-700 border-gray-400 w-full h-auto bg-gray-100 p-2 rounded-lg">
<p>{ ticket.call.transcript }</p>
</div>
</div>
{/* TEXTAREA */}
<div className="w-[100%] mt-5 p-8 overflow shadow-lg border bg-white border-slate-100 rounded-lg">
<div className="flex">
<div className="mx-auto w-full">
<form action="" method="POST">
<div className="mb-5">
<textarea rows="4" name="message" id="message" placeholder="Type your message" className="w-full resize-none rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" onChange={(e)=>setTicketMessage(e.target.value)} value={ ticketMessage } />
</div>
<div>
<button className="hover:shadow-form rounded-md bg-[#6A64F1] py-3 px-8 text-base font-semibold text-white outline-none" onClick={OnClick_Message}>Submit</button>
</div>
</form>
</div>
</div>
</div>
{/* TIMELINE */}
<div className="flex-1 bg-white rounded-lg shadow-xl mt-4 p-8 ">
<h4 className="text-xl text-gray-900 font-bold">Time Line</h4>
<div className="relative px-4">
<TimelineItems />
</div>
</div>
</div>
<div className="flex flex-col main-body-container w-[30%] h-full p-4">
{/* IMPORTANT */}
<div className="w-full h-50 justify-center items-center mt-1 hidden">
<div className="flex flex-row w-[100%] h-40 border border-red-400 bg-red-100 rounded-lg">
<div className="w-[90%] p-5 md:text-xs lg:text-sm xl:text-base"><p>Important Information</p></div>
</div>
</div>
{/* STAFF */}
<div className={"flex-col rounded-lg w-full h-80 mt-3 border " + (ticket.agent == "manual" ? "flex" : "hidden")}>
<div className="w-full overflow-x-hidden sm:text-xs md:text-xs lg:text-xs xl:text-base rounded-t-lg bg-gray-700 text-white h-10 text-center pt-1 border border-gray-900">Asigned Staff Member</div>
<div className="flex flex-row w-full h-auto border p-3 overflow-x-auto ">
<div className=""><img className="w-14 h-14 rounded-full border object-cover" src={propic} /></div>
<div className="w-3/5 p-5 md:text-xs lg:text-sm xl:text-sm flex flex-row">
<p>dilakshilamahewa@gmail.com</p><FontAwesomeIcon icon={faPen} className="ml-1"/>
</div>
</div>
<div className="p-5 md:text-xs lg:text-xs xl:text-sm grid grid-cols-3 overflow-x-auto text-gray-600">
<div className=" mt-2">Email - </div><div className="col-span-2 mt-2">dilakshilamahewa@gmail.com</div>
<div className=" mt-2">Post - </div><div className="col-span-2 mt-2">Support Engineer</div>
<div className=" mt-2">Phone - </div><div className="col-span-2 mt-2"> 0704003184</div>
<div className="col-span-3 flex justify-end pr-5"><button className="bg-blue-600 px-4 py-1 rounded-lg text-gray-100 mt-5">Primary</button></div>
</div>
</div>
{/* AI */}
<div className={"flex-col rounded-lg w-full h-80 mt-3 border " + (ticket.agent == "auto" ? "flex" : "hidden")}>
<div className="w-[100%] md:text-xs lg:text-sm xl:text-base rounded-t-lg bg-gray-700 text-white h-10 text-center pt-1 border border-gray-900">Auto (AI)</div>
<div className=""><h1 className="text-xl font-bold text-center pt-3">Hello!</h1></div>
<div className=" flex justify-center items-center mt-2"><img src={ai} className="w-1/2 h-auto "/></div>
<div className="md:text-xs lg:text-sm xl:text-base flex justify-center items-center mt-2"><p>How can I help you?</p></div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
}
import React from "react";
import Sidepanel from "../../components/sidepanel";
import bg from '../../images/mainbg1.jpg';
export default class Tickets extends React.Component {
constructor(props) {
super(props)
// STATE
this.state = {
tickets: []
}
}
componentDidMount = () => {
fetch("https://api.dcsrp.xyz/v1.0/tickets")
.then(Response => Response.json())
.then(Response => {
if (Response.status === "success") {
this.setState({...this.state, tickets: Response.data.tickets})
}
})
}
render() {
return (
<div className="main-body h-screen w-full bg-slate-100">
<img src={bg} alt="" className="object-cover w-[100%] h-[100%] fixed" />
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full bg-white rounded-lg">
<h2 className="flex items-center justify-center pt-4 text-xl uppercase font-bold pb-4 mt-4">All Tickets</h2>
<div class="overflow-x-auto">
<table class="min-w-full text-left text-sm font-light">
<thead class="border-b font-medium dark:border-neutral-500">
<tr>
<th scope="col" class="px-6 py-4">#ID</th>
<th scope="col" class="px-6 py-4">Customer's Name</th>
<th scope="col" class="px-6 py-4">Customer's Mobile</th>
<th scope="col" class="px-6 py-4">Status</th>
<th scope="col" class="px-6 py-4">Mode</th>
<th scope="col" class="px-6 py-4">Date</th>
<th scope="col" class="px-6 py-4">Action</th>
</tr>
</thead>
<tbody>
{
this.state.tickets.map((ticket, idx) => {
let date = new Date(ticket.time.created * 1000)
return <tr key={idx} class="border-b transition duration-300 ease-in-out hover:bg-neutral-100 dark:border-neutral-500 dark:hover:bg-neutral-600">
<td class="whitespace-nowrap px-6 py-4 font-medium">{ ticket.id }</td>
<td class="whitespace-nowrap px-6 py-4">{ ticket.customer.name }</td>
<td class="whitespace-nowrap px-6 py-4">{ ticket.customer.mobile }</td>
<td class="whitespace-nowrap px-6 py-4">{ ticket.status }</td>
{ ticket.agent == "auto" && <td class="whitespace-nowrap px-6 py-4">AI</td> }
{ ticket.agent == "manual" && <td class="whitespace-nowrap px-6 py-4">Human</td> }
<td class="whitespace-nowrap px-6 py-4">{ date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() }</td>
<td class="whitespace-nowrap px-6 py-4">
<a href={"/ticket/" + ticket.id }>
<button class="group relative h-8 w-24 overflow-hidden rounded-2xl bg-blue-500 text-sm font-bold text-white">View Ticket
<div class="absolute inset-0 h-full w-full scale-0 rounded-2xl transition-all duration-300 group-hover:scale-100 group-hover:bg-white/30"></div>
</button>
</a>
</td>
</tr>
})
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
);
}
}
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faTicket, faHome, faList } from '@fortawesome/free-solid-svg-icons'
export default function Sidepanel() {
return(
<div className="w-[300px] side-panel p-5 flex flex-col items-center bg-[#d7002a] ">
<div className="sidepalen-body h-2/3 p-3 w-full justify-center">
<div className="user-profile flex flex-row items-center space-x-5">
<label className="text-[28px]">
<FontAwesomeIcon icon={faTicket} color="white" />
</label>
<span className="user-name text-[22px] text-white">Tickets</span>
</div>
<div className="nav-body w-full flex-col justify-center space-y-5 mt-10">
<ul className="space-y-5">
<Link to="/Dashboard"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faHome} className="mr-5"/>Dashboard</li>
</Link>
<Link to="/tickets"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faList} className="mr-5"/>All Tickets</li>
</Link>
<Link to="/manualTickets"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faList} className="mr-5"/>Manual Tickets</li>
</Link>
</ul>
</div>
</div>
</div>
);
}
This diff is collapsed.
import { useState } from "react";
import Sidepanel from "../../components/sidepanel";
import bg from "../../images/mainbg1.jpg";
import axios from "axios";
import QRCode from "qrcode.react";
function AdminHome() {
const [formData, setFormData] = useState({
senderName: "",
senderContact: "",
img1: null,
img2: null,
img1Base64: "",
img2Base64: "",
});
const [isLoading, setIsLoading] = useState(false);
const [showQRCode, setShowQRCode] = useState(false);
const handleInputChange = (event) => {
const { name, value } = event.target;
setFormData({
...formData,
[name]: value,
});
};
const handleFileChange = async (event) => {
const { name, files } = event.target;
const selectedFile = files[0];
if (selectedFile) {
const reader = new FileReader();
reader.onload = (e) => {
const base64Data = e.target.result;
setFormData({
...formData,
[name]: selectedFile,
[`${name}Base64`]: base64Data,
});
};
reader.readAsDataURL(selectedFile);
}
};
const handleSubmit = async (event) => {
event.preventDefault();
try {
setIsLoading(true);
const requestData = {
senderName: formData.senderName,
senderContact: formData.senderContact,
img1: formData.img1Base64,
img2: formData.img2Base64,
};
console.log("Final Dataset:", requestData);
await axios.post(
"https://lime-plain-bullfrog.cyclic.app/api/saveFormData",
requestData
);
// setFormData({
// senderName: "",
// senderContact: "",
// img1: "",
// img2: "",
// img1Base64: "",
// img2Base64: "",
// });
setIsLoading(false);
setShowQRCode(true);
alert("Data saved successfully");
} catch (error) {
console.error(error);
alert("An error occurred while saving data");
setIsLoading(false);
}
};
const handlePrint = () => {
console.log("Print QR");
};
return (
<div className="main-body h-screen w-full bg-slate-100">
<img
src={bg}
alt=""
srcset=""
className="object-cover w-[100%] h-[100%] fixed"
/>
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[80%] flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg shadow-md shadow-slate-300">
<form onSubmit={handleSubmit} className="flex flex-col w-full">
<label
htmlFor="sendername"
className="mb-2 font-semibold text-gray-600"
>
Sender Name
</label>
<input
type="text"
id="sendername"
name="senderName"
required
value={formData.senderName}
onChange={handleInputChange}
className="mb-4 p-2 rounded-lg border border-gray-300"
/>
<label
htmlFor="senderContact"
className="mb-2 font-semibold text-gray-600"
>
Sender Contact
</label>
<input
type="number"
maxLength="10"
id="senderContact"
name="senderContact"
required
value={formData.senderContact}
onChange={handleInputChange}
className="mb-4 p-2 rounded-lg border border-gray-300"
/>
<label
htmlFor="image01"
className="mb-2 font-semibold text-gray-600"
>
Upload Image 01
</label>
<input
type="file"
id="image01"
name="img1"
className="mb-4 py-2 pl-5 file:rounded-lg rounded-lg border border-gray-300"
accept="image/*"
required
onChange={handleFileChange}
/>
{formData.img1Base64 && (
<img
width={200}
style={{ height: "250px" }}
src={formData.img1Base64}
alt="Image 01"
className="mb-4 max-w-[300px]"
/>
)}
<label
htmlFor="image02"
className="mb-2 font-semibold text-gray-600"
>
Upload Image 02
</label>
<input
type="file"
id="image02"
name="img2"
className="mb-4 py-2 pl-5 file:rounded-lg rounded-lg border border-gray-300"
accept="image/*"
required
onChange={handleFileChange}
/>
{formData.img2Base64 && (
<img
width={200}
style={{ height: "250px" }}
src={formData.img2Base64}
alt="Image 02"
className="mb-4 max-w-[300px]"
/>
)}
<div className="flex flex-row space-x-3 w-full">
<div className="flex items-center justify-between z-10">
<button
className="text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full bg-gradient-to-r from-red-500 to-red-700 z-10"
type="submit"
disabled={isLoading}
>
{isLoading ? "Saving..." : "Save"}{" "}
</button>
</div>
</div>
</form>
</div>
{showQRCode && (
<div className="bg-white p-4 mt-4 rounded-lg shadow-md">
<QRCode value={formData.senderContact} />
<button
onClick={handlePrint}
className="mt-2 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600"
>
Print QR Code
</button>
</div>
)}
</div>
</div>
</div>
</div>
);
}
export default AdminHome;
import { useState } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import bg from "../../images/mainbg1.jpg";
function AdminHome() {
const [formData, setFormData] = useState({
senderName: "",
receiverName: "",
packageId: "",
});
const handleInputChange = (event) => {
const { name, value } = event.target;
setFormData((prevState) => ({
...prevState,
[name]: value,
}));
};
const handleSubmit = (event) => {
event.preventDefault();
};
function handleImageUpload(event) {
const selectedFiles = event.target.files;
const fileCount = selectedFiles.length;
if (fileCount < 1 || fileCount > 5) {
console.log("Please select between 1 and 5 images.");
return;
}
}
return (
<div className="main-body h-screen w-full bg-slate-100">
<img
src={bg}
alt=""
srcset=""
className="object-cover w-[100%] h-[100%] fixed"
/>
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[80%] flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg shadow-md shadow-slate-300">
<form onSubmit={handleSubmit} className="flex flex-col w-full">
<label
htmlFor="sendername"
className="mb-2 font-semibold text-gray-600"
>
Sender Name
</label>
<input
type="text"
id="sendername"
name="senderName"
required
value={formData.senderName}
onChange={handleInputChange}
className="mb-4 p-2 rounded-lg border border-gray-300"
/>
<label
htmlFor="recievername"
className="mb-2 font-semibold text-gray-600"
>
Receiver Name
</label>
<input
type="text"
id="recievername"
required
name="receiverName"
value={formData.receiverName}
onChange={handleInputChange}
className="mb-4 p-2 rounded-lg border border-gray-300"
/>
<label
htmlFor="pid"
className="mb-2 font-semibold text-gray-600"
>
Package ID
</label>
<input
type="text"
id="pid"
required
name="packageId"
value={formData.packageId}
onChange={handleInputChange}
className="mb-4 p-2 rounded-lg border border-gray-300"
/>
<label
htmlFor="dd"
className="mb-2 font-semibold text-gray-600"
>
Driver Details
</label>
<input
type="text"
id="dd"
required
name="driverDetails"
value={formData.driverDetails}
onChange={handleInputChange}
className="mb-4 p-2 rounded-lg border border-gray-300"
/>
<label
htmlFor="date"
className="mb-2 font-semibold text-gray-600"
>
Date
</label>
<input
type="date"
id="date"
required
name="date"
className="mb-4 p-2 rounded-lg border border-gray-300"
/>
<label
htmlFor="time"
className="mb-2 font-semibold text-gray-600"
>
Time
</label>
<input
type="time"
id="time"
required
name="time"
className="mb-4 p-2 rounded-lg border border-gray-300"
/>
<label
htmlFor="pd"
className="mb-2 font-semibold text-gray-600"
>
Package Description
</label>
<input
type="textarea"
id="pd"
required
name="packageDescription"
value={formData.packageDescription}
onChange={handleInputChange}
className="mb-4 p-2 rounded-lg border border-gray-300 h-24"
/>
<label
htmlFor="images"
className="mb-2 font-semibold text-gray-600"
>
Upload Image
</label>
<input
type="file"
id="images"
name="images"
className="mb-4 py-2 pl-5 file:rounded-lg rounded-lg border border-gray-300"
accept="image/*"
multiple
onChange={handleImageUpload}
required
/>
<div className="flex flex-row space-x-3 w-full">
{/* <Link
to={{
pathname: "/PackageDispatch",
state: { formData }
}}
className="w-full"
> */}
{/* <a href="/PackageDispatch">
<button
type="submit"
className="py-2 px-4 bg-gradient-to-r from-blue-500 to-blue-700 text-white rounded-lg w-52 ml-auto mt-8"
>
Generate QR
</button>
</a> */}
<div className="flex items-center justify-between z-10">
<button
className="text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full bg-gradient-to-r from-red-500 to-red-700 z-10"
type="submit"
>
<a href="/PackageDispatch">Generate QR</a>
</button>
</div>
{/* </Link> */}
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
export default AdminHome;
import {useState} from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBox, faUser, faBoxesPacking, faStreetView, faHeadset, faChainBroken, faHome } from '@fortawesome/free-solid-svg-icons'
function AdminSidepanel()
{
return(
<div className="w-[300px] side-panel p-5 flex flex-col items-center bg-[#d7002a] ">
<div className="sidepalen-body h-2/3 p-3 w-full justify-center">
<div className="user-profile flex flex-row items-center space-x-5">
<label className="text-[28px]">
<FontAwesomeIcon icon={faUser} color="white" />
</label>
<span className="user-name text-[22px] text-white">User Name</span>
</div>
<div className="nav-body w-full flex-col justify-center space-y-5 mt-10">
<ul className="space-y-5">
<Link to="/Dashboard"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faHome} className="mr-5"/>Dashboard</li></Link>
<Link to="/AdminHome"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faBox} className="mr-5"/>Home</li></Link>
{/* <Link to="/PackageDispatch"><li className="p-2 w-full bg-slate-400 rounded-md mb-5">
<FontAwesomeIcon icon={faBoxesPacking} className="mr-5"/>Package Dispatch</li></Link> */}
</ul>
</div>
</div>
</div>
);
}
export default AdminSidepanel;
\ No newline at end of file
import { useState } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import qr from './images/qr.jpg';
import inq from './images/inq.jpg';
import bg from '../../images/mainbg1.jpg';
function CustomerHome() {
const handleSubmit = (event) => {
event.preventDefault();
};
return (
<div className="main-body h-screen w-full bg-slate-100">
<img src={bg} alt="" srcset="" className="object-cover w-[100%] h-[100%] fixed" />
<div className="main-body-container h-screen w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[80%] flex flex-row p-5 mx-auto items-center justify-center space-x-5">
<a href="/ScanQR"><div className="option-card p-5 w-[420px] border-[1px] border-gray-200 text-center rounded-md bg-white shadow-md shadow-slate-300">
<div className="card-body ">
<div className="img-box">
<img src={qr} alt="" srcset="" className="object-cover w-full h-full"/>
</div>
<div className="title p-3">
<h2 className="fonr-semibold text-gray-900">Scan QR now</h2>
</div>
</div>
</div></a>
<a href="/Inquiry"><div className="option-card p-5 w-[420px] border-[1px] border-gray-200 text-center rounded-md bg-white shadow-md shadow-slate-300">
<div className="card-body ">
<div className="img-box">
<img src={inq} alt="" srcset="" className="object-cover w-full h-full"/>
</div>
<div className="title p-3">
<h2 className="fonr-semibold text-gray-900">Inquiry</h2>
</div>
</div>
</div></a>
</div>
</div>
</div>
</div>
</div>
);
}
export default CustomerHome;
import { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import axios from "axios";
function InquiryStatus() {
const handleSubmit = (event) => {
event.preventDefault();
};
const [images, setImages] = useState([]);
useEffect(() => {
axios.get("api-endpoint")
.then(response => {
setImages(response.data);
})
.catch(error => {
console.log("Error fetching image data:", error);
});
}, []);
return (
<div className="main-body h-screen w-full bg-slate-100">
<div className="main-body-container h-screen w-full flex flex-row">
<Sidepanel />
<div className="w-5/6 side-panel bg-slate-100 p-5">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[80%] flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg shadow-md shadow-slate-300">
<form onSubmit={handleSubmit} className="flex flex-col w-full">
<label
htmlFor="orderId"
className="mb-2 font-semibold text-gray-600"
>
Package Before Delivery
</label>
<div className="image-holder flex">
{images.map((image, index) => (
<img
key={index}
src={image.url}
alt={`Image ${index + 1}`}
className="image-box w-[200px] mr-[10px]"
/>
))}
</div>
<label
htmlFor="orderId"
className="mb-2 font-semibold text-gray-600"
>
Package After Delivery
</label>
<div className="image-holder flex">
{images.map((image, index) => (
<img
key={index}
src={image.url}
alt={`Image ${index + 1}`}
className="image-box w-[200px] mr-[10px]"
/>
))}
</div>
<span>Package Status</span>
<div className="w-full text-right ">
<Link to="/CustomerHome"><input
type="button"
value="Next"
className="py-2 px-4 bg-blue-500 text-white rounded-lg w-1/4 "
/></Link>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
export default InquiryStatus;
import { useEffect } from "react";
import { Link, useLocation } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import QRCode from "qrcode.react";
import bg from '../../images/mainbg1.jpg';
function PackageDispatch() {
const location = useLocation();
const searchParams = new URLSearchParams(location.search);
const senderName = searchParams.get("sender");
const receiverName = searchParams.get("receiver");
const packageId = searchParams.get("packageId");
const handleSubmit = (event) => {
event.preventDefault();
};
return (
<div className="main-body h-screen w-full bg-slate-100">
<img src={bg} alt="" srcset="" className="object-cover w-[100%] h-[100%] fixed" />
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[80%] flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg shadow-md shadow-slate-300">
<form onSubmit={handleSubmit} className="flex flex-col w-full text-center">
<div className="QR text-center justify-center items-center w-full p-5 flex flex-row">
<QRCode
value={`Sender: ${senderName}\nReceiver: ${receiverName}\nPackage ID: ${packageId}`}
size={200}
className="mx-auto"
/>
</div>
<div className="flex flex-row space-x-3 w-full">
<Link to="/AdminHome" className="w-full">
<button
type="submit"
className="py-2 px-4 bg-blue-500 text-white rounded-lg w-full"
>
Submit
</button>
</Link>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
export default PackageDispatch;
import { useState } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
function PackageStatus() {
const handleSubmit = (event) => {
event.preventDefault();
};
function handleImageUpload(event) {
const selectedFiles = event.target.files;
const fileCount = selectedFiles.length;
if (fileCount < 1 || fileCount > 5) {
// Display an error message or handle the validation error accordingly
console.log("Please select between 1 and 5 images.");
return;
}
}
return (
<div className="main-body h-screen w-full bg-slate-100">
<div className="main-body-container h-screen w-full flex flex-row">
<Sidepanel />
<div className="w-5/6 side-panel bg-slate-100 p-5">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[80%] flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg shadow-md shadow-slate-300">
<form onSubmit={handleSubmit} className="flex flex-col w-full">
<label
htmlFor="orderId"
className="mb-2 font-semibold text-gray-600"
>
Send From
</label>
<input
type="text"
id="orderId"
name="orderId"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="pickup"
className="mb-2 font-semibold text-gray-600"
>
Send to
</label>
<input
type="text"
id="pickup"
name="pickup"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="destination"
className="mb-2 font-semibold text-gray-600"
>
Package Description
</label>
<input
type="text"
id="destination"
name="destination"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="images"
className="mb-2 font-semibold text-gray-600"
>
Upload Images (1-5)
</label>
<input
type="file"
id="images"
name="images"
className="mb-4 p-2 rounded-lg border border-gray-300"
accept="image/*"
multiple
required
onChange={handleImageUpload}
/>
<div className="flex flex-row space-x-3 w-full">
<Link to="/CustomerHome" className="w-full"><button
type="submit"
className="py-2 px-4 bg-blue-500 text-white rounded-lg w-full"
>
Approve
</button></Link>
<Link to="/Inquiry" className="w-full"><button
type="submit"
className="py-2 px-4 border-[1px] border-blue-500 text-gray-900 rounded-lg w-full"
>
Send for Inquiry
</button></Link>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
export default PackageStatus;
import { useState, useRef, useEffect } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import qr from './images/qr.jpg';
import inq from './images/inq.jpg';
import bg from '../../images/mainbg1.jpg';
function ScanQR() {
const [stream, setStream] = useState(null);
const videoRef = useRef(null);
useEffect(() => {
navigator.mediaDevices.getUserMedia({ video: true })
.then((mediaStream) => {
setStream(mediaStream);
if (videoRef.current) {
videoRef.current.srcObject = mediaStream;
}
})
.catch((error) => {
console.log("Error accessing camera:", error);
});
return () => {
if (stream) {
stream.getTracks().forEach((track) => {
track.stop();
});
}
};
}, []);
return (
<div className="main-body h-screen w-full bg-slate-100">
<img src={bg} alt="" srcset="" className="object-cover w-[100%] h-[100%] fixed" />
<div className="main-body-container h-screen w-full flex flex-row">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[80%] flex flex-row p-5 mx-auto items-center justify-center space-x-5">
<div className="relative">
<video
ref={videoRef}
autoPlay
muted
className="w-full h-auto"
></video>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default ScanQR;
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import bg from "../../images/mainbg1.jpg";
import axios from "axios";
function ViewPack() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get(
"https://lime-plain-bullfrog.cyclic.app/api/getData"
);
const responseData = response.data;
setData(responseData);
setLoading(false);
} catch (error) {
console.error(error);
setLoading(false);
}
};
fetchData();
}, []);
const renderImages = (base64Data) => {
return (
<img
src={base64Data}
alt="Image"
style={{ width: "100%", height: "100px" }}
/>
);
};
return (
<div className="main-body h-screen w-full bg-slate-100">
<img
src={bg}
alt=""
srcSet=""
className="object-cover w-[100%] h-[100%] fixed"
/>
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[80%] p-5 mx-auto bg-white rounded-lg shadow-md shadow-slate-300">
<h2>Package Data Table</h2>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
}}
>
{loading ? (
<p>Loading...</p>
) : (
<table
style={{
border: "1px solid #ddd",
borderCollapse: "collapse",
}}
>
<thead>
<tr>
<th
style={{ border: "1px solid #ddd", padding: "8px" }}
>
Sender Name
</th>
<th
style={{ border: "1px solid #ddd", padding: "8px" }}
>
Sender Contact
</th>
<th
style={{ border: "1px solid #ddd", padding: "8px" }}
>
Image 1
</th>
<th
style={{ border: "1px solid #ddd", padding: "8px" }}
>
Image 2
</th>
</tr>
</thead>
<tbody>
{data.map((item) => (
<tr key={item._id}>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{item.senderName}
</td>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{item.senderContact}
</td>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{item.img1 && renderImages(item.img1)}
</td>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{item.img2 && renderImages(item.img2)}
</td>
</tr>
))}
</tbody>
</table>
)}
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default ViewPack;
import { useState } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import bg from '../../images/mainbg1.jpg';
function Inquiry() {
const handleSubmit = (event) => {
event.preventDefault();
};
function handleImageUpload(event) {
const selectedFiles = event.target.files;
const fileCount = selectedFiles.length;
if (fileCount < 1 || fileCount > 5) {
// Display an error message or handle the validation error accordingly
console.log("Please select between 1 and 5 images.");
return;
}
}
return (
<div className="main-body h-screen w-full bg-slate-100">
<img src={bg} alt="" srcset="" className="object-cover w-[100%] h-[100%] fixed" />
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center">
<div className="form-body md:w-[80%] w-full flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg">
<form onSubmit={handleSubmit} className="flex flex-col w-full">
<label
htmlFor="orderId"
className="mb-2 font-semibold text-gray-600"
>
Package No
</label>
<input
type="text"
id="orderId"
name="orderId"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="pickup"
className="mb-2 font-semibold text-gray-600"
>
Reciever
</label>
<input
type="text"
id="pickup"
name="pickup"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="destination"
className="mb-2 font-semibold text-gray-600"
>
Package Description
</label>
<input
type="text"
id="destination"
name="destination"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="images"
className="mb-2 font-semibold text-gray-600"
>
Upload Images (1-5)
</label>
<input
type="file"
id="images"
name="images"
className="mb-4 py-2 pl-5 file:rounded-lg rounded-lg border border-gray-300"
accept="image/*"
multiple
onChange={handleImageUpload}
required
/>
<button
type="submit"
className="py-2 px-4 bg-blue-500 text-white rounded-lg w-52 ml-auto mt-8"
>
Send for Inquiry
</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
export default Inquiry;
import {useState} from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBox, faHome, faUser, faBoxesPacking, faStreetView, faHeadset, faChainBroken } from '@fortawesome/free-solid-svg-icons'
function Sidepanel()
{
return(
<div className="w-[300px] side-panel p-5 flex flex-col items-center bg-[#d7002a] ">
<div className="sidepalen-body h-2/3 p-3 w-full justify-center">
<div className="user-profile flex flex-row items-center space-x-5">
<label className="text-[28px]">
<FontAwesomeIcon icon={faUser} color="white" />
</label>
<span className="user-name text-[22px] text-white">User Name</span>
</div>
<div className="nav-body w-full flex-col justify-center space-y-5 mt-10">
<ul className="space-y-5">
<Link to="/Dashboard"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faHome} className="mr-5"/>Dashboard</li></Link>
<Link to="/CustomerHome"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faBox} className="mr-5"/>Home</li></Link>
<Link to="/ScanQR"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faBoxesPacking} className="mr-5"/>Scan QR</li></Link>
<Link to="/Inquiry"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faStreetView} className="mr-5"/>Inquiry</li></Link>
</ul>
</div>
</div>
</div>
);
}
export default Sidepanel;
\ No newline at end of file
import { useState } from "react";
import Sidepanel from "../../components/sidepanel";
import bg2 from "../../images/bg2.jpg";
import axios from "axios";
function RoutePlanning() {
const [status, setStatus] = useState("");
const [pickup, setPickup] = useState("");
const [delivery, setDelivery] = useState("");
const [mapUrl, setMapUrl] = useState(
"https://maps.google.com/maps?width=100%&height=600&hl=en&q=%C4%B0zmir+(My%20Business%20Name)&ie=UTF8&t=&z=14&iwloc=B&output=embed"
);
const [isLoading, setIsLoading] = useState(false);
const cityOptions = [
{ name: "Nugegoda", coordinates: "(6.8649,79.8997)" },
{ name: "Maharagama", coordinates: "(6.8511,79.9212)" },
{ name: "Dehiwala", coordinates: "(6.8518,79.8662)" },
{ name: "Mount Lavinia", coordinates: "(6.8277,79.8630)" },
{ name: "Rajagiriya", coordinates: "(6.9271,79.9182)" },
{ name: "Battaramulla", coordinates: "(6.9102,79.9585)" },
{ name: "Pannipitiya", coordinates: "(6.8532,79.9882)" },
{ name: "Malabe", coordinates: "(6.9176,79.9701)" },
{ name: "Kottawa", coordinates: "(6.8337,80.0036)" },
{ name: "Homagama", coordinates: "(6.8416,80.0037)" },
];
const handlePickupChange = (e) => {
setPickup(e.target.value);
};
const handleDeliveryChange = (e) => {
setDelivery(e.target.value);
};
const handleSubmit = async (event) => {
setStatus("");
event.preventDefault();
try {
if (pickup === delivery) setIsLoading(true);
setMapUrl("");
const API_URL = "http://MapAPI.pythonanywhere.com/maps";
// Make FormData
var formData = new FormData();
// formData.append("pickup", "(6.9271, 79.8612)")
// formData.append("delivery", "(7.0840, 80.0098)")
// (6.8649,79.8997) Nugegoda
// (6.8511,79.9212) Maharagama
formData.append("pickup", pickup);
formData.append("delivery", delivery);
if (pickup === delivery) {
alert("Pick Up and Delivery locations cannot be the same.");
setIsLoading(false);
return;
}
await axios
.post(API_URL, formData)
.then((resp) => {
setStatus("success");
setMapUrl(API_URL + "/map-inference.html");
console.log(resp.data.status);
console.log(status);
setIsLoading(false);
})
.catch((err) => {
console.log(err);
setStatus("failed");
});
} catch (error) {
console.error(error);
setStatus("failed");
}
};
function alertComponent() {
if (status == "success") {
return (
<>
<div
class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative"
role="alert"
>
<span class="block sm:inline">Success !</span>
</div>
</>
);
} else if (status == "failed") {
return (
<>
<div
class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
role="alert"
>
<span class="block sm:inline">Failed !</span>
</div>
</>
);
}
}
return (
<div className="main-body h-screen w-full bg-slate-100">
<img
src={bg2}
alt=""
srcset=""
className="object-cover w-[100%] h-[100%]"
/>
<div className="main-body-container h-screen w-full flex flex-row absolute top-0 bg-black bg-opacity-50">
<Sidepanel />
<div className="w-5/6 side-panel p-5 sm:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[90%] flex md:flex-row flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg shadow-md shadow-slate-300">
<div className="map sm:w-[60%] w-full text-center p-2 h-full">
<h1 className="flex items-center justify-center pt-4 text-xl uppercase font-bold pb-4">
Route Map
</h1>
{/* <span>G-MAP will appear here</span> */}
<div className="p-2 h-[200px] sm:h-[400px] bg-slate-400 mr-8">
<iframe
width="100%"
height="100%"
frameborder="0"
marginheight="0"
marginwidth="0"
title="map"
scrolling="no"
src={mapUrl}
></iframe>
</div>
</div>
<div className="order-details flex flex-col space-y-[20px] ">
{alertComponent()}
<form onSubmit={handleSubmit} className="flex flex-col w-full ">
<label
htmlFor="pickUp"
className="mb-2 font-semibold text-gray-600"
>
Pick Up
</label>
<select
id="pickUp"
name="pickUp"
className="mb-4 p-2 rounded-lg border border-gray-300"
onChange={handlePickupChange}
value={pickup}
required
>
<option value="">Select Pick Up Location</option>
{cityOptions.map((city, index) => (
<option key={index} value={city.coordinates}>
{city.name}
</option>
))}
</select>
<label
htmlFor="delivery"
className="mb-2 font-semibold text-gray-600"
>
Delivery
</label>
<select
id="delivery"
name="delivery"
className="mb-4 p-2 rounded-lg border border-gray-300"
onChange={handleDeliveryChange}
value={delivery}
required
>
<option value="">Select Delivery Location</option>
{cityOptions.map((city, index) => (
<option key={index} value={city.coordinates}>
{city.name}
</option>
))}
</select>
{isLoading ? (
<div className="loader">Loading...</div>
) : (
<button
type="submit"
className="py-2 px-4 bg-gradient-to-r from-red-500 to-red-700 text-white rounded-lg w-52 ml-auto mt-8 ml-4"
onClick={handleSubmit}
>
Route
</button>
)}
{/* <span>Order Id : #TJH097</span>
<span>Pick Up</span>
<span>Two more Steps</span>
<span>Delivery</span> */}
</form>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default RoutePlanning;
import React, { useState, useEffect } from "react";
import { Link, useNavigate } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import { post } from "../../Api";
import bg from "../../images/mainbg1.jpg";
import { BaseUrl } from "../../utils/base_url";
function CreateDelivery() {
const navigate = useNavigate();
const [customerIds, setCustomerIds] = useState([]);
const [packageIds, setPackageIds] = useState([]);
useEffect(() => {
fetch(`${BaseUrl}/order/customers`)
.then((response) => response.json())
.then((data) => setCustomerIds(data.data))
.catch((error) => console.error(error));
fetch(`${BaseUrl}/order/pakages`)
.then((response) => response.json())
.then((data) => setPackageIds(data.data))
.catch((error) => console.error(error));
}, []);
const handleSubmit = async (event) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
var postData = {
customerId: data.get("customerId"),
packageId: data.get("packageId"),
orderId: data.get("orderId"),
branch_pickup: data.get("pickup"),
vehicle: data.get("vehicle"),
date: data.get("date"),
destination: data.get("destination"),
status: "Processing",
estimated_date: data.get("date"),
telephone_number: data.get("tp"),
departure_date: data.get("departureDate"),
};
try {
const isValidPhoneNumber = /^\d{10}$/.test(postData.telephone_number);
if (!isValidPhoneNumber) {
alert(
"Invalid phone number. Please enter a valid 10-digit telephone number."
);
return;
}
const response = await fetch(`${BaseUrl}/order`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(postData),
});
if (response.ok) {
console.log("Order created successfully");
alert("Order created successfully");
navigate("/Orders");
} else {
alert(
"Error creating order, Check customer id and order id if already exists"
);
console.error("Error creating order");
}
} catch (error) {
console.error(error);
}
};
return (
<div className="main-body h-screen w-full bg-slate-100">
<img
src={bg}
alt=""
srcset=""
className="object-cover w-[100%] h-[100%] fixed"
/>
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center ">
<div className="form-body md:w-[80%] w-full flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg ">
<h1 className="flex items-center justify-center pt-4 text-xl uppercase font-bold pb-4">
Create Delivery
</h1>
<form onSubmit={handleSubmit} className="flex flex-col w-full">
<label htmlFor="customerId">Customer ID</label>
<select id="customerId" name="customerId">
{Array.isArray(customerIds) ? (
customerIds.map((customer) => (
<option key={customer.id} value={customer.id}>
{customer.id}
</option>
))
) : (
<option value="">Loading...</option>
)}
</select>
<label htmlFor="packageId">Package ID</label>
<select id="packageId" name="packageId">
{Array.isArray(packageIds) ? (
packageIds.map((data) => (
<option key={data.id} value={data.id}>
{data.id}
</option>
))
) : (
<option value="">Loading...</option>
)}
</select>
<label
htmlFor="orderId"
className="mb-2 font-semibold text-gray-600"
>
Order ID
</label>
<input
type="text"
id="orderId"
name="orderId"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="pickup"
className="mb-2 font-semibold text-gray-600"
>
Pickup
</label>
<input
type="text"
id="pickup"
name="pickup"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="destination"
className="mb-2 font-semibold text-gray-600"
>
Destination
</label>
<input
type="text"
id="destination"
name="destination"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="date"
className="mb-2 font-semibold text-gray-600"
>
Estimated Date
</label>
<input
type="date"
id="date"
name="date"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="departureDate"
className="mb-2 font-semibold text-gray-600"
>
Departure Date
</label>
<input
type="date"
id="departureDate"
name="departureDate"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
/>
<label
htmlFor="tp"
className="mb-2 font-semibold text-gray-600"
>
Telephone number
</label>
<input
type="text"
id="tp"
name="tp"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
pattern="[0-9]+"
title="Please enter a valid 10-digit telephone number"
/>
<label
htmlFor="vehicle"
className="mb-2 font-semibold text-gray-600"
>
Vehicle
</label>
<select
id="vehicle"
name="vehicle"
className="mb-4 p-2 rounded-lg border border-gray-300"
>
<option value="Please Select">Please Select</option>
<option value="car">Car</option>
<option value="bike">Bike</option>
<option value="truck">Truck</option>
</select>
<button
type="submit"
className="py-2 px-4 bg-gradient-to-r from-blue-500 to-blue-700 text-white rounded-lg w-52 ml-auto mt-8"
>
Create Delivery
</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
export default CreateDelivery;
import { Link } from "react-router-dom";
import Sidepanel from "../../components/sidepanel";
import bg from '../../images/mainbg1.jpg';
import { MessageDialog } from "../../components/MessageDialog";
import { useState, useEffect } from 'react';
export default function Tickets() {
const [popUpStatus, setpopUpStatus] = useState(false);
const popUp = () => {
setpopUpStatus(!popUpStatus)
console.log(popUpStatus)
}
return (
<div className="main-body h-screen w-full bg-slate-100">
<img src={bg} alt="" srcset="" className="object-cover w-[100%] h-[100%] fixed" />
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full bg-white rounded-lg">
<h2 className="flex items-center justify-center pt-4 text-xl uppercase font-bold pb-4 mt-4 mb-4">Customer Charn</h2>
<form>
<label for="default-search" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
</svg>
</div>
<input type="search" id="default-search" class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Search Orders....." required/>
<button type="submit" class="text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Search</button>
</div>
</form>
<br/>
<div class="flex flex-col">
<div class="overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="inline-block min-w-full py-2 sm:px-6 lg:px-8">
<div class="overflow-hidden">
<table class="min-w-full text-left text-sm font-light">
<thead class="border-b font-medium dark:border-neutral-500">
<tr>
<th scope="col" class="px-6 py-4">#ID</th>
<th scope="col" class="px-6 py-4">Sender Name</th>
<th scope="col" class="px-6 py-4">Sender Address</th>
<th scope="col" class="px-6 py-4">Province</th>
<th scope="col" class="px-6 py-4">Last Item</th>
<th scope="col" class="px-6 py-4">Feedback</th>
<th scope="col" class="px-6 py-4">Charn Status</th>
<th scope="col" class="px-6 py-4">Action</th>
</tr>
</thead>
<tbody>
<tr
class="border-b transition duration-300 ease-in-out hover:bg-neutral-100 dark:border-neutral-500 dark:hover:bg-neutral-600">
<td class="whitespace-nowrap px-6 py-4 font-medium">1</td>
<td class="whitespace-nowrap px-6 py-4">John Doe</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">
<button onClick={popUp} class="group relative h-8 w-24 overflow-hidden rounded-2xl bg-blue-500 text-sm font-bold text-white mr-4">
View
<div class="absolute inset-0 h-full w-full scale-0 rounded-2xl transition-all duration-300 group-hover:scale-100 group-hover:bg-white/30"></div>
</button>
</td>
</tr>
{popUpStatus &&
<div>
<MessageDialog click={true} link={`/CustomerCharnTable`}/>
</div>
}
<tr
class="border-b transition duration-300 ease-in-out hover:bg-neutral-100 dark:border-neutral-500 dark:hover:bg-neutral-600">
<td class="whitespace-nowrap px-6 py-4 font-medium">2</td>
<td class="whitespace-nowrap px-6 py-4"> Test</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">Test</td>
<td class="whitespace-nowrap px-6 py-4">
{/* <Link to={""}> */}
<button onClick={popUp} class="group relative h-8 w-24 overflow-hidden rounded-2xl bg-blue-500 text-sm font-bold text-white mr-4">
View
<div class="absolute inset-0 h-full w-full scale-0 rounded-2xl transition-all duration-300 group-hover:scale-100 group-hover:bg-white/30"></div>
</button>
{/* </Link> */}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import Sidepanel from "../../components/sidepanel";
import bg from "../../images/mainbg1.jpg";
import { BaseUrl } from "../../utils/base_url";
import axios from "axios";
export default function Orders() {
const [rows, setRows] = useState([]);
const [search, setSearch] = useState("");
const getData = async () => {
try {
const response = await axios.get(`${BaseUrl}/order`);
if (Array.isArray(response.data.data)) {
setRows(response.data.data);
} else {
setRows([]);
}
} catch (error) {
console.error(error);
}
};
const getDataById = async (e, id) => {
e.preventDefault();
if (id) {
const res = await axios.get(`${BaseUrl}/order/${id}`);
console.log(res.data);
if (Array.isArray(res.data.data)) {
setRows(res.data.data);
} else {
setRows([]);
}
}
};
const deleteData = async (e, id) => {
e.preventDefault();
await axios.delete(`${BaseUrl}/order/${id}`);
alert("Data deleted");
getData();
};
useEffect(() => {
if (!search) {
getData();
setSearch("");
}
}, [search]);
return (
<div className="main-body h-screen w-full bg-slate-100">
<img
src={bg}
alt=""
srcset=""
className="object-cover w-[100%] h-[100%] fixed"
/>
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full bg-white rounded-lg">
<h2 className="flex items-center justify-center pt-4 text-xl uppercase font-bold pb-4 mt-4 mb-4">
Orders
</h2>
<form>
<label
for="default-search"
class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white"
>
Search
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg
class="w-4 h-4 text-gray-500 dark:text-gray-400"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 20 20"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"
/>
</svg>
</div>
<input
type="search"
id="default-search"
class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="Search Orders....."
onChange={(e) => setSearch(e.target.value)}
required
/>
<button
type="submit"
class="text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
onClick={(e) => getDataById(e, search)}
>
Search
</button>
</div>
</form>
<br />
<div className="overflow-x-auto">
<table className="text-left text-sm font-light">
<thead className="border-b font-medium dark:border-neutral-500">
<tr>
<th scope="col" className="px-6 py-4">
#SearchID
</th>
<th scope="col" className="px-6 py-4">
Order ID
</th>
<th scope="col" className="px-6 py-4">
Destination
</th>
<th scope="col" className="px-6 py-4">
Vehicle
</th>
<th scope="col" className="px-6 py-4">
Status
</th>
<th scope="col" className="px-6 py-4">
Departure Date
</th>
<th scope="col" className="px-6 py-4">
Estimate Date
</th>
<th scope="col" className="px-6 py-4">
Action
</th>
</tr>
</thead>
<tbody>
{rows.map((row, i) => (
<tr className="border-b transition duration-300 ease-in-out hover:bg-neutral-100 dark:border-neutral-500 dark:hover:bg-neutral-600">
<td className="Destination p-2">#{row?.id}</td>
<td className="Destination p-2">#{row?.order_id}</td>
<td className="Order-ID p-2">{row?.destination}</td>
<td className="Vehicle p-2">{row?.vehicle}</td>
<td className="Status p-2 text-red-600">{row?.status}</td>
<td className="Departure-Date p-2">
{row?.departure_date}
</td>
<td className="Estimated-Date p-2">
{row?.estimated_date}
</td>
<td className="Estimated-Date p-2">
<div className="flex flex-row justify-center space-x-5">
<Link to={`/UpdateDelivery/${row?.id}`}>
<button className="group relative h-8 w-24 overflow-hidden rounded-2xl bg-purple-900 text-sm font-bold text-white mr-4">
UPDATE
</button>
</Link>
<button
onClick={(e) => deleteData(e, row?.id)}
className="group relative h-8 w-24 overflow-hidden rounded-2xl bg-red-500 text-sm font-bold text-white mr-4"
>
REMOVE
</button>
<Link to={`/ViewDelivery/${row?.id}`}>
<button className="group relative h-8 w-24 overflow-hidden rounded-2xl bg-blue-500 text-sm font-bold text-white mr-4">
INFO
</button>
</Link>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
);
}
import React from 'react';
const Modal = () => {
return (
<>
<button
data-modal-target="popup-modal"
data-modal-toggle="popup-modal"
className="block text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
type="button"
>
Toggle modal
</button>
<div
id="popup-modal"
tabIndex="-1"
className="fixed top-0 left-0 right-0 z-50 hidden p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] max-h-full"
>
<div className="relative w-full max-w-md max-h-full">
<div className="relative bg-white rounded-lg shadow dark:bg-gray-700">
<button
type="button"
className="absolute top-3 right-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ml-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
data-modal-hide="popup-modal"
>
<svg
className="w-3 h-3"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 14 14"
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"
/>
</svg>
<span className="sr-only">Close modal</span>
</button>
<div className="p-6 text-center">
<svg
className="w-12 h-12 mx-auto mb-4 text-gray-400 dark:text-gray-200"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 20 20"
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
/>
</svg>
<h3 className="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">
Are you sure you want to delete this product?
</h3>
<button
data-modal-hide="popup-modal"
type="button"
className="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center mr-2"
>
Yes, I'm sure
</button>
<button
data-modal-hide="popup-modal"
type="button"
className="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600"
>
No, cancel
</button>
</div>
</div>
</div>
</div>
</>
);
};
export default Modal;
import {useState} from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBox, faHome, faUser, faBoxesPacking, faStreetView, faHeadset, faChainBroken } from '@fortawesome/free-solid-svg-icons'
function Sidepanel()
{
return(
<div className="sm:w-[300px] w-[80px] side-panel sm:p-5 p-2 flex flex-col items-center bg-[#d7002a] fixed h-screen z-10">
<div className="sidepalen-body h-2/3 p-3 w-full justify-center">
<div className="user-profile sm:flex flex-row items-center space-x-5 hidden">
<label className="text-[28px]">
<FontAwesomeIcon icon={faUser} color="white" />
</label>
<span className="user-name text-[22px] text-white">User Name</span>
</div>
<div className="nav-body w-full flex-col justify-center space-y-5 mt-10">
<ul className="space-y-5">
<Link to="/Dashboard"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faHome} className="mr-5"/><span className="sm:inline-flex hidden">Dashboard</span></li></Link>
<Link to="/CreateDelivery"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faBox} className="mr-5"/><span className="sm:inline-flex hidden">Create Delivery</span></li></Link>
<Link to="/Orders"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faBoxesPacking} className="mr-5"/><span className="sm:inline-flex hidden">Orders</span></li></Link>
<Link to="/RoutePlanning"><li className="p-2 w-full bg-white rounded-md mb-5">
<FontAwesomeIcon icon={faStreetView} className="mr-5"/><span className="sm:inline-flex hidden">Route Planning</span></li></Link>
</ul>
</div>
</div>
</div>
);
}
export default Sidepanel;
\ No newline at end of file
import { useState } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBox, faUser, faHome, faBoxesPacking, faStreetView, faHeadset, faChainBroken } from '@fortawesome/free-solid-svg-icons'
function Sidepanel1() {
return (
<div className="w-[300px] side-panel p-5 flex flex-col items-center bg-[conic-gradient(at_bottom_left,_var(--tw-gradient-stops))] bg-[#d7002a]">
<div className="justify-center w-full p-3 sidepalen-body h-2/3">
<div className="flex flex-row items-center space-x-5 user-profile">
<label className="text-[28px]">
<FontAwesomeIcon icon={faUser} color="white" />
</label>
<span className="user-name text-[22px] text-white">User Name</span>
</div>
<div className="flex-col justify-center w-full mt-10 space-y-5 nav-body">
<ul className="space-y-5">
<Link to="/Dashboard"><li className="w-full p-2 mb-5 rounded-md bg-slate-400">
<FontAwesomeIcon icon={faHome} className="mr-5" />Dashboard</li></Link>
<Link to="/CreateDelivery"><li className="w-full p-2 mb-5 rounded-md bg-slate-400">
<FontAwesomeIcon icon={faBox} className="mr-5" />Create Delivery</li></Link>
<Link to="/Orders"><li className="w-full p-2 mb-5 rounded-md bg-slate-400">
<FontAwesomeIcon icon={faBoxesPacking} className="mr-5" />Orders</li></Link>
<Link to="/RoutePlanning"><li className="w-full p-2 mb-5 rounded-md bg-slate-400">
<FontAwesomeIcon icon={faStreetView} className="mr-5" />Route Planning</li></Link>
</ul>
</div>
</div>
</div>
);
}
export default Sidepanel1;
\ No newline at end of file
import { useState } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBox, faUser, faBoxesPacking, faStreetView, faHome, faHeadset, faChainBroken, faTable } from '@fortawesome/free-solid-svg-icons'
function Sidepanel2() {
return (
<div className="w-[300px] side-panel p-5 flex flex-col items-center bg-[conic-gradient(at_bottom_left,_var(--tw-gradient-stops))] bg-[#d7002a]">
<div className="justify-center w-full p-5 sidepalen-body h-2/3">
<div className="flex flex-row items-center space-x-5 user-profile">
<label className="text-[28px]">
<FontAwesomeIcon icon={faUser} color="white" />
</label>
<span className="user-name text-[22px] text-white">User Name</span>
</div>
<div className="flex-col justify-center w-full mt-10 space-y-5 nav-body">
<ul className="space-y-5">
<Link to="/Dashboard"><li className="w-full p-2 mb-5 rounded-md bg-white">
<FontAwesomeIcon icon={faHome} className="mr-5" />Dashboard</li></Link>
<Link to="/PerformanceTrack"><li className="w-full p-2 mb-5 rounded-md bg-white">
<FontAwesomeIcon icon={faTable} className="mr-5" />Performance Track</li></Link>
<Link to="/CreateOrder"><li className="w-full p-2 mb-5 rounded-md bg-white">
<FontAwesomeIcon icon={faBox} className="mr-5" />Create Order</li></Link>
<Link to="/CustomerChurn"><li className="w-full p-2 mb-5 rounded-md bg-white">
<FontAwesomeIcon icon={faBoxesPacking} className="mr-5" />Customer Charn</li></Link>
<Link to="/ChurnRank"><li className="w-full p-2 mb-5 rounded-md bg-white">
<FontAwesomeIcon icon={faBoxesPacking} className="mr-5" />Churn Rank</li></Link>
<Link to="/DeliveryRank"><li className="w-full p-2 mb-5 rounded-md bg-white">
<FontAwesomeIcon icon={faStreetView} className="mr-5" />Delivery Success Rank</li></Link>
</ul>
</div>
</div>
</div>
);
}
export default Sidepanel2;
\ No newline at end of file
import {useEffect, useState} from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPlus, faStarHalfStroke } from '@fortawesome/free-solid-svg-icons'
import Sidepanel from "../../components/sidepanel";
import {
BrowserRouter as Router,
Route,
useParams
} from "react-router-dom";
import { post } from "../../Api";
function SingleOrder()
{
const [data, setData] = useState(
{
branch_pickup: "",
customer_id: 1,
date: "",
departure_date: "",
destination: "",
estimated_date: "",
id: 1,
order_id: "",
package_id: null,
status: "",
telephone_number: "",
vehicle: ""
}
)
const { id } = useParams();
const getData = async () =>{
try {
const response = await post('/api/order/info', {id:id}, {});
if(response){
console.log(response)
setData(response.data)
}
} catch (error) {
console.error(error);
}
}
useEffect(() => {
getData();
}, []);
return(
<div className="main-body h-screen w-full bg-slate-100">
<div className="main-body-container h-screen w-full flex flex-row">
<Sidepanel/>
<div className="w-5/6 side-panel bg-slate-100 p-5">
<div className="common-body p-5 flex flex-col h-full items-center justify-center">
<div className="form-body w-[60%] flex flex-col p-5 mx-auto justify-left bg-white rounded-lg shadow-md shadow-slate-300">
<div className="order-details flex flex-col space-y-[20px]">
<span>Customer Id : #{data.customer_id}</span>
<span>Order Id : #{data.order_id}</span>
<span>Pick Up : {data.branch_pickup}</span>
<span>Destination : {data.destination}</span>
<span>Date : {data.date}</span>
<span>Contact : {data.telephone_number}</span>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default SingleOrder;
\ No newline at end of file
// import {useState,useEffect} from "react";
// import { Link } from "react-router-dom";
// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
// import { faPlus, faStarHalfStroke } from '@fortawesome/free-solid-svg-icons'
// import Sidepanel from "../../components/sidepanel";
// import bg from '../../images/mainbg1.jpg';
// import {
// BrowserRouter as Router,
// Route,
// useParams
// } from "react-router-dom";
// import { post } from "../../Api";
// function SingleOrderUpdate()
// {
// const [branchpickup, setbranchpickup] = useState();
// const [vehicle, setvehicle] = useState();
// const [date, setdate] = useState();
// const [destination, setdestination] = useState();
// const [orderid, setorderid] = useState();
// const [status, setstatus] = useState();
// const [customerid, setcustomerid] = useState();
// const [estimateddate, setestimateddate] = useState();
// const [telephonenumber, settelephonenumber] = useState();
// const [departuredate, setdeparturedate] = useState();
// const { id } = useParams();
// const getData = async () =>{
// try {
// const response = await post('/api/order/info', {id:id}, {});
// if(response){
// console.log(response)
// setbranchpickup(response.data.branch_pickup)
// setvehicle(response.data.vehicle)
// setdestination(response.data.destination)
// setdate(response.data.date)
// setorderid(response.data.order_id)
// setstatus(response.data.branch_pickup)
// setcustomerid(response.data.customer_id)
// setestimateddate(response.data.estimated_date)
// settelephonenumber(response.data.telephone_number)
// setdeparturedate(response.data.departure_date)
// }
// } catch (error) {
// console.error(error);
// }
// }
// useEffect(() => {
// getData();
// }, []);
// const handleSubmit = (event) => {
// event.preventDefault();
// };
// const handleUpdate = async (event) => {
// var postData = {
// id:id,
// branch_pickup:branchpickup,
// vehicle: vehicle,
// date: date,
// destination: destination,
// order_id: orderid,
// status: status,
// estimated_date: estimateddate,
// customer_id: customerid,
// telephone_number: telephonenumber,
// departure_date: departuredate,
// };
// console.log(postData)
// try {
// const response = await post('/api/order/update', postData, {});
// if(response){
// console.log(response)
// }
// } catch (error) {
// console.error(error);
// }
// };
// return(
// <div className="main-body h-screen w-full bg-slate-100">
// <img src={bg} alt="" srcset="" className="object-cover w-[100%] h-[100%] fixed" />
// <div className="main-body-container w-full flex flex-row absolute">
// <Sidepanel/>
// <div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
// <div className="common-body p-5 flex flex-col h-full items-center ">
// <div className="form-body w-[60%] flex flex-col p-5 mx-auto justify-left bg-white rounded-lg shadow-md shadow-slate-300">
// <div className="order-details flex flex-col space-y-[20px]">
// <form onSubmit={handleSubmit} className="flex flex-col w-full">
// <label htmlFor="customerId" className="mb-2 font-semibold text-gray-600">
// Customer ID
// </label>
// <input value={customerid} onChange={(e)=>setcustomerid(e.target.value)} type="text" id="customerId" name="customerId" className="mb-4 p-2 rounded-lg border border-gray-300" required/>
// <label htmlFor="orderId" className="mb-2 font-semibold text-gray-600">
// Order ID
// </label>
// <input value={orderid} onChange={(e)=>setorderid(e.target.value)} type="text" id="orderId" name="orderId" className="mb-4 p-2 rounded-lg border border-gray-300" required/>
// <label htmlFor="pickup" className="mb-2 font-semibold text-gray-600">
// Pickup
// </label>
// <input value={branchpickup} onChange={(e)=>setbranchpickup(e.target.value)} type="text" id="pickup" name="pickup" className="mb-4 p-2 rounded-lg border border-gray-300" required/>
// <label htmlFor="destination" className="mb-2 font-semibold text-gray-600">
// Destination
// </label>
// <input value={destination} onChange={(e)=>setdestination(e.target.value)} type="text" id="destination" name="destination" className="mb-4 p-2 rounded-lg border border-gray-300" required/>
// <label htmlFor="date" className="mb-2 font-semibold text-gray-600">
// Date
// </label>
// <input value={date} onChange={(e)=>setdate(e.target.value)} type="date" id="date" name="date" className="mb-4 p-2 rounded-lg border border-gray-300" required/>
// <label htmlFor="vehicle" className="mb-2 font-semibold text-gray-600">
// Vehicle
// </label>
// <select value={vehicle} onChange={(e)=>setvehicle(e.target.value)} id="vehicle" name="vehicle" className="mb-4 p-2 rounded-lg border border-gray-300">
// <option value="car">Car</option>
// <option value="bike">Bike</option>
// <option value="truck">Truck</option>
// </select>
// <label htmlFor="status" className="mb-2 font-semibold text-gray-600">
// Status
// </label>
// <select value={status} onChange={(e)=>setstatus(e.target.value)} id="status" name="status" className="mb-4 p-2 rounded-lg border border-gray-300">
// <option value="Processing">Processing</option>
// <option value="Delivered">Delivered</option>
// </select>
// <button onClick={handleUpdate} className="py-2 px-4 bg-gradient-to-r from-red-500 to-red-700 text-white rounded-lg w-52 ml-auto mt-8">
// Update
// </button>
// </form>
// </div>
// </div>
// </div>
// </div>
// </div>
// </div>
// );
// }
// export default SingleOrderUpdate;
\ No newline at end of file
This diff is collapsed.
import { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import { post } from "../../Api";
import axios from "axios";
import bg from "../../images/mainbg1.jpg";
import { BaseUrl } from "../../utils/base_url";
import { BrowserRouter as Router, Route, useParams } from "react-router-dom";
function ViewDelivery() {
const navigate = useNavigate();
const { id } = useParams();
const [data, setData] = useState({});
const getData = async (data, i) => {
try {
const res = await axios.get(`${BaseUrl}/order/${id}`);
console.log(res);
if (Array.isArray(res.data.data)) {
setData(res.data.data[0]);
console.log(data);
} else {
setData([]);
}
} catch (error) {
console.error(error);
}
};
useEffect(() => {
getData();
}, [id]);
const handleBackClick = () => {
navigate("/orders");
};
useEffect(() => {
getData();
}, []);
return (
<div className="main-body h-screen w-full bg-slate-100">
<img
src={bg}
alt=""
srcset=""
className="object-cover w-[100%] h-[100%] fixed"
/>
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="common-body p-5 flex flex-col h-full items-center ">
<div className="form-body md:w-[80%] w-full flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg ">
<h1 className="flex items-center justify-center pt-4 text-xl uppercase font-bold pb-4">
View Delivery
</h1>
<form className="flex flex-col w-full">
<label
htmlFor="customerId"
className="mb-2 font-semibold text-gray-600"
>
Customer ID
</label>
<input
value={data.customer_id}
type="text"
id="customerId"
name="customerId"
className="mb-4 p-2 rounded-lg border border-gray-300"
disabled
/>
<label
htmlFor="customerId"
className="mb-2 font-semibold text-gray-600"
>
package ID
</label>
<input
value={data?.package_id}
type="text"
id="customerId"
name="customerId"
className="mb-4 p-2 rounded-lg border border-gray-300"
required
readOnly
/>
<label
htmlFor="orderId"
className="mb-2 font-semibold text-gray-600"
>
Order ID
</label>
<input
value={data.order_id}
type="text"
id="orderId"
name="orderId"
className="mb-4 p-2 rounded-lg border border-gray-300"
disabled
/>
<label
htmlFor="pickup"
className="mb-2 font-semibold text-gray-600"
>
Pickup
</label>
<input
value={data.branch_pickup}
type="text"
id="pickup"
name="pickup"
className="mb-4 p-2 rounded-lg border border-gray-300"
disabled
/>
<label
htmlFor="destination"
className="mb-2 font-semibold text-gray-600"
>
Destination
</label>
<input
value={data.destination}
type="text"
id="destination"
name="destination"
className="mb-4 p-2 rounded-lg border border-gray-300"
disabled
/>
<label
htmlFor="date"
className="mb-2 font-semibold text-gray-600"
>
Estimated Date
</label>
<input
value={data.estimated_date}
type="date"
id="date"
name="date"
className="mb-4 p-2 rounded-lg border border-gray-300"
disabled
/>
<label
htmlFor="departureDate"
className="mb-2 font-semibold text-gray-600"
>
Departure Date
</label>
<input
value={data.departure_date}
type="date"
id="departureDate"
name="departureDate"
className="mb-4 p-2 rounded-lg border border-gray-300"
disabled
/>
<label
htmlFor="tp"
className="mb-2 font-semibold text-gray-600"
>
Telephone number
</label>
<input
value={data.telephone_number}
type="text"
id="tp"
name="tp"
className="mb-4 p-2 rounded-lg border border-gray-300"
disabled
/>
<label
htmlFor="vehicle"
className="mb-2 font-semibold text-gray-600"
>
Vehicle
</label>
<input
value={data.vehicle}
type="text"
id="vehicle"
name="vehicle"
className="mb-4 p-2 rounded-lg border border-gray-300"
disabled
/>
<button
onClick={handleBackClick}
className="py-2 px-4 bg-gradient-to-r from-blue-500 to-blue-700 text-white rounded-lg w-52 ml-auto mt-8"
>
Back
</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
export default ViewDelivery;
import { useState } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus, faStarHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Sidepanel from "../../components/sidepanel";
import BarChart from "../../components/Chart2";
import bg from "../../images/mainbg1.jpg";
function ChurnRank() {
const handleSubmit = (event) => {
event.preventDefault();
};
const [m, setM] = useState(null);
const [month, setMonth] = useState(null);
return (
<div className="main-body h-screen w-full bg-slate-100">
<img
src={bg}
alt=""
srcset=""
className="object-cover w-[100%] h-[100%] fixed"
/>
<div className="main-body-container w-full flex flex-row absolute">
<Sidepanel />
<div className="w-5/6 side-panel p-5 md:ml-[300px] ml-16">
<div className="flex flex-col items-center justify-center h-full p-5 common-body">
<div className="form-body w-[1000px] flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg shadow-md shadow-slate-300">
<form onSubmit={handleSubmit} className="flex flex-col w-full">
<h1 className="flex items-center justify-center pt-4 text-xl uppercase font-bold pb-4">
Churn Rank
</h1>
<label
htmlFor="province"
className="mb-2 font-semibold text-gray-600"
>
Province
</label>
<select
id="province"
name="province"
className="p-2 mb-4 border border-gray-300 rounded-lg"
>
<option value="Central">Central</option>
<option value="Eastern">Eastern</option>
<option value="North Central">North Central</option>
<option value="Northern">Northern</option>
<option value="Northe Westrn">Northe Westrn</option>
<option value="Sabaragamuwa">Sabaragamuwa</option>
<option value="Southern">Southern</option>
<option value="Uva">Uva</option>
<option value="Western">Western</option>
</select>
<label
htmlFor="customertype"
className="mb-2 font-semibold text-gray-600"
>
Customer type
</label>
<select
id="customertype"
name="customertype"
className="p-2 mb-4 border border-gray-300 rounded-lg"
>
<option value="Normal">Normal</option>
<option value="Business">Business</option>
</select>
<label
htmlFor="year"
className="mb-2 font-semibold text-gray-600"
>
Year
</label>
<input
type="text"
id="year"
name="year"
className="p-2 mb-4 border border-gray-300 rounded-lg"
/>
<label
htmlFor="province"
className="mb-2 font-semibold text-gray-600"
>
Month
</label>
<select
id="month"
name="month"
className="p-2 mb-4 border border-gray-300 rounded-lg"
onChange={(e) => setM(e.target.value)}
>
<option value="Jan">January</option>
<option value="Feb">February</option>
<option value="Mar">March</option>
<option value="Apr">April</option>
<option value="May">May</option>
<option value="Jun">June</option>
<option value="Jul">July</option>
<option value="Aug">August</option>
<option value="Sep">September</option>
<option value="Oct">October</option>
<option value="Nov">November</option>
<option value="Dec">December</option>
</select>
<div className="flex items-end justify-end ">
<button
type="button"
onClick={(e) => {
e.preventDefault();
setMonth(m);
}}
className="px-4 py-2 text-white bg-blue-500 rounded-lg hover:bg-blue-400 mt-8"
>
Search
</button>
</div>
</form>
</div>
<div className="pt-10">
<div className="form-body w-[1000px] flex flex-col p-5 mx-auto items-center justify-center bg-white rounded-lg shadow-md shadow-slate-300">
<h1 className="flex items-center justify-center pt-4 text-xl uppercase font-bold pb-4">
{" "}
Graph
</h1>
<BarChart key={1000} month={month} />
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default ChurnRank;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
export const BaseUrl = "https://jade-comfortable-kangaroo.cyclic.cloud";
// export const BaseUrl = "http://localhost:3001";
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {
width: {
'70': '32rem',
}
},
},
plugins: [
require('flowbite/plugin')
],
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment