# ADM-20 through ADM-24: Admin Finance — Figma Production Specs

---

## 1. FEE CATEGORIES (ADM-20)

### Create/Edit Modal

```
RP/Modal (md)
├── Header: "Create Fee Category"
├── Content:
│   ├── Name: RP/Input "Tuition"
│   ├── Description: RP/Input (textarea)
│   ├── Color: RP/ColorPicker (#0B3A66)
│   ├── Is Active: RP/Toggle (default: on)
│   └── Sort Order: RP/Input (number)
├── Footer: [Cancel] [Save Category]
```

### Fee Category Table

```
Columns: Category | Color | Fee Structures | Status | Actions
├── Tuition      | #0B3A66 | 3 structures | Active | [Edit] [Delete]
├── Exam Fee     | #1E5FA8 | 2 structures | Active | [Edit] [Delete]
├── Library      | #22C55E | 1 structure  | Active | [Edit] [Delete]
├── Activity Fee | #8B5CF6 | 1 structure  | Active | [Edit] [Delete]
└── Transport    | #EC4899 | 0 structures | Active | [Edit] [Delete]

Actions: [Edit] opens modal, [Delete] → confirmation dialog
Delete guard: "Cannot delete category with active fee structures."
```

---

## 2. FEE STRUCTURES (ADM-21)

### Create/Edit Modal

```
RP/Modal (lg)
├── Header: "Create Fee Structure"
├── Content:
│   ├── Category: RP/Select (from fee_categories)
│   ├── Name: RP/Input "Tuition — Term 3"
│   ├── Amount: RP/Input (number) "800.00"
│   │   Currency symbol: ₵ (GHS, fixed, read-only)
│   ├── Frequency: RP/Select
│   │   Options: [Once] [Termly] [Monthly] [Annually]
│   ├── Due Date: RP/Input (date)
│   ├── Academic Year: RP/Select (optional)
│   ├── Description: RP/Input (textarea)
│   └── Is Active: RP/Toggle (default: on)
├── Footer: [Cancel] [Create Fee Structure]
```

### Assign to Students Modal

```
RP/Modal (xl)
├── Header: "Assign Fee Structure to Students"
├── Content:
│   ├── Fee Structure: "Tuition — Term 3 — ₵ 800" (read-only)
│   ├── Class: RP/Select (filter students)
│   ├── Students: Multi-select (searchable)
│   │   ☑ Amara Asante — JSS 2 — RP-2026-00001
│   │   ☑ Kofi Mensah — JSS 2 — RP-2026-00002
│   │   ☐ Esi Boateng — JSS 2 — RP-2026-00003
│   ├── Waiver: RP/Toggle "Apply waiver to selected"
│   │   If on: RP/Input (textarea): "Reason for waiver"
│   └── Summary: "2 students selected — Total: ₵ 1,600"
├── Footer: [Cancel] [Assign to 2 Students]
```

### Fee Structure Table

```
Columns: Structure | Category | Amount | Frequency | Due Date | Active | Actions
├── Tuition — Term 3    | Tuition  | ₵ 800   | Termly  | Jul 30 | ✓ | [Edit] [Delete] [Assign]
├── Exam Fee — Term 3   | Exam Fee | ₵ 200   | Termly  | Jul 30 | ✓ | [Edit] [Delete] [Assign]
├── Library Annual       | Library  | ₵ 100   | Once    | Sep 1  | ✓ | [Edit] [Delete] [Assign]
└── Activity Fee         | Activity | ₵ 100   | Termly  | Jul 30 | ✓ | [Edit] [Delete] [Assign]
```

---

## 3. INVOICES (ADM-22)

### Generate Invoices — Batch Process

```
RP/Modal (xl)
├── Header: "Generate Invoices"
├── Content:
│   ├── Academic Year: RP/Select
│   ├── Term: RP/Select
│   ├── Fee Structure: RP/Select (or "All active structures")
│   ├── Class: RP/Select (or "All classes")
│   ├── Due Date: RP/Input (date)
│   │
│   ├── Preview section:
│   │   "This will generate invoices for 245 students."
│   │   "Total estimated: ₵ 196,000"
│   │
│   │   Table preview (scrollable, max 10 rows):
│   │   Student | Class | Amount | Parent (Primary Guardian)
│   │   Amara A. | JSS 2 | ₵ 800 | Kofi Asante
│   │   Kofi M.  | JSS 2 | ₵ 800 | Ama Mensah
│   │   Esi B.   | JSS 2 | ₵ 800 | Esi Boateng Sr.
│   │   ... (+ 242 more)
│   │
│   └── ⚠ "Invoices will be sent to primary guardians via email."
├── Footer: [Cancel] [Generate 245 Invoices]
```

### Invoice Aging Report

