# Component Overview

# Component Overview (C4 Level 3)

**Document:** HLD-002
**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 15 (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

```mermaid
graph TD
    subgraph "Next.js 15 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

```mermaid
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 (BankID)"]
        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 | BankID-only (auto-creation on first login; POST /register returns 410) | BankID-only (auto-creation on first login) |
| 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

- **API endpoints consumed by frontend:** See [API Reference](../../backend/API-REFERENCE.md)
- **Database schema behind API responses:** See [Database Schema](../../backend/DATABASE-SCHEMA.md)
- **Authentication flow (BankID OIDC):** See [Authentication](../../backend/AUTHENTICATION.md)
- **Page specifications:** See [PAGES.md](../../frontend/PAGES.md)
- **Figma exports (UI source of truth):** `mockups/figma-make-export/src/app/screens/`
- **Login authentication flow:** See [flow-login-authentication.md](../lld/flow-login-authentication.md)
- **QR payment flow:** See [flow-qr-payment.md](../lld/flow-qr-payment.md)
- **Transaction history flow:** See [flow-transaction-history.md](../lld/flow-transaction-history.md)
- **Notification flow:** See [flow-notifications.md](../lld/flow-notifications.md)
- **Merchant onboarding flow:** See [flow-merchant-onboarding.md](../lld/flow-merchant-onboarding.md)