diff --git a/apps/edr-freight-web/portal/index.css b/apps/edr-freight-web/portal/index.css index a461c505f..21deab082 100644 --- a/apps/edr-freight-web/portal/index.css +++ b/apps/edr-freight-web/portal/index.css @@ -1 +1,42 @@ -@import "tailwindcss"; \ No newline at end of file +@import "tailwindcss"; + +@custom-variant dark (&:where(.dark, .dark *)); + +* { + scrollbar-width: thin; + scrollbar-color: rgb(203 213 225 / 0.6) transparent; +} + +*::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +*::-webkit-scrollbar-track { + background: transparent; +} + +*::-webkit-scrollbar-thumb { + background-color: rgb(203 213 225 / 0.7); + border-radius: 9999px; +} + +*::-webkit-scrollbar-thumb:hover { + background-color: rgb(51 87 141 / 0.5); +} + +*::-webkit-scrollbar-corner { + background: transparent; +} + +.dark * { + scrollbar-color: rgb(71 85 105 / 0.6) transparent; +} + +.dark *::-webkit-scrollbar-thumb { + background-color: rgb(71 85 105 / 0.6); +} + +.dark *::-webkit-scrollbar-thumb:hover { + background-color: rgb(51 87 141 / 0.7); +} diff --git a/apps/edr-freight-web/portal/package.json b/apps/edr-freight-web/portal/package.json index ee0fa55c5..22fd4c4f1 100644 --- a/apps/edr-freight-web/portal/package.json +++ b/apps/edr-freight-web/portal/package.json @@ -17,11 +17,14 @@ "@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", "lucide-react": "^1.14.0", + "radix-ui": "^1.4.3", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.27.0", + "tailwind-merge": "^3.6.0", "zustand": "^5.0.0" }, "devDependencies": { diff --git a/apps/edr-freight-web/portal/src/App.tsx b/apps/edr-freight-web/portal/src/App.tsx index 804b8a680..9e644251d 100644 --- a/apps/edr-freight-web/portal/src/App.tsx +++ b/apps/edr-freight-web/portal/src/App.tsx @@ -6,10 +6,20 @@ import { Navigate, } from "react-router-dom"; import { DashboardLayout, type SidebarItem } from "@edr/ui-common"; +import { + LayoutDashboard, + Users, + CalendarCheck, + Package, + MapPin, + Train, + Receipt, + FileText, +} from "lucide-react"; import BookingsPage from "./pages/bookings/BookingsPage"; import BookingDetailPage from "./pages/bookings/BookingDetailPage"; -import CreateBookingPage from "./pages/bookings/CreateBookingPage"; +import NewBookingPage from "./pages/bookings/NewBookingPage"; import ConsignmentsPage from "./pages/consignments/ConsignmentsPage"; import ConsignmentDetailPage from "./pages/consignments/ConsignmentDetailPage"; import TrackingPage from "./pages/tracking/TrackingPage"; @@ -17,16 +27,20 @@ import BillingPage from "./pages/billing/BillingPage"; import TrainsPage from "./pages/trains/TrainsPage"; import DashboardPage from "./pages/dashboard/DashboardPage"; import { IamLoginPage } from "@tria-plc/iamui-common"; -import CustomersPage from "./pages/customers/CustomersPage"; +import CustomersPage from "./pages/customers/CustomersPage"; +import CustomerDetailPage from "./pages/customers/CustomerDetailPage"; +import NewCustomerPage from "./pages/customers/NewCustomerPage"; +import DocumentsPage from "./pages/documents/DocumentsPage"; const sidebarItems: SidebarItem[] = [ - { label: "Dashboard", href: "/" }, - { label: "Customers", href: "/Customers" }, - { label: "Bookings", href: "/bookings" }, - { label: "Consignments", href: "/consignments" }, - { label: "Tracking", href: "/tracking" }, - { label: "Trains", href: "/trains" }, - { label: "Billing", href: "/billing" }, + { label: "Dashboard", href: "/", icon: }, + { label: "Customers", href: "/customers", icon: }, + { label: "Bookings", href: "/bookings", icon: }, + { label: "Consignments", href: "/consignments", icon: }, + { label: "Tracking", href: "/tracking", icon: }, + { label: "Trains", href: "/trains", icon: }, + { label: "Billing", href: "/billing", icon: }, + { label: "Documents", href: "/documents", icon: }, ]; const App = () => { @@ -48,18 +62,22 @@ const App = () => { sidebarItems={sidebarItems} activeHref={location.pathname} onNavigate={navigate} + enableThemeToggle > } /> } /> } /> - } /> + } /> + } /> + } /> } /> } /> } /> } /> } /> } /> + } /> } /> diff --git a/apps/edr-freight-web/portal/src/components/Breadcrumbs.tsx b/apps/edr-freight-web/portal/src/components/Breadcrumbs.tsx new file mode 100644 index 000000000..159d7eead --- /dev/null +++ b/apps/edr-freight-web/portal/src/components/Breadcrumbs.tsx @@ -0,0 +1,56 @@ +import { Fragment } from "react"; +import { Link } from "react-router-dom"; +import { ChevronRight, Home } from "lucide-react"; + +export interface BreadcrumbItem { + label: string; + href?: string; +} + +export interface BreadcrumbsProps { + items: BreadcrumbItem[]; +} + +export default function Breadcrumbs({ items }: BreadcrumbsProps) { + return ( + + ); +} diff --git a/apps/edr-freight-web/portal/src/components/ui/button.tsx b/apps/edr-freight-web/portal/src/components/ui/button.tsx new file mode 100644 index 000000000..1d9f2e228 --- /dev/null +++ b/apps/edr-freight-web/portal/src/components/ui/button.tsx @@ -0,0 +1,58 @@ +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; +import { Slot } from "radix-ui"; + +import { cn } from "@/lib/utils"; + +const buttonVariants = cva( + "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +function Button({ + className, + variant = "default", + size = "default", + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean; + }) { + const Comp = asChild ? Slot.Root : "button"; + + return ( + + ); +} + +export { Button, buttonVariants }; diff --git a/apps/edr-freight-web/portal/src/components/ui/dialog.tsx b/apps/edr-freight-web/portal/src/components/ui/dialog.tsx new file mode 100644 index 000000000..5bf59ed79 --- /dev/null +++ b/apps/edr-freight-web/portal/src/components/ui/dialog.tsx @@ -0,0 +1,141 @@ +import * as React from "react"; +import { Dialog as DialogPrimitive } from "radix-ui"; +import { XIcon } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +function Dialog({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogTrigger({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogPortal({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogClose({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function DialogContent({ + className, + children, + showCloseButton = true, + ...props +}: React.ComponentProps & { + showCloseButton?: boolean; +}) { + return ( + + + + {children} + {showCloseButton && ( + + + Close + + )} + + + ); +} + +function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function DialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function DialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +}; diff --git a/apps/edr-freight-web/portal/src/components/ui/input.tsx b/apps/edr-freight-web/portal/src/components/ui/input.tsx new file mode 100644 index 000000000..311be213b --- /dev/null +++ b/apps/edr-freight-web/portal/src/components/ui/input.tsx @@ -0,0 +1,22 @@ +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +function Input({ className, type, ...props }: React.ComponentProps<"input">) { + return ( + + ); +} + +export { Input }; diff --git a/apps/edr-freight-web/portal/src/components/ui/label.tsx b/apps/edr-freight-web/portal/src/components/ui/label.tsx new file mode 100644 index 000000000..61818eba8 --- /dev/null +++ b/apps/edr-freight-web/portal/src/components/ui/label.tsx @@ -0,0 +1,22 @@ +import * as React from "react"; +import { Label as LabelPrimitive } from "radix-ui"; + +import { cn } from "@/lib/utils"; + +function Label({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { Label }; diff --git a/apps/edr-freight-web/portal/src/components/ui/textarea.tsx b/apps/edr-freight-web/portal/src/components/ui/textarea.tsx new file mode 100644 index 000000000..2e6c1f849 --- /dev/null +++ b/apps/edr-freight-web/portal/src/components/ui/textarea.tsx @@ -0,0 +1,21 @@ +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +function Textarea({ className, ...props }: React.ComponentProps<"textarea">) { + return ( +