big refactor

This commit is contained in:
2026-04-29 16:25:11 -05:00
parent 6c411ce2b6
commit 8265fb689a
156 changed files with 15845 additions and 50373 deletions

View File

@@ -1,35 +1,143 @@
<script setup lang="ts">
import { useProfileLayouts } from '~/composables/useProfileLayouts'
import type { ProfileLayout } from '~/composables/useProfileLayouts'
definePageMeta({ ssr: false })
usePageTitle('Profile Layouts · Settings')
const {
layouts,
activeLayoutId,
activeLayout,
sortedSections,
setActiveLayout,
updateLayout,
removeCustomLayout,
resetToDefaults,
} = useProfileLayouts()
interface ProfileSection {
id: string
label: string
visible: boolean
order: number
}
interface ProfileLayout {
id: string
name: string
description: string
icon: string
isCustom: boolean
defaultTab: string
sections: ProfileSection[]
}
const STORAGE_KEY = 'policy-ui.profile-layouts'
function loadLayouts(): ProfileLayout[] {
if (import.meta.client) {
const stored = localStorage.getItem(STORAGE_KEY)
if (stored) {
try {
return JSON.parse(stored)
} catch {
return defaultLayouts()
}
}
}
return defaultLayouts()
}
function defaultLayouts(): ProfileLayout[] {
return [
{
id: 'agent',
name: 'Agent',
description: 'For producers and account executives',
icon: 'i-heroicons-user',
isCustom: false,
defaultTab: 'policies',
sections: [
{ id: 'overview', label: 'Overview', visible: true, order: 1 },
{ id: 'policies', label: 'Policies', visible: true, order: 2 },
{ id: 'quotes', label: 'Quotes', visible: true, order: 3 },
{ id: 'claims', label: 'Claims', visible: true, order: 4 },
{ id: 'billing', label: 'Billing', visible: true, order: 5 },
{ id: 'documents', label: 'Documents', visible: true, order: 6 },
]
},
{
id: 'manager',
name: 'Manager',
description: 'For team leads and supervisors',
icon: 'i-heroicons-users',
isCustom: false,
defaultTab: 'team',
sections: [
{ id: 'overview', label: 'Overview', visible: true, order: 1 },
{ id: 'team', label: 'Team', visible: true, order: 2 },
{ id: 'performance', label: 'Performance', visible: true, order: 3 },
{ id: 'policies', label: 'Policies', visible: true, order: 4 },
{ id: 'reports', label: 'Reports', visible: true, order: 5 },
]
},
{
id: 'admin',
name: 'Admin',
description: 'For administrators and operations',
icon: 'i-heroicons-shield-check',
isCustom: false,
defaultTab: 'overview',
sections: [
{ id: 'overview', label: 'Overview', visible: true, order: 1 },
{ id: 'users', label: 'Users', visible: true, order: 2 },
{ id: 'settings', label: 'Settings', visible: true, order: 3 },
{ id: 'audit', label: 'Audit Log', visible: true, order: 4 },
{ id: 'integrations', label: 'Integrations', visible: true, order: 5 },
]
}
]
}
const layouts = ref<ProfileLayout[]>(loadLayouts())
const activeLayoutId = ref('agent')
function saveLayouts() {
if (import.meta.client) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(layouts.value))
}
}
const activeLayout = computed(() => layouts.value.find(l => l.id === activeLayoutId.value) || layouts.value[0])
const sortedSections = computed(() => {
if (!activeLayout.value) return []
return [...activeLayout.value.sections].sort((a, b) => a.order - b.order)
})
function setActiveLayout(id: string) {
activeLayoutId.value = id
}
function updateLayout(id: string, updates: Partial<ProfileLayout>) {
const idx = layouts.value.findIndex(l => l.id === id)
if (idx !== -1) {
layouts.value[idx] = { ...layouts.value[idx], ...updates }
saveLayouts()
}
}
function removeCustomLayout(id: string) {
layouts.value = layouts.value.filter(l => l.id !== id)
saveLayouts()
}
function resetToDefaults() {
layouts.value = defaultLayouts()
activeLayoutId.value = 'agent'
saveLayouts()
}
/* ── Built-in vs custom ── */
const builtInLayouts = computed(() => layouts.value.filter(l => !l.isCustom))
const customLayouts = computed(() => layouts.value.filter(l => l.isCustom))
/* ── Toggle section visibility ── */
function toggleSectionVisibility(sectionId: string) {
if (!activeLayout.value) return
const updated = activeLayout.value.sections.map(s =>
s.id === sectionId ? { ...s, visible: !s.visible } : s
)
updateLayout(activeLayout.value.id, { sections: updated })
}
/* ── Move section up/down ── */
function moveSection(sectionId: string, direction: 'up' | 'down') {
if (!activeLayout.value) return
const sections = [...activeLayout.value.sections].sort((a, b) => a.order - b.order)
const idx = sections.findIndex(s => s.id === sectionId)
if (idx < 0) return
@@ -43,12 +151,11 @@ function moveSection(sectionId: string, direction: 'up' | 'down') {
updateLayout(activeLayout.value.id, { sections })
}
/* ── Ordered sections for display ── */
const orderedSections = computed(() =>
[...activeLayout.value.sections].sort((a, b) => a.order - b.order)
)
const orderedSections = computed(() => {
if (!activeLayout.value) return []
return [...activeLayout.value.sections].sort((a, b) => a.order - b.order)
})
/* ── Delete custom layout ── */
function handleDelete(id: string) {
removeCustomLayout(id)
}