Skip to content

Latest commit

 

History

History
328 lines (309 loc) · 10.9 KB

File metadata and controls

328 lines (309 loc) · 10.9 KB

Assist — Reusable React Components Library

References: plan.md, spec.md, UI.md

Summary: This file lists reusable React components, their props, state, events, data binding and responsive behavior.

1) Header

Purpose: Global top navigation, brand, primary actions, user menu. Props:

  • navItems: Array<{ label: string; href: string; icon?: ReactNode }>
  • user?: { id: string; username: string; display_name?: string; avatarUrl?: string; account_type?: 'individual'|'ngo'|'brand' }
  • onSignOut?: () => void
  • onNavigate?: (href: string) => void State:
  • isMobileMenuOpen: boolean
  • isProfileMenuOpen: boolean Events:
  • onNavigate(href)
  • onSignOut Data binding:
  • Reads auth state from context (Supabase Auth) or props; pulls notification counts and unread messages via hooks. Responsive behavior:
  • Desktop: full nav inline.
  • Tablet/Mobile: hamburger → off-canvas drawer; profile collapses to avatar menu.
  • Sticky on scroll with compact header variant.

2) Footer

Purpose: Site links, legal, partners. Props:

  • columns: Array<{ title: string; links: { label: string; href: string }[] }>
  • socialLinks?: Array<{ provider: string; href: string }> State: none (pure presentational) Events: none aside from link clicks Data binding:
  • Static content from CMS/config (/api/settings/footer) Responsive behavior:
  • 3-column grid desktop, stacked single column on mobile; compact spacing. Note: Always display a small trusted-payment footer line — “Payments are securely processed by Paystack.”

3) CampaignCard (list view)

Purpose: Compact campaign preview for feeds and search results. Props:

  • campaign: { id, title, short_description, images: string[], goal, raised, creator: { username, display_name, avatarUrl, account_type }, is_published, status }
  • onClick?: (campaignId: string) => void
  • onDonate?: (campaignId: string) => void State:
  • imageLoaded: boolean
  • isFavorited?: boolean Events:
  • onClick
  • onFavoriteToggle Data binding:
  • From /api/campaigns list or useCampaigns() hook.
  • Progress computed client-side (raised / goal * 100). Responsive behavior:
  • 3-column grid desktop, 2-column tablet, 1-column mobile.
  • Hide long text on small screens; show compact progress bar. Notes:
  • Verified creators aren’t visually marked publicly; account_type badge displayed below title.

4) DonationBox

Purpose: Donation input UI used in campaign sidebar and modal. Props:

  • campaignId: string
  • initialUsername?: string
  • presets?: number[] (quick amounts)
  • minAmount?: number (default ₦50)
  • onSuccess?: (donationId: string) => void
  • paystackPublicKey?: string State:
  • username: string
  • email?: string
  • amount: number | null
  • anonymous: boolean
  • platformFee: number
  • netAmount: number
  • isSubmitting: boolean Events:
  • onValidate
  • onInitiate
  • onPaymentSuccess
  • onPaymentError Data binding:
  • Fetches platform_fee_percent from /api/fees and previews net payout.
  • Posts to /api/donations/initiate then opens Paystack flow; webhook updates donation record. Responsive behavior:
  • Fixed sidebar on desktop; collapsible sticky card or modal on mobile.
  • Inputs stacked vertically on narrow view; preset buttons scroll horizontally. Notes:
  • Username validated with regex:
/^[A-Za-z0-9_]{3,30}$/
  • Anonymous toggle hides username publicly.
  • After success, show donation receipt with paystack_reference, fee, and net amount.
  • Show message: “Funds become available for withdrawal after 24 hours.”

5) LeaderboardCard

Purpose: Display leaderboard entry for donor or campaign. Props:

  • entry: { rank: number; username: string; display_name?: string; amount: number; period?: 'daily'|'weekly'|'monthly' }
  • highlight?: boolean
  • variant?: 'donor'|'campaign' State: none Events:
  • onClickProfile(username) Data binding:
  • From /api/leaderboards?period={period} or campaign-specific /api/leaderboards?campaignId. Responsive behavior:
  • Compact single-line on mobile; avatar hidden on extra-small.
  • Highlight current user if highlight=true. Notes:
  • Leaderboards refresh every 24h; show “Updated {timestamp}”.

