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,112 @@
|
|
|
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 { JsonViewer } from "@/components/ui/json-viewer"
|
|
5
|
+
|
|
6
|
+
interface WireDetails {
|
|
7
|
+
type: string
|
|
8
|
+
originatorName: string
|
|
9
|
+
originatorAccountNumber: string
|
|
10
|
+
originatorAddress: string
|
|
11
|
+
beneficiaryName: string
|
|
12
|
+
beneficiaryAccountNumber: string
|
|
13
|
+
beneficiaryAddress: string
|
|
14
|
+
beneficiaryFIName: string
|
|
15
|
+
beneficiaryFIRoutingNumber: string
|
|
16
|
+
beneficiaryFIAddress: string
|
|
17
|
+
originatorFIName: string
|
|
18
|
+
originatorFIRoutingNumber: string
|
|
19
|
+
originatorFIAddress: string
|
|
20
|
+
intermediaryFIName?: string
|
|
21
|
+
intermediaryFIRoutingNumber?: string
|
|
22
|
+
intermediaryFIAddress?: string
|
|
23
|
+
raw?: any
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface WireDetailsSectionProps {
|
|
27
|
+
data: WireDetails
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const WireDetailsSection = ({ data }: WireDetailsSectionProps) => {
|
|
31
|
+
return (
|
|
32
|
+
<FormCard title="Wire Transfer Details">
|
|
33
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-x-8 gap-y-4">
|
|
34
|
+
<InfoField label="Type" value={data.type} layout="horizontal" />
|
|
35
|
+
<InfoField label="Originator Name" value={data.originatorName} layout="horizontal" />
|
|
36
|
+
<InfoField
|
|
37
|
+
label="Originator Account Number"
|
|
38
|
+
value={
|
|
39
|
+
<Button variant="link" className="h-auto p-0 text-sm">
|
|
40
|
+
{data.originatorAccountNumber}
|
|
41
|
+
</Button>
|
|
42
|
+
}
|
|
43
|
+
layout="horizontal"
|
|
44
|
+
/>
|
|
45
|
+
<InfoField label="Originator Address" value={data.originatorAddress} layout="horizontal" />
|
|
46
|
+
<InfoField label="Beneficiary Name" value={data.beneficiaryName} layout="horizontal" />
|
|
47
|
+
<InfoField
|
|
48
|
+
label="Beneficiary Account Number"
|
|
49
|
+
value={
|
|
50
|
+
<Button variant="link" className="h-auto p-0 text-sm">
|
|
51
|
+
{data.beneficiaryAccountNumber}
|
|
52
|
+
</Button>
|
|
53
|
+
}
|
|
54
|
+
layout="horizontal"
|
|
55
|
+
/>
|
|
56
|
+
<InfoField label="Beneficiary Address" value={data.beneficiaryAddress} layout="horizontal" />
|
|
57
|
+
<InfoField label="Beneficiary FI Name" value={data.beneficiaryFIName} layout="horizontal" />
|
|
58
|
+
<InfoField
|
|
59
|
+
label="Beneficiary FI Routing Number"
|
|
60
|
+
value={
|
|
61
|
+
<Button variant="link" className="h-auto p-0 text-sm">
|
|
62
|
+
{data.beneficiaryFIRoutingNumber}
|
|
63
|
+
</Button>
|
|
64
|
+
}
|
|
65
|
+
layout="horizontal"
|
|
66
|
+
/>
|
|
67
|
+
<InfoField label="Beneficiary FI Address" value={data.beneficiaryFIAddress} layout="horizontal" />
|
|
68
|
+
<InfoField label="Originator FI Name" value={data.originatorFIName} layout="horizontal" />
|
|
69
|
+
<InfoField
|
|
70
|
+
label="Originator FI Routing Number"
|
|
71
|
+
value={
|
|
72
|
+
<Button variant="link" className="h-auto p-0 text-sm">
|
|
73
|
+
{data.originatorFIRoutingNumber}
|
|
74
|
+
</Button>
|
|
75
|
+
}
|
|
76
|
+
layout="horizontal"
|
|
77
|
+
/>
|
|
78
|
+
<InfoField label="Originator FI Address" value={data.originatorFIAddress} layout="horizontal" />
|
|
79
|
+
|
|
80
|
+
{data.intermediaryFIName && (
|
|
81
|
+
<>
|
|
82
|
+
<InfoField label="Intermediary FI Name" value={data.intermediaryFIName} layout="horizontal" />
|
|
83
|
+
{data.intermediaryFIRoutingNumber && (
|
|
84
|
+
<InfoField
|
|
85
|
+
label="Intermediary FI Routing Number"
|
|
86
|
+
value={
|
|
87
|
+
<Button variant="link" className="h-auto p-0 text-sm">
|
|
88
|
+
{data.intermediaryFIRoutingNumber}
|
|
89
|
+
</Button>
|
|
90
|
+
}
|
|
91
|
+
layout="horizontal"
|
|
92
|
+
/>
|
|
93
|
+
)}
|
|
94
|
+
{data.intermediaryFIAddress && (
|
|
95
|
+
<InfoField label="Intermediary FI Address" value={data.intermediaryFIAddress} layout="horizontal" />
|
|
96
|
+
)}
|
|
97
|
+
</>
|
|
98
|
+
)}
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
{/* Raw JSON - Full Width */}
|
|
102
|
+
{data.raw && (
|
|
103
|
+
<div className="mt-6 pt-6 border-t border-border">
|
|
104
|
+
<InfoField
|
|
105
|
+
label="Raw"
|
|
106
|
+
value={<JsonViewer data={data.raw} className="mt-2" compact={true} />}
|
|
107
|
+
/>
|
|
108
|
+
</div>
|
|
109
|
+
)}
|
|
110
|
+
</FormCard>
|
|
111
|
+
)
|
|
112
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
|
3
|
+
import { Badge } from "@/components/ui/badge"
|
|
4
|
+
import { InfoField } from "@/components/ui/info-field"
|
|
5
|
+
import { DataGrid } from "@/components/ui/data-grid"
|
|
6
|
+
import { cn } from "@/lib/utils"
|
|
7
|
+
import { Building, CreditCard, Globe } from "lucide-react"
|
|
8
|
+
|
|
9
|
+
interface AccountCardProps {
|
|
10
|
+
account: {
|
|
11
|
+
id: string
|
|
12
|
+
name: string
|
|
13
|
+
number: string
|
|
14
|
+
type: "checking" | "savings" | "credit" | "investment"
|
|
15
|
+
status: "active" | "inactive" | "pending" | "suspended"
|
|
16
|
+
balance?: string
|
|
17
|
+
currency?: string
|
|
18
|
+
institution?: string
|
|
19
|
+
routingNumber?: string
|
|
20
|
+
country?: string
|
|
21
|
+
}
|
|
22
|
+
showBalance?: boolean
|
|
23
|
+
className?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const typeIcons = {
|
|
27
|
+
checking: CreditCard,
|
|
28
|
+
savings: Building,
|
|
29
|
+
credit: CreditCard,
|
|
30
|
+
investment: Globe
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const typeLabels = {
|
|
34
|
+
checking: "Checking",
|
|
35
|
+
savings: "Savings",
|
|
36
|
+
credit: "Credit",
|
|
37
|
+
investment: "Investment"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const AccountCard = React.forwardRef<HTMLDivElement, AccountCardProps>(
|
|
41
|
+
({ account, showBalance = true, className }, ref) => {
|
|
42
|
+
const TypeIcon = typeIcons[account.type]
|
|
43
|
+
|
|
44
|
+
const accountData = [
|
|
45
|
+
{ label: "Account Number", value: account.number },
|
|
46
|
+
{ label: "Type", value: typeLabels[account.type] },
|
|
47
|
+
...(account.routingNumber ? [{ label: "Routing Number", value: account.routingNumber }] : []),
|
|
48
|
+
...(account.institution ? [{ label: "Institution", value: account.institution }] : []),
|
|
49
|
+
...(account.country ? [{ label: "Country", value: account.country }] : [])
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<Card ref={ref} className={cn("", className)}>
|
|
54
|
+
<CardHeader>
|
|
55
|
+
<div className="flex items-center justify-between">
|
|
56
|
+
<div className="flex items-center space-x-3">
|
|
57
|
+
<div className="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10">
|
|
58
|
+
<TypeIcon className="w-5 h-5 text-primary" />
|
|
59
|
+
</div>
|
|
60
|
+
<div>
|
|
61
|
+
<CardTitle className="text-lg">{account.name}</CardTitle>
|
|
62
|
+
<div className="flex items-center space-x-2 mt-1">
|
|
63
|
+
<Badge variant={account.status as any}>{account.status}</Badge>
|
|
64
|
+
<span className="text-sm text-muted-foreground">
|
|
65
|
+
{typeLabels[account.type]}
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
{showBalance && account.balance && (
|
|
72
|
+
<div className="text-right">
|
|
73
|
+
<div className="text-2xl font-bold text-foreground">
|
|
74
|
+
{account.balance}
|
|
75
|
+
</div>
|
|
76
|
+
{account.currency && (
|
|
77
|
+
<div className="text-sm text-muted-foreground">
|
|
78
|
+
{account.currency}
|
|
79
|
+
</div>
|
|
80
|
+
)}
|
|
81
|
+
</div>
|
|
82
|
+
)}
|
|
83
|
+
</div>
|
|
84
|
+
</CardHeader>
|
|
85
|
+
|
|
86
|
+
<CardContent>
|
|
87
|
+
<DataGrid data={accountData} columns={2} gap="sm" />
|
|
88
|
+
</CardContent>
|
|
89
|
+
</Card>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
AccountCard.displayName = "AccountCard"
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
3
|
+
import { cn } from "@/lib/utils"
|
|
4
|
+
|
|
5
|
+
const badgeVariants = cva(
|
|
6
|
+
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default:
|
|
11
|
+
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
|
12
|
+
secondary:
|
|
13
|
+
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
14
|
+
destructive:
|
|
15
|
+
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
16
|
+
outline: "text-foreground",
|
|
17
|
+
success:
|
|
18
|
+
"border-transparent bg-success text-success-foreground hover:bg-success/80",
|
|
19
|
+
warning:
|
|
20
|
+
"border-transparent bg-warning text-warning-foreground hover:bg-warning/80",
|
|
21
|
+
// Business type specific variants
|
|
22
|
+
business:
|
|
23
|
+
"border-blue-200 bg-blue-50 text-blue-700 hover:bg-blue-100 dark:border-blue-800 dark:bg-blue-950 dark:text-blue-300",
|
|
24
|
+
individual:
|
|
25
|
+
"border-green-200 bg-green-50 text-green-700 hover:bg-green-100 dark:border-green-800 dark:bg-green-950 dark:text-green-300",
|
|
26
|
+
government:
|
|
27
|
+
"border-purple-200 bg-purple-50 text-purple-700 hover:bg-purple-100 dark:border-purple-800 dark:bg-purple-950 dark:text-purple-300",
|
|
28
|
+
nonprofit:
|
|
29
|
+
"border-orange-200 bg-orange-50 text-orange-700 hover:bg-orange-100 dark:border-orange-800 dark:bg-orange-950 dark:text-orange-300",
|
|
30
|
+
// Business entity type variants
|
|
31
|
+
corporation:
|
|
32
|
+
"border-slate-200 bg-slate-50 text-slate-700 hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300",
|
|
33
|
+
llc:
|
|
34
|
+
"border-teal-200 bg-teal-50 text-teal-700 hover:bg-teal-100 dark:border-teal-800 dark:bg-teal-950 dark:text-teal-300",
|
|
35
|
+
partnership:
|
|
36
|
+
"border-indigo-200 bg-indigo-50 text-indigo-700 hover:bg-indigo-100 dark:border-indigo-800 dark:bg-indigo-950 dark:text-indigo-300",
|
|
37
|
+
sole_proprietorship:
|
|
38
|
+
"border-amber-200 bg-amber-50 text-amber-700 hover:bg-amber-100 dark:border-amber-800 dark:bg-amber-950 dark:text-amber-300",
|
|
39
|
+
// Status variants
|
|
40
|
+
active:
|
|
41
|
+
"border-green-200 bg-green-50 text-green-700 hover:bg-green-100 dark:border-green-800 dark:bg-green-950 dark:text-green-300",
|
|
42
|
+
inactive:
|
|
43
|
+
"border-red-200 bg-red-50 text-red-700 hover:bg-red-100 dark:border-red-800 dark:bg-red-950 dark:text-red-300",
|
|
44
|
+
pending:
|
|
45
|
+
"border-yellow-200 bg-yellow-50 text-yellow-700 hover:bg-yellow-100 dark:border-yellow-800 dark:bg-yellow-950 dark:text-yellow-300",
|
|
46
|
+
suspended:
|
|
47
|
+
"border-gray-200 bg-gray-50 text-gray-700 hover:bg-gray-100 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300",
|
|
48
|
+
// Alert type subtle variants
|
|
49
|
+
"alert-ofac":
|
|
50
|
+
"border-red-200 bg-red-50 text-red-700 hover:bg-red-100 dark:border-red-800 dark:bg-red-950 dark:text-red-300 font-medium",
|
|
51
|
+
"alert-dual":
|
|
52
|
+
"border-emerald-200 bg-emerald-50 text-emerald-700 hover:bg-emerald-100 dark:border-emerald-800 dark:bg-emerald-950 dark:text-emerald-300 font-medium",
|
|
53
|
+
"alert-monitoring":
|
|
54
|
+
"border-amber-200 bg-amber-50 text-amber-700 hover:bg-amber-100 dark:border-amber-800 dark:bg-amber-950 dark:text-amber-300 font-medium",
|
|
55
|
+
"alert-error":
|
|
56
|
+
"border-rose-200 bg-rose-50 text-rose-700 hover:bg-rose-100 dark:border-rose-800 dark:bg-rose-950 dark:text-rose-300 font-medium",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
defaultVariants: {
|
|
60
|
+
variant: "default",
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
export interface BadgeProps
|
|
66
|
+
extends React.HTMLAttributes<HTMLDivElement>,
|
|
67
|
+
VariantProps<typeof badgeVariants> {}
|
|
68
|
+
|
|
69
|
+
function Badge({ className, variant, ...props }: BadgeProps) {
|
|
70
|
+
return (
|
|
71
|
+
<div className={cn(badgeVariants({ variant }), className)} {...props} />
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { Badge, badgeVariants }
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "@/lib/utils"
|
|
3
|
+
import { ChevronRight, Home } from "lucide-react"
|
|
4
|
+
import { NavLink } from "react-router-dom"
|
|
5
|
+
|
|
6
|
+
export interface BreadcrumbItem {
|
|
7
|
+
label: string
|
|
8
|
+
href?: string
|
|
9
|
+
icon?: React.ReactNode
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface BreadcrumbProps {
|
|
13
|
+
items: BreadcrumbItem[]
|
|
14
|
+
showHome?: boolean
|
|
15
|
+
separator?: React.ReactNode
|
|
16
|
+
className?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const Breadcrumb = React.forwardRef<HTMLElement, BreadcrumbProps>(
|
|
20
|
+
({ items, showHome = true, separator, className }, ref) => {
|
|
21
|
+
const defaultSeparator = <ChevronRight className="w-4 h-4 text-muted-foreground" />
|
|
22
|
+
const separatorElement = separator || defaultSeparator
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<nav
|
|
26
|
+
ref={ref}
|
|
27
|
+
aria-label="Breadcrumb"
|
|
28
|
+
className={cn("flex items-center space-x-1 text-sm", className)}
|
|
29
|
+
>
|
|
30
|
+
{showHome && (
|
|
31
|
+
<>
|
|
32
|
+
<NavLink
|
|
33
|
+
to="/"
|
|
34
|
+
className="flex items-center text-muted-foreground hover:text-foreground transition-colors"
|
|
35
|
+
>
|
|
36
|
+
<Home className="w-4 h-4" />
|
|
37
|
+
</NavLink>
|
|
38
|
+
{items.length > 0 && (
|
|
39
|
+
<span className="text-muted-foreground">{separatorElement}</span>
|
|
40
|
+
)}
|
|
41
|
+
</>
|
|
42
|
+
)}
|
|
43
|
+
|
|
44
|
+
{items.map((item, index) => {
|
|
45
|
+
const isLast = index === items.length - 1
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<React.Fragment key={index}>
|
|
49
|
+
{item.href && !isLast ? (
|
|
50
|
+
<NavLink
|
|
51
|
+
to={item.href}
|
|
52
|
+
className="flex items-center text-muted-foreground hover:text-foreground transition-colors"
|
|
53
|
+
>
|
|
54
|
+
{item.icon && <span className="mr-1">{item.icon}</span>}
|
|
55
|
+
{item.label}
|
|
56
|
+
</NavLink>
|
|
57
|
+
) : (
|
|
58
|
+
<span className={cn(
|
|
59
|
+
"flex items-center",
|
|
60
|
+
isLast ? "text-foreground font-medium" : "text-muted-foreground"
|
|
61
|
+
)}>
|
|
62
|
+
{item.icon && <span className="mr-1">{item.icon}</span>}
|
|
63
|
+
{item.label}
|
|
64
|
+
</span>
|
|
65
|
+
)}
|
|
66
|
+
|
|
67
|
+
{!isLast && (
|
|
68
|
+
<span className="text-muted-foreground">{separatorElement}</span>
|
|
69
|
+
)}
|
|
70
|
+
</React.Fragment>
|
|
71
|
+
)
|
|
72
|
+
})}
|
|
73
|
+
</nav>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
Breadcrumb.displayName = "Breadcrumb"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Badge } from "@/components/ui/badge"
|
|
2
|
+
import { Building, Briefcase, Users, User } from "lucide-react"
|
|
3
|
+
|
|
4
|
+
interface BusinessTypeBadgeProps {
|
|
5
|
+
type: "corporation" | "llc" | "partnership" | "sole_proprietorship"
|
|
6
|
+
className?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const typeConfig = {
|
|
10
|
+
corporation: {
|
|
11
|
+
variant: "corporation" as const,
|
|
12
|
+
label: "Corporation",
|
|
13
|
+
icon: Building
|
|
14
|
+
},
|
|
15
|
+
llc: {
|
|
16
|
+
variant: "llc" as const,
|
|
17
|
+
label: "LLC",
|
|
18
|
+
icon: Briefcase
|
|
19
|
+
},
|
|
20
|
+
partnership: {
|
|
21
|
+
variant: "partnership" as const,
|
|
22
|
+
label: "Partnership",
|
|
23
|
+
icon: Users
|
|
24
|
+
},
|
|
25
|
+
sole_proprietorship: {
|
|
26
|
+
variant: "sole_proprietorship" as const,
|
|
27
|
+
label: "Sole Proprietorship",
|
|
28
|
+
icon: User
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const BusinessTypeBadge = ({ type, className }: BusinessTypeBadgeProps) => {
|
|
33
|
+
const config = typeConfig[type]
|
|
34
|
+
const Icon = config.icon
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<Badge variant={config.variant} className={className}>
|
|
38
|
+
<Icon className="w-3 h-3 mr-1" />
|
|
39
|
+
{config.label}
|
|
40
|
+
</Badge>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot"
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils"
|
|
6
|
+
|
|
7
|
+
const buttonVariants = cva(
|
|
8
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
13
|
+
destructive:
|
|
14
|
+
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
15
|
+
outline:
|
|
16
|
+
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
17
|
+
secondary:
|
|
18
|
+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
19
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
20
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
default: "h-10 px-4 py-2",
|
|
24
|
+
sm: "h-9 rounded-md px-3",
|
|
25
|
+
lg: "h-11 rounded-md px-8",
|
|
26
|
+
icon: "h-10 w-10",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
defaultVariants: {
|
|
30
|
+
variant: "default",
|
|
31
|
+
size: "default",
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
export interface ButtonProps
|
|
37
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
38
|
+
VariantProps<typeof buttonVariants> {
|
|
39
|
+
asChild?: boolean
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
43
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
44
|
+
const Comp = asChild ? Slot : "button"
|
|
45
|
+
return (
|
|
46
|
+
<Comp
|
|
47
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
|
48
|
+
ref={ref}
|
|
49
|
+
{...props}
|
|
50
|
+
/>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
Button.displayName = "Button"
|
|
55
|
+
|
|
56
|
+
export { Button, buttonVariants }
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { DayPicker } from "react-day-picker"
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
import { buttonVariants } from "@/components/ui/button"
|
|
6
|
+
|
|
7
|
+
export type CalendarProps = React.ComponentProps<typeof DayPicker>
|
|
8
|
+
|
|
9
|
+
function Calendar({
|
|
10
|
+
className,
|
|
11
|
+
classNames,
|
|
12
|
+
showOutsideDays = true,
|
|
13
|
+
...props
|
|
14
|
+
}: CalendarProps) {
|
|
15
|
+
return (
|
|
16
|
+
<DayPicker
|
|
17
|
+
showOutsideDays={showOutsideDays}
|
|
18
|
+
className={cn("p-3 pointer-events-auto", className)}
|
|
19
|
+
classNames={{
|
|
20
|
+
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
|
|
21
|
+
month: "space-y-4",
|
|
22
|
+
caption: "flex justify-center pt-1 relative items-center",
|
|
23
|
+
caption_label: "text-sm font-medium",
|
|
24
|
+
nav: "space-x-1 flex items-center",
|
|
25
|
+
button_previous: "absolute left-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
|
26
|
+
button_next: "absolute right-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
|
27
|
+
month_grid: "w-full border-collapse space-y-1",
|
|
28
|
+
weekdays: "flex",
|
|
29
|
+
weekday: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
|
|
30
|
+
week: "flex w-full mt-2",
|
|
31
|
+
day: "h-9 w-9 text-center text-sm p-0 relative hover:bg-accent hover:text-accent-foreground rounded-md",
|
|
32
|
+
day_button: cn(
|
|
33
|
+
buttonVariants({ variant: "ghost" }),
|
|
34
|
+
"h-9 w-9 p-0 font-normal"
|
|
35
|
+
),
|
|
36
|
+
selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground",
|
|
37
|
+
today: "bg-accent text-accent-foreground",
|
|
38
|
+
outside: "text-muted-foreground opacity-50",
|
|
39
|
+
disabled: "text-muted-foreground opacity-50",
|
|
40
|
+
hidden: "invisible",
|
|
41
|
+
...classNames,
|
|
42
|
+
}}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
Calendar.displayName = "Calendar"
|
|
48
|
+
|
|
49
|
+
export { Calendar }
|