mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
feat(freight:backoffice): added basic frontend integration with auth(login) page
This commit is contained in:
@@ -1 +1,2 @@
|
||||
VITE_API_URL=http://localhost:3001
|
||||
VITE_BASE_API_URL=http://localhost:3001
|
||||
|
||||
2
apps/edr-freight-web/backoffice/index.css
Normal file
2
apps/edr-freight-web/backoffice/index.css
Normal file
@@ -0,0 +1,2 @@
|
||||
@import "tailwindcss";
|
||||
@import "@edr/ui-common/theme.css" layer(theme);
|
||||
@@ -12,27 +12,33 @@
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tria-plc/iamui-common": "1.0.3",
|
||||
"@edr/types": "workspace:*",
|
||||
"@edr/ui-common": "workspace:*",
|
||||
"@tanstack/react-query": "^5.59.0",
|
||||
"@tria-plc/iamui-common": "1.1.1",
|
||||
"axios": "^1.7.7",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"lucide-react": "^1.14.0",
|
||||
"radix-ui": "^1.4.3",
|
||||
"react": "19.2.6",
|
||||
"react-dom": "19.2.6",
|
||||
"react-router-dom": "^6.27.0",
|
||||
"recharts": "^3.8.1",
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"zustand": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@edr/eslint-config": "workspace:*",
|
||||
"@edr/tsconfig": "workspace:*",
|
||||
"@tailwindcss/vite": "^4.3.0",
|
||||
"@types/react": "^18.3.11",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react": "^4.3.2",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"jsdom": "^25.0.1",
|
||||
"postcss": "^8.4.47",
|
||||
"tailwindcss": "^3.4.13",
|
||||
"tailwindcss": "^4.3.0",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.8",
|
||||
"vitest": "^2.1.2"
|
||||
|
||||
10
apps/edr-freight-web/backoffice/public/assets/logo.svg
Normal file
10
apps/edr-freight-web/backoffice/public/assets/logo.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg width="96" height="96" viewBox="0 0 96 96" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="96" height="96" rx="20" fill="#0F766E"/>
|
||||
<path d="M24 66H72" stroke="#F8FAFC" stroke-width="5" stroke-linecap="round"/>
|
||||
<path d="M30 66V38C30 34.6863 32.6863 32 36 32H46C49.3137 32 52 34.6863 52 38V66" stroke="#F8FAFC" stroke-width="5" stroke-linejoin="round"/>
|
||||
<path d="M52 66V46C52 42.6863 54.6863 40 58 40H66C69.3137 40 72 42.6863 72 46V66" stroke="#F8FAFC" stroke-width="5" stroke-linejoin="round"/>
|
||||
<path d="M38 42H44" stroke="#F8FAFC" stroke-width="4" stroke-linecap="round"/>
|
||||
<path d="M38 50H44" stroke="#F8FAFC" stroke-width="4" stroke-linecap="round"/>
|
||||
<path d="M59 50H65" stroke="#F8FAFC" stroke-width="4" stroke-linecap="round"/>
|
||||
<path d="M59 58H65" stroke="#F8FAFC" stroke-width="4" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 852 B |
@@ -0,0 +1,20 @@
|
||||
<svg width="186" height="48" viewBox="0 0 186 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="48" height="48" rx="6" fill="#0F766E"/>
|
||||
<path d="M12 36H36" stroke="#F8FAFC" stroke-width="1.8" stroke-linecap="round"/>
|
||||
<path d="M31.2 20.4H26.4C23.4217 20.4 22.8 21.0217 22.8 24V36H34.8V24C34.8 21.0217 34.1783 20.4 31.2 20.4Z" stroke="#F8FAFC" stroke-width="1.8" stroke-linejoin="round"/>
|
||||
<path d="M27.6 36H13.2V15.6C13.2 12.6217 13.8217 12 16.8 12H24C26.9783 12 27.6 12.6217 27.6 15.6V20.4" stroke="#F8FAFC" stroke-width="1.8" stroke-linejoin="round"/>
|
||||
<path d="M13.2 16.8H16.8M13.2 21.6H16.8M13.2 26.4H16.8" stroke="#F8FAFC" stroke-width="1.8" stroke-linecap="round"/>
|
||||
<path d="M27.6 25.2H30M27.6 28.8H30" stroke="#F8FAFC" stroke-width="1.8" stroke-linecap="round"/>
|
||||
<path d="M28.8 36V32.4" stroke="#F8FAFC" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M64.8 17.5V5.3H69.4C70.4711 5.3 71.3873 5.47167 72.1486 5.815C72.9098 6.15833 73.4929 6.64833 73.8977 7.285C74.3024 7.915 74.5048 8.66967 74.5048 9.549C74.5048 10.4283 74.3024 11.1865 73.8977 11.8232C73.4929 12.4532 72.9098 12.9398 72.1486 13.2832C71.3873 13.6265 70.4711 13.7982 69.4 13.7982H66.2537V17.5H64.8ZM66.2537 12.472H69.2754C70.2629 12.472 71.0209 12.2207 71.5494 11.7182C72.0778 11.2157 72.342 10.4927 72.342 9.549C72.342 8.60533 72.0778 7.88233 71.5494 7.38C71.0209 6.87767 70.2629 6.6265 69.2754 6.6265H66.2537V12.472Z" fill="#0F172A"/>
|
||||
<path d="M82.4998 17.7515C81.5936 17.7515 80.7729 17.543 80.0378 17.126C79.3091 16.7023 78.7293 16.1242 78.2984 15.3915C77.8743 14.6522 77.6623 13.8093 77.6623 12.863C77.6623 11.9102 77.8777 11.0673 78.3084 10.3345C78.7452 9.60183 79.331 9.027 80.0661 8.61C80.8078 8.193 81.6351 7.9845 82.5481 7.9845C83.4544 7.9845 84.2684 8.193 84.9904 8.61C85.7191 9.027 86.2923 9.60183 86.7101 10.3345C87.1342 11.0673 87.3462 11.9102 87.3462 12.863C87.3462 13.8093 87.1308 14.6522 86.6999 15.3915C86.2758 16.1242 85.696 16.7023 84.9609 17.126C84.2322 17.543 83.4114 17.7515 82.4998 17.7515ZM82.4998 16.4545C83.0873 16.4545 83.6158 16.3147 84.0852 16.035C84.5611 15.7487 84.9367 15.3545 85.2122 14.8525C85.4877 14.3505 85.6254 13.7878 85.6254 13.1645V12.5715C85.6254 11.9482 85.4877 11.3855 85.2122 10.8835C84.9367 10.3815 84.5644 9.99083 84.0952 9.7115C83.6258 9.42517 83.1004 9.282 82.5198 9.282C81.9392 9.282 81.4107 9.42517 80.9348 9.7115C80.4589 9.99083 80.0833 10.3815 79.8078 10.8835C79.5323 11.3855 79.3946 11.9482 79.3946 12.5715V13.1645C79.3946 13.7878 79.5323 14.3505 79.8078 14.8525C80.0899 15.3545 80.4689 15.7487 80.9448 16.035C81.4207 16.3147 81.939 16.4545 82.4998 16.4545Z" fill="#0F172A"/>
|
||||
<path d="M90.5106 17.5V8.235H92.1549V9.816C92.4241 9.27067 92.8198 8.847 93.3421 8.545C93.8644 8.23633 94.4909 8.082 95.2216 8.082H95.7396V9.564H94.9599C94.1986 9.564 93.5753 9.80367 93.09 10.283C92.6112 10.7557 92.3718 11.4692 92.3718 12.4235V17.5H90.5106Z" fill="#0F172A"/>
|
||||
<path d="M101.872 17.7515C101.029 17.7515 100.271 17.5465 99.5979 17.1365C98.9314 16.7195 98.4029 16.1447 98.0124 15.412C97.6285 14.6727 97.4367 13.8265 97.4367 12.8735C97.4367 11.9207 97.6285 11.0778 98.0124 10.345C98.4029 9.61233 98.9314 9.04083 99.5979 8.6305C100.271 8.2135 101.029 8.005 101.872 8.005C102.602 8.005 103.245 8.16283 103.801 8.4785C104.356 8.78717 104.782 9.21083 105.079 9.7495V8.235H106.93V17.5H105.266V15.885C104.984 16.437 104.574 16.8747 104.038 17.198C103.503 17.514 102.78 17.6755 101.872 17.7515Z" fill="#0F172A"/>
|
||||
<path d="M113.792 17.7515C112.905 17.7515 112.094 17.543 111.357 17.126C110.627 16.709 110.044 16.1342 109.607 15.4015C109.177 14.6622 108.962 13.8193 108.962 12.8735C108.962 11.9207 109.18 11.0778 109.617 10.345C110.054 9.61233 110.64 9.04083 111.376 8.6305C112.113 8.2135 112.928 8.005 113.821 8.005C114.644 8.005 115.372 8.19433 116.007 8.573C116.649 8.94517 117.152 9.47083 117.517 10.15L116.19 10.8735C115.942 10.4198 115.611 10.0622 115.196 9.8005C114.785 9.53217 114.326 9.398 113.821 9.398C113.249 9.398 112.727 9.53767 112.256 9.817C111.787 10.0963 111.411 10.487 111.129 10.989C110.854 11.491 110.716 12.0537 110.716 12.677V13.27C110.716 13.8933 110.854 14.456 111.129 14.958C111.411 15.4535 111.79 15.8442 112.266 16.13C112.742 16.4163 113.271 16.5595 113.851 16.5595C114.354 16.5595 114.819 16.4288 115.245 16.167C115.672 15.8987 116.01 15.5377 116.26 15.084L117.595 15.827C117.236 16.499 116.73 17.0247 116.076 17.404C115.428 17.7833 114.667 17.7515 113.792 17.7515Z" fill="#0F172A"/>
|
||||
<path d="M123.928 17.7515C123.042 17.7515 122.234 17.5465 121.507 17.1365C120.778 16.7195 120.202 16.1413 119.778 15.4015C119.354 14.6622 119.142 13.816 119.142 12.863C119.142 11.9038 119.35 11.0577 119.765 10.3245C120.189 9.5845 120.765 9.00633 121.493 8.59C122.221 8.173 123.036 7.9645 123.938 7.9645C124.838 7.9645 125.629 8.16967 126.313 8.58C126.999 8.98317 127.533 9.546 127.918 10.2685C128.302 10.9843 128.494 11.8075 128.494 12.738V13.4155H120.919C120.956 13.9287 121.109 14.3915 121.376 14.804C121.651 15.2098 122.012 15.5313 122.46 15.7685C122.91 16.0057 123.413 16.1245 123.967 16.1245C124.591 16.1245 125.145 15.9867 125.631 15.7115C126.116 15.4297 126.476 15.0615 126.71 14.6075L128.07 15.341C127.752 16.0487 127.231 16.6235 126.506 17.0655C125.783 17.5078 124.923 17.7515 123.928 17.7515ZM120.967 11.968H126.649C126.576 11.1727 126.267 10.5365 125.721 10.0595C125.176 9.5825 124.455 9.344 123.558 9.344C122.722 9.344 122.018 9.5825 121.445 10.0595C120.881 10.5292 120.555 11.1655 120.467 11.968H120.967Z" fill="#0F172A"/>
|
||||
<path d="M64.8 42.5V30.3H66.2537V42.5H64.8ZM72.5302 42.7515C71.6872 42.7515 70.9292 42.5465 70.256 42.1365C69.5895 41.7195 69.0611 41.1447 68.6706 40.412C68.2866 39.6727 68.0948 38.8265 68.0948 37.8735C68.0948 36.9207 68.2866 36.0778 68.6706 35.345C69.0611 34.6123 69.5895 34.0408 70.256 33.6305C70.9292 33.2135 71.6872 33.005 72.5302 33.005C73.2609 33.005 73.9042 33.1628 74.4597 33.4785C75.0152 33.7872 75.4418 34.2108 75.7385 34.7495V33.235H77.5897V42.5H75.9255V40.885C75.6434 41.437 75.2335 41.8747 74.6981 42.198C74.1628 42.514 73.4398 42.6755 72.5302 42.7515Z" fill="#0F172A"/>
|
||||
<path d="M84.5774 42.7515C83.6914 42.7515 82.8834 42.5465 82.1554 42.1365C81.4267 41.7195 80.8507 41.1413 80.4266 40.4015C80.0025 39.6622 79.7904 38.816 79.7904 37.863C79.7904 36.9038 79.9989 36.0577 80.4167 35.3245C80.8344 34.5845 81.4105 34.0063 82.1445 33.59C82.8795 33.173 83.6902 32.9645 84.5774 32.9645C85.5708 32.9645 86.4239 33.2082 87.1367 33.6955C87.8559 34.1762 88.3642 34.8342 88.661 35.6695L87.0916 36.0725C86.9117 35.5308 86.608 35.1053 86.1806 34.796C85.7596 34.4797 85.2277 34.3215 84.5858 34.3215C84.0235 34.3215 83.5044 34.4647 83.0286 34.751C82.5527 35.0303 82.1737 35.421 81.8916 35.923C81.6159 36.425 81.478 36.9877 81.478 37.611V38.204C81.478 38.8273 81.6159 39.39 81.8916 39.892C82.1737 40.394 82.5527 40.7882 83.0286 41.0745C83.5044 41.3538 84.0269 41.4935 84.5972 41.4935C85.2461 41.4935 85.7902 41.3388 86.229 41.03C86.6676 40.714 86.9877 40.2815 87.1889 39.7325L88.7186 40.1845C88.4378 41.0005 87.9294 41.652 87.1939 42.1395C86.4646 42.6208 85.5924 42.8248 84.5774 42.7515Z" fill="#0F172A"/>
|
||||
<path d="M94.9155 42.7515C94.0284 42.7515 93.2203 42.5465 92.4916 42.1365C91.7636 41.7195 91.1875 41.1413 90.7634 40.4015C90.3392 39.6622 90.1271 38.816 90.1271 37.863C90.1271 36.9038 90.3359 36.0577 90.7534 35.3245C91.1711 34.5845 91.7472 34.0063 92.4814 33.59C93.2165 33.173 94.0272 32.9645 94.9155 32.9645C95.9085 32.9645 96.7617 33.2082 97.4747 33.6955C98.1937 34.1762 98.702 34.8342 98.9985 35.6695L97.4297 36.0725C97.2495 35.5308 96.946 35.1053 96.5185 34.796C96.0975 34.4797 95.5652 34.3215 94.9238 34.3215C94.3607 34.3215 93.8417 34.4647 93.3659 34.751C92.89 35.0303 92.511 35.421 92.2285 35.923C91.953 36.425 91.8152 36.9877 91.8152 37.611V38.204C91.8152 38.8273 91.953 39.39 92.2285 39.892C92.511 40.394 92.89 40.7882 93.3659 41.0745C93.8417 41.3538 94.3644 41.4935 94.9347 41.4935C95.5832 41.4935 96.1275 41.3388 96.5665 41.03C97.0047 40.714 97.325 40.2815 97.5262 39.7325L99.0555 40.1845C98.775 41.0005 98.2665 41.652 97.5307 42.1395C96.8022 42.6208 95.9302 42.8248 94.9155 42.7515Z" fill="#0F172A"/>
|
||||
<path d="M101.329 42.5V29.7H103.19V42.5H101.329ZM108.995 42.7515C108.108 42.7515 107.301 42.5465 106.572 42.1365C105.843 41.7195 105.267 41.1413 104.843 40.4015C104.419 39.6622 104.207 38.816 104.207 37.863C104.207 36.9038 104.416 36.0577 104.833 35.3245C105.251 34.5845 105.827 34.0063 106.562 33.59C107.297 33.173 108.108 32.9645 108.995 32.9645C109.989 32.9645 110.842 33.2082 111.555 33.6955C112.274 34.1762 112.782 34.8342 113.079 35.6695L111.51 36.0725C111.33 35.5308 111.026 35.1053 110.599 34.796C110.178 34.4797 109.646 34.3215 109.004 34.3215C108.441 34.3215 107.922 34.4647 107.446 34.751C106.97 35.0303 106.591 35.421 106.309 35.923C106.033 36.425 105.895 36.9877 105.895 37.611V38.204C105.895 38.8273 106.033 39.39 106.309 39.892C106.591 40.394 106.97 40.7882 107.446 41.0745C107.922 41.3538 108.444 41.4935 109.015 41.4935C109.663 41.4935 110.208 41.3388 110.646 41.03C111.085 40.714 111.405 40.2815 111.606 39.7325L113.136 40.1845C112.855 41.0005 112.347 41.652 111.611 42.1395C110.882 42.6208 110.01 42.8248 108.995 42.7515Z" fill="#0F172A"/>
|
||||
<path d="M115.507 42.5V33.235H117.151V34.816C117.42 34.2707 117.816 33.847 118.338 33.545C118.86 33.2363 119.487 33.082 120.217 33.082H120.736V34.564H119.955C119.194 34.564 118.571 34.8037 118.086 35.283C117.607 35.7557 117.368 36.4692 117.368 37.4235V42.5H115.507Z" fill="#0F172A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.3 KiB |
@@ -6,14 +6,94 @@ import {
|
||||
Navigate,
|
||||
} from "react-router-dom";
|
||||
import { DashboardLayout, type SidebarItem } from "@edr/ui-common";
|
||||
import {
|
||||
LayoutDashboard,
|
||||
Users,
|
||||
CalendarCheck,
|
||||
Package,
|
||||
MapPin,
|
||||
Train,
|
||||
Receipt,
|
||||
FileText,
|
||||
Settings,
|
||||
FileUp,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
IamLoginPage,
|
||||
LoadingScreen,
|
||||
useAuth,
|
||||
useAuthUser,
|
||||
} from "@tria-plc/iamui-common";
|
||||
|
||||
import BookingsPage from "./pages/bookings/BookingsPage";
|
||||
import BookingDetailPage from "./pages/bookings/BookingDetailPage";
|
||||
import NewBookingPage from "./pages/bookings/NewBookingPage";
|
||||
import ConsignmentsPage from "./pages/consignments/ConsignmentsPage";
|
||||
import ConsignmentDetailPage from "./pages/consignments/ConsignmentDetailPage";
|
||||
import TrackingPage from "./pages/tracking/TrackingPage";
|
||||
import BillingPage from "./pages/billing/BillingPage";
|
||||
import TrainsPage from "./pages/trains/TrainsPage";
|
||||
import DashboardPage from "./pages/dashboard/DashboardPage";
|
||||
import CustomersPage from "./pages/customers/CustomersPage";
|
||||
import CustomerDetailPage from "./pages/customers/CustomerDetailPage";
|
||||
import NewCustomerPage from "./pages/customers/NewCustomerPage";
|
||||
import DocumentsPage from "./pages/documents/DocumentsPage";
|
||||
import DropdownSettingsPage from "./pages/admin/DropdownSettingsPage";
|
||||
import FileUploadSettingsPage from "./pages/admin/FileUploadSettingsPage";
|
||||
|
||||
const sidebarItems: SidebarItem[] = [{ label: "Dashboard", href: "/" }];
|
||||
const sidebarItems: SidebarItem[] = [
|
||||
{ label: "Dashboard", href: "/", icon: <LayoutDashboard /> },
|
||||
{ label: "Customers", href: "/customers", icon: <Users /> },
|
||||
{ label: "Bookings", href: "/bookings", icon: <CalendarCheck /> },
|
||||
{ label: "Consignments", href: "/consignments", icon: <Package /> },
|
||||
{ label: "Tracking", href: "/tracking", icon: <MapPin /> },
|
||||
{ label: "Trains", href: "/trains", icon: <Train /> },
|
||||
{ label: "Billing", href: "/billing", icon: <Receipt /> },
|
||||
{ label: "Documents", href: "/documents", icon: <FileText /> },
|
||||
{ label: "Dropdown Settings", href: "/admin/dropdowns", icon: <Settings /> },
|
||||
{
|
||||
label: "File Upload Settings",
|
||||
href: "/admin/file-uploads",
|
||||
icon: <FileUp />,
|
||||
},
|
||||
];
|
||||
|
||||
const App = () => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const { user, loading } = useAuth();
|
||||
const { logout } = useAuthUser();
|
||||
|
||||
if (loading) {
|
||||
return <LoadingScreen />;
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/auth" element={<IamLoginPage />} />
|
||||
<Route path="*" element={<Navigate to="/auth" replace />} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
const displayName = user.name?.en || user.username || user.email || "User";
|
||||
const userEmail = user.email;
|
||||
|
||||
const handleLogout = () => {
|
||||
logout();
|
||||
[
|
||||
"auth-token",
|
||||
"refresh-token",
|
||||
"auth-user",
|
||||
"current-position-id",
|
||||
"selected-position-id",
|
||||
].forEach((name) => {
|
||||
document.cookie = `${name}=; Max-Age=0; path=/`;
|
||||
});
|
||||
localStorage.clear();
|
||||
window.location.replace("/auth");
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardLayout
|
||||
@@ -21,9 +101,34 @@ const App = () => {
|
||||
sidebarItems={sidebarItems}
|
||||
activeHref={location.pathname}
|
||||
onNavigate={navigate}
|
||||
enableThemeToggle
|
||||
userName={displayName}
|
||||
userEmail={userEmail}
|
||||
onLogout={handleLogout}
|
||||
>
|
||||
<Routes>
|
||||
<Route path="/" element={<DashboardPage />} />
|
||||
<Route path="/bookings" element={<BookingsPage />} />
|
||||
<Route path="/customers" element={<CustomersPage />} />
|
||||
<Route path="/customers/:id" element={<CustomerDetailPage />} />
|
||||
<Route path="/new-customer" element={<NewCustomerPage />} />
|
||||
<Route path="/bookings/new" element={<NewBookingPage />} />
|
||||
<Route path="/bookings/:id" element={<BookingDetailPage />} />
|
||||
<Route path="/consignments" element={<ConsignmentsPage />} />
|
||||
<Route path="/consignments/:id" element={<ConsignmentDetailPage />} />
|
||||
<Route path="/tracking" element={<TrackingPage />} />
|
||||
<Route path="/trains" element={<TrainsPage />} />
|
||||
<Route path="/billing" element={<BillingPage />} />
|
||||
<Route path="/documents" element={<DocumentsPage />} />
|
||||
<Route
|
||||
path="/admin/dropdowns"
|
||||
element={<DropdownSettingsPage />}
|
||||
/>
|
||||
<Route
|
||||
path="/admin/file-uploads"
|
||||
element={<FileUploadSettingsPage />}
|
||||
/>
|
||||
<Route path="/user-management" element={<Navigate to="/" replace />} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
</DashboardLayout>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
interface FeaturePlaceholderProps {
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
const FeaturePlaceholder = ({
|
||||
title,
|
||||
description,
|
||||
}: FeaturePlaceholderProps) => {
|
||||
return (
|
||||
<section className="p-6">
|
||||
<div className="rounded-2xl border border-border bg-card p-8 shadow-sm">
|
||||
<p className="text-sm font-medium uppercase tracking-[0.2em] text-muted-foreground">
|
||||
EDR Freight Backoffice
|
||||
</p>
|
||||
<h1 className="mt-3 text-3xl font-semibold text-foreground">{title}</h1>
|
||||
<p className="mt-3 max-w-2xl text-sm text-muted-foreground">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default FeaturePlaceholder;
|
||||
@@ -2,16 +2,75 @@ import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import "@tria-plc/iamui-common/styles.css";
|
||||
import "@edr/ui-common/styles.css";
|
||||
import "../index.css";
|
||||
import "@edr/ui-common/theme.css";
|
||||
|
||||
import App from "./App";
|
||||
import {
|
||||
AuthProvider,
|
||||
configureIam,
|
||||
UserProvider,
|
||||
axiosInstance,
|
||||
} from "@tria-plc/iamui-common";
|
||||
|
||||
["auth-token", "refresh-token"].forEach((name) => {
|
||||
const entry = document.cookie
|
||||
.split("; ")
|
||||
.find((cookie) => cookie.startsWith(`${name}=`));
|
||||
const value = entry?.split("=").slice(1).join("=");
|
||||
if (value === "undefined" || value === "null" || value === "") {
|
||||
document.cookie = `${name}=; Max-Age=0; path=/`;
|
||||
}
|
||||
});
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
window.__IAM_CONFIG__ = {
|
||||
apiUrl: `${import.meta.env.VITE_BASE_API_URL}/api`,
|
||||
postLoginPath: "/",
|
||||
};
|
||||
|
||||
axiosInstance.interceptors.response.use((response) => {
|
||||
if (
|
||||
response.data &&
|
||||
typeof response.data === "object" &&
|
||||
"success" in response.data &&
|
||||
"data" in response.data
|
||||
) {
|
||||
response.data = response.data.data;
|
||||
}
|
||||
return response;
|
||||
});
|
||||
|
||||
window.__USER_MANAGEMENT_BRANDING__ = {
|
||||
organizationName: "EDR Platform",
|
||||
appName: "EDR Backoffice",
|
||||
moduleBasePath: "/user-management",
|
||||
backToAppPath: "/",
|
||||
backToAppLabel: "Back to dashboard",
|
||||
};
|
||||
|
||||
configureIam({
|
||||
apiUrl: `${import.meta.env.VITE_BASE_API_URL}/api`,
|
||||
});
|
||||
|
||||
const rootElement = document.getElementById("root");
|
||||
|
||||
if (!rootElement) {
|
||||
throw new Error("Root element not found");
|
||||
}
|
||||
|
||||
createRoot(rootElement).render(
|
||||
<StrictMode>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
<AuthProvider>
|
||||
<UserProvider>
|
||||
<App />
|
||||
</UserProvider>
|
||||
</AuthProvider>
|
||||
</BrowserRouter>
|
||||
</QueryClientProvider>
|
||||
</StrictMode>,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const DropdownSettingsPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Dropdown Settings"
|
||||
description="Configure controlled dropdown options used across backoffice workflows."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default DropdownSettingsPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const FileUploadSettingsPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="File Upload Settings"
|
||||
description="Define the document fields and upload rules used by freight backoffice teams."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default FileUploadSettingsPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const BillingPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Billing"
|
||||
description="Review invoice activity, billing exceptions, and reconciliation tasks for freight operations."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default BillingPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const BookingDetailPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Booking Detail"
|
||||
description="Inspect booking metadata, operational notes, and fulfillment progress for internal teams."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default BookingDetailPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const BookingsPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Bookings"
|
||||
description="Manage freight bookings, review operational status, and coordinate internal processing flows."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default BookingsPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const NewBookingPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Create Booking"
|
||||
description="Capture and validate new freight bookings from the backoffice workflow."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewBookingPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const ConsignmentDetailPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Consignment Detail"
|
||||
description="Review cargo information, routing context, and operational actions for a consignment."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConsignmentDetailPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const ConsignmentsPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Consignments"
|
||||
description="Manage consignment handling, milestones, and internal exception resolution."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConsignmentsPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const CustomerDetailPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Customer Detail"
|
||||
description="View customer profile details, active shipments, and internal account notes."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomerDetailPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const CustomersPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Customers"
|
||||
description="Review and maintain customer records, service status, and operational context."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomersPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const NewCustomerPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Create Customer"
|
||||
description="Register a new freight customer and prepare the account for operational use."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewCustomerPage;
|
||||
@@ -1,9 +1,11 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const DashboardPage = () => {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<h1 className="text-2xl font-semibold">EDR Freight Backoffice</h1>
|
||||
<p className="mt-2 text-gray-600">Backoffice — coming soon.</p>
|
||||
</div>
|
||||
<FeaturePlaceholder
|
||||
title="Operations Dashboard"
|
||||
description="Track internal freight activity, exceptions, and workload from one backoffice workspace."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const DocumentsPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Documents"
|
||||
description="Manage internal freight documents, approvals, and operational record keeping."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default DocumentsPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const TrackingPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Tracking"
|
||||
description="Monitor shipment movement, operational events, and delays across the rail network."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default TrackingPage;
|
||||
@@ -0,0 +1,12 @@
|
||||
import FeaturePlaceholder from "@/components/FeaturePlaceholder";
|
||||
|
||||
const TrainsPage = () => {
|
||||
return (
|
||||
<FeaturePlaceholder
|
||||
title="Trains"
|
||||
description="Coordinate train assignments, scheduling visibility, and operational readiness."
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default TrainsPage;
|
||||
@@ -1 +1,24 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface Window {
|
||||
__IAM_CONFIG__?: {
|
||||
apiUrl: string;
|
||||
postLoginPath?: string;
|
||||
};
|
||||
__USER_MANAGEMENT_BRANDING__?: {
|
||||
organizationName: string;
|
||||
appName: string;
|
||||
moduleBasePath: string;
|
||||
backToAppPath?: string;
|
||||
backToAppLabel?: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_URL: string;
|
||||
readonly VITE_BASE_API_URL: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"useDefineForClassFields": true,
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
plugins: [react(), tailwindcss()],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
port: 5183,
|
||||
host: "0.0.0.0",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Table as TanstackTable } from "@tanstack/react-table";
|
||||
|
||||
import { TableCell, TableRow } from "#components/table";
|
||||
import { Button } from "#components/button.tsx";
|
||||
import { TableCell, TableRow } from "../table";
|
||||
import { Button } from "../button";
|
||||
|
||||
export function DataTableError({
|
||||
table,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Table as TanstackTable } from "@tanstack/react-table";
|
||||
|
||||
import { Skeleton } from "../skeleton";
|
||||
import { TableCell, TableRow } from "#components/table";
|
||||
import { TableCell, TableRow } from "../table";
|
||||
|
||||
export function DataTableSkeleton({ table }: { table: TanstackTable<any> }) {
|
||||
return Array.from({ length: 10 }).map((_, i) => (
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "#components/table";
|
||||
} from "../table";
|
||||
import { DataTableProps } from "./types";
|
||||
import { DataTableSkeleton } from "./skeleton";
|
||||
import { DataTableError } from "./error";
|
||||
|
||||
3346
pnpm-lock.yaml
generated
3346
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user