braid-ui 1.0.98 → 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.
Files changed (145) hide show
  1. package/README.md +44 -327
  2. package/components.json +20 -0
  3. package/eslint.config.js +29 -0
  4. package/index.html +24 -0
  5. package/package.json +55 -115
  6. package/postcss.config.js +6 -0
  7. package/public/favicon.ico +0 -0
  8. package/public/placeholder.svg +1 -0
  9. package/public/robots.txt +14 -0
  10. package/src/App.css +42 -0
  11. package/src/App.tsx +94 -0
  12. package/src/components/MainLayout.tsx +15 -0
  13. package/src/components/alerts/AlertDocuments.tsx +320 -0
  14. package/src/components/alerts/AlertNotes.tsx +185 -0
  15. package/src/components/alerts/AlertTimeline.tsx +79 -0
  16. package/src/components/alerts/ContextSection.tsx +155 -0
  17. package/src/components/app-sidebar.tsx +341 -0
  18. package/src/components/form-sections/ACHBankCard.tsx +78 -0
  19. package/src/components/form-sections/ACHBasicInfoCard.tsx +100 -0
  20. package/src/components/form-sections/ACHTransferSection.tsx +64 -0
  21. package/src/components/form-sections/AddressForm.tsx +94 -0
  22. package/src/components/form-sections/BankAddressCard.tsx +95 -0
  23. package/src/components/form-sections/BankingDetailsCard.tsx +46 -0
  24. package/src/components/form-sections/BasicInfoCard.tsx +103 -0
  25. package/src/components/form-sections/BasicInfoSection.tsx +34 -0
  26. package/src/components/form-sections/BeneficiaryAddress.tsx +19 -0
  27. package/src/components/form-sections/BeneficiaryCard.tsx +41 -0
  28. package/src/components/form-sections/BeneficiaryDomesticWire.tsx +23 -0
  29. package/src/components/form-sections/BusinessProfileCard.tsx +131 -0
  30. package/src/components/form-sections/BusinessStatusCard.tsx +53 -0
  31. package/src/components/form-sections/ContactInfoCard.tsx +63 -0
  32. package/src/components/form-sections/CounterpartyBasicInfo.tsx +101 -0
  33. package/src/components/form-sections/CounterpartyProfileCard.tsx +104 -0
  34. package/src/components/form-sections/CounterpartyRecordsCard.tsx +41 -0
  35. package/src/components/form-sections/IntermediaryCard.tsx +77 -0
  36. package/src/components/form-sections/IntermediaryFI.tsx +41 -0
  37. package/src/components/form-sections/IntermediaryFIAddress.tsx +14 -0
  38. package/src/components/form-sections/OriginatorCard.tsx +49 -0
  39. package/src/components/form-sections/OriginatorFI.tsx +42 -0
  40. package/src/components/form-sections/OriginatorFIAddress.tsx +14 -0
  41. package/src/components/form-sections/PaymentInformationSection.tsx +163 -0
  42. package/src/components/form-sections/ReceiverCard.tsx +94 -0
  43. package/src/components/form-sections/WireTransferSection.tsx +75 -0
  44. package/src/components/layouts/list-page.tsx +103 -0
  45. package/src/components/transaction/ACHDetailsSection.tsx +95 -0
  46. package/src/components/transaction/WireDetailsSection.tsx +112 -0
  47. package/src/components/ui/account-card.tsx +94 -0
  48. package/src/components/ui/badge.tsx +75 -0
  49. package/src/components/ui/breadcrumb.tsx +78 -0
  50. package/src/components/ui/business-type-badge.tsx +42 -0
  51. package/src/components/ui/button.tsx +56 -0
  52. package/src/components/ui/calendar.tsx +49 -0
  53. package/src/components/ui/card.tsx +223 -0
  54. package/src/components/ui/container.tsx +45 -0
  55. package/src/components/ui/counterparty-type-badge.tsx +53 -0
  56. package/src/components/ui/data-grid.tsx +99 -0
  57. package/src/components/ui/data-table.tsx +152 -0
  58. package/src/components/ui/detail-page-layout.tsx +83 -0
  59. package/src/components/ui/dialog.tsx +120 -0
  60. package/src/components/ui/dropdown-menu.tsx +82 -0
  61. package/src/components/ui/editable-form-card.tsx +106 -0
  62. package/src/components/ui/editable-info-field.tsx +67 -0
  63. package/src/components/ui/enhanced-input.tsx +78 -0
  64. package/src/components/ui/enhanced-select.tsx +101 -0
  65. package/src/components/ui/enhanced-textarea.tsx +64 -0
  66. package/src/components/ui/entity-card.tsx +140 -0
  67. package/src/components/ui/form-card.tsx +40 -0
  68. package/src/components/ui/form-field.tsx +50 -0
  69. package/src/components/ui/form-input.tsx +29 -0
  70. package/src/components/ui/form-provider.tsx +18 -0
  71. package/src/components/ui/form-section.tsx +66 -0
  72. package/src/components/ui/form-select.tsx +35 -0
  73. package/src/components/ui/info-field.tsx +36 -0
  74. package/src/components/ui/json-viewer.tsx +146 -0
  75. package/src/components/ui/label.tsx +24 -0
  76. package/src/components/ui/metric-card.tsx +80 -0
  77. package/src/components/ui/page-layout.tsx +183 -0
  78. package/src/components/ui/popover.tsx +29 -0
  79. package/src/components/ui/responsive-grid.tsx +46 -0
  80. package/src/components/ui/separator.tsx +31 -0
  81. package/src/components/ui/sheet.tsx +140 -0
  82. package/src/components/ui/sidebar.tsx +775 -0
  83. package/src/components/ui/sonner.tsx +29 -0
  84. package/src/components/ui/stack.tsx +77 -0
  85. package/src/components/ui/status-badge.tsx +68 -0
  86. package/src/components/ui/tabs.tsx +52 -0
  87. package/src/components/ui/toast.tsx +127 -0
  88. package/src/components/ui/toaster.tsx +33 -0
  89. package/src/components/ui/tooltip.tsx +28 -0
  90. package/src/components/ui/use-toast.ts +3 -0
  91. package/src/components/ui-kit/dashboard-demo.tsx +156 -0
  92. package/src/components/ui-kit/pattern-library.tsx +248 -0
  93. package/src/components/ui-kit/showcase.tsx +211 -0
  94. package/src/hooks/use-mobile.tsx +19 -0
  95. package/src/hooks/use-toast.ts +191 -0
  96. package/src/hooks/useEditState.ts +70 -0
  97. package/src/hooks/useFormWithEditState.ts +115 -0
  98. package/src/{styles.css → index.css} +10 -4
  99. package/src/lib/constants.ts +25 -0
  100. package/src/lib/mock-data/alert-data.ts +275 -0
  101. package/src/lib/mock-data/banking-data.ts +72 -0
  102. package/src/lib/mock-data/business-data.ts +71 -0
  103. package/src/lib/mock-data/counterparty-data.ts +70 -0
  104. package/src/lib/mock-data/index.ts +5 -0
  105. package/src/lib/mock-data/transaction-data.ts +283 -0
  106. package/src/lib/mock-data/wire-data.ts +103 -0
  107. package/src/lib/mock-data.tsx +180 -0
  108. package/src/lib/schemas/banking-schemas.ts +30 -0
  109. package/src/lib/schemas/business-schemas.ts +36 -0
  110. package/src/lib/schemas/counterparty-schemas.ts +43 -0
  111. package/src/lib/schemas/index.ts +5 -0
  112. package/src/lib/schemas/wire-schemas.ts +44 -0
  113. package/src/lib/utils.ts +6 -0
  114. package/src/main.tsx +10 -0
  115. package/src/pages/Cases.tsx +16 -0
  116. package/src/pages/Dashboard.tsx +16 -0
  117. package/src/pages/NotFound.tsx +27 -0
  118. package/src/pages/TransactionHistory.tsx +532 -0
  119. package/src/pages/UIKit.tsx +51 -0
  120. package/src/pages/alerts/AlertDetail.tsx +193 -0
  121. package/src/pages/alerts/Alerts.tsx +373 -0
  122. package/src/pages/business/Business.tsx +48 -0
  123. package/src/pages/business/Create.tsx +173 -0
  124. package/src/pages/counterparty/Create.tsx +48 -0
  125. package/src/pages/counterparty/DomesticWire.tsx +78 -0
  126. package/src/pages/counterparty/Manage.tsx +79 -0
  127. package/src/pages/transactions/NewTransaction.tsx +527 -0
  128. package/src/pages/transactions/TransactionDetail.tsx +192 -0
  129. package/src/vite-env.d.ts +1 -0
  130. package/tailwind.config.ts +124 -0
  131. package/tsconfig.app.json +30 -0
  132. package/tsconfig.json +19 -0
  133. package/tsconfig.node.json +22 -0
  134. package/vite.config.ts +22 -0
  135. package/dist/css/braid-ui-variables.css +0 -88
  136. package/dist/css/braid-ui.css +0 -4484
  137. package/dist/css/braid-ui.min.css +0 -1
  138. package/dist/index.cjs +0 -4
  139. package/dist/index.cjs.map +0 -1
  140. package/dist/index.d.cts +0 -2429
  141. package/dist/index.d.ts +0 -2429
  142. package/dist/index.js +0 -4
  143. package/dist/index.js.map +0 -1
  144. package/src/styles-only.css +0 -121
  145. /package/{dist/braid-logo-343BOQZ2.png → src/assets/braid-logo.png} +0 -0
