42 Commits

Author SHA1 Message Date
59485579ec clean: remove .pi/ config from calvana repo — lives in pi-vs-claude-code now
- Removed all .pi/ (agents, themes, extensions, skills, observatory)
- Removed CLAUDE.md (belongs in parent pi repo)
- Added .pi/ and CLAUDE.md to .gitignore
- Added .pi/ to pledge-now-pay-later/.gitignore
2026-03-04 17:32:20 +08:00
ef37ca0c18 Fix payment flexibility quote length and orphan word
- Shorten quote 03 from 'Can I split it across a few months?' to 'Can I pay monthly?' for column symmetry
- Add nbsp between 'money' and 'arriving' to prevent orphan line break
2026-03-04 13:58:42 +08:00
6b71fa227b fix stacking cards: flatMap siblings, no wrappers, no shadow, z < header
ROOT CAUSE: each card was wrapped in its own div (min-h-[85vh]),
scoping sticky to that wrapper — cards could NEVER overlap.

FIX: flatMap returns all sticky divs + h-4 spacers as direct
siblings under the same parent (mt-14). Sticky now works
correctly — each card overlaps the previous with 20px peek.

- Removed all shadows (border-gray-100 only)
- z-index: 1-4 (was 10-40, conflicting with nav z-40)
- top: 72/92/112/132px (20px stagger)
- h-4 spacers between cards (no big white gaps)
- Regenerated dinner image: dark navy table, candlelight, £5,000
  pledge card — zero white space (was white tablecloth)
2026-03-03 23:29:26 +08:00
dc1253af33 sticky stacking cards on scroll + kill border white space
STACKING EFFECT:
- Cards use position: sticky with increasing top offset (72-120px)
- z-index layering (10-40) so later cards stack on top
- pb-36 between cards for scroll breathing room
- will-change-transform for smooth compositing

WHITE SPACE FIX:
- Removed border border-gray-200 (was creating visible white gap)
- Replaced with shadow-[0_2px_8px_rgba(0,0,0,0.08)] for depth
- Switched from CSS Grid to flexbox (flex-row/flex-row-reverse)
- Image fills full card height via flexbox stretch

LAYOUT:
- md:w-7/12 for image, md:w-5/12 for text
- min-h-[400px] on desktop for substantial card presence
- Alternating image left/right preserved for visual rhythm
2026-03-03 22:55:03 +08:00
233e9320b5 stunning alternating editorial rows + fix invisible gray text
LAYOUT:
- Killed boring 2x2 grid boxes
- Full-width alternating image/text rows (7:5 split)
- Image left/text right on rows 1,3 — flipped on rows 2,4
- Creates visual rhythm like an editorial magazine spread
- gap-px between rows for signature pattern
- Images at 2:1 cinematic aspect, large and atmospheric

CONTRAST FIX:
- Pain stat 'before' text: gray-200 (invisible) -> gray-400 (readable)
- 'Systems do.' heading: gray-300 -> gray-400
- Both stats now clearly visible while maintaining muted/bold contrast
2026-03-03 22:35:25 +08:00
3a6ec55a68 persona section: scenario-based personas + cinematic photography + pain stats
PERSONA OVERHAUL:
- Personas now defined by WHAT THEY DID, not job titles
- 'Charity Manager' -> 'You organized the dinner'
- 'Personal Fundraiser' -> 'You shared the link'
- 'Volunteer' -> 'You were on the ground'
- 'Organisation/Programme Manager' -> 'You claim the Gift Aid'

SECTION HEADING:
- Brand core insight: 'People don't break promises. Systems do.'
- Eyebrow: 'THE PLEDGE GAP'
- Sub: 'We built the missing system between I'll donate and the money arriving.'

PAIN STATS (visual anchors):
- £50,000 pledged / £22,000 collected (the gap)
- 23 said I'll donate / 8 actually did
- 40 pledges collected / 0 updates received
- 200 rows, 47 typos / 6 hours every quarter

COPY: Emotionally precise, tells each persona's specific story

