@burdenoff/microfe-subscriberbot 2026.624.1 → 2026.626.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/subscriberbot/components/EmptyState.js +17 -10
  2. package/dist/subscriberbot/components/EmptyState.js.map +1 -1
  3. package/dist/subscriberbot/components/InvestmentCard.js +23 -22
  4. package/dist/subscriberbot/components/InvestmentCard.js.map +1 -1
  5. package/dist/subscriberbot/components/MetricsCard.js +15 -12
  6. package/dist/subscriberbot/components/MetricsCard.js.map +1 -1
  7. package/dist/subscriberbot/components/PageLayout.js +27 -15
  8. package/dist/subscriberbot/components/PageLayout.js.map +1 -1
  9. package/dist/subscriberbot/components/RatingDisplay.js +3 -3
  10. package/dist/subscriberbot/components/RatingDisplay.js.map +1 -1
  11. package/dist/subscriberbot/components/StatusBadge.js +25 -13
  12. package/dist/subscriberbot/components/StatusBadge.js.map +1 -1
  13. package/dist/subscriberbot/context/SubscriberBotContext.js.map +1 -1
  14. package/dist/subscriberbot/pages/HomePage.js +72 -63
  15. package/dist/subscriberbot/pages/HomePage.js.map +1 -1
  16. package/dist/subscriberbot/pages/admin/AdminAnalyticsPage.js +106 -100
  17. package/dist/subscriberbot/pages/admin/AdminAnalyticsPage.js.map +1 -1
  18. package/dist/subscriberbot/pages/admin/AdminDashboard.js +125 -85
  19. package/dist/subscriberbot/pages/admin/AdminDashboard.js.map +1 -1
  20. package/dist/subscriberbot/pages/admin/AdminFinancialPage.js +51 -45
  21. package/dist/subscriberbot/pages/admin/AdminFinancialPage.js.map +1 -1
  22. package/dist/subscriberbot/pages/admin/AdminOrdersPage.js +246 -241
  23. package/dist/subscriberbot/pages/admin/AdminOrdersPage.js.map +1 -1
  24. package/dist/subscriberbot/pages/admin/AdminProfilePage.js +131 -129
  25. package/dist/subscriberbot/pages/admin/AdminProfilePage.js.map +1 -1
  26. package/dist/subscriberbot/pages/admin/AdminSettingsPage.js +247 -242
  27. package/dist/subscriberbot/pages/admin/AdminSettingsPage.js.map +1 -1
  28. package/dist/subscriberbot/pages/admin/CartManagementPage.js +307 -302
  29. package/dist/subscriberbot/pages/admin/CartManagementPage.js.map +1 -1
  30. package/dist/subscriberbot/pages/admin/UserManagementPage.js +308 -303
  31. package/dist/subscriberbot/pages/admin/UserManagementPage.js.map +1 -1
  32. package/dist/subscriberbot/pages/cart-owner/AnalyticsDashboard.js +89 -84
  33. package/dist/subscriberbot/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
  34. package/dist/subscriberbot/pages/cart-owner/BusinessSettingsPage.js +269 -264
  35. package/dist/subscriberbot/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
  36. package/dist/subscriberbot/pages/cart-owner/CartOwnerDashboard.js +269 -227
  37. package/dist/subscriberbot/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
  38. package/dist/subscriberbot/pages/cart-owner/CartOwnerProfilePage.js +191 -186
  39. package/dist/subscriberbot/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
  40. package/dist/subscriberbot/pages/cart-owner/CartServiceConfigPage.js +168 -166
  41. package/dist/subscriberbot/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
  42. package/dist/subscriberbot/pages/cart-owner/InventoryManagementPage.js +344 -347
  43. package/dist/subscriberbot/pages/cart-owner/InventoryManagementPage.js.map +1 -1
  44. package/dist/subscriberbot/pages/cart-owner/OrderManagementPage.js +270 -272
  45. package/dist/subscriberbot/pages/cart-owner/OrderManagementPage.js.map +1 -1
  46. package/dist/subscriberbot/pages/cart-owner/StaffManagementPage.js +294 -289
  47. package/dist/subscriberbot/pages/cart-owner/StaffManagementPage.js.map +1 -1
  48. package/dist/subscriberbot/pages/common/HelpSupportPage.js +156 -158
  49. package/dist/subscriberbot/pages/common/HelpSupportPage.js.map +1 -1
  50. package/dist/subscriberbot/pages/common/NotificationCenterPage.js +94 -87
  51. package/dist/subscriberbot/pages/common/NotificationCenterPage.js.map +1 -1
  52. package/dist/subscriberbot/pages/common/SettingsPage.js +749 -740
  53. package/dist/subscriberbot/pages/common/SettingsPage.js.map +1 -1
  54. package/dist/subscriberbot/pages/customer/BookingDetailsPage.js +357 -324
  55. package/dist/subscriberbot/pages/customer/BookingDetailsPage.js.map +1 -1
  56. package/dist/subscriberbot/pages/customer/CartDetailPage.js +281 -247
  57. package/dist/subscriberbot/pages/customer/CartDetailPage.js.map +1 -1
  58. package/dist/subscriberbot/pages/customer/CartDiscoveryPage.js +106 -98
  59. package/dist/subscriberbot/pages/customer/CartDiscoveryPage.js.map +1 -1
  60. package/dist/subscriberbot/pages/customer/CheckoutPage.js +235 -238
  61. package/dist/subscriberbot/pages/customer/CheckoutPage.js.map +1 -1
  62. package/dist/subscriberbot/pages/customer/CustomerDashboard.js +426 -390
  63. package/dist/subscriberbot/pages/customer/CustomerDashboard.js.map +1 -1
  64. package/dist/subscriberbot/pages/customer/CustomerProfilePage.js +488 -479
  65. package/dist/subscriberbot/pages/customer/CustomerProfilePage.js.map +1 -1
  66. package/dist/subscriberbot/pages/customer/DirectServiceBookingPage.js +522 -512
  67. package/dist/subscriberbot/pages/customer/DirectServiceBookingPage.js.map +1 -1
  68. package/dist/subscriberbot/pages/customer/FavoritesPage.js +73 -66
  69. package/dist/subscriberbot/pages/customer/FavoritesPage.js.map +1 -1
  70. package/dist/subscriberbot/pages/customer/OrderHistoryPage.js +75 -67
  71. package/dist/subscriberbot/pages/customer/OrderHistoryPage.js.map +1 -1
  72. package/dist/subscriberbot/pages/customer/OrderTrackingPage.js +82 -76
  73. package/dist/subscriberbot/pages/customer/OrderTrackingPage.js.map +1 -1
  74. package/dist/subscriberbot/pages/customer/PaymentMethodsPage.js +100 -93
  75. package/dist/subscriberbot/pages/customer/PaymentMethodsPage.js.map +1 -1
  76. package/dist/subscriberbot/pages/customer/ReviewsPage.js +97 -90
  77. package/dist/subscriberbot/pages/customer/ReviewsPage.js.map +1 -1
  78. package/dist/subscriberbot/pages/customer/SavedAddressesPage.js +86 -79
  79. package/dist/subscriberbot/pages/customer/SavedAddressesPage.js.map +1 -1
  80. package/dist/subscriberbot/pages/investor/InvestmentDetailsPage.js +330 -293
  81. package/dist/subscriberbot/pages/investor/InvestmentDetailsPage.js.map +1 -1
  82. package/dist/subscriberbot/pages/investor/InvestmentOpportunitiesPage.js +269 -261
  83. package/dist/subscriberbot/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
  84. package/dist/subscriberbot/pages/investor/InvestorAnalyticsPage.js +97 -91
  85. package/dist/subscriberbot/pages/investor/InvestorAnalyticsPage.js.map +1 -1
  86. package/dist/subscriberbot/pages/investor/InvestorDashboard.js +354 -322
  87. package/dist/subscriberbot/pages/investor/InvestorDashboard.js.map +1 -1
  88. package/dist/subscriberbot/pages/investor/InvestorInvestmentsPage.js +118 -111
  89. package/dist/subscriberbot/pages/investor/InvestorInvestmentsPage.js.map +1 -1
  90. package/dist/subscriberbot/pages/investor/InvestorPortfolioPage.js +75 -69
  91. package/dist/subscriberbot/pages/investor/InvestorPortfolioPage.js.map +1 -1
  92. package/dist/subscriberbot/pages/investor/InvestorProfilePage.js +435 -430
  93. package/dist/subscriberbot/pages/investor/InvestorProfilePage.js.map +1 -1
  94. package/dist/subscriberbot/pages/worker/TaskDetailsPage.js +328 -289
  95. package/dist/subscriberbot/pages/worker/TaskDetailsPage.js.map +1 -1
  96. package/dist/subscriberbot/pages/worker/WorkerDashboard.js +135 -103
  97. package/dist/subscriberbot/pages/worker/WorkerDashboard.js.map +1 -1
  98. package/dist/subscriberbot/pages/worker/WorkerOrdersPage.js +120 -114
  99. package/dist/subscriberbot/pages/worker/WorkerOrdersPage.js.map +1 -1
  100. package/dist/subscriberbot/pages/worker/WorkerProfilePage.js +125 -120
  101. package/dist/subscriberbot/pages/worker/WorkerProfilePage.js.map +1 -1
  102. package/dist/subscriberbot/pages/worker/WorkerSchedulePage.js +354 -344
  103. package/dist/subscriberbot/pages/worker/WorkerSchedulePage.js.map +1 -1
  104. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"ReviewsPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/customer/ReviewsPage.tsx"],"sourcesContent":["/**\n * Reviews Page\n * @module subscriberbot/pages/customer\n *\n * Full-featured reviews: Write Review modal (interactive star rating with\n * text labels, title, comment, guidelines), Owner Response callout,\n * review images, verified badge, Mark as Helpful toggle, 4 filters\n * (search, type, rating, sort), Your Review label, 5 mock reviews.\n */\n\nimport { useState, useCallback } from 'react';\nimport {\n Star,\n MessageSquare,\n ThumbsUp,\n PenSquare,\n X,\n CheckCircle2,\n Image,\n MessageCircle,\n Info,\n Search,\n} from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { RatingDisplay } from '../../components/RatingDisplay';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { cn } from '../../utils/cn';\nimport { formatDate } from '../../utils/formatters';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface Review {\n id: string;\n userId: string;\n userName: string;\n userAvatar: string;\n itemId: string;\n itemName: string;\n itemType: 'cart' | 'product';\n cartId: string;\n cartName: string;\n orderId: string;\n rating: number;\n title: string;\n comment: string;\n images?: string[];\n helpfulCount: number;\n isHelpful: boolean;\n isVerified: boolean;\n createdAt: string;\n response?: {\n message: string;\n respondedBy: string;\n respondedAt: string;\n };\n}\n\ninterface ReviewFormData {\n rating: number;\n title: string;\n comment: string;\n}\n\ninterface ReviewFilters {\n searchQuery: string;\n type: 'all' | 'cart' | 'product' | 'my-reviews';\n rating: string;\n sortBy: 'recent' | 'helpful' | 'rating-high' | 'rating-low';\n}\n\nconst CURRENT_USER_ID = 'user-001';\n\nconst ratingLabels: Record<number, string> = {\n 1: 'Terrible',\n 2: 'Poor',\n 3: 'Average',\n 4: 'Good',\n 5: 'Excellent',\n};\n\n// ============================================================================\n// Mock Data\n// ============================================================================\n\nconst mockReviews: Review[] = [\n {\n id: 'review-001',\n userId: CURRENT_USER_ID,\n userName: 'Rahul Sharma',\n userAvatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100',\n itemId: 'FOOD-001',\n itemName: 'Dosa Express',\n itemType: 'cart',\n cartId: 'FOOD-001',\n cartName: 'Dosa Express',\n orderId: 'ORD-2024-001',\n rating: 5,\n title: 'Excellent breakfast spot!',\n comment:\n 'Amazing dosas and filter coffee. The masala dosa was perfectly crispy and the potato filling was delicious. Service was quick and friendly. Highly recommend for authentic South Indian breakfast!',\n helpfulCount: 12,\n isHelpful: true,\n isVerified: true,\n createdAt: '2024-06-20T09:30:00Z',\n response: {\n message:\n \"Thank you so much for your wonderful review! We're thrilled you enjoyed the dosas. We look forward to serving you again soon!\",\n respondedBy: 'Dosa Express Team',\n respondedAt: '2024-06-20T15:45:00Z',\n },\n },\n {\n id: 'review-002',\n userId: 'user-002',\n userName: 'Priya Patel',\n userAvatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100',\n itemId: 'prod-002',\n itemName: 'Pani Puri',\n itemType: 'product',\n cartId: 'FOOD-002',\n cartName: 'Chaat Corner',\n orderId: 'ORD-2024-002',\n rating: 4,\n title: 'Good but could be spicier',\n comment:\n 'The pani puri was good overall. The puris were crispy and fresh. However, the pani could have been more spicy and tangy. The portions were generous though.',\n helpfulCount: 8,\n isHelpful: false,\n isVerified: true,\n createdAt: '2024-06-18T19:15:00Z',\n },\n {\n id: 'review-003',\n userId: 'user-003',\n userName: 'Amit Kumar',\n userAvatar: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100',\n itemId: 'FOOD-002',\n itemName: 'Chaat Corner',\n itemType: 'cart',\n cartId: 'FOOD-002',\n cartName: 'Chaat Corner',\n orderId: 'ORD-2024-003',\n rating: 5,\n title: 'Authentic Mumbai street food!',\n comment:\n 'This place brings back memories of Mumbai streets. Every item I ordered was authentic and delicious. The bhel puri and vada pav were exceptional. Will definitely order again!',\n images: ['https://images.unsplash.com/photo-1601050690597-df0568f70950?w=400'],\n helpfulCount: 15,\n isHelpful: false,\n isVerified: true,\n createdAt: '2024-06-17T20:30:00Z',\n },\n {\n id: 'review-004',\n userId: CURRENT_USER_ID,\n userName: 'Rahul Sharma',\n userAvatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100',\n itemId: 'prod-001',\n itemName: 'Masala Dosa',\n itemType: 'product',\n cartId: 'FOOD-001',\n cartName: 'Dosa Express',\n orderId: 'ORD-2024-004',\n rating: 5,\n title: 'Perfect masala dosa!',\n comment:\n 'The masala dosa here is absolutely perfect. Crispy, golden brown, and the potato masala inside is perfectly spiced. Comes with great chutneys and sambar.',\n helpfulCount: 6,\n isHelpful: false,\n isVerified: true,\n createdAt: '2024-06-15T08:45:00Z',\n response: {\n message: 'Glad you loved it, Rahul! Our chef takes great care with every dosa. See you soon!',\n respondedBy: 'Dosa Express Team',\n respondedAt: '2024-06-15T14:00:00Z',\n },\n },\n {\n id: 'review-005',\n userId: 'user-004',\n userName: 'Sneha Reddy',\n userAvatar: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100',\n itemId: 'FOOD-001',\n itemName: 'Dosa Express',\n itemType: 'cart',\n cartId: 'FOOD-001',\n cartName: 'Dosa Express',\n orderId: 'ORD-2024-005',\n rating: 3,\n title: 'Average experience',\n comment:\n 'The food was okay but delivery took longer than expected. The taste was good but not exceptional. The packaging could be better to keep food warm.',\n helpfulCount: 4,\n isHelpful: false,\n isVerified: true,\n createdAt: '2024-06-12T12:20:00Z',\n },\n];\n\n// ============================================================================\n// Star Rating Interactive Component\n// ============================================================================\n\nfunction InteractiveStarRating({\n value,\n onChange,\n}: {\n value: number;\n onChange: (v: number) => void;\n}) {\n const [hoverValue, setHoverValue] = useState(0);\n const displayValue = hoverValue || value;\n\n return (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center gap-0.5\">\n {[1, 2, 3, 4, 5].map((star) => (\n <button\n key={star}\n type=\"button\"\n onClick={() => onChange(star)}\n onMouseEnter={() => setHoverValue(star)}\n onMouseLeave={() => setHoverValue(0)}\n className=\"p-0.5 transition-transform\"\n >\n <Star\n className={cn(\n 'h-6 w-6',\n star <= displayValue\n ? 'fill-yellow-400 text-yellow-400'\n : 'fill-none text-text-secondary/40'\n )}\n />\n </button>\n ))}\n </div>\n <span className=\"text-sm font-medium text-text-secondary\">\n {ratingLabels[displayValue] ?? ''}\n </span>\n </div>\n );\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function ReviewsPage() {\n const { navigateTo } = useSubscriberBot();\n const [reviews, setReviews] = useState<Review[]>(mockReviews);\n const [showWriteReview, setShowWriteReview] = useState(false);\n const [reviewForm, setReviewForm] = useState<ReviewFormData>({\n rating: 5,\n title: '',\n comment: '',\n });\n const [filters, setFilters] = useState<ReviewFilters>({\n searchQuery: '',\n type: 'all',\n rating: '',\n sortBy: 'recent',\n });\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n\n const showStatus = (msg: string) => {\n setStatusMessage(msg);\n setTimeout(() => setStatusMessage(null), 3000);\n };\n\n // --- Filtered reviews ---\n const filteredReviews = useCallback(() => {\n let result = [...reviews];\n\n // Type filter\n if (filters.type === 'my-reviews') {\n result = result.filter((r) => r.userId === CURRENT_USER_ID);\n } else if (filters.type !== 'all') {\n result = result.filter((r) => r.itemType === filters.type);\n }\n\n // Rating filter\n if (filters.rating) {\n const ratingVal = parseInt(filters.rating, 10);\n result = result.filter((r) => r.rating === ratingVal);\n }\n\n // Search\n if (filters.searchQuery) {\n const q = filters.searchQuery.toLowerCase();\n result = result.filter(\n (r) =>\n r.itemName.toLowerCase().includes(q) ||\n r.title.toLowerCase().includes(q) ||\n r.comment.toLowerCase().includes(q) ||\n r.cartName.toLowerCase().includes(q)\n );\n }\n\n // Sort\n switch (filters.sortBy) {\n case 'recent':\n result.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n break;\n case 'helpful':\n result.sort((a, b) => b.helpfulCount - a.helpfulCount);\n break;\n case 'rating-high':\n result.sort((a, b) => b.rating - a.rating);\n break;\n case 'rating-low':\n result.sort((a, b) => a.rating - b.rating);\n break;\n }\n\n return result;\n }, [reviews, filters])();\n\n // --- Stats ---\n const myReviewCount = reviews.filter((r) => r.userId === CURRENT_USER_ID).length;\n const avgRating =\n reviews.length > 0\n ? (reviews.reduce((s, r) => s + r.rating, 0) / reviews.length).toFixed(1)\n : '0';\n\n // --- Handlers ---\n const handleSubmitReview = () => {\n if (!reviewForm.title.trim() || !reviewForm.comment.trim()) {\n alert('Please fill in the Review Title and Comment.');\n return;\n }\n\n const newReview: Review = {\n id: `review-${Date.now()}`,\n userId: CURRENT_USER_ID,\n userName: 'Rahul Sharma',\n userAvatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100',\n itemId: 'FOOD-001',\n itemName: 'Dosa Express',\n itemType: 'cart',\n cartId: 'FOOD-001',\n cartName: 'Dosa Express',\n orderId: `ORD-2024-${Date.now()}`,\n rating: reviewForm.rating,\n title: reviewForm.title,\n comment: reviewForm.comment,\n helpfulCount: 0,\n isHelpful: false,\n isVerified: true,\n createdAt: new Date().toISOString(),\n };\n\n setReviews((prev) => [newReview, ...prev]);\n setReviewForm({ rating: 5, title: '', comment: '' });\n setShowWriteReview(false);\n showStatus('Review submitted successfully!');\n };\n\n const handleMarkHelpful = (reviewId: string) => {\n setReviews((prev) =>\n prev.map((r) =>\n r.id === reviewId\n ? {\n ...r,\n isHelpful: !r.isHelpful,\n helpfulCount: r.isHelpful ? r.helpfulCount - 1 : r.helpfulCount + 1,\n }\n : r\n )\n );\n };\n\n return (\n <PageLayout\n title=\"Reviews & Ratings\"\n description={`${filteredReviews.length} reviews found`}\n actions={\n <button\n type=\"button\"\n onClick={() => setShowWriteReview(true)}\n className={cn(\n 'flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-opacity',\n 'bg-foreground text-background hover:opacity-90'\n )}\n >\n <PenSquare className=\"h-4 w-4\" />\n Write Review\n </button>\n }\n >\n {/* Status message */}\n {statusMessage && (\n <div className=\"mb-4 rounded-lg border border-green-500/30 bg-green-500/10 p-3 flex items-center gap-2\">\n <CheckCircle2 className=\"h-4 w-4 text-green-600 dark:text-green-400 shrink-0\" />\n <p className=\"text-sm text-green-600 dark:text-green-400\">{statusMessage}</p>\n </div>\n )}\n\n {/* Stats */}\n <div className=\"flex flex-wrap items-center gap-4 text-sm text-text-secondary mb-6\">\n <span>{reviews.length} total reviews</span>\n <span>{myReviewCount} your reviews</span>\n <span className=\"flex items-center gap-1\">\n Average: {avgRating}\n <Star className=\"h-3.5 w-3.5 fill-yellow-400 text-yellow-400\" />\n </span>\n </div>\n\n {/* Filters */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 mb-6\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3\">\n {/* Search */}\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <input\n type=\"text\"\n placeholder=\"Search reviews...\"\n value={filters.searchQuery}\n onChange={(e) => setFilters((p) => ({ ...p, searchQuery: e.target.value }))}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-9 pr-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n {/* Type */}\n <select\n value={filters.type}\n onChange={(e) =>\n setFilters((p) => ({ ...p, type: e.target.value as ReviewFilters['type'] }))\n }\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"all\">All Reviews</option>\n <option value=\"cart\">Cart Reviews</option>\n <option value=\"product\">Product Reviews</option>\n <option value=\"my-reviews\">My Reviews</option>\n </select>\n\n {/* Rating */}\n <select\n value={filters.rating}\n onChange={(e) => setFilters((p) => ({ ...p, rating: e.target.value }))}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Ratings</option>\n <option value=\"5\">5 Stars</option>\n <option value=\"4\">4 Stars</option>\n <option value=\"3\">3 Stars</option>\n <option value=\"2\">2 Stars</option>\n <option value=\"1\">1 Star</option>\n </select>\n\n {/* Sort */}\n <select\n value={filters.sortBy}\n onChange={(e) =>\n setFilters((p) => ({ ...p, sortBy: e.target.value as ReviewFilters['sortBy'] }))\n }\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"recent\">Most Recent</option>\n <option value=\"helpful\">Most Helpful</option>\n <option value=\"rating-high\">Highest Rating</option>\n <option value=\"rating-low\">Lowest Rating</option>\n </select>\n </div>\n </div>\n\n {/* Reviews List */}\n {filteredReviews.length === 0 ? (\n <EmptyState\n icon={<MessageSquare className=\"h-12 w-12\" />}\n title=\"No reviews found\"\n description=\"Be the first to write a review!\"\n action={\n <button\n type=\"button\"\n onClick={() => setShowWriteReview(true)}\n className=\"rounded-lg bg-foreground px-4 py-2 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n Write a Review\n </button>\n }\n />\n ) : (\n <div className=\"space-y-4\">\n {filteredReviews.map((review) => {\n const isMyReview = review.userId === CURRENT_USER_ID;\n return (\n <div\n key={review.id}\n className={cn(\n 'rounded-lg border bg-bg-surface p-5',\n isMyReview ? 'border-foreground/20' : 'border-border-subtle'\n )}\n >\n {/* Header */}\n <div className=\"flex items-start gap-3 mb-3\">\n <img\n src={review.userAvatar}\n alt={review.userName}\n className=\"h-10 w-10 rounded-full object-cover shrink-0\"\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"text-sm font-semibold text-text-primary\">\n {review.userName}\n </span>\n {review.isVerified && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-green-500/10 px-2 py-0.5 text-[10px] font-medium text-green-600 dark:text-green-400\">\n <CheckCircle2 className=\"h-3 w-3\" />\n Verified\n </span>\n )}\n {isMyReview && (\n <span className=\"inline-flex items-center rounded-full bg-blue-500/10 px-2 py-0.5 text-[10px] font-medium text-blue-600 dark:text-blue-400\">\n Your Review\n </span>\n )}\n </div>\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-text-secondary mt-0.5\">\n <span>\n {review.itemType === 'cart' ? (\n <MessageSquare className=\"inline h-3 w-3 mr-0.5\" />\n ) : (\n <Star className=\"inline h-3 w-3 mr-0.5\" />\n )}\n {review.itemName}\n </span>\n <span>\n {formatDate(review.createdAt, {\n hour: undefined,\n minute: undefined,\n hour12: undefined,\n })}\n </span>\n </div>\n </div>\n <div className=\"shrink-0\">\n <RatingDisplay value={review.rating} size=\"sm\" />\n <p className=\"text-xs text-text-secondary mt-0.5 text-right\">\n From: {review.cartName}\n </p>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"mb-3\">\n <h4 className=\"text-sm font-semibold text-text-primary mb-1\">{review.title}</h4>\n <p className=\"text-sm text-text-primary leading-relaxed\">{review.comment}</p>\n </div>\n\n {/* Review Images */}\n {review.images && review.images.length > 0 && (\n <div className=\"mb-3 flex gap-2 overflow-x-auto pb-1\">\n {review.images.map((img, idx) => (\n <img\n key={idx}\n src={img}\n alt={`Review image ${idx + 1}`}\n className=\"h-20 w-20 rounded-lg object-cover shrink-0\"\n />\n ))}\n </div>\n )}\n\n {/* Owner Response */}\n {review.response && (\n <div className=\"mb-3 rounded-lg border border-blue-500/20 bg-blue-500/5 p-3\">\n <div className=\"flex flex-wrap items-center gap-2 mb-1.5\">\n <MessageCircle className=\"h-3.5 w-3.5 text-blue-600 dark:text-blue-400\" />\n <span className=\"text-xs font-medium text-blue-600 dark:text-blue-400\">\n Response from {review.response.respondedBy}\n </span>\n <span className=\"text-[10px] text-blue-500/70\">\n {formatDate(review.response.respondedAt, {\n hour: undefined,\n minute: undefined,\n hour12: undefined,\n })}\n </span>\n </div>\n <p className=\"text-xs text-blue-700 dark:text-blue-300 leading-relaxed\">\n {review.response.message}\n </p>\n </div>\n )}\n\n {/* Footer */}\n <div className=\"flex items-center justify-between pt-3 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={() => handleMarkHelpful(review.id)}\n className={cn(\n 'flex items-center gap-1.5 text-xs transition-colors',\n review.isHelpful\n ? 'text-blue-600 dark:text-blue-400 font-medium'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n <ThumbsUp className={cn('h-3.5 w-3.5', review.isHelpful && 'fill-current')} />\n Helpful ({review.helpfulCount})\n </button>\n\n <div className=\"flex items-center gap-3 text-xs text-text-secondary\">\n <span>Order: {review.orderId}</span>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/customer/carts/${review.cartId}`)}\n className=\"font-medium hover:text-text-primary transition-colors\"\n >\n View Cart\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Write Review Modal */}\n {showWriteReview && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\n <div className=\"w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-lg border border-border-subtle bg-bg-surface shadow-lg\">\n <div className=\"p-5\">\n {/* Header */}\n <div className=\"flex items-center justify-between mb-5\">\n <h3 className=\"text-lg font-semibold text-text-primary\">Write a Review</h3>\n <button\n type=\"button\"\n onClick={() => setShowWriteReview(false)}\n className=\"rounded-md p-2 text-text-secondary hover:bg-accent hover:text-text-primary transition-colors\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className=\"space-y-4\">\n {/* Rating */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Rating <span className=\"text-red-500\">*</span>\n </label>\n <InteractiveStarRating\n value={reviewForm.rating}\n onChange={(v) => setReviewForm((p) => ({ ...p, rating: v }))}\n />\n </div>\n\n {/* Title */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Review Title <span className=\"text-red-500\">*</span>\n </label>\n <input\n type=\"text\"\n placeholder=\"Summarize your experience\"\n value={reviewForm.title}\n onChange={(e) => setReviewForm((p) => ({ ...p, title: e.target.value }))}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n {/* Comment */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Your Review <span className=\"text-red-500\">*</span>\n </label>\n <textarea\n rows={5}\n placeholder=\"Share your experience with others...\"\n value={reviewForm.comment}\n onChange={(e) => setReviewForm((p) => ({ ...p, comment: e.target.value }))}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n\n {/* Guidelines */}\n <div className=\"rounded-lg bg-bg-sunken p-4\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Info className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-primary\">Review Guidelines</h4>\n </div>\n <ul className=\"text-xs text-text-secondary space-y-1\">\n <li>- Be honest and helpful to other customers</li>\n <li>- Focus on your experience with the food and service</li>\n <li>- Avoid personal information or inappropriate content</li>\n <li>- Reviews are public and cannot be deleted once submitted</li>\n </ul>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-3 pt-5\">\n <button\n type=\"button\"\n onClick={handleSubmitReview}\n className=\"rounded-lg bg-foreground px-4 py-2 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n Submit Review\n </button>\n <button\n type=\"button\"\n onClick={() => setShowWriteReview(false)}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReviewsPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/customer/ReviewsPage.tsx"],"sourcesContent":["/**\n * Reviews Page\n * @module subscriberbot/pages/customer\n *\n * Full-featured reviews: Write Review modal (interactive star rating with\n * text labels, title, comment, guidelines), Owner Response callout,\n * review images, verified badge, Mark as Helpful toggle, 4 filters\n * (search, type, rating, sort), Your Review label, 5 mock reviews.\n */\n\nimport { useState, useCallback } from 'react';\nimport {\n Star,\n MessageSquare,\n ThumbsUp,\n PenSquare,\n X,\n CheckCircle2,\n Image,\n MessageCircle,\n Info,\n Search,\n} from 'lucide-react';\nimport { PagePurpose, EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { RatingDisplay } from '../../components/RatingDisplay';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { cn } from '../../utils/cn';\nimport { formatDate } from '../../utils/formatters';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface Review {\n id: string;\n userId: string;\n userName: string;\n userAvatar: string;\n itemId: string;\n itemName: string;\n itemType: 'cart' | 'product';\n cartId: string;\n cartName: string;\n orderId: string;\n rating: number;\n title: string;\n comment: string;\n images?: string[];\n helpfulCount: number;\n isHelpful: boolean;\n isVerified: boolean;\n createdAt: string;\n response?: {\n message: string;\n respondedBy: string;\n respondedAt: string;\n };\n}\n\ninterface ReviewFormData {\n rating: number;\n title: string;\n comment: string;\n}\n\ninterface ReviewFilters {\n searchQuery: string;\n type: 'all' | 'cart' | 'product' | 'my-reviews';\n rating: string;\n sortBy: 'recent' | 'helpful' | 'rating-high' | 'rating-low';\n}\n\nconst CURRENT_USER_ID = 'user-001';\n\nconst ratingLabels: Record<number, string> = {\n 1: 'Terrible',\n 2: 'Poor',\n 3: 'Average',\n 4: 'Good',\n 5: 'Excellent',\n};\n\n// ============================================================================\n// Mock Data\n// ============================================================================\n\nconst mockReviews: Review[] = [\n {\n id: 'review-001',\n userId: CURRENT_USER_ID,\n userName: 'Rahul Sharma',\n userAvatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100',\n itemId: 'FOOD-001',\n itemName: 'Dosa Express',\n itemType: 'cart',\n cartId: 'FOOD-001',\n cartName: 'Dosa Express',\n orderId: 'ORD-2024-001',\n rating: 5,\n title: 'Excellent breakfast spot!',\n comment:\n 'Amazing dosas and filter coffee. The masala dosa was perfectly crispy and the potato filling was delicious. Service was quick and friendly. Highly recommend for authentic South Indian breakfast!',\n helpfulCount: 12,\n isHelpful: true,\n isVerified: true,\n createdAt: '2024-06-20T09:30:00Z',\n response: {\n message:\n \"Thank you so much for your wonderful review! We're thrilled you enjoyed the dosas. We look forward to serving you again soon!\",\n respondedBy: 'Dosa Express Team',\n respondedAt: '2024-06-20T15:45:00Z',\n },\n },\n {\n id: 'review-002',\n userId: 'user-002',\n userName: 'Priya Patel',\n userAvatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100',\n itemId: 'prod-002',\n itemName: 'Pani Puri',\n itemType: 'product',\n cartId: 'FOOD-002',\n cartName: 'Chaat Corner',\n orderId: 'ORD-2024-002',\n rating: 4,\n title: 'Good but could be spicier',\n comment:\n 'The pani puri was good overall. The puris were crispy and fresh. However, the pani could have been more spicy and tangy. The portions were generous though.',\n helpfulCount: 8,\n isHelpful: false,\n isVerified: true,\n createdAt: '2024-06-18T19:15:00Z',\n },\n {\n id: 'review-003',\n userId: 'user-003',\n userName: 'Amit Kumar',\n userAvatar: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100',\n itemId: 'FOOD-002',\n itemName: 'Chaat Corner',\n itemType: 'cart',\n cartId: 'FOOD-002',\n cartName: 'Chaat Corner',\n orderId: 'ORD-2024-003',\n rating: 5,\n title: 'Authentic Mumbai street food!',\n comment:\n 'This place brings back memories of Mumbai streets. Every item I ordered was authentic and delicious. The bhel puri and vada pav were exceptional. Will definitely order again!',\n images: ['https://images.unsplash.com/photo-1601050690597-df0568f70950?w=400'],\n helpfulCount: 15,\n isHelpful: false,\n isVerified: true,\n createdAt: '2024-06-17T20:30:00Z',\n },\n {\n id: 'review-004',\n userId: CURRENT_USER_ID,\n userName: 'Rahul Sharma',\n userAvatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100',\n itemId: 'prod-001',\n itemName: 'Masala Dosa',\n itemType: 'product',\n cartId: 'FOOD-001',\n cartName: 'Dosa Express',\n orderId: 'ORD-2024-004',\n rating: 5,\n title: 'Perfect masala dosa!',\n comment:\n 'The masala dosa here is absolutely perfect. Crispy, golden brown, and the potato masala inside is perfectly spiced. Comes with great chutneys and sambar.',\n helpfulCount: 6,\n isHelpful: false,\n isVerified: true,\n createdAt: '2024-06-15T08:45:00Z',\n response: {\n message: 'Glad you loved it, Rahul! Our chef takes great care with every dosa. See you soon!',\n respondedBy: 'Dosa Express Team',\n respondedAt: '2024-06-15T14:00:00Z',\n },\n },\n {\n id: 'review-005',\n userId: 'user-004',\n userName: 'Sneha Reddy',\n userAvatar: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100',\n itemId: 'FOOD-001',\n itemName: 'Dosa Express',\n itemType: 'cart',\n cartId: 'FOOD-001',\n cartName: 'Dosa Express',\n orderId: 'ORD-2024-005',\n rating: 3,\n title: 'Average experience',\n comment:\n 'The food was okay but delivery took longer than expected. The taste was good but not exceptional. The packaging could be better to keep food warm.',\n helpfulCount: 4,\n isHelpful: false,\n isVerified: true,\n createdAt: '2024-06-12T12:20:00Z',\n },\n];\n\n// ============================================================================\n// Star Rating Interactive Component\n// ============================================================================\n\nfunction InteractiveStarRating({\n value,\n onChange,\n}: {\n value: number;\n onChange: (v: number) => void;\n}) {\n const [hoverValue, setHoverValue] = useState(0);\n const displayValue = hoverValue || value;\n\n return (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center gap-0.5\">\n {[1, 2, 3, 4, 5].map((star) => (\n <button\n key={star}\n type=\"button\"\n onClick={() => onChange(star)}\n onMouseEnter={() => setHoverValue(star)}\n onMouseLeave={() => setHoverValue(0)}\n className=\"p-0.5 transition-transform\"\n >\n <Star\n className={cn(\n 'h-6 w-6',\n star <= displayValue\n ? 'fill-status-warning-text text-status-warning-text'\n : 'fill-none text-text-secondary/40'\n )}\n />\n </button>\n ))}\n </div>\n <span className=\"text-sm font-medium text-text-secondary\">\n {ratingLabels[displayValue] ?? ''}\n </span>\n </div>\n );\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function ReviewsPage() {\n const { navigateTo } = useSubscriberBot();\n const [reviews, setReviews] = useState<Review[]>(mockReviews);\n const [showWriteReview, setShowWriteReview] = useState(false);\n const [reviewForm, setReviewForm] = useState<ReviewFormData>({\n rating: 5,\n title: '',\n comment: '',\n });\n const [filters, setFilters] = useState<ReviewFilters>({\n searchQuery: '',\n type: 'all',\n rating: '',\n sortBy: 'recent',\n });\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n\n const showStatus = (msg: string) => {\n setStatusMessage(msg);\n setTimeout(() => setStatusMessage(null), 3000);\n };\n\n // --- Filtered reviews ---\n const filteredReviews = useCallback(() => {\n let result = [...reviews];\n\n // Type filter\n if (filters.type === 'my-reviews') {\n result = result.filter((r) => r.userId === CURRENT_USER_ID);\n } else if (filters.type !== 'all') {\n result = result.filter((r) => r.itemType === filters.type);\n }\n\n // Rating filter\n if (filters.rating) {\n const ratingVal = parseInt(filters.rating, 10);\n result = result.filter((r) => r.rating === ratingVal);\n }\n\n // Search\n if (filters.searchQuery) {\n const q = filters.searchQuery.toLowerCase();\n result = result.filter(\n (r) =>\n r.itemName.toLowerCase().includes(q) ||\n r.title.toLowerCase().includes(q) ||\n r.comment.toLowerCase().includes(q) ||\n r.cartName.toLowerCase().includes(q)\n );\n }\n\n // Sort\n switch (filters.sortBy) {\n case 'recent':\n result.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n break;\n case 'helpful':\n result.sort((a, b) => b.helpfulCount - a.helpfulCount);\n break;\n case 'rating-high':\n result.sort((a, b) => b.rating - a.rating);\n break;\n case 'rating-low':\n result.sort((a, b) => a.rating - b.rating);\n break;\n }\n\n return result;\n }, [reviews, filters])();\n\n // --- Stats ---\n const myReviewCount = reviews.filter((r) => r.userId === CURRENT_USER_ID).length;\n const avgRating =\n reviews.length > 0\n ? (reviews.reduce((s, r) => s + r.rating, 0) / reviews.length).toFixed(1)\n : '0';\n\n // --- Handlers ---\n const handleSubmitReview = () => {\n if (!reviewForm.title.trim() || !reviewForm.comment.trim()) {\n alert('Please fill in the Review Title and Comment.');\n return;\n }\n\n const newReview: Review = {\n id: `review-${Date.now()}`,\n userId: CURRENT_USER_ID,\n userName: 'Rahul Sharma',\n userAvatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100',\n itemId: 'FOOD-001',\n itemName: 'Dosa Express',\n itemType: 'cart',\n cartId: 'FOOD-001',\n cartName: 'Dosa Express',\n orderId: `ORD-2024-${Date.now()}`,\n rating: reviewForm.rating,\n title: reviewForm.title,\n comment: reviewForm.comment,\n helpfulCount: 0,\n isHelpful: false,\n isVerified: true,\n createdAt: new Date().toISOString(),\n };\n\n setReviews((prev) => [newReview, ...prev]);\n setReviewForm({ rating: 5, title: '', comment: '' });\n setShowWriteReview(false);\n showStatus('Review submitted successfully!');\n };\n\n const handleMarkHelpful = (reviewId: string) => {\n setReviews((prev) =>\n prev.map((r) =>\n r.id === reviewId\n ? {\n ...r,\n isHelpful: !r.isHelpful,\n helpfulCount: r.isHelpful ? r.helpfulCount - 1 : r.helpfulCount + 1,\n }\n : r\n )\n );\n };\n\n return (\n <PageLayout\n title=\"Reviews & Ratings\"\n description={`${filteredReviews.length} reviews found`}\n actions={\n <button\n type=\"button\"\n onClick={() => setShowWriteReview(true)}\n className={cn(\n 'flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-opacity',\n 'bg-foreground text-background hover:opacity-90'\n )}\n >\n <PenSquare className=\"h-4 w-4\" />\n Write Review\n </button>\n }\n >\n <PagePurpose icon={<Star className=\"h-4 w-4\" />} className=\"mb-6\">\n Share your experience and read what others think. Write reviews for carts you've\n ordered from to help the community find great service, and revisit your own ratings\n any time. Honest feedback keeps quality high and helps good carts stand out.\n </PagePurpose>\n\n {/* Status message */}\n {statusMessage && (\n <div className=\"mb-4 rounded-lg border border-status-success-border/30 bg-status-success-bg/10 p-3 flex items-center gap-2\">\n <CheckCircle2 className=\"h-4 w-4 text-status-success-text shrink-0\" />\n <p className=\"text-sm text-status-success-text\">{statusMessage}</p>\n </div>\n )}\n\n {/* Stats — the ONE emphasis zone */}\n <EmphasisPanel className=\"flex flex-wrap items-center gap-4 text-sm text-text-secondary mb-6\">\n <span>{reviews.length} total reviews</span>\n <span>{myReviewCount} your reviews</span>\n <span className=\"flex items-center gap-1\">\n Average: {avgRating}\n <Star className=\"h-3.5 w-3.5 fill-status-warning-text text-status-warning-text\" />\n </span>\n </EmphasisPanel>\n\n {/* Filters */}\n <div className=\"rounded-lg border border-border-seam bg-bg-surface p-4 mb-6\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3\">\n {/* Search */}\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <input\n type=\"text\"\n placeholder=\"Search reviews...\"\n value={filters.searchQuery}\n onChange={(e) => setFilters((p) => ({ ...p, searchQuery: e.target.value }))}\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface py-2 pl-9 pr-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n {/* Type */}\n <select\n value={filters.type}\n onChange={(e) =>\n setFilters((p) => ({ ...p, type: e.target.value as ReviewFilters['type'] }))\n }\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"all\">All Reviews</option>\n <option value=\"cart\">Cart Reviews</option>\n <option value=\"product\">Product Reviews</option>\n <option value=\"my-reviews\">My Reviews</option>\n </select>\n\n {/* Rating */}\n <select\n value={filters.rating}\n onChange={(e) => setFilters((p) => ({ ...p, rating: e.target.value }))}\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Ratings</option>\n <option value=\"5\">5 Stars</option>\n <option value=\"4\">4 Stars</option>\n <option value=\"3\">3 Stars</option>\n <option value=\"2\">2 Stars</option>\n <option value=\"1\">1 Star</option>\n </select>\n\n {/* Sort */}\n <select\n value={filters.sortBy}\n onChange={(e) =>\n setFilters((p) => ({ ...p, sortBy: e.target.value as ReviewFilters['sortBy'] }))\n }\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"recent\">Most Recent</option>\n <option value=\"helpful\">Most Helpful</option>\n <option value=\"rating-high\">Highest Rating</option>\n <option value=\"rating-low\">Lowest Rating</option>\n </select>\n </div>\n </div>\n\n {/* Reviews List */}\n {filteredReviews.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<MessageSquare className=\"h-12 w-12\" />}\n title=\"No reviews found\"\n description=\"Be the first to write a review!\"\n action={\n <button\n type=\"button\"\n onClick={() => setShowWriteReview(true)}\n className=\"rounded-lg bg-foreground px-4 py-2 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n Write a Review\n </button>\n }\n />\n ) : (\n <div className=\"space-y-4\">\n {filteredReviews.map((review) => {\n const isMyReview = review.userId === CURRENT_USER_ID;\n return (\n <div\n key={review.id}\n className={cn(\n 'rounded-lg border bg-bg-surface p-5',\n isMyReview ? 'border-foreground/20' : 'border-border-seam'\n )}\n >\n {/* Header */}\n <div className=\"flex items-start gap-3 mb-3\">\n <img\n src={review.userAvatar}\n alt={review.userName}\n className=\"h-10 w-10 rounded-full object-cover shrink-0\"\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"text-sm font-semibold text-text-primary\">\n {review.userName}\n </span>\n {review.isVerified && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-success-bg/10 px-2 py-0.5 text-[10px] font-medium text-status-success-text\">\n <CheckCircle2 className=\"h-3 w-3\" />\n Verified\n </span>\n )}\n {isMyReview && (\n <span className=\"inline-flex items-center rounded-full bg-status-info-bg/10 px-2 py-0.5 text-[10px] font-medium text-status-info-text\">\n Your Review\n </span>\n )}\n </div>\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-text-secondary mt-0.5\">\n <span>\n {review.itemType === 'cart' ? (\n <MessageSquare className=\"inline h-3 w-3 mr-0.5\" />\n ) : (\n <Star className=\"inline h-3 w-3 mr-0.5\" />\n )}\n {review.itemName}\n </span>\n <span>\n {formatDate(review.createdAt, {\n hour: undefined,\n minute: undefined,\n hour12: undefined,\n })}\n </span>\n </div>\n </div>\n <div className=\"shrink-0\">\n <RatingDisplay value={review.rating} size=\"sm\" />\n <p className=\"text-xs text-text-secondary mt-0.5 text-right\">\n From: {review.cartName}\n </p>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"mb-3\">\n <h4 className=\"text-sm font-semibold text-text-primary mb-1\">{review.title}</h4>\n <p className=\"text-sm text-text-primary leading-relaxed\">{review.comment}</p>\n </div>\n\n {/* Review Images */}\n {review.images && review.images.length > 0 && (\n <div className=\"mb-3 flex gap-2 overflow-x-auto pb-1\">\n {review.images.map((img, idx) => (\n <img\n key={idx}\n src={img}\n alt={`Review image ${idx + 1}`}\n className=\"h-20 w-20 rounded-lg object-cover shrink-0\"\n />\n ))}\n </div>\n )}\n\n {/* Owner Response */}\n {review.response && (\n <div className=\"mb-3 rounded-lg border border-status-info-border/20 bg-status-info-bg/5 p-3\">\n <div className=\"flex flex-wrap items-center gap-2 mb-1.5\">\n <MessageCircle className=\"h-3.5 w-3.5 text-status-info-text\" />\n <span className=\"text-xs font-medium text-status-info-text\">\n Response from {review.response.respondedBy}\n </span>\n <span className=\"text-[10px] text-status-info-text/70\">\n {formatDate(review.response.respondedAt, {\n hour: undefined,\n minute: undefined,\n hour12: undefined,\n })}\n </span>\n </div>\n <p className=\"text-xs text-status-info-text leading-relaxed\">\n {review.response.message}\n </p>\n </div>\n )}\n\n {/* Footer */}\n <div className=\"flex items-center justify-between pt-3 border-t border-border-seam\">\n <button\n type=\"button\"\n onClick={() => handleMarkHelpful(review.id)}\n className={cn(\n 'flex items-center gap-1.5 text-xs transition-colors',\n review.isHelpful\n ? 'text-status-info-text font-medium'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n <ThumbsUp className={cn('h-3.5 w-3.5', review.isHelpful && 'fill-current')} />\n Helpful ({review.helpfulCount})\n </button>\n\n <div className=\"flex items-center gap-3 text-xs text-text-secondary\">\n <span>Order: {review.orderId}</span>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/customer/carts/${review.cartId}`)}\n className=\"font-medium hover:text-text-primary transition-colors\"\n >\n View Cart\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Write Review Modal */}\n {showWriteReview && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-bg-canvas/50 p-4\">\n <div className=\"w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-lg border border-border-seam bg-bg-surface shadow-lg\">\n <div className=\"p-5\">\n {/* Header */}\n <div className=\"flex items-center justify-between mb-5\">\n <h3 className=\"text-lg font-semibold text-text-primary\">Write a Review</h3>\n <button\n type=\"button\"\n onClick={() => setShowWriteReview(false)}\n className=\"rounded-md p-2 text-text-secondary hover:bg-accent hover:text-text-primary transition-colors\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className=\"space-y-4\">\n {/* Rating */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Rating <span className=\"text-status-error-text\">*</span>\n </label>\n <InteractiveStarRating\n value={reviewForm.rating}\n onChange={(v) => setReviewForm((p) => ({ ...p, rating: v }))}\n />\n </div>\n\n {/* Title */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Review Title <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n type=\"text\"\n placeholder=\"Summarize your experience\"\n value={reviewForm.title}\n onChange={(e) => setReviewForm((p) => ({ ...p, title: e.target.value }))}\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n {/* Comment */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Your Review <span className=\"text-status-error-text\">*</span>\n </label>\n <textarea\n rows={5}\n placeholder=\"Share your experience with others...\"\n value={reviewForm.comment}\n onChange={(e) => setReviewForm((p) => ({ ...p, comment: e.target.value }))}\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n\n {/* Guidelines */}\n <div className=\"rounded-lg bg-bg-sunken p-4\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Info className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-primary\">Review Guidelines</h4>\n </div>\n <ul className=\"text-xs text-text-secondary space-y-1\">\n <li>- Be honest and helpful to other customers</li>\n <li>- Focus on your experience with the food and service</li>\n <li>- Avoid personal information or inappropriate content</li>\n <li>- Reviews are public and cannot be deleted once submitted</li>\n </ul>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-3 pt-5\">\n <button\n type=\"button\"\n onClick={handleSubmitReview}\n className=\"rounded-lg bg-foreground px-4 py-2 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n Submit Review\n </button>\n <button\n type=\"button\"\n onClick={() => setShowWriteReview(false)}\n className=\"rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -6,8 +6,9 @@ import { formatDate as i } from "../../utils/formatters.js";
6
6
  import { useState as a } from "react";
7
7
  import { Briefcase as o, CheckCircle2 as s, Clock as c, Hash as l, Home as u, MapPin as d, Pencil as f, Plus as p, Star as m, Trash2 as h, X as g } from "lucide-react";
8
8
  import { jsx as _, jsxs as v } from "react/jsx-runtime";
9
+ import { EmphasisPanel as y, PagePurpose as b } from "@burdenoff/fe-libs/ui";
9
10
  //#region src/subscriberbot/pages/customer/SavedAddressesPage.tsx
10
- var y = {
11
+ var x = {
11
12
  type: "home",
12
13
  nickname: "",
13
14
  addressLine1: "",
@@ -16,7 +17,7 @@ var y = {
16
17
  state: "",
17
18
  zipCode: "",
18
19
  isDefault: !1
19
- }, b = [
20
+ }, S = [
20
21
  {
21
22
  id: "addr-001",
22
23
  type: "home",
@@ -69,16 +70,16 @@ var y = {
69
70
  usageCount: 8,
70
71
  lastUsed: "2024-06-18T11:30:00Z"
71
72
  }
72
- ], x = {
73
+ ], C = {
73
74
  home: u,
74
75
  office: o,
75
76
  other: d
76
- }, S = {
77
- home: "bg-green-500/10 text-green-600 dark:text-green-400",
78
- office: "bg-blue-500/10 text-blue-600 dark:text-blue-400",
79
- other: "bg-purple-500/10 text-purple-600 dark:text-purple-400"
77
+ }, w = {
78
+ home: "bg-status-success-bg/10 text-status-success-text",
79
+ office: "bg-status-info-bg/10 text-status-info-text",
80
+ other: "bg-accent-purple-subtle text-accent-purple"
80
81
  };
81
- function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
82
+ function T({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
82
83
  return /* @__PURE__ */ v("div", {
83
84
  className: "space-y-4",
84
85
  children: [
@@ -87,13 +88,13 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
87
88
  children: [/* @__PURE__ */ v("div", { children: [/* @__PURE__ */ v("label", {
88
89
  className: "block text-sm font-medium text-text-primary mb-1.5",
89
90
  children: ["Address Type ", /* @__PURE__ */ _("span", {
90
- className: "text-red-500",
91
+ className: "text-status-error-text",
91
92
  children: "*"
92
93
  })]
93
94
  }), /* @__PURE__ */ v("select", {
94
95
  value: e.type,
95
96
  onChange: (e) => t("type", e.target.value),
96
- className: "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
97
+ className: "w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
97
98
  children: [
98
99
  /* @__PURE__ */ _("option", {
99
100
  value: "home",
@@ -116,13 +117,13 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
116
117
  placeholder: "e.g., Home Sweet Home",
117
118
  value: e.nickname,
118
119
  onChange: (e) => t("nickname", e.target.value),
119
- className: "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
120
+ className: "w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
120
121
  })] })]
121
122
  }),
122
123
  /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ v("label", {
123
124
  className: "block text-sm font-medium text-text-primary mb-1.5",
124
125
  children: ["Address Line 1 ", /* @__PURE__ */ _("span", {
125
- className: "text-red-500",
126
+ className: "text-status-error-text",
126
127
  children: "*"
127
128
  })]
128
129
  }), /* @__PURE__ */ _("input", {
@@ -130,7 +131,7 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
130
131
  placeholder: "House/Flat number, Street name",
131
132
  value: e.addressLine1,
132
133
  onChange: (e) => t("addressLine1", e.target.value),
133
- className: "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
134
+ className: "w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
134
135
  })] }),
135
136
  /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
136
137
  className: "block text-sm font-medium text-text-primary mb-1.5",
@@ -140,7 +141,7 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
140
141
  placeholder: "Area, Landmark",
141
142
  value: e.addressLine2,
142
143
  onChange: (e) => t("addressLine2", e.target.value),
143
- className: "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
144
+ className: "w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
144
145
  })] }),
145
146
  /* @__PURE__ */ v("div", {
146
147
  className: "grid grid-cols-1 sm:grid-cols-3 gap-4",
@@ -148,7 +149,7 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
148
149
  /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ v("label", {
149
150
  className: "block text-sm font-medium text-text-primary mb-1.5",
150
151
  children: ["City ", /* @__PURE__ */ _("span", {
151
- className: "text-red-500",
152
+ className: "text-status-error-text",
152
153
  children: "*"
153
154
  })]
154
155
  }), /* @__PURE__ */ _("input", {
@@ -156,12 +157,12 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
156
157
  placeholder: "City",
157
158
  value: e.city,
158
159
  onChange: (e) => t("city", e.target.value),
159
- className: "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
160
+ className: "w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
160
161
  })] }),
161
162
  /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ v("label", {
162
163
  className: "block text-sm font-medium text-text-primary mb-1.5",
163
164
  children: ["State ", /* @__PURE__ */ _("span", {
164
- className: "text-red-500",
165
+ className: "text-status-error-text",
165
166
  children: "*"
166
167
  })]
167
168
  }), /* @__PURE__ */ _("input", {
@@ -169,12 +170,12 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
169
170
  placeholder: "State",
170
171
  value: e.state,
171
172
  onChange: (e) => t("state", e.target.value),
172
- className: "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
173
+ className: "w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
173
174
  })] }),
