@burdenoff/microfe-proserviceworld 2026.525.1 → 2026.624.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.
- package/dist/proserviceworld/pages/AdminReportsPage.js +28 -28
- package/dist/proserviceworld/pages/AdminReportsPage.js.map +1 -1
- package/dist/proserviceworld/pages/AdminUsersPage.js +19 -19
- package/dist/proserviceworld/pages/AdminUsersPage.js.map +1 -1
- package/dist/proserviceworld/pages/AnalyticsPage.js +27 -27
- package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
- package/dist/proserviceworld/pages/BookingsPage.js +24 -24
- package/dist/proserviceworld/pages/BookingsPage.js.map +1 -1
- package/dist/proserviceworld/pages/DashboardPage.js +33 -33
- package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
- package/dist/proserviceworld/pages/DocumentsPage.js +29 -29
- package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
- package/dist/proserviceworld/pages/MessagesPage.js +15 -15
- package/dist/proserviceworld/pages/MessagesPage.js.map +1 -1
- package/dist/proserviceworld/pages/PaymentsPage.js +19 -19
- package/dist/proserviceworld/pages/PaymentsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ProjectsPage.js +36 -36
- package/dist/proserviceworld/pages/ProjectsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ProviderDetailPage.js +36 -36
- package/dist/proserviceworld/pages/ProviderDetailPage.js.map +1 -1
- package/dist/proserviceworld/pages/ProvidersPage.js +19 -19
- package/dist/proserviceworld/pages/ProvidersPage.js.map +1 -1
- package/dist/proserviceworld/pages/ReviewsPage.js +22 -22
- package/dist/proserviceworld/pages/ReviewsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ServiceDetailsPage.js +35 -35
- package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ServicesPage.js +14 -14
- package/dist/proserviceworld/pages/ServicesPage.js.map +1 -1
- package/dist/proserviceworld/pages/VerificationPage.js +23 -23
- package/dist/proserviceworld/pages/VerificationPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -29,7 +29,7 @@ function S() {
|
|
|
29
29
|
className: "text-2xl font-semibold",
|
|
30
30
|
children: C("proserviceworld.messages.title", "Messages")
|
|
31
31
|
}), /* @__PURE__ */ _("p", {
|
|
32
|
-
className: "text-sm text-
|
|
32
|
+
className: "text-sm text-text-secondary",
|
|
33
33
|
children: P
|
|
34
34
|
})] }), /* @__PURE__ */ v(b, {
|
|
35
35
|
size: "sm",
|
|
@@ -47,7 +47,7 @@ function S() {
|
|
|
47
47
|
className: "border-b p-3",
|
|
48
48
|
children: /* @__PURE__ */ v("div", {
|
|
49
49
|
className: "relative",
|
|
50
|
-
children: [/* @__PURE__ */ _(d, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-
|
|
50
|
+
children: [/* @__PURE__ */ _(d, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ _(x, {
|
|
51
51
|
placeholder: C("proserviceworld.messages.search.placeholder", "Search conversations..."),
|
|
52
52
|
value: T,
|
|
53
53
|
onChange: (e) => E(e.target.value),
|
|
@@ -57,17 +57,17 @@ function S() {
|
|
|
57
57
|
}), /* @__PURE__ */ _("div", {
|
|
58
58
|
className: "flex-1 overflow-y-auto",
|
|
59
59
|
children: j.length === 0 ? /* @__PURE__ */ _("div", {
|
|
60
|
-
className: "p-6 text-center text-sm text-
|
|
60
|
+
className: "p-6 text-center text-sm text-text-secondary",
|
|
61
61
|
children: C("proserviceworld.messages.empty.list", "No conversations found.")
|
|
62
62
|
}) : j.map((e) => /* @__PURE__ */ _("button", {
|
|
63
63
|
onClick: () => O(e.id),
|
|
64
|
-
className: `w-full border-b p-3 text-left transition-colors ${D === e.id ? "bg-primary/5" : "hover:bg-
|
|
64
|
+
className: `w-full border-b p-3 text-left transition-colors ${D === e.id ? "bg-action-primary-bg/5" : "hover:bg-bg-sunken/50"}`,
|
|
65
65
|
children: /* @__PURE__ */ v("div", {
|
|
66
66
|
className: "flex items-start gap-3",
|
|
67
67
|
children: [/* @__PURE__ */ v("div", {
|
|
68
68
|
className: "relative shrink-0",
|
|
69
69
|
children: [/* @__PURE__ */ _("div", {
|
|
70
|
-
className: "flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 font-semibold text-primary",
|
|
70
|
+
className: "flex h-10 w-10 items-center justify-center rounded-full bg-action-primary-bg/10 font-semibold text-primary",
|
|
71
71
|
children: e.participantName.charAt(0)
|
|
72
72
|
}), e.online && /* @__PURE__ */ _(o, { className: "absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-green-500 text-green-500 stroke-background" })]
|
|
73
73
|
}), /* @__PURE__ */ v("div", {
|
|
@@ -79,18 +79,18 @@ function S() {
|
|
|
79
79
|
className: `truncate text-sm ${e.unreadCount > 0 ? "font-bold" : "font-medium"}`,
|
|
80
80
|
children: e.participantName
|
|
81
81
|
}), /* @__PURE__ */ _("span", {
|
|
82
|
-
className: "shrink-0 text-xs text-
|
|
82
|
+
className: "shrink-0 text-xs text-text-secondary",
|
|
83
83
|
children: F(e.lastMessageTime)
|
|
84
84
|
})]
|
|
85
85
|
}),
|
|
86
86
|
/* @__PURE__ */ _("p", {
|
|
87
|
-
className: "text-xs text-
|
|
87
|
+
className: "text-xs text-text-secondary",
|
|
88
88
|
children: e.participantRole
|
|
89
89
|
}),
|
|
90
90
|
/* @__PURE__ */ v("div", {
|
|
91
91
|
className: "mt-1 flex items-center justify-between",
|
|
92
92
|
children: [/* @__PURE__ */ _("p", {
|
|
93
|
-
className: `truncate text-xs ${e.unreadCount > 0 ? "font-medium text-
|
|
93
|
+
className: `truncate text-xs ${e.unreadCount > 0 ? "font-medium text-text-primary" : "text-text-secondary"}`,
|
|
94
94
|
children: e.lastMessage
|
|
95
95
|
}), e.unreadCount > 0 && /* @__PURE__ */ _(y, {
|
|
96
96
|
className: "ml-2 h-5 w-5 shrink-0 rounded-full p-0 text-xs flex items-center justify-center",
|
|
@@ -112,14 +112,14 @@ function S() {
|
|
|
112
112
|
children: [/* @__PURE__ */ v("div", {
|
|
113
113
|
className: "relative",
|
|
114
114
|
children: [/* @__PURE__ */ _("div", {
|
|
115
|
-
className: "flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 font-semibold text-primary",
|
|
115
|
+
className: "flex h-10 w-10 items-center justify-center rounded-full bg-action-primary-bg/10 font-semibold text-primary",
|
|
116
116
|
children: M.participantName.charAt(0)
|
|
117
117
|
}), M.online && /* @__PURE__ */ _(o, { className: "absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-green-500 text-green-500 stroke-background" })]
|
|
118
118
|
}), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h3", {
|
|
119
119
|
className: "font-medium",
|
|
120
120
|
children: M.participantName
|
|
121
121
|
}), /* @__PURE__ */ v("p", {
|
|
122
|
-
className: "text-xs text-
|
|
122
|
+
className: "text-xs text-text-secondary",
|
|
123
123
|
children: [
|
|
124
124
|
M.online ? C("proserviceworld.messages.presence.online", "Online") : C("proserviceworld.messages.presence.offline", "Offline"),
|
|
125
125
|
" ",
|
|
@@ -155,16 +155,16 @@ function S() {
|
|
|
155
155
|
children: /* @__PURE__ */ v("div", {
|
|
156
156
|
className: `flex max-w-[75%] items-end gap-2 ${e.isOwn ? "flex-row-reverse" : ""}`,
|
|
157
157
|
children: [!e.isOwn && /* @__PURE__ */ _("div", {
|
|
158
|
-
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary",
|
|
158
|
+
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-action-primary-bg/10 text-xs font-semibold text-primary",
|
|
159
159
|
children: e.senderName.charAt(0)
|
|
160
160
|
}), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("div", {
|
|
161
|
-
className: `rounded-2xl px-4 py-2 ${e.isOwn ? "bg-primary text-primary-
|
|
161
|
+
className: `rounded-2xl px-4 py-2 ${e.isOwn ? "bg-action-primary-bg text-action-primary-text rounded-br-md" : "bg-bg-sunken rounded-bl-md"}`,
|
|
162
162
|
children: /* @__PURE__ */ _("p", {
|
|
163
163
|
className: "text-sm",
|
|
164
164
|
children: e.content
|
|
165
165
|
})
|
|
166
166
|
}), /* @__PURE__ */ v("div", {
|
|
167
|
-
className: `mt-1 flex items-center gap-1 text-xs text-
|
|
167
|
+
className: `mt-1 flex items-center gap-1 text-xs text-text-secondary ${e.isOwn ? "justify-end" : ""}`,
|
|
168
168
|
children: [/* @__PURE__ */ _("span", { children: F(e.timestamp) }), e.isOwn && (e.read ? /* @__PURE__ */ _(a, { className: "h-3 w-3 text-blue-500" }) : /* @__PURE__ */ _(i, { className: "h-3 w-3" }))]
|
|
169
169
|
})] })]
|
|
170
170
|
})
|
|
@@ -203,11 +203,11 @@ function S() {
|
|
|
203
203
|
})
|
|
204
204
|
})
|
|
205
205
|
] }) : /* @__PURE__ */ _("div", {
|
|
206
|
-
className: "flex flex-1 items-center justify-center text-
|
|
206
|
+
className: "flex flex-1 items-center justify-center text-text-secondary",
|
|
207
207
|
children: /* @__PURE__ */ v("div", {
|
|
208
208
|
className: "text-center",
|
|
209
209
|
children: [
|
|
210
|
-
/* @__PURE__ */ _(s, { className: "mx-auto h-12 w-12 text-
|
|
210
|
+
/* @__PURE__ */ _(s, { className: "mx-auto h-12 w-12 text-text-secondary/50" }),
|
|
211
211
|
/* @__PURE__ */ _("p", {
|
|
212
212
|
className: "mt-2 font-medium",
|
|
213
213
|
children: C("proserviceworld.messages.emptyConversation.title", "Select a conversation")
|
|
@@ -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 { Badge, Button, Card, CardContent, Input } 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\">\n <div className=\"mb-6 flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n {tr('proserviceworld.messages.title', 'Messages')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">{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-lg border lg:grid-cols-3\"\n style={{ height: 'calc(100vh - 220px)', minHeight: '500px' }}\n >\n {/* Conversation sidebar */}\n <div className=\"flex flex-col border-r lg:col-span-1\">\n {/* Search */}\n <div className=\"border-b p-3\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\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-muted-foreground\">\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 p-3 text-left transition-colors ${\n selectedConversationId === conversation.id\n ? 'bg-primary/5'\n : 'hover:bg-muted/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-primary/10 font-semibold 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-green-500 text-green-500 stroke-background\" />\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-muted-foreground\">\n {formatTime(conversation.lastMessageTime)}\n </span>\n </div>\n <p className=\"text-xs text-muted-foreground\">\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-foreground' : 'text-muted-foreground'}`}\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 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-primary/10 font-semibold 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-green-500 text-green-500 stroke-background\" />\n )}\n </div>\n <div>\n <h3 className=\"font-medium\">{selectedConversation.participantName}</h3>\n <p className=\"text-xs text-muted-foreground\">\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-primary/10 text-xs font-semibold 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-primary text-primary-foreground rounded-br-md'\n : 'bg-muted 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-muted-foreground ${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-blue-500\" />\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 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 text-muted-foreground\">\n <div className=\"text-center\">\n <MessageSquare className=\"mx-auto h-12 w-12 text-muted-foreground/50\" />\n <p className=\"mt-2 font-medium\">\n {tr('proserviceworld.messages.emptyConversation.title', 'Select a conversation')}\n </p>\n <p className=\"text-sm\">\n {tr(\n 'proserviceworld.messages.emptyConversation.description',\n 'Choose a conversation to start messaging.'\n )}\n </p>\n </div>\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 { Badge, Button, Card, CardContent, Input } 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\">\n <div className=\"mb-6 flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n {tr('proserviceworld.messages.title', 'Messages')}\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-lg border lg:grid-cols-3\"\n style={{ height: 'calc(100vh - 220px)', minHeight: '500px' }}\n >\n {/* Conversation sidebar */}\n <div className=\"flex flex-col border-r lg:col-span-1\">\n {/* Search */}\n <div className=\"border-b 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 p-3 text-left transition-colors ${\n selectedConversationId === conversation.id\n ? 'bg-action-primary-bg/5'\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-action-primary-bg/10 font-semibold 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-green-500 text-green-500 stroke-background\" />\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 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-action-primary-bg/10 font-semibold 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-green-500 text-green-500 stroke-background\" />\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-action-primary-bg/10 text-xs font-semibold 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-blue-500\" />\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 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 text-text-secondary\">\n <div className=\"text-center\">\n <MessageSquare className=\"mx-auto h-12 w-12 text-text-secondary/50\" />\n <p className=\"mt-2 font-medium\">\n {tr('proserviceworld.messages.emptyConversation.title', 'Select a conversation')}\n </p>\n <p className=\"text-sm\">\n {tr(\n 'proserviceworld.messages.emptyConversation.description',\n 'Choose a conversation to start messaging.'\n )}\n </p>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -34,7 +34,7 @@ function T() {
|
|
|
34
34
|
className: "text-2xl font-semibold",
|
|
35
35
|
children: "Payments"
|
|
36
36
|
}), /* @__PURE__ */ g("p", {
|
|
37
|
-
className: "text-sm text-
|
|
37
|
+
className: "text-sm text-text-secondary",
|
|
38
38
|
children: "Track transactions, manage payment methods, and view invoices."
|
|
39
39
|
})] }), /* @__PURE__ */ _(y, {
|
|
40
40
|
size: "sm",
|
|
@@ -62,7 +62,7 @@ function T() {
|
|
|
62
62
|
}
|
|
63
63
|
].map(({ key: e, label: t }) => /* @__PURE__ */ g("button", {
|
|
64
64
|
onClick: () => k(e),
|
|
65
|
-
className: `border-b-2 px-4 py-2 text-sm font-medium transition-colors ${O === e ? "border-primary text-primary" : "border-transparent text-
|
|
65
|
+
className: `border-b-2 px-4 py-2 text-sm font-medium transition-colors ${O === e ? "border-primary text-primary" : "border-transparent text-text-secondary hover:text-text-primary"}`,
|
|
66
66
|
children: t
|
|
67
67
|
}, e))
|
|
68
68
|
}),
|
|
@@ -82,7 +82,7 @@ function T() {
|
|
|
82
82
|
className: "text-2xl font-bold",
|
|
83
83
|
children: ["$", P.toLocaleString()]
|
|
84
84
|
}), /* @__PURE__ */ g("p", {
|
|
85
|
-
className: "text-xs text-
|
|
85
|
+
className: "text-xs text-text-secondary",
|
|
86
86
|
children: "Total Spent"
|
|
87
87
|
})] })]
|
|
88
88
|
})
|
|
@@ -98,7 +98,7 @@ function T() {
|
|
|
98
98
|
className: "text-2xl font-bold",
|
|
99
99
|
children: ["$", F.toLocaleString()]
|
|
100
100
|
}), /* @__PURE__ */ g("p", {
|
|
101
|
-
className: "text-xs text-
|
|
101
|
+
className: "text-xs text-text-secondary",
|
|
102
102
|
children: "Pending"
|
|
103
103
|
})] })]
|
|
104
104
|
})
|
|
@@ -114,7 +114,7 @@ function T() {
|
|
|
114
114
|
className: "text-2xl font-bold",
|
|
115
115
|
children: ["$", I.toLocaleString()]
|
|
116
116
|
}), /* @__PURE__ */ g("p", {
|
|
117
|
-
className: "text-xs text-
|
|
117
|
+
className: "text-xs text-text-secondary",
|
|
118
118
|
children: "Total Fees"
|
|
119
119
|
})] })]
|
|
120
120
|
})
|
|
@@ -130,7 +130,7 @@ function T() {
|
|
|
130
130
|
className: "text-2xl font-bold",
|
|
131
131
|
children: ["$", L.toLocaleString()]
|
|
132
132
|
}), /* @__PURE__ */ g("p", {
|
|
133
|
-
className: "text-xs text-
|
|
133
|
+
className: "text-xs text-text-secondary",
|
|
134
134
|
children: "Refunded"
|
|
135
135
|
})] })]
|
|
136
136
|
})
|
|
@@ -157,7 +157,7 @@ function T() {
|
|
|
157
157
|
className: "text-sm font-medium",
|
|
158
158
|
children: e.description
|
|
159
159
|
}), /* @__PURE__ */ _("p", {
|
|
160
|
-
className: "text-xs text-
|
|
160
|
+
className: "text-xs text-text-secondary",
|
|
161
161
|
children: [
|
|
162
162
|
e.counterparty,
|
|
163
163
|
" - ",
|
|
@@ -184,7 +184,7 @@ function T() {
|
|
|
184
184
|
className: "flex flex-col gap-4 sm:flex-row sm:items-center",
|
|
185
185
|
children: [/* @__PURE__ */ _("div", {
|
|
186
186
|
className: "relative flex-1",
|
|
187
|
-
children: [/* @__PURE__ */ g(p, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-
|
|
187
|
+
children: [/* @__PURE__ */ g(p, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ g(w, {
|
|
188
188
|
placeholder: "Search transactions...",
|
|
189
189
|
value: A,
|
|
190
190
|
onChange: (e) => j(e.target.value),
|
|
@@ -211,7 +211,7 @@ function T() {
|
|
|
211
211
|
children: /* @__PURE__ */ _("table", {
|
|
212
212
|
className: "w-full text-sm",
|
|
213
213
|
children: [/* @__PURE__ */ g("thead", { children: /* @__PURE__ */ _("tr", {
|
|
214
|
-
className: "border-b text-left text-
|
|
214
|
+
className: "border-b text-left text-text-secondary",
|
|
215
215
|
children: [
|
|
216
216
|
/* @__PURE__ */ g("th", {
|
|
217
217
|
className: "p-3",
|
|
@@ -251,7 +251,7 @@ function T() {
|
|
|
251
251
|
})
|
|
252
252
|
]
|
|
253
253
|
}) }), /* @__PURE__ */ g("tbody", { children: R.map((e) => /* @__PURE__ */ _("tr", {
|
|
254
|
-
className: "border-b hover:bg-
|
|
254
|
+
className: "border-b hover:bg-bg-sunken/50",
|
|
255
255
|
children: [
|
|
256
256
|
/* @__PURE__ */ g("td", {
|
|
257
257
|
className: "p-3",
|
|
@@ -281,7 +281,7 @@ function T() {
|
|
|
281
281
|
]
|
|
282
282
|
}),
|
|
283
283
|
/* @__PURE__ */ _("td", {
|
|
284
|
-
className: "p-3 text-right text-
|
|
284
|
+
className: "p-3 text-right text-text-secondary",
|
|
285
285
|
children: ["$", e.fees]
|
|
286
286
|
}),
|
|
287
287
|
/* @__PURE__ */ _("td", {
|
|
@@ -293,7 +293,7 @@ function T() {
|
|
|
293
293
|
children: B(e.status)
|
|
294
294
|
}),
|
|
295
295
|
/* @__PURE__ */ g("td", {
|
|
296
|
-
className: "p-3 text-
|
|
296
|
+
className: "p-3 text-text-secondary",
|
|
297
297
|
children: e.createdAt
|
|
298
298
|
})
|
|
299
299
|
]
|
|
@@ -322,7 +322,7 @@ function T() {
|
|
|
322
322
|
className: "font-medium",
|
|
323
323
|
children: e.name
|
|
324
324
|
}), /* @__PURE__ */ g("p", {
|
|
325
|
-
className: "text-sm text-
|
|
325
|
+
className: "text-sm text-text-secondary",
|
|
326
326
|
children: e.details
|
|
327
327
|
})] })]
|
|
328
328
|
}), e.isDefault && /* @__PURE__ */ g(v, { children: "Default" })]
|
|
@@ -336,7 +336,7 @@ function T() {
|
|
|
336
336
|
className: "flex items-center gap-1 text-yellow-600",
|
|
337
337
|
children: [/* @__PURE__ */ g(o, { className: "h-4 w-4" }), " Unverified"]
|
|
338
338
|
}), e.lastUsed && /* @__PURE__ */ _("span", {
|
|
339
|
-
className: "text-
|
|
339
|
+
className: "text-text-secondary",
|
|
340
340
|
children: ["Last used: ", e.lastUsed]
|
|
341
341
|
})]
|
|
342
342
|
}),
|
|
@@ -361,13 +361,13 @@ function T() {
|
|
|
361
361
|
children: /* @__PURE__ */ _(x, {
|
|
362
362
|
className: "py-8 text-center",
|
|
363
363
|
children: [
|
|
364
|
-
/* @__PURE__ */ g(d, { className: "mx-auto h-8 w-8 text-
|
|
364
|
+
/* @__PURE__ */ g(d, { className: "mx-auto h-8 w-8 text-text-secondary" }),
|
|
365
365
|
/* @__PURE__ */ g("p", {
|
|
366
366
|
className: "mt-2 text-sm font-medium",
|
|
367
367
|
children: "Add Payment Method"
|
|
368
368
|
}),
|
|
369
369
|
/* @__PURE__ */ g("p", {
|
|
370
|
-
className: "text-xs text-
|
|
370
|
+
className: "text-xs text-text-secondary",
|
|
371
371
|
children: "Add a new card, bank, or PayPal"
|
|
372
372
|
})
|
|
373
373
|
]
|
|
@@ -384,7 +384,7 @@ function T() {
|
|
|
384
384
|
children: /* @__PURE__ */ _("table", {
|
|
385
385
|
className: "w-full text-sm",
|
|
386
386
|
children: [/* @__PURE__ */ g("thead", { children: /* @__PURE__ */ _("tr", {
|
|
387
|
-
className: "border-b text-left text-
|
|
387
|
+
className: "border-b text-left text-text-secondary",
|
|
388
388
|
children: [
|
|
389
389
|
/* @__PURE__ */ g("th", {
|
|
390
390
|
className: "p-3",
|
|
@@ -416,7 +416,7 @@ function T() {
|
|
|
416
416
|
})
|
|
417
417
|
]
|
|
418
418
|
}) }), /* @__PURE__ */ g("tbody", { children: D.map((e) => /* @__PURE__ */ _("tr", {
|
|
419
|
-
className: "border-b hover:bg-
|
|
419
|
+
className: "border-b hover:bg-bg-sunken/50",
|
|
420
420
|
children: [
|
|
421
421
|
/* @__PURE__ */ g("td", {
|
|
422
422
|
className: "p-3 font-medium",
|
|
@@ -446,7 +446,7 @@ function T() {
|
|
|
446
446
|
})
|
|
447
447
|
}),
|
|
448
448
|
/* @__PURE__ */ g("td", {
|
|
449
|
-
className: "p-3 text-
|
|
449
|
+
className: "p-3 text-text-secondary",
|
|
450
450
|
children: e.dueDate
|
|
451
451
|
}),
|
|
452
452
|
/* @__PURE__ */ g("td", {
|
|
@@ -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} from '@burdenoff/fe-libs/ui';\nimport {\n DollarSign,\n CreditCard,\n Building2,\n Wallet,\n ArrowUpRight,\n ArrowDownLeft,\n RotateCcw,\n CheckCircle2,\n Clock,\n XCircle,\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-red-500\" />;\n if (type === 'refund') return <RotateCcw className=\"h-4 w-4 text-green-500\" />;\n return <ArrowDownLeft className=\"h-4 w-4 text-blue-500\" />;\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\">\n {/* Header */}\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\">Payments</h1>\n <p className=\"text-sm text-muted-foreground\">\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\n {/* Tabs */}\n <div className=\"flex gap-1 border-b\">\n {tabs.map(({ key, label }) => (\n <button\n key={key}\n onClick={() => setActiveTab(key)}\n className={`border-b-2 px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === key\n ? 'border-primary text-primary'\n : 'border-transparent text-muted-foreground hover:text-foreground'\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 <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-red-100 p-2 dark:bg-red-950\">\n <ArrowUpRight className=\"h-5 w-5 text-red-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">${totalSpent.toLocaleString()}</p>\n <p className=\"text-xs text-muted-foreground\">Total Spent</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-yellow-100 p-2 dark:bg-yellow-950\">\n <Clock className=\"h-5 w-5 text-yellow-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">${totalPending.toLocaleString()}</p>\n <p className=\"text-xs text-muted-foreground\">Pending</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-blue-100 p-2 dark:bg-blue-950\">\n <DollarSign className=\"h-5 w-5 text-blue-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">${totalFees.toLocaleString()}</p>\n <p className=\"text-xs text-muted-foreground\">Total Fees</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-green-100 p-2 dark:bg-green-950\">\n <RotateCcw className=\"h-5 w-5 text-green-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">${totalRefunded.toLocaleString()}</p>\n <p className=\"text-xs text-muted-foreground\">Refunded</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n {/* Recent transactions preview */}\n <Card>\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 p-3\"\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-muted-foreground\">\n {txn.counterparty} - {txn.createdAt}\n </p>\n </div>\n </div>\n <div className=\"text-right\">\n <p\n className={`text-sm font-bold ${txn.type === 'refund' ? 'text-green-600' : ''}`}\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-muted-foreground\" />\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 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>\n <CardContent className=\"pt-4\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-muted-foreground\">\n <th className=\"p-3\">Type</th>\n <th className=\"p-3\">Description</th>\n <th className=\"p-3\">Counterparty</th>\n <th className=\"p-3\">Method</th>\n <th className=\"p-3 text-right\">Amount</th>\n <th className=\"p-3 text-right\">Fees</th>\n <th className=\"p-3 text-right\">Net</th>\n <th className=\"p-3\">Status</th>\n <th className=\"p-3\">Date</th>\n </tr>\n </thead>\n <tbody>\n {filteredTxns.map((txn) => (\n <tr key={txn.id} className=\"border-b hover:bg-muted/50\">\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 ${txn.type === 'refund' ? 'text-green-600' : ''}`}\n >\n {txn.type === 'refund' ? '+' : '-'}${txn.amount.toLocaleString()}\n </td>\n <td className=\"p-3 text-right text-muted-foreground\">${txn.fees}</td>\n <td className=\"p-3 text-right\">${txn.netAmount.toLocaleString()}</td>\n <td className=\"p-3\">{statusBadge(txn.status)}</td>\n <td className=\"p-3 text-muted-foreground\">{txn.createdAt}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\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 <Card key={method.id} className={method.isDefault ? 'border-primary' : ''}>\n <CardContent className=\"pt-6\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg border p-2\">{methodIcon(method.type)}</div>\n <div>\n <p className=\"font-medium\">{method.name}</p>\n <p className=\"text-sm text-muted-foreground\">{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-green-600\">\n <Shield className=\"h-4 w-4\" /> Verified\n </span>\n ) : (\n <span className=\"flex items-center gap-1 text-yellow-600\">\n <Clock className=\"h-4 w-4\" /> Unverified\n </span>\n )}\n {method.lastUsed && (\n <span className=\"text-muted-foreground\">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 </CardContent>\n </Card>\n ))}\n\n {/* Add new method card */}\n <Card className=\"flex items-center justify-center border-dashed\">\n <CardContent className=\"py-8 text-center\">\n <Plus className=\"mx-auto h-8 w-8 text-muted-foreground\" />\n <p className=\"mt-2 text-sm font-medium\">Add Payment Method</p>\n <p className=\"text-xs text-muted-foreground\">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>\n <CardContent className=\"pt-4\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-muted-foreground\">\n <th className=\"p-3\">Invoice #</th>\n <th className=\"p-3\">Description</th>\n <th className=\"p-3\">Client</th>\n <th className=\"p-3 text-right\">Amount</th>\n <th className=\"p-3\">Status</th>\n <th className=\"p-3\">Due Date</th>\n <th className=\"p-3 text-right\">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 key={inv.id} className=\"border-b hover:bg-muted/50\">\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\">\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-muted-foreground\">{inv.dueDate}</td>\n <td className=\"p-3 text-right\">\n <div className=\"flex justify-end gap-1\">\n <Button variant=\"outline\" size=\"sm\">\n <FileText className=\"h-3 w-3\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"h-3 w-3\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
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} from '@burdenoff/fe-libs/ui';\nimport {\n DollarSign,\n CreditCard,\n Building2,\n Wallet,\n ArrowUpRight,\n ArrowDownLeft,\n RotateCcw,\n CheckCircle2,\n Clock,\n XCircle,\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-red-500\" />;\n if (type === 'refund') return <RotateCcw className=\"h-4 w-4 text-green-500\" />;\n return <ArrowDownLeft className=\"h-4 w-4 text-blue-500\" />;\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\">\n {/* Header */}\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\">Payments</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\n {/* Tabs */}\n <div className=\"flex gap-1 border-b\">\n {tabs.map(({ key, label }) => (\n <button\n key={key}\n onClick={() => setActiveTab(key)}\n className={`border-b-2 px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === key\n ? 'border-primary 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 <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-red-100 p-2 dark:bg-red-950\">\n <ArrowUpRight className=\"h-5 w-5 text-red-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">${totalSpent.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Total Spent</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-yellow-100 p-2 dark:bg-yellow-950\">\n <Clock className=\"h-5 w-5 text-yellow-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">${totalPending.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Pending</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-blue-100 p-2 dark:bg-blue-950\">\n <DollarSign className=\"h-5 w-5 text-blue-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">${totalFees.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Total Fees</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-green-100 p-2 dark:bg-green-950\">\n <RotateCcw className=\"h-5 w-5 text-green-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">${totalRefunded.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Refunded</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n {/* Recent transactions preview */}\n <Card>\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 p-3\"\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 ${txn.type === 'refund' ? 'text-green-600' : ''}`}\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 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>\n <CardContent className=\"pt-4\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-text-secondary\">\n <th className=\"p-3\">Type</th>\n <th className=\"p-3\">Description</th>\n <th className=\"p-3\">Counterparty</th>\n <th className=\"p-3\">Method</th>\n <th className=\"p-3 text-right\">Amount</th>\n <th className=\"p-3 text-right\">Fees</th>\n <th className=\"p-3 text-right\">Net</th>\n <th className=\"p-3\">Status</th>\n <th className=\"p-3\">Date</th>\n </tr>\n </thead>\n <tbody>\n {filteredTxns.map((txn) => (\n <tr key={txn.id} className=\"border-b hover:bg-bg-sunken/50\">\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 ${txn.type === 'refund' ? 'text-green-600' : ''}`}\n >\n {txn.type === 'refund' ? '+' : '-'}${txn.amount.toLocaleString()}\n </td>\n <td className=\"p-3 text-right text-text-secondary\">${txn.fees}</td>\n <td className=\"p-3 text-right\">${txn.netAmount.toLocaleString()}</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 </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 <Card key={method.id} className={method.isDefault ? 'border-primary' : ''}>\n <CardContent className=\"pt-6\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg border p-2\">{methodIcon(method.type)}</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-green-600\">\n <Shield className=\"h-4 w-4\" /> Verified\n </span>\n ) : (\n <span className=\"flex items-center gap-1 text-yellow-600\">\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 </CardContent>\n </Card>\n ))}\n\n {/* Add new method card */}\n <Card className=\"flex items-center justify-center border-dashed\">\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>\n <CardContent className=\"pt-4\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-text-secondary\">\n <th className=\"p-3\">Invoice #</th>\n <th className=\"p-3\">Description</th>\n <th className=\"p-3\">Client</th>\n <th className=\"p-3 text-right\">Amount</th>\n <th className=\"p-3\">Status</th>\n <th className=\"p-3\">Due Date</th>\n <th className=\"p-3 text-right\">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 key={inv.id} className=\"border-b hover:bg-bg-sunken/50\">\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\">\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\">\n <FileText className=\"h-3 w-3\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"h-3 w-3\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|