- Consolidate API logic: hooks/useApi.ts now uses services/api.ts - Create BaseFormField component to reduce form duplication - Refactor FormField, FormSelect, FormTextarea to use BaseFormField - Add centralized theme utility (utils/theme.ts) for colors/styles - Add comprehensive tests for api, auth.service, useApi hooks, AuthContext - Add tests for theme utility This reduces duplication from 11.45% and improves test coverage. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
58 lines
1.3 KiB
TypeScript
58 lines
1.3 KiB
TypeScript
'use client';
|
|
|
|
import React from 'react';
|
|
|
|
interface BaseFormFieldProps {
|
|
label: string;
|
|
name: string;
|
|
required?: boolean;
|
|
error?: string;
|
|
touched?: boolean;
|
|
className?: string;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
/**
|
|
* Base form field wrapper component that provides consistent styling
|
|
* for labels, error messages, and layout across all form components.
|
|
*/
|
|
export default function BaseFormField({
|
|
label,
|
|
name,
|
|
required = false,
|
|
error,
|
|
touched,
|
|
className = '',
|
|
children,
|
|
}: BaseFormFieldProps) {
|
|
const showError = touched && error;
|
|
|
|
return (
|
|
<div className={`mb-4 ${className}`}>
|
|
<label
|
|
htmlFor={name}
|
|
className="block text-sm font-medium text-gray-700 mb-2"
|
|
>
|
|
{label}
|
|
{required && <span className="text-red-500 ml-1">*</span>}
|
|
</label>
|
|
{children}
|
|
{showError && (
|
|
<p className="mt-1 text-sm text-red-500">{error}</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Common input class names for consistency
|
|
export const inputBaseClasses = `
|
|
w-full px-4 py-2 border rounded-lg
|
|
focus:outline-none focus:ring-2 focus:ring-primary-500
|
|
disabled:bg-gray-100 disabled:cursor-not-allowed
|
|
`;
|
|
|
|
export const getInputClasses = (hasError: boolean): string => `
|
|
${inputBaseClasses}
|
|
${hasError ? 'border-red-500' : 'border-gray-300'}
|
|
`;
|