mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 09:58:12 +00:00
add user registrations
This commit is contained in:
@@ -42,6 +42,8 @@ import DocumentsPage from "./pages/documents/DocumentsPage";
|
|||||||
import DropdownSettingsPage from "./pages/admin/DropdownSettingsPage";
|
import DropdownSettingsPage from "./pages/admin/DropdownSettingsPage";
|
||||||
import FileUploadSettingsPage from "./pages/admin/FileUploadSettingsPage";
|
import FileUploadSettingsPage from "./pages/admin/FileUploadSettingsPage";
|
||||||
import MyPortalPage from "./pages/portal/MyPortalPage";
|
import MyPortalPage from "./pages/portal/MyPortalPage";
|
||||||
|
import EDRFreightLandingPage from "./pages/EDRFreightLandingPage";
|
||||||
|
import SignupPage from "./pages/accounts/SignupPage";
|
||||||
|
|
||||||
const sidebarItems: SidebarItem[] = [
|
const sidebarItems: SidebarItem[] = [
|
||||||
{ label: "My Portal", href: "/portal", icon: <UserCircle /> },
|
{ label: "My Portal", href: "/portal", icon: <UserCircle /> },
|
||||||
@@ -74,8 +76,10 @@ const App = () => {
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<Routes>
|
||||||
|
<Route path="/" element={<EDRFreightLandingPage />} />
|
||||||
|
<Route path="/signup" element={<SignupPage />} />
|
||||||
<Route path="/auth" element={<IamLoginPage />} />
|
<Route path="/auth" element={<IamLoginPage />} />
|
||||||
<Route path="*" element={<Navigate to="/auth" replace />} />
|
{/* <Route path="*" element={<Navigate to="/auth" replace />} /> */}
|
||||||
</Routes>
|
</Routes>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
612
apps/edr-freight-web/portal/src/pages/EDRFreightLandingPage.tsx
Normal file
612
apps/edr-freight-web/portal/src/pages/EDRFreightLandingPage.tsx
Normal file
@@ -0,0 +1,612 @@
|
|||||||
|
import {
|
||||||
|
ArrowRight,
|
||||||
|
BarChart3,
|
||||||
|
CheckCircle2,
|
||||||
|
Clock3,
|
||||||
|
Globe2,
|
||||||
|
Mail,
|
||||||
|
MapPin,
|
||||||
|
Menu,
|
||||||
|
Phone,
|
||||||
|
ShieldCheck,
|
||||||
|
Train,
|
||||||
|
Truck,
|
||||||
|
Users,
|
||||||
|
} from "lucide-react";
|
||||||
|
|
||||||
|
const stats = [
|
||||||
|
{
|
||||||
|
label: "Active Corridors",
|
||||||
|
value: "24+",
|
||||||
|
icon: Globe2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Monthly Shipments",
|
||||||
|
value: "12K+",
|
||||||
|
icon: Truck,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Fleet Coverage",
|
||||||
|
value: "16 Trains",
|
||||||
|
icon: Train,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "On-time Delivery",
|
||||||
|
value: "100%",
|
||||||
|
icon: Clock3,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const features = [
|
||||||
|
{
|
||||||
|
title: "Real-time Shipment Tracking",
|
||||||
|
description:
|
||||||
|
"Track consignments across Addis Ababa, Dire Dawa, Djibouti, Mojo, and all major freight corridors.",
|
||||||
|
icon: Truck,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Rail Freight Operations",
|
||||||
|
description:
|
||||||
|
"Monitor train schedules, operational performance, maintenance, and corridor activity.",
|
||||||
|
icon: Train,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Smart Analytics Dashboard",
|
||||||
|
description:
|
||||||
|
"Visualize operational insights, shipment trends, and corridor performance in real time.",
|
||||||
|
icon: BarChart3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Enterprise-grade Security",
|
||||||
|
description:
|
||||||
|
"Secure portal access, billing workflows, document management, and customer operations.",
|
||||||
|
icon: ShieldCheck,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const corridors = [
|
||||||
|
"Addis Ababa → Djibouti",
|
||||||
|
"Dire Dawa → Djibouti",
|
||||||
|
"Adama → Dire Dawa",
|
||||||
|
"Mojo → Djibouti",
|
||||||
|
"Awash → Holhol",
|
||||||
|
"Mieso → Aysha",
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function EDRFreightLandingPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground">
|
||||||
|
{/* Navbar */}
|
||||||
|
<header className="sticky top-0 z-50 border-b border-border bg-background/80 backdrop-blur-xl">
|
||||||
|
<div className="mx-auto flex h-20 max-w-7xl items-center justify-between px-6">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="flex size-12 items-center justify-center rounded-2xl bg-primary text-primary-foreground shadow-lg">
|
||||||
|
<Train className="size-6" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h1 className="text-xl font-bold tracking-tight">
|
||||||
|
EDR Freight
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Rail Logistics Platform
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav className="hidden items-center gap-8 md:flex">
|
||||||
|
<a
|
||||||
|
href="#features"
|
||||||
|
className="text-sm font-medium text-muted-foreground transition hover:text-foreground"
|
||||||
|
>
|
||||||
|
Features
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="#corridors"
|
||||||
|
className="text-sm font-medium text-muted-foreground transition hover:text-foreground"
|
||||||
|
>
|
||||||
|
Corridors
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="#contact"
|
||||||
|
className="text-sm font-medium text-muted-foreground transition hover:text-foreground"
|
||||||
|
>
|
||||||
|
Contact
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<a
|
||||||
|
href="http://localhost:5173/auth"
|
||||||
|
className="hidden rounded-2xl border border-border bg-card px-5 py-2.5 text-sm font-medium transition hover:bg-accent md:block"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="http://localhost:5173/signup"
|
||||||
|
className="hidden items-center gap-2 rounded-2xl bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground shadow-lg transition hover:opacity-90 md:flex"
|
||||||
|
>
|
||||||
|
Get Started
|
||||||
|
<ArrowRight className="size-4" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button className="rounded-2xl border border-border p-2 md:hidden">
|
||||||
|
<Menu className="size-5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{/* Hero */}
|
||||||
|
<section className="relative overflow-hidden">
|
||||||
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_right,rgba(16,185,129,0.16),transparent_35%)]" />
|
||||||
|
|
||||||
|
<div className="mx-auto grid max-w-7xl gap-16 px-6 py-20 lg:grid-cols-2 lg:items-center">
|
||||||
|
<div>
|
||||||
|
<div className="mb-6 inline-flex items-center gap-2 rounded-full border border-border bg-accent px-4 py-2 text-sm font-medium text-primary shadow-sm">
|
||||||
|
<span className="size-2 rounded-full bg-primary" />
|
||||||
|
Ethiopia–Djibouti Railway Freight Platform
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 className="max-w-2xl text-5xl font-black leading-tight tracking-tight md:text-6xl">
|
||||||
|
Smarter Railway Freight Logistics For Modern Operations
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="mt-6 max-w-2xl text-lg leading-8 text-muted-foreground">
|
||||||
|
EDR Freight enables logistics companies and railway operators
|
||||||
|
to manage shipments, monitor freight corridors, optimize train
|
||||||
|
operations, and streamline enterprise logistics workflows.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mt-10 flex flex-wrap gap-4">
|
||||||
|
<a
|
||||||
|
href="http://localhost:5173/signup"
|
||||||
|
className="flex items-center gap-2 rounded-2xl bg-primary px-6 py-3 font-semibold text-primary-foreground shadow-lg transition hover:-translate-y-0.5 hover:opacity-90"
|
||||||
|
>
|
||||||
|
Get Started
|
||||||
|
<ArrowRight className="size-5" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="http://localhost:5173/auth"
|
||||||
|
className="rounded-2xl border border-border bg-card px-6 py-3 font-semibold transition hover:bg-accent"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-12 flex flex-wrap gap-6">
|
||||||
|
{[
|
||||||
|
"Real-time Tracking",
|
||||||
|
"Railway Analytics",
|
||||||
|
"Secure Operations",
|
||||||
|
"Multi-corridor Freight",
|
||||||
|
].map((item) => (
|
||||||
|
<div
|
||||||
|
key={item}
|
||||||
|
className="flex items-center gap-2 text-sm text-muted-foreground"
|
||||||
|
>
|
||||||
|
<CheckCircle2 className="size-4 text-primary" />
|
||||||
|
{item}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Hero Dashboard Card */}
|
||||||
|
<div className="relative">
|
||||||
|
<div className="rounded-[32px] border border-border bg-card p-8 shadow-2xl">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Freight Operations
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 className="mt-2 text-3xl font-bold">
|
||||||
|
Live Statistics
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-2xl bg-primary/10 p-4 text-primary">
|
||||||
|
<BarChart3 className="size-7" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-8 grid grid-cols-2 gap-4">
|
||||||
|
{stats.map((item) => {
|
||||||
|
const Icon = item.icon;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={item.label}
|
||||||
|
className="rounded-3xl border border-border bg-background p-5 transition hover:-translate-y-1 hover:shadow-lg"
|
||||||
|
>
|
||||||
|
<div className="mb-4 flex size-12 items-center justify-center rounded-2xl bg-accent text-primary">
|
||||||
|
<Icon className="size-6" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 className="text-3xl font-black">
|
||||||
|
{item.value}
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<p className="mt-1 text-sm text-muted-foreground">
|
||||||
|
{item.label}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-8 rounded-3xl border border-border bg-accent p-6">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Corridor Performance
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 className="mt-2 text-4xl font-black text-primary">
|
||||||
|
99%
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-2xl bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground">
|
||||||
|
Operational
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-6 h-3 overflow-hidden rounded-full bg-primary/10">
|
||||||
|
<div className="h-full w-[99%] rounded-full bg-primary" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="absolute -bottom-6 -left-6 hidden rounded-3xl border border-border bg-card p-5 shadow-xl lg:block">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex size-14 items-center justify-center rounded-2xl bg-primary/10 text-primary">
|
||||||
|
<Train className="size-7" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 className="text-lg font-bold">
|
||||||
|
16 Trains Active
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Across all freight corridors
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Features */}
|
||||||
|
<section
|
||||||
|
id="features"
|
||||||
|
className="border-t border-border bg-card/40 py-24"
|
||||||
|
>
|
||||||
|
<div className="mx-auto max-w-7xl px-6">
|
||||||
|
<div className="max-w-3xl">
|
||||||
|
<div className="inline-flex rounded-full bg-accent px-4 py-2 text-sm font-semibold text-primary">
|
||||||
|
Platform Features
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 className="mt-6 text-4xl font-black tracking-tight">
|
||||||
|
Everything needed for freight operations
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="mt-4 text-lg leading-8 text-muted-foreground">
|
||||||
|
Centralized railway freight operations with live shipment
|
||||||
|
visibility, operational monitoring, customer management,
|
||||||
|
and intelligent logistics insights.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-16 grid gap-6 md:grid-cols-2 xl:grid-cols-4">
|
||||||
|
{features.map((feature) => {
|
||||||
|
const Icon = feature.icon;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={feature.title}
|
||||||
|
className="group rounded-[28px] border border-border bg-background p-7 shadow-sm transition duration-300 hover:-translate-y-2 hover:shadow-2xl"
|
||||||
|
>
|
||||||
|
<div className="flex size-14 items-center justify-center rounded-2xl bg-accent text-primary transition group-hover:scale-110">
|
||||||
|
<Icon className="size-7" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 className="mt-6 text-xl font-bold">
|
||||||
|
{feature.title}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p className="mt-3 leading-7 text-muted-foreground">
|
||||||
|
{feature.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Corridors */}
|
||||||
|
<section id="corridors" className="py-24">
|
||||||
|
<div className="mx-auto max-w-7xl px-6">
|
||||||
|
<div className="grid gap-16 lg:grid-cols-2 lg:items-center">
|
||||||
|
<div>
|
||||||
|
<div className="inline-flex rounded-full bg-accent px-4 py-2 text-sm font-semibold text-primary">
|
||||||
|
Freight Corridors
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 className="mt-6 text-4xl font-black tracking-tight">
|
||||||
|
Connected logistics infrastructure
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="mt-5 text-lg leading-8 text-muted-foreground">
|
||||||
|
Efficiently move freight across strategic Ethiopia–Djibouti
|
||||||
|
railway corridors with operational visibility and optimized
|
||||||
|
transport coordination.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mt-10 grid gap-4 sm:grid-cols-2">
|
||||||
|
{corridors.map((corridor) => (
|
||||||
|
<div
|
||||||
|
key={corridor}
|
||||||
|
className="flex items-center gap-3 rounded-2xl border border-border bg-card p-4 transition hover:border-primary/30 hover:bg-accent"
|
||||||
|
>
|
||||||
|
<div className="size-3 rounded-full bg-primary" />
|
||||||
|
|
||||||
|
<span className="font-medium">{corridor}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-[32px] border border-border bg-card p-8 shadow-xl">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Operational Insights
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 className="mt-2 text-3xl font-bold">
|
||||||
|
Freight Performance
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-2xl bg-primary/10 p-4 text-primary">
|
||||||
|
<Users className="size-7" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 space-y-6">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
label: "Bookings Processed",
|
||||||
|
value: "9,842",
|
||||||
|
progress: "92%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "On-time Shipments",
|
||||||
|
value: "99%",
|
||||||
|
progress: "99%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Customer Satisfaction",
|
||||||
|
value: "99%",
|
||||||
|
progress: "99%",
|
||||||
|
},
|
||||||
|
].map((item) => (
|
||||||
|
<div key={item.label}>
|
||||||
|
<div className="mb-2 flex items-center justify-between">
|
||||||
|
<span className="font-medium">{item.label}</span>
|
||||||
|
|
||||||
|
<span className="text-muted-foreground">
|
||||||
|
{item.value}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="h-3 overflow-hidden rounded-full bg-secondary">
|
||||||
|
<div
|
||||||
|
className="h-full rounded-full bg-primary transition-all duration-700"
|
||||||
|
style={{ width: item.progress }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 rounded-3xl bg-accent p-6">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex size-14 items-center justify-center rounded-2xl bg-primary text-primary-foreground">
|
||||||
|
<CheckCircle2 className="size-7" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 className="text-lg font-bold">
|
||||||
|
Enterprise-ready Platform
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Designed for large-scale freight and railway operations.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Contact */}
|
||||||
|
<section
|
||||||
|
id="contact"
|
||||||
|
className="border-t border-border bg-card/40 py-24"
|
||||||
|
>
|
||||||
|
<div className="mx-auto max-w-7xl px-6">
|
||||||
|
<div className="grid gap-12 lg:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<div className="inline-flex rounded-full bg-accent px-4 py-2 text-sm font-semibold text-primary">
|
||||||
|
Contact Us
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 className="mt-6 text-4xl font-black tracking-tight">
|
||||||
|
Let’s move freight smarter
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="mt-5 text-lg leading-8 text-muted-foreground">
|
||||||
|
Contact EDR Freight for partnership opportunities,
|
||||||
|
enterprise onboarding, or logistics support.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mt-10 space-y-5">
|
||||||
|
<div className="flex items-center gap-4 rounded-2xl border border-border bg-background p-5">
|
||||||
|
<div className="rounded-2xl bg-accent p-3 text-primary">
|
||||||
|
<Mail className="size-5" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold">Email</p>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
support@edrfreight.com
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-4 rounded-2xl border border-border bg-background p-5">
|
||||||
|
<div className="rounded-2xl bg-accent p-3 text-primary">
|
||||||
|
<Phone className="size-5" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold">Phone</p>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
+251 11 000 0000
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-4 rounded-2xl border border-border bg-background p-5">
|
||||||
|
<div className="rounded-2xl bg-accent p-3 text-primary">
|
||||||
|
<MapPin className="size-5" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold">Head Office</p>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Addis Ababa, Ethiopia
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Contact Form */}
|
||||||
|
<div className="rounded-[32px] border border-border bg-card p-8 shadow-xl">
|
||||||
|
<h3 className="text-2xl font-bold">
|
||||||
|
Send us a message
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p className="mt-2 text-muted-foreground">
|
||||||
|
We’ll get back to you as soon as possible.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mt-8 space-y-5">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Full Name"
|
||||||
|
className="h-12 w-full rounded-2xl border border-input bg-background px-4 outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder="Email Address"
|
||||||
|
className="h-12 w-full rounded-2xl border border-input bg-background px-4 outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
rows={5}
|
||||||
|
placeholder="Write your message..."
|
||||||
|
className="w-full rounded-2xl border border-input bg-background px-4 py-3 outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button className="flex w-full items-center justify-center gap-2 rounded-2xl bg-primary px-6 py-3 font-semibold text-primary-foreground shadow-lg transition hover:opacity-90">
|
||||||
|
Send Message
|
||||||
|
<ArrowRight className="size-5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* CTA */}
|
||||||
|
<section className="border-t border-border py-24">
|
||||||
|
<div className="mx-auto max-w-5xl px-6">
|
||||||
|
<div className="rounded-[40px] bg-primary px-8 py-16 text-center text-primary-foreground shadow-2xl md:px-16">
|
||||||
|
<div className="mx-auto max-w-3xl">
|
||||||
|
<div className="inline-flex rounded-full bg-white/10 px-4 py-2 text-sm font-semibold">
|
||||||
|
EDR Freight Platform
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 className="mt-6 text-5xl font-black tracking-tight">
|
||||||
|
Transform railway freight operations
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="mt-6 text-lg leading-8 opacity-85">
|
||||||
|
Centralize logistics workflows, optimize freight movement,
|
||||||
|
and gain real-time operational visibility across all
|
||||||
|
railway corridors.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mt-10 flex flex-wrap items-center justify-center gap-4">
|
||||||
|
<a
|
||||||
|
href="http://localhost:5173/signup"
|
||||||
|
className="flex items-center gap-2 rounded-2xl bg-white px-7 py-3 font-semibold text-primary shadow-lg transition hover:opacity-90"
|
||||||
|
>
|
||||||
|
Create Account
|
||||||
|
<ArrowRight className="size-5" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="http://localhost:5173/auth"
|
||||||
|
className="rounded-2xl border border-white/20 bg-white/10 px-7 py-3 font-semibold backdrop-blur transition hover:bg-white/20"
|
||||||
|
>
|
||||||
|
Sign In
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Footer */}
|
||||||
|
<footer className="border-t border-border py-8">
|
||||||
|
<div className="mx-auto flex max-w-7xl flex-col items-center justify-between gap-4 px-6 text-sm text-muted-foreground md:flex-row">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="flex size-10 items-center justify-center rounded-2xl bg-primary text-primary-foreground">
|
||||||
|
<Train className="size-5" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold text-foreground">
|
||||||
|
EDR Freight
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Modern railway logistics management platform</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
© 2026 EDR Freight. All rights reserved.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
350
apps/edr-freight-web/portal/src/pages/accounts/SignupPage.tsx
Normal file
350
apps/edr-freight-web/portal/src/pages/accounts/SignupPage.tsx
Normal file
@@ -0,0 +1,350 @@
|
|||||||
|
import { ArrowRight, ShieldCheck, Train, UserPlus } from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
const userTypes = [
|
||||||
|
"Customer",
|
||||||
|
"Operator",
|
||||||
|
"Dispatcher",
|
||||||
|
"Admin",
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function SignupPage() {
|
||||||
|
const [form, setForm] = useState({
|
||||||
|
email: "",
|
||||||
|
username: "",
|
||||||
|
phoneNumber: "",
|
||||||
|
userType: "",
|
||||||
|
name: {
|
||||||
|
am: "",
|
||||||
|
en: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleChange = (
|
||||||
|
field: string,
|
||||||
|
value: string,
|
||||||
|
nested?: boolean
|
||||||
|
) => {
|
||||||
|
if (nested) {
|
||||||
|
setForm((prev) => ({
|
||||||
|
...prev,
|
||||||
|
name: {
|
||||||
|
...prev.name,
|
||||||
|
[field]: value,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setForm((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[field]: value,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
console.log(form);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Expected payload:
|
||||||
|
{
|
||||||
|
email: "",
|
||||||
|
username: "",
|
||||||
|
phoneNumber: "",
|
||||||
|
userType: "",
|
||||||
|
name: {
|
||||||
|
am: "",
|
||||||
|
en: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground">
|
||||||
|
<div className="grid min-h-screen lg:grid-cols-2">
|
||||||
|
{/* Left Side */}
|
||||||
|
<div className="relative hidden overflow-hidden bg-primary p-12 text-primary-foreground lg:flex lg:flex-col lg:justify-between">
|
||||||
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_right,rgba(255,255,255,0.14),transparent_35%)]" />
|
||||||
|
|
||||||
|
<div className="relative z-10">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="flex size-14 items-center justify-center rounded-3xl bg-white/10 backdrop-blur">
|
||||||
|
<Train className="size-7" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-black tracking-tight">
|
||||||
|
EDR Freight
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="mt-1 text-sm opacity-80">
|
||||||
|
Railway Logistics Platform
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-20 max-w-lg">
|
||||||
|
<div className="inline-flex rounded-full bg-white/10 px-4 py-2 text-sm font-semibold backdrop-blur">
|
||||||
|
Smart Freight Operations
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 className="mt-6 text-5xl font-black leading-tight tracking-tight">
|
||||||
|
Create your freight operations account
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="mt-6 text-lg leading-8 opacity-85">
|
||||||
|
Join EDR Freight to manage shipments, monitor railway
|
||||||
|
operations, track consignments, and streamline logistics
|
||||||
|
workflows across Ethiopia and Djibouti.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-14 grid gap-5">
|
||||||
|
{[
|
||||||
|
"Real-time shipment tracking",
|
||||||
|
"Secure logistics management",
|
||||||
|
"Enterprise-grade operations",
|
||||||
|
"Multi-corridor freight monitoring",
|
||||||
|
].map((item) => (
|
||||||
|
<div
|
||||||
|
key={item}
|
||||||
|
className="flex items-center gap-3"
|
||||||
|
>
|
||||||
|
<div className="flex size-10 items-center justify-center rounded-2xl bg-white/10">
|
||||||
|
<ShieldCheck className="size-5" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className="font-medium">{item}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative z-10 rounded-[32px] border border-white/10 bg-white/10 p-6 backdrop-blur-xl">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p className="text-sm opacity-80">
|
||||||
|
Active Corridors
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 className="mt-2 text-4xl font-black">
|
||||||
|
24+
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-2xl bg-white/10 px-4 py-2 text-sm font-semibold">
|
||||||
|
Operational
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-6 h-3 overflow-hidden rounded-full bg-white/10">
|
||||||
|
<div className="h-full w-[95%] rounded-full bg-white" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Side */}
|
||||||
|
<div className="flex items-center justify-center p-6 md:p-10">
|
||||||
|
<div className="w-full max-w-2xl">
|
||||||
|
{/* Mobile Logo */}
|
||||||
|
<div className="mb-8 flex items-center gap-3 lg:hidden">
|
||||||
|
<div className="flex size-12 items-center justify-center rounded-2xl bg-primary text-primary-foreground">
|
||||||
|
<Train className="size-6" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl font-bold">
|
||||||
|
EDR Freight
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Railway Logistics Platform
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-[36px] border border-border bg-card p-8 shadow-2xl md:p-10">
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="mb-4 flex size-16 items-center justify-center rounded-3xl bg-primary/10 text-primary">
|
||||||
|
<UserPlus className="size-8" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 className="text-4xl font-black tracking-tight">
|
||||||
|
Create Account
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="mt-3 text-lg text-muted-foreground">
|
||||||
|
Register to access EDR Freight services and
|
||||||
|
railway logistics operations.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
className="space-y-6"
|
||||||
|
>
|
||||||
|
{/* Names */}
|
||||||
|
<div className="grid gap-5 md:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block text-sm font-semibold">
|
||||||
|
Full Name (English)
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={form.name.en}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleChange(
|
||||||
|
"en",
|
||||||
|
e.target.value,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="John Doe"
|
||||||
|
className="h-13 w-full rounded-2xl border border-input bg-background px-4 outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block text-sm font-semibold">
|
||||||
|
Full Name (Amharic)
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={form.name.am}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleChange(
|
||||||
|
"am",
|
||||||
|
e.target.value,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="ጆን ዶ"
|
||||||
|
className="h-13 w-full rounded-2xl border border-input bg-background px-4 outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Username */}
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block text-sm font-semibold">
|
||||||
|
Username
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={form.username}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleChange(
|
||||||
|
"username",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="john_doe"
|
||||||
|
className="h-13 w-full rounded-2xl border border-input bg-background px-4 outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Email + Phone */}
|
||||||
|
<div className="grid gap-5 md:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block text-sm font-semibold">
|
||||||
|
Email Address
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
value={form.email}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleChange(
|
||||||
|
"email",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="john@example.com"
|
||||||
|
className="h-13 w-full rounded-2xl border border-input bg-background px-4 outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block text-sm font-semibold">
|
||||||
|
Phone Number
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
value={form.phoneNumber}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleChange(
|
||||||
|
"phoneNumber",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="+251 9xx xxx xxx"
|
||||||
|
className="h-13 w-full rounded-2xl border border-input bg-background px-4 outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* User Type */}
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block text-sm font-semibold">
|
||||||
|
User Type
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<select
|
||||||
|
value={form.userType}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleChange(
|
||||||
|
"userType",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="h-13 w-full rounded-2xl border border-input bg-background px-4 outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
|
||||||
|
>
|
||||||
|
<option value="">
|
||||||
|
Select user type
|
||||||
|
</option>
|
||||||
|
|
||||||
|
{userTypes.map((type) => (
|
||||||
|
<option
|
||||||
|
key={type}
|
||||||
|
value={type}
|
||||||
|
>
|
||||||
|
{type}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Submit */}
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="flex h-14 w-full items-center justify-center gap-2 rounded-2xl bg-primary text-lg font-semibold text-primary-foreground shadow-lg transition hover:-translate-y-0.5 hover:opacity-90"
|
||||||
|
>
|
||||||
|
Create Account
|
||||||
|
<ArrowRight className="size-5" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<p className="text-center text-sm text-muted-foreground">
|
||||||
|
Already have an account?
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ml-2 font-semibold text-primary hover:underline"
|
||||||
|
>
|
||||||
|
Sign In
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import { client } from "@/utils/api";
|
|
||||||
import { AxiosRequestConfig, AxiosResponse } from "axios";
|
|
||||||
|
|
||||||
|
|
||||||
class ApiService {
|
|
||||||
async get<T = any>(
|
|
||||||
url: string,
|
|
||||||
config?: AxiosRequestConfig
|
|
||||||
): Promise<T> {
|
|
||||||
const response: AxiosResponse<T> =
|
|
||||||
await client.get(url, config);
|
|
||||||
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
async post<T = any>(
|
|
||||||
url: string,
|
|
||||||
data?: any,
|
|
||||||
config?: AxiosRequestConfig
|
|
||||||
): Promise<T> {
|
|
||||||
const response: AxiosResponse<T> =
|
|
||||||
await client.post(url, data, config);
|
|
||||||
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
async put<T = any>(
|
|
||||||
url: string,
|
|
||||||
data?: any,
|
|
||||||
config?: AxiosRequestConfig
|
|
||||||
): Promise<T> {
|
|
||||||
const response: AxiosResponse<T> =
|
|
||||||
await client.put(url, data, config);
|
|
||||||
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
async patch<T = any>(
|
|
||||||
url: string,
|
|
||||||
data?: any,
|
|
||||||
config?: AxiosRequestConfig
|
|
||||||
): Promise<T> {
|
|
||||||
const response: AxiosResponse<T> =
|
|
||||||
await client.patch(url, data, config);
|
|
||||||
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
async delete<T = any>(
|
|
||||||
url: string,
|
|
||||||
config?: AxiosRequestConfig
|
|
||||||
): Promise<T> {
|
|
||||||
const response: AxiosResponse<T> =
|
|
||||||
await client.delete(url, config);
|
|
||||||
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const api = new ApiService();
|
|
||||||
Reference in New Issue
Block a user