Pages
Drop Frontend — Pages
All pages are in
src/drop-app/src/app/using Next.js App Router file-based routing.
Page Index
| Route | File | Type | Auth Required | BottomNav |
|---|---|---|---|---|
/ |
page.tsx |
Server | No | No |
/login |
login/page.tsx |
Client | No | No |
/register |
register/page.tsx |
Client | No | No |
/dashboard |
dashboard/page.tsx |
Client | Yes | Yes |
/accounts |
accounts/page.tsx |
Client | Yes | Yes |
/transactions |
transactions/page.tsx |
Client | Yes | Yes |
/scan |
scan/page.tsx |
Client | Yes | Yes |
/send |
send/page.tsx |
Client | Yes | No |
/profile |
profile/page.tsx |
Client | Yes | Yes |
/profile/personal |
profile/personal/page.tsx |
Client | Yes | No |
/profile/security |
profile/security/page.tsx |
Client | Yes | No |
/profile/notifications |
profile/notifications/page.tsx |
Client | Yes | No |
/profile/language |
profile/language/page.tsx |
Client | Yes | No |
/notifications |
notifications/page.tsx |
Client | Yes | Yes |
/cards |
cards/page.tsx |
Client | Yes | No |
/complaints |
complaints/page.tsx |
Client | No | No |
/fees |
fees/page.tsx |
Client | No | No |
/privacy |
privacy/page.tsx |
Client | No | No |
/terms |
terms/page.tsx |
Client | No | No |
/withdrawal |
withdrawal/page.tsx |
Client | No | No |
Page Details
/ — Home / Marketing Page
- File:
app/page.tsx - Type: Server component (no "use client")
- Auth: None
- Components used: DropLogoFull, DropAppIcon, Link, Image, custom icons (IconSendMoney, IconQrScan, IconVirtualCard, IconShield, IconFastTransfer, IconCorridors)
- Data: Static arrays
features(3 items) andstats(3 items) defined inline - Sections:
- Header with DropLogoFull + nav links (Tjenester, Priser, Om oss, Logg inn, Kom i gang)
- Hero with headline, subtext, CTA buttons, phone mockup placeholder
- Features grid (Send penger, Betal med QR, Virtuelt kort)
- Stats bar (0.5% Gebyr, <2t Leveringstid, 30+ Land)
- Trust section (BankID verified, Rask overføring, 30+ land)
- Merchant CTA section
- Footer with ALAI Holding AS credit
/login — Login
- File:
app/login/page.tsx - Type: Client component
- Auth: None (entry point)
- Components used: Image, Link, Button, Mail/Lock/Eye/EyeOff/ArrowRight (lucide)
- State: email, password, showPassword, error, loading
- Data fetching: POST
/api/auth/loginwith{ email, password } - Validation: Email regex
^[^\s@]+@[^\s@]+\.[^\s@]+$, required fields check - On success:
router.push("/dashboard") - Social login buttons: BankID, Vipps (UI only, not functional)
- Dev mode: Shows demo credentials
[email protected] / demo1234
/register — Registration
- File:
app/register/page.tsx - Type: Client component
- Auth: None
- Components used: ArrowLeft/ArrowRight/Check/Eye/EyeOff/Phone/Mail/User/Calendar/Lock (lucide), Button
- State: step (1-4), form fields, otp, pin, errors
- Steps:
- Info — firstName, lastName, email, phone (+47 prefix), dateOfBirth, password
- Verify — 6-digit OTP input (MVP: any 6 digits accepted)
- PIN — 4-digit PIN with custom numpad UI
- Success — Welcome message, redirect to /dashboard
- Validation:
- Age >= 18 (calculated from dateOfBirth)
- XSS protection: names reject
< > " ' & ; ( ) { } [ ] - Password: min 8 chars, must contain letters AND numbers
- Phone: must be 8 digits (Norwegian format)
- Data fetching: POST
/api/auth/register
/dashboard — Main Dashboard
- File:
app/dashboard/page.tsx - Type: Client component
- Auth: Yes (
useAuth()with redirect) - Components used: DropLogo, BottomNav, ScrollArea, Bell/LogOut (lucide)
- State: transactions, loading
- Data fetching: GET
/api/transactions?limit=10 - Interfaces:
Transaction { id, type, status, amount, currency, recipientName, createdAt } - Layout:
- Header: DropLogo + notification bell + logout + avatar initials
- Balance card: primary account balance, formatted NOK
- Action buttons: Send penger (→ /send), Skann QR (→ /scan)
- Recent transactions list in ScrollArea
- BottomNav
/accounts — Bank Accounts
- File:
app/accounts/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: BottomNav, Card, ArrowLeft/Landmark/Plus/ChevronRight (lucide)
- Data: Reads
user.bankAccountsfrom auth hook (no separate fetch) - Layout:
- PSD2/Open Banking info banner (blue)
- Account cards: bankName, masked accountNumber, balance, currency, isPrimary badge
- Total balance summary
- "Legg til bankkonto" button (BankID connection note)
/transactions — Transaction History
- File:
app/transactions/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: BottomNav, Tabs/TabsList/TabsTrigger, ArrowLeft/Clock (lucide)
- State: transactions, filter, loading
- Data fetching: GET
/api/transactions?type={filter}&limit=50 - Filters: Alle (all), Overforinger (remittance), QR-betalinger (qr_payment)
- Grouping:
groupByDate()function groups into: I dag, I gar, Denne uken, Eldre - Display: Amount with +/- prefix and color coding (green for received, red for sent)
/scan — QR Scanner
- File:
app/scan/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: BottomNav, Button, ArrowLeft/Camera/Check/X/Store (lucide)
- State: scanState (scanning | payment | paying | success), scannedMerchant, amount, paymentResult
- Interfaces:
ScannedMerchant { id, name, category },PaymentResult { id, status, amount, fee, merchant } - Flow:
- Scanning — Camera viewfinder UI with scan frame, "Simuler skanning" button (demo)
- Payment — Shows merchant info, amount input, 1% fee calculation
- Paying — Loading spinner
- Success — Confirmation with transaction details
- Data fetching: POST
/api/transactions/qr-paymentwith{ merchantId, amount } - Demo merchant: "Ahmetov Kebab" (id: "merchant_001", category: "Restaurant")
/send — Send Money (Remittance)
- File:
app/send/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: Button, ArrowLeft/ArrowRight/Check/ChevronDown/Globe/User (lucide)
- State: step (1-4), selectedRecipient, amount, recipients, rates, sending, txResult
- Steps:
- Select Recipient — List from GET
/api/recipients, shows name + country flag - Enter Amount — NOK input, real-time conversion with exchange rate, 0.5% fee display
- Review — Summary of recipient, amount, rate, fee, total
- Success — Confirmation with reference number
- Select Recipient — List from GET
- Data fetching:
- GET
/api/recipients(on mount) - GET
/api/rates(on mount) - POST
/api/transactions/remittancewith{ recipientId, amountNOK, targetCurrency }
- GET
- Country flags: RS (Serbia), BA (Bosnia), TR (Turkey), PK (Pakistan), PL (Poland)
- Interface:
TxResult { id, status, amount, fee, rate, recipientName, targetAmount, targetCurrency }
/profile — User Profile
- File:
app/profile/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: BottomNav, ArrowLeft/ChevronRight/LogOut/Settings/Shield/HelpCircle/Bell/CreditCard/Landmark (lucide)
- Data: Reads
userfrom auth hook - Layout:
- User info card with initials avatar (green bg), full name, email
- Menu items: Mine kontoer (→ /accounts), Varsler, Innstillinger, Sikkerhet, Hjelp og stotte
- Logout button with confirmation
- Version: "Drop v0.1.0 · ALAI Holding AS"
/withdrawal — Angrerett (Right of Withdrawal)
- File:
app/withdrawal/page.tsx - Type: Client component
- Auth: No
- Components used: ChevronLeft, RotateCcw, CheckCircle (lucide)
- State: submitted, loading
- Purpose: Norwegian angrerettloven compliance — 14-day right of withdrawal form
- Layout:
- Info section explaining angrerett (right to cancel service agreement within 14 days)
- Warning banner: Angrerett does not apply to completed payment transactions, only to the service agreement itself
- Form with optional reason dropdown (not_needed, alternative, not_satisfied, other) and comment textarea
- Submit button (red) with AML retention notice (data kept for 5 years per hvitvaskingsloven)
- Success screen with confirmation message (14-day processing time)
/complaints — Send Complaint
- File:
app/complaints/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: MessageSquare, CheckCircle, ChevronLeft, ExternalLink (lucide)
- State: submitted, loading, formData (category, subject, description)
- Data fetching: POST
/api/complaintswith{ category, subject, description } - Purpose: Finansavtaleloven §3-53 compliance — formal complaint submission with 15 business day response requirement
- Layout:
- Info text: All complaints taken seriously, up to 15 business days processing time
- Form with required fields:
- Category dropdown: transaction, fees, service, privacy, other
- Subject text input (max 200 chars)
- Description textarea (max 2000 chars)
- Submit button with POST to
/api/complaints - External complaint authority section: Finansklagenemnda (FinKN) contact info with link to finansklagenemnda.no
- Success screen: Complaint received, 15 business day review commitment
/privacy — Privacy Policy
- File:
app/privacy/page.tsx - Type: Client component
- Auth: None
- Components used: ChevronLeft, Shield (lucide)
- Purpose: GDPR-compliant privacy policy page (Norwegian language)
- Sections:
- Behandlingsansvarlig: ALAI Holding AS as data controller
- Hvilke opplysninger vi samler inn: Identification (name, email, phone, BankID), Financial data (bank accounts via Open Banking, transaction history), Technical data (IP, device, app version)
- Formaal med behandlingen: Transaction processing (PSD2/PISP), KYC/AML compliance, AML/terrorism prevention, service improvement
- Rettslig grunnlag: Contract (GDPR 6(1)(b)), Legal obligation (6(1)(c)) for AML/KYC, Legitimate interest (6(1)(f)) for service improvement
- Dine rettigheter: Innsyn (access), Retting (rectification), Sletting (erasure with 5-year AML retention), Dataportabilitet (portability)
- Oppbevaring: Minimum 5 years per hvitvaskingsloven, anonymization on account deletion but AML data retained
- Kontakt: [email protected], complaint to Datatilsynet
/terms — Terms of Service
- File:
app/terms/page.tsx - Type: Client component
- Auth: None
- Components used: ChevronLeft, FileText (lucide)
- Purpose: Legal terms of service (Norwegian language)
- Sections:
- Om tjenesten: Drop as PISP/AISP under PSD2, provided by ALAI Holding AS
- Krav til brukere: 18+ age, Norwegian residency with BankID, KYC required, Norwegian phone (+47)
- Betalingsmodell: Drop never holds customer money, pass-through model via Open Banking
- Gebyrer: All fees shown before transaction confirmation, see fees page for full list
- Ansvar: Drop responsible for correct payment execution per betalingstjenesteloven, refund rights per law, not liable for bank/recipient delays
- Misbruk og sperring: Right to block accounts for suspected AML/fraud, mandatory STR reporting to Økokrim/EFE
- Angrerett: 14-day withdrawal right per angrerettloven (does not apply to completed transactions)
- Tvister: Norwegian law, Oslo tingrett jurisdiction, complaint to Finansklagenemnda
/fees — Fee Overview
- File:
app/fees/page.tsx - Type: Client component
- Auth: None
- Components used: ChevronLeft, Receipt (lucide)
- Purpose: Transparent fee disclosure page (Norwegian language)
- Sections:
- Overføring til utlandet:
- Transaction fee: 1.5% per transfer
- Currency markup: 0.5% on mid-market rate
- Typical total: ~2% (compare with banks at 3-7%)
- QR-betaling i butikk:
- For customer: Free (no charge to payer)
- For merchant: 0.5% (lower than card terminals)
- Kontotjenester:
- Account creation: Free
- Monthly fee: Free
- Bank account linking (AISP): Free
- Viktig informasjon:
- Fees can change with 30-day notice
- Exchange rates updated in real-time from market
- Always see final amount before confirming
- Overføring til utlandet:
/profile/personal — Personal Information
- File:
app/profile/personal/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: ChevronLeft, ShieldCheck (lucide), BottomNav
- State: Reads
userfrom auth hook - Layout:
- User avatar with initials (green gradient)
- Full name and email display
- Read-only form fields: firstName, lastName, email, phone (+47 987 65 432), dateOfBirth (15. mars 1995)
- BankID verification badge (green banner with ShieldCheck icon)
- Note: All fields are disabled (cannot edit) — verified via BankID
/profile/security — Security Settings
- File:
app/profile/security/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: ChevronLeft, ChevronRight, Lock, Smartphone, Laptop (lucide), BottomNav
- Sections:
- Passord: Change password button (shows "Sist endret: Aldri")
- To-faktor autentisering:
- BankID verification: Active (green badge)
- Vipps verification: Not activated (gray badge)
- Aktive enheter:
- iPhone 15 Pro: Oslo, Norge — Aktiv nå (green dot indicator)
- MacBook Pro: Oslo, Norge — I går kl. 18:45
- Footer: Support contact ([email protected])
- Note: UI only, no actual functionality connected
/profile/notifications — Notification Settings
- File:
app/profile/notifications/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: ChevronLeft, Bell, Mail (lucide), BottomNav
- State: pushEnabled, emailEnabled, settingsLoaded
- Data fetching:
- GET
/api/settings(on mount) - PATCH
/api/settingswith{ pushEnabled: boolean }or{ emailEnabled: boolean }(on toggle)
- GET
- Layout:
- Push-varsler toggle switch (Bell icon)
- E-postvarsler toggle switch (Mail icon)
- Behavior: Toggles immediately update state and send PATCH request, revert on failure
/profile/language — Language Settings
- File:
app/profile/language/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: ChevronLeft, Check (lucide), BottomNav
- State: selected, saving
- Data fetching:
- GET
/api/settings(on mount) - PATCH
/api/settingswith{ language: string }(on save)
- GET
- Languages: nb (Norsk Bokmål), en (English), bs (Bosanski), sq (Shqip)
- Layout:
- Language list with radio selection (green checkmark for selected)
- "Lagre" button (green) to save selection
- Behavior: Selection updates local state, user must click "Lagre" to persist
/notifications — Notifications Center
- File:
app/notifications/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Components used: BottomNav, ArrowLeft, Bell, ArrowUpRight, ScanLine, Smartphone, TrendingUp (lucide)
- State: notifications, fetching
- Data fetching:
- GET
/api/notifications(on mount) - PATCH
/api/notificationswith{ notificationIds: [ids] }(mark read, fire-and-forget)
- GET
- Interface:
Notification { id, type, title, body, read, createdAt } - Layout:
- Header with back button + "Varsler" title
- Empty state: Bell icon + "Ingen varsler enna" message
- Grouped notifications: I DAG / I GÅR / date groups
- Notification cards: icon based on type, title, body, timestamp, unread dot indicator
- BottomNav
- Notification types: transaction_complete (green), qr_payment (yellow), security (blue), rate_update (yellow), default (gray)
- Auto-read: Automatically marks all unread notifications as read on page load
- Time formatting: "I dag kl. HH:MM", "I går kl. HH:MM", or "DD.MM.YYYY kl. HH:MM"
/cards — Card Management (FUTURE — feature-flagged)
Note: Cards are a FUTURE feature, gated behind feature flags (all default to
false). Requires a card issuing partner before activation.
- File:
app/cards/page.tsx - Type: Client component
- Auth: Yes (
useAuth()) - Feature flags:
virtualCards(gate),physicalCards,cardPin,spendingLimits— all default tofalse - Components used: Button, Dialog, various lucide icons (CreditCard, Plus, ArrowLeft, Smartphone, Eye, EyeOff, Lock, X, Check, Copy, RefreshCw)
- State: cards, selectedCard, showDetails, showOrderForm, orderForm, loading
- Data fetching:
- GET
/api/cards(list) - POST
/api/cards(create virtual) - POST
/api/cardswith type "physical" + address (order physical) - PATCH
/api/cards/{id}with{status: "frozen" | "active"} - DELETE
/api/cards/{id}
- GET
- Card visual: Green gradient background, masked card number (•••• •••• •••• 4242), expiry, cardholder name