PHOTOGRAPHY (4 cinematic moment shots):
- Dinner aftermath: empty table with lone pledge card, chandeliers
- Phone: hands on WhatsApp at kitchen table, warm light
- Volunteer: seen from behind, walking between gala tables with cards
- Desk still life: laptop spreadsheet, papers, tea, window light
- All 2:1 wide aspect, 2.7MB -> 260KB optimized
2026-03-03 22:21:49 +08:00
c18dc50657 persona section overhaul — editorial gap-px grid + fresh photography
SECTION REDESIGN:
- Killed standalone dashboard image (fake AI laptop, added nothing)
- New gap-px grid (signature pattern 2) with border-l-2 accents (pattern 1)
- Numbered anchors (01-04) as visual rhythm per brand guide
- Wider container: max-w-7xl matches hero width

PERSONA CHANGES:
- Renamed 'Organisation' -> 'Programme Manager'
- Reorder: Charity Manager, Programme Manager, Personal Fundraiser, Volunteer
- Updated /for/organisations page content to match

PHOTOGRAPHY (4 new images via gemini-3-pro-image-preview):
- persona-charity-manager.jpg — hijabi woman at mosque office desk
- persona-programme-manager.jpg — man at desk with campaign calendar
- persona-fundraiser.jpg — woman on London park bench with phone
- persona-volunteer.jpg — young man handing card at charity gala
- All optimized: 2.7MB -> 342KB (87% reduction via sharp)
- Consistent documentary candid style, 3:2 landscape, warm tones

FOOTER:
- 'Organisations' -> 'Programme Managers' in nav links
2026-03-03 22:01:53 +08:00
3ab440f103 center stat strip text 2026-03-03 21:41:11 +08:00
f0b1cb2f3a fix headline rhythm + wider hero image + 10x faster deploys
HEADLINE:
- 3 balanced lines: 'Turn I'll donate' / 'into money' / 'in the bank.'
- Removed &nbsp; that orphaned 'money' on its own line
- <br className='hidden lg:block'> controls breaks on desktop only

IMAGE:
- Hero container: max-w-5xl -> max-w-7xl (image 25% wider)
- Stat strip widened to match
- Much more of the gala scene visible, phone prominent

DEPLOY SPEED (deploy.sh):
- Persistent /opt/pnpl/ build dir (no temp dir creation/deletion)
- BuildKit with cache mounts (npm + .next/cache)
- No more docker builder prune / docker rmi (preserves cache!)
- Installed docker-buildx v0.31.1 on server
- Before: ~245s (4+ min)  After: ~29s (cached) / ~136s (first)
- Use: cd pledge-now-pay-later && bash deploy.sh
2026-03-03 21:37:34 +08:00
c9301edbe8 hero image fills full text column height on desktop
- Grid: items-start → md:items-stretch (both columns same height)
- Image: aspect-[4/5] → md:aspect-auto md:h-full (fills column)
- Mobile keeps aspect-[3/4] for stacked layout
- Bottom of image now lines up with buttons/trust line
2026-03-03 21:17:19 +08:00
ac19afce4e world-class hero image + 85% image optimization + sharp
HERO IMAGE:
- Generated 3 concepts with gemini-3-pro-image-preview, picked #1
- Phone showing 'Payment Received' notification at a charity gala dinner
- Warm tungsten bokeh chandeliers against dark bg-gray-950
- Directly visualizes the headline: 'money in the bank'
- Candid documentary angle, not looking at camera, brand compliant

IMAGE OPTIMIZATION (85% total reduction):
- All 21 images resized: landscape max 1200px, portrait max 1000px
- Compressed JPEG quality 80, progressive encoding, EXIF stripped
- Total: 13.6MB -> 2.1MB (saved 11.5MB)
- Individual savings: 81-90% per image

NEXT.JS IMAGE PIPELINE:
- Added sharp (10x faster than squoosh for image processing)
- next.config.mjs: WebP format, proper device/image sizes, 1yr cache TTL
- Dockerfile: libc6-compat + NEXT_SHARP_PATH for Alpine sharp support
- First request: ~3s (processing), cached: <1s

