diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f964fb5e..364d6181 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -69,8 +69,23 @@ jobs:
INTERNAL_API_KEY: test_internal_api_key
FRONTEND_URL: https://frontend.example.com
+ migration-paths:
+ runs-on: ubuntu-latest
+ outputs:
+ migrations: ${{ steps.filter.outputs.migrations }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: dorny/paths-filter@v3
+ id: filter
+ with:
+ filters: |
+ migrations:
+ - 'backend/migrations/**'
+ - 'backend/package.json'
+
migration-check:
- needs: supply-chain-audit
+ needs: [supply-chain-audit, migration-paths]
+ if: github.event_name == 'push' || needs.migration-paths.outputs.migrations == 'true'
runs-on: ubuntu-latest
services:
postgres:
@@ -97,7 +112,22 @@ jobs:
- name: Install dependencies
run: npm ci
working-directory: backend
- - name: Run full migration set against empty database
+ - name: Migrate up from empty schema
+ run: npm run migrate:up
+ working-directory: backend
+ env:
+ DATABASE_URL: postgres://pguser:pgpass@localhost:5432/remitlend_test
+ - name: Migrate all the way down (reversibility check)
+ run: |
+ # Count migrations and roll them all back one by one
+ MIGRATION_COUNT=$(ls migrations/*.js 2>/dev/null | wc -l)
+ for i in $(seq 1 "$MIGRATION_COUNT"); do
+ npm run migrate:down -- --count 1
+ done
+ working-directory: backend
+ env:
+ DATABASE_URL: postgres://pguser:pgpass@localhost:5432/remitlend_test
+ - name: Migrate up again (ordering + idempotency check)
run: npm run migrate:up
working-directory: backend
env:
diff --git a/frontend/README.md b/frontend/README.md
index 4c5353e8..4584c070 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -6,460 +6,338 @@ Next.js web application for the RemitLend platform, providing user interfaces fo
The frontend is a modern React application built with Next.js that enables:
-- Wallet connection (Freighter, Albedo, etc.)
-- Credit score visualization
+- Wallet connection via Freighter
+- Credit score visualisation
- Remittance NFT minting
- Loan request and management
- Lending pool participation
- Real-time transaction tracking
+- Notifications and activity streams
## Tech Stack
-- **Framework**: Next.js 16 (App Router)
-- **React**: 19.2.3
-- **Language**: TypeScript
-- **Styling**: Tailwind CSS 4
-- **Wallet Integration**: Stellar Wallet Kit (planned)
-- **State Management**: React hooks + Context API (planned)
+| Layer | Technology |
+|---|---|
+| Framework | Next.js 16 (App Router) |
+| React | 19.2.3 |
+| Language | TypeScript |
+| Styling | Tailwind CSS 4 (`@import "tailwindcss"` in globals.css, no config file) |
+| State management | Zustand 5 |
+| Server state / caching | TanStack React Query 5 |
+| Wallet integration | `@stellar/freighter-api` |
+| Blockchain SDK | `@stellar/stellar-sdk` |
+| Internationalisation | next-intl 4 (locales: `en`, `es`, `tl`) |
+| Charts | Recharts |
+| Animation | Framer Motion |
+| Notifications | Sonner |
+| Monitoring | Sentry |
+| PWA | Serwist |
## Getting Started
### Prerequisites
- Node.js 18 or higher
-- npm or yarn
-- Stellar wallet (Freighter recommended)
+- npm
+- Freighter browser extension (for wallet features)
### Installation
```bash
-# Install dependencies
npm install
-
-# Start development server
npm run dev
```
-### Access the Application
-
Open [http://localhost:3000](http://localhost:3000) in your browser.
## Available Scripts
```bash
-# Development
npm run dev # Start dev server with hot reload
-
-# Production
-npm run build # Build for production
-npm start # Run production build
-
-# Code Quality
-npm run lint # Check code quality with ESLint
+npm run build # Production build
+npm start # Serve production build
+npm run lint # Check formatting with Prettier (not ESLint)
+npm run format # Auto-format with Prettier
+npm run typecheck # TypeScript type check (tsc --noEmit)
+npm test # Jest unit tests
+npm run test:watch # Jest in watch mode
+npm run test:e2e # Playwright end-to-end tests
+npm run audit:a11y # Build then run axe-playwright accessibility audit
```
+> **Note:** `npm run lint` runs `prettier --check` — it checks formatting, not ESLint rules.
+> ESLint runs automatically via `lint-staged` on pre-commit.
+
## Project Structure
```
frontend/
+├── e2e/ # Playwright end-to-end tests
+│ ├── borrower-loan-flow.spec.ts
+│ ├── criticalFlows.spec.ts
+│ └── ...
+├── messages/ # next-intl translation files
+│ ├── en.json
+│ ├── es.json
+│ └── tl.json
├── src/
-│ └── app/ # Next.js App Router
-│ ├── components/ # React components
-│ │ └── global_ui/ # Reusable UI components
-│ │ └── Spinner.tsx
-│ ├── layout.tsx # Root layout
-│ ├── page.tsx # Home page
-│ ├── not-found.tsx # 404 page
-│ ├── globals.css # Global styles
-│ └── favicon.ico
-├── public/ # Static assets
-│ ├── og-image.png
-│ └── *.svg
-├── next.config.ts # Next.js configuration
-├── tailwind.config.ts # Tailwind CSS configuration
-├── tsconfig.json # TypeScript configuration
-├── package.json
-└── README.md
+│ └── app/
+│ ├── [locale]/ # Localised routes (en / es / tl)
+│ │ ├── layout.tsx
+│ │ ├── page.tsx # Landing page
+│ │ ├── globals.css # Tailwind 4 entry + CSS custom properties
+│ │ ├── loans/ # Borrower loan list + [loanId] detail
+│ │ ├── lend/ # Lender dashboard
+│ │ ├── wallet/ # Wallet connection & balance
+│ │ ├── remittances/ # Remittance NFT viewer
+│ │ ├── send-remittance/
+│ │ ├── request-loan/
+│ │ ├── repay/
+│ │ ├── notifications/
+│ │ ├── analytics/
+│ │ ├── activity/
+│ │ ├── settings/
+│ │ ├── liquidations/
+│ │ ├── kingdom/
+│ │ ├── admin/ # Admin governance
+│ │ └── ui-demo/ # Dev-only component gallery (404 in production)
+│ ├── components/
+│ │ ├── ui/ # Design-system primitives (22 components)
+│ │ ├── global_ui/ # App-shell components (Spinner, ErrorBoundary …)
+│ │ ├── borrower/
+│ │ ├── lender/
+│ │ └── remittance/
+│ ├── stores/ # Zustand stores
+│ │ ├── useWalletStore.ts
+│ │ ├── useUserStore.ts
+│ │ ├── useThemeStore.ts
+│ │ ├── useUIStore.ts
+│ │ ├── useToastStore.ts
+│ │ └── useGamificationStore.ts
+│ ├── hooks/ # Custom React hooks
+│ ├── lib/ # API clients and utilities
+│ └── utils/ # Pure helpers (cn, stellar, amount, csv …)
+├── i18n.config.ts
+├── next.config.ts
+├── postcss.config.mjs
+├── playwright.config.ts
+├── jest.config.js
+├── tsconfig.json
+└── package.json
```
-## Features
-
-### Current Features
-
-- Landing page with project overview
-- Responsive design for mobile and desktop
-- Loading states with spinner component
-- SEO optimization with metadata
-- Custom 404 page
-
-### Planned Features
-
-#### Borrower Dashboard
-
-- [ ] Wallet connection interface
-- [ ] Credit score display
-- [ ] Remittance NFT minting
-- [ ] Loan request form
-- [ ] Active loans management
-- [ ] Repayment interface
-- [ ] Transaction history
-
-#### Lender Dashboard
-
-- [ ] Pool liquidity overview
-- [ ] Deposit/withdraw interface
-- [ ] Loan approval queue
-- [ ] Yield tracking
-- [ ] Portfolio analytics
-
-#### Shared Features
-
-- [ ] Real-time transaction status
-- [ ] Notification system
-- [ ] Multi-language support
-- [ ] Dark mode toggle
-- [ ] Wallet balance display
-
-## Component Library
-
-### Global UI Components
-
-#### Spinner
-
-Loading indicator component.
-
-```tsx
-import { Spinner } from "@/app/components/global_ui/Spinner";
-
-;
-```
-
-**Props:**
-
-- `size`: 'sm' | 'md' | 'lg' (default: 'md')
-
-### Planned Components
-
-- `Button` - Reusable button with variants
-- `Card` - Container component
-- `Modal` - Dialog component
-- `Input` - Form input with validation
-- `WalletConnect` - Wallet connection button
-- `TransactionStatus` - Transaction feedback
-- `LoanCard` - Loan information display
-- `PoolStats` - Pool statistics display
-
-## Styling
-
-### Tailwind CSS
-
-The project uses Tailwind CSS 4 for styling with a custom configuration.
-
-**Key Features:**
-
-- Utility-first CSS
-- Responsive design utilities
-- Custom color palette (planned)
-- Dark mode support (planned)
+## Routing
-**Example:**
+All pages are nested under the `[locale]` segment, so every URL is prefixed with the active locale:
+
+| Route | Description |
+|---|---|
+| `/[locale]` | Landing page |
+| `/[locale]/wallet` | Wallet connection |
+| `/[locale]/loans` | Loan list |
+| `/[locale]/loans/[loanId]` | Loan detail |
+| `/[locale]/lend` | Lender dashboard |
+| `/[locale]/request-loan` | New loan request |
+| `/[locale]/repay` | Repayment flow |
+| `/[locale]/remittances` | Remittance NFT gallery |
+| `/[locale]/send-remittance` | Send remittance |
+| `/[locale]/notifications` | Notification inbox |
+| `/[locale]/activity` | Activity log |
+| `/[locale]/analytics` | Analytics dashboard |
+| `/[locale]/settings` | User settings |
+| `/[locale]/liquidations` | Liquidation queue |
+| `/[locale]/kingdom` | Gamification / Kingdom view |
+| `/[locale]/admin` | Governance admin |
+| `/[locale]/ui-demo` | Dev-only component gallery |
+| `/[locale]/not-found` | 404 page |
-```tsx
-
-
Welcome to RemitLend
-
-```
+## State Management
-### Global Styles
+Global state is managed with **Zustand 5** stores:
-Global styles are defined in `src/app/globals.css`:
+| Store | Responsibility |
+|---|---|
+| `useWalletStore` | Freighter wallet connection, public key, signing |
+| `useUserStore` | User profile and credit score |
+| `useThemeStore` | Light / dark / system theme with `localStorage` persistence |
+| `useUIStore` | Modal and sidebar open/close state |
+| `useToastStore` | Toast queue used by `useToast` hook |
+| `useGamificationStore` | Kingdom / XP state |
-- CSS reset
-- Tailwind directives
-- Custom CSS variables
-- Typography defaults
+TanStack React Query handles server-state caching and background refetching for all API calls.
## Wallet Integration
-### Stellar Wallet Kit (Planned)
-
-Integration with Stellar wallets for transaction signing.
-
-**Supported Wallets:**
-
-- Freighter
-- Albedo
-- Rabet
-- xBull
-
-**Example Usage:**
+Wallet integration uses **`@stellar/freighter-api`**:
```tsx
-import { StellarWalletKit } from "@stellar/wallet-kit";
-
-const kit = new StellarWalletKit({
- network: "testnet",
- selectedWallet: "freighter",
-});
+import { isConnected, getPublicKey, signTransaction } from "@stellar/freighter-api";
-// Connect wallet
-await kit.connect();
-
-// Sign transaction
-const signedTx = await kit.sign(transaction);
+const connected = await isConnected();
+const publicKey = await getPublicKey();
+const signedXdr = await signTransaction(xdr, { networkPassphrase });
```
-## State Management
+Wallet state (public key, connection status) is managed by `useWalletStore`.
-### React Context (Planned)
-
-Global state management using React Context API.
-
-**Contexts:**
+## Component Library
-- `WalletContext` - Wallet connection state
-- `UserContext` - User profile and credit score
-- `LoanContext` - Active loans data
-- `PoolContext` - Lending pool information
+Design-system primitives live in [`src/app/components/ui/`](src/app/components/ui/). There are 22 components:
+
+### Core primitives
+
+| Component | Props | Description |
+|---|---|---|
+| `Button` | `variant` (`primary`\|`secondary`\|`outline`\|`ghost`\|`danger`), `size` (`sm`\|`md`\|`lg`\|`icon`), `isLoading`, `leftIcon`, `rightIcon` | Polymorphic button with loading spinner |
+| `Input` | `label`, `error`, `helperText`, `leftIcon`, `rightIcon` | Labelled text input with accessible error/helper text |
+| `Card` / `CardHeader` / `CardTitle` / `CardDescription` / `CardContent` / `CardFooter` | `className` | Compound card layout |
+| `Modal` | `isOpen`, `onClose`, `title`, `size` (`sm`\|`md`\|`lg`\|`xl`), `ariaLabel` | Focus-trapped animated dialog |
+
+### Feedback & status
+
+| Component | Props | Description |
+|---|---|---|
+| `Skeleton` / `SkeletonText` / `SkeletonCard` / `SkeletonRow` / `SkeletonChart` / `SkeletonAvatar` | `className`, `lines` (SkeletonText) | Loading placeholders |
+| `EmptyState` | `icon`, `title`, `description`, `actionLabel`, `actionHref` \| `onAction`, `actionIcon` | Zero-state placeholder with optional CTA |
+| `StatusIndicator` | `label`, `tone` (`success`\|`danger`\|`warning`\|`info`\|`neutral`), `icon`, `iconOnly` | Coloured badge pill |
+| `LoanStatusBadge` | `status` (`active`\|`pending`\|`repaid`\|`defaulted`\|`liquidated`) | Domain-specific status badge |
+| `Toast` / `Toaster` | — | Toast notification components backed by `useToastStore` |
+
+### Controls & utilities
+
+| Component | Props | Description |
+|---|---|---|
+| `Tooltip` | `content`, `label`, `iconClassName` | Hover/focus tooltip with info icon |
+| `PaginationControls` | `currentPage`, `totalPages`, `hasPrevious`, `hasNext`, `onPageChange`, `onPrevious`, `onNext`, `summary` | Page navigation with ellipsis windowing |
+| `CopyButton` | `value` | Clipboard copy with check feedback |
+| `TxHashLink` | `txHash`, `chars` | Truncated hash with copy + Stellar Explorer link |
+| `ThemeToggle` | — | Light / dark / system switcher |
+| `ConfirmTransactionDialog` | — | Pre-submit transaction confirmation modal |
+| `OperationProgress` | — | Multi-step operation stepper |
+| `RepaymentProgress` | — | Loan repayment progress bar |
+| `LoanTimeline` | — | Chronological loan event list |
+| `TransactionStatusTracker` | — | Live transaction polling status |
+| `CreditScoreGauge` | — | Circular credit score visualisation |
+| `CreditScoreBreakdown` | — | Score factor breakdown chart |
+
+> A live, interactive gallery is available in development at `/[locale]/ui-demo` (returns 404 in production).
-**Example:**
+## Styling
-```tsx
-import { useWallet } from "@/contexts/WalletContext";
+Tailwind CSS 4 is configured via CSS-first `@import "tailwindcss"` in
+[`src/app/[locale]/globals.css`](src/app/%5Blocale%5D/globals.css) — there is no
+`tailwind.config.ts` file. Design tokens are declared as CSS custom properties in `:root`:
-function MyComponent() {
- const { address, connected, connect, disconnect } = useWallet();
+```css
+@import "tailwindcss";
- return (
-
- );
+:root {
+ --background: #ffffff;
+ --foreground: #171717;
+ --focus-ring: #2563eb;
}
-```
-
-## API Integration
-
-### Backend API
-The frontend communicates with the Express backend for off-chain data.
-
-**Base URL:** `http://localhost:3001/api`
-
-**Example:**
-
-```tsx
-async function fetchCreditScore(userId: string) {
- const response = await fetch(`http://localhost:3001/api/score/${userId}`);
- const data = await response.json();
- return data.score;
+@theme inline {
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --font-sans: var(--font-geist-sans);
+ --font-mono: var(--font-geist-mono);
}
```
-### Blockchain Integration
+Dark mode is driven by the `.dark` class (set by `useThemeStore`) and also respects
+`prefers-color-scheme`.
-Direct interaction with Soroban smart contracts via Stellar SDK.
-
-**Example:**
-
-```tsx
-import { Contract, SorobanRpc } from "@stellar/stellar-sdk";
+## Testing
-const contract = new Contract(contractId);
-const server = new SorobanRpc.Server("https://soroban-testnet.stellar.org");
+### Unit tests — Jest + React Testing Library
-// Call contract method
-const result = await contract.call("get_score", [nftId]);
+```bash
+npm test # run once
+npm run test:watch # interactive watch mode
```
-## Routing
-
-### App Router Structure
-
-Next.js 13+ App Router with file-based routing.
-
-**Current Routes:**
-
-- `/` - Landing page
-- `/404` - Not found page
-
-**Planned Routes:**
+Test files sit alongside source files (`*.test.ts` / `*.test.tsx`). Key test suites:
-- `/borrower` - Borrower dashboard
-- `/lender` - Lender dashboard
-- `/loans` - Loan management
-- `/loans/[id]` - Loan details
-- `/pool` - Pool overview
-- `/profile` - User profile
+- `src/app/stores/stores.test.ts` — Zustand store logic
+- `src/app/utils/*.test.ts` — pure utility functions
+- `src/app/components/**/*.test.tsx` — component rendering
-## SEO & Metadata
+### End-to-end tests — Playwright
-### Metadata Configuration
-
-```tsx
-export const metadata = {
- title: "RemitLend - Credit from Remittances",
- description: "Turn your remittance history into credit history",
- openGraph: {
- title: "RemitLend",
- description: "Decentralized lending for migrant workers",
- images: ["/og-image.png"],
- },
-};
+```bash
+npm run test:e2e
```
-## Performance Optimization
-
-### Next.js Features
+Specs live in `e2e/` and cover critical user flows:
-- **Static Generation**: Pre-render pages at build time
-- **Image Optimization**: Automatic image optimization
-- **Code Splitting**: Automatic code splitting per route
-- **Font Optimization**: Automatic font optimization
+- `borrower-loan-flow.spec.ts`
+- `borrower-repay-flow.spec.ts`
+- `lender-withdraw-flow.spec.ts`
+- `notifications-inbox.spec.ts`
+- `remittance-nft-viewer.spec.ts`
+- `admin-governance.spec.ts`
+- `criticalFlows.spec.ts`
-### Best Practices
+### Accessibility audit
-- Use `next/image` for images
-- Implement lazy loading for heavy components
-- Minimize client-side JavaScript
-- Use server components when possible
-- Implement proper caching strategies
-
-## Testing (Planned)
-
-### Testing Stack
+```bash
+npm run audit:a11y # builds then runs axe-playwright
+```
-- **Unit Tests**: Jest + React Testing Library
-- **E2E Tests**: Playwright or Cypress
-- **Component Tests**: Storybook
+## API Integration
-### Example Test
+The frontend talks to the Express backend for off-chain data and uses `@stellar/stellar-sdk`
+directly for on-chain calls.
-```tsx
-import { render, screen } from "@testing-library/react";
-import { Spinner } from "@/app/components/global_ui/Spinner";
-
-describe("Spinner", () => {
- it("renders spinner", () => {
- render();
- expect(screen.getByRole("status")).toBeInTheDocument();
- });
-});
-```
+**Backend base URL:** `NEXT_PUBLIC_API_URL` (default: `http://localhost:3001`)
## Deployment
-### Vercel (Recommended)
+### Vercel (recommended)
```bash
-# Install Vercel CLI
npm i -g vercel
-
-# Deploy
vercel
```
### Docker
```bash
-# Build image
docker build -t remitlend-frontend .
-
-# Run container
docker run -p 3000:3000 remitlend-frontend
```
### Environment Variables
-Create `.env.local` for local development:
-
```env
NEXT_PUBLIC_API_URL=http://localhost:3001
NEXT_PUBLIC_STELLAR_NETWORK=testnet
NEXT_PUBLIC_STELLAR_RPC_URL=https://soroban-testnet.stellar.org
```
-## Accessibility
-
-### WCAG Compliance
-
-The application aims for WCAG 2.1 Level AA compliance:
-
-- Semantic HTML elements
-- ARIA labels where needed
-- Keyboard navigation support
-- Color contrast ratios
-- Screen reader compatibility
-
-**Note:** Full WCAG compliance requires manual testing with assistive technologies.
-
-## Browser Support
-
-- Chrome (latest 2 versions)
-- Firefox (latest 2 versions)
-- Safari (latest 2 versions)
-- Edge (latest 2 versions)
-
-## Contributing
-
-See [CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines.
-
-### Code Style
-
-- Use functional components with hooks
-- Prefer TypeScript interfaces over types
-- Use descriptive component names
-- Keep components small and focused
-- Extract reusable logic into custom hooks
-- Follow Next.js best practices
-
-### Before Submitting PR
-
-```bash
-npm run lint
-npm run build
-```
-
## Troubleshooting
-### Port Already in Use
-
```bash
-# Kill process on port 3000
+# Port in use
lsof -ti:3000 | xargs kill -9
-```
-### Build Errors
+# Stale Next.js cache
+rm -rf .next/ && npm run build
-```bash
-# Clean Next.js cache
-rm -rf .next/
-npm run build
-```
-
-### Module Not Found
-
-```bash
# Reinstall dependencies
-rm -rf node_modules package-lock.json
-npm install
+rm -rf node_modules package-lock.json && npm install
```
## Resources
- [Next.js Documentation](https://nextjs.org/docs)
-- [React Documentation](https://react.dev)
-- [Tailwind CSS Documentation](https://tailwindcss.com/docs)
+- [Tailwind CSS v4 Documentation](https://tailwindcss.com/docs)
+- [Zustand Documentation](https://zustand.docs.pmnd.rs)
+- [TanStack React Query](https://tanstack.com/query/latest)
- [Stellar Documentation](https://developers.stellar.org)
-- [Soroban Documentation](https://soroban.stellar.org/docs)
+- [next-intl Documentation](https://next-intl-docs.vercel.app)
## License
-ISC License - See LICENSE file for details.
-
-## Support
-
-- Open an issue for bug reports
-- Check existing issues before creating new ones
-- Provide browser and OS information
-- Include screenshots for UI issues
+ISC License — see LICENSE file for details.
diff --git a/frontend/src/app/[locale]/ui-demo/page.tsx b/frontend/src/app/[locale]/ui-demo/page.tsx
index 45d8b02d..e6fd6702 100644
--- a/frontend/src/app/[locale]/ui-demo/page.tsx
+++ b/frontend/src/app/[locale]/ui-demo/page.tsx
@@ -1,5 +1,8 @@
"use client";
+// This route is intentionally gated from production — it is a development-only
+// component gallery. If accidentally shipped, requests are bounced to 404.
+import { notFound } from "next/navigation";
import React, { useState } from "react";
import { Button } from "../../components/ui/Button";
import { Input } from "../../components/ui/Input";
@@ -12,11 +15,32 @@ import {
CardFooter,
} from "../../components/ui/Card";
import { Modal } from "../../components/ui/Modal";
-import { Search, Mail, Lock, User, Terminal, ChevronRight } from "lucide-react";
+import { Skeleton, SkeletonText, SkeletonCard, SkeletonRow } from "../../components/ui/Skeleton";
+import { EmptyState } from "../../components/ui/EmptyState";
+import { StatusIndicator } from "../../components/ui/StatusIndicator";
+import { LoanStatusBadge } from "../../components/ui/LoanStatusBadge";
+import { Tooltip } from "../../components/ui/Tooltip";
+import { PaginationControls } from "../../components/ui/PaginationControls";
+import { CopyButton } from "../../components/ui/CopyButton";
+import { ThemeToggle } from "../../components/ui/ThemeToggle";
+import {
+ Search,
+ Mail,
+ Lock,
+ User,
+ Terminal,
+ ChevronRight,
+ Inbox,
+ FileQuestion,
+} from "lucide-react";
export default function UIDemoPage() {
+ if (process.env.NODE_ENV === "production") notFound();
+
const [isModalOpen, setIsModalOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
+ const [currentPage, setCurrentPage] = useState(3);
+ const totalPages = 10;
const handleAction = () => {
setIsLoading(true);
@@ -26,21 +50,22 @@ export default function UIDemoPage() {
return (
-
-
- UI Component Library
-
+
+
+
+ UI Component Library
+
+
+
- A boutique collection of reusable atomic components for RemitLend.
+ Development-only gallery — not shipped to production. Covers all 22 components in{" "}
+ src/app/components/ui/.
{/* Buttons */}
-
-
-
Buttons
-
+ Button
@@ -66,6 +91,7 @@ export default function UIDemoPage() {
} variant="secondary">
Next Step
+
Are you sure you want to update your privacy settings? This will affect how your
@@ -188,7 +201,161 @@ export default function UIDemoPage() {
+
+ {/* Skeleton */}
+
+ Skeleton
+