Operations module for issuing, tracking, and redeeming gift certificates — loyalty rewards, service recovery credits, and promotional vouchers.
StatCardRow + SegmentedControl + CertificateCard
Filters: All / Active / Partial / Used
EmptyState with IconCircle D hero
CTA leads to Issue screen
Loyal customer since 2022. Issued as part of the Winter Appreciation campaign. Applied toward drain cleaning service.
Terracotta header with IconCircle G lg
Progress bar, recipient, redemption timeline
Nov 20, 2025, 3:45 PM
Promotional campaign ended early. Customer was offered a replacement certificate with extended validity.
Cancelled state with error-bordered card
Empty redemption history, no action buttons
IconCircle G hero header + amount card
Recipient fields are optional
Source select, reason, code, expiration
Source options: Manual, Loyalty, Refund, Promo, Referral, Recovery
Code lookup + balance display + amount input
“Use Full Balance” shortcut button
Error state with IconCircle B lg
Searched code echoed in error message
Value limits, redemption rules, expiration config
IconCircle D lg header
Numbering prefix + loyalty rewards config
Loyalty: threshold, reward value, max per year
index.tsx // Certificate list + stats
[id].tsx // Certificate detail + timeline
new.tsx // Issue certificate form
redeem.tsx // Redeem by code/number
settings.tsx // Feature configuration
// Path: app/(contractor)/(tabs)/(home)/
// operations/gift-certificates/
listGiftCertificates
args: status? // Filter by status
returns: certificates[], hasMore
getGiftCertificate
args: certificateId | code | certificateNumber
returns: full cert + recipient + metadata
getGiftCertificateRedemptions
args: certificateId
returns: redemption[] with balanceBefore/After
getGiftCertificateSettings
returns: limits, expiration, loyalty config
issueGiftCertificate
args: valueCents, source, recipient?,
code?, issueReason?, expirationDays?,
internalNotes?
returns: certificateNumber, certificateId
redeemGiftCertificate
args: certificateId, amountCents,
transactionNote?
returns: amountRedeemed, remainingBalance
extendGiftCertificateExpiration
args: certificateId, additionalDays
cancelGiftCertificate
args: certificateId, reason
upsertGiftCertificateSettings
args: min/maxValue, expiration, loyalty
StatCard / StatCardRow
SegmentedControl // All/Active/Partial/Used
CertificateCard // List item w/ values
EmptyState // IconCircle D hero
Badge // Status + source badges
IconCircle // Styles B, D, G
TextInput / Select / Switch
Prompt // Extend/Cancel dialogs
Button // primary, secondary, outline