'use client'; import { useEffect, useState, useCallback } from 'react'; import { useRouter, useParams } from 'next/navigation'; import Link from 'next/link'; import { profileSectionsService, profileFieldsService, agentTypesService, ProfileSection, ProfileField, AgentType, CreateFieldDto, UpdateFieldDto, FieldType, FieldOption, RangeConfig, FIELD_TYPES, getErrorMessage, } from '@/services'; type FieldModalType = 'create' | 'edit' | 'delete' | null; type AssignModalType = 'assign' | null; const REQUIRES_OPTIONS: FieldType[] = ['SELECT', 'RADIO', 'MULTI_SELECT', 'CHECKBOX_GROUP']; export default function SectionDetailPage() { const router = useRouter(); const params = useParams(); const sectionId = params.id as string; const [section, setSection] = useState(null); const [fields, setFields] = useState([]); const [agentTypes, setAgentTypes] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(''); // Field Modal state const [fieldModalType, setFieldModalType] = useState(null); const [selectedField, setSelectedField] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [modalError, setModalError] = useState(''); // Assign Modal state const [assignModalType, setAssignModalType] = useState(null); // Field Form state const [fieldForm, setFieldForm] = useState({ sectionId: '', name: '', fieldType: 'TEXT', description: '', placeholder: '', defaultValue: '', sortOrder: 0, isActive: true, isRequired: false, options: [], rangeConfig: undefined, }); // Options editor state const [optionInput, setOptionInput] = useState({ value: '', label: '' }); // Assignment form state const [assignForm, setAssignForm] = useState({ agentTypeId: '', sortOrder: 0, isRequired: false, }); const fetchData = useCallback(async () => { setIsLoading(true); setError(''); try { const [sectionData, fieldsData, agentTypesData] = await Promise.all([ profileSectionsService.getById(sectionId), profileFieldsService.getAll(sectionId, true), agentTypesService.getAll(true), ]); setSection(sectionData); setFields(fieldsData); setAgentTypes(agentTypesData); } catch (err) { const errorMessage = getErrorMessage(err); setError(errorMessage); if (errorMessage.includes('Unauthorized')) { router.push('/login'); } } finally { setIsLoading(false); } }, [sectionId, router]); useEffect(() => { if (sectionId) { fetchData(); } }, [sectionId, fetchData]); // Field Modal handlers const openCreateFieldModal = () => { setFieldForm({ sectionId, name: '', fieldType: 'TEXT', description: '', placeholder: '', defaultValue: '', sortOrder: fields.length, isActive: true, isRequired: false, options: [], rangeConfig: undefined, }); setOptionInput({ value: '', label: '' }); setModalError(''); setFieldModalType('create'); }; const openEditFieldModal = (field: ProfileField) => { setSelectedField(field); setFieldForm({ sectionId, name: field.name, fieldType: field.fieldType, description: field.description || '', placeholder: field.placeholder || '', defaultValue: field.defaultValue || '', sortOrder: field.sortOrder, isActive: field.isActive, isRequired: field.isRequired, options: field.options || [], rangeConfig: field.rangeConfig || undefined, }); setOptionInput({ value: '', label: '' }); setModalError(''); setFieldModalType('edit'); }; const openDeleteFieldModal = (field: ProfileField) => { setSelectedField(field); setModalError(''); setFieldModalType('delete'); }; const closeFieldModal = () => { setFieldModalType(null); setSelectedField(null); setModalError(''); }; const handleCreateField = async (e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); setModalError(''); try { await profileFieldsService.create(fieldForm); closeFieldModal(); fetchData(); } catch (err) { setModalError(getErrorMessage(err)); } finally { setIsSubmitting(false); } }; const handleUpdateField = async (e: React.FormEvent) => { e.preventDefault(); if (!selectedField) return; setIsSubmitting(true); setModalError(''); try { const { sectionId: _, ...updateData } = fieldForm; await profileFieldsService.update(selectedField.id, updateData as UpdateFieldDto); closeFieldModal(); fetchData(); } catch (err) { setModalError(getErrorMessage(err)); } finally { setIsSubmitting(false); } }; const handleDeleteField = async () => { if (!selectedField) return; setIsSubmitting(true); setModalError(''); try { await profileFieldsService.delete(selectedField.id); closeFieldModal(); fetchData(); } catch (err) { setModalError(getErrorMessage(err)); } finally { setIsSubmitting(false); } }; // Options management const addOption = () => { if (!optionInput.value.trim() || !optionInput.label.trim()) return; setFieldForm({ ...fieldForm, options: [...(fieldForm.options || []), { ...optionInput }], }); setOptionInput({ value: '', label: '' }); }; const removeOption = (index: number) => { setFieldForm({ ...fieldForm, options: (fieldForm.options || []).filter((_, i) => i !== index), }); }; // Range config management const updateRangeConfig = (key: keyof RangeConfig, value: number | string) => { setFieldForm({ ...fieldForm, rangeConfig: { min: fieldForm.rangeConfig?.min || 0, max: fieldForm.rangeConfig?.max || 100, step: fieldForm.rangeConfig?.step, unit: fieldForm.rangeConfig?.unit, [key]: typeof value === 'string' ? value : Number(value), }, }); }; // Toggle field status const toggleFieldStatus = async (field: ProfileField) => { try { await profileFieldsService.update(field.id, { isActive: !field.isActive }); fetchData(); } catch (err) { setError(getErrorMessage(err)); } }; // Assignment handlers const openAssignModal = () => { setAssignForm({ agentTypeId: '', sortOrder: 0, isRequired: false, }); setModalError(''); setAssignModalType('assign'); }; const closeAssignModal = () => { setAssignModalType(null); setModalError(''); }; const handleAssign = async (e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); setModalError(''); try { await profileSectionsService.assignToAgentType(sectionId, assignForm); closeAssignModal(); fetchData(); } catch (err) { setModalError(getErrorMessage(err)); } finally { setIsSubmitting(false); } }; const handleRemoveAssignment = async (agentTypeId: string) => { if (!confirm('Remove this section from the agent type?')) return; try { await profileSectionsService.removeFromAgentType(sectionId, agentTypeId); fetchData(); } catch (err) { setError(getErrorMessage(err)); } }; const getFieldTypeLabel = (type: FieldType) => { const found = FIELD_TYPES.find((ft) => ft.value === type); return found?.label || type; }; if (isLoading) { return (
); } if (!section) { return (

Section not found

Back to sections
); } // Get assigned agent types const assignedAgentTypeIds = section.agentTypeSections?.map((ats) => ats.agentTypeId) || []; const availableAgentTypes = agentTypes.filter((at) => !assignedAgentTypeIds.includes(at.id)); return (
{/* Breadcrumb */}
← Back to Profile Sections
{/* Page Header */}
{section.icon && {section.icon}}