WebP served sizes: hero 52KB, cards 32-40KB (vs original 500-800KB JPEGs)
2026-03-03 21:10:59 +08:00
2592c4ba5b dark editorial hero — typography + documentary photo + gap-px stat strip
HERO REDESIGN:
- bg-gray-950 full-bleed dark hero (was white text-on-white)
- Split layout: 7-col massive headline + 5-col documentary photo
- Gala photo (02) as hero — warm tungsten pops against dark bg
- border-l-2 promise-blue eyebrow accent (signature pattern 1)
- gap-px stat strip: 30-50%, 60s, £0, 2 min (signature pattern 2)
- stagger-children animation on text column
- Delayed fade-up on image column (opacity: 0 → fadeUp after 250ms)
- Trust line with vertical pipe separators
- Merges old hero + hero image + stat section into 1 cinematic opening

NAV:
- Wordmark hidden on mobile (sm:inline), shows P mark only
- shrink-0 on logo, whitespace-nowrap on nav buttons

PERSONA CARDS:
- Charity Manager card now uses mosque photo (08) for variety
- Hover color: text-trust-blue → text-promise-blue (proper token)

Brand compliant: 0 violations (no gradients, rounded-2xl, backdrop-blur)
2026-03-03 20:53:25 +08:00
e2295020a1 add brand/ assets to repo + BRAND.md as single source of truth
BRAND.md: Complete brand guide with code snippets, color tokens, typography scale,
logo usage rules, DO/DON'T checklist, photography direction, voice & tone.
Every section references its visual asset in brand/.

brand/ folder (52 assets):
- photography/ (20) — landing page photos
- logo/ (6) — lockup, reversed, blue, marks, favicon
- color-palette/ (3) — primary, tints, psychology
- typography/ (3) — specimen, scale, numbers
- moodboard/ (3) — trust, community, editorial
- brand-guide/ (7) — cover through UI patterns
- social-templates/ (4) — OG, Instagram, Story, LinkedIn
- icons/ (6) — pledge, whatsapp, gift-aid, zakat, dashboard, schedule

Also fixed: Nav component still had backdrop-blur-lg (last violation)
2026-03-03 20:31:01 +08:00
fc80399092 brand identity overhaul: match BRAND-IDENTITY.md across all pages
Design system changes (per brand guide):
- ZERO rounded-2xl/3xl remaining (was 131 instances)
- ZERO bg-gradient remaining (was 25) — all solid colors
- ZERO colored shadows (shadow-trust-blue, etc) — flat, no glow
- ZERO backdrop-blur/glass effects — solid backgrounds
- ZERO emoji in logo marks — square P logomark everywhere
- ZERO decorative scale animations (group-hover:scale-105, etc)

Tailwind config:
- Added brand color names: midnight, promise-blue, generosity-gold, fulfilled-green, alert-red, paper
- Kept legacy aliases (trust-blue, etc) for backwards compat
- --radius: 0.75rem → 0.5rem (tighter corners)

CSS:
- Removed glass, glass-dark, card-hover, pulse-ring, bounce-gentle, confetti-fall, scale-in animations
- Kept only purposeful animations: fadeUp, fadeIn, slideDown, shimmer, counter-roll
- --primary tuned to match Promise Blue exactly

Components:
- Button: removed all colored shadows, added 'blue' variant, removed rounded from sizes
- All UI components: rounded-xl/2xl → rounded-lg

Pages updated (41 files):
- Dashboard layout: solid header (no blur), border-l-2 active indicator, midnight logo mark
- Login/Signup: paper bg (no gradient), midnight logo mark, no emoji
- Pledge flow: solid color icons, no gradient progress bars
- All dashboard pages: flat, sharp, editorial
2026-03-03 20:13:22 +08:00
f4ad6df45a add AI-generated landing page photography (Gemini 3 Pro)
20 images generated via gemini-3-pro-image-preview (Nano Banana Pro):
- Documentary street photography style, British-diverse subjects
- 12 square (1:1), 8 landscape (16:9) matching placeholder aspect ratios
- Replaced all ImagePlaceholder components with LandingImage + next/image
- Images in public/images/landing/, served statically

Pages updated: /, /for/charities, /for/fundraisers, /for/volunteers, /for/organisations
New component: LandingImage (next/image with fill + object-cover)
2026-03-03 19:27:36 +08:00
581f1e5f14 sharp flat redesign: all landing pages + replace donors with organisations
Design overhaul:
- Removed all emoji-heavy sections, rounded-3xl, cartoonish borders
- Sharp flat edges (square or rounded-lg max)
- Typography-driven hierarchy with numbered steps (01, 02, 03...)
- Border-left accent lines instead of colored card borders
- Grid-with-gap-px pattern for table-like sections
- Dark sections (bg-gray-950) for stats and CTAs
- Image placeholders (gray boxes with photo icons) for future real photography
- Shared components: Nav, Footer, BottomCta, ImagePlaceholder in /for/_components