@@ -0,0 +1,131 @@
1
+ import { EditableFormCard } from "@/components/ui/editable-form-card"
2
+ import { InfoField } from "@/components/ui/info-field"
3
+ import { FormProvider } from "@/components/ui/form-provider"
4
+ import { FormInput } from "@/components/ui/form-input"
5
+ import { FormSelect } from "@/components/ui/form-select"
6
+ import { useFormWithEditState } from "@/hooks/useFormWithEditState"
7
+ import { businessProfileSchema, type BusinessProfile } from "@/lib/schemas"
8
+ import { defaultBusinessProfile } from "@/lib/mock-data/business-data"
9
+
10
+ interface BusinessProfileCardProps {
11
+ data?: Partial<BusinessProfile>
12
+ onDataChange?: (data: BusinessProfile) => void
13
+ isEditing?: boolean
14
+ onToggleEdit?: () => void
15
+ className?: string
16
+ hideActions?: boolean
17
+ }
18
+
19
+ export const BusinessProfileCard = ({
20
+ data,
21
+ onDataChange,
22
+ isEditing,
23
+ onToggleEdit,
24
+ className,
25
+ hideActions
26
+ }: BusinessProfileCardProps) => {
27
+ const form = useFormWithEditState<BusinessProfile>({
28
+ schema: businessProfileSchema,
29
+ defaultValues: { ...defaultBusinessProfile, ...data },
30
+ initialEditing: isEditing,
31
+ onToggleEdit,
32
+ onSave: onDataChange,
33
+ })
34
+
35
+ const editContent = (
36
+ <FormProvider form={form}>
37
+ <div className="space-y-6">
38
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
39
+ <FormInput
40
+ name="legalName"
41
+ label="Legal Name"
42
+ placeholder="Enter legal business name"
43
+ required
44
+ />
45
+
46
+ <FormInput
47
+ name="dbaName"
48
+ label="DBA Name"
49
+ placeholder="Enter doing business as name"
50
+ />
51
+
52
+ <FormSelect
53
+ name="businessType"
54
+ label="Business Type"
55
+ placeholder="Select business type"
56
+ options={[
57
+ { value: "corporation", label: "Corporation" },
58
+ { value: "llc", label: "LLC" },
59
+ { value: "partnership", label: "Partnership" },
60
+ { value: "sole_proprietorship", label: "Sole Proprietorship" }
61
+ ]}
62
+ />
63
+
64
+ <FormInput
65
+ name="taxId"
66
+ label="Tax ID"
67
+ placeholder="Enter tax identification number"
68
+ required
69
+ />
70
+
71
+ <FormInput
72
+ name="businessPhone"
73
+ label="Business Phone"
74
+ placeholder="Enter business phone number"
75
+ required
76
+ />
77
+
78
+ <FormInput
79
+ name="businessEmail"
80
+ label="Business Email"
81
+ type="email"
82
+ placeholder="Enter business email"
83
+ required
84
+ />
85
+
86
+ <FormInput
87
+ name="website"
88
+ label="Website"
89
+ placeholder="Enter website URL"
90
+ />
91
+ </div>
92
+ </div>
93
+ </FormProvider>
94
+ )
95
+
96
+ const formValues = form.watch()
97
+ const viewContent = (
98
+ <div className="space-y-4">
99
+ <div className="grid grid-cols-2 gap-4">
100
+ <InfoField label="Legal Name" value={formValues?.legalName} layout="horizontal" />
101
+ <InfoField label="DBA Name" value={formValues?.dbaName} layout="horizontal" />
102
+ </div>
103
+ <div className="grid grid-cols-2 gap-4">
104
+ <InfoField label="Business Type" value={formValues?.businessType} layout="horizontal" />
105
+ <InfoField label="Tax ID" value={formValues?.taxId} layout="horizontal" />
106
+ </div>
107
+ <div className="grid grid-cols-2 gap-4">
108
+ <InfoField label="Business Phone" value={formValues?.businessPhone} layout="horizontal" />
109
+ <InfoField label="Business Email" value={formValues?.businessEmail} layout="horizontal" />
110
+ </div>
111
+ <div className="grid grid-cols-2 gap-4">
112
+ <InfoField label="Website" value={formValues?.website} layout="horizontal" />
113
+ </div>
114
+ </div>
115
+ )
116
+
117
+ return (
118
+ <EditableFormCard
119
+ title="Business Profile"
120
+ variant="subtle"
121
+ className={className}
122
+ isEditing={form.isEditing}
123
+ onToggleEdit={form.handleToggleEdit}
124
+ onSave={form.handleSave}
125
+ onCancel={form.handleCancel}
126
+ hideActions={hideActions}
127
+ editContent={editContent}
128
+ viewContent={viewContent}
129
+ />
130
+ )
131
+ }
@@ -0,0 +1,53 @@
1
+ import { FormCard } from "@/components/ui/form-card"
2
+ import { InfoField } from "@/components/ui/info-field"
3
+ import { Button } from "@/components/ui/button"
4
+ import { StatusBadge } from "@/components/ui/status-badge"
5
+ import { Edit } from "lucide-react"
6
+
7
+ interface BusinessStatusCardProps {
8
+ isEditing?: boolean
9
+ onToggleEdit?: () => void
10
+ className?: string
11
+ }
12
+
13
+ export const BusinessStatusCard = ({ isEditing, onToggleEdit, className }: BusinessStatusCardProps) => {
14
+ return (
15
+ <FormCard
16
+ title="Business Status & Records"
17
+ className={className}
18
+ headerActions={
19
+ <div className="flex items-center gap-2">
20
+ {isEditing ? (
21
+ <>
22
+ <Button variant="outline" size="sm" onClick={onToggleEdit}>
23
+ Cancel
24
+ </Button>
25
+ <Button size="sm" onClick={onToggleEdit}>
26
+ Save
27
+ </Button>
28
+ </>
29
+ ) : (
30
+ <Button variant="ghost" size="icon" onClick={onToggleEdit} className="text-primary hover:text-primary/80 hover:bg-primary/10">
31
+ <Edit className="h-4 w-4" />
32
+ </Button>
33
+ )}
34
+ </div>
35
+ }
36
+ >
37
+ <div className="space-y-4">
38
+ <div className="grid grid-cols-2 gap-4">
39
+ <InfoField label="Status" value={<StatusBadge status="ACTIVE" />} layout="horizontal" />
40
+ <InfoField label="CIP Status" value="NOT_START" layout="horizontal" />
41
+ </div>
42
+ <div className="grid grid-cols-2 gap-4">
43
+ <InfoField label="Created Date" value="2025-08-03" layout="horizontal" />
44
+ <InfoField label="Updated Date" value="2025-09-05" layout="horizontal" />
45
+ </div>
46
+ <div className="grid grid-cols-2 gap-4">
47
+ <InfoField label="Last OFAC Date" value="2025-09-05" layout="horizontal" />
48
+ <InfoField label="Last OFAC Status" value="View Status" layout="horizontal" className="text-primary cursor-pointer" />
49
+ </div>
50
+ </div>
51
+ </FormCard>
52
+ )
53
+ }
@@ -0,0 +1,63 @@
1
+ import { FormCard } from "@/components/ui/form-card"
2
+ import { InfoField } from "@/components/ui/info-field"
3
+ import { Button } from "@/components/ui/button"
4
+ import { Edit } from "lucide-react"
5
+
6
+ interface ContactInfoCardProps {
7
+ isEditing?: boolean
8
+ onToggleEdit?: () => void
9
+ className?: string
10
+ }
11
+
12
+ export const ContactInfoCard = ({ isEditing, onToggleEdit, className }: ContactInfoCardProps) => {
13
+ return (
14
+ <FormCard
15
+ title="Contact Information"
16
+ className={className}
17
+ headerActions={
18
+ <div className="flex items-center gap-2">
19
+ {isEditing ? (
20
+ <>
21
+ <Button variant="outline" size="sm" onClick={onToggleEdit}>
22
+ Cancel
23
+ </Button>
24
+ <Button size="sm" onClick={onToggleEdit}>
25
+ Save
26
+ </Button>
27
+ </>
28
+ ) : (
29
+ <Button variant="ghost" size="icon" onClick={onToggleEdit} className="text-primary hover:text-primary/80 hover:bg-primary/10">
30
+ <Edit className="h-4 w-4" />
31
+ </Button>
32
+ )}
33
+ </div>
34
+ }
35
+ >
36
+ <div className="space-y-4">
37
+ <h4 className="text-sm font-medium text-muted-foreground">Contact Person</h4>
38
+ <div className="grid grid-cols-2 gap-4">
39
+ <InfoField label="First Name" value="" layout="horizontal" />
40
+ <InfoField label="Last Name" value="" layout="horizontal" />
41
+ </div>
42
+ <div className="grid grid-cols-2 gap-4">
43
+ <InfoField label="Email" value="" layout="horizontal" />
44
+ <InfoField label="Phone Number" value="" layout="horizontal" />
45
+ </div>
46
+
47
+ <h4 className="text-sm font-medium text-muted-foreground mt-6">Mailing Address</h4>
48
+ <div className="grid grid-cols-1 gap-3">
49
+ <InfoField label="Street Address" value="" layout="horizontal" />
50
+ <InfoField label="Apartment, suite, or floor" value="" layout="horizontal" />
51
+ </div>
52
+ <div className="grid grid-cols-2 gap-4">
53
+ <InfoField label="City" value="" layout="horizontal" />
54
+ <InfoField label="State" value="Alabama" layout="horizontal" />
55
+ </div>
56
+ <div className="grid grid-cols-2 gap-4">
57
+ <InfoField label="Postal Code" value="" layout="horizontal" />
58
+ <InfoField label="Country Code" value="US" layout="horizontal" />
59
+ </div>
60
+ </div>
61
+ </FormCard>
62
+ )
63
+ }
@@ -0,0 +1,101 @@
1
+ import { EnhancedInput } from "@/components/ui/enhanced-input"
2
+ import { Label } from "@/components/ui/label"
3
+ import { useState } from "react"
4
+
5
+ interface CounterpartyBasicInfoProps {
6
+ onDataChange?: (data: any) => void
7
+ }
8
+
9
+ export const CounterpartyBasicInfo = ({ onDataChange }: CounterpartyBasicInfoProps) => {
10
+ const [formData, setFormData] = useState({
11
+ name: "",
12
+ type: "business",
13
+ email: "",
14
+ phone: "",
15
+ productId: "167990"
16
+ })
17
+
18
+ const handleInputChange = (field: string, value: string) => {
19
+ const updatedData = { ...formData, [field]: value }
20
+ setFormData(updatedData)
21
+ onDataChange?.(updatedData)
22
+ }
23
+
24
+ const handleTypeChange = (type: string) => {
25
+ handleInputChange("type", type)
26
+ }
27
+
28
+ return (
29
+ <div className="space-y-6">
30
+ <div className="border-b border-border pb-4">
31
+ <h2 className="text-lg font-semibold text-foreground">Basic Information</h2>
32
+ <p className="text-sm text-muted-foreground">Enter the basic details for the counterparty</p>
33
+ </div>
34
+
35
+ <div className="space-y-6">
36
+ <EnhancedInput
37
+ label="Counterparty Name"
38
+ value={formData.name}
39
+ onChange={(e) => handleInputChange("name", e.target.value)}
40
+ placeholder="Enter counterparty name"
41
+ required
42
+ />
43
+
44
+ <div className="space-y-3">
45
+ <Label className="text-sm font-medium">Counterparty Type</Label>
46
+ <div className="flex gap-6">
47
+ <label className="flex items-center space-x-2 cursor-pointer">
48
+ <input
49
+ type="radio"
50
+ name="counterpartyType"
51
+ value="business"
52
+ checked={formData.type === "business"}
53
+ onChange={() => handleTypeChange("business")}
54
+ className="w-4 h-4 text-primary border-border focus:ring-primary focus:ring-2"
55
+ />
56
+ <span className="text-sm text-foreground">Business</span>
57
+ </label>
58
+ <label className="flex items-center space-x-2 cursor-pointer">
59
+ <input
60
+ type="radio"
61
+ name="counterpartyType"
62
+ value="individual"
63
+ checked={formData.type === "individual"}
64
+ onChange={() => handleTypeChange("individual")}
65
+ className="w-4 h-4 text-primary border-border focus:ring-primary focus:ring-2"
66
+ />
67
+ <span className="text-sm text-foreground">Individual</span>
68
+ </label>
69
+ </div>
70
+ </div>
71
+
72
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
73
+ <EnhancedInput
74
+ label="Email"
75
+ type="email"
76
+ value={formData.email}
77
+ onChange={(e) => handleInputChange("email", e.target.value)}
78
+ placeholder="Enter email address"
79
+ required
80
+ />
81
+
82
+ <EnhancedInput
83
+ label="Phone Number"
84
+ type="tel"
85
+ value={formData.phone}
86
+ onChange={(e) => handleInputChange("phone", e.target.value)}
87
+ placeholder="Enter phone number"
88
+ required
89
+ />
90
+ </div>
91
+
92
+ <EnhancedInput
93
+ label="Product ID"
94
+ value={formData.productId}
95
+ readOnly
96
+ className="bg-muted"
97
+ />
98
+ </div>
99
+ </div>
100
+ )
101
+ }
@@ -0,0 +1,104 @@
1
+ import { EditableFormCard } from "@/components/ui/editable-form-card"
2
+ import { InfoField } from "@/components/ui/info-field"
3
+ import { FormProvider } from "@/components/ui/form-provider"
4
+ import { FormInput } from "@/components/ui/form-input"
5
+ import { FormSelect } from "@/components/ui/form-select"
6
+ import { CounterpartyTypeBadge } from "@/components/ui/counterparty-type-badge"
7
+ import { StatusBadge } from "@/components/ui/status-badge"
8
+ import { useFormWithEditState } from "@/hooks/useFormWithEditState"
9
+ import { counterpartyBasicInfoSchema, type CounterpartyBasicInfo } from "@/lib/schemas"
10
+ import { defaultCounterpartyBasicInfo } from "@/lib/mock-data/counterparty-data"
11
+
12
+ interface CounterpartyProfileCardProps {
13
+ data?: Partial<CounterpartyBasicInfo>
14
+ onDataChange?: (data: CounterpartyBasicInfo) => void
15
+ isEditing?: boolean
16
+ onToggleEdit?: () => void
17
+ hideActions?: boolean
18
+ className?: string
19
+ }
20
+
21
+ export const CounterpartyProfileCard = ({
22
+ data,
23
+ onDataChange,
24
+ isEditing = false,
25
+ onToggleEdit,
26
+ hideActions = false,
27
+ className
28
+ }: CounterpartyProfileCardProps) => {
29
+ const form = useFormWithEditState<CounterpartyBasicInfo>({
30
+ schema: counterpartyBasicInfoSchema,
31
+ defaultValues: { ...defaultCounterpartyBasicInfo, ...data },
32
+ initialEditing: isEditing,
33
+ onToggleEdit,
34
+ onSave: onDataChange,
35
+ })
36
+
37
+ const editContent = (
38
+ <FormProvider form={form}>
39
+ <div className="space-y-6">
40
+ <FormInput
41
+ name="name"
42
+ label="Name"
43
+ placeholder="Enter counterparty name"
44
+ required
45
+ />
46
+
47
+ <FormSelect
48
+ name="type"
49
+ label="Counterparty Type"
50
+ placeholder="Select counterparty type"
51
+ options={[
52
+ { value: "BUSINESS", label: "Business" },
53
+ { value: "INDIVIDUAL", label: "Individual" },
54
+ { value: "GOVERNMENT", label: "Government" },
55
+ { value: "NONPROFIT", label: "Non-Profit" }
56
+ ]}
57
+ />
58
+
59
+ <FormSelect
60
+ name="status"
61
+ label="Status"
62
+ placeholder="Select status"
63
+ options={[
64
+ { value: "ACTIVE", label: "Active" },
65
+ { value: "INACTIVE", label: "Inactive" },
66
+ { value: "PENDING", label: "Pending" },
67
+ { value: "SUSPENDED", label: "Suspended" }
68
+ ]}
69
+ />
70
+
71
+ <FormInput
72
+ name="description"
73
+ label="Description"
74
+ placeholder="Enter description"
75
+ />
76
+ </div>
77
+ </FormProvider>
78
+ )
79
+
80
+ const formValues = form.watch()
81
+ const viewContent = (
82
+ <div className="space-y-3">
83
+ <InfoField label="Name" value={formValues?.name} layout="horizontal" />
84
+ <InfoField label="Counterparty Type" value={<CounterpartyTypeBadge type={formValues?.type as "BUSINESS" | "INDIVIDUAL" | "GOVERNMENT" | "NONPROFIT"} />} layout="horizontal" />
85
+ <InfoField label="Status" value={<StatusBadge status={formValues?.status as "ACTIVE" | "INACTIVE" | "PENDING" | "SUSPENDED"} />} layout="horizontal" />
86
+ <InfoField label="Description" value={formValues?.description} layout="horizontal" />
87
+ </div>
88
+ )
89
+
90
+ return (
91
+ <EditableFormCard
92
+ title="Profile Information"
93
+ variant="subtle"
94
+ className={className}
95
+ isEditing={form.isEditing}
96
+ onToggleEdit={form.handleToggleEdit}
97
+ onSave={form.handleSave}
98
+ onCancel={form.handleCancel}
99
+ hideActions={hideActions}
100
+ editContent={editContent}
101
+ viewContent={viewContent}
102
+ />
103
+ )
104
+ }
@@ -0,0 +1,41 @@
1
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
2
+ import { InfoField } from "@/components/ui/info-field"
3
+
4
+ interface CounterpartyRecordsCardProps {
5
+ isEditing?: boolean
6
+ hideActions?: boolean
7
+ className?: string
8
+ }
9
+
10
+ export const CounterpartyRecordsCard = ({
11
+ isEditing = false,
12
+ hideActions = false,
13
+ className
14
+ }: CounterpartyRecordsCardProps) => {
15
+ return (
16
+ <Card variant="subtle" className={className}>
17
+ <CardHeader size="lg">
18
+ <CardTitle size="lg">System Records</CardTitle>
19
+ </CardHeader>
20
+ <CardContent size="lg">
21
+ <div className="space-y-4">
22
+ <div className="space-y-3">
23
+ <InfoField label="ID" value="5000541" layout="horizontal" />
24
+ <InfoField label="Created By" value="admin" layout="horizontal" />
25
+ <InfoField label="Created At" value="2025-07-14" layout="horizontal" />
26
+ <InfoField label="Updated By" value="admin" layout="horizontal" />
27
+ <InfoField label="Updated At" value="2025-07-14" layout="horizontal" />
28
+ </div>
29
+
30
+ <div className="pt-3 border-t border-border">
31
+ <h4 className="text-sm font-medium text-foreground mb-2">OFAC Details</h4>
32
+ <div className="space-y-3">
33
+ <InfoField label="Last OFAC date" value="2025-07-14" layout="horizontal" />
34
+ <InfoField label="Last OFAC status" value="Verified" layout="horizontal" />
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </CardContent>
39
+ </Card>
40
+ )
41
+ }
@@ -0,0 +1,77 @@
1
+ import { EditableFormCard } from "@/components/ui/editable-form-card"
2
+ import { InfoField } from "@/components/ui/info-field"
3
+ import { FormProvider } from "@/components/ui/form-provider"
4
+ import { FormSection } from "@/components/ui/form-section"
5
+ import { IntermediaryFI } from "@/components/form-sections/IntermediaryFI"
6
+ import { IntermediaryFIAddress } from "@/components/form-sections/IntermediaryFIAddress"
7
+ import { useFormWithEditState } from "@/hooks/useFormWithEditState"
8
+ import { intermediaryFISchema, type IntermediaryFI as IntermediaryFIType } from "@/lib/schemas"
9
+ import { defaultIntermediaryFIInfo } from "@/lib/mock-data/wire-data"
10
+
11
+ interface IntermediaryCardProps {
12
+ data?: Partial<IntermediaryFIType>
13
+ onDataChange?: (data: IntermediaryFIType) => void
14
+ isEditing?: boolean
15
+ onToggleEdit?: () => void
16
+ className?: string
17
+ hideActions?: boolean
18
+ }
19
+
20
+ export const IntermediaryCard = ({
21
+ data,
22
+ onDataChange,
23
+ isEditing,
24
+ onToggleEdit,
25
+ className,
26
+ hideActions
27
+ }: IntermediaryCardProps) => {
28
+ const form = useFormWithEditState<IntermediaryFIType>({
29
+ schema: intermediaryFISchema,
30
+ defaultValues: { ...defaultIntermediaryFIInfo, ...data },
31
+ initialEditing: isEditing,
32
+ onToggleEdit,
33
+ onSave: onDataChange,
34
+ })
35
+
36
+ const editContent = (
37
+ <FormProvider form={form}>
38
+ <FormSection spacing="lg">
39
+ <IntermediaryFI />
40
+ <IntermediaryFIAddress />
41
+ </FormSection>
42
+ </FormProvider>
43
+ )
44
+
45
+ const formValues = form.watch()
46
+ const viewContent = (
47
+ <div className="space-y-3">
48
+ <div>
49
+ <h4 className="text-sm font-medium text-foreground mb-2">Financial Institution</h4>
50
+ <div className="space-y-1.5">
51
+ <InfoField label="Institution" value={`${formValues?.name} (${formValues?.accountNumber})`} layout="horizontal" />
52
+ <InfoField label="Identifier" value={`${formValues?.idType?.toUpperCase()} - ${formValues?.idNumber}`} layout="horizontal" />
53
+ </div>
54
+ </div>
55
+
56
+ <div className="pt-3 border-t border-border">
57
+ <h4 className="text-sm font-medium text-foreground mb-2">FI Address</h4>
58
+ <InfoField value={formValues?.address ? `${formValues.address.streetAddress}, ${formValues.address.city}, ${formValues.address.postalCode}, ${formValues.address.country}` : ""} />
59
+ </div>
60
+ </div>
61
+ )
62
+
63
+ return (
64
+ <EditableFormCard
65
+ title="Intermediary"
66
+ variant="subtle"
67
+ className={className}
68
+ isEditing={form.isEditing}
69
+ onToggleEdit={form.handleToggleEdit}
70
+ onSave={form.handleSave}
71
+ onCancel={form.handleCancel}
72
+ hideActions={hideActions}
73
+ editContent={editContent}
74
+ viewContent={viewContent}
75
+ />
76
+ )
77
+ }
@@ -0,0 +1,41 @@
1
+ import { EnhancedInput } from "@/components/ui/enhanced-input"
2
+ import { EnhancedSelect } from "@/components/ui/enhanced-select"
3
+ import { FI_ID_TYPE_OPTIONS } from "@/lib/constants"
4
+
5
+ export const IntermediaryFI = () => {
6
+ return (
7
+ <div className="space-y-6">
8
+ <div className="border-b border-border pb-4">
9
+ <h2 className="text-lg font-semibold text-foreground">Intermediary FI Details</h2>
10
+ <p className="text-sm text-muted-foreground">Financial institution details for the intermediary</p>
11
+ </div>
12
+
13
+ <div className="space-y-6">
14
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
15
+ <EnhancedInput
16
+ label="Intermediary FI Account Number"
17
+ placeholder="Enter account number"
18
+ />
19
+
20
+ <EnhancedInput
21
+ label="Intermediary FI Name"
22
+ placeholder="Enter FI name"
23
+ hint="Full name of the intermediary financial institution"
24
+ />
25
+
26
+ <EnhancedSelect
27
+ label="Intermediary FI ID Type"
28
+ placeholder="Select ID type"
29
+ options={FI_ID_TYPE_OPTIONS}
30
+ />
31
+
32
+ <EnhancedInput
33
+ label="Intermediary FI ID Number"
34
+ placeholder="Enter ID number"
35
+ hint="Financial institution identification number"
36
+ />
37
+ </div>
38
+ </div>
39
+ </div>
40
+ )
41
+ }
@@ -0,0 +1,14 @@
1
+ import { AddressForm } from "./AddressForm"
2
+
3
+ export const IntermediaryFIAddress = () => {
4
+ return (
5
+ <AddressForm
6
+ title="Intermediary FI Address"
7
+ description="Address of the intermediary financial institution"
8
+ fieldPrefix="Intermediary FI"
9
+ fieldOverrides={{
10
+ streetAddress: { hint: "Intermediary financial institution street address" }
11
+ }}
12
+ />
13
+ )
14
+ }
@@ -0,0 +1,49 @@
1
+ import { EditableFormCard } from "@/components/ui/editable-form-card"
2
+ import { DataGrid } from "@/components/ui/data-grid"
3
+ import { FormSection } from "@/components/ui/form-section"
4
+ import { OriginatorFI } from "@/components/form-sections/OriginatorFI"
5
+ import { OriginatorFIAddress } from "@/components/form-sections/OriginatorFIAddress"
6
+
7
+ interface OriginatorCardProps {
8
+ isEditing?: boolean
9
+ onToggleEdit?: () => void
10
+ className?: string
11
+ hideActions?: boolean
12
+ }
13
+
14
+ export const OriginatorCard = ({ isEditing, onToggleEdit, className, hideActions }: OriginatorCardProps) => {
15
+ const viewData = [
16
+ {
17
+ title: "Financial Institution",
18
+ items: [
19
+ { label: "Institution", value: "JPMorgan Chase Bank (1234567890)" },
20
+ { label: "Identifier", value: "ABA - 021000021" }
21
+ ]
22
+ },
23
+ {
24
+ title: "FI Address",
25
+ items: [
26
+ { value: "270 Park Avenue, New York, NY, 10017, United States" }
27
+ ],
28
+ className: "pt-3 border-t border-border"
29
+ }
30
+ ]
31
+
32
+ return (
33
+ <EditableFormCard
34
+ title="Originator"
35
+ variant="subtle"
36
+ className={className}
37
+ isEditing={isEditing}
38
+ onToggleEdit={onToggleEdit}
39
+ hideActions={hideActions}
40
+ editContent={
41
+ <FormSection spacing="lg">
42
+ <OriginatorFI />
43
+ <OriginatorFIAddress />
44
+ </FormSection>
45
+ }
46
+ viewContent={<DataGrid data={viewData} columns={1} />}
47
+ />
48
+ )
49
+ }