Component Overview
Component Overview (C4 Level 3)
Document: HLD-001
Version: 1.0
Date: 2026-02-21
Author: Frontend Architect (AI Agent)
Status: Draft
Scope: Frontend component architecture for web and mobile applications
1. Purpose
This document provides a C4 Level 3 component view of the Drop frontend, covering both the Next.js web application and the Expo mobile application. It maps the component tree, shared component library, page composition patterns, and design system integration.
2. Web Application Component Architecture
The web application is built with Next.js 1615 (App Router) and React 19, using Tailwind CSS v4 for styling and shadcn/ui (Radix UI primitives) for the component library.
2.1 Component Diagram — Web App Structure
graph TD
subgraph "Next.js 1615 App Router"
RootLayout["RootLayout<br/>(app/layout.tsx)"]
RootLayout --> CookieConsent["CookieConsent"]
RootLayout --> PWARegister["PWARegister"]
subgraph "Public Pages (No Auth)"
Landing["/ Landing<br/>(Server Component)"]
LoginPage["/login LoginPage"]
RegisterPage["/register RegisterPage"]
TermsPage["/terms TermsPage"]
PrivacyPage["/privacy PrivacyPage"]
FeesPage["/fees FeesPage"]
WithdrawalPage["/withdrawal WithdrawalPage"]
end
subgraph "Authenticated Pages (useAuth)"
Dashboard["/dashboard Dashboard"]
SendMoney["/send SendMoney"]
ScanQR["/scan ScanQR"]
Accounts["/accounts BankAccounts"]
Transactions["/transactions TransactionHistory"]
Profile["/profile ProfileHub"]
Notifications["/notifications NotificationCenter"]
Complaints["/complaints ComplaintForm"]
end
subgraph "Profile Sub-Pages"
ProfilePersonal["/profile/personal"]
ProfileSecurity["/profile/security"]
ProfileNotifications["/profile/notifications"]
ProfileLanguage["/profile/language"]
end
subgraph "Feature-Flagged Pages"
Cards["/cards CardManagement<br/>(FUTURE)"]
end
Profile --> ProfilePersonal
Profile --> ProfileSecurity
Profile --> ProfileNotifications
Profile --> ProfileLanguage
end
subgraph "Shared Components"
BottomNav["BottomNav<br/>(5 tabs)"]
DropLogo["DropLogo / DropWordmark /<br/>DropLogoFull / DropAppIcon"]
PrePaymentDisclosure["PrePaymentDisclosure<br/>(PSD2 modal)"]
end
subgraph "shadcn/ui Primitives"
Button["Button"]
Card["Card"]
Dialog["Dialog"]
Tabs["Tabs"]
ScrollArea["ScrollArea"]
Input["Input"]
Select["Select"]
Badge["Badge"]
Skeleton["Skeleton"]
Sheet["Sheet"]
Separator["Separator"]
Avatar["Avatar"]
Alert["Alert"]
Sonner["Sonner (Toast)"]
end
Dashboard --> BottomNav
Dashboard --> DropLogo
Dashboard --> ScrollArea
Transactions --> BottomNav
Transactions --> Tabs
ScanQR --> BottomNav
Accounts --> BottomNav
Accounts --> Card
Profile --> BottomNav
Notifications --> BottomNav
SendMoney --> PrePaymentDisclosure
Landing --> DropLogoFull["DropLogoFull"]
2.2 Page Composition Pattern
Every authenticated page follows a consistent composition:
+----------------------------------+
| Header (back nav + title) |
+----------------------------------+
| |
| Page Content |
| (scrollable area) |
| |
| |
+----------------------------------+
| BottomNav (fixed, 5 tabs) |
+----------------------------------+
BottomNav Tabs (Web):
| Tab |
Label |
Route |
Icon |
| 1 |
Hjem |
/dashboard |
Home (lucide) |
| 2 |
Aktivitet |
/history |
Clock (lucide) |
| 3 |
Skann |
/scan |
IconQrScan (custom) |
| 4 |
Kontoer |
/accounts |
Landmark (lucide) |
| 5 |
Profil |
/profile |
User (lucide) |
3. Mobile Application Component Architecture
The mobile application is built with React Native (Expo SDK) using Expo Router for file-based navigation.
3.1 Component Diagram — Mobile App Structure
graph TD
subgraph "Expo Router (React Native)"
RootStack["Root Stack Layout<br/>(app/_layout.js)"]
subgraph "Auth Screens (No Auth)"
Welcome["index.js<br/>Welcome Screen"]
MobileLogin["login.js<br/>Login Screen"]
MobileRegister["register.js<br/>Registration (2-step)"]
end
subgraph "Tab Navigator (4 tabs)"
TabLayout["(tabs)/_layout.js"]
MobileDashboard["(tabs)/index.js<br/>Dashboard / Home"]
MobileSend["(tabs)/send.js<br/>Send Money"]
MobileScan["(tabs)/scan.js<br/>QR Scanner"]
MobileProfile["(tabs)/profile.js<br/>Profile & Settings"]
end
subgraph "Modal Screens"
MobileHistory["history.js<br/>Transaction History"]
end
RootStack --> Welcome
RootStack --> MobileLogin
RootStack --> MobileRegister
RootStack --> TabLayout
RootStack --> MobileHistory
TabLayout --> MobileDashboard
TabLayout --> MobileSend
TabLayout --> MobileScan
TabLayout --> MobileProfile
end
subgraph "Shared Libraries"
APIClient["lib/api.js<br/>Fetch wrapper + Bearer auth"]
Theme["lib/theme.js<br/>Colors, fonts, spacing"]
end
MobileDashboard --> APIClient
MobileSend --> APIClient
MobileScan --> APIClient
MobileProfile --> APIClient
MobileHistory --> APIClient
Tab Bar (Mobile):
| Tab |
Label |
Icon |
Screen |
| 1 |
Hjem |
House (Unicode) |
Dashboard |
| 2 |
Send |
Arrow (Unicode) |
Send money |
| 3 |
QR |
QR (Unicode) |
QR scanner |
| 4 |
Profil |
Person (Unicode) |
Profile |
4. Shared Component Library
4.1 Custom Drop Components
| Component |
File (Web) |
Mobile Equivalent |
Purpose |
| BottomNav |
components/bottom-nav.tsx |
(tabs)/_layout.js Tab Bar |
Primary navigation |
| DropLogo |
components/drop-logo.tsx |
Inline SVG in Welcome |
Brand mark (green "d" + gold arrow) |
| DropWordmark |
components/drop-logo.tsx |
Fraunces <Text> |
"drop" text in Fraunces font |
| DropLogoFull |
components/drop-logo.tsx |
N/A |
Mark + wordmark combined |
| DropAppIcon |
components/drop-logo.tsx |
N/A |
App launcher icon |
| CookieConsent |
components/cookie-consent.tsx |
N/A (not applicable) |
GDPR consent banner |
| PrePaymentDisclosure |
components/pre-payment-disclosure.tsx |
N/A (inline) |
PSD2 fee disclosure modal |
| PWARegister |
components/pwa-register.tsx |
N/A |
Service Worker registration |
4.2 Custom Icons (drop-icons.tsx)
| Icon |
Usage |
Shared Props |
| IconSendMoney |
Send money action button |
{ size?: number; className?: string } |
| IconQrScan |
QR scan action / BottomNav tab |
Same |
| IconVirtualCard |
Card feature (FUTURE) |
Same |
| IconShield |
Trust/security sections |
Same |
| IconFastTransfer |
Marketing feature highlight |
Same |
| IconCorridors |
Corridor/globe feature |
Same |
4.3 shadcn/ui Components (Web Only)
All shadcn/ui components live in components/ui/ and are built on Radix UI primitives with Tailwind styling via CSS variables in globals.css.
| Component |
Radix Primitive |
Used By |
| Button |
@radix-ui/react-slot |
All pages |
| Card |
div-based |
Accounts, Dashboard |
| Dialog |
@radix-ui/react-dialog |
CookieConsent, Cards |
| Tabs |
@radix-ui/react-tabs |
Transactions |
| ScrollArea |
@radix-ui/react-scroll-area |
Dashboard |
| Input |
native input |
Login, Register, Send |
| Select |
@radix-ui/react-select |
Complaints, Settings |
| Badge |
cva variants |
Accounts, Profile |
| Skeleton |
div + pulse animation |
Loading states |
| Sheet |
@radix-ui/react-dialog |
Side panels |
| Separator |
@radix-ui/react-separator |
Profile sections |
| Avatar |
@radix-ui/react-avatar |
Profile, Dashboard |
| Alert |
div-based |
Accounts (PSD2 banner) |
| Sonner |
sonner library |
Toast notifications |
5. Design System Integration
5.1 Design Token Reference
Colors
| Token |
Hex |
Usage |
| Primary Green |
#0B6E35 |
Buttons, active states, BottomNav active |
| Primary Green Dark |
#095C2C |
Hover/pressed states |
| Primary Green Light |
#E8F5E9 |
Light backgrounds |
| Gold Accent |
#D4A017 |
Logo accent, QR scanner brackets, pending status |
| Text Primary |
#1A1A1A (web) / #1E293B |
Headings, body text |
| Text Secondary |
#6B7280 (mobile) / #64748B (web) |
Descriptions, labels |
| Text Muted |
#9CA3AF (mobile) / #94A3B8 (web) |
Timestamps, hints |
| Background |
#FAFCF8 (mobile) / #F8FAFC (web) |
Page backgrounds |
| Card |
#FFFFFF |
Card surfaces |
| Border |
#E5E7EB (mobile) / #E2E8F0 (web) |
Dividers, input borders |
| Error |
#EF4444 |
Error states |
| Success |
#10B981 |
Success indicators |
Typography
| Role |
Web |
Mobile |
| Display / Headings |
Fraunces (via CSS) |
Fraunces_700Bold / Fraunces_600SemiBold |
| Body |
System / Inter |
DMSans_400Regular |
| Body Medium |
System / Inter Medium |
DMSans_500Medium |
| Body Bold |
System / Inter Bold |
DMSans_700Bold |
Spacing (Mobile)
| Token |
Value |
| xs |
4px |
| sm |
8px |
| md |
16px |
| lg |
24px |
| xl |
32px |
| xxl |
48px |
Border Radius
| Token |
Value |
| sm |
8px |
| md |
12px |
| lg |
16px |
| xl |
24px (rounded-2xl) |
| full |
9999px (circular) |
5.2 Figma-to-Code Pipeline
Figma Design (Make Export)
|
v
Figma Make Export (Vite + React)
mockups/figma-make-export/src/app/screens/
10 screens: Login, Onboarding, Dashboard, SendMoney,
BankAccounts, TransactionHistory, ScanQR, Profile,
Notifications, MerchantDashboard
|
v
Implementation (Next.js / Expo)
- Web: src/drop-app/src/app/
- Mobile: src/drop-mobile/app/
|
v
Visual Validation
Screenshot vs Figma reference comparison
Source of truth: mockups/figma-make-export/src/components/ contains the canonical UI for all 10 core screens. Before any UI change, the corresponding Make component must be read first.
6. Web vs Mobile Feature Matrix
| Feature |
Web (Next.js) |
Mobile (Expo) |
| Auth storage |
httpOnly cookie (drop_token) |
Bearer token (in-memory + AsyncStorage) |
| Navigation |
App Router (file-based) |
Expo Router (Stack + Tabs) |
| Send money flow |
4 steps (recipient, amount, review, success) |
2 steps (recipient+currency, amount+confirm) |
| Registration |
4 steps (info, OTP, PIN, success) |
2 steps (info, password) |
| QR scanner |
Simulated camera viewfinder |
Simulated camera placeholder |
| Bottom nav |
5 tabs (Hjem, Aktivitet, Skann, Kontoer, Profil) |
4 tabs (Hjem, Send, QR, Profil) |
| Cards page |
Yes (feature-flagged, default off) |
No |
| Merchant dashboard |
Yes (role-gated) |
No |
| Bank accounts |
Dedicated /accounts page |
Balance shown on dashboard |
| Notifications |
Dedicated /notifications page |
Not implemented |
| Profile sub-pages |
4 (personal, security, notifications, language) |
Inline settings |
| Feature flags |
Environment variables |
Not implemented |
| Legal pages |
Terms, Privacy, Fees, Withdrawal, Complaints |
Not implemented (links only) |
| Offline support |
PWA Service Worker registration |
No offline support |
| Deep linking |
N/A |
Not configured |
| Push notifications |
N/A |
Not implemented |
| Biometric auth |
N/A |
Not implemented |
| UI framework |
shadcn/ui (Radix) + Tailwind v4 |
React Native StyleSheet |
| State management |
useState + useAuth hook |
useState + api module |
7. Accessibility Considerations (WCAG 2.1 AA)
| Area |
Web Implementation |
Mobile Implementation |
| Color contrast |
Primary green (#0B6E35) on white meets 4.5:1 |
Same color tokens, system font rendering |
| Focus management |
Radix UI provides built-in focus trapping for Dialog, Sheet |
Expo Router handles screen focus |
| Screen reader |
Semantic HTML via shadcn/ui, lucide icons with aria-hidden |
React Native accessibility props needed |
| Touch targets |
Buttons min 44px height (py-3 = 48px) |
Tab bar height 60px, buttons styled per platform |
| Motion |
Tailwind transition-colors only, no complex animation |
Minimal animation (SplashScreen) |
| Language |
lang="nb" on html element (Norwegian) |
Not configured |
| Keyboard nav |
Radix handles arrow keys, Escape, Tab |
N/A (touch-first) |
8. Cross-References