@djangocfg/ui-nextjs 1.4.45

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 (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +152 -0
  3. package/package.json +110 -0
  4. package/src/animations/AnimatedBackground.tsx +645 -0
  5. package/src/animations/index.ts +2 -0
  6. package/src/blocks/ArticleCard.tsx +94 -0
  7. package/src/blocks/ArticleList.tsx +95 -0
  8. package/src/blocks/CTASection.tsx +136 -0
  9. package/src/blocks/FeatureSection.tsx +104 -0
  10. package/src/blocks/Hero.tsx +102 -0
  11. package/src/blocks/NewsletterSection.tsx +119 -0
  12. package/src/blocks/StatsSection.tsx +103 -0
  13. package/src/blocks/SuperHero.tsx +328 -0
  14. package/src/blocks/TestimonialSection.tsx +122 -0
  15. package/src/blocks/index.ts +9 -0
  16. package/src/components/README.md +2018 -0
  17. package/src/components/breadcrumb-navigation.tsx +127 -0
  18. package/src/components/breadcrumb.tsx +132 -0
  19. package/src/components/button-download.tsx +275 -0
  20. package/src/components/dropdown-menu.tsx +219 -0
  21. package/src/components/index.ts +86 -0
  22. package/src/components/markdown/MarkdownMessage.tsx +338 -0
  23. package/src/components/markdown/index.ts +5 -0
  24. package/src/components/menubar.tsx +274 -0
  25. package/src/components/multi-select-pro/async.tsx +608 -0
  26. package/src/components/multi-select-pro/helpers.tsx +84 -0
  27. package/src/components/multi-select-pro/index.tsx +622 -0
  28. package/src/components/navigation-menu.tsx +153 -0
  29. package/src/components/pagination-static.tsx +348 -0
  30. package/src/components/pagination.tsx +138 -0
  31. package/src/components/phone-input.tsx +276 -0
  32. package/src/components/sidebar.tsx +866 -0
  33. package/src/components/sonner.tsx +31 -0
  34. package/src/components/ssr-pagination.tsx +237 -0
  35. package/src/hooks/index.ts +19 -0
  36. package/src/hooks/useCfgRouter.ts +153 -0
  37. package/src/hooks/useLocalStorage.ts +221 -0
  38. package/src/hooks/useQueryParams.ts +73 -0
  39. package/src/hooks/useSessionStorage.ts +188 -0
  40. package/src/hooks/useTheme.ts +57 -0
  41. package/src/index.ts +24 -0
  42. package/src/lib/index.ts +2 -0
  43. package/src/styles/index.css +2 -0
  44. package/src/theme/ForceTheme.tsx +115 -0
  45. package/src/theme/ThemeProvider.tsx +82 -0
  46. package/src/theme/ThemeToggle.tsx +52 -0
  47. package/src/theme/index.ts +3 -0
  48. package/src/tools/JsonForm/JsonSchemaForm.tsx +199 -0
  49. package/src/tools/JsonForm/examples/BotConfigExample.tsx +245 -0
  50. package/src/tools/JsonForm/examples/RealBotConfigExample.tsx +157 -0
  51. package/src/tools/JsonForm/index.ts +46 -0
  52. package/src/tools/JsonForm/templates/ArrayFieldItemTemplate.tsx +46 -0
  53. package/src/tools/JsonForm/templates/ArrayFieldTemplate.tsx +73 -0
  54. package/src/tools/JsonForm/templates/BaseInputTemplate.tsx +106 -0
  55. package/src/tools/JsonForm/templates/ErrorListTemplate.tsx +34 -0
  56. package/src/tools/JsonForm/templates/FieldTemplate.tsx +61 -0
  57. package/src/tools/JsonForm/templates/ObjectFieldTemplate.tsx +43 -0
  58. package/src/tools/JsonForm/templates/index.ts +12 -0
  59. package/src/tools/JsonForm/types.ts +83 -0
  60. package/src/tools/JsonForm/utils.ts +212 -0
  61. package/src/tools/JsonForm/widgets/CheckboxWidget.tsx +36 -0
  62. package/src/tools/JsonForm/widgets/NumberWidget.tsx +88 -0
  63. package/src/tools/JsonForm/widgets/SelectWidget.tsx +100 -0
  64. package/src/tools/JsonForm/widgets/SwitchWidget.tsx +34 -0
  65. package/src/tools/JsonForm/widgets/TextWidget.tsx +95 -0
  66. package/src/tools/JsonForm/widgets/index.ts +12 -0
  67. package/src/tools/JsonTree/index.tsx +252 -0
  68. package/src/tools/LottiePlayer/LottiePlayer.client.tsx +212 -0
  69. package/src/tools/LottiePlayer/index.tsx +54 -0
  70. package/src/tools/LottiePlayer/types.ts +108 -0
  71. package/src/tools/LottiePlayer/useLottie.ts +163 -0
  72. package/src/tools/Mermaid/Mermaid.client.tsx +341 -0
  73. package/src/tools/Mermaid/index.tsx +40 -0
  74. package/src/tools/OpenapiViewer/components/EndpointInfo.tsx +144 -0
  75. package/src/tools/OpenapiViewer/components/EndpointsLibrary.tsx +255 -0
  76. package/src/tools/OpenapiViewer/components/PlaygroundLayout.tsx +123 -0
  77. package/src/tools/OpenapiViewer/components/PlaygroundStepper.tsx +98 -0
  78. package/src/tools/OpenapiViewer/components/RequestBuilder.tsx +164 -0
  79. package/src/tools/OpenapiViewer/components/RequestParametersForm.tsx +253 -0
  80. package/src/tools/OpenapiViewer/components/ResponseViewer.tsx +169 -0
  81. package/src/tools/OpenapiViewer/components/VersionSelector.tsx +64 -0
  82. package/src/tools/OpenapiViewer/components/index.ts +14 -0
  83. package/src/tools/OpenapiViewer/constants.ts +39 -0
  84. package/src/tools/OpenapiViewer/context/PlaygroundContext.tsx +338 -0
  85. package/src/tools/OpenapiViewer/hooks/index.ts +8 -0
  86. package/src/tools/OpenapiViewer/hooks/useMobile.ts +10 -0
  87. package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +203 -0
  88. package/src/tools/OpenapiViewer/index.tsx +36 -0
  89. package/src/tools/OpenapiViewer/types.ts +152 -0
  90. package/src/tools/OpenapiViewer/utils/apiKeyManager.ts +149 -0
  91. package/src/tools/OpenapiViewer/utils/formatters.ts +71 -0
  92. package/src/tools/OpenapiViewer/utils/index.ts +9 -0
  93. package/src/tools/OpenapiViewer/utils/versionManager.ts +161 -0
  94. package/src/tools/PrettyCode/PrettyCode.client.tsx +217 -0
  95. package/src/tools/PrettyCode/index.tsx +43 -0
  96. package/src/tools/VideoPlayer/README.md +239 -0
  97. package/src/tools/VideoPlayer/VideoControls.tsx +138 -0
  98. package/src/tools/VideoPlayer/VideoPlayer.tsx +230 -0
  99. package/src/tools/VideoPlayer/index.ts +9 -0
  100. package/src/tools/VideoPlayer/types.ts +62 -0
  101. package/src/tools/index.ts +43 -0
@@ -0,0 +1,199 @@
1
+ 'use client';
2
+
3
+ import React, { useMemo, useCallback } from 'react';
4
+ import Form from '@rjsf/core';
5
+ import validator from '@rjsf/validator-ajv8';
6
+ import { RegistryWidgetsType } from '@rjsf/utils';
7
+ import { Button, Alert, AlertDescription } from '@djangocfg/ui-core/components';
8
+ import { AlertCircle } from 'lucide-react';
9
+ import consola from 'consola';
10
+
11
+ import { JsonSchemaFormProps } from './types';
12
+ import {
13
+ TextWidget,
14
+ NumberWidget,
15
+ CheckboxWidget,
16
+ SelectWidget,
17
+ SwitchWidget,
18
+ } from './widgets';
19
+ import {
20
+ FieldTemplate,
21
+ ObjectFieldTemplate,
22
+ ArrayFieldTemplate,
23
+ ArrayFieldItemTemplate,
24
+ ErrorListTemplate,
25
+ BaseInputTemplate,
26
+ } from './templates';
27
+ import { validateSchema, normalizeFormData } from './utils';
28
+
29
+ /**
30
+ * JSON Schema Form Component
31
+ *
32
+ * A fully-featured form generator that creates forms from JSON Schema.
33
+ * Built on top of react-jsonschema-form with custom widgets and templates
34
+ * using @djangocfg/ui components.
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * const schema = {
39
+ * type: 'object',
40
+ * required: ['name'],
41
+ * properties: {
42
+ * name: { type: 'string', title: 'Name' },
43
+ * age: { type: 'number', title: 'Age' },
44
+ * active: { type: 'boolean', title: 'Active' }
45
+ * }
46
+ * };
47
+ *
48
+ * <JsonSchemaForm
49
+ * schema={schema}
50
+ * onSubmit={(data) => console.log(data.formData)}
51
+ * />
52
+ * ```
53
+ */
54
+ export function JsonSchemaForm<T = any>(props: JsonSchemaFormProps<T>) {
55
+ const {
56
+ schema,
57
+ uiSchema,
58
+ formData,
59
+ onSubmit,
60
+ onChange,
61
+ onError,
62
+ showErrorList = 'top',
63
+ liveValidate = false,
64
+ disabled = false,
65
+ readonly = false,
66
+ className,
67
+ showSubmitButton = true,
68
+ submitButtonText = 'Submit',
69
+ ...restProps
70
+ } = props;
71
+
72
+ // Validate and normalize schema before render
73
+ const validatedSchema = useMemo(() => {
74
+ if (process.env.NODE_ENV === 'development') {
75
+ consola.info('[JsonSchemaForm] Validating schema...', schema);
76
+ }
77
+ const result = validateSchema(schema);
78
+ if (!result && process.env.NODE_ENV === 'development') {
79
+ consola.error('[JsonSchemaForm] Schema validation failed');
80
+ }
81
+ return result;
82
+ }, [schema]);
83
+
84
+ // Normalize form data before render
85
+ const normalizedFormData = useMemo(() => {
86
+ if (!validatedSchema) {
87
+ if (process.env.NODE_ENV === 'development') {
88
+ consola.warn('[JsonSchemaForm] Cannot normalize formData - invalid schema');
89
+ }
90
+ return null;
91
+ }
92
+ if (process.env.NODE_ENV === 'development') {
93
+ consola.info('[JsonSchemaForm] Normalizing formData...', formData);
94
+ }
95
+ const normalized = normalizeFormData<T>(formData, validatedSchema);
96
+ if (process.env.NODE_ENV === 'development') {
97
+ consola.info('[JsonSchemaForm] Normalized formData:', normalized);
98
+ }
99
+ return normalized;
100
+ }, [formData, validatedSchema]);
101
+
102
+ // Memoize widgets mapping to prevent recreation on every render
103
+ // IMPORTANT: Widget keys must match RJSF's expected names:
104
+ // - For type: string -> uses 'TextWidget' or 'text'
105
+ // - For type: number/integer -> uses 'updown' or 'range'
106
+ // - For type: boolean -> uses 'checkbox' or 'select'
107
+ // - For enum fields -> uses 'SelectWidget' or 'select'
108
+ const widgets: RegistryWidgetsType = useMemo(() => ({
109
+ // Standard widget names (PascalCase) - used by RJSF internally
110
+ TextWidget,
111
+ NumberWidget,
112
+ CheckboxWidget,
113
+ SelectWidget,
114
+ SwitchWidget,
115
+ // Lowercase aliases - for uiSchema 'ui:widget' references
116
+ text: TextWidget,
117
+ number: NumberWidget,
118
+ checkbox: CheckboxWidget,
119
+ select: SelectWidget,
120
+ switch: SwitchWidget,
121
+ }), []);
122
+
123
+ // Memoize templates to prevent recreation on every render
124
+ const templates = useMemo(() => ({
125
+ FieldTemplate,
126
+ ObjectFieldTemplate,
127
+ ArrayFieldTemplate,
128
+ ArrayFieldItemTemplate,
129
+ ErrorListTemplate,
130
+ BaseInputTemplate,
131
+ }), []);
132
+
133
+ // Memoize callbacks
134
+ const handleSubmit = useCallback((data: any) => {
135
+ if (onSubmit) {
136
+ // Ensure clean data on submit
137
+ const cleanData = {
138
+ ...data,
139
+ formData: normalizeFormData(data.formData, validatedSchema!),
140
+ };
141
+ onSubmit(cleanData);
142
+ }
143
+ }, [onSubmit, validatedSchema]);
144
+
145
+ const handleChange = useCallback((data: any) => {
146
+ if (onChange) {
147
+ onChange(data);
148
+ }
149
+ }, [onChange]);
150
+
151
+ const handleError = useCallback((errors: any) => {
152
+ if (onError) {
153
+ onError(errors);
154
+ }
155
+ }, [onError]);
156
+
157
+ // Early return if schema is invalid
158
+ if (!validatedSchema) {
159
+ return (
160
+ <div className={className}>
161
+ <Alert variant="destructive">
162
+ <AlertCircle className="h-4 w-4" />
163
+ <AlertDescription>
164
+ Invalid schema provided. Please check the schema format.
165
+ </AlertDescription>
166
+ </Alert>
167
+ </div>
168
+ );
169
+ }
170
+
171
+ return (
172
+ <div className={className}>
173
+ <Form
174
+ schema={validatedSchema}
175
+ uiSchema={uiSchema}
176
+ formData={normalizedFormData}
177
+ validator={validator}
178
+ widgets={widgets}
179
+ templates={templates}
180
+ onSubmit={handleSubmit}
181
+ onChange={handleChange}
182
+ onError={handleError}
183
+ showErrorList={showErrorList}
184
+ liveValidate={liveValidate}
185
+ disabled={disabled}
186
+ readonly={readonly}
187
+ {...restProps}
188
+ >
189
+ {showSubmitButton && (
190
+ <div className="mt-6 flex gap-2">
191
+ <Button type="submit" disabled={disabled}>
192
+ {submitButtonText}
193
+ </Button>
194
+ </div>
195
+ )}
196
+ </Form>
197
+ </div>
198
+ );
199
+ }
@@ -0,0 +1,245 @@
1
+ 'use client';
2
+
3
+ import React, { useState } from 'react';
4
+ import { JsonSchemaForm } from '../JsonSchemaForm';
5
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@djangocfg/ui-core/components';
6
+ import { RJSFSchema, UiSchema } from '@rjsf/utils';
7
+ import consola from 'consola';
8
+
9
+ /**
10
+ * Example JSON Schema for Bot Configuration
11
+ */
12
+ const botConfigSchema: RJSFSchema = {
13
+ $schema: 'http://json-schema.org/draft-07/schema#',
14
+ title: 'Bot Configuration',
15
+ type: 'object',
16
+ required: ['name', 'exchange', 'bot_type'],
17
+ properties: {
18
+ name: {
19
+ type: 'string',
20
+ title: 'Bot Name',
21
+ description: 'A unique name for your trading bot',
22
+ minLength: 3,
23
+ maxLength: 50,
24
+ },
25
+ active: {
26
+ type: 'boolean',
27
+ title: 'Active',
28
+ description: 'Enable or disable the bot',
29
+ default: true,
30
+ },
31
+ enabled: {
32
+ type: 'boolean',
33
+ title: 'Enabled',
34
+ description: 'Whether the bot is enabled for trading',
35
+ default: false,
36
+ },
37
+ exchange: {
38
+ type: 'string',
39
+ title: 'Exchange',
40
+ description: 'Select the trading exchange',
41
+ enum: ['binance', 'bybit', 'okx', 'kucoin'],
42
+ },
43
+ bot_type: {
44
+ type: 'string',
45
+ title: 'Bot Type',
46
+ description: 'Type of trading bot',
47
+ enum: ['spot', 'futures', 'margin'],
48
+ },
49
+ settings: {
50
+ type: 'object',
51
+ title: 'Bot Settings',
52
+ properties: {
53
+ max_trades: {
54
+ type: 'integer',
55
+ title: 'Maximum Trades',
56
+ description: 'Maximum number of concurrent trades',
57
+ minimum: 1,
58
+ maximum: 100,
59
+ default: 3,
60
+ },
61
+ trade_amount: {
62
+ type: 'number',
63
+ title: 'Trade Amount (USD)',
64
+ description: 'Amount to invest per trade',
65
+ minimum: 10,
66
+ maximum: 10000,
67
+ default: 100,
68
+ },
69
+ stop_loss: {
70
+ type: 'number',
71
+ title: 'Stop Loss (%)',
72
+ description: 'Stop loss percentage',
73
+ minimum: 0.1,
74
+ maximum: 50,
75
+ default: 5,
76
+ },
77
+ take_profit: {
78
+ type: 'number',
79
+ title: 'Take Profit (%)',
80
+ description: 'Take profit percentage',
81
+ minimum: 0.1,
82
+ maximum: 100,
83
+ default: 10,
84
+ },
85
+ strategy: {
86
+ type: 'string',
87
+ title: 'Trading Strategy',
88
+ enum: ['scalping', 'swing', 'arbitrage', 'grid'],
89
+ },
90
+ },
91
+ },
92
+ api_credentials: {
93
+ type: 'object',
94
+ title: 'API Credentials',
95
+ required: ['api_key', 'api_secret'],
96
+ properties: {
97
+ api_key: {
98
+ type: 'string',
99
+ title: 'API Key',
100
+ description: 'Your exchange API key',
101
+ },
102
+ api_secret: {
103
+ type: 'string',
104
+ title: 'API Secret',
105
+ description: 'Your exchange API secret',
106
+ },
107
+ testnet: {
108
+ type: 'boolean',
109
+ title: 'Use Testnet',
110
+ description: 'Use testnet environment for testing',
111
+ default: true,
112
+ },
113
+ },
114
+ },
115
+ notifications: {
116
+ type: 'object',
117
+ title: 'Notifications',
118
+ properties: {
119
+ email: {
120
+ type: 'boolean',
121
+ title: 'Email Notifications',
122
+ default: true,
123
+ },
124
+ telegram: {
125
+ type: 'boolean',
126
+ title: 'Telegram Notifications',
127
+ default: false,
128
+ },
129
+ webhook: {
130
+ type: 'string',
131
+ title: 'Webhook URL',
132
+ format: 'uri',
133
+ },
134
+ },
135
+ },
136
+ },
137
+ };
138
+
139
+ /**
140
+ * UI Schema for customizing form appearance
141
+ */
142
+ const uiSchema: UiSchema = {
143
+ 'ui:submitButtonOptions': {
144
+ submitText: 'Save Bot Configuration',
145
+ },
146
+ name: {
147
+ 'ui:placeholder': 'My Trading Bot',
148
+ },
149
+ active: {
150
+ 'ui:widget': 'SwitchWidget',
151
+ },
152
+ enabled: {
153
+ 'ui:widget': 'SwitchWidget',
154
+ },
155
+ exchange: {
156
+ 'ui:placeholder': 'Select exchange...',
157
+ },
158
+ bot_type: {
159
+ 'ui:placeholder': 'Select bot type...',
160
+ },
161
+ settings: {
162
+ 'ui:className': 'grid grid-cols-2 gap-4',
163
+ strategy: {
164
+ 'ui:placeholder': 'Select strategy...',
165
+ },
166
+ },
167
+ api_credentials: {
168
+ api_secret: {
169
+ 'ui:widget': 'password',
170
+ },
171
+ testnet: {
172
+ 'ui:widget': 'SwitchWidget',
173
+ },
174
+ },
175
+ notifications: {
176
+ email: {
177
+ 'ui:widget': 'SwitchWidget',
178
+ },
179
+ telegram: {
180
+ 'ui:widget': 'SwitchWidget',
181
+ },
182
+ webhook: {
183
+ 'ui:placeholder': 'https://example.com/webhook',
184
+ },
185
+ },
186
+ };
187
+
188
+ /**
189
+ * Example component demonstrating JsonSchemaForm usage
190
+ */
191
+ export function BotConfigExample() {
192
+ const [formData, setFormData] = useState<any>();
193
+ const [submittedData, setSubmittedData] = useState<any>(null);
194
+
195
+ const handleSubmit = (data: any) => {
196
+ consola.success('Form submitted:', data.formData);
197
+ setSubmittedData(data.formData);
198
+ };
199
+
200
+ const handleChange = (data: any) => {
201
+ setFormData(data.formData);
202
+ };
203
+
204
+ return (
205
+ <div className="container mx-auto p-6 max-w-4xl">
206
+ <div className="space-y-6">
207
+ <Card>
208
+ <CardHeader>
209
+ <CardTitle>Bot Configuration Form</CardTitle>
210
+ <CardDescription>
211
+ Example of JSON Schema Form with Bot Configuration
212
+ </CardDescription>
213
+ </CardHeader>
214
+ <CardContent>
215
+ <JsonSchemaForm
216
+ schema={botConfigSchema}
217
+ uiSchema={uiSchema}
218
+ formData={formData}
219
+ onSubmit={handleSubmit}
220
+ onChange={handleChange}
221
+ liveValidate={false}
222
+ showErrorList="top"
223
+ />
224
+ </CardContent>
225
+ </Card>
226
+
227
+ {submittedData && (
228
+ <Card>
229
+ <CardHeader>
230
+ <CardTitle>Submitted Data</CardTitle>
231
+ <CardDescription>
232
+ The data that was submitted from the form
233
+ </CardDescription>
234
+ </CardHeader>
235
+ <CardContent>
236
+ <pre className="p-4 bg-muted rounded-md overflow-auto text-sm">
237
+ {JSON.stringify(submittedData, null, 2)}
238
+ </pre>
239
+ </CardContent>
240
+ </Card>
241
+ )}
242
+ </div>
243
+ </div>
244
+ );
245
+ }
@@ -0,0 +1,157 @@
1
+ 'use client';
2
+
3
+ import React, { useState } from 'react';
4
+ import { JsonSchemaForm } from '../JsonSchemaForm';
5
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@djangocfg/ui-core/components';
6
+ import { RJSFSchema } from '@rjsf/utils';
7
+ import consola from 'consola';
8
+
9
+ /**
10
+ * Real Bot Config Schema from API
11
+ * This is the actual schema returned by the backend
12
+ */
13
+ const realBotConfigSchema: RJSFSchema = {
14
+ type: 'object',
15
+ title: 'BotConfig',
16
+ $schema: 'http://json-schema.org/draft-07/schema#',
17
+ required: ['name', 'exchange'],
18
+ properties: {
19
+ name: {
20
+ type: 'string',
21
+ description: 'Bot name',
22
+ },
23
+ active: {
24
+ type: 'boolean',
25
+ description: 'Bot active',
26
+ },
27
+ enabled: {
28
+ type: 'boolean',
29
+ description: 'Bot enabled',
30
+ },
31
+ exchange: {
32
+ type: 'string',
33
+ description: 'Exchange name (binance, bybit, etc)',
34
+ },
35
+ direction: {
36
+ type: 'string',
37
+ description: 'Trading direction (long, short, both)',
38
+ },
39
+ amount_usdt: {
40
+ type: 'number',
41
+ description: 'Amount in USDT',
42
+ },
43
+ market_type: {
44
+ type: 'string',
45
+ description: 'Market type (spot, futures, swap)',
46
+ },
47
+ signal_type: {
48
+ type: 'string',
49
+ description: 'Signal type (listing, technical, etc)',
50
+ },
51
+ allowed_quotes: {
52
+ type: 'array',
53
+ items: {
54
+ type: 'string',
55
+ },
56
+ description: 'Allowed quote currencies',
57
+ },
58
+ allowed_sources: {
59
+ type: 'array',
60
+ items: {
61
+ type: 'string',
62
+ },
63
+ description: 'Allowed signal sources',
64
+ },
65
+ force_market_close_timer: {
66
+ type: 'integer',
67
+ description: 'Force close timer in seconds',
68
+ },
69
+ force_market_close_enabled: {
70
+ type: 'boolean',
71
+ description: 'Enable forced market close',
72
+ },
73
+ },
74
+ };
75
+
76
+ /**
77
+ * Real settings data from bot
78
+ */
79
+ const realSettings = {
80
+ version: '1.0.0',
81
+ hostname: 'botserver',
82
+ supported_exchanges: ['binance'],
83
+ supported_strategies: ['default'],
84
+ };
85
+
86
+ /**
87
+ * Example component with real bot config schema
88
+ */
89
+ export function RealBotConfigExample() {
90
+ const [formData, setFormData] = useState<any>(realSettings);
91
+ const [submittedData, setSubmittedData] = useState<any>(null);
92
+
93
+ const handleSubmit = (data: any) => {
94
+ consola.success('Form submitted:', data.formData);
95
+ setSubmittedData(data.formData);
96
+ };
97
+
98
+ const handleChange = (data: any) => {
99
+ consola.info('Form changed:', data.formData);
100
+ setFormData(data.formData);
101
+ };
102
+
103
+ return (
104
+ <div className="container mx-auto p-6 max-w-4xl">
105
+ <div className="space-y-6">
106
+ <Card>
107
+ <CardHeader>
108
+ <CardTitle>Real Bot Configuration Form</CardTitle>
109
+ <CardDescription>
110
+ Using actual schema from API response
111
+ </CardDescription>
112
+ </CardHeader>
113
+ <CardContent>
114
+ <JsonSchemaForm
115
+ schema={realBotConfigSchema}
116
+ formData={formData}
117
+ onSubmit={handleSubmit}
118
+ onChange={handleChange}
119
+ liveValidate={false}
120
+ showErrorList="top"
121
+ />
122
+ </CardContent>
123
+ </Card>
124
+
125
+ {submittedData && (
126
+ <Card>
127
+ <CardHeader>
128
+ <CardTitle>Submitted Data</CardTitle>
129
+ <CardDescription>
130
+ The data that was submitted from the form
131
+ </CardDescription>
132
+ </CardHeader>
133
+ <CardContent>
134
+ <pre className="p-4 bg-muted rounded-md overflow-auto text-sm">
135
+ {JSON.stringify(submittedData, null, 2)}
136
+ </pre>
137
+ </CardContent>
138
+ </Card>
139
+ )}
140
+
141
+ <Card>
142
+ <CardHeader>
143
+ <CardTitle>Current Form Data</CardTitle>
144
+ <CardDescription>
145
+ Real-time form data (onChange)
146
+ </CardDescription>
147
+ </CardHeader>
148
+ <CardContent>
149
+ <pre className="p-4 bg-muted rounded-md overflow-auto text-sm">
150
+ {JSON.stringify(formData, null, 2)}
151
+ </pre>
152
+ </CardContent>
153
+ </Card>
154
+ </div>
155
+ </div>
156
+ );
157
+ }
@@ -0,0 +1,46 @@
1
+ "use client"
2
+
3
+ /**
4
+ * JSON Schema Form Module
5
+ *
6
+ * A complete solution for generating forms from JSON Schema 7
7
+ * Built with React JSON Schema Form (rjsf), Radix UI, and Tailwind CSS
8
+ *
9
+ * Features:
10
+ * - Automatic form generation from JSON Schema
11
+ * - Custom widgets using @djangocfg/ui components
12
+ * - Validation with ajv8
13
+ * - TypeScript support
14
+ * - Responsive design
15
+ * - Dark mode support
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * import { JsonSchemaForm } from '@/components/JsonForm';
20
+ *
21
+ * const schema = {
22
+ * type: 'object',
23
+ * properties: {
24
+ * name: { type: 'string' },
25
+ * age: { type: 'number' }
26
+ * }
27
+ * };
28
+ *
29
+ * <JsonSchemaForm
30
+ * schema={schema}
31
+ * onSubmit={(data) => console.log(data)}
32
+ * />
33
+ * ```
34
+ */
35
+
36
+ export { JsonSchemaForm } from './JsonSchemaForm';
37
+ export type { JsonSchemaFormProps } from './types';
38
+
39
+ // Export widgets for custom usage
40
+ export * from './widgets';
41
+
42
+ // Export templates for custom usage
43
+ export * from './templates';
44
+
45
+ // Export utilities for advanced usage
46
+ export * from './utils';
@@ -0,0 +1,46 @@
1
+ "use client"
2
+
3
+ import React from 'react';
4
+ import { ArrayFieldItemTemplateProps, getTemplate, getUiOptions } from '@rjsf/utils';
5
+ import { cn } from '@djangocfg/ui-core/lib';
6
+
7
+ /**
8
+ * Array field item template for JSON Schema Form
9
+ * Renders individual array items with proper styling and action buttons
10
+ *
11
+ * In RJSF v6, this template is responsible for rendering each item in an array,
12
+ * including the item content (children) and the action buttons (remove, move up/down, copy).
13
+ */
14
+ export function ArrayFieldItemTemplate(props: ArrayFieldItemTemplateProps) {
15
+ const {
16
+ children,
17
+ className,
18
+ buttonsProps,
19
+ hasToolbar,
20
+ registry,
21
+ uiSchema,
22
+ } = props;
23
+
24
+ const uiOptions = getUiOptions(uiSchema);
25
+ const ArrayFieldItemButtonsTemplate = getTemplate(
26
+ 'ArrayFieldItemButtonsTemplate',
27
+ registry,
28
+ uiOptions,
29
+ );
30
+
31
+ return (
32
+ <div
33
+ className={cn(
34
+ 'flex gap-2 items-start p-4 rounded-md border bg-card',
35
+ className
36
+ )}
37
+ >
38
+ <div className="flex-1">{children}</div>
39
+ {hasToolbar && (
40
+ <div className="flex items-center gap-1">
41
+ <ArrayFieldItemButtonsTemplate {...buttonsProps} />
42
+ </div>
43
+ )}
44
+ </div>
45
+ );
46
+ }