# Ejemplos de Uso - UniClienteUniPunto

## 📖 Guía de Uso de Componentes y Hooks

### 1. Uso del Hook Principal

```typescript
import { useContratoUniClienteUniPunto } from './hooks';

const MyComponent = ({ clientes }) => {
    const {
        data,
        errors,
        processing,
        selectedCliente,
        handleClienteChange,
        saveContrato,
        isFormValid,
    } = useContratoUniClienteUniPunto({ clientes });

    return (
        <div>
            {/* Tu componente aquí */}
            <button onClick={saveContrato} disabled={!isFormValid()}>
                Guardar
            </button>
        </div>
    );
};
```

### 2. Uso del Componente ClienteSection

```typescript
import { ClienteSection } from './components';

const MyForm = () => {
    const [cliente, setCliente] = useState(null);
    
    return (
        <ClienteSection
            documentoFiscal={cliente?.documento || ''}
            razonSocial={cliente?.razon_social || ''}
            fechaPropuesta={new Date().toISOString().split('T')[0]}
            numeroPropuesta=""
            estatus=""
            clientesOptions={clientesData}
            selectedCliente={cliente ? [cliente] : []}
            errors={{}}
            onClienteChange={(selected) => setCliente(selected[0])}
            onFechaPropuestaChange={(fecha) => console.log(fecha)}
        />
    );
};
```

### 3. Uso del Hook useCupsElectrico

```typescript
import { useCupsElectrico } from './hooks';

const ElectricForm = ({ datos, onChange }) => {
    const {
        formDataElectrico,
        setFormDataElectrico,
        cupsOptions,
        tarifaOptions,
        formErrors,
        showErrors,
        handleBuscarSipsCups,
        saveElectricoForm,
    } = useCupsElectrico({
        comercializadoras,
        productos,
        anexos,
        cupsData,
        localidades,
        clientes,
        clienteId: 123,
        datos,
        onChange
    });

    return (
        <div>
            {/* Formulario eléctrico */}
            <button onClick={handleBuscarSipsCups}>
                Buscar en SIPS
            </button>
            <button onClick={saveElectricoForm}>
                Guardar
            </button>
        </div>
    );
};
```

### 4. Uso del Componente DatosComerciales

```typescript
import { DatosComerciales } from './components';

const CommercialData = () => {
    const [formData, setFormData] = useState({
        comercializadora: '',
        producto: '',
        anexo: '',
        tipoprecio: ''
    });

    return (
        <DatosComerciales
            comercializadora={formData.comercializadora}
            producto={formData.producto}
            anexo={formData.anexo}
            tipoprecio={formData.tipoprecio}
            comercializadoras={comercializadorasData}
            productosFiltrados={productosData}
            anexosFiltrados={anexosData}
            tipoprecios={tipopreciosData}
            showErrors={false}
            formErrors={{}}
            onComercializadoraChange={(e) => 
                setFormData({ ...formData, comercializadora: e.target.value })
            }
            onProductoChange={(e) => 
                setFormData({ ...formData, producto: e.target.value })
            }
            onAnexoChange={(e) => 
                setFormData({ ...formData, anexo: e.target.value })
            }
            onTipoPrecioChange={(value) => 
                setFormData({ ...formData, tipoprecio: value })
            }
        />
    );
};
```

### 5. Uso del Componente CupsToggleButton

```typescript
import { CupsToggleButton } from './components';

const MyForm = () => {
    const [showElectric, setShowElectric] = useState(true);
    const [showGas, setShowGas] = useState(false);

    return (
        <div>
            <CupsToggleButton
                show={showElectric}
                onToggle={() => setShowElectric(!showElectric)}
                type="electric"
            />
            
            <CupsToggleButton
                show={showGas}
                onToggle={() => setShowGas(!showGas)}
                type="gas"
            />
        </div>
    );
};
```

### 6. Uso de Utilidades

```typescript
import { getSelectedTypeaheadValue } from './utils';

const MyTypeahead = ({ options, value }) => {
    const selected = getSelectedTypeaheadValue(options, value, 'id');
    
    return (
        <Typeahead
            id="my-typeahead"
            labelKey="name"
            options={options}
            selected={selected}
            onChange={(selected) => console.log(selected)}
        />
    );
};
```

## 🔧 Patrones Comunes

### Patrón 1: Formulario con Validación

```typescript
const FormWithValidation = () => {
    const {
        formDataElectrico,
        setFormDataElectrico,
        formErrors,
        showErrors,
        saveElectricoForm,
    } = useCupsElectrico({ /* props */ });

    const handleSubmit = () => {
        const isValid = saveElectricoForm();
        if (isValid) {
            console.log('Formulario válido');
        } else {
            console.log('Errores:', formErrors);
        }
    };

    return (
        <form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
            {/* Campos del formulario */}
            {showErrors && formErrors.cups_electrico && (
                <div className="error">{formErrors.cups_electrico}</div>
            )}
        </form>
    );
};
```

### Patrón 2: Cascada de Selects

```typescript
const CascadingSelects = () => {
    const [comercializadora, setComercializadora] = useState('');
    const [producto, setProducto] = useState('');
    
    // Los productos se filtran automáticamente en el hook
    const { productosFiltrados } = useCupsElectrico({ 
        comercializadora,
        /* otros props */
    });

    return (
        <div>
            <select 
                value={comercializadora} 
                onChange={(e) => {
                    setComercializadora(e.target.value);
                    setProducto(''); // Reset producto
                }}
            >
                {/* Opciones */}
            </select>
            
            <select 
                value={producto} 
                onChange={(e) => setProducto(e.target.value)}
                disabled={!comercializadora}
            >
                {productosFiltrados.map(p => (
                    <option key={p.id} value={p.id}>{p.name}</option>
                ))}
            </select>
        </div>
    );
};
```