{section.name}

{section.isGlobal && ( Global )}

{section.description || 'No description'}

{error && (

{error}

)}
{/* Fields Section */}

Fields ({fields.length})

{fields.length === 0 ? (

No fields defined yet

) : ( fields.map((field, index) => (
#{index + 1} {field.name} {field.isRequired && ( *required )}
{getFieldTypeLabel(field.fieldType)} {field.slug} {field.placeholder && ( placeholder: {field.placeholder} )}
{field.options && field.options.length > 0 && (
{(field.options as FieldOption[]).slice(0, 5).map((opt, i) => ( {opt.label} ))} {field.options.length > 5 && ( +{field.options.length - 5} more )}
)}
)) )}
{/* Agent Type Assignments */}

Agent Types

{!section.isGlobal && availableAgentTypes.length > 0 && ( )}
{section.isGlobal ? (
Available to all agent types

This is a global section and appears for all agent types.

) : section.agentTypeSections && section.agentTypeSections.length > 0 ? (
{section.agentTypeSections.map((ats) => { const agentType = agentTypes.find((at) => at.id === ats.agentTypeId); return (

{agentType?.name || 'Unknown'}

{ats.isRequired ? 'Required' : 'Optional'} • Order: {ats.sortOrder}

); })}
) : (

Not assigned to any agent type

{availableAgentTypes.length > 0 && ( )}
)}
{/* Field Create/Edit Modal */} {(fieldModalType === 'create' || fieldModalType === 'edit') && (

{fieldModalType === 'create' ? 'Create Field' : 'Edit Field'}

{modalError && (

{modalError}

)}
setFieldForm({ ...fieldForm, name: e.target.value })} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-gray-900 bg-white" required />
setFieldForm({ ...fieldForm, description: e.target.value })} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-gray-900 bg-white placeholder:text-gray-500" placeholder="Help text for this field" />
setFieldForm({ ...fieldForm, placeholder: e.target.value })} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-gray-900 bg-white" />
setFieldForm({ ...fieldForm, defaultValue: e.target.value })} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-gray-900 bg-white" />
setFieldForm({ ...fieldForm, sortOrder: parseInt(e.target.value) || 0 })} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-gray-900 bg-white" />
setFieldForm({ ...fieldForm, isActive: e.target.checked })} className="rounded border-gray-300 text-blue-600 focus:ring-blue-500" />
setFieldForm({ ...fieldForm, isRequired: e.target.checked })} className="rounded border-gray-300 text-red-600 focus:ring-red-500" />
{/* Options Editor for SELECT, RADIO, MULTI_SELECT, CHECKBOX_GROUP */} {REQUIRES_OPTIONS.includes(fieldForm.fieldType) && (
setOptionInput({ ...optionInput, value: e.target.value })} placeholder="Value" className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm text-gray-900 bg-white placeholder:text-gray-500" /> setOptionInput({ ...optionInput, label: e.target.value })} placeholder="Label" className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm text-gray-900 bg-white placeholder:text-gray-500" />
{fieldForm.options && fieldForm.options.length > 0 && (
{fieldForm.options.map((opt, index) => (
{opt.value} {opt.label}
))}
)}
)} {/* Range Config for RANGE type */} {fieldForm.fieldType === 'RANGE' && (
updateRangeConfig('min', e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm text-gray-900 bg-white" />
updateRangeConfig('max', e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm text-gray-900 bg-white" />
updateRangeConfig('step', e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm text-gray-900 bg-white" />
updateRangeConfig('unit', e.target.value)} placeholder="e.g., years" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm text-gray-900 bg-white placeholder:text-gray-500" />
)}
)} {/* Field Delete Modal */} {fieldModalType === 'delete' && selectedField && (

Delete Field

{modalError && (

{modalError}

)}

Are you sure you want to delete the field {selectedField.name}?

)} {/* Assign to Agent Type Modal */} {assignModalType === 'assign' && (

Assign to Agent Type

{modalError && (

{modalError}

)}
setAssignForm({ ...assignForm, sortOrder: parseInt(e.target.value) || 0 })} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-gray-900 bg-white" />
setAssignForm({ ...assignForm, isRequired: e.target.checked })} className="rounded border-gray-300 text-blue-600 focus:ring-blue-500" />
)}
); }