6) UpdateBlock + CommentThread (nested)

UpdateBlock Purpose: Show campaign updates (author posts). Props:

  • update: { id, author: { username, display_name, avatarUrl }, title?, body, images?: string[], created_at }
  • onOpenComments?: (updateId) => void State:
  • isExpanded: boolean
  • imageGalleryOpen: boolean Events:
  • expand/collapse
  • open gallery Data binding:
  • /api/campaigns/:id/updates Responsive behavior:
  • single column; images in 2-column grid mobile, 3 desktop.

CommentThread Props:

  • campaignId: string
  • updateId?: string
  • comments: Comment[] Comment object:
  • { id, parent_id?, author, body, created_at, is_anonymous } State:
  • comments, replyDrafts, collapsedParents Events:
  • onPost, onReply, onDelete, onEdit Data binding:
  • /api/campaigns/:id/comments (GET/POST) Responsive behavior:
  • Nested up to depth 5; collapsible replies on mobile. Notes:
  • Guests can comment with optional name; “Post Anonymously” toggle.
  • Realtime updates via Supabase subscription optional.

7) DashboardTabs & Sidebar

Purpose: Dashboard navigation and content switching. DashboardTabs Props:

  • tabs: Array<{ key: string; label: string; badgeCount?: number }>
  • activeKey: string
  • onChange: (key) => void Sidebar Props:
  • items: Array<{ key:string; label:string; icon?:ReactNode; href?:string }>
  • collapsed?: boolean
  • onCollapseToggle?: () => void State:
  • activeKey, isCollapsed, isMobileOpen Events:
  • onNavigate, onCollapseToggle Data binding:
  • Tab counts from /api/dashboard/metrics. Responsive behavior:
  • Desktop: sidebar fixed.
  • Tablet/mobile: slide-over drawer; tabs horizontal scroll on narrow screens. Notes:
  • Sidebar includes “Start New Assist”, “My Campaigns”, “My Donations”, “Verification”, “Withdrawals”, “Settings”.

8) VerificationStatus

Purpose: Show Dojah and Paystack BVN verification statuses and actions. Props:

  • status: { dojah: 'pending'|'passed'|'failed', bvn: 'pending'|'matched'|'mismatch' }
  • onRetry?: (source: 'dojah'|'bvn') => void State:
  • optional isTooltipOpen Events:
  • onRetry Data binding:
  • /api/verifications for latest; Dojah/Paystack webhook updates. Responsive behavior:
  • Inline badges desktop; stacked with text mobile. Notes:
  • Show timestamps and next-step hints (“Upload ID”, “Retry BVN match”).
  • On “Retry”, call verification endpoint.

9) WithdrawalForm

Purpose: Request payout with BVN and bank selection and fee preview. Props:

  • userId: string
  • banks: Array<{ code:string; name:string }>
  • minAmount?: number (default ₦5000)
  • onSubmit?: (payload) => Promise State:
  • selectedBankCode, accountNumber, bvn, amount, feePreview, isSubmitting, errors Events:
  • onValidateAccount, onCalculateFee, onSubmit Data binding:
  • Fetch /api/fees for platform/withdrawal fees.
  • Validate BVN + bank via Paystack /api/paystack/resolve.
  • Submit /api/withdrawals/request. Responsive behavior:
  • Two-column (bank+amount) desktop; stacked mobile.
  • Fee preview fixed below amount. Notes:
  • Mask BVN input; do not persist full BVN client-side.
  • Show “Funds eligible for withdrawal 24h after donation confirmation.”
  • On success, show toast and refresh withdrawal history.

10) AdminAnalyticsChart

