big refactor
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user