braid-ui 1.0.99 → 1.0.100
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/README.md +327 -44
- package/dist/css/braid-ui-variables.css +88 -0
- package/dist/css/braid-ui.css +4702 -0
- package/dist/css/braid-ui.min.css +1 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2027 -0
- package/dist/index.d.ts +2027 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +115 -55
- package/src/styles-only.css +121 -0
- package/src/{index.css → styles.css} +4 -10
- package/components.json +0 -20
- package/eslint.config.js +0 -29
- package/index.html +0 -24
- package/postcss.config.js +0 -6
- package/public/favicon.ico +0 -0
- package/public/placeholder.svg +0 -1
- package/public/robots.txt +0 -14
- package/src/App.css +0 -42
- package/src/App.tsx +0 -94
- package/src/components/MainLayout.tsx +0 -15
- package/src/components/alerts/AlertDocuments.tsx +0 -320
- package/src/components/alerts/AlertNotes.tsx +0 -185
- package/src/components/alerts/AlertTimeline.tsx +0 -79
- package/src/components/alerts/ContextSection.tsx +0 -155
- package/src/components/app-sidebar.tsx +0 -341
- package/src/components/form-sections/ACHBankCard.tsx +0 -78
- package/src/components/form-sections/ACHBasicInfoCard.tsx +0 -100
- package/src/components/form-sections/ACHTransferSection.tsx +0 -64
- package/src/components/form-sections/AddressForm.tsx +0 -94
- package/src/components/form-sections/BankAddressCard.tsx +0 -95
- package/src/components/form-sections/BankingDetailsCard.tsx +0 -46
- package/src/components/form-sections/BasicInfoCard.tsx +0 -103
- package/src/components/form-sections/BasicInfoSection.tsx +0 -34
- package/src/components/form-sections/BeneficiaryAddress.tsx +0 -19
- package/src/components/form-sections/BeneficiaryCard.tsx +0 -41
- package/src/components/form-sections/BeneficiaryDomesticWire.tsx +0 -23
- package/src/components/form-sections/BusinessProfileCard.tsx +0 -131
- package/src/components/form-sections/BusinessStatusCard.tsx +0 -53
- package/src/components/form-sections/ContactInfoCard.tsx +0 -63
- package/src/components/form-sections/CounterpartyBasicInfo.tsx +0 -101
- package/src/components/form-sections/CounterpartyProfileCard.tsx +0 -104
- package/src/components/form-sections/CounterpartyRecordsCard.tsx +0 -41
- package/src/components/form-sections/IntermediaryCard.tsx +0 -77
- package/src/components/form-sections/IntermediaryFI.tsx +0 -41
- package/src/components/form-sections/IntermediaryFIAddress.tsx +0 -14
- package/src/components/form-sections/OriginatorCard.tsx +0 -49
- package/src/components/form-sections/OriginatorFI.tsx +0 -42
- package/src/components/form-sections/OriginatorFIAddress.tsx +0 -14
- package/src/components/form-sections/PaymentInformationSection.tsx +0 -163
- package/src/components/form-sections/ReceiverCard.tsx +0 -94
- package/src/components/form-sections/WireTransferSection.tsx +0 -75
- package/src/components/layouts/list-page.tsx +0 -103
- package/src/components/transaction/ACHDetailsSection.tsx +0 -95
- package/src/components/transaction/WireDetailsSection.tsx +0 -112
- package/src/components/ui/account-card.tsx +0 -94
- package/src/components/ui/badge.tsx +0 -75
- package/src/components/ui/breadcrumb.tsx +0 -78
- package/src/components/ui/business-type-badge.tsx +0 -42
- package/src/components/ui/button.tsx +0 -56
- package/src/components/ui/calendar.tsx +0 -49
- package/src/components/ui/card.tsx +0 -223
- package/src/components/ui/container.tsx +0 -45
- package/src/components/ui/counterparty-type-badge.tsx +0 -53
- package/src/components/ui/data-grid.tsx +0 -99
- package/src/components/ui/data-table.tsx +0 -152
- package/src/components/ui/detail-page-layout.tsx +0 -83
- package/src/components/ui/dialog.tsx +0 -120
- package/src/components/ui/dropdown-menu.tsx +0 -82
- package/src/components/ui/editable-form-card.tsx +0 -106
- package/src/components/ui/editable-info-field.tsx +0 -67
- package/src/components/ui/enhanced-input.tsx +0 -78
- package/src/components/ui/enhanced-select.tsx +0 -101
- package/src/components/ui/enhanced-textarea.tsx +0 -64
- package/src/components/ui/entity-card.tsx +0 -140
- package/src/components/ui/form-card.tsx +0 -40
- package/src/components/ui/form-field.tsx +0 -50
- package/src/components/ui/form-input.tsx +0 -29
- package/src/components/ui/form-provider.tsx +0 -18
- package/src/components/ui/form-section.tsx +0 -66
- package/src/components/ui/form-select.tsx +0 -35
- package/src/components/ui/info-field.tsx +0 -36
- package/src/components/ui/json-viewer.tsx +0 -146
- package/src/components/ui/label.tsx +0 -24
- package/src/components/ui/metric-card.tsx +0 -80
- package/src/components/ui/page-layout.tsx +0 -183
- package/src/components/ui/popover.tsx +0 -29
- package/src/components/ui/responsive-grid.tsx +0 -46
- package/src/components/ui/separator.tsx +0 -31
- package/src/components/ui/sheet.tsx +0 -140
- package/src/components/ui/sidebar.tsx +0 -775
- package/src/components/ui/sonner.tsx +0 -29
- package/src/components/ui/stack.tsx +0 -77
- package/src/components/ui/status-badge.tsx +0 -68
- package/src/components/ui/tabs.tsx +0 -52
- package/src/components/ui/toast.tsx +0 -127
- package/src/components/ui/toaster.tsx +0 -33
- package/src/components/ui/tooltip.tsx +0 -28
- package/src/components/ui/use-toast.ts +0 -3
- package/src/components/ui-kit/dashboard-demo.tsx +0 -156
- package/src/components/ui-kit/pattern-library.tsx +0 -248
- package/src/components/ui-kit/showcase.tsx +0 -211
- package/src/hooks/use-mobile.tsx +0 -19
- package/src/hooks/use-toast.ts +0 -191
- package/src/hooks/useEditState.ts +0 -70
- package/src/hooks/useFormWithEditState.ts +0 -115
- package/src/lib/constants.ts +0 -25
- package/src/lib/mock-data/alert-data.ts +0 -275
- package/src/lib/mock-data/banking-data.ts +0 -72
- package/src/lib/mock-data/business-data.ts +0 -71
- package/src/lib/mock-data/counterparty-data.ts +0 -70
- package/src/lib/mock-data/index.ts +0 -5
- package/src/lib/mock-data/transaction-data.ts +0 -283
- package/src/lib/mock-data/wire-data.ts +0 -103
- package/src/lib/mock-data.tsx +0 -180
- package/src/lib/schemas/banking-schemas.ts +0 -30
- package/src/lib/schemas/business-schemas.ts +0 -36
- package/src/lib/schemas/counterparty-schemas.ts +0 -43
- package/src/lib/schemas/index.ts +0 -5
- package/src/lib/schemas/wire-schemas.ts +0 -44
- package/src/lib/utils.ts +0 -6
- package/src/main.tsx +0 -10
- package/src/pages/Cases.tsx +0 -16
- package/src/pages/Dashboard.tsx +0 -16
- package/src/pages/NotFound.tsx +0 -27
- package/src/pages/TransactionHistory.tsx +0 -532
- package/src/pages/UIKit.tsx +0 -51
- package/src/pages/alerts/AlertDetail.tsx +0 -193
- package/src/pages/alerts/Alerts.tsx +0 -373
- package/src/pages/business/Business.tsx +0 -48
- package/src/pages/business/Create.tsx +0 -173
- package/src/pages/counterparty/Create.tsx +0 -48
- package/src/pages/counterparty/DomesticWire.tsx +0 -78
- package/src/pages/counterparty/Manage.tsx +0 -79
- package/src/pages/transactions/NewTransaction.tsx +0 -527
- package/src/pages/transactions/TransactionDetail.tsx +0 -192
- package/src/vite-env.d.ts +0 -1
- package/tailwind.config.ts +0 -124
- package/tsconfig.app.json +0 -30
- package/tsconfig.json +0 -19
- package/tsconfig.node.json +0 -22
- package/vite.config.ts +0 -22
- /package/{src/assets/braid-logo.png → dist/braid-logo-343BOQZ2.png} +0 -0
package/src/pages/UIKit.tsx
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { Container } from "@/components/ui/container"
|
|
3
|
-
import { Stack } from "@/components/ui/stack"
|
|
4
|
-
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
|
5
|
-
import { UIKitShowcase } from "@/components/ui-kit/showcase"
|
|
6
|
-
import { PatternLibrary } from "@/components/ui-kit/pattern-library"
|
|
7
|
-
import { DashboardDemo } from "@/components/ui-kit/dashboard-demo"
|
|
8
|
-
import { Breadcrumb } from "@/components/ui/breadcrumb"
|
|
9
|
-
|
|
10
|
-
export default function UIKit() {
|
|
11
|
-
const breadcrumbs = [
|
|
12
|
-
{ label: "UI Kit" }
|
|
13
|
-
]
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<div className="min-h-screen bg-gradient-subtle">
|
|
17
|
-
<Container size="xl">
|
|
18
|
-
<Stack spacing="lg">
|
|
19
|
-
<Breadcrumb items={breadcrumbs} />
|
|
20
|
-
|
|
21
|
-
<div>
|
|
22
|
-
<h1 className="text-3xl font-bold text-foreground">UI Kit</h1>
|
|
23
|
-
<p className="text-muted-foreground mt-2">
|
|
24
|
-
Complete collection of reusable components, layouts, and patterns
|
|
25
|
-
</p>
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
<Tabs defaultValue="showcase" className="w-full">
|
|
29
|
-
<TabsList className="grid w-full grid-cols-3">
|
|
30
|
-
<TabsTrigger value="showcase">Component Showcase</TabsTrigger>
|
|
31
|
-
<TabsTrigger value="patterns">Pattern Library</TabsTrigger>
|
|
32
|
-
<TabsTrigger value="demo">Dashboard Demo</TabsTrigger>
|
|
33
|
-
</TabsList>
|
|
34
|
-
|
|
35
|
-
<TabsContent value="showcase" className="mt-6">
|
|
36
|
-
<UIKitShowcase />
|
|
37
|
-
</TabsContent>
|
|
38
|
-
|
|
39
|
-
<TabsContent value="patterns" className="mt-6">
|
|
40
|
-
<PatternLibrary />
|
|
41
|
-
</TabsContent>
|
|
42
|
-
|
|
43
|
-
<TabsContent value="demo" className="mt-6">
|
|
44
|
-
<DashboardDemo />
|
|
45
|
-
</TabsContent>
|
|
46
|
-
</Tabs>
|
|
47
|
-
</Stack>
|
|
48
|
-
</Container>
|
|
49
|
-
</div>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import { useState } from "react"
|
|
2
|
-
import { useParams, useNavigate } from "react-router-dom"
|
|
3
|
-
import { PageLayout } from "@/components/ui/page-layout"
|
|
4
|
-
import { FormCard } from "@/components/ui/form-card"
|
|
5
|
-
import { Button } from "@/components/ui/button"
|
|
6
|
-
import { Badge } from "@/components/ui/badge"
|
|
7
|
-
import { Edit } from "lucide-react"
|
|
8
|
-
import { mockAlerts } from "@/lib/mock-data/alert-data"
|
|
9
|
-
import { cn } from "@/lib/utils"
|
|
10
|
-
import { AlertTimeline } from "@/components/alerts/AlertTimeline"
|
|
11
|
-
import { AlertNotes } from "@/components/alerts/AlertNotes"
|
|
12
|
-
import { AlertDocuments } from "@/components/alerts/AlertDocuments"
|
|
13
|
-
import { ContextSection } from "@/components/alerts/ContextSection"
|
|
14
|
-
import { InfoField } from "@/components/ui/info-field"
|
|
15
|
-
import { EditableInfoField } from "@/components/ui/editable-info-field"
|
|
16
|
-
|
|
17
|
-
const RFI_STATUS_OPTIONS = [
|
|
18
|
-
{ value: "Completed", label: "Completed" },
|
|
19
|
-
{ value: "Provided", label: "Provided" },
|
|
20
|
-
{ value: "Pending", label: "Pending" }
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
const ASSIGNEE_OPTIONS = [
|
|
24
|
-
{ value: "John Smith", label: "John Smith" },
|
|
25
|
-
{ value: "Sarah Johnson", label: "Sarah Johnson" },
|
|
26
|
-
{ value: "Michael Chen", label: "Michael Chen" },
|
|
27
|
-
{ value: "approverdev", label: "approverdev" },
|
|
28
|
-
{ value: "Unassigned", label: "Unassigned" }
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
const AlertDetail = () => {
|
|
32
|
-
const { id } = useParams()
|
|
33
|
-
const navigate = useNavigate()
|
|
34
|
-
|
|
35
|
-
const alert = mockAlerts.find(a => a.id === id)
|
|
36
|
-
|
|
37
|
-
// Local state for editable fields
|
|
38
|
-
const [rfiStatus, setRfiStatus] = useState(alert?.rfiStatus || "")
|
|
39
|
-
const [assignee, setAssignee] = useState(alert?.assignee || "Unassigned")
|
|
40
|
-
|
|
41
|
-
const handleRfiStatusChange = (newStatus: string) => {
|
|
42
|
-
setRfiStatus(newStatus)
|
|
43
|
-
console.log("RFI Status updated to:", newStatus)
|
|
44
|
-
// TODO: API call to update alert
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const handleAssigneeChange = (newAssignee: string) => {
|
|
48
|
-
setAssignee(newAssignee)
|
|
49
|
-
console.log("Assignee updated to:", newAssignee)
|
|
50
|
-
// TODO: API call to update alert
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (!alert) {
|
|
54
|
-
return (
|
|
55
|
-
<div className="container mx-auto px-4 py-8">
|
|
56
|
-
<div className="text-center">
|
|
57
|
-
<h1 className="text-2xl font-bold mb-2">Alert Not Found</h1>
|
|
58
|
-
<p className="text-muted-foreground mb-4">The alert #{id} could not be found.</p>
|
|
59
|
-
<Button onClick={() => navigate("/alerts")}>
|
|
60
|
-
Back to Alerts
|
|
61
|
-
</Button>
|
|
62
|
-
</div>
|
|
63
|
-
</div>
|
|
64
|
-
)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const getTypeBadgeVariant = (type: string): any => {
|
|
68
|
-
switch (type) {
|
|
69
|
-
case "Ofac":
|
|
70
|
-
return "alert-ofac"
|
|
71
|
-
case "Dual Approval":
|
|
72
|
-
return "alert-dual"
|
|
73
|
-
case "Transaction Monitoring":
|
|
74
|
-
return "alert-monitoring"
|
|
75
|
-
case "Transaction Processing Error":
|
|
76
|
-
return "alert-error"
|
|
77
|
-
default:
|
|
78
|
-
return "outline"
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const getStatusColor = (status: string) => {
|
|
83
|
-
switch (status) {
|
|
84
|
-
case "Unassigned":
|
|
85
|
-
return "text-destructive"
|
|
86
|
-
case "Closed":
|
|
87
|
-
return "text-success"
|
|
88
|
-
case "In Progress":
|
|
89
|
-
return "text-warning"
|
|
90
|
-
default:
|
|
91
|
-
return ""
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return (
|
|
96
|
-
<PageLayout
|
|
97
|
-
title={`Alert #${alert.id}`}
|
|
98
|
-
description={alert.description}
|
|
99
|
-
maxWidth="full"
|
|
100
|
-
actions={[
|
|
101
|
-
{
|
|
102
|
-
label: "Back to Alerts",
|
|
103
|
-
variant: "outline",
|
|
104
|
-
onClick: () => navigate("/alerts")
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
label: "Assign",
|
|
108
|
-
variant: "outline",
|
|
109
|
-
onClick: () => console.log("Assign alert")
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
label: "Close Alert",
|
|
113
|
-
variant: "default",
|
|
114
|
-
onClick: () => console.log("Close alert")
|
|
115
|
-
}
|
|
116
|
-
]}
|
|
117
|
-
>
|
|
118
|
-
{/* 3-Column Layout: 2x2 Grid on Left, Timeline on Right */}
|
|
119
|
-
<div className="flex flex-col lg:flex-row gap-6">
|
|
120
|
-
{/* Left Section: 2x2 Grid */}
|
|
121
|
-
<div className="flex-1 grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
122
|
-
{/* Alert Information */}
|
|
123
|
-
<FormCard
|
|
124
|
-
title="Alert Information"
|
|
125
|
-
headerActions={
|
|
126
|
-
<Button variant="ghost" size="sm">
|
|
127
|
-
<Edit className="h-4 w-4" />
|
|
128
|
-
</Button>
|
|
129
|
-
}
|
|
130
|
-
>
|
|
131
|
-
<div className="grid grid-cols-2 gap-4">
|
|
132
|
-
<InfoField label="Alert ID" value={alert.id} />
|
|
133
|
-
<InfoField
|
|
134
|
-
label="Type"
|
|
135
|
-
value={<Badge variant={getTypeBadgeVariant(alert.type)}>{alert.type}</Badge>}
|
|
136
|
-
/>
|
|
137
|
-
<InfoField
|
|
138
|
-
label="Status"
|
|
139
|
-
value={<span className={cn("font-medium", getStatusColor(alert.status))}>{alert.status}</span>}
|
|
140
|
-
/>
|
|
141
|
-
<InfoField label="Created At" value={alert.createdAt} />
|
|
142
|
-
<InfoField
|
|
143
|
-
label="Context Type"
|
|
144
|
-
value={<Badge variant="outline">{alert.contextType}</Badge>}
|
|
145
|
-
/>
|
|
146
|
-
<InfoField label="Context ID" value={alert.contextId || "N/A"} />
|
|
147
|
-
<EditableInfoField
|
|
148
|
-
label="Assignee"
|
|
149
|
-
value={assignee}
|
|
150
|
-
options={ASSIGNEE_OPTIONS}
|
|
151
|
-
onChange={handleAssigneeChange}
|
|
152
|
-
placeholder="Unassigned"
|
|
153
|
-
/>
|
|
154
|
-
<EditableInfoField
|
|
155
|
-
label="RFI Status"
|
|
156
|
-
value={rfiStatus}
|
|
157
|
-
options={RFI_STATUS_OPTIONS}
|
|
158
|
-
onChange={handleRfiStatusChange}
|
|
159
|
-
placeholder="Select status"
|
|
160
|
-
renderValue={(value) => <Badge variant="success">{value}</Badge>}
|
|
161
|
-
/>
|
|
162
|
-
<div className="col-span-2">
|
|
163
|
-
<InfoField label="Description" value={alert.description} />
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
</FormCard>
|
|
167
|
-
|
|
168
|
-
{/* Context Section */}
|
|
169
|
-
<ContextSection alert={alert} />
|
|
170
|
-
|
|
171
|
-
{/* Notes Section */}
|
|
172
|
-
<FormCard title="Notes">
|
|
173
|
-
<AlertNotes alertId={alert.id} notes={alert.notes || []} />
|
|
174
|
-
</FormCard>
|
|
175
|
-
|
|
176
|
-
{/* Documents Section */}
|
|
177
|
-
<FormCard title="Documents">
|
|
178
|
-
<AlertDocuments alertId={alert.id} documents={alert.documents || []} />
|
|
179
|
-
</FormCard>
|
|
180
|
-
</div>
|
|
181
|
-
|
|
182
|
-
{/* Right Section: Timeline Column */}
|
|
183
|
-
<div className="lg:w-64">
|
|
184
|
-
<FormCard title="Status Timeline" className="h-full">
|
|
185
|
-
<AlertTimeline events={alert.timeline || []} />
|
|
186
|
-
</FormCard>
|
|
187
|
-
</div>
|
|
188
|
-
</div>
|
|
189
|
-
</PageLayout>
|
|
190
|
-
)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
export default AlertDetail
|
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
import { useState } from "react"
|
|
2
|
-
import { useNavigate } from "react-router-dom"
|
|
3
|
-
import { PageLayout } from "@/components/ui/page-layout"
|
|
4
|
-
import { Button } from "@/components/ui/button"
|
|
5
|
-
import { Filter, ChevronLeft, ChevronRight } from "lucide-react"
|
|
6
|
-
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger, SheetFooter } from "@/components/ui/sheet"
|
|
7
|
-
import { Badge } from "@/components/ui/badge"
|
|
8
|
-
import { mockAlerts, Alert } from "@/lib/mock-data/alert-data"
|
|
9
|
-
import { EnhancedInput } from "@/components/ui/enhanced-input"
|
|
10
|
-
import { EnhancedSelect } from "@/components/ui/enhanced-select"
|
|
11
|
-
import { cn } from "@/lib/utils"
|
|
12
|
-
import {
|
|
13
|
-
DropdownMenu,
|
|
14
|
-
DropdownMenuContent,
|
|
15
|
-
DropdownMenuItem,
|
|
16
|
-
DropdownMenuTrigger,
|
|
17
|
-
} from "@/components/ui/dropdown-menu"
|
|
18
|
-
|
|
19
|
-
const Alerts = () => {
|
|
20
|
-
const navigate = useNavigate()
|
|
21
|
-
const [filters, setFilters] = useState({
|
|
22
|
-
alertId: "",
|
|
23
|
-
contextId: "",
|
|
24
|
-
contextType: "",
|
|
25
|
-
alertType: "",
|
|
26
|
-
alertStatus: "",
|
|
27
|
-
assignee: "",
|
|
28
|
-
rfiStatus: "",
|
|
29
|
-
startDate: "",
|
|
30
|
-
endDate: ""
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
const [filteredAlerts, setFilteredAlerts] = useState<Alert[]>(mockAlerts)
|
|
34
|
-
const [currentPage, setCurrentPage] = useState(1)
|
|
35
|
-
const [rowsPerPage, setRowsPerPage] = useState(100)
|
|
36
|
-
|
|
37
|
-
const handleFilterChange = (field: string, value: string) => {
|
|
38
|
-
setFilters(prev => ({ ...prev, [field]: value }))
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const applyFilters = () => {
|
|
42
|
-
let filtered = mockAlerts
|
|
43
|
-
|
|
44
|
-
if (filters.alertId) {
|
|
45
|
-
filtered = filtered.filter(alert => alert.id.includes(filters.alertId))
|
|
46
|
-
}
|
|
47
|
-
if (filters.alertStatus) {
|
|
48
|
-
filtered = filtered.filter(alert => alert.status === filters.alertStatus)
|
|
49
|
-
}
|
|
50
|
-
if (filters.alertType) {
|
|
51
|
-
filtered = filtered.filter(alert => alert.type === filters.alertType)
|
|
52
|
-
}
|
|
53
|
-
if (filters.contextType) {
|
|
54
|
-
filtered = filtered.filter(alert => alert.contextType === filters.contextType)
|
|
55
|
-
}
|
|
56
|
-
if (filters.rfiStatus) {
|
|
57
|
-
filtered = filtered.filter(alert => alert.rfiStatus === filters.rfiStatus)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
setFilteredAlerts(filtered)
|
|
61
|
-
setCurrentPage(1) // Reset to first page when applying filters
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const resetFilters = () => {
|
|
65
|
-
setFilters({
|
|
66
|
-
alertId: "",
|
|
67
|
-
contextId: "",
|
|
68
|
-
contextType: "",
|
|
69
|
-
alertType: "",
|
|
70
|
-
alertStatus: "",
|
|
71
|
-
assignee: "",
|
|
72
|
-
rfiStatus: "",
|
|
73
|
-
startDate: "",
|
|
74
|
-
endDate: ""
|
|
75
|
-
})
|
|
76
|
-
setFilteredAlerts(mockAlerts)
|
|
77
|
-
setCurrentPage(1) // Reset to first page when resetting filters
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const getTypeBadgeVariant = (type: string): any => {
|
|
81
|
-
switch (type) {
|
|
82
|
-
case "Ofac":
|
|
83
|
-
return "alert-ofac"
|
|
84
|
-
case "Dual Approval":
|
|
85
|
-
return "alert-dual"
|
|
86
|
-
case "Transaction Monitoring":
|
|
87
|
-
return "alert-monitoring"
|
|
88
|
-
case "Transaction Processing Error":
|
|
89
|
-
return "alert-error"
|
|
90
|
-
default:
|
|
91
|
-
return "outline"
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const getStatusColor = (status: string) => {
|
|
96
|
-
switch (status) {
|
|
97
|
-
case "Unassigned":
|
|
98
|
-
return "text-destructive"
|
|
99
|
-
case "Closed":
|
|
100
|
-
return "text-success"
|
|
101
|
-
case "In Progress":
|
|
102
|
-
return "text-warning"
|
|
103
|
-
default:
|
|
104
|
-
return ""
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Pagination calculations
|
|
109
|
-
const totalPages = Math.ceil(filteredAlerts.length / rowsPerPage)
|
|
110
|
-
const startIndex = (currentPage - 1) * rowsPerPage
|
|
111
|
-
const endIndex = startIndex + rowsPerPage
|
|
112
|
-
const paginatedAlerts = filteredAlerts.slice(startIndex, endIndex)
|
|
113
|
-
|
|
114
|
-
const handlePageChange = (newPage: number) => {
|
|
115
|
-
if (newPage >= 1 && newPage <= totalPages) {
|
|
116
|
-
setCurrentPage(newPage)
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const handleRowsPerPageChange = (value: number) => {
|
|
121
|
-
setRowsPerPage(value)
|
|
122
|
-
setCurrentPage(1) // Reset to first page when changing rows per page
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return (
|
|
126
|
-
<div className="flex flex-col h-screen bg-gradient-subtle">
|
|
127
|
-
{/* Fixed Header */}
|
|
128
|
-
<div className="flex-none border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
129
|
-
<div className="container mx-auto px-4 py-4 max-w-none">
|
|
130
|
-
<div className="flex items-center justify-between">
|
|
131
|
-
<h1 className="text-3xl font-bold text-foreground">Alerts</h1>
|
|
132
|
-
<Sheet>
|
|
133
|
-
<SheetTrigger asChild>
|
|
134
|
-
<Button variant="outline" className="gap-2">
|
|
135
|
-
<Filter className="h-4 w-4" />
|
|
136
|
-
Filters
|
|
137
|
-
</Button>
|
|
138
|
-
</SheetTrigger>
|
|
139
|
-
<SheetContent side="right" className="w-full sm:max-w-xl overflow-y-auto">
|
|
140
|
-
<SheetHeader>
|
|
141
|
-
<SheetTitle>Alert Filters</SheetTitle>
|
|
142
|
-
</SheetHeader>
|
|
143
|
-
|
|
144
|
-
<div className="space-y-6 py-6">
|
|
145
|
-
<EnhancedInput
|
|
146
|
-
label="Alert ID"
|
|
147
|
-
value={filters.alertId}
|
|
148
|
-
onChange={(e) => handleFilterChange("alertId", e.target.value)}
|
|
149
|
-
placeholder="Enter alert ID"
|
|
150
|
-
/>
|
|
151
|
-
|
|
152
|
-
<EnhancedInput
|
|
153
|
-
label="Context ID"
|
|
154
|
-
value={filters.contextId}
|
|
155
|
-
onChange={(e) => handleFilterChange("contextId", e.target.value)}
|
|
156
|
-
placeholder="Enter context ID"
|
|
157
|
-
/>
|
|
158
|
-
|
|
159
|
-
<EnhancedSelect
|
|
160
|
-
label="Context Type"
|
|
161
|
-
value={filters.contextType}
|
|
162
|
-
onValueChange={(value) => handleFilterChange("contextType", value)}
|
|
163
|
-
placeholder="Select context type"
|
|
164
|
-
options={[
|
|
165
|
-
{ value: "Ofac", label: "Ofac" },
|
|
166
|
-
{ value: "Transaction", label: "Transaction" },
|
|
167
|
-
{ value: "Product", label: "Product" },
|
|
168
|
-
{ value: "File Record", label: "File Record" }
|
|
169
|
-
]}
|
|
170
|
-
/>
|
|
171
|
-
|
|
172
|
-
<EnhancedSelect
|
|
173
|
-
label="Alert Type"
|
|
174
|
-
value={filters.alertType}
|
|
175
|
-
onValueChange={(value) => handleFilterChange("alertType", value)}
|
|
176
|
-
placeholder="Select alert type"
|
|
177
|
-
options={[
|
|
178
|
-
{ value: "Ofac", label: "Ofac" },
|
|
179
|
-
{ value: "Dual Approval", label: "Dual Approval" },
|
|
180
|
-
{ value: "Transaction Monitoring", label: "Transaction Monitoring" },
|
|
181
|
-
{ value: "Transaction Processing Error", label: "Transaction Processing Error" }
|
|
182
|
-
]}
|
|
183
|
-
/>
|
|
184
|
-
|
|
185
|
-
<EnhancedSelect
|
|
186
|
-
label="Alert Status"
|
|
187
|
-
value={filters.alertStatus}
|
|
188
|
-
onValueChange={(value) => handleFilterChange("alertStatus", value)}
|
|
189
|
-
placeholder="Select status"
|
|
190
|
-
options={[
|
|
191
|
-
{ value: "Unassigned", label: "Unassigned" },
|
|
192
|
-
{ value: "Closed", label: "Closed" },
|
|
193
|
-
{ value: "In Progress", label: "In Progress" }
|
|
194
|
-
]}
|
|
195
|
-
/>
|
|
196
|
-
|
|
197
|
-
<EnhancedInput
|
|
198
|
-
label="Assignee"
|
|
199
|
-
value={filters.assignee}
|
|
200
|
-
onChange={(e) => handleFilterChange("assignee", e.target.value)}
|
|
201
|
-
placeholder="Enter assignee name"
|
|
202
|
-
/>
|
|
203
|
-
|
|
204
|
-
<EnhancedSelect
|
|
205
|
-
label="RFI Status"
|
|
206
|
-
value={filters.rfiStatus}
|
|
207
|
-
onValueChange={(value) => handleFilterChange("rfiStatus", value)}
|
|
208
|
-
placeholder="Select RFI status"
|
|
209
|
-
options={[
|
|
210
|
-
{ value: "Completed", label: "Completed" },
|
|
211
|
-
{ value: "Provided", label: "Provided" },
|
|
212
|
-
{ value: "Pending", label: "Pending" }
|
|
213
|
-
]}
|
|
214
|
-
/>
|
|
215
|
-
|
|
216
|
-
<div className="grid grid-cols-2 gap-4">
|
|
217
|
-
<EnhancedInput
|
|
218
|
-
label="Start Date"
|
|
219
|
-
type="date"
|
|
220
|
-
value={filters.startDate}
|
|
221
|
-
onChange={(e) => handleFilterChange("startDate", e.target.value)}
|
|
222
|
-
/>
|
|
223
|
-
|
|
224
|
-
<EnhancedInput
|
|
225
|
-
label="End Date"
|
|
226
|
-
type="date"
|
|
227
|
-
value={filters.endDate}
|
|
228
|
-
onChange={(e) => handleFilterChange("endDate", e.target.value)}
|
|
229
|
-
/>
|
|
230
|
-
</div>
|
|
231
|
-
</div>
|
|
232
|
-
|
|
233
|
-
<SheetFooter className="gap-2">
|
|
234
|
-
<Button variant="outline" onClick={resetFilters}>
|
|
235
|
-
Reset Filters
|
|
236
|
-
</Button>
|
|
237
|
-
<Button onClick={applyFilters}>
|
|
238
|
-
Apply Filters
|
|
239
|
-
</Button>
|
|
240
|
-
</SheetFooter>
|
|
241
|
-
</SheetContent>
|
|
242
|
-
</Sheet>
|
|
243
|
-
</div>
|
|
244
|
-
</div>
|
|
245
|
-
</div>
|
|
246
|
-
|
|
247
|
-
{/* Scrollable Content */}
|
|
248
|
-
<div className="flex-1 overflow-hidden">
|
|
249
|
-
<div className="container mx-auto px-4 h-full max-w-none flex flex-col">
|
|
250
|
-
<div className="flex-1 mt-4 rounded-lg border bg-card overflow-hidden flex flex-col">
|
|
251
|
-
<div className="flex-1 overflow-auto">
|
|
252
|
-
<table className="w-full table-fixed">
|
|
253
|
-
<colgroup>
|
|
254
|
-
<col className="w-28" />
|
|
255
|
-
<col className="w-36" />
|
|
256
|
-
<col className="w-52" />
|
|
257
|
-
<col className="w-32" />
|
|
258
|
-
<col className="w-36" />
|
|
259
|
-
<col className="w-32" />
|
|
260
|
-
<col className="w-auto" />
|
|
261
|
-
</colgroup>
|
|
262
|
-
<thead className="sticky top-0 bg-card z-10 shadow-sm">
|
|
263
|
-
<tr className="border-b">
|
|
264
|
-
<th className="px-3 py-2 text-left text-xs font-medium bg-muted/50">Alert ID</th>
|
|
265
|
-
<th className="px-3 py-2 text-left text-xs font-medium bg-muted/50">Created At</th>
|
|
266
|
-
<th className="px-3 py-2 text-left text-xs font-medium bg-muted/50">Type</th>
|
|
267
|
-
<th className="px-3 py-2 text-left text-xs font-medium bg-muted/50">Status</th>
|
|
268
|
-
<th className="px-3 py-2 text-left text-xs font-medium bg-muted/50">Context Type</th>
|
|
269
|
-
<th className="px-3 py-2 text-left text-xs font-medium bg-muted/50">RFI Status</th>
|
|
270
|
-
<th className="px-3 py-2 text-left text-xs font-medium bg-muted/50">Description</th>
|
|
271
|
-
</tr>
|
|
272
|
-
</thead>
|
|
273
|
-
<tbody>
|
|
274
|
-
{paginatedAlerts.map((alert) => (
|
|
275
|
-
<tr
|
|
276
|
-
key={alert.id}
|
|
277
|
-
className="border-b hover:bg-muted/50 transition-colors cursor-pointer"
|
|
278
|
-
onClick={() => navigate(`/alerts/${alert.id}`)}
|
|
279
|
-
>
|
|
280
|
-
<td className="px-3 py-2 text-xs">{alert.id}</td>
|
|
281
|
-
<td className="px-3 py-2 text-xs">{alert.createdAt}</td>
|
|
282
|
-
<td className="px-3 py-2">
|
|
283
|
-
<Badge variant={getTypeBadgeVariant(alert.type)} className="whitespace-nowrap">
|
|
284
|
-
{alert.type}
|
|
285
|
-
</Badge>
|
|
286
|
-
</td>
|
|
287
|
-
<td className="px-3 py-2">
|
|
288
|
-
<span className={cn("text-xs font-medium", getStatusColor(alert.status))}>
|
|
289
|
-
{alert.status}
|
|
290
|
-
</span>
|
|
291
|
-
</td>
|
|
292
|
-
<td className="px-3 py-2">
|
|
293
|
-
<Badge variant="outline" className="whitespace-nowrap">
|
|
294
|
-
{alert.contextType}
|
|
295
|
-
</Badge>
|
|
296
|
-
</td>
|
|
297
|
-
<td className="px-3 py-2">
|
|
298
|
-
{alert.rfiStatus && (
|
|
299
|
-
<Badge variant="success" className="whitespace-nowrap">
|
|
300
|
-
{alert.rfiStatus}
|
|
301
|
-
</Badge>
|
|
302
|
-
)}
|
|
303
|
-
</td>
|
|
304
|
-
<td className="px-3 py-2 text-xs truncate">
|
|
305
|
-
{alert.description}
|
|
306
|
-
</td>
|
|
307
|
-
</tr>
|
|
308
|
-
))}
|
|
309
|
-
</tbody>
|
|
310
|
-
</table>
|
|
311
|
-
</div>
|
|
312
|
-
|
|
313
|
-
{/* Pagination Footer */}
|
|
314
|
-
<div className="flex-none border-t bg-background py-3 px-4">
|
|
315
|
-
<div className="flex items-center justify-between">
|
|
316
|
-
<div className="flex items-center gap-2">
|
|
317
|
-
<span className="text-sm text-muted-foreground">Rows per page:</span>
|
|
318
|
-
<DropdownMenu>
|
|
319
|
-
<DropdownMenuTrigger asChild>
|
|
320
|
-
<Button variant="outline" size="sm" className="h-8 gap-1">
|
|
321
|
-
{rowsPerPage}
|
|
322
|
-
<ChevronRight className="h-4 w-4 rotate-90" />
|
|
323
|
-
</Button>
|
|
324
|
-
</DropdownMenuTrigger>
|
|
325
|
-
<DropdownMenuContent align="start" className="bg-background z-50">
|
|
326
|
-
<DropdownMenuItem onClick={() => handleRowsPerPageChange(100)}>
|
|
327
|
-
100
|
|
328
|
-
</DropdownMenuItem>
|
|
329
|
-
<DropdownMenuItem onClick={() => handleRowsPerPageChange(200)}>
|
|
330
|
-
200
|
|
331
|
-
</DropdownMenuItem>
|
|
332
|
-
<DropdownMenuItem onClick={() => handleRowsPerPageChange(500)}>
|
|
333
|
-
500
|
|
334
|
-
</DropdownMenuItem>
|
|
335
|
-
</DropdownMenuContent>
|
|
336
|
-
</DropdownMenu>
|
|
337
|
-
</div>
|
|
338
|
-
|
|
339
|
-
<div className="flex items-center gap-4">
|
|
340
|
-
<span className="text-sm text-muted-foreground">
|
|
341
|
-
Page {currentPage} of {totalPages}
|
|
342
|
-
</span>
|
|
343
|
-
<div className="flex items-center gap-1">
|
|
344
|
-
<Button
|
|
345
|
-
variant="outline"
|
|
346
|
-
size="sm"
|
|
347
|
-
className="h-8 w-8 p-0"
|
|
348
|
-
onClick={() => handlePageChange(currentPage - 1)}
|
|
349
|
-
disabled={currentPage === 1}
|
|
350
|
-
>
|
|
351
|
-
<ChevronLeft className="h-4 w-4" />
|
|
352
|
-
</Button>
|
|
353
|
-
<Button
|
|
354
|
-
variant="outline"
|
|
355
|
-
size="sm"
|
|
356
|
-
className="h-8 w-8 p-0"
|
|
357
|
-
onClick={() => handlePageChange(currentPage + 1)}
|
|
358
|
-
disabled={currentPage === totalPages}
|
|
359
|
-
>
|
|
360
|
-
<ChevronRight className="h-4 w-4" />
|
|
361
|
-
</Button>
|
|
362
|
-
</div>
|
|
363
|
-
</div>
|
|
364
|
-
</div>
|
|
365
|
-
</div>
|
|
366
|
-
</div>
|
|
367
|
-
</div>
|
|
368
|
-
</div>
|
|
369
|
-
</div>
|
|
370
|
-
)
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
export default Alerts
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { DetailPageLayout } from "@/components/ui/detail-page-layout"
|
|
2
|
-
import { BusinessProfileCard } from "@/components/form-sections/BusinessProfileCard"
|
|
3
|
-
import { BusinessStatusCard } from "@/components/form-sections/BusinessStatusCard"
|
|
4
|
-
import { ContactInfoCard } from "@/components/form-sections/ContactInfoCard"
|
|
5
|
-
import { BankingDetailsCard } from "@/components/form-sections/BankingDetailsCard"
|
|
6
|
-
|
|
7
|
-
const Business = () => {
|
|
8
|
-
return (
|
|
9
|
-
<DetailPageLayout
|
|
10
|
-
title="Business Management"
|
|
11
|
-
description="Manage business entities and their configurations"
|
|
12
|
-
cards={[
|
|
13
|
-
{
|
|
14
|
-
key: "profile",
|
|
15
|
-
component: BusinessProfileCard,
|
|
16
|
-
expandOnEdit: true
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
key: "status",
|
|
20
|
-
component: BusinessStatusCard,
|
|
21
|
-
expandOnEdit: true
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
key: "contact",
|
|
25
|
-
component: ContactInfoCard,
|
|
26
|
-
expandOnEdit: true
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
key: "banking",
|
|
30
|
-
component: BankingDetailsCard,
|
|
31
|
-
expandOnEdit: true
|
|
32
|
-
}
|
|
33
|
-
]}
|
|
34
|
-
actions={[
|
|
35
|
-
{
|
|
36
|
-
label: "Export Data",
|
|
37
|
-
variant: "outline"
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
label: "Edit Business",
|
|
41
|
-
className: "bg-gradient-primary hover:opacity-90"
|
|
42
|
-
}
|
|
43
|
-
]}
|
|
44
|
-
/>
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export default Business
|