- Progressive Web App with Express + JSON backend - PIN-based auth, multi-device sync - Invoice + Statement PDF generation (branded, Grandstander + Nunito) - Mobile + Desktop responsive layouts - n8n backup integration - Custom logo upload - Settings for business info, fees, banking - Bulk invoice generation - Web Share API integration
152 lines
6.2 KiB
Markdown
152 lines
6.2 KiB
Markdown
# Slim Uiltjies AfterCare — Invoice System
|
||
|
||
A beautiful, fully offline **Progressive Web App** for managing parents, children, invoices and payments for **Slim Uiltjies AfterCare** — built to match the look of the original branded receipt.
|
||
|
||
> _"A safe place to learn, grow and shine!"_
|
||
|
||
## What's included
|
||
|
||
- **Parents** — manage parent / guardian info (name, phone, email, address)
|
||
- **Children** — link learners to parents, set plan (Full Day / Half Day) and monthly fee
|
||
- **Invoices** — generate monthly invoices, auto-numbered (e.g. `SU-0001`)
|
||
- **Payments** — record cash / EFT / other payments, mark invoices paid
|
||
- **Statements** — beautiful "Statement of Payments Received" matching the original receipt
|
||
- **Sharing** — Share PDF via WhatsApp, email, or any app on the phone (Web Share API). Falls back to download + WhatsApp deep-link.
|
||
- **PWA** — installable on phone home screen, works **fully offline**, with custom owl mascot icons
|
||
- **Backup / restore** — export all data as JSON, import on any device
|
||
- **Branded** — cream paper background, purple primary, pink / yellow / green / blue accents, owl mascot
|
||
|
||
## Run it locally
|
||
|
||
This is a static app — no build step.
|
||
|
||
```bash
|
||
# Option 1: Python (built-in on macOS / Linux)
|
||
cd /path/to/SLIMUILTIES
|
||
python3 -m http.server 8080
|
||
|
||
# Option 2: Node
|
||
npx serve -l 8080
|
||
|
||
# Option 3: Any static server
|
||
```
|
||
|
||
Then open **http://localhost:8080** in any browser.
|
||
|
||
> **Tip:** For PWA install + service worker to work, you need `localhost` or `https://`. Plain `file://` won't.
|
||
|
||
## Install on a phone
|
||
|
||
Once deployed (locally or on the web):
|
||
|
||
1. Open the URL in **Chrome** (Android) or **Safari** (iOS).
|
||
2. **Android Chrome:** tap the menu (⋮) → "Install app" or "Add to Home screen".
|
||
3. **iOS Safari:** tap the Share button → "Add to Home Screen".
|
||
|
||
The app will appear on the home screen with the owl icon and open full-screen like a native app.
|
||
|
||
## Deploy to the web
|
||
|
||
Because it's 100% static, you can host it anywhere:
|
||
|
||
- **Netlify:** drag the folder onto [app.netlify.com/drop](https://app.netlify.com/drop)
|
||
- **Vercel:** `vercel deploy` from the project folder
|
||
- **Cloudflare Pages:** connect a Git repo
|
||
- **GitHub Pages:** push to a repo, enable Pages
|
||
- **Any web host:** upload the files via FTP
|
||
|
||
HTTPS is required for the service worker (PWA install).
|
||
|
||
## Project structure
|
||
|
||
```
|
||
SLIMUILTIES/
|
||
├── index.html # App shell + splash screen
|
||
├── manifest.webmanifest # PWA manifest (install + shortcuts)
|
||
├── sw.js # Service worker (offline cache)
|
||
├── css/
|
||
│ └── styles.css # Design system + components
|
||
├── js/
|
||
│ ├── app.js # Router + init
|
||
│ ├── views.js # All screens (home, parents, invoices, etc.)
|
||
│ ├── invoice.js # Invoice + statement HTML render
|
||
│ ├── pdf.js # html2canvas + jsPDF wrapper
|
||
│ ├── share.js # Web Share API + WhatsApp fallback
|
||
│ ├── db.js # IndexedDB layer
|
||
│ ├── seed.js # Sample data (Slim Uiltjies example)
|
||
│ └── icons.js # Inline SVG brand mark
|
||
├── vendor/
|
||
│ ├── jspdf.umd.min.js # Vendored offline (357 KB)
|
||
│ └── html2canvas.min.js # Vendored offline (194 KB)
|
||
├── icons/
|
||
│ ├── icon.svg # SVG owl (used in manifest)
|
||
│ ├── icon-192.png # PWA icon 192×192
|
||
│ ├── icon-512.png # PWA icon 512×512
|
||
│ ├── apple-touch-icon.png # iOS install icon
|
||
│ └── favicon-32.png # Browser favicon
|
||
└── README.md
|
||
```
|
||
|
||
Total payload: ~600 KB (icons + CSS + JS + libs). Loads instantly after first install.
|
||
|
||
## Data model (IndexedDB)
|
||
|
||
| Store | Shape | Notes |
|
||
|---|---|---|
|
||
| `business` | single record `id='business'` | name, tagline, fees, banking, footer |
|
||
| `parents` | `{id, name, phone, email, address, notes}` | |
|
||
| `children` | `{id, parentId, name, plan, monthlyFee, startDate}` | indexed by `parentId` |
|
||
| `invoices` | `{id, number, childId, parentId, period, items[], subtotal, total, paid, balance, status, notes}` | indexed by `childId`, `parentId`, `period`, `status` |
|
||
| `payments` | `{id, invoiceId, date, amount, method, receivedBy}` | indexed by `invoiceId` |
|
||
| `meta` | `{id, value}` | seeded flag, next receipt number |
|
||
|
||
All data lives on the device — never sent to a server. Export to JSON for backup.
|
||
|
||
## How sharing works
|
||
|
||
1. User taps **Share PDF** on an invoice.
|
||
2. The invoice HTML is rendered off-screen.
|
||
3. **html2canvas** captures it as a pixel-perfect PNG.
|
||
4. **jsPDF** wraps the PNG into a multi-page A4 PDF.
|
||
5. **Web Share API** opens the phone's native share sheet — user picks WhatsApp / Gmail / Telegram / print / save to drive / etc.
|
||
6. If Web Share isn't available (older desktop browser), it falls back to a direct PDF download. A "WhatsApp" button also opens a `wa.me` deep-link with a pre-filled message.
|
||
|
||
## Default sample data
|
||
|
||
On first launch, the app seeds with realistic data:
|
||
- **3 parents**: Valentine, Nomsa Dlamini, Pieter van Wyk
|
||
- **4 children**: Tshireletso, Lerato, Themba, Mia (mix of Full Day / Half Day)
|
||
- **Historical payments** matching the original receipt (R500 / R1000 patterns)
|
||
- **Current-month invoices** for unpaid + paid examples
|
||
|
||
Tap **Settings → Data → Load sample data** to reseed anytime.
|
||
|
||
## Customization checklist
|
||
|
||
Go to **Settings** in the app:
|
||
|
||
- [x] Business name, tagline, address, phone, email, Facebook
|
||
- [x] Footer message on invoices
|
||
- [x] Default full-day & half-day fees
|
||
- [x] Receipt prefix & auto-numbering
|
||
- [x] Banking details (shown on every invoice)
|
||
- [x] Payment reference note
|
||
|
||
Or edit directly in `js/seed.js` before deploying.
|
||
|
||
## Browser support
|
||
|
||
| Feature | Required |
|
||
|---|---|
|
||
| IndexedDB | ✅ All modern browsers |
|
||
| Service Worker | ✅ Chrome, Edge, Firefox, Safari 11.1+ |
|
||
| Web Share API (files) | ✅ Chrome on Android, Safari on iOS |
|
||
| Web Share API (text) | ✅ All modern browsers |
|
||
| `display: standalone` | ✅ Chrome, Edge, Safari, Firefox |
|
||
| `<input type="date">` | ✅ All modern browsers |
|
||
|
||
For older browsers, the app degrades gracefully — `Share PDF` falls back to download + WhatsApp link.
|
||
|
||
## License
|
||
|
||
Built for Slim Uiltjies AfterCare. Use freely.
|