```
┌──────────────────────────────────────────────────────────┐
│  Invoice Aging Report                    Period: Jun 2026│
├──────────────────────────────────────────────────────────┤
│                                                          │
│  Current (0-30 days)     12 invoices    ₵ 8,100        │
│  ████████████████████████████████████████░░░░░░░░░░░░░  │
│                                                          │
│  31-60 days               6 invoices    ₵ 2,400        │
│  ████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  │
│                                                          │
│  61-90 days               3 invoices    ₵ 1,200        │
│  ████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  │
│                                                          │
│  90+ days                 2 invoices    ₵ 600          │
│  ██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  │
│                                                          │
│  Total: 23 invoices    ₵ 12,300                        │
│                                                          │
│  [Export Report]  [Send Reminders to All Overdue]        │
└──────────────────────────────────────────────────────────┘
```

### Invoice Table

```
Tabs: [Outstanding (23)] [Paid (22)] [Overdue (8)] [All (48)]

Columns: Invoice # | Student | Amount | Paid | Balance | Status | Due Date | Aging | Actions
├── INV-2026-0045 | Amara A. | ₵ 1,200 | ₵ 0   | ₵ 1,200 | Overdue | Jun 1  | 45d  | [View] [Send] [Cancel]
├── INV-2026-0038 | Kofi M.  | ₵ 800   | ₵ 0   | ₵ 800   | Overdue | May 15 | 32d  | [View] [Send] [Cancel]
├── INV-2026-0041 | Esi B.   | ₵ 1,500 | ₵ 500 | ₵ 1,000 | Partial | May 20 | 28d  | [View] [Send] [Cancel]
├── INV-2026-0044 | Yaa A.   | ₵ 950   | ₵ 0   | ₵ 950   | Overdue | Jun 15 | 15d  | [View] [Send] [Cancel]
├── INV-2026-0046 | Kwame D. | ₵ 600   | ₵ 0   | ₵ 600   | Sent    | Jun 25 | 7d   | [View] [Send] [Cancel]
└── INV-2026-0050 | Ama S.   | ₵ 1,200 | ₵ 1,200| ₵ 0    | Paid    | Jun 10 | —    | [View] [Receipt]

Status badge colors:
├── draft: grey
├── sent: blue
├── partially_paid: amber
├── paid: green
├── overdue: red
├── cancelled: grey (strikethrough)
└── refunded: purple
```

### Record Manual Payment Modal

```
RP/Modal (md)
├── Header: "Record Manual Payment"
├── Content:
│   ├── Invoice: "INV-2026-0041 — ₵ 1,500" (read-only)
│   ├── Balance Due: ₵ 1,000 (read-only)
│   ├── Amount: RP/Input (number) "500.00"
│   ├── Payment Method: RP/Select
│   │   [Cash] [Cheque] [Bank Transfer] [Mobile Money] [Other]
│   ├── Reference Number: RP/Input (optional)
│   ├── Notes: RP/Input (textarea)
│   └── Recorded by: Admin name (read-only)
├── Footer: [Cancel] [Record Payment]
```

---

## 4. INVOICE DETAIL — Admin (ADM-23)

### Admin Invoice Actions

```
Invoice Document (same as PAR-09):
├── School header + Invoice number
├── Student & Parent info
├── Line items table
├── Totals (subtotal, discount, total)
├── Status + Due date
├── Payment history

Admin-specific actions:
├── [Edit Invoice] — only if status = draft
├── [Send to Parent] — triggers email with PDF
├── [Record Manual Payment] — opens modal
├── [Cancel Invoice] — confirmation: "Cancel this invoice?"
├── [Refund] — opens refund modal
├── [Download PDF] — generates DomPDF
└── [View Audit Trail] — who created, modified, sent

Cancel Modal:
RP/Modal (md)
├── Header: "Cancel Invoice"
├── Content:
│   "Cancel INV-2026-0045?"
│   "Amount: ₵ 1,200.00"
│   "This action cannot be undone."
│   Reason: RP/Input (textarea, required)
├── Footer: [Keep Invoice] [Cancel Invoice] (danger)

Refund Modal:
RP/Modal (md)
├── Header: "Refund Payment"
├── Content:
│   Invoice: INV-2026-0041
│   Original Payment: ₵ 500.00 — Card
│   Refund Amount: RP/Input (number)
│   Reason: RP/Input (textarea)
│   ⚠ "Refund will be processed through Paystack."
├── Footer: [Cancel] [Process Refund]
```

---

## 5. PAYMENTS (ADM-24)

### Payments Table

