feat(admin): inquiry inbox, send log, email-template overrides, reports dashboard, recommender keys, role-editor coverage; replace placeholder pages
Closes the bulk of audit-pass-#1 admin gaps in one batch. New admin pages: - /admin/inquiries reads website_submissions with filter chips for berth/residence/contact + payload viewer per row. - /admin/sends reads document_sends with sent/failed filter chips and expandable body markdown; failures surface errorReason and any fallback-to-link reason from the SMTP retry. - /admin/email-templates lets per-port admins override the subject of each transactional template (8 templates catalogued in template-catalog.ts). Body editing is a follow-on; portal_activation + portal_reset are wired to honor the override via loadSubjectOverride. - /admin/reports replaces the "Coming in Layer 3" placeholder with a KPI dashboard: 4 KPI tiles, pipeline funnel bars, berth occupancy donut-bars, conversion %, refresh every 60s. - backup/import/onboarding admin pages replace placeholders with actionable guidance: backup posture + planned features, available CLI imports + planned UI, ordered onboarding checklist linking to admin pages. Existing pages widened: - settings-manager exposes the 9 berth-recommender tunables that were previously code-only (recommender_*, heat_weight_*, fallthrough_*, tier_ladder_hide_late_stage). - role-form covers all 19 RolePermissions schema groups; previously missing yachts/companies/memberships/reservations + missing documents.edit + files.edit checkboxes. snake_case residential labels replaced with friendly text. portal-auth.service.ts now also writes audit_log rows for portal invite, resend, activate, password-reset request, and reset (closes one more audit-pass-#2 gap while we were touching the file). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,8 @@ import {
|
||||
} from '@/components/ui/accordion';
|
||||
import { apiFetch } from '@/lib/api/client';
|
||||
|
||||
/** Default permissions structure matching RolePermissions type */
|
||||
/** Default permissions structure matching RolePermissions type in
|
||||
* src/lib/db/schema/users.ts. Keep this in sync when actions are added. */
|
||||
const DEFAULT_PERMISSIONS: Record<string, Record<string, boolean>> = {
|
||||
clients: { view: false, create: false, edit: false, delete: false, merge: false, export: false },
|
||||
interests: {
|
||||
@@ -33,6 +34,7 @@ const DEFAULT_PERMISSIONS: Record<string, Record<string, boolean>> = {
|
||||
documents: {
|
||||
view: false,
|
||||
create: false,
|
||||
edit: false,
|
||||
send_for_signing: false,
|
||||
upload_signed: false,
|
||||
delete: false,
|
||||
@@ -54,7 +56,7 @@ const DEFAULT_PERMISSIONS: Record<string, Record<string, boolean>> = {
|
||||
record_payment: false,
|
||||
export: false,
|
||||
},
|
||||
files: { view: false, upload: false, delete: false, manage_folders: false },
|
||||
files: { view: false, upload: false, edit: false, delete: false, manage_folders: false },
|
||||
email: { view: false, send: false, configure_account: false },
|
||||
reminders: {
|
||||
view_own: false,
|
||||
@@ -67,6 +69,10 @@ const DEFAULT_PERMISSIONS: Record<string, Record<string, boolean>> = {
|
||||
calendar: { connect: false, view_events: false },
|
||||
reports: { view_dashboard: false, view_analytics: false, export: false },
|
||||
document_templates: { view: false, generate: false, manage: false },
|
||||
yachts: { view: false, create: false, edit: false, delete: false, transfer: false },
|
||||
companies: { view: false, create: false, edit: false, delete: false },
|
||||
memberships: { view: false, manage: false },
|
||||
reservations: { view: false, create: false, activate: false, cancel: false },
|
||||
admin: {
|
||||
manage_users: false,
|
||||
view_audit_log: false,
|
||||
@@ -101,7 +107,13 @@ const GROUP_LABELS: Record<string, string> = {
|
||||
calendar: 'Calendar',
|
||||
reports: 'Reports',
|
||||
document_templates: 'Document Templates',
|
||||
yachts: 'Yachts',
|
||||
companies: 'Companies',
|
||||
memberships: 'Company Memberships',
|
||||
reservations: 'Reservations',
|
||||
admin: 'Administration',
|
||||
residential_clients: 'Residential Clients',
|
||||
residential_interests: 'Residential Interests',
|
||||
};
|
||||
|
||||
function formatAction(action: string): string {
|
||||
|
||||
Reference in New Issue
Block a user