{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "loyalty-rewards-tier-hub",
  "title": "Loyalty Rewards Tier Hub",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/loyalty-rewards-tier-hub/LoyaltyRewardsTierHub.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Award,\n  Check,\n  Crown,\n  Gift,\n  Headphones,\n  History,\n  Lock,\n  ShoppingBag,\n  Tag,\n  Ticket,\n  Truck,\n  Zap,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Avatar, AvatarFallback } from '@/components/ui/avatar'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Progress } from '@/components/ui/progress'\nimport { Separator } from '@/components/ui/separator'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\n\nexport interface LoyaltyPerk {\n  id: string\n  title: string\n  subtitle: string\n  description: string\n  status: 'active' | 'locked'\n  tierBadge: string\n  unlockPoints?: number\n}\n\nexport interface LoyaltyReward {\n  id: string\n  title: string\n  category: string\n  pointsCost: number\n  description: string\n  unlocked: boolean\n  pointsNeeded?: number\n  code?: string\n}\n\nexport interface LoyaltyLedgerEntry {\n  id: string\n  title: string\n  subtitle: string\n  type: string\n  date: string\n  pointsChange: number\n  isPositive: boolean\n}\n\nexport interface LoyaltyRewardsTierHubProps {\n  customerName?: string\n  tierName?: string\n  currentPoints?: number\n  targetPoints?: number\n  pointValueDollars?: number\n  multiplier?: string\n  className?: string\n}\n\nconst perks: LoyaltyPerk[] = [\n  {\n    id: 'perk-shipping',\n    title: 'Free Express Shipping on All Orders',\n    subtitle: 'All Orders',\n    description: 'Complimentary 2-day express shipping on every online order with zero minimum spend.',\n    status: 'active',\n    tierBadge: 'Active',\n  },\n  {\n    id: 'perk-archive',\n    title: 'Early Access to Private Archive Sales',\n    subtitle: '48h Early Access',\n    description: 'Shop seasonal private archives and limited capsule releases 48 hours before public launch.',\n    status: 'active',\n    tierBadge: 'Active',\n  },\n  {\n    id: 'perk-stylist',\n    title: 'Dedicated VIP Concierge & Personal Stylist',\n    subtitle: '1-on-1 Stylist Line',\n    description: 'Direct priority chat with our senior stylists for bespoke fashion curation and concierge care.',\n    status: 'active',\n    tierBadge: 'Active',\n  },\n  {\n    id: 'perk-annual-gift',\n    title: 'Diamond Exclusive Annual Gift',\n    subtitle: 'Bespoke Curated Box',\n    description: 'Curated luxury anniversary gift box ($120+ retail value) delivered automatically each winter.',\n    status: 'locked',\n    tierBadge: 'Unlocks at 3,000 pts',\n    unlockPoints: 3000,\n  },\n]\n\nconst rewards: LoyaltyReward[] = [\n  {\n    id: 'reward-15-off',\n    title: '$15 Off Any Order',\n    category: 'Store Credit Voucher',\n    pointsCost: 1500,\n    description: 'Instant digital coupon applied at checkout on any order above $50.',\n    unlocked: true,\n    code: 'VIP-SAVE15',\n  },\n  {\n    id: 'reward-leather-pouch',\n    title: 'Free Travel Leather Pouch',\n    category: 'Exclusive Merchandise',\n    pointsCost: 2000,\n    description: 'Handcrafted Italian pebbled leather travel accessory pouch in signature Midnight Noir.',\n    unlocked: true,\n    code: 'CLAIM-POUCH24',\n  },\n  {\n    id: 'reward-audio-30',\n    title: '$30 Off Premium Audio',\n    category: 'Partner Exclusive',\n    pointsCost: 3000,\n    description: 'Exclusive member markdown on noise-cancelling headphones and studio sound gear.',\n    unlocked: false,\n    pointsNeeded: 550,\n  },\n]\n\nconst ledgerTransactions: LoyaltyLedgerEntry[] = [\n  {\n    id: 'tx-1',\n    title: 'Order #ORD-9428 - Studio Silk Blouse',\n    subtitle: 'Online Purchase · $190.00 subtotal',\n    type: 'Earned · 2x Platinum Multiplier',\n    date: 'Oct 18, 2024',\n    pointsChange: 380,\n    isPositive: true,\n  },\n  {\n    id: 'tx-2',\n    title: 'Redeemed: $10 Voucher Code #VIP-10OFF',\n    subtitle: 'Rewards Catalog · Checkout Redemption',\n    type: 'Reward Redemption',\n    date: 'Oct 10, 2024',\n    pointsChange: -1000,\n    isPositive: false,\n  },\n  {\n    id: 'tx-3',\n    title: 'Order #ORD-9104 - Cashmere Wrap',\n    subtitle: 'Online Purchase · $320.00 subtotal',\n    type: 'Earned · 2x Platinum Multiplier',\n    date: 'Sep 29, 2024',\n    pointsChange: 640,\n    isPositive: true,\n  },\n  {\n    id: 'tx-4',\n    title: 'Tier Upgrade Bonus - Platinum Milestone',\n    subtitle: 'Milestone Threshold · 2,000 pts Achieved',\n    type: 'Milestone Tier Reward',\n    date: 'Sep 15, 2024',\n    pointsChange: 500,\n    isPositive: true,\n  },\n]\n\nexport function LoyaltyRewardsTierHub({\n  customerName = 'Elena Rostova',\n  tierName = 'VIP Platinum Member',\n  currentPoints = 2450,\n  targetPoints = 3000,\n  pointValueDollars = 24.5,\n  multiplier = '2x Points Multiplier',\n  className,\n}: LoyaltyRewardsTierHubProps) {\n  const [redeemedMap, setRedeemedMap] = React.useState<Record<string, boolean>>({})\n\n  const handleRedeem = (rewardId: string) => {\n    setRedeemedMap((prev) => ({ ...prev, [rewardId]: true }))\n  }\n\n  return (\n    <div data-slot=\"loyalty-rewards-tier-hub\" className={cn('mx-auto w-full max-w-5xl space-y-6', className)}>\n      {/* Header Section */}\n      <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n        <div>\n          <div className=\"flex items-center gap-2\">\n            <Badge wrap variant=\"secondary\" className=\"gap-1.5 font-medium\">\n              <Award className=\"text-primary size-3.5\" aria-hidden=\"true\" />\n              VIP Rewards Club\n            </Badge>\n          </div>\n          <h1 className=\"text-foreground mt-2 text-2xl font-bold tracking-tight sm:text-3xl\">\n            Loyalty &amp; Rewards Hub\n          </h1>\n          <p className=\"text-muted-foreground mt-1 max-w-2xl text-sm sm:text-base\">\n            Track VIP tier progress, redeem points for luxury perks, and review your member transaction ledger.\n          </p>\n        </div>\n      </div>\n\n      {/* Customer Loyalty Hero Card */}\n      <Card className=\"border-border/80 shadow-xs\">\n        <CardContent className=\"space-y-6 p-6\">\n          {/* Profile Header & Tier Status */}\n          <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n            <div className=\"flex items-center gap-4\">\n              <Avatar className=\"border-primary/20 size-14 border-2 shadow-xs\">\n                <AvatarFallback className=\"bg-primary/10 text-primary text-base font-semibold\">ER</AvatarFallback>\n              </Avatar>\n              <div>\n                <h2 className=\"text-foreground text-lg font-bold tracking-tight sm:text-xl\">{customerName}</h2>\n                <p className=\"text-muted-foreground text-xs font-medium sm:text-sm\">{tierName} · Member since 2022</p>\n              </div>\n            </div>\n\n            <Badge\n              wrap\n              variant=\"outline\"\n              className=\"border-primary/20 bg-primary/10 text-primary gap-1.5 px-3 py-1.5 text-xs font-semibold\"\n            >\n              <Crown className=\"text-primary size-3.5 shrink-0\" aria-hidden=\"true\" />\n              <span>Platinum Tier · 2x Points Multiplier</span>\n            </Badge>\n          </div>\n\n          <Separator />\n\n          {/* Points Balance & Multiplier Display */}\n          <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n            {/* Balance Stat */}\n            <div className=\"border-border/60 bg-muted/30 flex flex-col justify-between rounded-xl border p-4\">\n              <div>\n                <p className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                  Available Points Balance\n                </p>\n                <div className=\"mt-1 flex items-baseline gap-2\">\n                  <span className=\"text-foreground text-3xl font-bold tracking-tight tabular-nums sm:text-4xl\">\n                    2,450\n                  </span>\n                  <span className=\"text-muted-foreground text-sm font-medium\">Points</span>\n                </div>\n              </div>\n              <p className=\"text-muted-foreground mt-3 text-xs font-medium\">\n                Estimated reward cash value:{' '}\n                <span className=\"text-success text-success font-semibold tabular-nums\">$24.50 reward value</span>\n              </p>\n            </div>\n\n            {/* Tier Multiplier Stat */}\n            <div className=\"border-border/60 bg-muted/30 flex flex-col justify-between rounded-xl border p-4\">\n              <div>\n                <p className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                  Current Multiplier\n                </p>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <span className=\"text-foreground text-3xl font-bold tracking-tight tabular-nums sm:text-4xl\">2x</span>\n                  <Badge wrap variant=\"success\" className=\"gap-1 text-xs\">\n                    <Zap className=\"size-3\" aria-hidden=\"true\" />\n                    Active\n                  </Badge>\n                </div>\n              </div>\n              <p className=\"text-muted-foreground mt-3 text-xs font-medium\">\n                Earn 2 points per $1 spent on all boutique catalog orders.\n              </p>\n            </div>\n\n            {/* Next Reward Threshold */}\n            <div className=\"border-border/60 bg-muted/30 flex flex-col justify-between rounded-xl border p-4 sm:col-span-2 lg:col-span-1\">\n              <div>\n                <p className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">Next Tier Goal</p>\n                <div className=\"mt-1 flex items-baseline gap-2\">\n                  <span className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums sm:text-3xl\">\n                    550 pts\n                  </span>\n                  <span className=\"text-muted-foreground text-xs font-medium\">to Diamond VIP</span>\n                </div>\n              </div>\n              <p className=\"text-muted-foreground mt-3 text-xs font-medium\">\n                Unlocks 3x points multiplier and annual exclusive gift.\n              </p>\n            </div>\n          </div>\n\n          {/* Next Tier Progress Bar Section */}\n          <div className=\"border-border/80 bg-muted/40 space-y-2.5 rounded-xl border p-4\">\n            <div className=\"flex flex-wrap items-center justify-between gap-2 text-xs sm:text-sm\">\n              <div className=\"flex items-center gap-2\">\n                <Award className=\"text-primary size-4 shrink-0\" aria-hidden=\"true\" />\n                <span className=\"text-foreground font-semibold\">Next Tier Progress: Diamond VIP</span>\n              </div>\n              <span className=\"text-foreground font-semibold tabular-nums\">2,450 / 3,000 Points</span>\n            </div>\n\n            <Progress value={81.6} className=\"h-2.5\" />\n\n            <div className=\"flex flex-wrap items-center justify-between gap-2 text-xs\">\n              <span className=\"text-muted-foreground font-medium tabular-nums\">\n                81.6% to Diamond VIP · 550 points to upgrade\n              </span>\n              <span className=\"text-muted-foreground\">Target qualification date: Dec 31, 2024</span>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* 4 VIP Tier Privilege Perks Summary */}\n      <div className=\"space-y-3\">\n        <div className=\"flex items-center justify-between gap-2\">\n          <div>\n            <h3 className=\"text-foreground text-base font-semibold\">VIP Tier Privilege Perks</h3>\n            <p className=\"text-muted-foreground text-xs\">\n              Active benefits unlocked with your Platinum status and next-tier Diamond previews.\n            </p>\n          </div>\n          <Badge wrap variant=\"outline\" className=\"shrink-0 text-xs font-medium tabular-nums\">\n            3 of 4 Perks Active\n          </Badge>\n        </div>\n\n        <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n          {perks.map((perk) => (\n            <div\n              key={perk.id}\n              className={cn(\n                'flex flex-col justify-between rounded-xl border p-4 transition-colors',\n                perk.status === 'active'\n                  ? 'border-border/80 bg-card shadow-xs'\n                  : 'border-border/60 bg-muted/20 opacity-85',\n              )}\n            >\n              <div className=\"space-y-3\">\n                <div className=\"flex items-center justify-between gap-2\">\n                  <div\n                    className={cn(\n                      'flex size-9 shrink-0 items-center justify-center rounded-lg border',\n                      perk.id === 'perk-shipping' && 'border-success/20 bg-success/10 text-success',\n                      perk.id === 'perk-archive' && 'border-chart-1/30 bg-chart-1/10 text-chart-1',\n                      perk.id === 'perk-stylist' && 'border-info/20 bg-info/10 text-info',\n                      perk.id === 'perk-annual-gift' && 'border-border/60 bg-muted text-muted-foreground',\n                    )}\n                  >\n                    {perk.id === 'perk-shipping' && <Truck className=\"size-4\" aria-hidden=\"true\" />}\n                    {perk.id === 'perk-archive' && <Tag className=\"size-4\" aria-hidden=\"true\" />}\n                    {perk.id === 'perk-stylist' && <Headphones className=\"size-4\" aria-hidden=\"true\" />}\n                    {perk.id === 'perk-annual-gift' && <Gift className=\"size-4\" aria-hidden=\"true\" />}\n                  </div>\n\n                  {perk.status === 'active' ? (\n                    <Badge wrap variant=\"success\" className=\"gap-1 text-xs\">\n                      <Check className=\"size-3\" aria-hidden=\"true\" />\n                      Active\n                    </Badge>\n                  ) : (\n                    <Badge wrap variant=\"secondary\" className=\"text-muted-foreground gap-1 text-xs\">\n                      <Lock className=\"size-3\" aria-hidden=\"true\" />\n                      Unlocks at 3,000 pts\n                    </Badge>\n                  )}\n                </div>\n\n                <div>\n                  <p className=\"text-foreground text-sm font-semibold\">{perk.title}</p>\n                  <p className=\"text-muted-foreground mt-0.5 text-xs font-medium\">{perk.subtitle}</p>\n                  <p className=\"text-muted-foreground mt-2 text-xs leading-relaxed\">{perk.description}</p>\n                </div>\n              </div>\n\n              <div className=\"border-border/50 mt-4 border-t pt-3\">\n                <span className=\"text-muted-foreground text-xs\">\n                  {perk.status === 'active' ? 'Included in Platinum VIP' : 'Requires Diamond Tier'}\n                </span>\n              </div>\n            </div>\n          ))}\n        </div>\n      </div>\n\n      {/* Rewards Catalog Grid (3 unlockable rewards) */}\n      <div className=\"space-y-3\">\n        <div className=\"flex items-center justify-between gap-2\">\n          <div>\n            <h3 className=\"text-foreground text-base font-semibold\">Rewards Catalog</h3>\n            <p className=\"text-muted-foreground text-xs\">\n              Redeem your points balance for instant discount vouchers and complimentary luxury items.\n            </p>\n          </div>\n          <Badge wrap variant=\"outline\" className=\"shrink-0 text-xs font-medium tabular-nums\">\n            2 Available to Redeem\n          </Badge>\n        </div>\n\n        <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n          {rewards.map((reward) => (\n            <Card\n              key={reward.id}\n              className={cn(\n                'border-border/80 flex flex-col justify-between shadow-xs transition-colors',\n                !reward.unlocked && 'bg-muted/20 opacity-90',\n              )}\n            >\n              <CardHeader className=\"pb-3\">\n                <div className=\"flex items-center justify-between gap-2\">\n                  <Badge wrap variant=\"secondary\" className=\"min-w-0 shrink text-xs font-medium\">\n                    {reward.category}\n                  </Badge>\n                  <div className=\"shrink-0 text-right\">\n                    <span className=\"text-foreground text-sm font-bold tabular-nums\">\n                      {reward.pointsCost.toLocaleString()} pts\n                    </span>\n                  </div>\n                </div>\n                <CardTitle className=\"mt-2 text-base font-semibold\">{reward.title}</CardTitle>\n                <CardDescription className=\"text-xs leading-relaxed\">{reward.description}</CardDescription>\n              </CardHeader>\n\n              <CardContent className=\"pb-3\">\n                {/* When locked, show points shortfall */}\n                {!reward.unlocked ? (\n                  <div className=\"space-y-1.5\">\n                    <div className=\"flex items-center justify-between text-xs\">\n                      <span className=\"text-muted-foreground\">Progress to unlock</span>\n                      <span className=\"text-foreground font-semibold tabular-nums\">2,450 / 3,000 pts</span>\n                    </div>\n                    <Progress value={81.6} className=\"h-1.5\" />\n                  </div>\n                ) : redeemedMap[reward.id] ? (\n                  <div className=\"border-success/30 bg-success/10 text-success rounded-md border p-2.5 text-center text-xs font-medium\">\n                    <div className=\"flex items-center justify-center gap-1\">\n                      <Check className=\"size-3.5\" aria-hidden=\"true\" />\n                      <span>Redeemed! Code:</span>\n                      <span className=\"font-mono font-bold\">{reward.code}</span>\n                    </div>\n                  </div>\n                ) : null}\n              </CardContent>\n\n              <CardFooter className=\"pt-0\">\n                {reward.unlocked && !redeemedMap[reward.id] && (\n                  <Button\n                    type=\"button\"\n                    className=\"w-full gap-1.5 text-xs font-medium\"\n                    onClick={() => handleRedeem(reward.id)}\n                  >\n                    <Tag className=\"size-3.5\" aria-hidden=\"true\" />\n                    <span>Redeem Reward</span>\n                  </Button>\n                )}\n\n                {reward.unlocked && redeemedMap[reward.id] && (\n                  <Button\n                    type=\"button\"\n                    variant=\"outline\"\n                    className=\"border-success/40 text-success w-full gap-1.5 text-xs font-medium\"\n                    disabled\n                  >\n                    <Check className=\"size-3.5\" aria-hidden=\"true\" />\n                    <span>Voucher Claimed</span>\n                  </Button>\n                )}\n\n                {!reward.unlocked && (\n                  <Button type=\"button\" variant=\"outline\" disabled className=\"w-full gap-1.5 text-xs font-medium\">\n                    <Lock className=\"size-3.5\" aria-hidden=\"true\" />\n                    <span>Locked · Need {reward.pointsNeeded} pts</span>\n                  </Button>\n                )}\n              </CardFooter>\n            </Card>\n          ))}\n        </div>\n      </div>\n\n      {/* Points History Ledger */}\n      <Card className=\"border-border/80 shadow-xs\">\n        <CardHeader className=\"pb-4\">\n          <div className=\"flex items-center justify-between gap-2\">\n            <div>\n              <div className=\"flex items-center gap-2\">\n                <History className=\"text-muted-foreground size-4\" aria-hidden=\"true\" />\n                <CardTitle className=\"text-base font-semibold\">Points History Ledger</CardTitle>\n              </div>\n              <CardDescription>Recent earnings and redemption transactions on your VIP account.</CardDescription>\n            </div>\n            <Badge wrap variant=\"outline\" className=\"shrink-0 text-xs font-medium tabular-nums\">\n              Recent 4 Transactions\n            </Badge>\n          </div>\n        </CardHeader>\n\n        <CardContent className=\"p-0 sm:p-6 sm:pt-0\">\n          <div className=\"overflow-x-auto\">\n            <Table density=\"cozy\">\n              <TableHeader>\n                <TableRow>\n                  <TableHead>Transaction Details</TableHead>\n                  <TableHead>Type &amp; Multiplier</TableHead>\n                  <TableHead>Date</TableHead>\n                  <TableHead className=\"text-right\">Points Change</TableHead>\n                </TableRow>\n              </TableHeader>\n              <TableBody>\n                {ledgerTransactions.map((tx) => (\n                  <TableRow key={tx.id}>\n                    <TableCell>\n                      <div className=\"flex items-center gap-3\">\n                        <div\n                          className={cn(\n                            'flex size-8 shrink-0 items-center justify-center rounded-lg border',\n                            tx.isPositive\n                              ? 'border-success/20 bg-success/10 text-success'\n                              : 'border-border/60 bg-muted text-muted-foreground',\n                          )}\n                        >\n                          {tx.isPositive && tx.pointsChange < 500 && (\n                            <ShoppingBag className=\"size-4\" aria-hidden=\"true\" />\n                          )}\n                          {tx.isPositive && tx.pointsChange >= 500 && <Crown className=\"size-4\" aria-hidden=\"true\" />}\n                          {!tx.isPositive && <Ticket className=\"size-4\" aria-hidden=\"true\" />}\n                        </div>\n                        <div className=\"min-w-0\">\n                          <p className=\"text-foreground truncate text-sm font-medium\">{tx.title}</p>\n                          <p className=\"text-muted-foreground truncate text-xs\">{tx.subtitle}</p>\n                        </div>\n                      </div>\n                    </TableCell>\n                    <TableCell>\n                      {tx.type.includes('Multiplier') ? (\n                        <Badge wrap variant=\"outline\" className=\"gap-1 text-xs font-medium\">\n                          <Zap className=\"text-warning size-3\" aria-hidden=\"true\" />\n                          {tx.type}\n                        </Badge>\n                      ) : tx.type.includes('Milestone') ? (\n                        <Badge\n                          wrap\n                          variant=\"outline\"\n                          className=\"border-primary/20 bg-primary/10 text-primary gap-1 text-xs font-medium\"\n                        >\n                          <Crown className=\"text-primary size-3\" aria-hidden=\"true\" />\n                          {tx.type}\n                        </Badge>\n                      ) : (\n                        <Badge wrap variant=\"secondary\" className=\"text-muted-foreground gap-1 text-xs font-medium\">\n                          <Ticket className=\"size-3\" aria-hidden=\"true\" />\n                          {tx.type}\n                        </Badge>\n                      )}\n                    </TableCell>\n                    <TableCell className=\"text-muted-foreground text-xs whitespace-nowrap sm:text-sm\">\n                      {tx.date}\n                    </TableCell>\n                    <TableCell className=\"text-right text-xs font-medium tabular-nums sm:text-sm\">\n                      <span\n                        className={tx.isPositive ? 'text-success font-bold' : 'text-muted-foreground font-semibold'}\n                      >\n                        {tx.isPositive\n                          ? `+${tx.pointsChange.toLocaleString()} pts`\n                          : `${tx.pointsChange.toLocaleString()} pts`}\n                      </span>\n                    </TableCell>\n                  </TableRow>\n                ))}\n              </TableBody>\n            </Table>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/LoyaltyRewardsTierHub.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/avatar.json",
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/progress.json",
    "https://uipkge.dev/r/react/separator.json",
    "https://uipkge.dev/r/react/table.json"
  ],
  "description": "Sephora and Starbucks style VIP customer loyalty tier dashboard, points wallet, and rewards catalog. Features a customer hero card with points balance, reward valuation, and tier progress tracker, 4 VIP privilege perks with unlock statuses, a 3-item redeemable rewards catalog grid, and a recent points earnings & redemption history ledger.",
  "categories": [
    "commerce",
    "ecommerce",
    "dashboard",
    "marketing"
  ]
}