braid-ui 1.0.97 → 1.0.99
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 +44 -327
- package/components.json +20 -0
- package/eslint.config.js +29 -0
- package/index.html +24 -0
- package/package.json +55 -115
- package/postcss.config.js +6 -0
- package/public/favicon.ico +0 -0
- package/public/placeholder.svg +1 -0
- package/public/robots.txt +14 -0
- package/src/App.css +42 -0
- package/src/App.tsx +94 -0
- package/src/components/MainLayout.tsx +15 -0
- package/src/components/alerts/AlertDocuments.tsx +320 -0
- package/src/components/alerts/AlertNotes.tsx +185 -0
- package/src/components/alerts/AlertTimeline.tsx +79 -0
- package/src/components/alerts/ContextSection.tsx +155 -0
- package/src/components/app-sidebar.tsx +341 -0
- package/src/components/form-sections/ACHBankCard.tsx +78 -0
- package/src/components/form-sections/ACHBasicInfoCard.tsx +100 -0
- package/src/components/form-sections/ACHTransferSection.tsx +64 -0
- package/src/components/form-sections/AddressForm.tsx +94 -0
- package/src/components/form-sections/BankAddressCard.tsx +95 -0
- package/src/components/form-sections/BankingDetailsCard.tsx +46 -0
- package/src/components/form-sections/BasicInfoCard.tsx +103 -0
- package/src/components/form-sections/BasicInfoSection.tsx +34 -0
- package/src/components/form-sections/BeneficiaryAddress.tsx +19 -0
- package/src/components/form-sections/BeneficiaryCard.tsx +41 -0
- package/src/components/form-sections/BeneficiaryDomesticWire.tsx +23 -0
- package/src/components/form-sections/BusinessProfileCard.tsx +131 -0
- package/src/components/form-sections/BusinessStatusCard.tsx +53 -0
- package/src/components/form-sections/ContactInfoCard.tsx +63 -0
- package/src/components/form-sections/CounterpartyBasicInfo.tsx +101 -0
- package/src/components/form-sections/CounterpartyProfileCard.tsx +104 -0
- package/src/components/form-sections/CounterpartyRecordsCard.tsx +41 -0
- package/src/components/form-sections/IntermediaryCard.tsx +77 -0
- package/src/components/form-sections/IntermediaryFI.tsx +41 -0
- package/src/components/form-sections/IntermediaryFIAddress.tsx +14 -0
- package/src/components/form-sections/OriginatorCard.tsx +49 -0
- package/src/components/form-sections/OriginatorFI.tsx +42 -0
- package/src/components/form-sections/OriginatorFIAddress.tsx +14 -0
- package/src/components/form-sections/PaymentInformationSection.tsx +163 -0
- package/src/components/form-sections/ReceiverCard.tsx +94 -0
- package/src/components/form-sections/WireTransferSection.tsx +75 -0
- package/src/components/layouts/list-page.tsx +103 -0
- package/src/components/transaction/ACHDetailsSection.tsx +95 -0
- package/src/components/transaction/WireDetailsSection.tsx +112 -0
- package/src/components/ui/account-card.tsx +94 -0
- package/src/components/ui/badge.tsx +75 -0
- package/src/components/ui/breadcrumb.tsx +78 -0
- package/src/components/ui/business-type-badge.tsx +42 -0
- package/src/components/ui/button.tsx +56 -0
- package/src/components/ui/calendar.tsx +49 -0
- package/src/components/ui/card.tsx +223 -0
- package/src/components/ui/container.tsx +45 -0
- package/src/components/ui/counterparty-type-badge.tsx +53 -0
- package/src/components/ui/data-grid.tsx +99 -0
- package/src/components/ui/data-table.tsx +152 -0
- package/src/components/ui/detail-page-layout.tsx +83 -0
- package/src/components/ui/dialog.tsx +120 -0
- package/src/components/ui/dropdown-menu.tsx +82 -0
- package/src/components/ui/editable-form-card.tsx +106 -0
- package/src/components/ui/editable-info-field.tsx +67 -0
- package/src/components/ui/enhanced-input.tsx +78 -0
- package/src/components/ui/enhanced-select.tsx +101 -0
- package/src/components/ui/enhanced-textarea.tsx +64 -0
- package/src/components/ui/entity-card.tsx +140 -0
- package/src/components/ui/form-card.tsx +40 -0
- package/src/components/ui/form-field.tsx +50 -0
- package/src/components/ui/form-input.tsx +29 -0
- package/src/components/ui/form-provider.tsx +18 -0
- package/src/components/ui/form-section.tsx +66 -0
- package/src/components/ui/form-select.tsx +35 -0
- package/src/components/ui/info-field.tsx +36 -0
- package/src/components/ui/json-viewer.tsx +146 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/metric-card.tsx +80 -0
- package/src/components/ui/page-layout.tsx +183 -0
- package/src/components/ui/popover.tsx +29 -0
- package/src/components/ui/responsive-grid.tsx +46 -0
- package/src/components/ui/separator.tsx +31 -0
- package/src/components/ui/sheet.tsx +140 -0
- package/src/components/ui/sidebar.tsx +775 -0
- package/src/components/ui/sonner.tsx +29 -0
- package/src/components/ui/stack.tsx +77 -0
- package/src/components/ui/status-badge.tsx +68 -0
- package/src/components/ui/tabs.tsx +52 -0
- package/src/components/ui/toast.tsx +127 -0
- package/src/components/ui/toaster.tsx +33 -0
- package/src/components/ui/tooltip.tsx +28 -0
- package/src/components/ui/use-toast.ts +3 -0
- package/src/components/ui-kit/dashboard-demo.tsx +156 -0
- package/src/components/ui-kit/pattern-library.tsx +248 -0
- package/src/components/ui-kit/showcase.tsx +211 -0
- package/src/hooks/use-mobile.tsx +19 -0
- package/src/hooks/use-toast.ts +191 -0
- package/src/hooks/useEditState.ts +70 -0
- package/src/hooks/useFormWithEditState.ts +115 -0
- package/src/{styles.css → index.css} +10 -4
- package/src/lib/constants.ts +25 -0
- package/src/lib/mock-data/alert-data.ts +275 -0
- package/src/lib/mock-data/banking-data.ts +72 -0
- package/src/lib/mock-data/business-data.ts +71 -0
- package/src/lib/mock-data/counterparty-data.ts +70 -0
- package/src/lib/mock-data/index.ts +5 -0
- package/src/lib/mock-data/transaction-data.ts +283 -0
- package/src/lib/mock-data/wire-data.ts +103 -0
- package/src/lib/mock-data.tsx +180 -0
- package/src/lib/schemas/banking-schemas.ts +30 -0
- package/src/lib/schemas/business-schemas.ts +36 -0
- package/src/lib/schemas/counterparty-schemas.ts +43 -0
- package/src/lib/schemas/index.ts +5 -0
- package/src/lib/schemas/wire-schemas.ts +44 -0
- package/src/lib/utils.ts +6 -0
- package/src/main.tsx +10 -0
- package/src/pages/Cases.tsx +16 -0
- package/src/pages/Dashboard.tsx +16 -0
- package/src/pages/NotFound.tsx +27 -0
- package/src/pages/TransactionHistory.tsx +532 -0
- package/src/pages/UIKit.tsx +51 -0
- package/src/pages/alerts/AlertDetail.tsx +193 -0
- package/src/pages/alerts/Alerts.tsx +373 -0
- package/src/pages/business/Business.tsx +48 -0
- package/src/pages/business/Create.tsx +173 -0
- package/src/pages/counterparty/Create.tsx +48 -0
- package/src/pages/counterparty/DomesticWire.tsx +78 -0
- package/src/pages/counterparty/Manage.tsx +79 -0
- package/src/pages/transactions/NewTransaction.tsx +527 -0
- package/src/pages/transactions/TransactionDetail.tsx +192 -0
- package/src/vite-env.d.ts +1 -0
- package/tailwind.config.ts +124 -0
- package/tsconfig.app.json +30 -0
- package/tsconfig.json +19 -0
- package/tsconfig.node.json +22 -0
- package/vite.config.ts +22 -0
- package/dist/css/braid-ui-variables.css +0 -88
- package/dist/css/braid-ui.css +0 -4484
- package/dist/css/braid-ui.min.css +0 -1
- package/dist/index.cjs +0 -4
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -2429
- package/dist/index.d.ts +0 -2429
- package/dist/index.js +0 -4
- package/dist/index.js.map +0 -1
- package/src/styles-only.css +0 -121
- /package/{dist/braid-logo-343BOQZ2.png → src/assets/braid-logo.png} +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect } from "react"
|
|
2
|
+
|
|
3
|
+
interface UseEditStateProps {
|
|
4
|
+
initialEditing?: boolean
|
|
5
|
+
onToggleEdit?: () => void
|
|
6
|
+
onSave?: () => void | Promise<void>
|
|
7
|
+
onCancel?: () => void
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const useEditState = ({ initialEditing = false, onToggleEdit, onSave, onCancel }: UseEditStateProps) => {
|
|
11
|
+
const [localEditing, setLocalEditing] = useState(initialEditing)
|
|
12
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
13
|
+
|
|
14
|
+
// Sync local state with prop changes
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
setLocalEditing(initialEditing)
|
|
17
|
+
}, [initialEditing])
|
|
18
|
+
|
|
19
|
+
const isEditing = onToggleEdit !== undefined ? initialEditing : localEditing
|
|
20
|
+
|
|
21
|
+
const handleToggleEdit = useCallback(() => {
|
|
22
|
+
if (onToggleEdit) {
|
|
23
|
+
onToggleEdit()
|
|
24
|
+
} else {
|
|
25
|
+
setLocalEditing(prev => !prev)
|
|
26
|
+
}
|
|
27
|
+
}, [onToggleEdit])
|
|
28
|
+
|
|
29
|
+
const handleSave = useCallback(async () => {
|
|
30
|
+
setIsLoading(true)
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
if (onSave) {
|
|
34
|
+
await onSave()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Exit edit mode after successful save
|
|
38
|
+
if (onToggleEdit) {
|
|
39
|
+
onToggleEdit()
|
|
40
|
+
} else {
|
|
41
|
+
setLocalEditing(false)
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error("Save error:", error)
|
|
45
|
+
// Don't exit edit mode on error
|
|
46
|
+
} finally {
|
|
47
|
+
setIsLoading(false)
|
|
48
|
+
}
|
|
49
|
+
}, [onSave, onToggleEdit])
|
|
50
|
+
|
|
51
|
+
const handleCancel = useCallback(() => {
|
|
52
|
+
if (onCancel) {
|
|
53
|
+
onCancel()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (onToggleEdit) {
|
|
57
|
+
onToggleEdit()
|
|
58
|
+
} else {
|
|
59
|
+
setLocalEditing(false)
|
|
60
|
+
}
|
|
61
|
+
}, [onCancel, onToggleEdit])
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
isEditing,
|
|
65
|
+
isLoading,
|
|
66
|
+
handleToggleEdit,
|
|
67
|
+
handleSave,
|
|
68
|
+
handleCancel
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect } from "react"
|
|
2
|
+
import { useForm, UseFormProps, UseFormReturn, FieldValues, Path } from "react-hook-form"
|
|
3
|
+
import { zodResolver } from "@hookform/resolvers/zod"
|
|
4
|
+
import { z } from "zod"
|
|
5
|
+
|
|
6
|
+
interface UseFormWithEditStateProps<T extends FieldValues> extends UseFormProps<T> {
|
|
7
|
+
schema?: z.ZodSchema<T>
|
|
8
|
+
initialEditing?: boolean
|
|
9
|
+
onToggleEdit?: () => void
|
|
10
|
+
onSave?: (data: T) => void | Promise<void>
|
|
11
|
+
onCancel?: () => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface UseFormWithEditStateReturn<T extends FieldValues> extends UseFormReturn<T> {
|
|
15
|
+
isEditing: boolean
|
|
16
|
+
isLoading: boolean
|
|
17
|
+
handleToggleEdit: () => void
|
|
18
|
+
handleSave: () => Promise<void>
|
|
19
|
+
handleCancel: () => void
|
|
20
|
+
isFormValid: boolean
|
|
21
|
+
isDirty: boolean
|
|
22
|
+
setFieldError: (field: Path<T>, error: string) => void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const useFormWithEditState = <T extends FieldValues>({
|
|
26
|
+
schema,
|
|
27
|
+
initialEditing = false,
|
|
28
|
+
onToggleEdit,
|
|
29
|
+
onSave,
|
|
30
|
+
onCancel,
|
|
31
|
+
...formProps
|
|
32
|
+
}: UseFormWithEditStateProps<T>): UseFormWithEditStateReturn<T> => {
|
|
33
|
+
const [localEditing, setLocalEditing] = useState(initialEditing)
|
|
34
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
35
|
+
|
|
36
|
+
const form = useForm<T>({
|
|
37
|
+
...formProps,
|
|
38
|
+
resolver: schema ? zodResolver(schema) : undefined,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const { formState, reset, setError } = form
|
|
42
|
+
const { isValid, isDirty } = formState
|
|
43
|
+
|
|
44
|
+
// Sync local state with prop changes
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
setLocalEditing(initialEditing)
|
|
47
|
+
}, [initialEditing])
|
|
48
|
+
|
|
49
|
+
const isEditing = onToggleEdit !== undefined ? initialEditing : localEditing
|
|
50
|
+
|
|
51
|
+
const handleToggleEdit = useCallback(() => {
|
|
52
|
+
if (onToggleEdit) {
|
|
53
|
+
onToggleEdit()
|
|
54
|
+
} else {
|
|
55
|
+
setLocalEditing(prev => !prev)
|
|
56
|
+
}
|
|
57
|
+
}, [onToggleEdit])
|
|
58
|
+
|
|
59
|
+
const handleSave = useCallback(async () => {
|
|
60
|
+
if (!isValid) return
|
|
61
|
+
|
|
62
|
+
setIsLoading(true)
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const data = form.getValues()
|
|
66
|
+
if (onSave) {
|
|
67
|
+
await onSave(data)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Exit edit mode after successful save
|
|
71
|
+
if (onToggleEdit) {
|
|
72
|
+
onToggleEdit()
|
|
73
|
+
} else {
|
|
74
|
+
setLocalEditing(false)
|
|
75
|
+
}
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error("Form save error:", error)
|
|
78
|
+
// Don't exit edit mode on error
|
|
79
|
+
} finally {
|
|
80
|
+
setIsLoading(false)
|
|
81
|
+
}
|
|
82
|
+
}, [form, isValid, onSave, onToggleEdit])
|
|
83
|
+
|
|
84
|
+
const handleCancel = useCallback(() => {
|
|
85
|
+
// Reset form to original values
|
|
86
|
+
reset()
|
|
87
|
+
|
|
88
|
+
if (onCancel) {
|
|
89
|
+
onCancel()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Exit edit mode
|
|
93
|
+
if (onToggleEdit) {
|
|
94
|
+
onToggleEdit()
|
|
95
|
+
} else {
|
|
96
|
+
setLocalEditing(false)
|
|
97
|
+
}
|
|
98
|
+
}, [reset, onCancel, onToggleEdit])
|
|
99
|
+
|
|
100
|
+
const setFieldError = useCallback((field: Path<T>, error: string) => {
|
|
101
|
+
setError(field, { type: "manual", message: error })
|
|
102
|
+
}, [setError])
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
...form,
|
|
106
|
+
isEditing,
|
|
107
|
+
isLoading,
|
|
108
|
+
handleToggleEdit,
|
|
109
|
+
handleSave,
|
|
110
|
+
handleCancel,
|
|
111
|
+
isFormValid: isValid,
|
|
112
|
+
isDirty,
|
|
113
|
+
setFieldError,
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -65,12 +65,19 @@ All colors MUST be HSL.
|
|
|
65
65
|
--radius: 0.5rem;
|
|
66
66
|
|
|
67
67
|
--sidebar-background: 0 0% 98%;
|
|
68
|
+
|
|
68
69
|
--sidebar-foreground: 240 5.3% 26.1%;
|
|
70
|
+
|
|
69
71
|
--sidebar-primary: 240 5.9% 10%;
|
|
72
|
+
|
|
70
73
|
--sidebar-primary-foreground: 0 0% 98%;
|
|
74
|
+
|
|
71
75
|
--sidebar-accent: 240 4.8% 95.9%;
|
|
76
|
+
|
|
72
77
|
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
78
|
+
|
|
73
79
|
--sidebar-border: 220 13% 91%;
|
|
80
|
+
|
|
74
81
|
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
75
82
|
}
|
|
76
83
|
|
|
@@ -115,11 +122,10 @@ All colors MUST be HSL.
|
|
|
115
122
|
|
|
116
123
|
@layer base {
|
|
117
124
|
* {
|
|
118
|
-
border-
|
|
125
|
+
@apply border-border;
|
|
119
126
|
}
|
|
120
127
|
|
|
121
128
|
body {
|
|
122
|
-
background-
|
|
123
|
-
color: hsl(var(--foreground));
|
|
129
|
+
@apply bg-background text-foreground;
|
|
124
130
|
}
|
|
125
|
-
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Shared constants for form options across the application
|
|
2
|
+
|
|
3
|
+
export const COUNTRY_OPTIONS = [
|
|
4
|
+
{ value: "US", label: "United States" },
|
|
5
|
+
{ value: "CA", label: "Canada" },
|
|
6
|
+
{ value: "GB", label: "United Kingdom" },
|
|
7
|
+
{ value: "DE", label: "Germany" },
|
|
8
|
+
{ value: "FR", label: "France" }
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
export const FI_ID_TYPE_OPTIONS = [
|
|
12
|
+
{ value: "bic", label: "BIC" },
|
|
13
|
+
{ value: "swift", label: "SWIFT" },
|
|
14
|
+
{ value: "aba", label: "ABA" },
|
|
15
|
+
{ value: "iban", label: "IBAN" },
|
|
16
|
+
{ value: "routing", label: "Routing Number" }
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
export const ADDRESS_TYPE_OPTIONS = {
|
|
20
|
+
FI: [
|
|
21
|
+
{ value: "headquarters", label: "Headquarters" },
|
|
22
|
+
{ value: "branch", label: "Branch Office" },
|
|
23
|
+
{ value: "correspondent", label: "Correspondent Bank" }
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
export interface TimelineEvent {
|
|
2
|
+
id: string
|
|
3
|
+
timestamp: string
|
|
4
|
+
user: string
|
|
5
|
+
action: string
|
|
6
|
+
details?: string
|
|
7
|
+
status?: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface AlertNote {
|
|
11
|
+
id: string
|
|
12
|
+
timestamp: string
|
|
13
|
+
user: string
|
|
14
|
+
content: string
|
|
15
|
+
type: "RFI Note" | "Internal Note"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AlertDocument {
|
|
19
|
+
id: string
|
|
20
|
+
name: string
|
|
21
|
+
type: string
|
|
22
|
+
description?: string
|
|
23
|
+
size: string
|
|
24
|
+
uploadedBy: string
|
|
25
|
+
uploadedAt: string
|
|
26
|
+
url?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface Alert {
|
|
30
|
+
id: string
|
|
31
|
+
createdAt: string
|
|
32
|
+
type: string
|
|
33
|
+
status: "Unassigned" | "Closed" | "In Progress"
|
|
34
|
+
contextType: string
|
|
35
|
+
rfiStatus?: "Completed" | "Provided" | "Pending"
|
|
36
|
+
description: string
|
|
37
|
+
contextId?: string
|
|
38
|
+
assignee?: string
|
|
39
|
+
timeline?: TimelineEvent[]
|
|
40
|
+
notes?: AlertNote[]
|
|
41
|
+
documents?: AlertDocument[]
|
|
42
|
+
contextData?: any
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const mockAlerts: Alert[] = [
|
|
46
|
+
{
|
|
47
|
+
id: "4402",
|
|
48
|
+
createdAt: "2025-09-30 03:00:21",
|
|
49
|
+
type: "Ofac",
|
|
50
|
+
status: "Unassigned",
|
|
51
|
+
contextType: "Ofac",
|
|
52
|
+
description: "INDIVIDUAL: ali hassan is flagged for OFAC",
|
|
53
|
+
timeline: [
|
|
54
|
+
{ id: "1", timestamp: "2025-09-30 03:00:21", user: "System", action: "Alert Created", status: "Unassigned" },
|
|
55
|
+
{ id: "2", timestamp: "2025-09-30 09:15:32", user: "John Smith", action: "Alert Assigned", details: "Assigned to compliance team", status: "In Progress" }
|
|
56
|
+
],
|
|
57
|
+
notes: [
|
|
58
|
+
{ id: "1", timestamp: "2025-09-30 10:22:15", user: "John Smith", content: "Reviewing OFAC match. Need to verify identity documents.", type: "RFI Note" },
|
|
59
|
+
{ id: "2", timestamp: "2025-09-30 11:45:30", user: "Sarah Johnson", content: "Requested additional documentation from customer. Passport and proof of address needed.", type: "RFI Note" },
|
|
60
|
+
{ id: "3", timestamp: "2025-09-30 14:20:45", user: "John Smith", content: "Customer responded with requested documents. Passport appears valid, reviewing address verification now.", type: "Internal Note" },
|
|
61
|
+
{ id: "4", timestamp: "2025-10-01 09:10:00", user: "Michael Chen", content: "Cross-referenced with internal records. Customer has been with us for 5 years with no prior issues. Match appears to be false positive due to common name.", type: "Internal Note" }
|
|
62
|
+
],
|
|
63
|
+
documents: [
|
|
64
|
+
{
|
|
65
|
+
id: "1",
|
|
66
|
+
name: "passport_scan.pdf",
|
|
67
|
+
type: "ID Verification",
|
|
68
|
+
description: "Customer passport for identity verification",
|
|
69
|
+
size: "2.4 MB",
|
|
70
|
+
uploadedBy: "John Smith",
|
|
71
|
+
uploadedAt: "2025-09-30 10:25:00",
|
|
72
|
+
url: "/placeholder.svg"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: "2",
|
|
76
|
+
name: "proof_of_address.jpg",
|
|
77
|
+
type: "Proof of Address",
|
|
78
|
+
description: "Utility bill showing current residential address",
|
|
79
|
+
size: "1.8 MB",
|
|
80
|
+
uploadedBy: "Sarah Johnson",
|
|
81
|
+
uploadedAt: "2025-09-30 11:50:00",
|
|
82
|
+
url: "/placeholder.svg"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
contextData: {
|
|
86
|
+
entityName: "Ali Hassan",
|
|
87
|
+
entityType: "Individual",
|
|
88
|
+
matchScore: "95%",
|
|
89
|
+
listName: "OFAC SDN List",
|
|
90
|
+
flaggedItems: [
|
|
91
|
+
{ field: "Name", value: "Ali Hassan", matchScore: "95%" },
|
|
92
|
+
{ field: "DOB", value: "1985-03-12", matchScore: "100%" }
|
|
93
|
+
],
|
|
94
|
+
sdns: [
|
|
95
|
+
{
|
|
96
|
+
uid: 12345,
|
|
97
|
+
firstName: "Ali",
|
|
98
|
+
lastName: "Hassan",
|
|
99
|
+
sdnType: "Individual",
|
|
100
|
+
programs: ["SYRIA", "SDGT"],
|
|
101
|
+
title: "Military Commander",
|
|
102
|
+
remarks: "DOB 12 Mar 1985; POB Damascus, Syria; Passport D1234567 (Syria); alt. Passport E7654321 (Lebanon); Linked to Entity XYZ",
|
|
103
|
+
nationalities: ["Syria", "Lebanon"],
|
|
104
|
+
citizenships: ["Syria"],
|
|
105
|
+
dateOfBirthList: [
|
|
106
|
+
{ dateOfBirth: "1985-03-12", mainEntry: true },
|
|
107
|
+
{ dateOfBirth: "1985-03-15", mainEntry: false }
|
|
108
|
+
],
|
|
109
|
+
placeOfBirthList: [
|
|
110
|
+
{ placeOfBirth: "Damascus, Syria", mainEntry: true },
|
|
111
|
+
{ placeOfBirth: "Aleppo, Syria", mainEntry: false }
|
|
112
|
+
],
|
|
113
|
+
akaList: [
|
|
114
|
+
{ category: "strong", firstName: "Ali", lastName: "Al-Hassan" },
|
|
115
|
+
{ category: "weak", firstName: "Ali", lastName: "Hasan" },
|
|
116
|
+
{ category: "strong", firstName: "Ali Hassan", lastName: "Mohamed" }
|
|
117
|
+
],
|
|
118
|
+
idList: [
|
|
119
|
+
{ idType: "Passport", idNumber: "D1234567", idCountry: "Syria", issueDate: "2010-01-15", expirationDate: "2020-01-15" },
|
|
120
|
+
{ idType: "Passport", idNumber: "E7654321", idCountry: "Lebanon", issueDate: "2015-06-20", expirationDate: "2025-06-20" },
|
|
121
|
+
{ idType: "National ID", idNumber: "SY123456789", idCountry: "Syria" }
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
addresses: [
|
|
126
|
+
{
|
|
127
|
+
uid: 67890,
|
|
128
|
+
address1: "Building 42, Al-Mazzeh",
|
|
129
|
+
city: "Damascus",
|
|
130
|
+
stateOrProvince: "Damascus Governorate",
|
|
131
|
+
postalCode: "12345",
|
|
132
|
+
country: "Syria",
|
|
133
|
+
addressRemarks: "Primary Residence"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
uid: 67891,
|
|
137
|
+
address1: "Apartment 15, Hamra Street",
|
|
138
|
+
city: "Beirut",
|
|
139
|
+
country: "Lebanon",
|
|
140
|
+
addressRemarks: "Secondary Address"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
uid: 67892,
|
|
144
|
+
address1: "Office 203, Business District",
|
|
145
|
+
city: "Aleppo",
|
|
146
|
+
stateOrProvince: "Aleppo Governorate",
|
|
147
|
+
country: "Syria",
|
|
148
|
+
addressRemarks: "Business Address - Suspected Front Company"
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
alt_names: [
|
|
152
|
+
{ uid: 54321, type: "aka", category: "strong", firstName: "Ali", lastName: "Al-Hassan" },
|
|
153
|
+
{ uid: 54322, type: "aka", category: "weak", firstName: "Ali", lastName: "Hasan" },
|
|
154
|
+
{ uid: 54323, type: "aka", category: "strong", firstName: "Ali Hassan", lastName: "Mohamed" },
|
|
155
|
+
{ uid: 54324, type: "fka", category: "weak", firstName: "Ali", lastName: "Hassani" }
|
|
156
|
+
],
|
|
157
|
+
sanctions_entries: [
|
|
158
|
+
{
|
|
159
|
+
program: "SYRIA",
|
|
160
|
+
effectiveDate: "2015-03-15",
|
|
161
|
+
authority: "Executive Order 13572",
|
|
162
|
+
legalBasis: "Involvement in human rights abuses in Syria"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
program: "SDGT",
|
|
166
|
+
effectiveDate: "2016-08-22",
|
|
167
|
+
authority: "Executive Order 13224",
|
|
168
|
+
legalBasis: "Specially Designated Global Terrorist"
|
|
169
|
+
}
|
|
170
|
+
],
|
|
171
|
+
associated_entities: [
|
|
172
|
+
{
|
|
173
|
+
entityName: "XYZ Trading Company",
|
|
174
|
+
relationship: "Director",
|
|
175
|
+
entityType: "Business"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
entityName: "Hassan Family Trust",
|
|
179
|
+
relationship: "Beneficiary",
|
|
180
|
+
entityType: "Trust"
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
screening_metadata: {
|
|
184
|
+
screenedAt: "2025-09-30T03:00:21Z",
|
|
185
|
+
screeningEngine: "OFAC Advanced Matcher v3.2",
|
|
186
|
+
datasetVersion: "2025-09-25",
|
|
187
|
+
totalRecordsScreened: 1,
|
|
188
|
+
matchAlgorithm: "Fuzzy + Phonetic",
|
|
189
|
+
confidenceThreshold: 0.85
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
id: "4401",
|
|
195
|
+
createdAt: "2025-09-29 15:00:45",
|
|
196
|
+
type: "Ofac",
|
|
197
|
+
status: "Closed",
|
|
198
|
+
contextType: "Ofac",
|
|
199
|
+
description: "INDIVIDUAL: ali hassan is flagged for OFAC"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
id: "4400",
|
|
203
|
+
createdAt: "2025-09-27 03:02:34",
|
|
204
|
+
type: "Ofac",
|
|
205
|
+
status: "Unassigned",
|
|
206
|
+
contextType: "Ofac",
|
|
207
|
+
description: "BUSINESS: Randy is flagged for OFAC"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
id: "4399",
|
|
211
|
+
createdAt: "2025-09-27 03:02:31",
|
|
212
|
+
type: "Ofac",
|
|
213
|
+
status: "Unassigned",
|
|
214
|
+
contextType: "Ofac",
|
|
215
|
+
description: "BUSINESS: test is flagged for OFAC"
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
id: "4398",
|
|
219
|
+
createdAt: "2025-09-24 10:01:58",
|
|
220
|
+
type: "Transaction Processing Error",
|
|
221
|
+
status: "Unassigned",
|
|
222
|
+
contextType: "File Record",
|
|
223
|
+
description: "Inbound WIRE for $100,000.00 can not be processed. Exception: incorrect account..."
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
id: "4397",
|
|
227
|
+
createdAt: "2025-09-22 20:33:59",
|
|
228
|
+
type: "Dual Approval",
|
|
229
|
+
status: "Unassigned",
|
|
230
|
+
contextType: "Transaction",
|
|
231
|
+
description: "Debit adjustment for $20.00 for account number 84804949"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
id: "4396",
|
|
235
|
+
createdAt: "2025-09-22 20:33:12",
|
|
236
|
+
type: "Transaction Monitoring",
|
|
237
|
+
status: "Unassigned",
|
|
238
|
+
contextType: "Transaction",
|
|
239
|
+
description: "Transaction WIRE_INTERNATIONAL_DEBIT of $3,000.00 is flagged for velocity li..."
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
id: "4395",
|
|
243
|
+
createdAt: "2025-09-13 03:02:29",
|
|
244
|
+
type: "Ofac",
|
|
245
|
+
status: "Closed",
|
|
246
|
+
contextType: "Ofac",
|
|
247
|
+
rfiStatus: "Completed",
|
|
248
|
+
description: "BUSINESS: test is flagged for OFAC"
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
id: "4394",
|
|
252
|
+
createdAt: "2025-09-11 07:46:28",
|
|
253
|
+
type: "Dual Approval",
|
|
254
|
+
status: "Closed",
|
|
255
|
+
contextType: "Product",
|
|
256
|
+
description: "Product 2787 is set for deactivation"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
id: "4393",
|
|
260
|
+
createdAt: "2025-09-11 07:46:17",
|
|
261
|
+
type: "Dual Approval",
|
|
262
|
+
status: "Unassigned",
|
|
263
|
+
contextType: "Product",
|
|
264
|
+
description: "Product 2787 is set for deactivation"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
id: "4392",
|
|
268
|
+
createdAt: "2025-09-10 14:44:46",
|
|
269
|
+
type: "Transaction Monitoring",
|
|
270
|
+
status: "Closed",
|
|
271
|
+
contextType: "Transaction",
|
|
272
|
+
rfiStatus: "Provided",
|
|
273
|
+
description: "Transaction WIRE_DOMESTIC_CREDIT of $30,000.00 is flagged for velocity limit ..."
|
|
274
|
+
}
|
|
275
|
+
]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export interface ACHBasicInfo {
|
|
2
|
+
bankName: string
|
|
3
|
+
accountType: string
|
|
4
|
+
routingNumber: string
|
|
5
|
+
accountNumber: string
|
|
6
|
+
countryCode: string
|
|
7
|
+
status: string
|
|
8
|
+
swiftCode?: string
|
|
9
|
+
bankAddress?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ACHBankDetails {
|
|
13
|
+
gatewayRoutingNumber: string
|
|
14
|
+
rdfiNumberQualifier: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface BankAddress {
|
|
18
|
+
street: string
|
|
19
|
+
city: string
|
|
20
|
+
state: string
|
|
21
|
+
postalCode: string
|
|
22
|
+
country: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface BankingDetails {
|
|
26
|
+
primaryBank: string
|
|
27
|
+
accountNumber: string
|
|
28
|
+
routingNumber: string
|
|
29
|
+
accountType: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const defaultACHBasicInfo: ACHBasicInfo = {
|
|
33
|
+
bankName: "Bank of New York",
|
|
34
|
+
accountType: "checking",
|
|
35
|
+
routingNumber: "043087080",
|
|
36
|
+
accountNumber: "1234567890",
|
|
37
|
+
countryCode: "US",
|
|
38
|
+
status: "active",
|
|
39
|
+
swiftCode: "CHASUS33",
|
|
40
|
+
bankAddress: "270 Park Avenue, New York, NY 10017"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const defaultACHBankDetails: ACHBankDetails = {
|
|
44
|
+
gatewayRoutingNumber: "043087080",
|
|
45
|
+
rdfiNumberQualifier: "01"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const defaultBankAddress: BankAddress = {
|
|
49
|
+
street: "270 Park Avenue",
|
|
50
|
+
city: "New York",
|
|
51
|
+
state: "NY",
|
|
52
|
+
postalCode: "10017",
|
|
53
|
+
country: "US"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const defaultBankingDetails: BankingDetails = {
|
|
57
|
+
primaryBank: "JPMorgan Chase",
|
|
58
|
+
accountNumber: "****-****-****-1234",
|
|
59
|
+
routingNumber: "021000021",
|
|
60
|
+
accountType: "Business Checking"
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Combined ACH Transfer data that matches the schema
|
|
64
|
+
export const defaultACHTransfer = {
|
|
65
|
+
basicInfo: {
|
|
66
|
+
counterpartyName: "Acme Corporation",
|
|
67
|
+
shortName: "ACME",
|
|
68
|
+
type: "business",
|
|
69
|
+
description: "ACH transfer for Acme Corporation"
|
|
70
|
+
},
|
|
71
|
+
bankDetails: defaultACHBankDetails
|
|
72
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export interface BusinessProfile {
|
|
2
|
+
legalName: string
|
|
3
|
+
dbaName?: string
|
|
4
|
+
businessType: string
|
|
5
|
+
taxId: string
|
|
6
|
+
businessPhone: string
|
|
7
|
+
businessEmail: string
|
|
8
|
+
website?: string
|
|
9
|
+
address: {
|
|
10
|
+
streetAddress: string
|
|
11
|
+
apartment?: string
|
|
12
|
+
city: string
|
|
13
|
+
state: string
|
|
14
|
+
postalCode: string
|
|
15
|
+
country: string
|
|
16
|
+
addressType?: string
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface BusinessStatus {
|
|
21
|
+
operationalStatus: string
|
|
22
|
+
complianceStatus: string
|
|
23
|
+
lastReview: string
|
|
24
|
+
nextReview: string
|
|
25
|
+
riskLevel: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ContactInfo {
|
|
29
|
+
primaryContact: string
|
|
30
|
+
email: string
|
|
31
|
+
phone: string
|
|
32
|
+
alternateContact?: string
|
|
33
|
+
alternateEmail?: string
|
|
34
|
+
alternatePhone?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const defaultBusinessProfile: BusinessProfile = {
|
|
38
|
+
legalName: "Acme Corporation",
|
|
39
|
+
dbaName: "ACME Tech",
|
|
40
|
+
businessType: "corporation",
|
|
41
|
+
taxId: "12-3456789",
|
|
42
|
+
businessPhone: "+1 (555) 123-4567",
|
|
43
|
+
businessEmail: "contact@acme.com",
|
|
44
|
+
website: "https://acme.com",
|
|
45
|
+
address: {
|
|
46
|
+
streetAddress: "123 Business Avenue",
|
|
47
|
+
apartment: "Suite 100",
|
|
48
|
+
city: "New York",
|
|
49
|
+
state: "NY",
|
|
50
|
+
postalCode: "10001",
|
|
51
|
+
country: "US",
|
|
52
|
+
addressType: "business"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const defaultBusinessStatus: BusinessStatus = {
|
|
57
|
+
operationalStatus: "active",
|
|
58
|
+
complianceStatus: "compliant",
|
|
59
|
+
lastReview: "2024-01-15",
|
|
60
|
+
nextReview: "2024-07-15",
|
|
61
|
+
riskLevel: "low"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const defaultContactInfo: ContactInfo = {
|
|
65
|
+
primaryContact: "John Smith",
|
|
66
|
+
email: "john.smith@acme.com",
|
|
67
|
+
phone: "+1 (555) 123-4567",
|
|
68
|
+
alternateContact: "Jane Doe",
|
|
69
|
+
alternateEmail: "jane.doe@acme.com",
|
|
70
|
+
alternatePhone: "+1 (555) 987-6543"
|
|
71
|
+
}
|