Skip to content

Commit ed99428

Browse files
committed
f
1 parent 45cd8c5 commit ed99428

File tree

6 files changed

+91
-82
lines changed

6 files changed

+91
-82
lines changed

web/src/components/common/Checkbox.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,31 @@ import React from 'react';
22
import { useSettings } from '../../contexts/SettingsContext';
33

44
interface CheckboxProps {
5-
id: string;
6-
label: string;
75
checked: boolean;
86
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
97
disabled?: boolean;
108
error?: string;
11-
helpText?: string;
129
className?: string;
1310
labelClassName?: string;
11+
12+
// props shared through ConfigItem
13+
id?: string;
14+
label?: string;
1415
dataTestId?: string;
16+
helpText?: string;
1517
}
1618

1719
const Checkbox: React.FC<CheckboxProps> = ({
18-
id,
19-
label,
2020
checked,
2121
onChange,
2222
disabled = false,
2323
error,
24-
helpText,
2524
className = '',
2625
labelClassName = '',
26+
id,
27+
label,
2728
dataTestId,
29+
helpText,
2830
}) => {
2931
const { settings } = useSettings();
3032
const themeColor = settings.themeColor;
@@ -43,6 +45,7 @@ const Checkbox: React.FC<CheckboxProps> = ({
4345
style={{
4446
color: themeColor,
4547
'--tw-ring-color': themeColor,
48+
accentColor: themeColor,
4649
} as React.CSSProperties}
4750
/>
4851
<label htmlFor={id} className={`text-sm text-gray-700 ${labelClassName}`}>

web/src/components/common/ConfigItem.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ interface ConfigItemProps {
1111
const ConfigItem: React.FC<ConfigItemProps> = ({
1212
id,
1313
label,
14-
dataTestId,
1514
helpText,
1615
children,
1716
}) => {
1817
// Clone the child element and inject the common props
1918
const enhancedChild = React.cloneElement(children, {
2019
id,
2120
label,
22-
dataTestId,
2321
helpText,
2422
} as any);
2523

2624
return (
27-
<div className="mb-4">
28-
{enhancedChild}
25+
<div key={id} data-testid={`config-item-${id}`}>
26+
<div className="mb-4">
27+
{enhancedChild}
28+
</div>
2929
</div>
3030
);
3131
};
@@ -40,7 +40,6 @@ export const withConfigItem = <P extends object>(
4040
<ConfigItem
4141
id={id}
4242
label={label}
43-
dataTestId={dataTestId}
4443
helpText={helpText}
4544
>
4645
<WrappedComponent {...(wrappedComponentProps as P)} ref={ref} />

web/src/components/common/Input.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,41 @@ import React from 'react';
22
import { useSettings } from '../../contexts/SettingsContext';
33

44
interface InputProps {
5-
id: string;
6-
label: string;
75
type?: string;
86
value: string;
9-
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
10-
onKeyDown?: (e: React.KeyboardEvent) => void;
7+
icon?: React.ReactNode;
118
placeholder?: string;
129
required?: boolean;
10+
onKeyDown?: (e: React.KeyboardEvent) => void;
11+
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
1312
disabled?: boolean;
1413
error?: string;
15-
helpText?: string;
1614
className?: string;
1715
labelClassName?: string;
18-
icon?: React.ReactNode;
16+
17+
// props shared through ConfigItem
18+
id?: string;
19+
label?: string;
1920
dataTestId?: string;
21+
helpText?: string;
2022
}
2123

2224
const Input: React.FC<InputProps> = ({
23-
id,
24-
label,
2525
type = 'text',
2626
value,
27-
onChange,
28-
onKeyDown,
27+
icon,
2928
placeholder = '',
3029
required = false,
30+
onKeyDown,
31+
onChange,
3132
disabled = false,
3233
error,
33-
helpText,
3434
className = '',
3535
labelClassName = '',
36-
icon,
36+
id,
37+
label,
3738
dataTestId,
39+
helpText,
3840
}) => {
3941
const { settings } = useSettings();
4042
const themeColor = settings.themeColor;

web/src/components/common/Radio.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,33 @@ import { useSettings } from '../../contexts/SettingsContext';
33
import { AppConfigChildItem } from '../../types';
44

55
interface RadioProps {
6-
id: string;
7-
label: string;
86
value: string;
9-
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
107
options: AppConfigChildItem[];
8+
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
119
disabled?: boolean;
1210
error?: string;
13-
helpText?: string;
1411
className?: string;
1512
labelClassName?: string;
13+
14+
// props shared through ConfigItem
15+
id?: string;
16+
label?: string;
1617
dataTestId?: string;
18+
helpText?: string;
1719
}
1820

1921
const Radio: React.FC<RadioProps> = ({
20-
id,
21-
label,
22-
value,
23-
onChange,
24-
options,
25-
disabled = false,
26-
error,
27-
helpText,
28-
className = '',
29-
labelClassName = '',
30-
dataTestId,
22+
value,
23+
options,
24+
onChange,
25+
disabled = false,
26+
error,
27+
className = '',
28+
labelClassName = '',
29+
id,
30+
label,
31+
dataTestId,
32+
helpText,
3133
}) => {
3234
const { settings } = useSettings();
3335
const themeColor = settings.themeColor;
@@ -53,6 +55,7 @@ const Radio: React.FC<RadioProps> = ({
5355
style={{
5456
color: themeColor,
5557
'--tw-ring-color': themeColor,
58+
accentColor: themeColor,
5659
} as React.CSSProperties}
5760
/>
5861
<label htmlFor={option.name} className="ml-3 text-sm text-gray-700">

web/src/components/common/Textarea.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,37 @@ import { ChangeEvent, CSSProperties } from 'react';
22
import { useSettings } from '../../contexts/SettingsContext';
33

44
interface TextareaProps {
5-
id: string;
6-
label: string;
75
value: string;
8-
onChange: (e: ChangeEvent<HTMLTextAreaElement>) => void;
96
rows?: number;
107
placeholder?: string;
118
required?: boolean;
9+
onChange: (e: ChangeEvent<HTMLTextAreaElement>) => void;
1210
disabled?: boolean;
1311
error?: string;
14-
helpText?: string;
1512
className?: string;
1613
labelClassName?: string;
14+
15+
// props shared through ConfigItem
16+
id?: string;
17+
label?: string;
1718
dataTestId?: string;
19+
helpText?: string;
1820
}
1921

2022
const Textarea = ({
21-
id,
22-
label,
2323
value,
24-
onChange,
2524
rows = 4,
2625
placeholder = '',
2726
required = false,
27+
onChange,
2828
disabled = false,
2929
error,
30-
helpText,
3130
className = '',
3231
labelClassName = '',
32+
id,
33+
label,
3334
dataTestId,
35+
helpText,
3436
}: TextareaProps) => {
3537
const { settings } = useSettings();
3638
const themeColor = settings.themeColor;

web/src/components/wizard/config/ConfigurationStep.tsx

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Input from '../../common/Input';
66
import Textarea from '../../common/Textarea';
77
import Checkbox from '../../common/Checkbox';
88
import Radio from '../../common/Radio';
9+
import ConfigItem from '../../common/ConfigItem';
910
import { useWizard } from '../../../contexts/WizardModeContext';
1011
import { useAuth } from '../../../contexts/AuthContext';
1112
import { useSettings } from '../../../contexts/SettingsContext';
@@ -163,53 +164,44 @@ const ConfigurationStep: React.FC<ConfigurationStepProps> = ({ onNext }) => {
163164
};
164165

165166
const renderConfigItem = (item: AppConfigItem) => {
166-
const sharedProps = {
167-
id: item.name,
168-
label: item.title,
169-
helpText: item.help_text,
170-
}
171-
172167
switch (item.type) {
173168
case 'text':
174169
return (
175-
<Input
176-
{...sharedProps}
177-
value={getDisplayValue(item)}
178-
onChange={handleInputChange}
179-
dataTestId={`text-input-${item.name}`}
180-
/>
170+
<Input
171+
value={getDisplayValue(item)}
172+
onChange={handleInputChange}
173+
dataTestId={`text-input-${item.name}`}
174+
/>
181175
);
182176

183177
case 'textarea':
184178
return (
185-
<Textarea
186-
{...sharedProps}
187-
value={getDisplayValue(item)}
188-
onChange={handleInputChange}
189-
dataTestId={`textarea-input-${item.name}`}
190-
/>
179+
<Textarea
180+
value={getDisplayValue(item)}
181+
onChange={handleInputChange}
182+
dataTestId={`textarea-input-${item.name}`}
183+
/>
184+
191185
);
192186

193187
case 'bool':
194188
return (
195-
<Checkbox
196-
{...sharedProps}
197-
checked={getEffectiveValue(item) === '1'}
198-
onChange={handleCheckboxChange}
199-
dataTestId={`bool-input-${item.name}`}
200-
/>
189+
<Checkbox
190+
checked={getEffectiveValue(item) === '1'}
191+
onChange={handleCheckboxChange}
192+
dataTestId={`bool-input-${item.name}`}
193+
/>
201194
);
202195

203196
case 'radio':
204197
if (item.items) {
205198
return (
206-
<Radio
207-
{...sharedProps}
208-
value={getEffectiveValue(item)}
209-
options={item.items}
210-
onChange={e => handleRadioChange(item.name, e)}
211-
dataTestId={`radio-input-${item.name}`}
212-
/>
199+
<Radio
200+
value={getEffectiveValue(item)}
201+
options={item.items}
202+
onChange={e => handleRadioChange(item.name, e)}
203+
dataTestId={`radio-input-${item.name}`}
204+
/>
213205
);
214206
}
215207
return null;
@@ -227,11 +219,19 @@ const ConfigurationStep: React.FC<ConfigurationStepProps> = ({ onNext }) => {
227219
{group.description && (
228220
<p className="text-gray-600 mb-4">{group.description}</p>
229221
)}
230-
{group.items.map(item => (
231-
<div key={item.name} data-testid={`config-item-${item.name}`}>
232-
{renderConfigItem(item)}
233-
</div>
234-
))}
222+
{group.items.map(item => {
223+
const renderedItem = renderConfigItem(item);
224+
if (!renderedItem) return null;
225+
return (
226+
<ConfigItem
227+
id={item.name}
228+
label={item.title}
229+
helpText={item.help_text}
230+
>
231+
{renderedItem}
232+
</ConfigItem>
233+
);
234+
})}
235235
</div>
236236
);
237237
};

0 commit comments

Comments
 (0)