174
175
  /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ v("label", {
175
176
  className: "block text-sm font-medium text-text-primary mb-1.5",
176
177
  children: ["ZIP Code ", /* @__PURE__ */ _("span", {
177
- className: "text-red-500",
178
+ className: "text-status-error-text",
178
179
  children: "*"
179
180
  })]
180
181
  }), /* @__PURE__ */ _("input", {
@@ -182,7 +183,7 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
182
183
  placeholder: "560001",
183
184
  value: e.zipCode,
184
185
  onChange: (e) => t("zipCode", e.target.value),
185
- className: "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
186
+ className: "w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
186
187
  })] })
187
188
  ]
188
189
  }),
@@ -192,7 +193,7 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
192
193
  type: "checkbox",
193
194
  checked: e.isDefault,
194
195
  onChange: (e) => t("isDefault", e.target.checked),
195
- className: "h-4 w-4 rounded border-border-subtle text-text-primary"
196
+ className: "h-4 w-4 rounded border-border-seam text-text-primary"
196
197
  }), /* @__PURE__ */ _("span", {
197
198
  className: "text-sm text-text-secondary",
198
199
  children: "Set as default address"
@@ -208,54 +209,54 @@ function C({ data: e, onChange: t, onSubmit: n, onCancel: r, submitLabel: i }) {
208
209
  }), /* @__PURE__ */ _("button", {
209
210
  type: "button",
210
211
  onClick: r,
211
- className: "rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors",
212
+ className: "rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors",
212
213
  children: "Cancel"
213
214
  })]