```
Columns: Reference | Invoice # | Parent | Student | Amount | Method | Status | Date | Actions
├── PSK-abc123  | INV-2026-0050 | K. Asante | Amara A. | ₵ 1,200 | Card           | Successful | Jun 10 | [View] [Receipt]
├── PSK-def456  | INV-2026-0041 | E. Boateng| Esi B.   | ₵ 500   | Mobile Money  | Successful | Jun 15 | [View] [Receipt]
├── PSK-ghi789  | INV-2026-0044 | Y. Asante | Yaa A.   | ₵ 950   | Bank Transfer | Pending    | Jun 20 | [View]
├── PSK-jkl012  | INV-2026-0038 | A. Mensah | Kofi M.  | ₵ 800   | USSD          | Failed     | Jun 18 | [View] [Retry]
└── MNL-001     | INV-2026-0052 | Admin     | Ama S.   | ₵ 200   | Cash          | Successful | Jun 22 | [View] [Receipt]

Method badge colors:
├── Card: #1E5FA8 (secondary)
├── Mobile Money: #22C55E (success)
├── Bank Transfer: #8B5CF6 (purple)
├── USSD: #F59E0B (warning)
├── Cash: #64748B (muted)
├── Cheque: #EC4899 (pink)
└── Waiver: #94A3B8 (grey)

Status colors:
├── Successful: green
├── Pending: amber
├── Failed: red
├── Refunded: purple
└── Cancelled: grey
```

### Payment Detail Modal

```
RP/Modal (lg)
├── Header: "Payment Details"
├── Content:
│   ├── Reference: PSK-abc123 (Mono/Base)
│   ├── Invoice: INV-2026-0050 [View]
│   ├── Parent: Kofi Asante
│   ├── Student: Amara Asante — JSS 2
│   ├── Amount: ₵ 1,200.00
│   ├── Method: Card (Paystack)
│   ├── Status: Successful ✓
│   ├── Date: June 10, 2026 at 3:45 PM
│   ├── Gateway Response: "Approved"
│   ├── Paystack Metadata: [Expand JSON]
│   └── Receipt: REC-2026-0038 [Download]
├── Footer: [Close] [Download Receipt] [Refund]
```

---

## 6. PAYMENT CHARTS (ADM-01 Dashboard)

### CH-10: Revenue Trend

```
ApexCharts: Dual line chart
├── Series 1: Realized Revenue (solid, green #22C55E)
├── Series 2: Projected Revenue (dashed, grey #94A3B8)
├── X-axis: Months (Jan–Jun)
├── Y-axis: Amount in GHS (₵ format)
├── Tooltip: Shared, GHS formatted
└── Legend: Bottom, centered
```

### Payment Method Distribution (ADM-24 sidebar)

```
ApexCharts: Donut chart
├── Series: Count by payment method
├── Labels: Card, Mobile Money, Bank Transfer, USSD, Cash
├── Colors: Per method badge colors
└── Center label: "Total: 35 payments"
```

---

## 7. DARK MODE — Finance Screens

| Element | Light | Dark |
|---------|-------|------|
| Aging bar (current) | #22C55E | #4ADE80 |
| Aging bar (31-60) | #F59E0B | #FBBF24 |
| Aging bar (61-90) | #DC2626 | #F87171 |
| Aging bar (90+) | #7F1D1D | #B91C1C |
| Invoice document BG | #FFFFFF | #1E293B |
| Invoice border | #E2E8F0 | #334155 |
| Status badges | Same colors | Same colors |
| Method badges | Same colors | Same colors |
| Table hover | #F1F5F9 | #1E293B |
| Modal BG | #FFFFFF | #1E293B |
| Amount text | #0F172A | #F8FAFC |

---

## 8. EMPTY STATES — Finance Screens

| Screen | Title | CTA |
|--------|-------|-----|
| ADM-20 | "No fee categories created" | [Create Category] |
| ADM-21 | "No fee structures defined" | [Create Fee Structure] |
| ADM-22 | "No invoices generated" | [Generate Invoices] |
| ADM-24 | "No payments recorded" | — (auto-populated from Paystack) |

---

## 9. LOADING / ERROR STATES

### Loading
```
Table: RP/Skeleton × 8 rows (48px each)
Charts: RP/Skeleton (rect, height: 280px)
KPIs: RP/Skeleton × 5 cards
```

### Error
```
Table: RP/Banner (danger) "Failed to load data" + [Retry]
Modal: RP/Banner (danger, inline) "Failed to save"
Payment error: RP/Banner (danger) "Payment processing failed" + [Retry] [Contact Support]
```

---

## 10. ACCESSIBILITY — Finance Screens

- Currency amounts: `aria-label` includes full text ("1200 Ghana Cedis")
- Status badges: `aria-label` includes status ("Invoice status: Overdue")
- Aging bars: `role="img"` with `aria-label` ("12 invoices, 0-30 days, 8100 GHS")
- Tables: Sortable columns indicated with `aria-sort`
- Modals: Focus trap, ESC to close
- Payment forms: Error messages linked via `aria-describedby`