Purpose: Charts for donation trends, revenue, campaigns. Props:

  • data: { labels: string[]; series: { name: string; values: number[] }[] }
  • height?: number
  • onFilterChange?: (filters) => void State:
  • selectedRange, loading, hoveredPoint Events:
  • onPointHover, onRangeSelect, onExportCSV Data binding:
  • /api/admin/analytics endpoint. Responsive behavior:
  • Full chart + legend desktop; legend collapses mobile. Implementation:
  • Recharts or ApexCharts with responsive container. Notes:
  • Add “Platform Revenue” and “Total Donations” charts per admin dashboard spec.

11) FeeSettingsForm

Purpose: Admin form to edit platform and withdrawal fees. Props:

  • initial: { platform_fee_percent: number; withdrawal_fee_percent:number; withdrawal_fee_fixed:number }
  • onSave: (newSettings) => Promise State:
  • draftSettings, isSaving, validationErrors, lastSavedAt Events:
  • onChange, onSave, onReset Data binding:
  • /api/admin/settings (GET/POST). Responsive behavior:
  • Single column mobile; inline desktop. Notes:
  • Validate 0–100%.
  • Changes affect new donations only.
  • Show “Last updated by” (admin email) if metadata returned.

12) MediaUpload

Purpose: Upload up to 5 images and one Mux video for campaign creation or updates. Props:

  • maxImages?: number (default 5)
  • allowVideo?: boolean (default true)
  • onChange?: (uploadedMeta) => void
  • uploadImageUrlFn?: (file) => Promise<{ uploadUrl, path }>
  • createMuxUploadUrlFn?: (meta) => Promise<{ uploadUrl, uploadId }> State:
  • images: Array<{ file, previewUrl, status:'pending'|'uploading'|'done'|'error', path? }>
  • video: { file?, previewUrl?, status, muxUploadId?, muxAssetId?, duration? }
  • queueProgress: number Events:
  • onAddFiles, onRemoveFile, onStartUpload, onUploadProgress, onUploadComplete, onError Data binding:
  • Images upload to Supabase Storage via signed URLs.
  • Video uploaded to Mux via direct PUT; webhook updates status. Responsive behavior:
  • Desktop: drag-and-drop grid thumbnails with progress bars.
  • Mobile: vertical list; tap to upload; show warnings for file size/network. Notes:
  • Validate image types, ≤10 MB each, ≤5 images.
  • Validate video ≤200 MB, ≤120 s.
  • Show inline accessible error messages.

13) WebhookLogsTable

Purpose: Admin tool to review webhook and system event logs. Props:

  • logs: Array<{ id:string; source:'paystack'|'dojah'|'mux'; event_type:string; status:'success'|'failed'; created_at:string; payload_excerpt:string }>
  • onRetry?: (id:string) => void State:
  • expandedRow?: string Events:
  • onRetry, row expand/collapse Data binding:
  • /api/admin/webhooks (GET/POST for retry). Responsive behavior:
  • Table desktop; stacked cards mobile. Notes:
  • Mask sensitive fields (e.g., BVN).
  • Color-code sources; failed rows red border.
  • Allow CSV export of filtered logs.

14) NotificationDropdown

Purpose: Show notifications (new donations, verification updates, withdrawals). Props:

  • notifications: Array<{ id:string; type:string; message:string; created_at:string; read:boolean }>
  • onMarkRead?: (id:string) => void
  • onViewAll?: () => void State:
  • isOpen, highlightedId? Events:
  • onMarkRead, onViewAll Data binding:
  • /api/notifications (GET/PATCH). Responsive behavior:
  • Popover on desktop, full-screen sheet mobile. Notes:
  • Unread indicator badge in Header icon.
  • Auto-mark as read when opened.

15) DonationReceiptModal

Purpose: Show confirmed donation summary after Paystack success. Props:

  • donation: { id, campaignTitle, amount, platform_fee, net_amount, paystack_reference, created_at }
  • onClose: () => void State: none Events:
  • onClose
  • share link Data binding:
  • Receives data from donation success callback. Responsive behavior:
  • Centered modal desktop, full-screen mobile. Notes:
  • Include “Share this campaign” CTA.
  • Display “Funds available to creator after 24 h hold.”

End of components spec.