@burdenoff/microfe-proserviceworld 2026.625.1 → 2026.626.2

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 (31) hide show
  1. package/dist/proserviceworld/pages/AdminReportsPage.js +102 -68
  2. package/dist/proserviceworld/pages/AdminReportsPage.js.map +1 -1
  3. package/dist/proserviceworld/pages/AdminUsersPage.js +37 -33
  4. package/dist/proserviceworld/pages/AdminUsersPage.js.map +1 -1
  5. package/dist/proserviceworld/pages/AnalyticsPage.js +66 -36
  6. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  7. package/dist/proserviceworld/pages/BookingsPage.js +52 -48
  8. package/dist/proserviceworld/pages/BookingsPage.js.map +1 -1
  9. package/dist/proserviceworld/pages/DashboardPage.js +275 -243
  10. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  11. package/dist/proserviceworld/pages/DocumentsPage.js +204 -200
  12. package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
  13. package/dist/proserviceworld/pages/MessagesPage.js +200 -186
  14. package/dist/proserviceworld/pages/MessagesPage.js.map +1 -1
  15. package/dist/proserviceworld/pages/PaymentsPage.js +70 -39
  16. package/dist/proserviceworld/pages/PaymentsPage.js.map +1 -1
  17. package/dist/proserviceworld/pages/ProjectsPage.js +510 -477
  18. package/dist/proserviceworld/pages/ProjectsPage.js.map +1 -1
  19. package/dist/proserviceworld/pages/ProviderDetailPage.js +71 -41
  20. package/dist/proserviceworld/pages/ProviderDetailPage.js.map +1 -1
  21. package/dist/proserviceworld/pages/ProvidersPage.js +62 -58
  22. package/dist/proserviceworld/pages/ProvidersPage.js.map +1 -1
  23. package/dist/proserviceworld/pages/ReviewsPage.js +80 -63
  24. package/dist/proserviceworld/pages/ReviewsPage.js.map +1 -1
  25. package/dist/proserviceworld/pages/ServiceDetailsPage.js +118 -83
  26. package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +1 -1
  27. package/dist/proserviceworld/pages/ServicesPage.js +134 -130
  28. package/dist/proserviceworld/pages/ServicesPage.js.map +1 -1
  29. package/dist/proserviceworld/pages/VerificationPage.js +23 -19
  30. package/dist/proserviceworld/pages/VerificationPage.js.map +1 -1
  31. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"MessagesPage.js","names":[],"sources":["../../../src/proserviceworld/pages/MessagesPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n Badge,\n Button,\n Input,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Send,\n Circle,\n CheckCheck,\n Check,\n MessageSquare,\n Phone,\n Video,\n MoreHorizontal,\n Paperclip,\n Smile,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport { tWithFallback } from '../utils/i18n';\n\nexport function MessagesPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>): string =>\n tWithFallback(t, key, fallback, params);\n const { conversations } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedConversationId, setSelectedConversationId] = useState<string>(\n conversations[0]?.id ?? ''\n );\n const [messageInput, setMessageInput] = useState('');\n\n const filteredConversations = useMemo(() => {\n if (!searchQuery.trim()) return conversations;\n const q = searchQuery.toLowerCase();\n return conversations.filter(\n (c) => c.participantName.toLowerCase().includes(q) || c.lastMessage.toLowerCase().includes(q)\n );\n }, [conversations, searchQuery]);\n\n const selectedConversation = conversations.find((c) => c.id === selectedConversationId);\n const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);\n const unreadSummary =\n totalUnread > 0\n ? tr('proserviceworld.messages.subtitle.unread', '{{count}} unread messages', {\n count: totalUnread,\n })\n : tr('proserviceworld.messages.subtitle.caughtUp', 'All caught up');\n\n const formatTime = (timestamp: string) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffDays = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24));\n if (diffDays === 0) {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n if (diffDays === 1) return tr('proserviceworld.messages.time.yesterday', 'Yesterday');\n if (diffDays < 7) return date.toLocaleDateString([], { weekday: 'short' });\n return date.toLocaleDateString([], { month: 'short', day: 'numeric' });\n };\n\n return (\n <div className=\"p-6 bg-bg-canvas min-h-screen\">\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1 mb-6 flex items-center justify-between gap-4\">\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>{tr('proserviceworld.messages.title', 'Messages')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{unreadSummary}</p>\n </div>\n <Button size=\"sm\">\n <MessageSquare className=\"mr-2 h-4 w-4\" />\n {tr('proserviceworld.messages.actions.newMessage', 'New Message')}\n </Button>\n </div>\n\n <div\n className=\"grid gap-0 overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-pop lg:grid-cols-3\"\n style={{ height: 'calc(100vh - 220px)', minHeight: '500px' }}\n >\n {/* Conversation sidebar */}\n <div className=\"flex flex-col border-r border-border-seam lg:col-span-1\">\n {/* Search */}\n <div className=\"border-b border-border-seam p-3\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder={tr(\n 'proserviceworld.messages.search.placeholder',\n 'Search conversations...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n </div>\n\n {/* Conversation list */}\n <div className=\"flex-1 overflow-y-auto\">\n {filteredConversations.length === 0 ? (\n <div className=\"p-6 text-center text-sm text-text-secondary\">\n {tr('proserviceworld.messages.empty.list', 'No conversations found.')}\n </div>\n ) : (\n filteredConversations.map((conversation) => (\n <button\n key={conversation.id}\n onClick={() => setSelectedConversationId(conversation.id)}\n className={`w-full border-b border-border-seam p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-border-focus ${\n selectedConversationId === conversation.id\n ? 'bg-accent-soft'\n : 'hover:bg-bg-sunken/50'\n }`}\n >\n <div className=\"flex items-start gap-3\">\n {/* Avatar */}\n <div className=\"relative shrink-0\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary\">\n {conversation.participantName.charAt(0)}\n </div>\n {conversation.online && (\n <Circle className=\"absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-status-success-text text-status-success-text stroke-bg-surface motion-safe:animate-vc-glow-pulse\" />\n )}\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between\">\n <h3\n className={`truncate text-sm ${conversation.unreadCount > 0 ? 'font-bold' : 'font-medium'}`}\n >\n {conversation.participantName}\n </h3>\n <span className=\"shrink-0 text-xs text-text-secondary\">\n {formatTime(conversation.lastMessageTime)}\n </span>\n </div>\n <p className=\"text-xs text-text-secondary\">\n {conversation.participantRole}\n </p>\n <div className=\"mt-1 flex items-center justify-between\">\n <p\n className={`truncate text-xs ${conversation.unreadCount > 0 ? 'font-medium text-text-primary' : 'text-text-secondary'}`}\n >\n {conversation.lastMessage}\n </p>\n {conversation.unreadCount > 0 && (\n <Badge className=\"ml-2 h-5 w-5 shrink-0 rounded-full p-0 text-xs flex items-center justify-center\">\n {conversation.unreadCount}\n </Badge>\n )}\n </div>\n </div>\n </div>\n </button>\n ))\n )}\n </div>\n </div>\n\n {/* Chat area */}\n <div className=\"flex flex-col lg:col-span-2\">\n {selectedConversation ? (\n <>\n {/* Chat header */}\n <div className=\"flex items-center justify-between border-b border-border-seam p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary\">\n {selectedConversation.participantName.charAt(0)}\n </div>\n {selectedConversation.online && (\n <Circle className=\"absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-status-success-text text-status-success-text stroke-bg-surface motion-safe:animate-vc-glow-pulse\" />\n )}\n </div>\n <div>\n <h3 className=\"font-medium\">{selectedConversation.participantName}</h3>\n <p className=\"text-xs text-text-secondary\">\n {selectedConversation.online\n ? tr('proserviceworld.messages.presence.online', 'Online')\n : tr('proserviceworld.messages.presence.offline', 'Offline')}{' '}\n - {selectedConversation.participantRole}\n </p>\n </div>\n </div>\n <div className=\"flex gap-1\">\n <Button variant=\"outline\" size=\"sm\">\n <Phone className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <Video className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n {/* Messages area */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {selectedConversation.messages.map((message) => (\n <div\n key={message.id}\n className={`flex ${message.isOwn ? 'justify-end' : 'justify-start'}`}\n >\n <div\n className={`flex max-w-[75%] items-end gap-2 ${message.isOwn ? 'flex-row-reverse' : ''}`}\n >\n {!message.isOwn && (\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-accent-soft text-xs font-semibold text-text-primary\">\n {message.senderName.charAt(0)}\n </div>\n )}\n <div>\n <div\n className={`rounded-2xl px-4 py-2 ${\n message.isOwn\n ? 'bg-action-primary-bg text-action-primary-text rounded-br-md'\n : 'bg-bg-sunken rounded-bl-md'\n }`}\n >\n <p className=\"text-sm\">{message.content}</p>\n </div>\n <div\n className={`mt-1 flex items-center gap-1 text-xs text-text-secondary ${message.isOwn ? 'justify-end' : ''}`}\n >\n <span>{formatTime(message.timestamp)}</span>\n {message.isOwn &&\n (message.read ? (\n <CheckCheck className=\"h-3 w-3 text-accent-blue\" />\n ) : (\n <Check className=\"h-3 w-3\" />\n ))}\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n\n {/* Message input */}\n <div className=\"border-t border-border-seam p-3\">\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Paperclip className=\"h-4 w-4\" />\n </Button>\n <Input\n placeholder={tr(\n 'proserviceworld.messages.input.placeholder',\n 'Type a message...'\n )}\n value={messageInput}\n onChange={(e) => setMessageInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && messageInput.trim()) {\n setMessageInput('');\n }\n }}\n className=\"flex-1\"\n />\n <Button variant=\"outline\" size=\"sm\">\n <Smile className=\"h-4 w-4\" />\n </Button>\n <Button size=\"sm\" disabled={!messageInput.trim()}>\n <Send className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </>\n ) : (\n <div className=\"flex flex-1 items-center justify-center\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title={tr('proserviceworld.messages.emptyConversation.title', 'Select a conversation')}\n description={tr(\n 'proserviceworld.messages.emptyConversation.description',\n 'Choose a conversation to start messaging.'\n )}\n />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MessagesPage.js","names":[],"sources":["../../../src/proserviceworld/pages/MessagesPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n Badge,\n Button,\n Input,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Send,\n Circle,\n CheckCheck,\n Check,\n MessageSquare,\n Phone,\n Video,\n MoreHorizontal,\n Paperclip,\n Smile,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport { tWithFallback } from '../utils/i18n';\n\nexport function MessagesPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>): string =>\n tWithFallback(t, key, fallback, params);\n const { conversations } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedConversationId, setSelectedConversationId] = useState<string>(\n conversations[0]?.id ?? ''\n );\n const [messageInput, setMessageInput] = useState('');\n\n const filteredConversations = useMemo(() => {\n if (!searchQuery.trim()) return conversations;\n const q = searchQuery.toLowerCase();\n return conversations.filter(\n (c) => c.participantName.toLowerCase().includes(q) || c.lastMessage.toLowerCase().includes(q)\n );\n }, [conversations, searchQuery]);\n\n const selectedConversation = conversations.find((c) => c.id === selectedConversationId);\n const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);\n const unreadSummary =\n totalUnread > 0\n ? tr('proserviceworld.messages.subtitle.unread', '{{count}} unread messages', {\n count: totalUnread,\n })\n : tr('proserviceworld.messages.subtitle.caughtUp', 'All caught up');\n\n const formatTime = (timestamp: string) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffDays = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24));\n if (diffDays === 0) {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n if (diffDays === 1) return tr('proserviceworld.messages.time.yesterday', 'Yesterday');\n if (diffDays < 7) return date.toLocaleDateString([], { weekday: 'short' });\n return date.toLocaleDateString([], { month: 'short', day: 'numeric' });\n };\n\n return (\n <div className=\"p-6 bg-bg-canvas min-h-screen\">\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1 mb-6 flex items-center justify-between gap-4\">\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>{tr('proserviceworld.messages.title', 'Messages')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{unreadSummary}</p>\n </div>\n <Button size=\"sm\">\n <MessageSquare className=\"mr-2 h-4 w-4\" />\n {tr('proserviceworld.messages.actions.newMessage', 'New Message')}\n </Button>\n </div>\n\n <div className=\"mb-6\">\n <PagePurpose icon={<MessageSquare className=\"h-4 w-4\" />}>\n {tr(\n 'proserviceworld.messages.purpose',\n 'Keep every client and provider conversation in one place. Discuss scope, share updates, and coordinate bookings in real time — pick a conversation on the left to read the full thread and reply.'\n )}\n </PagePurpose>\n </div>\n\n <div\n className=\"grid gap-0 overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-pop lg:grid-cols-3\"\n style={{ height: 'calc(100vh - 220px)', minHeight: '500px' }}\n >\n {/* Conversation sidebar */}\n <div className=\"flex flex-col border-r border-border-seam lg:col-span-1\">\n {/* Search */}\n <div className=\"border-b border-border-seam p-3\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder={tr(\n 'proserviceworld.messages.search.placeholder',\n 'Search conversations...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n </div>\n\n {/* Conversation list */}\n <div className=\"flex-1 overflow-y-auto\">\n {filteredConversations.length === 0 ? (\n <div className=\"p-4\">\n <IllustratedEmptyState\n illustration={searchQuery ? 'empty-search' : 'empty-people'}\n title={tr('proserviceworld.messages.empty.list', 'No conversations found')}\n description={\n searchQuery\n ? tr(\n 'proserviceworld.messages.empty.listSearch',\n 'No conversations match your search.'\n )\n : tr(\n 'proserviceworld.messages.empty.listDescription',\n 'Conversations with clients and providers will appear here.'\n )\n }\n />\n </div>\n ) : (\n filteredConversations.map((conversation) => (\n <button\n key={conversation.id}\n onClick={() => setSelectedConversationId(conversation.id)}\n className={`w-full border-b border-border-seam p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-border-focus ${\n selectedConversationId === conversation.id\n ? 'bg-accent-soft'\n : 'hover:bg-bg-sunken/50'\n }`}\n >\n <div className=\"flex items-start gap-3\">\n {/* Avatar */}\n <div className=\"relative shrink-0\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary\">\n {conversation.participantName.charAt(0)}\n </div>\n {conversation.online && (\n <Circle className=\"absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-status-success-text text-status-success-text stroke-bg-surface motion-safe:animate-vc-glow-pulse\" />\n )}\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between\">\n <h3\n className={`truncate text-sm ${conversation.unreadCount > 0 ? 'font-bold' : 'font-medium'}`}\n >\n {conversation.participantName}\n </h3>\n <span className=\"shrink-0 text-xs text-text-secondary\">\n {formatTime(conversation.lastMessageTime)}\n </span>\n </div>\n <p className=\"text-xs text-text-secondary\">\n {conversation.participantRole}\n </p>\n <div className=\"mt-1 flex items-center justify-between\">\n <p\n className={`truncate text-xs ${conversation.unreadCount > 0 ? 'font-medium text-text-primary' : 'text-text-secondary'}`}\n >\n {conversation.lastMessage}\n </p>\n {conversation.unreadCount > 0 && (\n <Badge className=\"ml-2 h-5 w-5 shrink-0 rounded-full p-0 text-xs flex items-center justify-center\">\n {conversation.unreadCount}\n </Badge>\n )}\n </div>\n </div>\n </div>\n </button>\n ))\n )}\n </div>\n </div>\n\n {/* Chat area */}\n <div className=\"flex flex-col lg:col-span-2\">\n {selectedConversation ? (\n <>\n {/* Chat header */}\n <div className=\"flex items-center justify-between border-b border-border-seam p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary\">\n {selectedConversation.participantName.charAt(0)}\n </div>\n {selectedConversation.online && (\n <Circle className=\"absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-status-success-text text-status-success-text stroke-bg-surface motion-safe:animate-vc-glow-pulse\" />\n )}\n </div>\n <div>\n <h3 className=\"font-medium\">{selectedConversation.participantName}</h3>\n <p className=\"text-xs text-text-secondary\">\n {selectedConversation.online\n ? tr('proserviceworld.messages.presence.online', 'Online')\n : tr('proserviceworld.messages.presence.offline', 'Offline')}{' '}\n - {selectedConversation.participantRole}\n </p>\n </div>\n </div>\n <div className=\"flex gap-1\">\n <Button variant=\"outline\" size=\"sm\">\n <Phone className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <Video className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n {/* Messages area */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {selectedConversation.messages.map((message) => (\n <div\n key={message.id}\n className={`flex ${message.isOwn ? 'justify-end' : 'justify-start'}`}\n >\n <div\n className={`flex max-w-[75%] items-end gap-2 ${message.isOwn ? 'flex-row-reverse' : ''}`}\n >\n {!message.isOwn && (\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-accent-soft text-xs font-semibold text-text-primary\">\n {message.senderName.charAt(0)}\n </div>\n )}\n <div>\n <div\n className={`rounded-2xl px-4 py-2 ${\n message.isOwn\n ? 'bg-action-primary-bg text-action-primary-text rounded-br-md'\n : 'bg-bg-sunken rounded-bl-md'\n }`}\n >\n <p className=\"text-sm\">{message.content}</p>\n </div>\n <div\n className={`mt-1 flex items-center gap-1 text-xs text-text-secondary ${message.isOwn ? 'justify-end' : ''}`}\n >\n <span>{formatTime(message.timestamp)}</span>\n {message.isOwn &&\n (message.read ? (\n <CheckCheck className=\"h-3 w-3 text-accent-blue\" />\n ) : (\n <Check className=\"h-3 w-3\" />\n ))}\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n\n {/* Message input */}\n <div className=\"border-t border-border-seam p-3\">\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Paperclip className=\"h-4 w-4\" />\n </Button>\n <Input\n placeholder={tr(\n 'proserviceworld.messages.input.placeholder',\n 'Type a message...'\n )}\n value={messageInput}\n onChange={(e) => setMessageInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && messageInput.trim()) {\n setMessageInput('');\n }\n }}\n className=\"flex-1\"\n />\n <Button variant=\"outline\" size=\"sm\">\n <Smile className=\"h-4 w-4\" />\n </Button>\n <Button size=\"sm\" disabled={!messageInput.trim()}>\n <Send className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </>\n ) : (\n <div className=\"flex flex-1 items-center justify-center\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title={tr('proserviceworld.messages.emptyConversation.title', 'Select a conversation')}\n description={tr(\n 'proserviceworld.messages.emptyConversation.description',\n 'Choose a conversation to start messaging.'\n )}\n />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -2,21 +2,21 @@ import { useProServiceWorldStore as e } from "../store/proserviceworldStore.js";
2
2
  import { useMemo as t, useState as n } from "react";
3
3
  import { ArrowDownLeft as r, ArrowUpRight as i, Building2 as a, Clock as o, CreditCard as s, DollarSign as c, Download as l, FileText as u, Plus as d, RotateCcw as f, Search as p, Shield as m, Wallet as h } from "lucide-react";
4
4
  import { jsx as g, jsxs as _ } from "react/jsx-runtime";
5
- import { AuroraBackground as v, Badge as y, Button as b, Card as x, CardContent as S, CardHeader as C, CardTitle as w, GlassCard as T, GradientText as E, IllustratedEmptyState as D, Input as O } from "@burdenoff/fe-libs/ui";
5
+ import { AuroraBackground as v, Badge as y, Button as b, Card as x, CardContent as S, CardHeader as C, CardTitle as w, GlassCard as T, GradientText as E, IllustratedEmptyState as D, Input as O, NextSteps as k, PagePurpose as A } from "@burdenoff/fe-libs/ui";
6
6
  //#region src/proserviceworld/pages/PaymentsPage.tsx
7
- function k() {
8
- let { transactions: k, paymentMethods: A, invoices: j } = e(), [M, N] = n("overview"), [P, F] = n(""), [I, L] = n("all"), R = k.filter((e) => e.type === "outgoing" && e.status === "completed").reduce((e, t) => e + t.amount, 0), z = k.filter((e) => e.status === "pending").reduce((e, t) => e + t.amount, 0), B = k.filter((e) => e.status === "completed").reduce((e, t) => e + t.fees, 0), V = k.filter((e) => e.type === "refund" && e.status === "completed").reduce((e, t) => e + t.amount, 0), H = t(() => {
9
- let e = [...k];
10
- if (I !== "all" && (e = e.filter((e) => e.status === I)), P.trim()) {
11
- let t = P.toLowerCase();
7
+ function j() {
8
+ let { transactions: j, paymentMethods: M, invoices: N } = e(), [P, F] = n("overview"), [I, L] = n(""), [R, z] = n("all"), B = j.filter((e) => e.type === "outgoing" && e.status === "completed").reduce((e, t) => e + t.amount, 0), V = j.filter((e) => e.status === "pending").reduce((e, t) => e + t.amount, 0), H = j.filter((e) => e.status === "completed").reduce((e, t) => e + t.fees, 0), U = j.filter((e) => e.type === "refund" && e.status === "completed").reduce((e, t) => e + t.amount, 0), W = t(() => {
9
+ let e = [...j];
10
+ if (R !== "all" && (e = e.filter((e) => e.status === R)), I.trim()) {
11
+ let t = I.toLowerCase();
12
12
  e = e.filter((e) => e.description.toLowerCase().includes(t) || e.counterparty.toLowerCase().includes(t) || (e.serviceName?.toLowerCase().includes(t) ?? !1));
13
13
  }
14
14
  return e.sort((e, t) => new Date(t.createdAt).getTime() - new Date(e.createdAt).getTime());
15
15
  }, [
16
- k,
17
- I,
18
- P
19
- ]), U = (e) => e === "outgoing" ? /* @__PURE__ */ g(i, { className: "h-4 w-4 text-status-error-text" }) : e === "refund" ? /* @__PURE__ */ g(f, { className: "h-4 w-4 text-status-success-text" }) : /* @__PURE__ */ g(r, { className: "h-4 w-4 text-accent-blue" }), W = (e) => /* @__PURE__ */ g(y, {
16
+ j,
17
+ R,
18
+ I
19
+ ]), G = (e) => e === "outgoing" ? /* @__PURE__ */ g(i, { className: "h-4 w-4 text-status-error-text" }) : e === "refund" ? /* @__PURE__ */ g(f, { className: "h-4 w-4 text-status-success-text" }) : /* @__PURE__ */ g(r, { className: "h-4 w-4 text-accent-blue" }), K = (e) => /* @__PURE__ */ g(y, {
20
20
  variant: {
21
21
  completed: "default",
22
22
  pending: "secondary",
@@ -24,7 +24,7 @@ function k() {
24
24
  cancelled: "outline"
25
25
  }[e] ?? "secondary",
26
26
  children: e
27
- }), G = (e) => g(e === "card" ? s : e === "bank" ? a : h, { className: "h-5 w-5" });
27
+ }), q = (e) => g(e === "card" ? s : e === "bank" ? a : h, { className: "h-5 w-5" });
28
28
  return /* @__PURE__ */ _("div", {
29
29
  className: "space-y-6 p-6 bg-bg-canvas min-h-screen",
30
30
  children: [
@@ -44,6 +44,37 @@ function k() {
44
44
  })]
45
45
  })]
46
46
  }),
47
+ /* @__PURE__ */ g(A, {
48
+ icon: /* @__PURE__ */ g(c, { className: "h-4 w-4" }),
49
+ children: "Your money, end to end. See what you have spent, what is pending, and what has been refunded; search and reconcile individual transactions; manage the cards and bank accounts you pay with; and download invoices for your records."
50
+ }),
51
+ /* @__PURE__ */ g(k, {
52
+ storageKey: "proserviceworld-payments",
53
+ steps: [
54
+ {
55
+ id: "transactions",
56
+ label: "Review your transactions",
57
+ description: "Search and filter every payment, fee, and refund.",
58
+ icon: /* @__PURE__ */ g(p, { className: "h-4 w-4" }),
59
+ onClick: () => F("transactions")
60
+ },
61
+ {
62
+ id: "methods",
63
+ label: "Manage payment methods",
64
+ description: "Add or set a default card, bank, or wallet.",
65
+ icon: /* @__PURE__ */ g(s, { className: "h-4 w-4" }),
66
+ onClick: () => F("methods"),
67
+ done: M.length > 0
68
+ },
69
+ {
70
+ id: "invoices",
71
+ label: "Check your invoices",
72
+ description: "View and download invoices you create or receive.",
73
+ icon: /* @__PURE__ */ g(u, { className: "h-4 w-4" }),
74
+ onClick: () => F("invoices")
75
+ }
76
+ ]
77
+ }),
47
78
  /* @__PURE__ */ g("div", {
48
79
  className: "flex flex-wrap gap-1 border-b border-border-seam",
49
80
  children: [
@@ -64,13 +95,13 @@ function k() {
64
95
  label: "Invoices"
65
96
  }
66
97
  ].map(({ key: e, label: t }) => /* @__PURE__ */ g("button", {
67
- onClick: () => N(e),
68
- "aria-pressed": M === e,
69
- className: `border-b-2 px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${M === e ? "border-action-primary-bg text-text-primary" : "border-transparent text-text-secondary hover:text-text-primary"}`,
98
+ onClick: () => F(e),
99
+ "aria-pressed": P === e,
100
+ className: `border-b-2 px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${P === e ? "border-action-primary-bg text-text-primary" : "border-transparent text-text-secondary hover:text-text-primary"}`,
70
101
  children: t
71
102
  }, e))
72
103
  }),
73
- M === "overview" && /* @__PURE__ */ _("div", {
104
+ P === "overview" && /* @__PURE__ */ _("div", {
74
105
  className: "space-y-6",
75
106
  children: [/* @__PURE__ */ _("div", {
76
107
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-4",
@@ -86,7 +117,7 @@ function k() {
86
117
  children: /* @__PURE__ */ g(i, { className: "h-5 w-5 text-status-error-text" })
87
118
  }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("p", {
88
119
  className: "text-2xl font-bold tabular-nums",
89
- children: ["$", R.toLocaleString()]
120
+ children: ["$", B.toLocaleString()]
90
121
  }), /* @__PURE__ */ g("p", {
91
122
  className: "text-xs text-text-secondary",
92
123
  children: "Total Spent"
@@ -103,7 +134,7 @@ function k() {
103
134
  children: /* @__PURE__ */ g(o, { className: "h-5 w-5 text-status-warning-text" })
104
135
  }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("p", {
105
136
  className: "text-2xl font-bold tabular-nums",
106
- children: ["$", z.toLocaleString()]
137
+ children: ["$", V.toLocaleString()]
107
138
  }), /* @__PURE__ */ g("p", {
108
139
  className: "text-xs text-text-secondary",
109
140
  children: "Pending"
@@ -120,7 +151,7 @@ function k() {
120
151
  children: /* @__PURE__ */ g(c, { className: "h-5 w-5 text-accent-blue" })
121
152
  }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("p", {
122
153
  className: "text-2xl font-bold tabular-nums",
123
- children: ["$", B.toLocaleString()]
154
+ children: ["$", H.toLocaleString()]
124
155
  }), /* @__PURE__ */ g("p", {
125
156
  className: "text-xs text-text-secondary",
126
157
  children: "Total Fees"
@@ -137,7 +168,7 @@ function k() {
137
168
  children: /* @__PURE__ */ g(f, { className: "h-5 w-5 text-status-success-text" })
138
169
  }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("p", {
139
170
  className: "text-2xl font-bold tabular-nums",
140
- children: ["$", V.toLocaleString()]
171
+ children: ["$", U.toLocaleString()]
141
172
  }), /* @__PURE__ */ g("p", {
142
173
  className: "text-xs text-text-secondary",
143
174
  children: "Refunded"
@@ -155,16 +186,16 @@ function k() {
155
186
  }), /* @__PURE__ */ g(b, {
156
187
  variant: "outline",
157
188
  size: "sm",
158
- onClick: () => N("transactions"),
189
+ onClick: () => F("transactions"),
159
190
  children: "View All"
160
191
  })]
161
192
  }) }), /* @__PURE__ */ g(S, { children: /* @__PURE__ */ g("div", {
162
193
  className: "space-y-3",
163
- children: k.slice(0, 5).map((e) => /* @__PURE__ */ _("div", {
194
+ children: j.slice(0, 5).map((e) => /* @__PURE__ */ _("div", {
164
195
  className: "flex items-center justify-between rounded-lg border border-border-seam p-3 transition-shadow hover:shadow-pop",
165
196
  children: [/* @__PURE__ */ _("div", {
166
197
  className: "flex items-center gap-3",
167
- children: [U(e.type), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("p", {
198
+ children: [G(e.type), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("p", {
168
199
  className: "text-sm font-medium",
169
200
  children: e.description
170
201
  }), /* @__PURE__ */ _("p", {
@@ -184,13 +215,13 @@ function k() {
184
215
  "$",
185
216
  e.amount.toLocaleString()
186
217
  ]
187
- }), W(e.status)]
218
+ }), K(e.status)]
188
219
  })]
189
220
  }, e.id))
190
221
  }) })]
191
222
  })]
192
223
  }),
193
- M === "transactions" && /* @__PURE__ */ _("div", {
224
+ P === "transactions" && /* @__PURE__ */ _("div", {
194
225
  className: "space-y-4",
195
226
  children: [/* @__PURE__ */ _("div", {
196
227
  className: "flex flex-col gap-4 sm:flex-row sm:items-center",
@@ -198,8 +229,8 @@ function k() {
198
229
  className: "relative flex-1",
199
230
  children: [/* @__PURE__ */ g(p, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ g(O, {
200
231
  placeholder: "Search transactions...",
201
- value: P,
202
- onChange: (e) => F(e.target.value),
232
+ value: I,
233
+ onChange: (e) => L(e.target.value),
203
234
  className: "pl-10"
204
235
  })]
205
236
  }), /* @__PURE__ */ g("div", {
@@ -210,9 +241,9 @@ function k() {
210
241
  "pending",
211
242
  "failed"
212
243
  ].map((e) => /* @__PURE__ */ g(b, {
213
- variant: I === e ? "default" : "outline",
244
+ variant: R === e ? "default" : "outline",
214
245
  size: "sm",
215
- onClick: () => L(e),
246
+ onClick: () => z(e),
216
247
  children: e === "all" ? "All" : e.charAt(0).toUpperCase() + e.slice(1)
217
248
  }, e))
218
249
  })]
@@ -220,7 +251,7 @@ function k() {
220
251
  className: "border-border-seam",
221
252
  children: /* @__PURE__ */ g(S, {
222
253
  className: "pt-4",
223
- children: H.length === 0 ? /* @__PURE__ */ g(D, {
254
+ children: W.length === 0 ? /* @__PURE__ */ g(D, {
224
255
  illustration: "empty-search",
225
256
  title: "No transactions found",
226
257
  description: "No transactions match your current filters."
@@ -268,12 +299,12 @@ function k() {
268
299
  children: "Date"
269
300
  })
270
301
  ]
271
- }) }), /* @__PURE__ */ g("tbody", { children: H.map((e) => /* @__PURE__ */ _("tr", {
302
+ }) }), /* @__PURE__ */ g("tbody", { children: W.map((e) => /* @__PURE__ */ _("tr", {
272
303
  className: "border-b border-border-seam transition-colors hover:bg-bg-sunken/50",
273
304
  children: [
274
305
  /* @__PURE__ */ g("td", {
275
306
  className: "p-3",
276
- children: U(e.type)
307
+ children: G(e.type)
277
308
  }),
278
309
  /* @__PURE__ */ g("td", {
279
310
  className: "p-3 font-medium",
@@ -308,7 +339,7 @@ function k() {
308
339
  }),
309
340
  /* @__PURE__ */ g("td", {
310
341
  className: "p-3",
311
- children: W(e.status)
342
+ children: K(e.status)
312
343
  }),
313
344
  /* @__PURE__ */ g("td", {
314
345
  className: "p-3 text-text-secondary",
@@ -321,11 +352,11 @@ function k() {
321
352
  })
322
353
  })]
323
354
  }),
324
- M === "methods" && /* @__PURE__ */ g("div", {
355
+ P === "methods" && /* @__PURE__ */ g("div", {
325
356
  className: "space-y-4",
326
357
  children: /* @__PURE__ */ _("div", {
327
358
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
328
- children: [A.map((e) => /* @__PURE__ */ _(T, {
359
+ children: [M.map((e) => /* @__PURE__ */ _(T, {
329
360
  treatment: "glass",
330
361
  glow: e.isDefault,
331
362
  className: `border-border-seam ${e.isDefault, ""}`,
@@ -336,7 +367,7 @@ function k() {
336
367
  className: "flex items-center gap-3",
337
368
  children: [/* @__PURE__ */ g("div", {
338
369
  className: "rounded-lg border border-border-seam p-2 text-text-primary",
339
- children: G(e.type)
370
+ children: q(e.type)
340
371
  }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("p", {
341
372
  className: "font-medium",
342
373
  children: e.name
@@ -393,13 +424,13 @@ function k() {
393
424
  })]
394
425
  })
395
426
  }),
396
- M === "invoices" && /* @__PURE__ */ g("div", {
427
+ P === "invoices" && /* @__PURE__ */ g("div", {
397
428
  className: "space-y-4",
398
429
  children: /* @__PURE__ */ g(x, {
399
430
  className: "border-border-seam",
400
431
  children: /* @__PURE__ */ g(S, {
401
432
  className: "pt-4",
402
- children: j.length === 0 ? /* @__PURE__ */ g(D, {
433
+ children: N.length === 0 ? /* @__PURE__ */ g(D, {
403
434
  illustration: "empty-files",
404
435
  title: "No invoices yet",
405
436
  description: "Invoices you create or receive will appear here."
@@ -439,7 +470,7 @@ function k() {
439
470
  children: "Actions"
440
471
  })
441
472
  ]
442
- }) }), /* @__PURE__ */ g("tbody", { children: j.map((e) => /* @__PURE__ */ _("tr", {
473
+ }) }), /* @__PURE__ */ g("tbody", { children: N.map((e) => /* @__PURE__ */ _("tr", {
443
474
  className: "border-b border-border-seam transition-colors hover:bg-bg-sunken/50",
444
475
  children: [
445
476
  /* @__PURE__ */ g("td", {
@@ -501,6 +532,6 @@ function k() {
501
532
  });
502
533
  }
503
534
  //#endregion
504
- export { k as PaymentsPage };
535
+ export { j as PaymentsPage };
505
536
 
506
537
  //# sourceMappingURL=PaymentsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PaymentsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/PaymentsPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n GlassCard,\n IllustratedEmptyState,\n AuroraBackground,\n GradientText,\n} from '@burdenoff/fe-libs/ui';\nimport {\n DollarSign,\n CreditCard,\n Building2,\n Wallet,\n ArrowUpRight,\n ArrowDownLeft,\n RotateCcw,\n Clock,\n Search,\n FileText,\n Plus,\n Shield,\n Download,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\n\ntype PaymentTab = 'overview' | 'transactions' | 'methods' | 'invoices';\n\nexport function PaymentsPage() {\n const { transactions, paymentMethods, invoices } = useProServiceWorldStore();\n const [activeTab, setActiveTab] = useState<PaymentTab>('overview');\n const [searchQuery, setSearchQuery] = useState('');\n const [txnStatusFilter, setTxnStatusFilter] = useState<string>('all');\n\n // Overview stats\n const totalSpent = transactions\n .filter((t) => t.type === 'outgoing' && t.status === 'completed')\n .reduce((s, t) => s + t.amount, 0);\n const totalPending = transactions\n .filter((t) => t.status === 'pending')\n .reduce((s, t) => s + t.amount, 0);\n const totalFees = transactions\n .filter((t) => t.status === 'completed')\n .reduce((s, t) => s + t.fees, 0);\n const totalRefunded = transactions\n .filter((t) => t.type === 'refund' && t.status === 'completed')\n .reduce((s, t) => s + t.amount, 0);\n\n // Filter transactions\n const filteredTxns = useMemo(() => {\n let result = [...transactions];\n if (txnStatusFilter !== 'all') {\n result = result.filter((t) => t.status === txnStatusFilter);\n }\n if (searchQuery.trim()) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (t) =>\n t.description.toLowerCase().includes(q) ||\n t.counterparty.toLowerCase().includes(q) ||\n (t.serviceName?.toLowerCase().includes(q) ?? false)\n );\n }\n return result.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n }, [transactions, txnStatusFilter, searchQuery]);\n\n const txnTypeIcon = (type: string) => {\n if (type === 'outgoing') return <ArrowUpRight className=\"h-4 w-4 text-status-error-text\" />;\n if (type === 'refund') return <RotateCcw className=\"h-4 w-4 text-status-success-text\" />;\n return <ArrowDownLeft className=\"h-4 w-4 text-accent-blue\" />;\n };\n\n const statusBadge = (status: string) => {\n const variants: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n completed: 'default',\n pending: 'secondary',\n failed: 'destructive',\n cancelled: 'outline',\n };\n return <Badge variant={variants[status] ?? 'secondary'}>{status}</Badge>;\n };\n\n const methodIcon = (type: string) => {\n if (type === 'card') return <CreditCard className=\"h-5 w-5\" />;\n if (type === 'bank') return <Building2 className=\"h-5 w-5\" />;\n return <Wallet className=\"h-5 w-5\" />;\n };\n\n const tabs: { key: PaymentTab; label: string }[] = [\n { key: 'overview', label: 'Overview' },\n { key: 'transactions', label: 'Transactions' },\n { key: 'methods', label: 'Payment Methods' },\n { key: 'invoices', label: 'Invoices' },\n ];\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n {/* Hero header — the ONE aurora backdrop for this MFE */}\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>Payments</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Track transactions, manage payment methods, and view invoices.\n </p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" /> Make Payment\n </Button>\n </div>\n </div>\n\n {/* Tabs */}\n <div className=\"flex flex-wrap gap-1 border-b border-border-seam\">\n {tabs.map(({ key, label }) => (\n <button\n key={key}\n onClick={() => setActiveTab(key)}\n aria-pressed={activeTab === key}\n className={`border-b-2 px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${\n activeTab === key\n ? 'border-action-primary-bg text-text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n }`}\n >\n {label}\n </button>\n ))}\n </div>\n\n {/* Overview Tab */}\n {activeTab === 'overview' && (\n <div className=\"space-y-6\">\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-error-bg-subtle p-2\">\n <ArrowUpRight className=\"h-5 w-5 text-status-error-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">${totalSpent.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Total Spent</p>\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-warning-bg-subtle p-2\">\n <Clock className=\"h-5 w-5 text-status-warning-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">${totalPending.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Pending</p>\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-info-bg-subtle p-2\">\n <DollarSign className=\"h-5 w-5 text-accent-blue\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">${totalFees.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Total Fees</p>\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-success-bg-subtle p-2\">\n <RotateCcw className=\"h-5 w-5 text-status-success-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">\n ${totalRefunded.toLocaleString()}\n </p>\n <p className=\"text-xs text-text-secondary\">Refunded</p>\n </div>\n </div>\n </GlassCard>\n </div>\n\n {/* Recent transactions preview */}\n <Card className=\"border-border-seam\">\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">Recent Transactions</CardTitle>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setActiveTab('transactions')}>\n View All\n </Button>\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {transactions.slice(0, 5).map((txn) => (\n <div\n key={txn.id}\n className=\"flex items-center justify-between rounded-lg border border-border-seam p-3 transition-shadow hover:shadow-pop\"\n >\n <div className=\"flex items-center gap-3\">\n {txnTypeIcon(txn.type)}\n <div>\n <p className=\"text-sm font-medium\">{txn.description}</p>\n <p className=\"text-xs text-text-secondary\">\n {txn.counterparty} - {txn.createdAt}\n </p>\n </div>\n </div>\n <div className=\"text-right\">\n <p\n className={`text-sm font-bold tabular-nums ${txn.type === 'refund' ? 'text-status-success-text' : ''}`}\n >\n {txn.type === 'refund' ? '+' : '-'}${txn.amount.toLocaleString()}\n </p>\n {statusBadge(txn.status)}\n </div>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Transactions Tab */}\n {activeTab === 'transactions' && (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search transactions...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {['all', 'completed', 'pending', 'failed'].map((status) => (\n <Button\n key={status}\n variant={txnStatusFilter === status ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setTxnStatusFilter(status)}\n >\n {status === 'all' ? 'All' : status.charAt(0).toUpperCase() + status.slice(1)}\n </Button>\n ))}\n </div>\n </div>\n\n <Card className=\"border-border-seam\">\n <CardContent className=\"pt-4\">\n {filteredTxns.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No transactions found\"\n description=\"No transactions match your current filters.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left text-text-secondary\">\n <th className=\"p-3 font-medium\">Type</th>\n <th className=\"p-3 font-medium\">Description</th>\n <th className=\"p-3 font-medium\">Counterparty</th>\n <th className=\"p-3 font-medium\">Method</th>\n <th className=\"p-3 text-right font-medium\">Amount</th>\n <th className=\"p-3 text-right font-medium\">Fees</th>\n <th className=\"p-3 text-right font-medium\">Net</th>\n <th className=\"p-3 font-medium\">Status</th>\n <th className=\"p-3 font-medium\">Date</th>\n </tr>\n </thead>\n <tbody>\n {filteredTxns.map((txn) => (\n <tr\n key={txn.id}\n className=\"border-b border-border-seam transition-colors hover:bg-bg-sunken/50\"\n >\n <td className=\"p-3\">{txnTypeIcon(txn.type)}</td>\n <td className=\"p-3 font-medium\">{txn.description}</td>\n <td className=\"p-3\">{txn.counterparty}</td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{txn.method.replace('_', ' ')}</Badge>\n </td>\n <td\n className={`p-3 text-right font-medium tabular-nums ${txn.type === 'refund' ? 'text-status-success-text' : ''}`}\n >\n {txn.type === 'refund' ? '+' : '-'}${txn.amount.toLocaleString()}\n </td>\n <td className=\"p-3 text-right text-text-secondary tabular-nums\">\n ${txn.fees}\n </td>\n <td className=\"p-3 text-right tabular-nums\">\n ${txn.netAmount.toLocaleString()}\n </td>\n <td className=\"p-3\">{statusBadge(txn.status)}</td>\n <td className=\"p-3 text-text-secondary\">{txn.createdAt}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Payment Methods Tab */}\n {activeTab === 'methods' && (\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {paymentMethods.map((method) => (\n <GlassCard\n key={method.id}\n treatment=\"glass\"\n glow={method.isDefault}\n className={`border-border-seam ${method.isDefault ? '' : ''}`}\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg border border-border-seam p-2 text-text-primary\">\n {methodIcon(method.type)}\n </div>\n <div>\n <p className=\"font-medium\">{method.name}</p>\n <p className=\"text-sm text-text-secondary\">{method.details}</p>\n </div>\n </div>\n {method.isDefault && <Badge>Default</Badge>}\n </div>\n\n <div className=\"mt-4 flex items-center gap-4 text-sm\">\n {method.isVerified ? (\n <span className=\"flex items-center gap-1 text-status-success-text\">\n <Shield className=\"h-4 w-4\" /> Verified\n </span>\n ) : (\n <span className=\"flex items-center gap-1 text-status-warning-text\">\n <Clock className=\"h-4 w-4\" /> Unverified\n </span>\n )}\n {method.lastUsed && (\n <span className=\"text-text-secondary\">Last used: {method.lastUsed}</span>\n )}\n </div>\n\n <div className=\"mt-4 flex gap-2\">\n {!method.isDefault && (\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1\">\n Set Default\n </Button>\n )}\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1\">\n Remove\n </Button>\n </div>\n </GlassCard>\n ))}\n\n {/* Add new method card */}\n <Card className=\"flex items-center justify-center border-dashed border-border-seam transition-shadow hover:shadow-pop\">\n <CardContent className=\"py-8 text-center\">\n <Plus className=\"mx-auto h-8 w-8 text-text-secondary\" />\n <p className=\"mt-2 text-sm font-medium\">Add Payment Method</p>\n <p className=\"text-xs text-text-secondary\">Add a new card, bank, or PayPal</p>\n </CardContent>\n </Card>\n </div>\n </div>\n )}\n\n {/* Invoices Tab */}\n {activeTab === 'invoices' && (\n <div className=\"space-y-4\">\n <Card className=\"border-border-seam\">\n <CardContent className=\"pt-4\">\n {invoices.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-files\"\n title=\"No invoices yet\"\n description=\"Invoices you create or receive will appear here.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left text-text-secondary\">\n <th className=\"p-3 font-medium\">Invoice #</th>\n <th className=\"p-3 font-medium\">Description</th>\n <th className=\"p-3 font-medium\">Client</th>\n <th className=\"p-3 text-right font-medium\">Amount</th>\n <th className=\"p-3 font-medium\">Status</th>\n <th className=\"p-3 font-medium\">Due Date</th>\n <th className=\"p-3 text-right font-medium\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {invoices.map((inv) => {\n const invoiceStatusVariant: Record<\n string,\n 'default' | 'secondary' | 'destructive'\n > = {\n paid: 'default',\n pending: 'secondary',\n overdue: 'destructive',\n };\n return (\n <tr\n key={inv.id}\n className=\"border-b border-border-seam transition-colors hover:bg-bg-sunken/50\"\n >\n <td className=\"p-3 font-medium\">{inv.number}</td>\n <td className=\"p-3\">{inv.description}</td>\n <td className=\"p-3\">{inv.clientName}</td>\n <td className=\"p-3 text-right font-medium tabular-nums\">\n ${inv.amount.toLocaleString()}\n </td>\n <td className=\"p-3\">\n <Badge variant={invoiceStatusVariant[inv.status] ?? 'secondary'}>\n {inv.status}\n </Badge>\n </td>\n <td className=\"p-3 text-text-secondary\">{inv.dueDate}</td>\n <td className=\"p-3 text-right\">\n <div className=\"flex justify-end gap-1\">\n <Button variant=\"outline\" size=\"sm\" aria-label=\"View invoice\">\n <FileText className=\"h-3 w-3\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\" aria-label=\"Download invoice\">\n <Download className=\"h-3 w-3\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AAiCA,SAAgB,IAAe;CAC7B,IAAM,EAAE,iBAAc,mBAAgB,gBAAa,GAAyB,EACtE,CAAC,GAAW,KAAgB,EAAqB,WAAW,EAC5D,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAiB,KAAsB,EAAiB,MAAM,EAG/D,IAAa,EAChB,QAAQ,MAAM,EAAE,SAAS,cAAc,EAAE,WAAW,YAAY,CAChE,QAAQ,GAAG,MAAM,IAAI,EAAE,QAAQ,EAAE,EAC9B,IAAe,EAClB,QAAQ,MAAM,EAAE,WAAW,UAAU,CACrC,QAAQ,GAAG,MAAM,IAAI,EAAE,QAAQ,EAAE,EAC9B,IAAY,EACf,QAAQ,MAAM,EAAE,WAAW,YAAY,CACvC,QAAQ,GAAG,MAAM,IAAI,EAAE,MAAM,EAAE,EAC5B,IAAgB,EACnB,QAAQ,MAAM,EAAE,SAAS,YAAY,EAAE,WAAW,YAAY,CAC9D,QAAQ,GAAG,MAAM,IAAI,EAAE,QAAQ,EAAE,EAG9B,IAAe,QAAc;EACjC,IAAI,IAAS,CAAC,GAAG,EAAa;AAI9B,MAHI,MAAoB,UACtB,IAAS,EAAO,QAAQ,MAAM,EAAE,WAAW,EAAgB,GAEzD,EAAY,MAAM,EAAE;GACtB,IAAM,IAAI,EAAY,aAAa;AACnC,OAAS,EAAO,QACb,MACC,EAAE,YAAY,aAAa,CAAC,SAAS,EAAE,IACvC,EAAE,aAAa,aAAa,CAAC,SAAS,EAAE,KACvC,EAAE,aAAa,aAAa,CAAC,SAAS,EAAE,IAAI,IAChD;;AAEH,SAAO,EAAO,MAAM,GAAG,MAAM,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,GAAG,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC;IAC9F;EAAC;EAAc;EAAiB;EAAY,CAAC,EAE1C,KAAe,MACf,MAAS,aAAmB,kBAAC,GAAD,EAAc,WAAU,kCAAmC,CAAA,GACvF,MAAS,WAAiB,kBAAC,GAAD,EAAW,WAAU,oCAAqC,CAAA,GACjF,kBAAC,GAAD,EAAe,WAAU,4BAA6B,CAAA,EAGzD,KAAe,MAOZ,kBAAC,GAAD;EAAO,SANwE;GACpF,WAAW;GACX,SAAS;GACT,QAAQ;GACR,WAAW;GACZ,CAC+B,MAAW;YAAc;EAAe,CAAA,EAGpE,KAAc,MACU,EAAxB,MAAS,SAAgB,IACzB,MAAS,SAAgB,IACrB,GAFoB,EAAY,WAAU,WAAY,CAAA;AAYhE,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAkB,WAAU,UAAW,CAAA,EACvC,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;gBACZ,kBAAC,GAAD,EAAA,UAAc,YAAuB,CAAA;MAClC,CAAA,EACL,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,GAAD;MAAQ,MAAK;gBAAb,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,gBAC1B;QACL;OACF;;GAGN,kBAAC,OAAD;IAAK,WAAU;cA5BgC;KACjD;MAAE,KAAK;MAAY,OAAO;MAAY;KACtC;MAAE,KAAK;MAAgB,OAAO;MAAgB;KAC9C;MAAE,KAAK;MAAW,OAAO;MAAmB;KAC5C;MAAE,KAAK;MAAY,OAAO;MAAY;KACvC,CAwBW,KAAK,EAAE,QAAK,eAChB,kBAAC,UAAD;KAEE,eAAe,EAAa,EAAI;KAChC,gBAAc,MAAc;KAC5B,WAAW,8IACT,MAAc,IACV,+CACA;eAGL;KACM,EAVF,EAUE,CACT;IACE,CAAA;GAGL,MAAc,cACb,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OAAW,WAAU;OAAQ,MAAA;OAAK,WAAU;iBAC1C,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD,EAAc,WAAU,kCAAmC,CAAA;SACvD,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAb,CAA+C,KAAE,EAAW,gBAAgB,CAAK;YACjF,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAAe,CAAA,CACtD,EAAA,CAAA,CACF;;OACI,CAAA;MACZ,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBACtC,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD,EAAO,WAAU,oCAAqC,CAAA;SAClD,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAb,CAA+C,KAAE,EAAa,gBAAgB,CAAK;YACnF,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAAW,CAAA,CAClD,EAAA,CAAA,CACF;;OACI,CAAA;MACZ,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBACtC,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD,EAAY,WAAU,4BAA6B,CAAA;SAC/C,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAb,CAA+C,KAAE,EAAU,gBAAgB,CAAK;YAChF,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAAc,CAAA,CACrD,EAAA,CAAA,CACF;;OACI,CAAA;MACZ,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBACtC,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD,EAAW,WAAU,oCAAqC,CAAA;SACtD,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAb,CAA+C,KAC3C,EAAc,gBAAgB,CAC9B;YACJ,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAAY,CAAA,CACnD,EAAA,CAAA,CACF;;OACI,CAAA;MACR;QAGN,kBAAC,GAAD;KAAM,WAAU;eAAhB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OAAW,WAAU;iBAAY;OAA+B,CAAA,EAChE,kBAAC,GAAD;OAAQ,SAAQ;OAAU,MAAK;OAAK,eAAe,EAAa,eAAe;iBAAE;OAExE,CAAA,CACL;SACK,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAa,MAAM,GAAG,EAAE,CAAC,KAAK,MAC7B,kBAAC,OAAD;OAEE,WAAU;iBAFZ,CAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACG,EAAY,EAAI,KAAK,EACtB,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAuB,EAAI;SAAgB,CAAA,EACxD,kBAAC,KAAD;SAAG,WAAU;mBAAb;UACG,EAAI;UAAa;UAAI,EAAI;UACxB;WACA,EAAA,CAAA,CACF;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SACE,WAAW,kCAAkC,EAAI,SAAS,WAAW,6BAA6B;mBADpG;UAGG,EAAI,SAAS,WAAW,MAAM;UAAI;UAAE,EAAI,OAAO,gBAAgB;UAC9D;YACH,EAAY,EAAI,OAAO,CACpB;UACF;SApBC,EAAI,GAoBL,CACN;MACE,CAAA,EACM,CAAA,CACT;OACH;;GAIP,MAAc,kBACb,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,wEAAyE,CAAA,EAC3F,kBAAC,GAAD;OACE,aAAY;OACZ,OAAO;OACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;OAC/C,WAAU;OACV,CAAA,CACE;SACN,kBAAC,OAAD;MAAK,WAAU;gBACZ;OAAC;OAAO;OAAa;OAAW;OAAS,CAAC,KAAK,MAC9C,kBAAC,GAAD;OAEE,SAAS,MAAoB,IAAS,YAAY;OAClD,MAAK;OACL,eAAe,EAAmB,EAAO;iBAExC,MAAW,QAAQ,QAAQ,EAAO,OAAO,EAAE,CAAC,aAAa,GAAG,EAAO,MAAM,EAAE;OACrE,EANF,EAME,CACT;MACE,CAAA,CACF;QAEN,kBAAC,GAAD;KAAM,WAAU;eACd,kBAAC,GAAD;MAAa,WAAU;gBACpB,EAAa,WAAW,IACvB,kBAAC,GAAD;OACE,cAAa;OACb,OAAM;OACN,aAAY;OACZ,CAAA,GAEF,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;SAAI,WAAU;mBAAd;UACE,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAS,CAAA;UACzC,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAgB,CAAA;UAChD,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAiB,CAAA;UACjD,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAW,CAAA;UAC3C,kBAAC,MAAD;WAAI,WAAU;qBAA6B;WAAW,CAAA;UACtD,kBAAC,MAAD;WAAI,WAAU;qBAA6B;WAAS,CAAA;UACpD,kBAAC,MAAD;WAAI,WAAU;qBAA6B;WAAQ,CAAA;UACnD,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAW,CAAA;UAC3C,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAS,CAAA;UACtC;YACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAa,KAAK,MACjB,kBAAC,MAAD;SAEE,WAAU;mBAFZ;UAIE,kBAAC,MAAD;WAAI,WAAU;qBAAO,EAAY,EAAI,KAAK;WAAM,CAAA;UAChD,kBAAC,MAAD;WAAI,WAAU;qBAAmB,EAAI;WAAiB,CAAA;UACtD,kBAAC,MAAD;WAAI,WAAU;qBAAO,EAAI;WAAkB,CAAA;UAC3C,kBAAC,MAAD;WAAI,WAAU;qBACZ,kBAAC,GAAD;YAAO,SAAQ;sBAAW,EAAI,OAAO,QAAQ,KAAK,IAAI;YAAS,CAAA;WAC5D,CAAA;UACL,kBAAC,MAAD;WACE,WAAW,2CAA2C,EAAI,SAAS,WAAW,6BAA6B;qBAD7G;YAGG,EAAI,SAAS,WAAW,MAAM;YAAI;YAAE,EAAI,OAAO,gBAAgB;YAC7D;;UACL,kBAAC,MAAD;WAAI,WAAU;qBAAd,CAAgE,KAC5D,EAAI,KACH;;UACL,kBAAC,MAAD;WAAI,WAAU;qBAAd,CAA4C,KACxC,EAAI,UAAU,gBAAgB,CAC7B;;UACL,kBAAC,MAAD;WAAI,WAAU;qBAAO,EAAY,EAAI,OAAO;WAAM,CAAA;UAClD,kBAAC,MAAD;WAAI,WAAU;qBAA2B,EAAI;WAAe,CAAA;UACzD;WAtBE,EAAI,GAsBN,CACL,EACI,CAAA,CACF;;OACJ,CAAA;MAEI,CAAA;KACT,CAAA,CACH;;GAIP,MAAc,aACb,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACG,EAAe,KAAK,MACnB,kBAAC,GAAD;MAEE,WAAU;MACV,MAAM,EAAO;MACb,WAAW,sBAAsB,EAAO,WAAY;gBAJtD;OAME,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBACZ,EAAW,EAAO,KAAK;UACpB,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;UAAG,WAAU;oBAAe,EAAO;UAAS,CAAA,EAC5C,kBAAC,KAAD;UAAG,WAAU;oBAA+B,EAAO;UAAY,CAAA,CAC3D,EAAA,CAAA,CACF;YACL,EAAO,aAAa,kBAAC,GAAD,EAAA,UAAO,WAAe,CAAA,CACvC;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACG,EAAO,aACN,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,YACzB;aAEP,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAAA,cACxB;YAER,EAAO,YACN,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CAAsC,eAAY,EAAO,SAAgB;WAEvE;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACG,CAAC,EAAO,aACP,kBAAC,GAAD;SAAQ,SAAQ;SAAU,MAAK;SAAK,WAAU;mBAAS;SAE9C,CAAA,EAEX,kBAAC,GAAD;SAAQ,SAAQ;SAAU,MAAK;SAAK,WAAU;mBAAS;SAE9C,CAAA,CACL;;OACI;QA3CL,EAAO,GA2CF,CACZ,EAGF,kBAAC,GAAD;MAAM,WAAU;gBACd,kBAAC,GAAD;OAAa,WAAU;iBAAvB;QACE,kBAAC,GAAD,EAAM,WAAU,uCAAwC,CAAA;QACxD,kBAAC,KAAD;SAAG,WAAU;mBAA2B;SAAsB,CAAA;QAC9D,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAAmC,CAAA;QAClE;;MACT,CAAA,CACH;;IACF,CAAA;GAIP,MAAc,cACb,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KAAM,WAAU;eACd,kBAAC,GAAD;MAAa,WAAU;gBACpB,EAAS,WAAW,IACnB,kBAAC,GAAD;OACE,cAAa;OACb,OAAM;OACN,aAAY;OACZ,CAAA,GAEF,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;SAAI,WAAU;mBAAd;UACE,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAc,CAAA;UAC9C,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAgB,CAAA;UAChD,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAW,CAAA;UAC3C,kBAAC,MAAD;WAAI,WAAU;qBAA6B;WAAW,CAAA;UACtD,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAW,CAAA;UAC3C,kBAAC,MAAD;WAAI,WAAU;qBAAkB;WAAa,CAAA;UAC7C,kBAAC,MAAD;WAAI,WAAU;qBAA6B;WAAY,CAAA;UACpD;YACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAS,KAAK,MAUX,kBAAC,MAAD;SAEE,WAAU;mBAFZ;UAIE,kBAAC,MAAD;WAAI,WAAU;qBAAmB,EAAI;WAAY,CAAA;UACjD,kBAAC,MAAD;WAAI,WAAU;qBAAO,EAAI;WAAiB,CAAA;UAC1C,kBAAC,MAAD;WAAI,WAAU;qBAAO,EAAI;WAAgB,CAAA;UACzC,kBAAC,MAAD;WAAI,WAAU;qBAAd,CAAwD,KACpD,EAAI,OAAO,gBAAgB,CAC1B;;UACL,kBAAC,MAAD;WAAI,WAAU;qBACZ,kBAAC,GAAD;YAAO,SAjBT;aACF,MAAM;aACN,SAAS;aACT,SAAS;aACV,CAa0C,EAAI,WAAW;sBACjD,EAAI;YACC,CAAA;WACL,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBAA2B,EAAI;WAAa,CAAA;UAC1D,kBAAC,MAAD;WAAI,WAAU;qBACZ,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,GAAD;aAAQ,SAAQ;aAAU,MAAK;aAAK,cAAW;uBAC7C,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;aACzB,CAAA,EACT,kBAAC,GAAD;aAAQ,SAAQ;aAAU,MAAK;aAAK,cAAW;uBAC7C,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;aACzB,CAAA,CACL;;WACH,CAAA;UACF;WAzBE,EAAI,GAyBN,CAEP,EACI,CAAA,CACF;;OACJ,CAAA;MAEI,CAAA;KACT,CAAA;IACH,CAAA;GAEJ"}
1
+ {"version":3,"file":"PaymentsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/PaymentsPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n GlassCard,\n IllustratedEmptyState,\n AuroraBackground,\n GradientText,\n PagePurpose,\n NextSteps,\n} from '@burdenoff/fe-libs/ui';\nimport {\n DollarSign,\n CreditCard,\n Building2,\n Wallet,\n ArrowUpRight,\n ArrowDownLeft,\n RotateCcw,\n Clock,\n Search,\n FileText,\n Plus,\n Shield,\n Download,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\n\ntype PaymentTab = 'overview' | 'transactions' | 'methods' | 'invoices';\n\nexport function PaymentsPage() {\n const { transactions, paymentMethods, invoices } = useProServiceWorldStore();\n const [activeTab, setActiveTab] = useState<PaymentTab>('overview');\n const [searchQuery, setSearchQuery] = useState('');\n const [txnStatusFilter, setTxnStatusFilter] = useState<string>('all');\n\n // Overview stats\n const totalSpent = transactions\n .filter((t) => t.type === 'outgoing' && t.status === 'completed')\n .reduce((s, t) => s + t.amount, 0);\n const totalPending = transactions\n .filter((t) => t.status === 'pending')\n .reduce((s, t) => s + t.amount, 0);\n const totalFees = transactions\n .filter((t) => t.status === 'completed')\n .reduce((s, t) => s + t.fees, 0);\n const totalRefunded = transactions\n .filter((t) => t.type === 'refund' && t.status === 'completed')\n .reduce((s, t) => s + t.amount, 0);\n\n // Filter transactions\n const filteredTxns = useMemo(() => {\n let result = [...transactions];\n if (txnStatusFilter !== 'all') {\n result = result.filter((t) => t.status === txnStatusFilter);\n }\n if (searchQuery.trim()) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (t) =>\n t.description.toLowerCase().includes(q) ||\n t.counterparty.toLowerCase().includes(q) ||\n (t.serviceName?.toLowerCase().includes(q) ?? false)\n );\n }\n return result.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n }, [transactions, txnStatusFilter, searchQuery]);\n\n const txnTypeIcon = (type: string) => {\n if (type === 'outgoing') return <ArrowUpRight className=\"h-4 w-4 text-status-error-text\" />;\n if (type === 'refund') return <RotateCcw className=\"h-4 w-4 text-status-success-text\" />;\n return <ArrowDownLeft className=\"h-4 w-4 text-accent-blue\" />;\n };\n\n const statusBadge = (status: string) => {\n const variants: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n completed: 'default',\n pending: 'secondary',\n failed: 'destructive',\n cancelled: 'outline',\n };\n return <Badge variant={variants[status] ?? 'secondary'}>{status}</Badge>;\n };\n\n const methodIcon = (type: string) => {\n if (type === 'card') return <CreditCard className=\"h-5 w-5\" />;\n if (type === 'bank') return <Building2 className=\"h-5 w-5\" />;\n return <Wallet className=\"h-5 w-5\" />;\n };\n\n const tabs: { key: PaymentTab; label: string }[] = [\n { key: 'overview', label: 'Overview' },\n { key: 'transactions', label: 'Transactions' },\n { key: 'methods', label: 'Payment Methods' },\n { key: 'invoices', label: 'Invoices' },\n ];\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n {/* Hero header — the ONE aurora backdrop for this MFE */}\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>Payments</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Track transactions, manage payment methods, and view invoices.\n </p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" /> Make Payment\n </Button>\n </div>\n </div>\n\n <PagePurpose icon={<DollarSign className=\"h-4 w-4\" />}>\n Your money, end to end. See what you have spent, what is pending, and what has been\n refunded; search and reconcile individual transactions; manage the cards and bank accounts\n you pay with; and download invoices for your records.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"proserviceworld-payments\"\n steps={[\n {\n id: 'transactions',\n label: 'Review your transactions',\n description: 'Search and filter every payment, fee, and refund.',\n icon: <Search className=\"h-4 w-4\" />,\n onClick: () => setActiveTab('transactions'),\n },\n {\n id: 'methods',\n label: 'Manage payment methods',\n description: 'Add or set a default card, bank, or wallet.',\n icon: <CreditCard className=\"h-4 w-4\" />,\n onClick: () => setActiveTab('methods'),\n done: paymentMethods.length > 0,\n },\n {\n id: 'invoices',\n label: 'Check your invoices',\n description: 'View and download invoices you create or receive.',\n icon: <FileText className=\"h-4 w-4\" />,\n onClick: () => setActiveTab('invoices'),\n },\n ]}\n />\n\n {/* Tabs */}\n <div className=\"flex flex-wrap gap-1 border-b border-border-seam\">\n {tabs.map(({ key, label }) => (\n <button\n key={key}\n onClick={() => setActiveTab(key)}\n aria-pressed={activeTab === key}\n className={`border-b-2 px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${\n activeTab === key\n ? 'border-action-primary-bg text-text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n }`}\n >\n {label}\n </button>\n ))}\n </div>\n\n {/* Overview Tab */}\n {activeTab === 'overview' && (\n <div className=\"space-y-6\">\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-error-bg-subtle p-2\">\n <ArrowUpRight className=\"h-5 w-5 text-status-error-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">${totalSpent.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Total Spent</p>\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-warning-bg-subtle p-2\">\n <Clock className=\"h-5 w-5 text-status-warning-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">${totalPending.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Pending</p>\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-info-bg-subtle p-2\">\n <DollarSign className=\"h-5 w-5 text-accent-blue\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">${totalFees.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Total Fees</p>\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-success-bg-subtle p-2\">\n <RotateCcw className=\"h-5 w-5 text-status-success-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">\n ${totalRefunded.toLocaleString()}\n </p>\n <p className=\"text-xs text-text-secondary\">Refunded</p>\n </div>\n </div>\n </GlassCard>\n </div>\n\n {/* Recent transactions preview */}\n <Card className=\"border-border-seam\">\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">Recent Transactions</CardTitle>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setActiveTab('transactions')}>\n View All\n </Button>\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {transactions.slice(0, 5).map((txn) => (\n <div\n key={txn.id}\n className=\"flex items-center justify-between rounded-lg border border-border-seam p-3 transition-shadow hover:shadow-pop\"\n >\n <div className=\"flex items-center gap-3\">\n {txnTypeIcon(txn.type)}\n <div>\n <p className=\"text-sm font-medium\">{txn.description}</p>\n <p className=\"text-xs text-text-secondary\">\n {txn.counterparty} - {txn.createdAt}\n </p>\n </div>\n </div>\n <div className=\"text-right\">\n <p\n className={`text-sm font-bold tabular-nums ${txn.type === 'refund' ? 'text-status-success-text' : ''}`}\n >\n {txn.type === 'refund' ? '+' : '-'}${txn.amount.toLocaleString()}\n </p>\n {statusBadge(txn.status)}\n </div>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Transactions Tab */}\n {activeTab === 'transactions' && (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search transactions...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {['all', 'completed', 'pending', 'failed'].map((status) => (\n <Button\n key={status}\n variant={txnStatusFilter === status ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setTxnStatusFilter(status)}\n >\n {status === 'all' ? 'All' : status.charAt(0).toUpperCase() + status.slice(1)}\n </Button>\n ))}\n </div>\n </div>\n\n <Card className=\"border-border-seam\">\n <CardContent className=\"pt-4\">\n {filteredTxns.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No transactions found\"\n description=\"No transactions match your current filters.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left text-text-secondary\">\n <th className=\"p-3 font-medium\">Type</th>\n <th className=\"p-3 font-medium\">Description</th>\n <th className=\"p-3 font-medium\">Counterparty</th>\n <th className=\"p-3 font-medium\">Method</th>\n <th className=\"p-3 text-right font-medium\">Amount</th>\n <th className=\"p-3 text-right font-medium\">Fees</th>\n <th className=\"p-3 text-right font-medium\">Net</th>\n <th className=\"p-3 font-medium\">Status</th>\n <th className=\"p-3 font-medium\">Date</th>\n </tr>\n </thead>\n <tbody>\n {filteredTxns.map((txn) => (\n <tr\n key={txn.id}\n className=\"border-b border-border-seam transition-colors hover:bg-bg-sunken/50\"\n >\n <td className=\"p-3\">{txnTypeIcon(txn.type)}</td>\n <td className=\"p-3 font-medium\">{txn.description}</td>\n <td className=\"p-3\">{txn.counterparty}</td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{txn.method.replace('_', ' ')}</Badge>\n </td>\n <td\n className={`p-3 text-right font-medium tabular-nums ${txn.type === 'refund' ? 'text-status-success-text' : ''}`}\n >\n {txn.type === 'refund' ? '+' : '-'}${txn.amount.toLocaleString()}\n </td>\n <td className=\"p-3 text-right text-text-secondary tabular-nums\">\n ${txn.fees}\n </td>\n <td className=\"p-3 text-right tabular-nums\">\n ${txn.netAmount.toLocaleString()}\n </td>\n <td className=\"p-3\">{statusBadge(txn.status)}</td>\n <td className=\"p-3 text-text-secondary\">{txn.createdAt}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Payment Methods Tab */}\n {activeTab === 'methods' && (\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {paymentMethods.map((method) => (\n <GlassCard\n key={method.id}\n treatment=\"glass\"\n glow={method.isDefault}\n className={`border-border-seam ${method.isDefault ? '' : ''}`}\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg border border-border-seam p-2 text-text-primary\">\n {methodIcon(method.type)}\n </div>\n <div>\n <p className=\"font-medium\">{method.name}</p>\n <p className=\"text-sm text-text-secondary\">{method.details}</p>\n </div>\n </div>\n {method.isDefault && <Badge>Default</Badge>}\n </div>\n\n <div className=\"mt-4 flex items-center gap-4 text-sm\">\n {method.isVerified ? (\n <span className=\"flex items-center gap-1 text-status-success-text\">\n <Shield className=\"h-4 w-4\" /> Verified\n </span>\n ) : (\n <span className=\"flex items-center gap-1 text-status-warning-text\">\n <Clock className=\"h-4 w-4\" /> Unverified\n </span>\n )}\n {method.lastUsed && (\n <span className=\"text-text-secondary\">Last used: {method.lastUsed}</span>\n )}\n </div>\n\n <div className=\"mt-4 flex gap-2\">\n {!method.isDefault && (\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1\">\n Set Default\n </Button>\n )}\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1\">\n Remove\n </Button>\n </div>\n </GlassCard>\n ))}\n\n {/* Add new method card */}\n <Card className=\"flex items-center justify-center border-dashed border-border-seam transition-shadow hover:shadow-pop\">\n <CardContent className=\"py-8 text-center\">\n <Plus className=\"mx-auto h-8 w-8 text-text-secondary\" />\n <p className=\"mt-2 text-sm font-medium\">Add Payment Method</p>\n <p className=\"text-xs text-text-secondary\">Add a new card, bank, or PayPal</p>\n </CardContent>\n </Card>\n </div>\n </div>\n )}\n\n {/* Invoices Tab */}\n {activeTab === 'invoices' && (\n <div className=\"space-y-4\">\n <Card className=\"border-border-seam\">\n <CardContent className=\"pt-4\">\n {invoices.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-files\"\n title=\"No invoices yet\"\n description=\"Invoices you create or receive will appear here.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left text-text-secondary\">\n <th className=\"p-3 font-medium\">Invoice #</th>\n <th className=\"p-3 font-medium\">Description</th>\n <th className=\"p-3 font-medium\">Client</th>\n <th className=\"p-3 text-right font-medium\">Amount</th>\n <th className=\"p-3 font-medium\">Status</th>\n <th className=\"p-3 font-medium\">Due Date</th>\n <th className=\"p-3 text-right font-medium\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {invoices.map((inv) => {\n const invoiceStatusVariant: Record<\n string,\n 'default' | 'secondary' | 'destructive'\n > = {\n paid: 'default',\n pending: 'secondary',\n overdue: 'destructive',\n };\n return (\n <tr\n key={inv.id}\n className=\"border-b border-border-seam transition-colors hover:bg-bg-sunken/50\"\n >\n <td className=\"p-3 font-medium\">{inv.number}</td>\n <td className=\"p-3\">{inv.description}</td>\n <td className=\"p-3\">{inv.clientName}</td>\n <td className=\"p-3 text-right font-medium tabular-nums\">\n ${inv.amount.toLocaleString()}\n </td>\n <td className=\"p-3\">\n <Badge variant={invoiceStatusVariant[inv.status] ?? 'secondary'}>\n {inv.status}\n </Badge>\n </td>\n <td className=\"p-3 text-text-secondary\">{inv.dueDate}</td>\n <td className=\"p-3 text-right\">\n <div className=\"flex justify-end gap-1\">\n <Button variant=\"outline\" size=\"sm\" aria-label=\"View invoice\">\n <FileText className=\"h-3 w-3\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\" aria-label=\"Download invoice\">\n <Download className=\"h-3 w-3\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}