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.
Files changed (145) hide show
  1. package/README.md +327 -44
  2. package/dist/css/braid-ui-variables.css +88 -0
  3. package/dist/css/braid-ui.css +4702 -0
  4. package/dist/css/braid-ui.min.css +1 -0
  5. package/dist/index.cjs +4 -0
  6. package/dist/index.cjs.map +1 -0
  7. package/dist/index.d.cts +2027 -0
  8. package/dist/index.d.ts +2027 -0
  9. package/dist/index.js +4 -0
  10. package/dist/index.js.map +1 -0
  11. package/package.json +115 -55
  12. package/src/styles-only.css +121 -0
  13. package/src/{index.css → styles.css} +4 -10
  14. package/components.json +0 -20
  15. package/eslint.config.js +0 -29
  16. package/index.html +0 -24
  17. package/postcss.config.js +0 -6
  18. package/public/favicon.ico +0 -0
  19. package/public/placeholder.svg +0 -1
  20. package/public/robots.txt +0 -14
  21. package/src/App.css +0 -42
  22. package/src/App.tsx +0 -94
  23. package/src/components/MainLayout.tsx +0 -15
  24. package/src/components/alerts/AlertDocuments.tsx +0 -320
  25. package/src/components/alerts/AlertNotes.tsx +0 -185
  26. package/src/components/alerts/AlertTimeline.tsx +0 -79
  27. package/src/components/alerts/ContextSection.tsx +0 -155
  28. package/src/components/app-sidebar.tsx +0 -341
  29. package/src/components/form-sections/ACHBankCard.tsx +0 -78
  30. package/src/components/form-sections/ACHBasicInfoCard.tsx +0 -100
  31. package/src/components/form-sections/ACHTransferSection.tsx +0 -64
  32. package/src/components/form-sections/AddressForm.tsx +0 -94
  33. package/src/components/form-sections/BankAddressCard.tsx +0 -95
  34. package/src/components/form-sections/BankingDetailsCard.tsx +0 -46
  35. package/src/components/form-sections/BasicInfoCard.tsx +0 -103
  36. package/src/components/form-sections/BasicInfoSection.tsx +0 -34
  37. package/src/components/form-sections/BeneficiaryAddress.tsx +0 -19
  38. package/src/components/form-sections/BeneficiaryCard.tsx +0 -41
  39. package/src/components/form-sections/BeneficiaryDomesticWire.tsx +0 -23
  40. package/src/components/form-sections/BusinessProfileCard.tsx +0 -131
  41. package/src/components/form-sections/BusinessStatusCard.tsx +0 -53
  42. package/src/components/form-sections/ContactInfoCard.tsx +0 -63
  43. package/src/components/form-sections/CounterpartyBasicInfo.tsx +0 -101
  44. package/src/components/form-sections/CounterpartyProfileCard.tsx +0 -104
  45. package/src/components/form-sections/CounterpartyRecordsCard.tsx +0 -41
  46. package/src/components/form-sections/IntermediaryCard.tsx +0 -77
  47. package/src/components/form-sections/IntermediaryFI.tsx +0 -41
  48. package/src/components/form-sections/IntermediaryFIAddress.tsx +0 -14
  49. package/src/components/form-sections/OriginatorCard.tsx +0 -49
  50. package/src/components/form-sections/OriginatorFI.tsx +0 -42
  51. package/src/components/form-sections/OriginatorFIAddress.tsx +0 -14
  52. package/src/components/form-sections/PaymentInformationSection.tsx +0 -163
  53. package/src/components/form-sections/ReceiverCard.tsx +0 -94
  54. package/src/components/form-sections/WireTransferSection.tsx +0 -75
  55. package/src/components/layouts/list-page.tsx +0 -103
  56. package/src/components/transaction/ACHDetailsSection.tsx +0 -95
  57. package/src/components/transaction/WireDetailsSection.tsx +0 -112
  58. package/src/components/ui/account-card.tsx +0 -94
  59. package/src/components/ui/badge.tsx +0 -75
  60. package/src/components/ui/breadcrumb.tsx +0 -78
  61. package/src/components/ui/business-type-badge.tsx +0 -42
  62. package/src/components/ui/button.tsx +0 -56
  63. package/src/components/ui/calendar.tsx +0 -49
  64. package/src/components/ui/card.tsx +0 -223
  65. package/src/components/ui/container.tsx +0 -45
  66. package/src/components/ui/counterparty-type-badge.tsx +0 -53
  67. package/src/components/ui/data-grid.tsx +0 -99
  68. package/src/components/ui/data-table.tsx +0 -152
  69. package/src/components/ui/detail-page-layout.tsx +0 -83
  70. package/src/components/ui/dialog.tsx +0 -120
  71. package/src/components/ui/dropdown-menu.tsx +0 -82
  72. package/src/components/ui/editable-form-card.tsx +0 -106
  73. package/src/components/ui/editable-info-field.tsx +0 -67
  74. package/src/components/ui/enhanced-input.tsx +0 -78
  75. package/src/components/ui/enhanced-select.tsx +0 -101
  76. package/src/components/ui/enhanced-textarea.tsx +0 -64
  77. package/src/components/ui/entity-card.tsx +0 -140
  78. package/src/components/ui/form-card.tsx +0 -40
  79. package/src/components/ui/form-field.tsx +0 -50
  80. package/src/components/ui/form-input.tsx +0 -29
  81. package/src/components/ui/form-provider.tsx +0 -18
  82. package/src/components/ui/form-section.tsx +0 -66
  83. package/src/components/ui/form-select.tsx +0 -35
  84. package/src/components/ui/info-field.tsx +0 -36
  85. package/src/components/ui/json-viewer.tsx +0 -146
  86. package/src/components/ui/label.tsx +0 -24
  87. package/src/components/ui/metric-card.tsx +0 -80
  88. package/src/components/ui/page-layout.tsx +0 -183
  89. package/src/components/ui/popover.tsx +0 -29
  90. package/src/components/ui/responsive-grid.tsx +0 -46
  91. package/src/components/ui/separator.tsx +0 -31
  92. package/src/components/ui/sheet.tsx +0 -140
  93. package/src/components/ui/sidebar.tsx +0 -775
  94. package/src/components/ui/sonner.tsx +0 -29
  95. package/src/components/ui/stack.tsx +0 -77
  96. package/src/components/ui/status-badge.tsx +0 -68
  97. package/src/components/ui/tabs.tsx +0 -52
  98. package/src/components/ui/toast.tsx +0 -127
  99. package/src/components/ui/toaster.tsx +0 -33
  100. package/src/components/ui/tooltip.tsx +0 -28
  101. package/src/components/ui/use-toast.ts +0 -3
  102. package/src/components/ui-kit/dashboard-demo.tsx +0 -156
  103. package/src/components/ui-kit/pattern-library.tsx +0 -248
  104. package/src/components/ui-kit/showcase.tsx +0 -211
  105. package/src/hooks/use-mobile.tsx +0 -19
  106. package/src/hooks/use-toast.ts +0 -191
  107. package/src/hooks/useEditState.ts +0 -70
  108. package/src/hooks/useFormWithEditState.ts +0 -115
  109. package/src/lib/constants.ts +0 -25
  110. package/src/lib/mock-data/alert-data.ts +0 -275
  111. package/src/lib/mock-data/banking-data.ts +0 -72
  112. package/src/lib/mock-data/business-data.ts +0 -71
  113. package/src/lib/mock-data/counterparty-data.ts +0 -70
  114. package/src/lib/mock-data/index.ts +0 -5
  115. package/src/lib/mock-data/transaction-data.ts +0 -283
  116. package/src/lib/mock-data/wire-data.ts +0 -103
  117. package/src/lib/mock-data.tsx +0 -180
  118. package/src/lib/schemas/banking-schemas.ts +0 -30
  119. package/src/lib/schemas/business-schemas.ts +0 -36
  120. package/src/lib/schemas/counterparty-schemas.ts +0 -43
  121. package/src/lib/schemas/index.ts +0 -5
  122. package/src/lib/schemas/wire-schemas.ts +0 -44
  123. package/src/lib/utils.ts +0 -6
  124. package/src/main.tsx +0 -10
  125. package/src/pages/Cases.tsx +0 -16
  126. package/src/pages/Dashboard.tsx +0 -16
  127. package/src/pages/NotFound.tsx +0 -27
  128. package/src/pages/TransactionHistory.tsx +0 -532
  129. package/src/pages/UIKit.tsx +0 -51
  130. package/src/pages/alerts/AlertDetail.tsx +0 -193
  131. package/src/pages/alerts/Alerts.tsx +0 -373
  132. package/src/pages/business/Business.tsx +0 -48
  133. package/src/pages/business/Create.tsx +0 -173
  134. package/src/pages/counterparty/Create.tsx +0 -48
  135. package/src/pages/counterparty/DomesticWire.tsx +0 -78
  136. package/src/pages/counterparty/Manage.tsx +0 -79
  137. package/src/pages/transactions/NewTransaction.tsx +0 -527
  138. package/src/pages/transactions/TransactionDetail.tsx +0 -192
  139. package/src/vite-env.d.ts +0 -1
  140. package/tailwind.config.ts +0 -124
  141. package/tsconfig.app.json +0 -30
  142. package/tsconfig.json +0 -19
  143. package/tsconfig.node.json +0 -22
  144. package/vite.config.ts +0 -22
  145. /package/{src/assets/braid-logo.png → dist/braid-logo-343BOQZ2.png} +0 -0
