- 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.
63 lines
1.6 KiB
TypeScript
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;
|