### Patrón 3: Búsqueda Asíncrona

```typescript
const AsyncSearch = () => {
    const { handleBuscarSipsCups } = useCupsElectrico({ /* props */ });
    const [loading, setLoading] = useState(false);

    const handleSearch = async () => {
        setLoading(true);
        try {
            await handleBuscarSipsCups();
        } catch (error) {
            console.error('Error en búsqueda:', error);
        } finally {
            setLoading(false);
        }
    };

    return (
        <button onClick={handleSearch} disabled={loading}>
            {loading ? 'Buscando...' : 'Buscar en SIPS'}
        </button>
    );
};
```

### Patrón 4: Formulario Maestro-Detalle

```typescript
const MasterDetailForm = () => {
    const {
        data,
        formHijoElectrico,
        formHijoGas,
        saveContrato,
    } = useContratoUniClienteUniPunto({ clientes });

    const handleSave = () => {
        // Los formularios hijos se validan automáticamente
        saveContrato();
    };

    return (
        <div>
            {/* Formulario maestro (cliente) */}
            <ClienteSection {...clienteProps} />
            
            {/* Formularios detalle (CUPS) */}
            <CupsElectricSection ref={formHijoElectrico} {...electricProps} />
            <CupsGasSection ref={formHijoGas} {...gasProps} />
            
            <button onClick={handleSave}>Guardar Todo</button>
        </div>
    );
};
```

## 🎯 Casos de Uso Comunes

### Caso 1: Agregar un Nuevo Campo

```typescript
// 1. Agregar en la interfaz (Interfaces.ts)
export interface FormDataElectrico {
    // ... campos existentes
    nuevoCampo: string;
}

// 2. Agregar en las constantes (constants.ts)
export const initialFormDataElectrico: FormDataElectrico = {
    // ... campos existentes
    nuevoCampo: '',
};

// 3. Agregar en el componente
<Form.Control
    type="text"
    value={formDataElectrico.nuevoCampo || ''}
    onChange={(e) => setFormDataElectrico(prev => ({ 
        ...prev, 
        nuevoCampo: e.target.value 
    }))}
/>
```

### Caso 2: Agregar Validación Personalizada

```typescript
// En el hook useCupsElectrico
const saveElectricoForm = () => {
    setShowErrors(true);
    const currentErrors: { [key: string]: string } = {};
    
    // Validación existente...
    
    // Nueva validación
    if (formDataElectrico.nuevocampo && formDataElectrico.nuevoampo.length < 5) {
        currentErrors['nuevoampo'] = 'Debe tener al menos 5 caracteres';
        hasValidationErrors = true;
    }
    
    setFormErrors(currentErrors);
    return !hasValidationErrors;
};
```

### Caso 3: Agregar un Nuevo Componente Reutilizable

```typescript
// components/NuevoComponente.tsx
import React from 'react';
import { Form } from 'react-bootstrap';

interface NuevoComponenteProps {
    value: string;
    onChange: (value: string) => void;
    error?: string;
}

export const NuevoComponente: React.FC<NuevoComponenteProps> = ({
    value,
    onChange,
    error
}) => {
    return (
        <Form.Group>
            <Form.Label>Nuevo Campo</Form.Label>
            <Form.Control
                type="text"
                value={value}
                onChange={(e) => onChange(e.target.value)}
                isInvalid={!!error}
            />
            <Form.Control.Feedback type="invalid">
                {error}
            </Form.Control.Feedback>
        </Form.Group>
    );
};

// Exportar en components/index.ts
export { NuevoComponente } from './NuevoComponente';
```

## 📝 Mejores Prácticas

### 1. Siempre usar Barrel Exports

```typescript
// ❌ Mal
import { ClienteSection } from './components/ClienteSection';
import { DatosComerciales } from './components/DatosComerciales';

// ✅ Bien
import { ClienteSection, DatosComerciales } from './components';
```

### 2. Mantener Componentes Pequeños

```typescript
// ❌ Mal: Componente de 500 líneas
const BigComponent = () => {
    // Mucho código...
};

// ✅ Bien: Componentes pequeños y enfocados
const SmallComponent1 = () => { /* ... */ };
const SmallComponent2 = () => { /* ... */ };
const ParentComponent = () => (
    <>
        <SmallComponent1 />
        <SmallComponent2 />
    </>
);
```

### 3. Usar Hooks para Lógica Compleja

```typescript
// ❌ Mal: Lógica en el componente
const Component = () => {
    const [data, setData] = useState({});
    // Mucha lógica...
    
    return <div>{/* JSX */}</div>;
};

// ✅ Bien: Lógica en hook
const useMyLogic = () => {
    const [data, setData] = useState({});
    // Lógica encapsulada
    return { data, setData };
};

const Component = () => {
    const { data, setData } = useMyLogic();
    return <div>{/* JSX */}</div>;
};
```

### 4. Tipado Estricto

```typescript
// ❌ Mal
const handleChange = (e: any) => {
    setData(e.target.value);
};

// ✅ Bien
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setData(e.target.value);
};
```

## 🚀 Tips de Performance

### 1. Usar React.memo para Componentes Puros

```typescript
import React, { memo } from 'react';

export const ClienteSection = memo<ClienteSectionProps>(({
    // props
}) => {
    // componente
});
```

### 2. Usar useCallback para Handlers

```typescript
const handleChange = useCallback((value: string) => {
    setFormData(prev => ({ ...prev, field: value }));
}, []);
```

### 3. Usar useMemo para Cálculos Costosos

```typescript
const filteredData = useMemo(() => {
    return data.filter(item => item.active);
}, [data]);
```

---

**Última actualización**: Octubre 2025
**Versión**: 1.0.0