214
215
  })
215
216
  ]
216
217
  });
217
218
  }
218
- function w() {
219
- let { navigateTo: o } = e(), [u, w] = a(b), [T, E] = a(!1), [D, O] = a(null), [k, A] = a({ ...y }), [j, M] = a(null), N = (e) => {
220
- M(e), setTimeout(() => M(null), 3e3);
221
- }, P = (e) => !e.addressLine1.trim() || !e.city.trim() || !e.state.trim() || !e.zipCode.trim() ? (alert("Please fill in all required fields (Address Line 1, City, State, ZIP Code)."), !1) : !0, F = () => {
222
- if (!P(k)) return;
219
+ function E() {
220
+ let { navigateTo: o } = e(), [u, E] = a(S), [D, O] = a(!1), [k, A] = a(null), [j, M] = a({ ...x }), [N, P] = a(null), F = (e) => {
221
+ P(e), setTimeout(() => P(null), 3e3);
222
+ }, I = (e) => !e.addressLine1.trim() || !e.city.trim() || !e.state.trim() || !e.zipCode.trim() ? (alert("Please fill in all required fields (Address Line 1, City, State, ZIP Code)."), !1) : !0, L = () => {
223
+ if (!I(j)) return;
223
224
  let e = {
224
225
  id: `addr-${Date.now()}`,
225
- type: k.type,
226
- nickname: k.nickname,
227
- addressLine1: k.addressLine1,
228
- addressLine2: k.addressLine2,
229
- city: k.city,
230
- state: k.state,
231
- zipCode: k.zipCode,
232
- isDefault: k.isDefault,
226
+ type: j.type,
227
+ nickname: j.nickname,
228
+ addressLine1: j.addressLine1,
229
+ addressLine2: j.addressLine2,
230
+ city: j.city,
231
+ state: j.state,
232
+ zipCode: j.zipCode,
233
+ isDefault: j.isDefault,
233
234
  usageCount: 0
234
235
  };
235
- w((t) => {
236
+ E((t) => {
236
237
  let n = [...t];
237
238
  return e.isDefault && (n = n.map((e) => ({
238
239
  ...e,
239
240
  isDefault: !1
240
241
  }))), [...n, e];
241
- }), A({ ...y }), E(!1), N("Address added successfully");
242
- }, I = () => {
243
- D && P(D) && (w((e) => e.map((e) => e.id === D.id ? D : D.isDefault ? {
242
+ }), M({ ...x }), O(!1), F("Address added successfully");
243
+ }, R = () => {
244
+ k && I(k) && (E((e) => e.map((e) => e.id === k.id ? k : k.isDefault ? {
244
245
  ...e,
245
246
  isDefault: !1
246
- } : e)), O(null), N("Address updated successfully"));
247
- }, L = (e) => {
247
+ } : e)), A(null), F("Address updated successfully"));
248
+ }, z = (e) => {
248
249
  if (u.find((t) => t.id === e)?.isDefault) {
249
250
  alert("Cannot delete default address. Set another address as default first.");
250
251
  return;
251
252
  }
252
- w((t) => t.filter((t) => t.id !== e)), N("Address deleted successfully");
253
- }, R = (e) => {
254
- w((t) => t.map((t) => ({
253
+ E((t) => t.filter((t) => t.id !== e)), F("Address deleted successfully");
254
+ }, B = (e) => {
255
+ E((t) => t.map((t) => ({
255
256
  ...t,
256
257
  isDefault: t.id === e
257
- }))), N("Default address updated");
258
- }, z = (e, t, n) => {
258
+ }))), F("Default address updated");
259
+ }, V = (e, t, n) => {
259
260
  e((e) => ({
260
261
  ...e,
261
262
  [t]: n
@@ -264,41 +265,46 @@ function w() {
264
265
  return /* @__PURE__ */ v(n, {
265
266
  title: "Saved Addresses",
266
267
  description: "Manage your delivery addresses for faster checkout",
267
- actions: T ? void 0 : /* @__PURE__ */ v("button", {
268
+ actions: D ? void 0 : /* @__PURE__ */ v("button", {
268
269
  type: "button",
269
- onClick: () => E(!0),
270
+ onClick: () => O(!0),
270
271
  className: t("flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-opacity", "bg-foreground text-background hover:opacity-90"),
271
272
  children: [/* @__PURE__ */ _(p, { className: "h-4 w-4" }), "Add New Address"]
272
273
  }),
273
274
  children: [
274
- j && /* @__PURE__ */ v("div", {
275
- className: "mb-4 rounded-lg border border-green-500/30 bg-green-500/10 p-3 flex items-center gap-2",
276
- children: [/* @__PURE__ */ _(s, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }), /* @__PURE__ */ _("p", {
277
- className: "text-sm text-green-600 dark:text-green-400",
278
- children: j
275
+ /* @__PURE__ */ _(b, {
276
+ icon: /* @__PURE__ */ _(d, { className: "h-4 w-4" }),
277
+ className: "mb-6",
278
+ children: "Save the places you order to most — home, work, a friend's — so checkout is one tap instead of retyping an address every time. Set a default for the address you use most, and edit or remove any that change. Accurate addresses mean fewer failed deliveries."
279
+ }),
280
+ N && /* @__PURE__ */ v("div", {
281
+ className: "mb-4 rounded-lg border border-status-success-border/30 bg-status-success-bg/10 p-3 flex items-center gap-2",
282
+ children: [/* @__PURE__ */ _(s, { className: "h-4 w-4 text-status-success-text shrink-0" }), /* @__PURE__ */ _("p", {
283
+ className: "text-sm text-status-success-text",
284
+ children: N
279
285
  })]
280
286
  }),
281
- T && /* @__PURE__ */ v("div", {
282
- className: "rounded-lg border border-border-subtle bg-bg-surface p-5 mb-6",
287
+ D && /* @__PURE__ */ v("div", {
288
+ className: "rounded-lg border border-border-seam bg-bg-surface p-5 mb-6",
283
289
  children: [/* @__PURE__ */ _("h3", {
284
290
  className: "text-base font-semibold text-text-primary mb-4",
285
291
  children: "Add New Address"
286
- }), /* @__PURE__ */ _(C, {
287
- data: k,
288
- onChange: (e, t) => z(A, e, t),
289
- onSubmit: F,
292
+ }), /* @__PURE__ */ _(T, {
293
+ data: j,
294
+ onChange: (e, t) => V(M, e, t),
295
+ onSubmit: L,
290
296
  onCancel: () => {
291
- E(!1), A({ ...y });
297
+ O(!1), M({ ...x });
292
298
  },
293
299
  submitLabel: "Save Address"
294
300
  })]
295
301
  }),
296
- u.length > 0 ? /* @__PURE__ */ _("div", {
302
+ u.length > 0 ? /* @__PURE__ */ _(y, {
297
303
  className: "space-y-3",
298
304
  children: u.map((e) => {
299
- let n = x[e.type];
305
+ let n = C[e.type];
300
306
  return /* @__PURE__ */ _("div", {
301
- className: t("rounded-lg border bg-bg-surface p-4", e.isDefault ? "border-foreground/30" : "border-border-subtle"),
307
+ className: t("rounded-lg border bg-bg-surface p-4", e.isDefault ? "border-foreground/30" : "border-border-seam"),
302
308
  children: /* @__PURE__ */ v("div", {
303
309
  className: "flex items-start justify-between gap-3",
304
310
  children: [/* @__PURE__ */ v("div", {
@@ -312,10 +318,10 @@ function w() {
312
318
  /* @__PURE__ */ v("div", {
313
319
  className: "flex flex-wrap items-center gap-2",
314
320
  children: [/* @__PURE__ */ _("span", {
315
- className: t("inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium capitalize", S[e.type]),
321
+ className: t("inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium capitalize", w[e.type]),
316
322
  children: e.type
317
323
  }), e.isDefault && /* @__PURE__ */ v("span", {
318
- className: "inline-flex items-center gap-1 rounded-full bg-green-500/10 px-2 py-0.5 text-[10px] font-medium text-green-600 dark:text-green-400",
324
+ className: "inline-flex items-center gap-1 rounded-full bg-status-success-bg/10 px-2 py-0.5 text-[10px] font-medium text-status-success-text",
319
325
  children: [/* @__PURE__ */ _(s, { className: "h-3 w-3" }), "Default"]
320
326
  })]
321
327
  }),
@@ -372,21 +378,21 @@ function w() {
372
378
  children: [
373
379
  !e.isDefault && /* @__PURE__ */ _("button", {
374
380
  type: "button",
375
- onClick: () => R(e.id),
381
+ onClick: () => B(e.id),
376
382
  title: "Set as default",
377
383
  className: "rounded-md p-2 text-text-secondary hover:bg-accent hover:text-text-primary transition-colors",
378
384
  children: /* @__PURE__ */ _(m, { className: "h-4 w-4" })
379
385
  }),
380
386
  /* @__PURE__ */ _("button", {
381
387
  type: "button",
382
- onClick: () => O({ ...e }),
388
+ onClick: () => A({ ...e }),
383
389
  title: "Edit address",
384
390
  className: "rounded-md p-2 text-text-secondary hover:bg-accent hover:text-text-primary transition-colors",
385
391
  children: /* @__PURE__ */ _(f, { className: "h-4 w-4" })
386
392
  }),
387
393
  /* @__PURE__ */ _("button", {
388
394
  type: "button",
389
- onClick: () => L(e.id),
395
+ onClick: () => z(e.id),
390
396
  title: "Delete address",
391
397
  className: "rounded-md p-2 text-text-secondary hover:bg-status-error-bg/10 hover:text-status-error-text transition-colors",
392
398
  children: /* @__PURE__ */ _(h, { className: "h-4 w-4" })
@@ -397,20 +403,21 @@ function w() {
397
403
  }, e.id);
398
404
  })
399
405
  }) : /* @__PURE__ */ _(r, {
406
+ illustration: "empty-data",
400
407
  icon: /* @__PURE__ */ _(d, { className: "h-12 w-12" }),
401
408
  title: "No saved addresses",
402
409
  description: "Add a delivery address to get started.",
403
410
  action: /* @__PURE__ */ _("button", {
404
411
  type: "button",
405
- onClick: () => E(!0),
412
+ onClick: () => O(!0),
406
413
  className: "rounded-lg bg-foreground px-4 py-2 text-sm font-medium text-background hover:opacity-90 transition-opacity",
407
414
  children: "Add Address"
408
415
  })
409
416
  }),
410
- D && /* @__PURE__ */ _("div", {
411
- className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4",
417
+ k && /* @__PURE__ */ _("div", {
418
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-canvas/50 p-4",
412
419
  children: /* @__PURE__ */ _("div", {
413
- className: "w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-lg border border-border-subtle bg-bg-surface shadow-lg",
420
+ className: "w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-lg border border-border-seam bg-bg-surface shadow-lg",
414
421
  children: /* @__PURE__ */ v("div", {
415
422
  className: "p-5",
416
423
  children: [/* @__PURE__ */ v("div", {
@@ -420,15 +427,15 @@ function w() {
420
427
  children: "Edit Address"
421
428
  }), /* @__PURE__ */ _("button", {
422
429
  type: "button",
423
- onClick: () => O(null),
430
+ onClick: () => A(null),
424
431
  className: "rounded-md p-2 text-text-secondary hover:bg-accent hover:text-text-primary transition-colors",
425
432
  children: /* @__PURE__ */ _(g, { className: "h-4 w-4" })
426
433
  })]
427
- }), /* @__PURE__ */ _(C, {
428
- data: D,
429
- onChange: (e, t) => z(O, e, t),
430
- onSubmit: I,
431
- onCancel: () => O(null),
434
+ }), /* @__PURE__ */ _(T, {
435
+ data: k,
436
+ onChange: (e, t) => V(A, e, t),
437
+ onSubmit: R,
438
+ onCancel: () => A(null),
432
439
  submitLabel: "Save Changes"
433
440
  })]
434
441
  })
@@ -438,6 +445,6 @@ function w() {
438
445
  });
439
446
  }
440
447
  //#endregion
441
- export { w as SavedAddressesPage };
448
+ export { E as SavedAddressesPage };
442
449
 
443
450
  //# sourceMappingURL=SavedAddressesPage.js.map