-
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' }}
- />
-
-
-
+
+
+ setFormData({...formData, parentGroupId: e.target.value})} />
+
+
+
+
+ setFormData({...formData, displayOrder: parseInt(e.target.value)})} />
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+// 2. Container Type Form
+const ContainerTypeForm = ({ initialData, onSubmit, onCancel, isSubmitting }: any) => {
+ const [formData, setFormData] = useState({
+ sizeCode: initialData?.sizeCode || '',
+ description: initialData?.description || '',
+ containersPerWagon: initialData?.containersPerWagon || 1,
+ isActive: initialData?.isActive !== undefined ? initialData.isActive : true,
+ });
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ onSubmit(formData);
+ };
+
+ return (
+
+ );
+};
+
+// 3. Priority Rule Form
+const PriorityRuleForm = ({ initialData, onSubmit, onCancel, isSubmitting }: any) => {
+ const [formData, setFormData] = useState({
+ priorityType: initialData?.priorityType || 'MEDIUM',
+ ruleName: initialData?.ruleName || '',
+ description: initialData?.description || '',
+ activationCondition: initialData?.activationCondition || '',
+ bonusPoints: initialData?.bonusPoints || 0,
+ isActive: initialData?.isActive !== undefined ? initialData.isActive : true,
+ });
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ onSubmit(formData);
+ };
+
+ return (
+
+ );
+};
+
+// 4. Service Type Form
+const ServiceTypeForm = ({ initialData, onSubmit, onCancel, isSubmitting }: any) => {
+ const [formData, setFormData] = useState({
+ code: initialData?.code || '',
+ serviceName: initialData?.serviceName || '',
+ description: initialData?.description || '',
+ canBeBookedAlone: initialData?.canBeBookedAlone !== undefined ? initialData.canBeBookedAlone : true,
+ includesFirstMile: initialData?.includesFirstMile || false,
+ includesLastMile: initialData?.includesLastMile || false,
+ includesCustoms: initialData?.includesCustoms || false,
+ priorityBonusPoints: initialData?.priorityBonusPoints || 0,
+ isActive: initialData?.isActive !== undefined ? initialData.isActive : true,
+ displayOrder: initialData?.displayOrder || 1,
+ });
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ onSubmit(formData);
+ };
+
+ return (
+
+ );
+};
+
+// 5. Surcharge Type Form
+const SurchargeTypeForm = ({ initialData, onSubmit, onCancel, isSubmitting }: any) => {
+ const [formData, setFormData] = useState({
+ code: initialData?.code || '',
+ name: initialData?.name || '',
+ description: initialData?.description || '',
+ isActive: initialData?.isActive !== undefined ? initialData.isActive : true,
+ });
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ onSubmit(formData);
+ };
+
+ return (
+
+ );
+};
+
+// 6. Surcharge Form
+const SurchargeForm = ({ initialData, onSubmit, onCancel, isSubmitting, surchargeTypes }: any) => {
+ const [formData, setFormData] = useState({
+ surchargeTypeId: initialData?.surchargeTypeId || '',
+ feeName: initialData?.feeName || '',
+ triggerDescription: initialData?.triggerDescription || '',
+ calculationMethod: initialData?.calculationMethod || 'FLAT',
+ rate: initialData?.rate || 0,
+ currency: initialData?.currency || 'USD',
+ applyToRail: initialData?.applyToRail || false,
+ applyToFirstMile: initialData?.applyToFirstMile || false,
+ applyToLastMile: initialData?.applyToLastMile || false,
+ isActive: initialData?.isActive !== undefined ? initialData.isActive : true,
+ });
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ onSubmit(formData);
+ };
+
+ return (
+
+ );
+};
+
+// 7. Weight Limit Rule Form
+const WeightLimitRuleForm = ({ initialData, onSubmit, onCancel, isSubmitting, containerTypes, surcharges }: any) => {
+ const [formData, setFormData] = useState({
+ containerTypeId: initialData?.containerTypeId || '',
+ tradeDirection: initialData?.tradeDirection || 'IMPORT',
+ maxWeightTons: initialData?.maxWeightTons || 20,
+ warningThresholdTons: initialData?.warningThresholdTons || 18,
+ exceededAction: initialData?.exceededAction || 'WARNING_ONLY',
+ surchargeId: initialData?.surchargeId || '',
+ isActive: initialData?.isActive !== undefined ? initialData.isActive : true,
+ });
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ onSubmit(formData);
+ };
+
+ return (
+
+ );
+};
+
+// ==================== Entity Table Component ====================
+const EntityTable = ({ title, data, columns, onAdd, onEdit, onDelete, isLoading }: any) => {
+ const [expanded, setExpanded] = useState(true);
+ const [searchTerm, setSearchTerm] = useState('');
+
+ const filteredData = Array.isArray(data) ? data.filter((item: any) =>
+ Object.values(item).some(value =>
+ String(value).toLowerCase().includes(searchTerm.toLowerCase())
+ )
+ ) : [];
+
+ if (isLoading) {
+ return (
+
+ );
+ }
+
+ return (
+
+
setExpanded(!expanded)}>
+
+ {expanded ? '▼' : '▶'}
+
{title}
+ {filteredData.length} items
+
+
+ {expanded && (
+
+
+
+
- )}
-
-
-
-
- | ID |
- Name |
- Description |
- Actions |
-
-
-
- {types.map((type) => (
-
- | {type.id} |
- {type.name} |
- {type.description} |
-
-
-
- |
+
+
+
+
+
+ {columns.map((col: any) => (| {col.label} | ))}
+ Actions |
- ))}
-
-
+
+
+ {filteredData.map((item: any) => (
+
+ {columns.map((col: any) => (| {col.render ? col.render(item[col.key], item) : item[col.key]} | ))}
+
+
+
+ |
+
+ ))}
+
+
+ {filteredData.length === 0 && (
No data found. Click "Add" to create one.
)}
+
)}
);
+};
+
+// ==================== Main Component ====================
+const ContractTypePage = () => {
+ const [activeTab, setActiveTab] = useState('cargo-types');
+ const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null);
+ const [loading, setLoading] = useState(true);
+ const [modalOpen, setModalOpen] = useState(false);
+ const [editingItem, setEditingItem] = useState
(null);
+ const [currentEntity, setCurrentEntity] = useState('');
+ const [isSubmitting, setIsSubmitting] = useState(false);
+
+ const [cargoTypes, setCargoTypes] = useState([]);
+ const [containerTypes, setContainerTypes] = useState([]);
+ const [priorityRules, setPriorityRules] = useState([]);
+ const [serviceTypes, setServiceTypes] = useState([]);
+ const [surchargeTypes, setSurchargeTypes] = useState([]);
+ const [surcharges, setSurcharges] = useState([]);
+ const [weightLimitRules, setWeightLimitRules] = useState([]);
+
+ const showToast = (message: string, type: 'success' | 'error') => setToast({ message, type });
+
+ useEffect(() => { loadAllData(); }, []);
+
+ const loadAllData = async () => {
+ setLoading(true);
+ try {
+ const [cargo, container, priority, service, surchargeType, surcharge, weight] = await Promise.all([
+ apiService.getCargoTypes().catch(() => []),
+ apiService.getContainerTypes().catch(() => []),
+ apiService.getPriorityRules().catch(() => []),
+ apiService.getServiceTypes().catch(() => []),
+ apiService.getSurchargeTypes().catch(() => []),
+ apiService.getSurcharges().catch(() => []),
+ apiService.getWeightLimitRules().catch(() => []),
+ ]);
+ setCargoTypes(cargo);
+ setContainerTypes(container);
+ setPriorityRules(priority);
+ setServiceTypes(service);
+ setSurchargeTypes(surchargeType);
+ setSurcharges(surcharge);
+ setWeightLimitRules(weight);
+ } catch (error) {
+ console.error(error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const handleAdd = (entity: string) => {
+ setCurrentEntity(entity);
+ setEditingItem(null);
+ setModalOpen(true);
+ };
+
+ const handleEdit = (entity: string, item: any) => {
+ setCurrentEntity(entity);
+ setEditingItem(item);
+ setModalOpen(true);
+ };
+
+ const handleSubmitForm = async (formData: any) => {
+ setIsSubmitting(true);
+ try {
+ let result: any;
+
+ switch(currentEntity) {
+ case 'cargo-types':
+ if (editingItem) {
+ result = await apiService.updateCargoType(editingItem.id, formData);
+ setCargoTypes(cargoTypes.map(c => c.id === editingItem.id ? result : c));
+ } else {
+ result = await createCargoType(formData);
+ setCargoTypes([...cargoTypes, result]);
+ }
+ break;
+
+ case 'container-types':
+ if (editingItem) {
+ result = await apiService.updateContainerType(editingItem.id, formData);
+ setContainerTypes(containerTypes.map(c => c.id === editingItem.id ? result : c));
+ } else {
+ result = await apiService.createContainerType(formData);
+ setContainerTypes([...containerTypes, result]);
+ }
+ break;
+
+ case 'priority-rules':
+ if (editingItem) {
+ result = await apiService.updatePriorityRule(editingItem.id, formData);
+ setPriorityRules(priorityRules.map(p => p.id === editingItem.id ? result : p));
+ } else {
+ result = await apiService.createPriorityRule(formData);
+ setPriorityRules([...priorityRules, result]);
+ }
+ break;
+
+ case 'service-types':
+ if (editingItem) {
+ result = await apiService.updateServiceType(editingItem.id, formData);
+ setServiceTypes(serviceTypes.map(s => s.id === editingItem.id ? result : s));
+ } else {
+ result = await apiService.createServiceType(formData);
+ setServiceTypes([...serviceTypes, result]);
+ }
+ break;
+
+ case 'surcharge-types':
+ if (editingItem) {
+ result = await apiService.updateSurchargeType(editingItem.id, formData);
+ setSurchargeTypes(surchargeTypes.map(s => s.id === editingItem.id ? result : s));
+ } else {
+ result = await apiService.createSurchargeType(formData);
+ setSurchargeTypes([...surchargeTypes, result]);
+ }
+ break;
+
+ case 'surcharges':
+ if (editingItem) {
+ result = await apiService.updateSurcharge(editingItem.id, formData);
+ setSurcharges(surcharges.map(s => s.id === editingItem.id ? result : s));
+ } else {
+ result = await apiService.createSurcharge(formData);
+ setSurcharges([...surcharges, result]);
+ }
+ break;
+
+ case 'weight-limit-rules':
+ if (editingItem) {
+ result = await apiService.updateWeightLimitRule(editingItem.id, formData);
+ setWeightLimitRules(weightLimitRules.map(w => w.id === editingItem.id ? result : w));
+ } else {
+ result = await apiService.createWeightLimitRule(formData);
+ setWeightLimitRules([...weightLimitRules, result]);
+ }
+ break;
+ }
+
+ showToast(`${currentEntity} ${editingItem ? 'updated' : 'created'} successfully!`, 'success');
+ setModalOpen(false);
+ setEditingItem(null);
+
+ } catch (error: any) {
+ console.error('Submit error:', error);
+ showToast(error.message || `Failed to ${editingItem ? 'update' : 'create'}`, 'error');
+ } finally {
+ setIsSubmitting(false);
+ }
+ };
+
+ const handleDelete = async (entity: string, item: any) => {
+ if (!confirm(`Delete this ${entity}?`)) return;
+ try {
+ switch(entity) {
+ case 'cargo-types':
+ await apiService.deleteCargoType(item.id);
+ setCargoTypes(cargoTypes.filter(c => c.id !== item.id));
+ break;
+ case 'container-types':
+ await apiService.deleteContainerType(item.id);
+ setContainerTypes(containerTypes.filter(c => c.id !== item.id));
+ break;
+ case 'priority-rules':
+ await apiService.deletePriorityRule(item.id);
+ setPriorityRules(priorityRules.filter(p => p.id !== item.id));
+ break;
+ case 'service-types':
+ await apiService.deleteServiceType(item.id);
+ setServiceTypes(serviceTypes.filter(s => s.id !== item.id));
+ break;
+ case 'surcharge-types':
+ await apiService.deleteSurchargeType(item.id);
+ setSurchargeTypes(surchargeTypes.filter(s => s.id !== item.id));
+ break;
+ case 'surcharges':
+ await apiService.deleteSurcharge(item.id);
+ setSurcharges(surcharges.filter(s => s.id !== item.id));
+ break;
+ case 'weight-limit-rules':
+ await apiService.deleteWeightLimitRule(item.id);
+ setWeightLimitRules(weightLimitRules.filter(w => w.id !== item.id));
+ break;
+ }
+ showToast(`${entity} deleted successfully!`, 'success');
+ } catch (error: any) {
+ showToast(error.message || `Failed to delete`, 'error');
+ }
+ };
+
+ const getColumns = (entity: string) => {
+ const baseStatus = { key: 'isActive', label: 'Status', render: (val: boolean) => val ? '✅ Active' : '❌ Inactive' };
+ switch(entity) {
+ case 'cargo-types':
+ return [{ key: 'code', label: 'Code' }, { key: 'cargoTypeName', label: 'Name' }, { key: 'displayOrder', label: 'Order' }, baseStatus];
+ case 'container-types':
+ return [{ key: 'sizeCode', label: 'Size Code' }, { key: 'description', label: 'Description' }, { key: 'containersPerWagon', label: 'Containers/Wagon' }, baseStatus];
+ case 'priority-rules':
+ return [{ key: 'priorityType', label: 'Priority Type' }, { key: 'ruleName', label: 'Rule Name' }, { key: 'bonusPoints', label: 'Bonus Points' }, baseStatus];
+ case 'service-types':
+ return [{ key: 'code', label: 'Code' }, { key: 'serviceName', label: 'Service Name' }, { key: 'displayOrder', label: 'Order' }, baseStatus];
+ case 'surcharge-types':
+ return [{ key: 'code', label: 'Code' }, { key: 'name', label: 'Name' }, baseStatus];
+ case 'surcharges':
+ return [{ key: 'feeName', label: 'Fee Name' }, { key: 'calculationMethod', label: 'Method' }, { key: 'rate', label: 'Rate', render: (val: number, item: any) => `${val} ${item.currency}` }, baseStatus];
+ case 'weight-limit-rules':
+ return [{ key: 'tradeDirection', label: 'Direction' }, { key: 'maxWeightTons', label: 'Max Weight', render: (val: number) => `${val} tons` }, { key: 'exceededAction', label: 'Action' }, baseStatus];
+ default:
+ return [];
+ }
+ };
+
+ const getEntityData = (entity: string) => {
+ switch(entity) {
+ case 'cargo-types': return cargoTypes;
+ case 'container-types': return containerTypes;
+ case 'priority-rules': return priorityRules;
+ case 'service-types': return serviceTypes;
+ case 'surcharge-types': return surchargeTypes;
+ case 'surcharges': return surcharges;
+ case 'weight-limit-rules': return weightLimitRules;
+ default: return [];
+ }
+ };
+
+ const tabs = [
+ { id: 'cargo-types', label: 'Cargo Types', Form: CargoTypeForm },
+ { id: 'container-types', label: 'Container Types', Form: ContainerTypeForm },
+ { id: 'priority-rules', label: 'Priority Rules', Form: PriorityRuleForm },
+ { id: 'service-types', label: 'Service Types', Form: ServiceTypeForm },
+ { id: 'surcharge-types', label: 'Surcharge Types', Form: SurchargeTypeForm },
+ { id: 'surcharges', label: 'Surcharges', Form: SurchargeForm },
+ { id: 'weight-limit-rules', label: 'Weight Limit Rules', Form: WeightLimitRuleForm },
+ ];
+
+ const currentTab = tabs.find(t => t.id === currentEntity);
+ const FormComponent = currentTab?.Form;
return (
-
- {renderTable(
- 'Contract Types',
- contractTypes,
- handleAddContractType,
- newContractType,
- setNewContractType,
- showAddForms.contractType,
- 'contractType',
- handleAddContractType
- )}
+
+ {toast &&
setToast(null)} />}
- {renderTable(
- 'Service Types',
- serviceTypes,
- handleAddServiceType,
- newServiceType,
- setNewServiceType,
- showAddForms.serviceType,
- 'serviceType',
- handleAddServiceType
- )}
+
+
Rule Engine - Master Data
+
Manage cargo types, container types, priority rules, and more
+
- {renderTable(
- 'Cargo Types',
- cargoTypes,
- handleAddCargoType,
- newCargoType,
- setNewCargoType,
- showAddForms.cargoType,
- 'cargoType',
- handleAddCargoType
- )}
+
+
+ {tabs.map((tab) => (
+
+ ))}
+
+
+
+
+ {tabs.map((tab) => (
+
+ handleAdd(tab.id)}
+ onEdit={(item: any) => handleEdit(tab.id, item)}
+ onDelete={(item: any) => handleDelete(tab.id, item)}
+ isLoading={loading}
+ />
+
+ ))}
+
+
+ { setModalOpen(false); setEditingItem(null); }}
+ title={editingItem ? `Edit ${currentEntity?.replace('-', ' ')}` : `Add ${currentEntity?.replace('-', ' ')}`}
+ >
+ {FormComponent && (
+ { setModalOpen(false); setEditingItem(null); }}
+ isSubmitting={isSubmitting}
+ surchargeTypes={surchargeTypes}
+ containerTypes={containerTypes}
+ surcharges={surcharges}
+ />
+ )}
+
);
-};
\ No newline at end of file
+};
+
+export default ContractTypePage;
\ No newline at end of file
diff --git a/apps/edr-freight-web/backoffice/src/constants/URLS.ts b/apps/edr-freight-web/backoffice/src/constants/URLS.ts
index 9ce2cc3de..739faf950 100644
--- a/apps/edr-freight-web/backoffice/src/constants/URLS.ts
+++ b/apps/edr-freight-web/backoffice/src/constants/URLS.ts
@@ -85,5 +85,40 @@ export const URL_CONSTANTS = {
OTP: {
SEND: "/api/otp/send",
VERIFY: "/api/otp/verify",
- }
-};
\ No newline at end of file
+ },
+ RULE_ENGINE: {
+ // Cargo Types
+ CARGO_TYPES: "/cargo-types",
+ CARGO_TYPE_BY_ID: (id: string | number) => `/cargo-types/${id}`,
+
+ // Container Types
+ CONTAINER_TYPES: "/container-types",
+ CONTAINER_TYPE_BY_ID: (id: string | number) =>
+ `/container-types/${id}`,
+
+ // Priority Rules
+ PRIORITY_RULES: "/priority-rules",
+ PRIORITY_RULE_BY_ID: (id: string | number) =>
+ `/priority-rules/${id}`,
+
+ // Service Types
+ SERVICE_TYPES: "/service-types",
+ SERVICE_TYPE_BY_ID: (id: string | number) =>
+ `/service-types/${id}`,
+
+ // Surcharge Types
+ SURCHARGE_TYPES: "/surcharge-types",
+ SURCHARGE_TYPE_BY_ID: (id: string | number) =>
+ `/surcharge-types/${id}`,
+
+ // Surcharges
+ SURCHARGES: "/surcharges",
+ SURCHARGE_BY_ID: (id: string | number) =>
+ `/surcharges/${id}`,
+
+ // Weight Limit Rules
+ WEIGHT_LIMIT_RULES: "/weight-limit-rules",
+ WEIGHT_LIMIT_RULE_BY_ID: (id: string | number) =>
+ `/weight-limit-rules/${id}`,
+ },
+};
diff --git a/apps/edr-freight-web/backoffice/src/pages/ruleEngine/RuleEngine.tsx b/apps/edr-freight-web/backoffice/src/pages/ruleEngine/RuleEngine.tsx
index 96493948d..5d02ce082 100644
--- a/apps/edr-freight-web/backoffice/src/pages/ruleEngine/RuleEngine.tsx
+++ b/apps/edr-freight-web/backoffice/src/pages/ruleEngine/RuleEngine.tsx
@@ -1,14 +1,10 @@
-import { ContractTypePage, } from "@/components/ruleEngine/ContractType";
+// src/pages/ruleEngine/RuleEngine.tsx
+import ContractTypePage from "@/components/ruleEngine/ContractType";
export const RuleEnginePage = () => {
- return
-
- Rule Engine Page
-
-
-
-
-
-
-
;
+ return (
+
+
+
+ );
};
\ No newline at end of file
diff --git a/apps/edr-freight-web/backoffice/src/services/rule.engine/cargoType.ts b/apps/edr-freight-web/backoffice/src/services/rule.engine/cargoType.ts
new file mode 100644
index 000000000..5759ab8f8
--- /dev/null
+++ b/apps/edr-freight-web/backoffice/src/services/rule.engine/cargoType.ts
@@ -0,0 +1,25 @@
+// import { CargoType } from "@edr-freight-web/types";
+import { api as client } from "../../auth/http";
+import { URL_CONSTANTS } from "../../constants/URLS";
+
+export const createCargoType = (data: any) => {
+ return client.post(URL_CONSTANTS.RULE_ENGINE.CARGO_TYPES, { data });
+};
+
+
+export const getCargoType = () => {
+ return client.get(URL_CONSTANTS.RULE_ENGINE.CARGO_TYPES);
+};
+
+export const getCargoTypeById = (id: string) => {
+ return client.get(`${URL_CONSTANTS.RULE_ENGINE.CARGO_TYPES}/${id}`);
+};
+
+export const updateCargoType = (id: string, data: any) => {
+ return client.put(`${URL_CONSTANTS.RULE_ENGINE.CARGO_TYPES}/${id}`, { data });
+};
+
+
+export const deleteCargoType = (id: string) => {
+ return client.delete(`${URL_CONSTANTS.RULE_ENGINE.CARGO_TYPES}/${id}`);
+};
\ No newline at end of file
diff --git a/apps/edr-freight-web/backoffice/src/services/rule.engine/containerType.ts b/apps/edr-freight-web/backoffice/src/services/rule.engine/containerType.ts
new file mode 100644
index 000000000..d8b152b9f
--- /dev/null
+++ b/apps/edr-freight-web/backoffice/src/services/rule.engine/containerType.ts
@@ -0,0 +1,19 @@
+import { api as client } from "../../auth/http";
+import { URL_CONSTANTS } from "../../constants/URLS";
+
+export const createContainerType = (data: any) =>
+ client.post(URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPES, { data });
+
+export const getContainerTypes = () =>
+ client.get(URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPES);
+
+export const getContainerTypeById = (id: string) =>
+ client.get(URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPE_BY_ID(id));
+
+
+
+export const updateContainerType = (id: string, data: any) =>
+ client.put(URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPE_BY_ID(id), { data });
+
+export const deleteContainerType = (id: string) =>
+ client.delete(URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPE_BY_ID(id));
\ No newline at end of file
diff --git a/apps/edr-freight-web/backoffice/vite.config.ts.timestamp-1779977728892-a0ba1f5e8e96b.mjs b/apps/edr-freight-web/backoffice/vite.config.ts.timestamp-1779977728892-a0ba1f5e8e96b.mjs
new file mode 100644
index 000000000..50f04e63d
--- /dev/null
+++ b/apps/edr-freight-web/backoffice/vite.config.ts.timestamp-1779977728892-a0ba1f5e8e96b.mjs
@@ -0,0 +1,24 @@
+// vite.config.ts
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+import { defineConfig } from "file:///C:/laragon/www/edr-platform/node_modules/.pnpm/vite@5.4.21_@types+node@20.19.41_lightningcss@1.32.0_terser@5.48.0/node_modules/vite/dist/node/index.js";
+import react from "file:///C:/laragon/www/edr-platform/node_modules/.pnpm/@vitejs+plugin-react@4.7.0_vite@5.4.21_@types+node@20.19.41_lightningcss@1.32.0_terser@5.48.0_/node_modules/@vitejs/plugin-react/dist/index.js";
+import tailwindcss from "file:///C:/laragon/www/edr-platform/node_modules/.pnpm/@tailwindcss+vite@4.3.0_vite@5.4.21_@types+node@20.19.41_lightningcss@1.32.0_terser@5.48.0_/node_modules/@tailwindcss/vite/dist/index.mjs";
+var __vite_injected_original_import_meta_url = "file:///C:/laragon/www/edr-platform/apps/edr-freight-web/backoffice/vite.config.ts";
+var __dirname = path.dirname(fileURLToPath(__vite_injected_original_import_meta_url));
+var vite_config_default = defineConfig({
+ plugins: [react(), tailwindcss()],
+ resolve: {
+ alias: {
+ "@": path.resolve(__dirname, "./src")
+ }
+ },
+ server: {
+ port: 5183,
+ host: "0.0.0.0"
+ }
+});
+export {
+ vite_config_default as default
+};
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFxlZHItcGxhdGZvcm1cXFxcYXBwc1xcXFxlZHItZnJlaWdodC13ZWJcXFxcYmFja29mZmljZVwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcZWRyLXBsYXRmb3JtXFxcXGFwcHNcXFxcZWRyLWZyZWlnaHQtd2ViXFxcXGJhY2tvZmZpY2VcXFxcdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0M6L2xhcmFnb24vd3d3L2Vkci1wbGF0Zm9ybS9hcHBzL2Vkci1mcmVpZ2h0LXdlYi9iYWNrb2ZmaWNlL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xyXG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcIm5vZGU6dXJsXCI7XHJcblxyXG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiO1xyXG5pbXBvcnQgcmVhY3QgZnJvbSBcIkB2aXRlanMvcGx1Z2luLXJlYWN0XCI7XHJcbmltcG9ydCB0YWlsd2luZGNzcyBmcm9tIFwiQHRhaWx3aW5kY3NzL3ZpdGVcIjtcclxuXHJcbmNvbnN0IF9fZGlybmFtZSA9IHBhdGguZGlybmFtZShmaWxlVVJMVG9QYXRoKGltcG9ydC5tZXRhLnVybCkpO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcclxuICBwbHVnaW5zOiBbcmVhY3QoKSwgdGFpbHdpbmRjc3MoKV0sXHJcbiAgcmVzb2x2ZToge1xyXG4gICAgYWxpYXM6IHtcclxuICAgICAgXCJAXCI6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsIFwiLi9zcmNcIiksXHJcbiAgICB9LFxyXG4gIH0sXHJcbiAgc2VydmVyOiB7XHJcbiAgICBwb3J0OiA1MTgzLFxyXG4gICAgaG9zdDogXCIwLjAuMC4wXCIsXHJcbiAgfSxcclxufSk7XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBaVgsT0FBTyxVQUFVO0FBQ2xZLFNBQVMscUJBQXFCO0FBRTlCLFNBQVMsb0JBQW9CO0FBQzdCLE9BQU8sV0FBVztBQUNsQixPQUFPLGlCQUFpQjtBQUxtTixJQUFNLDJDQUEyQztBQU81UixJQUFNLFlBQVksS0FBSyxRQUFRLGNBQWMsd0NBQWUsQ0FBQztBQUU3RCxJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMxQixTQUFTLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQztBQUFBLEVBQ2hDLFNBQVM7QUFBQSxJQUNQLE9BQU87QUFBQSxNQUNMLEtBQUssS0FBSyxRQUFRLFdBQVcsT0FBTztBQUFBLElBQ3RDO0FBQUEsRUFDRjtBQUFBLEVBQ0EsUUFBUTtBQUFBLElBQ04sTUFBTTtBQUFBLElBQ04sTUFBTTtBQUFBLEVBQ1I7QUFDRixDQUFDOyIsCiAgIm5hbWVzIjogW10KfQo=
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4481fbf09..b9b737e64 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -201,6 +201,9 @@ importers:
react-dom:
specifier: 19.2.6
version: 19.2.6(react@19.2.6)
+ react-hot-toast:
+ specifier: ^2.6.0
+ version: 2.6.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
react-router-dom:
specifier: ^6.27.0
version: 6.30.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
@@ -6281,6 +6284,11 @@ packages:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'}
+ goober@2.1.19:
+ resolution: {integrity: sha512-U7veizMqxyKlM58+Z5j2ngJBH/r9siDmxpvNxSw0PylF6WQvrASJEZrxh1hidRBJc2jqoBVSyOban5u8m+6Rxg==}
+ peerDependencies:
+ csstype: ^3.0.10
+
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
@@ -8408,6 +8416,13 @@ packages:
peerDependencies:
react: 19.2.6
+ react-hot-toast@2.6.0:
+ resolution: {integrity: sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ react: 19.2.6
+ react-dom: 19.2.6
+
react-i18next@15.7.4:
resolution: {integrity: sha512-nyU8iKNrI5uDJch0z9+Y5XEr34b0wkyYj3Rp+tfbahxtlswxSCjcUL9H0nqXo9IR3/t5Y5PKIA3fx3MfUyR9Xw==}
peerDependencies:
@@ -17011,6 +17026,10 @@ snapshots:
define-properties: 1.2.1
gopd: 1.2.0
+ goober@2.1.19(csstype@3.2.3):
+ dependencies:
+ csstype: 3.2.3
+
gopd@1.2.0: {}
graceful-fs@4.2.11: {}
@@ -19373,6 +19392,13 @@ snapshots:
dependencies:
react: 19.2.6
+ react-hot-toast@2.6.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
+ dependencies:
+ csstype: 3.2.3
+ goober: 2.1.19(csstype@3.2.3)
+ react: 19.2.6
+ react-dom: 19.2.6(react@19.2.6)
+
react-i18next@15.7.4(i18next@25.10.10(typescript@5.9.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3):
dependencies:
'@babel/runtime': 7.29.2