almeira-web/src/components/publications/FormSection.tsx
Carlos (Almeira) dda9ae0f4a feat: implement robust publications module with real-time validation and state management
- Refactor dashboard entity pages to support dynamic publications management.
- Add Publications Module with Atomic Design components (PostCard, PublicationsList, FormSection).
- Implement Zod-based real-time validation for publication forms.
- Manage state using Zustand for optimistic UI and in-place relations.
- Add RBAC protection with PermissionGuard and server-side API validation.
- Fix: Resolve TypeScript type error in AdWrappers.tsx to ensure successful build.
- Add ToastProvider and ErrorBoundary for improved user experience.
- Update dependencies for publications logic.
2026-03-28 08:47:40 -05:00

63 lines
1.6 KiB
TypeScript

'use client';
/**
* @file FormSection.tsx
* @description Reusable form section wrapper with title, icon, and internal grid.
* Groups related form fields visually and logically.
*
* @example
* <FormSection title="Datos Básicos" icon={<FileText size={18} />} columns={2}>
* <input name="titulo" />
* <input name="slug" />
* </FormSection>
*/
import React from 'react';
import { FormSectionProps } from '@/types/publications';
/** Maps column count to Tailwind grid class */
const gridColsMap: Record<number, string> = {
1: 'grid-cols-1',
2: 'grid-cols-1 md:grid-cols-2',
3: 'grid-cols-1 md:grid-cols-3',
4: 'grid-cols-2 md:grid-cols-4',
6: 'grid-cols-2 md:grid-cols-6',
12: 'grid-cols-12',
};
export const FormSection: React.FC<FormSectionProps> = ({
title,
icon,
columns = 2,
children,
className = '',
}) => {
const gridClass = gridColsMap[columns] ?? 'grid-cols-1 md:grid-cols-2';
return (
<fieldset className={`border-0 p-0 m-0 ${className}`}>
{/* Section Header */}
<div className="flex items-center gap-3 mb-5">
{icon && (
<div className="p-2 bg-cyan-500/10 rounded-lg text-cyan-400 shrink-0">
{icon}
</div>
)}
<div className="flex-1">
<legend className="text-sm font-black text-white uppercase tracking-widest">
{title}
</legend>
<div className="mt-1.5 h-px bg-gradient-to-r from-cyan-500/40 via-slate-700/40 to-transparent" />
</div>
</div>
{/* Fields Grid */}
<div className={`grid ${gridClass} gap-5`}>
{children}
</div>
</fieldset>
);
};
export default FormSection;