mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
Some checks failed
CI/CD Pipeline / backend-build (push) Has been skipped
CI/CD Pipeline / backend-lint (push) Failing after 31s
CI/CD Pipeline / frontend-lint (push) Failing after 1m26s
CI/CD Pipeline / frontend-build (push) Has been skipped
CI/CD Pipeline / e2e-test (push) Has been skipped
- Fix prettier formatting issues in multiple components - Fix React Compiler memoization issues in ProductServiceMarkers.tsx - Replace literal strings with i18n keys across components - Address i18n issues in heritage, network graph, and match components - Fix dependency arrays in useMemo hooks to match React Compiler expectations
67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
import React from 'react';
|
||
import { useFieldArray, Control, FieldErrors, FieldValues, Path } from 'react-hook-form';
|
||
import Button from '@/components/ui/Button.tsx';
|
||
import { useTranslation } from '@/hooks/useI18n.tsx';
|
||
|
||
interface DynamicFieldArrayProps<T extends FieldValues> {
|
||
control: Control<T>;
|
||
name: Path<T>;
|
||
title: string;
|
||
addText: string;
|
||
errors: FieldErrors<T>;
|
||
defaultItem: Record<string, unknown>;
|
||
children?: (index: number) => React.ReactNode;
|
||
}
|
||
|
||
const DynamicFieldArray = <T extends FieldValues>({
|
||
control,
|
||
name,
|
||
title,
|
||
addText,
|
||
errors,
|
||
defaultItem,
|
||
children,
|
||
}: DynamicFieldArrayProps<T>) => {
|
||
const { t } = useTranslation();
|
||
const { fields, append, remove } = useFieldArray({ control, name });
|
||
const arrayErrors = errors[name as string];
|
||
|
||
return (
|
||
<div>
|
||
<h3 className="text-base font-semibold mb-2">{title}</h3>
|
||
<div className="space-y-3">
|
||
{fields.map((field, index) => (
|
||
<div key={field.id} className="flex items-start gap-2">
|
||
<div className="flex-1">{children && children(index)}</div>
|
||
<Button
|
||
type="button"
|
||
variant="outline"
|
||
onClick={() => remove(index)}
|
||
className="h-10 w-10 p-0 shrink-0 mt-1.5"
|
||
aria-label={t('form.removeItem')}
|
||
>
|
||
×
|
||
</Button>
|
||
</div>
|
||
))}
|
||
</div>
|
||
{arrayErrors && (
|
||
<p className="text-destructive text-xs mt-1">
|
||
{(arrayErrors as { message?: string; root?: { message?: string } })?.message ||
|
||
(arrayErrors as { message?: string; root?: { message?: string } })?.root?.message}
|
||
</p>
|
||
)}
|
||
<Button
|
||
type="button"
|
||
variant="ghost"
|
||
onClick={() => append(defaultItem)}
|
||
className="text-sm mt-2"
|
||
>
|
||
{addText}
|
||
</Button>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default DynamicFieldArray;
|