@@ -1,67 +0,0 @@
1
- import { useState } from "react"
2
- import { InfoField } from "./info-field"
3
- import { EnhancedSelect } from "./enhanced-select"
4
- import { Badge } from "./badge"
5
- import { cn } from "@/lib/utils"
6
-
7
- interface EditableInfoFieldProps {
8
- label: string
9
- value: string | null | undefined
10
- options: { value: string; label: string }[]
11
- onChange: (value: string) => void
12
- placeholder?: string
13
- renderValue?: (value: string) => React.ReactNode
14
- className?: string
15
- }
16
-
17
- export const EditableInfoField = ({
18
- label,
19
- value,
20
- options,
21
- onChange,
22
- placeholder = "Select...",
23
- renderValue,
24
- className
25
- }: EditableInfoFieldProps) => {
26
- const [isEditing, setIsEditing] = useState(false)
27
-
28
- const handleChange = (newValue: string) => {
29
- onChange(newValue)
30
- setIsEditing(false)
31
- }
32
-
33
- if (isEditing) {
34
- return (
35
- <div className={className}>
36
- <EnhancedSelect
37
- label={label}
38
- value={value || ""}
39
- onValueChange={handleChange}
40
- options={options}
41
- placeholder={placeholder}
42
- />
43
- </div>
44
- )
45
- }
46
-
47
- const displayValue = value
48
- ? (renderValue ? renderValue(value) : value)
49
- : placeholder
50
-
51
- return (
52
- <div
53
- className={cn("cursor-pointer transition-colors hover:bg-muted/50 rounded-md -mx-2 px-2 -my-1 py-1", className)}
54
- onClick={() => setIsEditing(true)}
55
- role="button"
56
- tabIndex={0}
57
- onKeyDown={(e) => {
58
- if (e.key === 'Enter' || e.key === ' ') {
59
- e.preventDefault()
60
- setIsEditing(true)
61
- }
62
- }}
63
- >
64
- <InfoField label={label} value={displayValue} />
65
- </div>
66
- )
67
- }
@@ -1,78 +0,0 @@
1
- import * as React from "react"
2
- import { cn } from "@/lib/utils"
3
- import { cva, type VariantProps } from "class-variance-authority"
4
-
5
- const inputVariants = cva(
6
- "flex w-full rounded-md bg-form-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground transition-form",
7
- {
8
- variants: {
9
- variant: {
10
- default: "border border-form-border focus-visible:border-form-border-focus focus-visible:outline-none focus-visible:shadow-form-focus",
11
- error: "border border-form-border-error focus-visible:border-form-border-error focus-visible:outline-none focus-visible:shadow-form-error",
12
- success: "border border-form-border-success focus-visible:border-form-border-success focus-visible:outline-none",
13
- disabled: "border border-form-border bg-muted cursor-not-allowed opacity-50",
14
- readonly: "border border-form-border bg-muted/50 cursor-default"
15
- },
16
- size: {
17
- default: "h-10",
18
- sm: "h-9",
19
- lg: "h-11"
20
- }
21
- },
22
- defaultVariants: {
23
- variant: "default",
24
- size: "default"
25
- }
26
- }
27
- )
28
-
29
- export interface InputProps
30
- extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>,
31
- VariantProps<typeof inputVariants> {
32
- label?: string
33
- hint?: string
34
- error?: string
35
- success?: string
36
- isLoading?: boolean
37
- }
38
-
39
- const EnhancedInput = React.forwardRef<HTMLInputElement, InputProps>(
40
- ({ className, variant, size, label, hint, error, success, isLoading, ...props }, ref) => {
41
- const inputVariant = error ? "error" : success ? "success" : props.disabled ? "disabled" : props.readOnly ? "readonly" : variant
42
-
43
- return (
44
- <div className="space-y-2">
45
- {label && (
46
- <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
47
- {label}
48
- {props.required && <span className="text-destructive ml-1">*</span>}
49
- </label>
50
- )}
51
- <div className="relative">
52
- <input
53
- className={cn(inputVariants({ variant: inputVariant, size, className }))}
54
- ref={ref}
55
- {...props}
56
- />
57
- {isLoading && (
58
- <div className="absolute right-3 top-1/2 transform -translate-y-1/2">
59
- <div className="animate-spin rounded-full h-4 w-4 border-2 border-primary border-t-transparent"></div>
60
- </div>
61
- )}
62
- </div>
63
- {hint && !error && !success && (
64
- <p className="text-xs text-muted-foreground">{hint}</p>
65
- )}
66
- {error && (
67
- <p className="text-xs text-destructive">{error}</p>
68
- )}
69
- {success && (
70
- <p className="text-xs text-success">{success}</p>
71
- )}
72
- </div>
73
- )
74
- }
75
- )
76
- EnhancedInput.displayName = "EnhancedInput"
77
-
78
- export { EnhancedInput, inputVariants }
@@ -1,101 +0,0 @@
1
- import * as React from "react"
2
- import * as SelectPrimitive from "@radix-ui/react-select"
3
- import { Check, ChevronDown, ChevronUp } from "lucide-react"
4
- import { cn } from "@/lib/utils"
5
- import { cva, type VariantProps } from "class-variance-authority"
6
-
7
- const selectVariants = cva(
8
- "flex h-10 w-full items-center justify-between rounded-md bg-form-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none transition-form",
9
- {
10
- variants: {
11
- variant: {
12
- default: "border border-form-border focus:border-form-border-focus focus:shadow-form-focus",
13
- error: "border border-form-border-error focus:border-form-border-error focus:shadow-form-error",
14
- success: "border border-form-border-success focus:border-form-border-success",
15
- disabled: "border border-form-border bg-muted cursor-not-allowed opacity-50",
16
- }
17
- },
18
- defaultVariants: {
19
- variant: "default"
20
- }
21
- }
22
- )
23
-
24
- interface EnhancedSelectProps extends VariantProps<typeof selectVariants> {
25
- label?: string
26
- hint?: string
27
- error?: string
28
- success?: string
29
- placeholder?: string
30
- options: { value: string; label: string; disabled?: boolean }[]
31
- value?: string
32
- onValueChange?: (value: string) => void
33
- disabled?: boolean
34
- }
35
-
36
- const EnhancedSelect = React.forwardRef<
37
- React.ElementRef<typeof SelectPrimitive.Trigger>,
38
- EnhancedSelectProps
39
- >(({ variant, label, hint, error, success, placeholder, options, disabled, ...props }, ref) => {
40
- const selectVariant = error ? "error" : success ? "success" : disabled ? "disabled" : variant
41
-
42
- return (
43
- <div className="space-y-2">
44
- {label && (
45
- <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
46
- {label}
47
- </label>
48
- )}
49
- <SelectPrimitive.Root {...props} disabled={disabled}>
50
- <SelectPrimitive.Trigger
51
- ref={ref}
52
- className={cn(selectVariants({ variant: selectVariant }))}
53
- >
54
- <SelectPrimitive.Value placeholder={placeholder} />
55
- <SelectPrimitive.Icon asChild>
56
- <ChevronDown className="h-4 w-4 opacity-50" />
57
- </SelectPrimitive.Icon>
58
- </SelectPrimitive.Trigger>
59
- <SelectPrimitive.Portal>
60
- <SelectPrimitive.Content className="relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2">
61
- <SelectPrimitive.ScrollUpButton className="flex cursor-default items-center justify-center py-1">
62
- <ChevronUp className="h-4 w-4" />
63
- </SelectPrimitive.ScrollUpButton>
64
- <SelectPrimitive.Viewport className="p-1">
65
- {options.map((option) => (
66
- <SelectPrimitive.Item
67
- key={option.value}
68
- value={option.value}
69
- disabled={option.disabled}
70
- className="relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
71
- >
72
- <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
73
- <SelectPrimitive.ItemIndicator>
74
- <Check className="h-4 w-4" />
75
- </SelectPrimitive.ItemIndicator>
76
- </span>
77
- <SelectPrimitive.ItemText>{option.label}</SelectPrimitive.ItemText>
78
- </SelectPrimitive.Item>
79
- ))}
80
- </SelectPrimitive.Viewport>
81
- <SelectPrimitive.ScrollDownButton className="flex cursor-default items-center justify-center py-1">
82
- <ChevronDown className="h-4 w-4" />
83
- </SelectPrimitive.ScrollDownButton>
84
- </SelectPrimitive.Content>
85
- </SelectPrimitive.Portal>
86
- </SelectPrimitive.Root>
87
- {hint && !error && !success && (
88
- <p className="text-xs text-muted-foreground">{hint}</p>
89
- )}
90
- {error && (
91
- <p className="text-xs text-destructive">{error}</p>
92
- )}
93
- {success && (
94
- <p className="text-xs text-success">{success}</p>
95
- )}
96
- </div>
97
- )
98
- })
99
- EnhancedSelect.displayName = "EnhancedSelect"
100
-
101
- export { EnhancedSelect }
@@ -1,64 +0,0 @@
1
- import * as React from "react"
2
- import { cn } from "@/lib/utils"
3
- import { cva, type VariantProps } from "class-variance-authority"
4
-
5
- const textareaVariants = cva(
6
- "flex min-h-[80px] w-full rounded-md bg-form-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground transition-form resize-y",
7
- {
8
- variants: {
9
- variant: {
10
- default: "border border-form-border focus-visible:border-form-border-focus focus-visible:outline-none focus-visible:shadow-form-focus",
11
- error: "border border-form-border-error focus-visible:border-form-border-error focus-visible:outline-none focus-visible:shadow-form-error",
12
- success: "border border-form-border-success focus-visible:border-form-border-success focus-visible:outline-none",
13
- disabled: "border border-form-border bg-muted cursor-not-allowed opacity-50 resize-none",
14
- readonly: "border border-form-border bg-muted/50 cursor-default resize-none"
15
- }
16
- },
17
- defaultVariants: {
18
- variant: "default"
19
- }
20
- }
21
- )
22
-
23
- export interface TextareaProps
24
- extends React.TextareaHTMLAttributes<HTMLTextAreaElement>,
25
- VariantProps<typeof textareaVariants> {
26
- label?: string
27
- hint?: string
28
- error?: string
29
- success?: string
30
- }
31
-
32
- const EnhancedTextarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
33
- ({ className, variant, label, hint, error, success, ...props }, ref) => {
34
- const textareaVariant = error ? "error" : success ? "success" : props.disabled ? "disabled" : props.readOnly ? "readonly" : variant
35
-
36
- return (
37
- <div className="space-y-2">
38
- {label && (
39
- <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
40
- {label}
41
- {props.required && <span className="text-destructive ml-1">*</span>}
42
- </label>
43
- )}
44
- <textarea
45
- className={cn(textareaVariants({ variant: textareaVariant, className }))}
46
- ref={ref}
47
- {...props}
48
- />
49
- {hint && !error && !success && (
50
- <p className="text-xs text-muted-foreground">{hint}</p>
51
- )}
52
- {error && (
53
- <p className="text-xs text-destructive">{error}</p>
54
- )}
55
- {success && (
56
- <p className="text-xs text-success">{success}</p>
57
- )}
58
- </div>
59
- )
60
- }
61
- )
62
- EnhancedTextarea.displayName = "EnhancedTextarea"
63
-
64
- export { EnhancedTextarea, textareaVariants }
@@ -1,140 +0,0 @@
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 { Button } from "@/components/ui/button"
5
- import { DataGrid } from "@/components/ui/data-grid"
6
- import { cn } from "@/lib/utils"
7
- import { MoreVertical, Edit, Trash2, Eye } from "lucide-react"
8
- import {
9
- DropdownMenu,
10
- DropdownMenuContent,
11
- DropdownMenuItem,
12
- DropdownMenuSeparator,
13
- DropdownMenuTrigger
14
- } from "@/components/ui/dropdown-menu"
15
-
16
- interface EntityAction {
17
- label: string
18
- icon: React.ReactNode
19
- onClick: () => void
20
- variant?: "default" | "destructive"
21
- }
22
-
23
- interface EntityCardProps {
24
- entity: {
25
- id: string
26
- name: string
27
- type: string
28
- status: string
29
- description?: string
30
- metadata?: Record<string, any>
31
- }
32
- actions?: EntityAction[]
33
- showDefaultActions?: boolean
34
- onView?: (id: string) => void
35
- onEdit?: (id: string) => void
36
- onDelete?: (id: string) => void
37
- className?: string
38
- children?: React.ReactNode
39
- }
40
-
41
- export const EntityCard = React.forwardRef<HTMLDivElement, EntityCardProps>(
42
- ({
43
- entity,
44
- actions,
45
- showDefaultActions = true,
46
- onView,
47
- onEdit,
48
- onDelete,
49
- className,
50
- children
51
- }, ref) => {
52
- const defaultActions: EntityAction[] = [
53
- ...(onView ? [{
54
- label: "View Details",
55
- icon: <Eye className="w-4 h-4" />,
56
- onClick: () => onView(entity.id)
57
- }] : []),
58
- ...(onEdit ? [{
59
- label: "Edit",
60
- icon: <Edit className="w-4 h-4" />,
61
- onClick: () => onEdit(entity.id)
62
- }] : []),
63
- ...(onDelete ? [{
64
- label: "Delete",
65
- icon: <Trash2 className="w-4 h-4" />,
66
- onClick: () => onDelete(entity.id),
67
- variant: "destructive" as const
68
- }] : [])
69
- ]
70
-
71
- const allActions = showDefaultActions ? [...defaultActions, ...(actions || [])] : (actions || [])
72
-
73
- const entityData = entity.metadata ? Object.entries(entity.metadata)
74
- .filter(([_, value]) => value !== null && value !== undefined)
75
- .map(([key, value]) => ({
76
- label: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1'),
77
- value: typeof value === 'object' ? JSON.stringify(value) : String(value)
78
- })) : []
79
-
80
- return (
81
- <Card ref={ref} className={cn("relative", className)}>
82
- <CardHeader>
83
- <div className="flex items-start justify-between">
84
- <div className="flex-1 min-w-0">
85
- <CardTitle className="text-lg truncate">{entity.name}</CardTitle>
86
- <div className="flex items-center space-x-2 mt-2">
87
- <Badge variant={entity.status as any}>{entity.status}</Badge>
88
- <Badge variant="outline">{entity.type}</Badge>
89
- </div>
90
- {entity.description && (
91
- <p className="text-sm text-muted-foreground mt-2 line-clamp-2">
92
- {entity.description}
93
- </p>
94
- )}
95
- </div>
96
-
97
- {allActions.length > 0 && (
98
- <DropdownMenu>
99
- <DropdownMenuTrigger asChild>
100
- <Button variant="ghost" size="icon" className="h-8 w-8">
101
- <MoreVertical className="w-4 h-4" />
102
- </Button>
103
- </DropdownMenuTrigger>
104
- <DropdownMenuContent align="end">
105
- {allActions.map((action, index) => (
106
- <React.Fragment key={index}>
107
- <DropdownMenuItem
108
- onClick={action.onClick}
109
- className={cn(
110
- action.variant === "destructive" && "text-destructive focus:text-destructive"
111
- )}
112
- >
113
- {action.icon}
114
- {action.label}
115
- </DropdownMenuItem>
116
- {index < allActions.length - 1 && action.variant === "destructive" && (
117
- <DropdownMenuSeparator />
118
- )}
119
- </React.Fragment>
120
- ))}
121
- </DropdownMenuContent>
122
- </DropdownMenu>
123
- )}
124
- </div>
125
- </CardHeader>
126
-
127
- {(entityData.length > 0 || children) && (
128
- <CardContent>
129
- {entityData.length > 0 && (
130
- <DataGrid data={entityData} columns={2} gap="sm" />
131
- )}
132
- {children}
133
- </CardContent>
134
- )}
135
- </Card>
136
- )
137
- }
138
- )
139
-
140
- EntityCard.displayName = "EntityCard"
@@ -1,40 +0,0 @@
1
- import * as React from "react"
2
- import { Card, CardContent, CardHeader, CardTitle, CardDescription, type CardProps } from "@/components/ui/card"
3
- import { cn } from "@/lib/utils"
4
-
5
- export interface FormCardProps extends Omit<CardProps, 'children'> {
6
- title: string
7
- description?: string
8
- children: React.ReactNode
9
- headerActions?: React.ReactNode
10
- }
11
-
12
- export const FormCard = React.forwardRef<HTMLDivElement, FormCardProps>(
13
- ({ title, description, children, headerActions, className, variant = "default", ...props }, ref) => (
14
- <Card
15
- ref={ref}
16
- variant={variant}
17
- fullHeight
18
- className={cn("", className)}
19
- {...props}
20
- >
21
- <CardHeader
22
- direction={headerActions ? "row" : "column"}
23
- size="md"
24
- >
25
- <div className="space-y-1">
26
- <CardTitle size="md">{title}</CardTitle>
27
- </div>
28
- {headerActions && (
29
- <div className="flex items-center gap-2">
30
- {headerActions}
31
- </div>
32
- )}
33
- </CardHeader>
34
- <CardContent size="md" fullHeight>
35
- {children}
36
- </CardContent>
37
- </Card>
38
- )
39
- )
40
- FormCard.displayName = "FormCard"
@@ -1,50 +0,0 @@
1
- import * as React from "react"
2
- import { cn } from "@/lib/utils"
3
-
4
- interface FormFieldProps {
5
- label?: string
6
- description?: string
7
- error?: string
8
- required?: boolean
9
- children: React.ReactNode
10
- className?: string
11
- layout?: "vertical" | "horizontal"
12
- }
13
-
14
- export const FormField = React.forwardRef<HTMLDivElement, FormFieldProps>(
15
- ({ label, description, error, required, children, className, layout = "vertical" }, ref) => {
16
- const isHorizontal = layout === "horizontal"
17
-
18
- return (
19
- <div
20
- ref={ref}
21
- className={cn(
22
- "space-y-2",
23
- isHorizontal && "grid grid-cols-1 md:grid-cols-3 gap-4 items-start space-y-0",
24
- className
25
- )}
26
- >
27
- {label && (
28
- <div className={cn("space-y-1", isHorizontal && "pt-2")}>
29
- <label className="text-sm font-medium text-foreground">
30
- {label}
31
- {required && <span className="text-destructive ml-1">*</span>}
32
- </label>
33
- {description && (
34
- <p className="text-xs text-muted-foreground">{description}</p>
35
- )}
36
- </div>
37
- )}
38
-
39
- <div className={cn(isHorizontal && "md:col-span-2")}>
40
- {children}
41
- {error && (
42
- <p className="text-xs text-destructive mt-1">{error}</p>
43
- )}
44
- </div>
45
- </div>
46
- )
47
- }
48
- )
49
-
50
- FormField.displayName = "FormField"
@@ -1,29 +0,0 @@
1
- import * as React from "react"
2
- import { Controller, useFormContext, FieldPath, FieldValues } from "react-hook-form"
3
- import { EnhancedInput, type InputProps } from "@/components/ui/enhanced-input"
4
-
5
- interface FormInputProps<T extends FieldValues = FieldValues> extends Omit<InputProps, 'error' | 'name'> {
6
- name: FieldPath<T>
7
- }
8
-
9
- export const FormInput = <T extends FieldValues = FieldValues>({
10
- name,
11
- ...props
12
- }: FormInputProps<T>) => {
13
- const { control, formState } = useFormContext<T>()
14
- const error = formState.errors[name]?.message as string | undefined
15
-
16
- return (
17
- <Controller
18
- name={name}
19
- control={control}
20
- render={({ field }) => (
21
- <EnhancedInput
22
- {...props}
23
- {...field}
24
- error={error}
25
- />
26
- )}
27
- />
28
- )
29
- }
@@ -1,18 +0,0 @@
1
- import * as React from "react"
2
- import { FormProvider as RHFFormProvider, UseFormReturn, FieldValues } from "react-hook-form"
3
-
4
- interface FormProviderProps<T extends FieldValues> {
5
- form: UseFormReturn<T>
6
- children: React.ReactNode
7
- }
8
-
9
- export const FormProvider = <T extends FieldValues>({
10
- form,
11
- children
12
- }: FormProviderProps<T>) => {
13
- return (
14
- <RHFFormProvider {...form}>
15
- {children}
16
- </RHFFormProvider>
17
- )
18
- }
@@ -1,66 +0,0 @@
1
- import * as React from "react"
2
- import { cn } from "@/lib/utils"
3
-
4
- interface FormSectionProps {
5
- title?: string
6
- description?: string
7
- children: React.ReactNode
8
- className?: string
9
- spacing?: "sm" | "md" | "lg"
10
- layout?: "vertical" | "grid"
11
- columns?: 1 | 2 | 3 | 4
12
- }
13
-
14
- const spacingClasses = {
15
- sm: "space-y-3",
16
- md: "space-y-4",
17
- lg: "space-y-6"
18
- }
19
-
20
- const gridClasses = {
21
- 1: "grid-cols-1",
22
- 2: "grid-cols-1 md:grid-cols-2",
23
- 3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
24
- 4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4"
25
- }
26
-
27
- export const FormSection = React.forwardRef<HTMLDivElement, FormSectionProps>(
28
- ({
29
- title,
30
- description,
31
- children,
32
- className,
33
- spacing = "md",
34
- layout = "vertical",
35
- columns = 2
36
- }, ref) => {
37
- return (
38
- <div ref={ref} className={cn("space-y-4", className)}>
39
- {(title || description) && (
40
- <div className="space-y-1">
41
- {title && (
42
- <h3 className="text-lg font-semibold text-foreground">
43
- {title}
44
- </h3>
45
- )}
46
- {description && (
47
- <p className="text-sm text-muted-foreground">
48
- {description}
49
- </p>
50
- )}
51
- </div>
52
- )}
53
-
54
- <div className={cn(
55
- layout === "grid"
56
- ? `grid gap-4 ${gridClasses[columns]}`
57
- : spacingClasses[spacing]
58
- )}>
59
- {children}
60
- </div>
61
- </div>
62
- )
63
- }
64
- )
65
-
66
- FormSection.displayName = "FormSection"