diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/page.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/page.tsx index 650dde2cf..4ce923279 100644 --- a/apps/edr-passenger-web/backoffice/src/app/docs/page.tsx +++ b/apps/edr-passenger-web/backoffice/src/app/docs/page.tsx @@ -3,193 +3,48 @@ import React, { useState } from 'react'; import Link from 'next/link'; import { ChevronDown, ChevronRight, FileText, Home } from 'lucide-react'; +import { navSections } from './sections/_shared'; +import OverviewSection from './sections/OverviewSection'; +import OperationsSection from './sections/OperationsSection'; +import TourismSection from './sections/TourismSection'; +import MasterDataSection from './sections/MasterDataSection'; +import FinancialSection from './sections/FinancialSection'; +import CustomerServicesSection from './sections/CustomerServicesSection'; +import SecuritySection from './sections/SecuritySection'; +import AnalyticsSection from './sections/AnalyticsSection'; +import SystemSection from './sections/SystemSection'; -const DocPage = () => { - const [expandedSections, setExpandedSections] = useState<{ [key: string]: boolean }>({ - overview: true, - operations: true, - masterdata: false, - financial: false, - services: false, - security: false, - analytics: false, - system: false, - enhanced: false, +export default function DocPage() { + const [expanded, setExpanded] = useState>({ + overview: true, operations: true, tourism: false, masterdata: false, + financial: false, services: false, security: false, analytics: false, system: false, }); - const toggleSection = (section: string) => { - setExpandedSections(prev => (({ - ...prev, - [section]: !prev[section] - }))); - }; + const toggle = (id: string) => setExpanded(prev => ({ ...prev, [id]: !prev[id] })); - const scrollToSection = (id: string) => { + const scrollTo = (id: string) => { setTimeout(() => { - const element = document.getElementById(id); - if (element) { - const headerOffset = 120; - const elementPosition = element.getBoundingClientRect().top + window.pageYOffset; - const offsetPosition = elementPosition - headerOffset; - window.scrollTo({ - top: offsetPosition, - behavior: 'smooth' - }); - } + const el = document.getElementById(id); + if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.pageYOffset - 120, behavior: 'smooth' }); }, 0); }; - const sections = [ - { - id: 'overview', - title: 'πŸ“‹ Overview & Getting Started', - items: [ - { id: 'about', label: 'Application Overview' }, - { id: 'features', label: 'Key Features' }, - ] - }, - { - id: 'operations', - title: 'πŸ“Š Operations', - items: [ - { id: 'bookings', label: 'Bookings' }, - { id: 'bookings-how', label: 'β†’ How-To' }, - { id: 'passengers', label: 'Passengers' }, - { id: 'passengers-how', label: 'β†’ How-To' }, - { id: 'tickets', label: 'Tickets' }, - { id: 'tickets-how', label: 'β†’ How-To' }, - ] - }, - { - id: 'masterdata', - title: '🏒 Master Data', - items: [ - { id: 'stations', label: 'Stations' }, - { id: 'stations-how', label: 'β†’ How-To' }, - { id: 'trains', label: 'Trains' }, - { id: 'trains-how', label: 'β†’ How-To' }, - { id: 'coaches', label: 'Coaches' }, - { id: 'coaches-how', label: 'β†’ How-To' }, - { id: 'seats', label: 'Seats' }, - { id: 'seats-how', label: 'β†’ How-To' }, - { id: 'classes', label: 'Seat Classes' }, - { id: 'classes-how', label: 'β†’ How-To' }, - { id: 'routes', label: 'Routes' }, - { id: 'routes-how', label: 'β†’ How-To' }, - { id: 'schedules', label: 'Schedules' }, - { id: 'schedules-how', label: 'β†’ How-To' }, - ] - }, - { - id: 'financial', - title: 'πŸ’° Financial', - items: [ - { id: 'pricing', label: 'Pricing & Fares' }, - { id: 'pricing-how', label: 'β†’ How-To' }, - { id: 'currencies', label: 'Currencies' }, - { id: 'currencies-how', label: 'β†’ How-To' }, - { id: 'payments', label: 'Payments' }, - { id: 'payments-how', label: 'β†’ How-To' }, - { id: 'promos', label: 'Promo Codes' }, - { id: 'promos-how', label: 'β†’ How-To' }, - ] - }, - { - id: 'services', - title: '🎁 Customer Services', - items: [ - { id: 'loyalty', label: 'Loyalty' }, - { id: 'loyalty-how', label: 'β†’ How-To' }, - { id: 'support', label: 'Support' }, - { id: 'support-how', label: 'β†’ How-To' }, - { id: 'notifications', label: 'Notifications' }, - { id: 'notifications-how', label: 'β†’ How-To' }, - ] - }, - { - id: 'security', - title: 'πŸ”’ Security', - items: [ - { id: 'audit', label: 'Audit Logs' }, - { id: 'audit-how', label: 'β†’ How-To' }, - { id: 'fraud', label: 'Fraud Detection' }, - { id: 'fraud-how', label: 'β†’ How-To' }, - { id: 'verifayda', label: 'Verifayda' }, - { id: 'verifayda-how', label: 'β†’ How-To' }, - ] - }, - { - id: 'analytics', - title: 'πŸ“ˆ Analytics', - items: [ - { id: 'reports', label: 'Reports' }, - { id: 'reports-how', label: 'β†’ How-To' }, - ] - }, - { - id: 'system', - title: 'βš™οΈ System', - items: [ - { id: 'agents', label: 'Agents' }, - { id: 'agents-how', label: 'β†’ How-To' }, - { id: 'users', label: 'Users' }, - { id: 'users-how', label: 'β†’ How-To' }, - { id: 'system-config', label: 'System Config' }, - { id: 'system-config-how', label: 'β†’ How-To' }, - { id: 'settings', label: 'Settings' }, - { id: 'settings-how', label: 'β†’ How-To' }, - ] - }, - { - id: 'enhanced', - title: '✨ Enhanced Features', - items: [ - { id: 'excess-baggage', label: 'Excess Baggage' }, - { id: 'excess-baggage-how', label: 'β†’ How-To' }, - { id: 'packages', label: 'Travel Packages' }, - { id: 'packages-how', label: 'β†’ How-To' }, - { id: 'package-inquiries', label: 'Package Inquiries' }, - { id: 'package-inquiries-how', label: 'β†’ How-To' }, - { id: 'health', label: 'Health Monitoring' }, - { id: 'health-how', label: 'β†’ How-To' }, - { id: 'boarding', label: 'Boarding Management' }, - { id: 'boarding-how', label: 'β†’ How-To' }, - { id: 'fare-config', label: 'Advanced Fare Config' }, - { id: 'fare-config-how', label: 'β†’ How-To' }, - { id: 'payment-methods', label: 'Payment Methods' }, - { id: 'payment-methods-how', label: 'β†’ How-To' }, - ] - }, - ]; - - const HowToStep = ({ number, title, children }: { number: number; title: string; children: React.ReactNode }) => ( -
-
-
{number}
-
-

{title}

- {children} -
-
-
- ); - return (
+ {/* Top bar */}
- -

Documentation

+ +

Documentation

- - - View API Docs + + API Docs - - - Dashboard + + Dashboard
@@ -197,19 +52,25 @@ const DocPage = () => {
+ + {/* Sidebar nav */}
-
+
-
-
-

Β© 2026 Ethio-Djibouti Railway | Passenger Backoffice Documentation v1.0.0

+
+
+ Β© 2026 Ethio-Djibouti Railway Β· Passenger Backoffice Documentation v1.0.0
); -}; - -export default DocPage; \ No newline at end of file +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/AnalyticsSection.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/AnalyticsSection.tsx new file mode 100644 index 000000000..ab1bf40fc --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/AnalyticsSection.tsx @@ -0,0 +1,39 @@ +import { HowToStep } from './_shared'; + +const li = 'text-sm text-slate-700 dark:text-slate-300'; +const ol = 'list-decimal pl-5 space-y-1 ' + li; + +export default function AnalyticsSection() { + return ( + <> +
+

πŸ“ˆ Reports

+

Generate revenue, occupancy, agent performance, and passenger analytics reports with custom date ranges. Access level: Supervisor, Admin.

+
+ {[ + ['Revenue', 'Total, by route, by class, by payment method'], + ['Occupancy', 'Seat utilisation %, peak/off-peak analysis'], + ['Agent Performance', 'Counter bookings, commission, ranking'], + ['Passenger Analytics', 'New vs repeat, loyalty stats, regional split'], + ].map(([t, d]) => ( +
+
{t}
+
{d}
+
+ ))} +
+
+
+

πŸ“ˆ How-To: Generate Reports

+
+ +
  1. Click Reports in Analytics & Reports
  2. Select report type, set date range, apply optional route/agent filters
  3. Choose group-by: Day / Week / Month / Year
  4. Click Generate Report
+
+ +
  1. Download as PDF, Excel, or CSV
  2. Click Save Report to store config for one-click re-runs
+
+
+
+ + ); +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/CustomerServicesSection.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/CustomerServicesSection.tsx new file mode 100644 index 000000000..e18bdc8ac --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/CustomerServicesSection.tsx @@ -0,0 +1,59 @@ +import { HowToStep } from './_shared'; + +const li = 'text-sm text-slate-700 dark:text-slate-300'; +const ol = 'list-decimal pl-5 space-y-1 ' + li; + +export default function CustomerServicesSection() { + return ( + <> +
+

πŸ† Loyalty Program

+

View and manage passenger loyalty accounts, tiers, points, and rewards. Access level: Agent, Supervisor, Admin.

+
+ + {['Tier','Points','Bonus'].map(h => )} + + + + + + +
{h}
BRONZE0–999Standard
SILVER1,000–2,999+5%
GOLD3,000–4,999+10%
PLATINUM5,000++15% + Priority
+
+
+
+

πŸ† How-To: Manage Loyalty

+
+ +
  1. Click Loyalty Program in Customer Services
  2. Search by name/email; filter by tier
+
+ +
  1. Click Adjust Points on an account
  2. Enter amount, select reason (Bonus / Correction / Promotion), click Apply
+
+ +
  1. Click Grant Reward, select from catalog, specify quantity
  2. Confirmation email sent to passenger automatically
+
+
+
+ +
+

πŸ”” Notifications

+

View logs, manage templates, and send manual notifications via Email, SMS, or Push. Access level: Supervisor, Admin.

+
+
+

πŸ”” How-To: Manage Notifications

+
+ +
  1. Click Notifications in Customer Services
  2. Filter by recipient, channel, status, or date; click Retry on failures (max 3)
+
+ +
  1. Click Send Notification
  2. Select recipients, choose template or custom message, pick channels
  3. Preview then Send
+
+ +
  1. Open Templates tab; click a template to edit
  2. Use placeholders: {'{{name}}'} {'{{bookingRef}}'}
  3. Click Add Template to create new ones
+
+
+
+ + ); +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/FinancialSection.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/FinancialSection.tsx new file mode 100644 index 000000000..7ee860bb2 --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/FinancialSection.tsx @@ -0,0 +1,152 @@ +import { HowToStep } from './_shared'; + +const li = 'text-sm text-slate-700 dark:text-slate-300'; +const ol = 'list-decimal pl-5 space-y-1 ' + li; + +export default function FinancialSection() { + return ( + <> + {/* PRICING */} +
+

πŸ’² Pricing & Fares

+

View dynamically calculated fares per schedule and seat class. Fare = Base + Premium + Insurance. ADULT pays 100%; first CHILD free, subsequent CHILD 100%. Access level: Admin, Supervisor.

+
+
+

πŸ’² How-To: View Schedule Fares

+
+ +
  1. Click Pricing & Fares in Financial
  2. Choose a schedule from the dropdown
  3. Table shows calculated fares per seat class and passenger type
+
+
+
+ + {/* TARIFF RATES */} +
+

πŸ“Š Tariff Rates

+

Manage base per-km tariff rates used to calculate fares across routes and seat classes. Access level: Admin.

+
+
+

πŸ“Š How-To: Manage Tariff Rates

+
+ +
  1. Click Tariff Rates in Financial
  2. Click Add Rate β€” set seat class, rate per km (ETB), passenger type, nationality, validity dates
  3. Click Edit on existing rows to update; changes apply to new bookings only
+
+
+
+ + {/* FARE RULES */} +
+

πŸ“ Fare Rules

+

Override or extend fares with schedule-specific or segment-specific rules, including nationality and passenger-type filters. Access level: Admin, Supervisor.

+
+ Priority: Segment (nationality) β†’ Segment (generic) β†’ Schedule (nationality) β†’ Schedule (generic) β†’ Default class fare +
+
+
+

πŸ“ How-To: Manage Fare Rules

+
+ +
  1. Click Fare Rules in Financial β†’ Schedule Fares tab
  2. Click Add Fare Rule: select schedule, seat class, fare (ETB), passenger type, nationality, validity dates
+
+ +
  1. Switch to Segment Fares tab
  2. Select route, then origin and destination stations
  3. Set seat class, fare, passenger type, nationality, validity dates
  4. Destination must be after origin on the route
+
+ +
  1. Click Edit to update amount or dates
  2. Click Delete β€” removed immediately for new bookings
+
+
+
+ + {/* PAYMENTS */} +
+

πŸ’³ Payments

+

Monitor transactions across all providers and process refunds. Providers: Telebirr Β· CBE Birr Β· eBirr Β· Card Β· Wallet Β· WAAFI. Access level: Supervisor, Admin.

+
+
+

πŸ’³ How-To: Manage Payments

+
+ +
  1. Click Payments in Financial
  2. Search by booking reference or transaction ID
  3. Filter by status (Succeeded Β· Failed Β· Processing Β· Refunded) or provider
+
+ +
  1. Click Process Refund on a completed payment
  2. Enter amount, select reason, add notes
  3. Confirm β€” refund status: Pending β†’ Processing β†’ Completed
+
+
+
+ + {/* CURRENCIES */} +
+

πŸ’± Currencies

+

Manage ETB→DJF and ETB→USD exchange rates used for display conversion. ETB is the transaction currency. Access level: Admin.

+
+ + {['From','To','Rate','Example (3500 ETB)'].map(h=>)} + + + + +
{h}
ETBDJF3.2511,375 DJF
ETBUSD0.01863 USD
+
+
+
+

πŸ’± How-To: Manage Exchange Rates

+
+ +
  1. Click Currencies in Financial
  2. Click Add Currency Rate: from/to currency, rate value, effective date
  3. Click Edit on existing rows to update; applies to future bookings/display
+
+
+
+ + {/* PROMOS */} +
+

🎁 Promo Codes

+

Create percentage or fixed-amount discount codes with expiry dates. Access level: Admin, Supervisor.

+
+
+

🎁 How-To: Manage Promo Codes

+
+ +
  1. Click Add Promo Code
  2. Fill: code (uppercase), title, discount type (Percentage / Amount), value, valid until date
  3. Toggle active and save
+
+ +
  1. Click Edit to update value, dates, or active status
  2. Click Delete β€” already-applied bookings keep their discount
+
+
+
+ + {/* PAYMENT METHODS */} +
+

πŸ”Œ Payment Methods

+

Configure API credentials, fees, and enable/disable payment providers. Access level: Admin.

+
+
+

πŸ”Œ How-To: Configure Payment Methods

+
+ +
  1. Click Payment Methods in Financial
  2. Select a provider (Telebirr, CBE Birr, eBirr, Card, WAAFI)
  3. Enter base URL, API key/secret, merchant ID, webhook endpoint
  4. Set transaction fees, min/max amounts, enable/disable toggle
+
+ +
  1. Run a test transaction to verify connectivity
  2. Validate webhook endpoint accessibility and security secret
+
+
+
+ + {/* WALLET ACCOUNTS */} +
+

πŸ‘› Wallet Accounts

+

View and manage passenger EDR wallet balances and transaction ledgers. Access level: Supervisor, Admin.

+
+
+

πŸ‘› How-To: Manage Wallet Accounts

+
+ +
  1. Click Wallet Accounts in Financial
  2. Search by passenger name or email
  3. View current balance (ETB minor units) and last activity
+
+ +
  1. Click a wallet row to open the transaction ledger
  2. See all credits, debits, top-ups, and refunds with timestamps
+
+
+
+ + ); +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/MasterDataSection.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/MasterDataSection.tsx new file mode 100644 index 000000000..877f54c5d --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/MasterDataSection.tsx @@ -0,0 +1,142 @@ +import { HowToStep } from './_shared'; + +const li = 'text-sm text-slate-700 dark:text-slate-300'; +const ol = 'list-decimal pl-5 space-y-1 ' + li; + +export default function MasterDataSection() { + return ( + <> + {/* STATIONS */} +
+

πŸ“ Stations

+

Configure railway stations with code, city, country, coordinates, and operational status. Access level: Supervisor, Admin.

+
+
+

πŸ“ How-To: Manage Stations

+
+ +
  1. Click Add Station
  2. Fill: 3-letter code (e.g. ADD), name, city, country code, lat/lng, timezone
  3. Toggle operational status and save
+
+ +
  1. Click Edit on any row to update fields
  2. Click Delete β€” system warns if routes or schedules depend on this station
+
+
+
+ + {/* TRAINS */} +
+

πŸš‚ Trains

+

Manage the train fleet β€” number, name, operator, status, and attached coaches. Access level: Supervisor, Admin.

+
+
+

πŸš‚ How-To: Manage Trains

+
+ +
  1. Click Add Train
  2. Fill: unique number, name, operator, description, status
  3. Save, then assign coaches
+
+ +
  1. Click Edit to update details or change status
  2. Delete only if no active schedules reference this train
+
+
+
+ + {/* COACHES */} +
+

πŸšƒ Coaches

+

Manage coach inventory, seat layout, type, and maintenance status. Access level: Supervisor, Admin.

+
+
+

πŸšƒ How-To: Manage Coaches

+
+ +
  1. Click Add Coach
  2. Fill: number, coach type, arrangement (e.g. 2+2), capacity, status
  3. Auto-generate seats from arrangement or configure manually
+
+ +
  1. Update arrangement (limited if seats are occupied)
  2. Delete only if no scheduled trips use this coach
+
+
+
+ + {/* SEATS */} +
+

πŸ’Ί Seats

+

View seat maps, update properties, block/unblock seats, and bulk import/export via CSV. Access level: Supervisor, Admin.

+
+
+

πŸ’Ί How-To: Manage Seats

+
+ +
  1. Select a coach from the dropdown
  2. Color-coded grid: Green=Available Β· Yellow=Held Β· Blue=Booked Β· Red=Blocked
+
+ +
  1. Click a seat β†’ Block with reason (Maintenance, Reserved, Damaged)
  2. Optionally set an expiry date; click Unblock to release
+
+ +
  1. Select multiple seats via checkboxes for bulk status changes
  2. Use CSV Import to create/update seats in bulk; CSV Export for backup
+
+
+
+ + {/* CLASSES */} +
+

🏷️ Seat Classes

+

Define seat class types with base fare, premium fee, and insurance fee. Access level: Supervisor, Admin.

+
+ + {['Class','Base Fare','Premium','Insurance','Total/Adult'].map(h=>)} + + + + + +
{h}
Economy Regular350 ETB0 ETB5 ETB355 ETB
Economy Bed490 ETB50 ETB10 ETB550 ETB
VIP Bed630 ETB150 ETB15 ETB795 ETB
+
+
+
+

🏷️ How-To: Manage Seat Classes

+
+ +
  1. Click Add Class
  2. Fill: name, coach type, base fare (ETB), premium fee, insurance fee
  3. Toggle active and save β€” changes apply to new bookings only
+
+
+
+ + {/* ROUTES */} +
+

πŸ—ΊοΈ Routes

+

Define routes as ordered station sequences with cumulative distances. Access level: Supervisor, Admin.

+
+
+

πŸ—ΊοΈ How-To: Manage Routes

+
+ +
  1. Click Add Route
  2. Fill: code (e.g. ADD-DJI), name, effective dates, active status
  3. Add stops: select station, enter distance from previous stop
+
+ +
  1. Reorder stops via drag-and-drop; update distances
  2. Remove stops only if no bookings exist on that segment
+
+
+
+ + {/* SCHEDULES */} +
+

πŸ“… Schedules

+

Create individual or bulk-generated trip schedules with coach assignments. Access level: Supervisor, Admin.

+
+
+

πŸ“… How-To: Manage Schedules

+
+ +
  1. Click Create Schedule
  2. Select train, route, departure/arrival date-time
  3. Assign coaches (order matters for position numbers)
+
+ +
  1. Click Bulk Generate
  2. Set train, route, start date/time, duration (hrs), repeat interval (days), and period (days)
  3. Preview count then click Generate Schedules
+
+ +
  1. Edit departure/arrival times, status, or coach assignments
  2. Delete cascades to seat holds and live status records
  3. Bulk-select rows for multi-delete
+
+
+
+ + ); +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/OperationsSection.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/OperationsSection.tsx new file mode 100644 index 000000000..7c14cc357 --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/OperationsSection.tsx @@ -0,0 +1,106 @@ +import { HowToStep } from './_shared'; + +const li = 'text-sm text-slate-700 dark:text-slate-300'; +const ol = 'list-decimal pl-5 space-y-1 ' + li; + +export default function OperationsSection() { + return ( + <> + {/* BOOKINGS */} +
+

πŸ“‹ Bookings

+

View, search, cancel, and delete passenger bookings. Access level: Agent, Supervisor, Admin.

+
+
+

πŸ“‹ How-To: Manage Bookings

+
+ +
  1. Click Bookings in Operations
  2. Use search box for reference, email, or phone
  3. Filter by status: Pending Β· Confirmed Β· Cancelled Β· Completed
+
+ +
  1. Click View Details to open booking modal
  2. See passenger info, journey, payment, and booking source
+
+ +
  1. Click Cancel Booking β€” auto-processes refund (80% confirmed, 0% pending)
  2. Click Delete to permanently remove and release seats
+
+
+
+ + {/* PASSENGERS */} +
+

πŸ‘₯ Passengers

+

View passenger profiles, verification status, loyalty tier, and wallet balance. Access level: Agent, Supervisor, Admin.

+
+
+

πŸ‘₯ How-To: Manage Passengers

+
+ +
  1. Click Passengers in Operations
  2. Search by name, email, phone, or ID
  3. Filter by nationality, Verifayda status, or loyalty tier
+
+ +
  1. Click a passenger row to open profile modal
  2. Review account info, verification status, loyalty points, wallet balance, and booking history
+
+
+
+ + {/* TICKETS */} +
+

🎫 Tickets

+

View issued tickets, QR/barcode status, and gate validation logs. Access level: Supervisor, Admin.

+
+
+

🎫 How-To: Manage Tickets

+
+ +
  1. Click Tickets in Operations
  2. Search by booking reference or passenger name
  3. Filter by status: Confirmed Β· Validated Β· Cancelled
+
+ +
  1. Click View to see QR/barcode, seat, and fare breakdown
  2. Download PDF or resend to passenger email
+
+ +
  1. Unvalidated: not yet scanned at gate
  2. Validated: scanned and approved for boarding
  3. View gate validation logs with timestamp and validator ID
+
+
+
+ + {/* BOARDING */} +
+

πŸš† Boarding

+

Manage gate operations and real-time passenger boarding for active trips. Access level: Agent, Supervisor, Admin.

+
+
+

πŸš† How-To: Manage Boarding

+
+ +
  1. Click Boarding in Operations
  2. Select the active trip/schedule
  3. View real-time passenger count and progress
+
+ +
  1. Scan or validate tickets at gate
  2. Resolve seat conflicts or duplicate assignments
  3. Mark no-shows and process late arrivals
+
+
+
+ + {/* EXCESS BAGGAGE */} +
+

πŸ“¦ Luggage (Excess Baggage)

+

Handle excess baggage charges at boarding β€” passenger self-pay or agent cash collection. Access level: Agent, Supervisor, Admin.

+
+ {['PENDING','PAID','CASH_COLLECTED','EXPIRED','WAIVED'].map(s => ( + {s} + ))} +
+
+
+

πŸ“¦ How-To: Handle Excess Baggage

+
+ +
  1. Click Luggage in Operations
  2. Search by booking reference; filter by status or date
+
+ +
  1. Resend Link β€” sends fresh 5-min payment link to passenger
  2. Waive β€” enter reason (supervisor authority); logged for audit
  3. Delete β€” only for EXPIRED or WAIVED charges
+
+
+
+ + ); +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/OverviewSection.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/OverviewSection.tsx new file mode 100644 index 000000000..10b011718 --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/OverviewSection.tsx @@ -0,0 +1,43 @@ +export default function OverviewSection() { + return ( + <> +
+

Welcome to EDR Passenger Backoffice

+

+ Comprehensive management system for the Ethio-Djibouti Railway passenger platform. Covers bookings, fleet, financials, security, and analytics for agents, supervisors, and admins. +

+
+

βœ… Version 1.0.0 β€” Complete Platform

+
    +
  • β€’ Roles: AGENT Β· SUPERVISOR Β· ADMIN Β· STAFF
  • +
  • β€’ Auth: Corporate IAM (back-office) + JWT (passenger-facing)
  • +
  • β€’ Currencies: ETB (transaction) Β· DJF Β· USD (display)
  • +
  • β€’ Age pricing: ADULT β‰₯5 yrs full fare Β· CHILD <5 yrs first free
  • +
  • β€’ ID verification: Verifayda 2.0 for Ethiopian nationals
  • +
+
+
+ +
+

🌟 Key Features

+
+ {[ + ['πŸ“Š Operations', 'Bookings, passengers, tickets, boarding, excess baggage'], + ['πŸŽ’ Tourism', 'Travel packages with tiered pricing and inquiry management'], + ['🏒 Master Data', 'Stations, trains, coaches, seats, classes, routes, schedules'], + ['πŸ’° Financial', 'Fares, tariffs, payments, currencies, promos, wallets'], + ['🎁 Customer Services', 'Loyalty program and notification management'], + ['πŸ”’ Security', 'Audit logs and fraud detection'], + ['πŸ“ˆ Analytics', 'Revenue, occupancy, and agent performance reports'], + ['βš™οΈ System', 'Agents, users, settings, health monitoring, app releases'], + ].map(([title, desc]) => ( +
+
{title}
+
{desc}
+
+ ))} +
+
+ + ); +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/SecuritySection.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/SecuritySection.tsx new file mode 100644 index 000000000..97507752d --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/SecuritySection.tsx @@ -0,0 +1,53 @@ +import { HowToStep } from './_shared'; + +const li = 'text-sm text-slate-700 dark:text-slate-300'; +const ol = 'list-decimal pl-5 space-y-1 ' + li; + +export default function SecuritySection() { + return ( + <> +
+

πŸ“‹ Audit Logs

+

Immutable log of all user actions β€” creates, updates, deletes, payments, cancellations, and auth events. Access level: Supervisor, Admin.

+
+
+

πŸ“‹ How-To: Use Audit Logs

+
+ +
  1. Click Audit Logs in Security & Compliance
  2. Filter by user, action type (Create / Update / Delete), entity type, or date range
+
+ +
  1. Click a log entry to open the detail modal
  2. Side-by-side old vs new values with highlighted changed fields
  3. Includes IP address and user-agent
+
+ +
  1. Click Export β€” choose CSV, JSON, or PDF
  2. Apply current filters before exporting for targeted compliance reports
  3. Logs retained 12 months active, 7 years archived
+
+
+
+ +
+

πŸ›‘οΈ Fraud Detection

+

Monitor fraud alerts triggered by rules (rapid bookings, high-value transactions, failed payments, duplicate IDs). Access level: Supervisor, Admin.

+
+ {[['LOW','bg-yellow-100 text-yellow-800'],['MEDIUM','bg-orange-100 text-orange-800'],['HIGH','bg-red-100 text-red-800']].map(([s, cls]) => ( + {s} + ))} +
+
+
+

πŸ›‘οΈ How-To: Manage Fraud Alerts

+
+ +
  1. Click Fraud Detection in Security & Compliance
  2. Filter by severity or status (Open / Acknowledged / Resolved)
  3. Click an alert to see full context, triggering rules, and risk score
+
+ +
  1. Allow β€” booking proceeds; logged for audit
  2. Block User β€” set duration and reason; user cannot book during block period
  3. Escalate to Admin β€” adds to priority review queue
+
+ +
  1. Open Rules tab to view all active detection rules
  2. Click a rule to adjust threshold values or toggle active/inactive
+
+
+
+ + ); +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/SystemSection.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/SystemSection.tsx new file mode 100644 index 000000000..4c73a8d89 --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/SystemSection.tsx @@ -0,0 +1,98 @@ +import { HowToStep } from './_shared'; + +const li = 'text-sm text-slate-700 dark:text-slate-300'; +const ol = 'list-decimal pl-5 space-y-1 ' + li; + +export default function SystemSection() { + return ( + <> + {/* AGENTS */} +
+

πŸ§‘β€πŸ’Ό Agents

+

Counter booking, shift management, commission tracking, and daily reconciliation. Access level: Supervisor, Admin.

+
+
+

πŸ§‘β€πŸ’Ό How-To: Agent Operations

+
+ +
  1. Click Agents in System β†’ New Booking
  2. Select schedule, seats, passengers, and seat class
  3. Choose payment method (Cash / Card / Check); enter amount received
  4. Click Create Booking β€” prints or emails ticket
+
+ +
  1. Open Shift β€” enter opening cash balance
  2. Close Shift β€” enter closing balance; system calculates variance
  3. View shift summary: total bookings, revenue, commission earned
+
+
+
+ + {/* USERS */} +
+

πŸ‘€ Users

+

Manage back-office user accounts and role assignments. Roles: AGENT Β· SUPERVISOR Β· ADMIN Β· STAFF. Access level: Admin.

+
+
+

πŸ‘€ How-To: Manage Users

+
+ +
  1. Click Users in System β†’ Add User
  2. Fill: email, full name, phone, role, department
  3. Save β€” temporary password emailed to user automatically
+
+ +
  1. Click a user row to open profile modal
  2. Update name, role, or department; toggle active status
  3. Click Reset Password to generate and email a new temporary password
+
+ +
  1. Deactivate β€” keeps records, disables login (preferred)
  2. Delete β€” permanently removes user
+
+
+
+ + {/* SETTINGS */} +
+

βš™οΈ Settings

+

Configure application-wide settings: general, email (SMTP), payment provider credentials, API integrations, and rate limits. Access level: Admin.

+
+
+

βš™οΈ How-To: Manage Settings

+
+ +
  1. Click Settings in System
  2. Select category tab: General Β· Email Β· Payments Β· API
  3. Modify values, test connections where applicable, then Save
  4. Changes take effect immediately and are audit-logged
+
+ +
  1. Auth endpoints default: 5 req/min
  2. Strict endpoints (bookings, payments, wallet) default: 20 req/min
  3. Default endpoints: 100 req/min Β· Health/webhooks: exempt
  4. Seat hold duration default: 5 min Β· Hold cutoff before departure: 2 hrs
+
+
+
+ + {/* HEALTH */} +
+

πŸ₯ Health

+

Real-time API health dashboard β€” liveness, readiness (DB latency), and app info. Auto-refreshes every 30–60 s. Access level: Admin, Supervisor.

+
+
+

πŸ₯ How-To: Monitor Health

+
+ +
  1. Click Health in System
  2. Green banner = all systems operational; Red = degraded
  3. Liveness probe: API process alive (30 s) Β· Readiness: DB ping + latency (30 s) Β· App Info: version, uptime (60 s)
+
+ +
  1. Red readiness: check DB server and connection string
  2. High latency: review slow queries and server resources
  3. Click Refresh for an immediate manual check
+
+
+
+ + {/* APP RELEASES */} +
+

πŸ“± App Releases

+

Manage mobile app release notes and version announcements shown to passengers. Access level: Admin.

+
+
+

πŸ“± How-To: Manage App Releases

+
+ +
  1. Click App Releases in System β†’ New Release
  2. Fill: version number, platform (iOS / Android / Both), release notes, release date
  3. Toggle Force Update if the release is mandatory
  4. Save to publish the announcement
+
+ +
  1. Click Edit to update notes or toggle force-update flag
  2. Click Delete to remove an outdated release entry
+
+
+
+ + ); +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/TourismSection.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/TourismSection.tsx new file mode 100644 index 000000000..415fa5d1d --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/TourismSection.tsx @@ -0,0 +1,83 @@ +import { HowToStep } from './_shared'; + +const li = 'text-sm text-slate-700 dark:text-slate-300'; +const ol = 'list-decimal pl-5 space-y-1 ' + li; + +export default function TourismSection() { + return ( + <> + {/* PACKAGES */} +
+

πŸŽ’ Travel Packages

+

Create and manage pilgrimage/group travel packages with tiered pricing and capacity control. Access level: Supervisor, Admin.

+
+ {['DRAFT','ACTIVE','SOLD_OUT','EXPIRED','CANCELLED'].map(s => ( + {s} + ))} +
+
+
+

πŸŽ’ How-To: Manage Travel Packages

+
+ +
    +
  1. Click New Package
  2. +
  3. Fill: code, name, origin/destination stations, outbound/return schedules
  4. +
  5. Set total capacity, validity period, included services, and optional bus transfer
  6. +
  7. Save β€” package starts in DRAFT status
  8. +
+
+ +
    +
  1. Click Tiers on the package row
  2. +
  3. Add tiers: seat type, label, price (minor units), available seats
  4. +
  5. Edit or delete tiers (restricted once bookings exist)
  6. +
+
+ +
    +
  1. Click Activate on a DRAFT package to open for booking
  2. +
  3. Click Deactivate to stop new bookings (existing bookings remain valid)
  4. +
  5. Click Delete only if no bookings exist
  6. +
+
+
+
+ + {/* PACKAGE INQUIRIES */} +
+

πŸ“ Package Inquiries

+

Track and convert incoming package booking inquiries. Access level: Agent, Supervisor, Admin.

+
+ {['NEW','CONTACTED','CONVERTED','CLOSED'].map(s => ( + {s} + ))} +
+
+
+

πŸ“ How-To: Handle Inquiries

+
+ +
    +
  1. Click Inquiries in Tourism
  2. +
  3. Filter by package or status
  4. +
  5. View contact details, requested tier, and traveler count
  6. +
+
+ +
    +
  1. Use the status dropdown on each row β€” saves immediately
  2. +
  3. Workflow: NEW β†’ CONTACTED β†’ CONVERTED / CLOSED
  4. +
  5. Respond to NEW inquiries within 24 hours
  6. +
+
+ +
    +
  1. Click Delete to remove spam or duplicate inquiries
  2. +
+
+
+
+ + ); +} diff --git a/apps/edr-passenger-web/backoffice/src/app/docs/sections/_shared.tsx b/apps/edr-passenger-web/backoffice/src/app/docs/sections/_shared.tsx new file mode 100644 index 000000000..aa7051063 --- /dev/null +++ b/apps/edr-passenger-web/backoffice/src/app/docs/sections/_shared.tsx @@ -0,0 +1,95 @@ +import React from 'react'; + +export const HowToStep = ({ number, title, children }: { number: number; title: string; children: React.ReactNode }) => ( +
+
+
{number}
+
+

{title}

+ {children} +
+
+
+); + +export const navSections = [ + { + id: 'overview', title: 'πŸ“‹ Overview', + items: [ + { id: 'about', label: 'Application Overview' }, + { id: 'features', label: 'Key Features' }, + ], + }, + { + id: 'operations', title: 'πŸ“Š Operations', + items: [ + { id: 'bookings', label: 'Bookings' }, { id: 'bookings-how', label: 'β†’ How-To' }, + { id: 'passengers', label: 'Passengers' }, { id: 'passengers-how', label: 'β†’ How-To' }, + { id: 'tickets', label: 'Tickets' }, { id: 'tickets-how', label: 'β†’ How-To' }, + { id: 'boarding', label: 'Boarding' }, { id: 'boarding-how', label: 'β†’ How-To' }, + { id: 'excess-baggage', label: 'Luggage (Excess)' }, { id: 'excess-baggage-how', label: 'β†’ How-To' }, + ], + }, + { + id: 'tourism', title: 'πŸŽ’ Tourism', + items: [ + { id: 'packages', label: 'Travel Packages' }, { id: 'packages-how', label: 'β†’ How-To' }, + { id: 'package-inquiries', label: 'Inquiries' }, { id: 'package-inquiries-how', label: 'β†’ How-To' }, + ], + }, + { + id: 'masterdata', title: '🏒 Master Data', + items: [ + { id: 'stations', label: 'Stations' }, { id: 'stations-how', label: 'β†’ How-To' }, + { id: 'trains', label: 'Trains' }, { id: 'trains-how', label: 'β†’ How-To' }, + { id: 'coaches', label: 'Coaches' }, { id: 'coaches-how', label: 'β†’ How-To' }, + { id: 'seats', label: 'Seats' }, { id: 'seats-how', label: 'β†’ How-To' }, + { id: 'classes', label: 'Seat Classes' }, { id: 'classes-how', label: 'β†’ How-To' }, + { id: 'routes', label: 'Routes' }, { id: 'routes-how', label: 'β†’ How-To' }, + { id: 'schedules', label: 'Schedules' }, { id: 'schedules-how', label: 'β†’ How-To' }, + ], + }, + { + id: 'financial', title: 'πŸ’° Financial', + items: [ + { id: 'pricing', label: 'Pricing & Fares' }, { id: 'pricing-how', label: 'β†’ How-To' }, + { id: 'tariff-rates', label: 'Tariff Rates' }, { id: 'tariff-rates-how', label: 'β†’ How-To' }, + { id: 'fare-rules', label: 'Fare Rules' }, { id: 'fare-rules-how', label: 'β†’ How-To' }, + { id: 'payments', label: 'Payments' }, { id: 'payments-how', label: 'β†’ How-To' }, + { id: 'currencies', label: 'Currencies' }, { id: 'currencies-how', label: 'β†’ How-To' }, + { id: 'promos', label: 'Promo Codes' }, { id: 'promos-how', label: 'β†’ How-To' }, + { id: 'payment-methods', label: 'Payment Methods' }, { id: 'payment-methods-how', label: 'β†’ How-To' }, + { id: 'wallet-accounts', label: 'Wallet Accounts' }, { id: 'wallet-accounts-how', label: 'β†’ How-To' }, + ], + }, + { + id: 'services', title: '🎁 Customer Services', + items: [ + { id: 'loyalty', label: 'Loyalty Program' }, { id: 'loyalty-how', label: 'β†’ How-To' }, + { id: 'notifications', label: 'Notifications' }, { id: 'notifications-how', label: 'β†’ How-To' }, + ], + }, + { + id: 'security', title: 'πŸ”’ Security', + items: [ + { id: 'audit', label: 'Audit Logs' }, { id: 'audit-how', label: 'β†’ How-To' }, + { id: 'fraud', label: 'Fraud Detection' }, { id: 'fraud-how', label: 'β†’ How-To' }, + ], + }, + { + id: 'analytics', title: 'πŸ“ˆ Analytics', + items: [ + { id: 'reports', label: 'Reports' }, { id: 'reports-how', label: 'β†’ How-To' }, + ], + }, + { + id: 'system', title: 'βš™οΈ System', + items: [ + { id: 'agents', label: 'Agents' }, { id: 'agents-how', label: 'β†’ How-To' }, + { id: 'users', label: 'Users' }, { id: 'users-how', label: 'β†’ How-To' }, + { id: 'settings', label: 'Settings' }, { id: 'settings-how', label: 'β†’ How-To' }, + { id: 'health', label: 'Health' }, { id: 'health-how', label: 'β†’ How-To' }, + { id: 'app-releases', label: 'App Releases' }, { id: 'app-releases-how', label: 'β†’ How-To' }, + ], + }, +];