diff --git a/apps/edr-freight-web/backoffice/src/App.tsx b/apps/edr-freight-web/backoffice/src/App.tsx index 6d28d8ac9..26a743b67 100644 --- a/apps/edr-freight-web/backoffice/src/App.tsx +++ b/apps/edr-freight-web/backoffice/src/App.tsx @@ -1,12 +1,13 @@ import { Navigate, Outlet, Route, Routes, useLocation, useNavigate } from "react-router-dom"; import { DashboardLayout, type SidebarItem } from "@edr/ui-common"; -import { LayoutDashboard, Network } from "lucide-react"; +import { LayoutDashboard, Network, Settings } from "lucide-react"; import { useAuth } from "./auth/useAuth"; import LoginPage from "./pages/auth/LoginPage"; import OverviewPage from "./pages/dashboard/OverviewPage"; import UserManagementPage from "./pages/dashboard/user-management/UserManagementPage"; import LoadingScreen from "./components/LoadingScreen"; +import { RuleEnginePage } from "./pages/ruleEngine/RuleEngine"; const sidebarItems: SidebarItem[] = [ { @@ -19,6 +20,11 @@ const sidebarItems: SidebarItem[] = [ href: "/dashboard/user-management", icon: , }, + { + label: "Rule Engine", + href: "/dashboard/rule-engine", + icon: , + }, ]; const DashboardShell = () => { @@ -67,6 +73,7 @@ const App = () => { }> } /> } /> + } /> } /> } /> diff --git a/apps/edr-freight-web/backoffice/src/components/ruleEngine/ContractType.tsx b/apps/edr-freight-web/backoffice/src/components/ruleEngine/ContractType.tsx new file mode 100644 index 000000000..dff4d0c7c --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/components/ruleEngine/ContractType.tsx @@ -0,0 +1,221 @@ +import { JSXElementConstructor, MouseEventHandler, ReactElement, ReactNode, SetStateAction, useState } from 'react'; + +export const ContractTypePage = () => { + const [expandedSections, setExpandedSections] = useState({ + contractType: true, + serviceType: false, + cargoType: false + }); + + const [contractTypes, setContractTypes] = useState([ + { id: 1, name: 'Shipper', description: 'Company that sends the freight' }, + { id: 2, name: 'Consignee', description: 'Company that receives the freight' }, + { id: 3, name: 'Third Party', description: 'Company that is neither the shipper nor the consignee but is involved in the freight process' } + ]); + + const [serviceTypes, setServiceTypes] = useState([ + { id: 1, name: 'Standard', description: 'Regular shipping service' }, + { id: 2, name: 'Express', description: 'Fast delivery service' }, + { id: 3, name: 'Economy', description: 'Cost-effective shipping option' } + ]); + + const [cargoTypes, setCargoTypes] = useState([ + { id: 1, name: 'General Cargo', description: 'Standard packaged goods' }, + { id: 2, name: 'Temperature Controlled', description: 'Goods requiring specific temperature' }, + { id: 3, name: 'Hazardous Materials', description: 'Dangerous goods requiring special handling' } + ]); + + const [newContractType, setNewContractType] = useState({ name: '', description: '' }); + const [newServiceType, setNewServiceType] = useState({ name: '', description: '' }); + const [newCargoType, setNewCargoType] = useState({ name: '', description: '' }); + const [showAddForms, setShowAddForms] = useState({ + contractType: false, + serviceType: false, + + cargoType: false + }); + + type SectionKey = 'contractType' | 'serviceType' | 'cargoType'; + + const toggleSection = (section: SectionKey) => { + setExpandedSections(prev => ({ + ...prev, + [section]: !prev[section] + })); + }; + + const toggleAddForm = (section: SectionKey) => { + setShowAddForms(prev => ({ + ...prev, + [section]: !prev[section] + })); + }; + + const handleAddContractType = () => { + if (newContractType.name && newContractType.description) { + setContractTypes([ + ...contractTypes, + { id: Date.now(), ...newContractType } + ]); + setNewContractType({ name: '', description: '' }); + toggleAddForm('contractType'); + } + }; + + const handleAddServiceType = () => { + if (newServiceType.name && newServiceType.description) { + setServiceTypes([ + ...serviceTypes, + { id: Date.now(), ...newServiceType } + ]); + setNewServiceType({ name: '', description: '' }); + toggleAddForm('serviceType'); + } + }; + + const handleAddCargoType = () => { + if (newCargoType.name && newCargoType.description) { + setCargoTypes([ + ...cargoTypes, + { id: Date.now(), ...newCargoType } + ]); + setNewCargoType({ name: '', description: '' }); + toggleAddForm('cargoType'); + } + }; + + const handleDelete = (type: string, id: number) => { + if (type === 'contract') { + setContractTypes(contractTypes.filter(item => item.id !== id)); + } else if (type === 'service') { + setServiceTypes(serviceTypes.filter(item => item.id !== id)); + } else if (type === 'cargo') { + setCargoTypes(cargoTypes.filter(item => item.id !== id)); + } + }; + + const handleEdit = (type: any, id: any) => { + // Implement edit functionality as needed + alert(`Edit ${type} type with id: ${id}`); + }; + + const renderTable = (title: string | number | boolean | ReactElement> | Iterable | null | undefined, types: any[], onAdd: { (): void; (): void; (): void; }, newItem: { name: any; description: any; }, setNewItem: { (value: SetStateAction<{ name: string; description: string; }>): void; (value: SetStateAction<{ name: string; description: string; }>): void; (value: SetStateAction<{ name: string; description: string; }>): void; (arg0: any): void; }, showAddForm: boolean, typeKey: string, addHandler: MouseEventHandler | undefined) => ( +
+
toggleSection(typeKey)} + > + + {expandedSections[typeKey] ? '▼' : '▶'} + +

{title}

+
+ + {expandedSections[typeKey] && ( +
+ + + {showAddForm && ( +
+

Add New {title.replace(' Types', '')}

+
+ setNewItem({ ...newItem, name: e.target.value })} + style={{ marginRight: '10px', padding: '5px' }} + /> + setNewItem({ ...newItem, description: e.target.value })} + style={{ marginRight: '10px', padding: '5px' }} + /> + + +
+
+ )} + + + + + + + + + + + + {types.map((type) => ( + + + + + + + ))} + +
IDNameDescriptionActions
{type.id}{type.name}{type.description} + + +
+
+ )} +
+ ); + + return ( +
+ {renderTable( + 'Contract Types', + contractTypes, + handleAddContractType, + newContractType, + setNewContractType, + showAddForms.contractType, + 'contractType', + handleAddContractType + )} + + {renderTable( + 'Service Types', + serviceTypes, + handleAddServiceType, + newServiceType, + setNewServiceType, + showAddForms.serviceType, + 'serviceType', + handleAddServiceType + )} + + {renderTable( + 'Cargo Types', + cargoTypes, + handleAddCargoType, + newCargoType, + setNewCargoType, + showAddForms.cargoType, + 'cargoType', + handleAddCargoType + )} +
+ ); +}; \ No newline at end of file diff --git a/apps/edr-freight-web/backoffice/src/pages/ruleEngine/RuleEngine.tsx b/apps/edr-freight-web/backoffice/src/pages/ruleEngine/RuleEngine.tsx new file mode 100644 index 000000000..96493948d --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/pages/ruleEngine/RuleEngine.tsx @@ -0,0 +1,14 @@ +import { ContractTypePage, } from "@/components/ruleEngine/ContractType"; + +export const RuleEnginePage = () => { + return
+

+ Rule Engine Page +

+ +
+ +
+ +
; +}; \ No newline at end of file