Pages:
- / (main): Hero → 30-50% stat → 4 persona cards with images → 4 steps → compliance → payment → platforms → CTA
- /for/charities: Hero split with image → pain points → numbered flow with 2 images → features with left-border accents
- /for/fundraisers: Hero split → gap visualization (3-col dark panel) → flow with images → before/after grid → platforms grid
- /for/volunteers: Hero split → 3-col features (gap-px grid) → event flow → share channels → CTA to charity manager
- /for/organisations: NEW (replaces /for/donors) → multi-org pledges, umbrella fundraising, institutional partnerships

Removed /for/donors — donors use the pledge form, they don't need a landing page
2026-03-03 18:27:04 +08:00
121e2bbde8 4-persona landing pages + main page CRO rewrite
Main page (pledge.quikcue.com):
- Hero: 'Turn I'll donate into money in the bank'
- 30-50% stat in dark section (single number, maximum impact)
- 4 persona cards linking to /for/* pages
- 4-step how-it-works (tightened from previous)
- Compliance strip (Gift Aid, Zakat, email, WhatsApp - compact)
- Payment flexibility (now/later/monthly)
- Platform logos
- Dark CTA section
- Footer with persona links

/for/charities:
- Pain: pledges on napkins, awkward chasing, no visibility
- 5-step how-it-works specific to charity managers
- 6 features: Gift Aid, Zakat, WhatsApp, scheduling, GDPR, exports
- CTA: Start Free

/for/fundraisers:
- Pain: shared link 50 times, 3 donated
- Before/after comparison grid (without vs with)
- 6 external platforms with branding
- CTA: Start Free

/for/volunteers:
- Personal link, live stats, leaderboard
- Event night flow (4 steps)
- Share channels grid
- CTA: Tell your charity about this

/for/donors:
- Educational trust page, not a sign-up funnel
- 6-step pledge flow explained
- Data protection table (what/why for each field)
- FAQ (cancel, already paid, no WhatsApp consent)
- CTA: Are you a charity?
2026-03-03 17:46:20 +08:00
582c85b3d9 landing page: compliance section covers Gift Aid, Zakat, email + WhatsApp consent
Replaced Zakat-only section with full compliance showcase:
- Gift Aid (HMRC): +25%, home address, model declaration, HMRC-ready CSV
- Zakat: per-campaign toggle, separate tracking
- Email consent (GDPR): granular opt-in, never pre-ticked
- WhatsApp consent (PECR): separate opt-in, STOP instructions
- Audit trail callout: exact text, timestamp, IP, version
- Feature grid: 'Zakat Tracking' → 'Bulletproof Consent'
2026-03-03 17:25:48 +08:00
865c5a1f93 bulletproof consent: Gift Aid (HMRC), email opt-in, WhatsApp opt-in with full audit trail
GIFT AID (HMRC compliance):
- Exact HMRC model declaration text displayed and recorded
- Home address (line 1 + postcode) collected when Gift Aid is ticked
- giftAidAt timestamp recorded separately from the boolean
- Declaration text, donor name, timestamp stored in consentMeta JSON

EMAIL + WHATSAPP (GDPR/PECR compliance):
- Separate, granular opt-in checkboxes (not bundled, not pre-ticked)
- Each consent records: exact text shown, timestamp, consent version
- Consent checkboxes only appear when relevant contact info is provided
- Cron reminders gated on consent — no sends without opt-in
- Pledge creation WhatsApp receipt gated on whatsappOptIn

AUDIT TRAIL (consentMeta JSON on every pledge):
- giftAid: {declared, declarationText, declaredAt}
- email: {granted, consentText, grantedAt}
- whatsapp: {granted, consentText, grantedAt}
- IP address captured server-side from x-forwarded-for
- User agent captured client-side
- consentVersion field for tracking wording changes

EXPORTS:
- CRM CSV now includes: donor_address, donor_postcode, gift_aid_declared_at,
  is_zakat, email_opt_in, whatsapp_opt_in
- Gift Aid export has full HMRC-required fields

Schema: 6 new columns on Pledge (donorAddressLine1, donorPostcode,
giftAidAt, emailOptIn, whatsappOptIn, consentMeta)
2026-03-03 07:38:51 +08:00
e6b7f325da replace PNPL abbreviation with full name in all user-facing copy
- Landing page: 'PNPL captures...' → 'Pledge Now, Pay Later captures...'
- Landing page: 'Who uses PNPL?' → 'Who uses Pledge Now, Pay Later?'
- Landing page: rewrote HNW + fundraiser descriptions to avoid abbreviation
- Dashboard sidebar fallback: 'PNPL' → 'Pledge Now, Pay Later'
- Bank reference prefixes (PNPL-XXXX-50) left as-is — 18-char BACS limit
2026-03-03 07:24:14 +08:00
fc80a43a89 simplify: zakat yes/no per campaign, remove 5 fund types, add I've Donated button for external pledges
- Event.zakatEligible (boolean) replaces Organization.zakatEnabled + 5 fund types
- Pledge.isZakat (boolean) replaces Pledge.fundType enum
- Removed fundAllocation from Event (campaign IS the allocation)
- Identity step: simple checkbox instead of 5-option grid
- Campaign creation: Zakat toggle + optional external URL for self-payment
- External redirect step: 'I've Donated' button calls /api/pledges/[id]/mark-initiated
- Landing page: simplified Zakat section (toggle preview, not 5 fund descriptions)
- Settings: removed org-level Zakat toggle (it's per campaign now)
- Migration: ALTER TABLE adds zakatEligible/isZakat, drops fundAllocation
2026-03-03 07:19:52 +08:00
f87aec7beb full terminology overhaul + zakat fund types + fund allocation
POSITIONING FIX — PNPL is NOT just 'QR codes at events':
- Charities collecting at events (QR per table)
- High-net-worth donor outreach (personal links via WhatsApp/email)
- Org-to-org pledges (multi-charity projects)
- Personal fundraisers (LaunchGood/Enthuse redirect)

TERMINOLOGY (throughout app):
- Events → Campaigns (sidebar, pages, create dialogs, onboarding)
- QR Codes page → Pledge Links (sharing-first, QR is one option)
- Scans → Clicks (not just QR scans)
- 'New Event' → 'New Campaign'
- 'Create QR Code' → 'Create Pledge Link'
- Source label: 'Table Name' → 'Source / Channel'

SHARING (pledge links page):
- 4-button share row: Copy · WhatsApp · Email · More (native share)
- Each link shows its full URL
- Create dialog suggests: 'WhatsApp Family Group, Table 5, Instagram Bio'
- QR code is still shown but as one option, not the hero

LANDING PAGE (complete rewrite):
- Hero: 'Collect pledges. Convert them into donations.'
- 4 use case cards: Events, HNW Donors, Org-to-Org, Personal Fundraisers
- 'Share anywhere' section: WhatsApp, QR, Email, Instagram, Twitter, 1-on-1
- Platform support: Bank Transfer, LaunchGood, Enthuse, JustGiving, GoFundMe, Any URL
- Islamic fund types section: Zakat, Sadaqah, Sadaqah Jariyah, Lillah, Fitrana

ZAKAT & FUND TYPES:
- Organization.zakatEnabled toggle in Settings
- Pledge.fundType: general, zakat, sadaqah, lillah, fitrana
- Identity step: fund type picker (5 options) when org has zakatEnabled
- Zakat note: Quran 9:60 categories reference
- Settings: toggle card with fund type descriptions

FUND ALLOCATION:
- Event.fundAllocation: 'Mosque Building Fund', 'Orphan Sponsorship' etc.
- Charities can also add external URL for reference/allocation (not just fundraisers)
- Shows on campaign cards and pledge flow
2026-03-03 07:00:04 +08:00
0e8df76f89 fundraiser mode: external platforms, role-aware onboarding, show-don't-gate
SCHEMA:
- Organization.orgType: 'charity' | 'fundraiser'
- Organization.whatsappConnected: boolean
- Event.paymentMode: 'self' (bank transfer) | 'external' (redirect to URL)
- Event.externalUrl: fundraising page URL
- Event.externalPlatform: launchgood, enthuse, justgiving, gofundme, other

ONBOARDING (role-aware):
- Dashboard shows getting-started banner AT TOP, not full-page blocker
- First-time users see role picker: 'Charity/Mosque' vs 'Personal Fundraiser'
- POST /api/onboarding sets orgType
- Charity checklist: bank details → WhatsApp → create fundraiser → share link
- Fundraiser checklist: add fundraising page → WhatsApp → share pledge link → first pledge
- WhatsApp is now a core onboarding step for both types
- Banner is dismissable via X button
- Dashboard always shows stats (with zeros), progress bar, empty-state card

SHOW DON'T GATE:
- Stats cards show immediately (with zeros, slightly faded)
- Collection progress bar always visible
- Empty-state card says 'Your pledge data will appear here'
- Getting started is a guidance banner, not a lock screen

EXTERNAL PAYMENT FLOW:
- Events can be paymentMode='external' with externalUrl
- Pledge flow: amount → identity → 'Donate on LaunchGood' redirect (skips schedule + payment method)
- ExternalRedirectStep: branded per platform (LaunchGood green, Enthuse purple, etc.)
- Marks pledge as 'initiated' when donor clicks through
- WhatsApp sends donation link instead of bank details
- Share button shares the external URL

EVENT CREATION:
- Payment mode toggle: 'Bank transfer' vs 'External page'
- External shows URL input + platform dropdown
- Fundraiser orgs default to external mode
- Platform badge on event cards

PLATFORMS SUPPORTED:
🌙 LaunchGood, 💜 Enthuse, 💛 JustGiving, 💚 GoFundMe, 🔗 Other/Custom
2026-03-03 06:42:11 +08:00
05acda0adb auth0: Google login, social auth auto-provisioning
AUTH0 SETUP (done via Management API):
- Created 'Pledge Now Pay Later' app (regular_web) on quikcue.us.auth0.com
- Enabled connections: Google, Apple, Username-Password
- Callback: https://pledge.quikcue.com/api/auth/callback/auth0
- Client ID: hpr7JcEAAk3Q5ADkzyyZSRDxGIZTcjRJ

CODE CHANGES:
- Auth0Provider added to NextAuth alongside existing CredentialsProvider
- findOrCreateSocialUser(): first Google login auto-creates org + user
- Login page: 'Continue with Google' button at top, email/password below
- Signup page: 'Sign up with Google' button at top, form below
- JWT callback: resolves Auth0 users to DB users on every token refresh
- Docker compose: AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, AUTH0_ISSUER env vars

FLOW:
- Click 'Continue with Google' → Auth0 Universal Login → Google consent
- First time: auto-creates '{Name}'s Charity' org + org_admin user
- Return time: finds existing user, loads their org
- Demo login still works via credentials provider
2026-03-03 06:17:34 +08:00
369860d8b9 insanely simple onboarding: 1-screen signup → dashboard checklist
OLD FLOW (8+ screens):
  signup (4 fields) → auto-login → setup wizard step 1 → step 2 → step 3 → step 4 → dashboard

NEW FLOW (2 screens):
  signup (3 fields) → dashboard with inline checklist

- Signup page: just charity name + email + password. No 'your name' field. One button.
- Dashboard: shows getting-started checklist when org has no pledges yet
- /api/onboarding: returns setup progress (bank, event, qr, pledge)
- Checklist: progress bar, next-step highlighting, done states with strikethrough
- Each step links directly to the right page (settings, events, pledges)
- Tip shown for brand new orgs: 'Add bank details first'
- No more separate setup wizard — guidance is inline on the dashboard
- Signup loading state: pulsing emoji while account creates
2026-03-03 06:05:10 +08:00
12ea9691c4 demo login, super admin view, password reset
- Landing page: 'Try the Demo' button links to /login?demo=1
- Login page: 'Try the Demo — no signup needed' button auto-logs in as demo@pnpl.app
- /login?demo=1: auto-triggers demo login on page load
- Super Admin page (/dashboard/admin): platform stats, org list, user list, recent pledges
- /api/admin: returns cross-org data, gated by super_admin role check
- Sidebar shows 'Super Admin' link only for super_admin users
- Password reset: omair@quikcue.com = Omair2026!, demo@pnpl.app = demo1234
- omair@quikcue.com confirmed as super_admin role
2026-03-03 05:55:27 +08:00
5f111d1808 fix: only show WhatsApp QR after user clicks Connect
- Don't auto-poll WAHA on settings page load
- Check connection status once on mount (to show 'Connected' if already paired)
- QR screenshot + polling only starts after clicking 'Connect WhatsApp'
- Polling stops once status changes to CONNECTED
2026-03-03 05:47:20 +08:00
4f23f28873 production auth: signup, login, protected dashboard, landing page, WAHA QR fix
AUTH:
- NextAuth with credentials provider (bcrypt password hashing)
- /api/auth/signup: creates org + user in transaction
- /login, /signup pages with clean minimal UI
- Middleware protects all /dashboard/* routes → redirects to /login
- Session-based org resolution (no more hardcoded 'demo' headers)
- SessionProvider wraps entire app
- Dashboard header shows org name + sign out button

LANDING PAGE:
- Full marketing page at / with hero, problem, how-it-works, features, CTA
- 'Get Started Free' → /signup → auto-login → /dashboard/setup
- Clean responsive design, no auth required for public pages

WAHA QR FIX:
- WAHA CORE doesn't expose QR value via API or webhook
- Now uses /api/screenshot (full browser capture) with CSS crop to QR area
- Settings panel shows cropped screenshot with overflow:hidden
- Auto-polls every 5s, refresh button

MULTI-TENANT:
- getOrgId() tries session first, then header, then first-org fallback
- All dashboard APIs use session-based org
- Signup creates isolated org per charity
2026-03-03 05:37:04 +08:00
6894f091fd waha: QR pairing in dashboard, whatsapp/qr API, settings overhaul
- /api/whatsapp/qr: GET returns session status + QR image, POST starts/restarts session
- Settings page: WhatsApp panel shows QR code for pairing, connected status with phone info
- WAHA session started with webhook pointing to /api/whatsapp/webhook
- WAHA_API_URL updated to external https://waha.quikcue.com (cross-stack DNS doesn't work)
- Auto-polls every 5 seconds during QR scan state
- Shows connected state with phone number, push name, feature summary
2026-03-03 05:19:54 +08:00
c79b9bcabc production: reminder cron, dashboard overhaul, shadcn components, setup wizard
- /api/cron/reminders: processes pending reminders every 15min, sends WhatsApp with email fallback
- /api/cron/overdue: marks overdue pledges daily (7d deferred, 14d immediate)
- /api/pledges: GET handler with filtering, search, pagination, sort by dueDate
- Dashboard overview: stats, collection progress bar, needs attention, upcoming payments
- Dashboard pledges: proper table with status tabs, search, actions, pagination
- New shadcn components: Table, Tabs, DropdownMenu, Progress
- Setup wizard: 4-step onboarding (org → bank → event → QR code)
- Settings API: PUT handler for org create/update
- Org resolver: single-tenant fallback to first org
- Cron jobs installed: reminders every 15min, overdue check at 6am
- Auto-generates installment dates when not provided
- HOSTNAME=0.0.0.0 in compose for multi-network binding
2026-03-03 05:11:17 +08:00
250221b530 feat: deferred payments & installment plans — pledge = promise to pay on a date
CORE PRODUCT SHIFT:
A pledge is now a promise to pay on a future date, not just 'pay now'.

NEW FLOW: Amount → Schedule → Payment/Identity → Confirmation

SCHEDULE STEP (/p/[token] step 1):
- 'Pay right now' — existing card/DD/bank flow
- 'Pay on a specific date' — calendar picker with smart suggestions
  (This Friday, End of month, Payday 1st, In 2 weeks, In 1 month)
- 'Split into monthly payments' — 2/3/4/6/12 month installment plans
  with per-installment breakdown and date schedule

SCHEMA CHANGES:
- Pledge.dueDate — when the donor promises to pay (null = now)
- Pledge.planId — groups installment pledges together
- Pledge.installmentNumber / installmentTotal — e.g. 2 of 4
- Pledge.reminderSentForDueDate — tracking flag
- New indexes on dueDate+status and planId

INSTALLMENT PLANS:
- Creates N linked Pledge records with shared planId
- Each installment gets its own reference, due date, reminders
- Reminders: 2 days before, on due date, 3 days after, 10 days after
- WhatsApp receipt shows full plan summary

DEFERRED SINGLE PLEDGES:
- Reminders anchored to due date, not creation date
- 'Pay on date' → reminders: 2 days before, on day, +3d nudge, +10d final
- WhatsApp preferred when phone number provided

DASHBOARD:
- API returns dueDate, planId, installment info for each pledge
- Confirmation step shows schedule details for deferred pledges
2026-03-03 04:43:19 +08:00
c6e7e4f01e feat: premium UI overhaul, AI suggestions, WAHA WhatsApp integration
PREMIUM UI:
- All animations: fade-up, scale-in, stagger children, confetti celebration
- Glass effects, gradient icons, premium card hover states
- Custom CSS: shimmer, pulse-ring, bounce, counter-roll animations
- Smooth progress bar with gradient

AI-POWERED (GPT-4o-mini nano model):
- Smart amount suggestions based on peer data (/api/ai/suggest)
- Social proof: '42 people pledged · Average £85'
- AI-generated nudge text for conversion
- AI fuzzy matching for bank reconciliation
- AI reminder message generation

WAHA WHATSAPP INTEGRATION:
- Auto-send pledge receipt with bank details via WhatsApp
- 4-step reminder sequence: gentle → nudge → urgent → final
- Chatbot: donors reply PAID, HELP, CANCEL, STATUS
- Volunteer notification on new pledges
- WhatsApp status in dashboard settings
- Webhook endpoint for incoming messages

DONOR FLOW (CRO):
- Amount step: AI suggestions, Gift Aid preview, social proof, haptic feedback
- Payment step: trust signals, fee comparison, benefit badges
- Identity step: email/phone toggle, WhatsApp reminder indicator
- Bank instructions: tap-to-copy each field, WhatsApp delivery confirmation
- Confirmation: confetti, pulse animation, share CTA, WhatsApp receipt

COMPOSE:
- Added WAHA env vars + qc-comms network for WhatsApp access
2026-03-03 04:31:07 +08:00
0236867c88 feat: remove FPX, add UK charity persona features
- Remove FPX payment rail entirely (Malaysian, not UK)
- Add volunteer portal (/v/[code]) with live pledge tracking
- Add public event page (/e/[slug]) with progress bar + social proof
- Add fundraiser leaderboard (/dashboard/events/[id]/leaderboard)
- Add WhatsApp share buttons on confirmation, bank instructions, volunteer view
- Enhanced Gift Aid UX with +25% bonus display and HMRC declaration text
- Gift Aid report export (HMRC-ready CSV filter)
- Volunteer view link + WhatsApp share on QR code cards
- Updated home page: 4 personas, 3 UK payment rails, 8 features
- Public event API endpoint with privacy-safe donor name truncation
- Volunteer API with stats, conversion rate, auto-refresh
2026-03-03 03:47:18 +08:00
Azreen Jamal
1389c848b2 infra.md: full topology map, .env: all server credentials 2026-03-03 03:11:11 +08:00
Azreen Jamal
dfd64112dd infra.md references .env vars only, no hardcoded values 2026-03-03 03:09:13 +08:00
Azreen Jamal
201aa94056 move infra.md to .pi/ 2026-03-03 03:07:09 +08:00
Azreen Jamal
a3c6d09350 remove infra.md.example, infra.md is the source of truth 2026-03-03 03:06:13 +08:00
Azreen Jamal
1ad3033cc1 infra.md: reference only, secrets stay in .env 2026-03-03 03:05:06 +08:00
Azreen Jamal
5e0d80daf9 add infra credentials setup (gitignored secrets, shared template) 2026-03-03 03:01:54 +08:00
Azreen Jamal
f832b913d5 feat: add improved pi agent with observatory, dashboard, and pledge-now-pay-later 2026-03-01 23:41:24 +08:00
IndyDevDan
ae242436c9 pi vs open code 2026-02-26 15:55:17 -06:00
IndyDevDan
32dfe122cb 🚀 2026-02-22 20:19:33 -06:00