mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +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 FileUploadSettingsPage from "./pages/admin/FileUploadSettingsPage";
|
||||
import MyPortalPage from "./pages/portal/MyPortalPage";
|
||||
import EDRFreightLandingPage from "./pages/EDRFreightLandingPage";
|
||||
import SignupPage from "./pages/accounts/SignupPage";
|
||||
|
||||
const sidebarItems: SidebarItem[] = [
|
||||
{ label: "My Portal", href: "/portal", icon: <UserCircle /> },
|
||||
@@ -74,8 +76,10 @@ const App = () => {
|
||||
if (!user) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/" element={<EDRFreightLandingPage />} />
|
||||
<Route path="/signup" element={<SignupPage />} />
|
||||
<Route path="/auth" element={<IamLoginPage />} />
|
||||
<Route path="*" element={<Navigate to="/auth" replace />} />
|
||||
{/* <Route path="*" element={<Navigate to="/auth" replace />} /> */}
|
||||
</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