Skip to content

XyNaP.crm — WYSIWYG Page Designer, Theming & UI Components

Status:Concept v1.0 (2026-03-06) Abhaengigkeit:modular product system.md (Phase 2: CRM Core) Ziel:CRM with real WYSIWYG In-Page designer — directly on the live page design, preview and publishing


1. Vision

The XyNaP.crm Designer is no separate editor — it is the page. The user works directly on the live view, can add widgets, move, configure and immediately see the result. Change. See. Publish.

┌──────────────────────────────────────────────────────────────────┐
│                    WYSIWYG Page-Designer                          │
│                                                                   │
│  ┌─ Toolbar ──────────────────────────────────────────────────┐  │
│  │ [Bearbeiten] [Vorschau] [Publish]  💻 📱  [Undo] [Redo]   │  │
│  └────────────────────────────────────────────────────────────┘  │
│                                                                   │
│  ┌─ Live-Page (WYSIWYG) ─────────────────────────────────────┐  │
│  │                                                             │  │
│  │   Design direkt auf der Seite.                              │  │
│  │   Klicke auf ein Widget → Inline-Config erscheint.          │  │
│  │   Ziehe neue Widgets aus dem [+] Panel.                     │  │
│  │   Verschiebe per Drag & Drop.                               │  │
│  │   Resize per Edge-Handles.                                  │  │
│  │                                                             │  │
│  │   Was du siehst = was publisht wird.                        │  │
│  │                                                             │  │
│  └─────────────────────────────────────────────────────────────┘  │
│                                                                   │
│  ┌─ Context Panel (rechts, ausklappbar) ──────────────────────┐  │
│  │ Widget-Einstellungen │ Theme │ Seiten-Settings              │  │
│  └────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────┘

Core principles:

  1. In-Place Editing— No separate designer mode. The live page is edited directly.
  2. Preview = Reality — What to see in the designer is exactly the published result.
  3. Publish-Workflow— Changes are only visible after explicit "publish" for all (draft/published).
  4. Responsive Live— Switch between desktop/tablet/mobile — directly in the designer.
  5. Zero Code— No HTML/CSS/JS noetig. All visual.

Two. Page architecture

2.1 Page types

Type Description Examples
**dashboard * * Overview pages with KPIs, charts, lists Sales Dashboard, Support Dashboard, CEO View
**detail * * Entity-Detail with dynamic fields Contact page, Deal page, Ticket page
list * Filtered lists/tables Open deals, My tasks, All contacts
report * Evaluations with data sources + filter MRR Report, Pipeline Report, Team Performance
form Forms (internal + external) Lead-Erfassung, Contact Form, Survey
*custome * Free pages Onboarding-Wizard, Welcome page

2.2 Page data model

interface Page {
  id: string
  tenant_id: string
  name: string                        // "Sales Dashboard"
  slug: string                        // "sales-dashboard"
  type: PageType
  icon?: string                       // Lucide Icon fuer Navigation
  entity_type?: string                // Fuer detail/list: "deal", "contact", "ticket"

  // Versioning
  draft: PageContent                  // Aktueller Entwurf (wird im Designer bearbeitet)
  published: PageContent | null       // Veroeffentlichte Version (null = noch nie publisht)
  published_at: string | null
  published_by: string | null

  // Meta
  is_system: boolean                  // System-Seiten (nicht loeschbar)
  is_default: boolean                 // Standard-Seite fuer diesen Typ
  is_public: boolean                  // Fuer alle Tenant-User sichtbar
  owner_id: string
  permissions: string[]               // Welche Rollen diese Seite sehen
  sort_order: number                  // Position in der Navigation

  // Navigation
  nav_section?: string                // "crm", "support", "reports", null (versteckt)
  nav_parent_id?: string              // Fuer verschachtelte Navigation

  created_at: string
  updated_at: string
}

interface PageContent {
  version: number
  rows: Row[]
  settings: PageSettings
  theme_overrides?: Partial<ThemeOverrides>  // Seitenspezifische Theme-Anpassungen
}

interface PageSettings {
  max_width: string                   // "1440px" | "100%" | "1200px"
  padding: string                     // "24px"
  row_gap: string                     // "24px"
  background?: string                 // Seiten-Hintergrund (ueberschreibt Theme)
  auto_refresh?: number               // Sekunden (0 = aus)
  filters?: PageFilter[]              // Globale Seitenfilter (Zeitraum, Team, etc.)
}

interface PageFilter {
  id: string
  label: string
  type: 'date_range' | 'select' | 'user' | 'pipeline' | 'custom'
  options?: any
  default_value?: any
  affects_widgets: string[]           // Widget-IDs die auf diesen Filter reagieren
}

2.3 Row & Cell Model

interface Row {
  id: string
  order: number
  cells: Cell[]

  // Layout
  columns: number                     // Spaltenanzahl: 1-12 (CSS Grid)
  gap: string                         // "16px"
  align_items: 'stretch' | 'start' | 'center' | 'end'
  min_height?: string
  max_height?: string

  // Optik
  background?: string
  padding?: string
  margin_top?: string
  border_bottom?: boolean

  // Responsive
  responsive: {
    desktop: { columns: number; visible: boolean }
    tablet:  { columns: number; visible: boolean }
    mobile:  { columns: number; visible: boolean }
  }

  // Bedingung (optional)
  visible_condition?: {
    field: string                     // "user.role", "page.filter.period"
    operator: 'eq' | 'neq' | 'in' | 'gt' | 'lt'
    value: any
  }
}

interface Cell {
  id: string
  order: number

  // Was wird angezeigt
  widget_type: string                 // "kpi-number", "deal-kanban", "chart-bar", etc.
  widget_config: Record<string, any>  // Widget-spezifische Konfiguration

  // Grid-Position (responsive)
  span: {
    desktop: number                   // 1-12 Spalten
    tablet: number
    mobile: number
  }
  offset?: {
    desktop: number                   // 0-11 Spalten Einrueckung
    tablet: number
    mobile: number
  }

  // Optik
  title?: string
  show_title: boolean
  card_style: 'elevated' | 'outlined' | 'flat' | 'none'
  padding?: string
  min_height?: string
  max_height?: string
  overflow: 'visible' | 'scroll' | 'hidden'

  // Verhalten
  collapsible: boolean                // Einklappbar
  collapsed_default: boolean
  loading_skeleton: boolean           // Skeleton-Loader waehrend Daten laden
  refresh_interval?: number           // Widget-spezifischer Refresh (Sekunden)

  // Bedingung
  visible_condition?: {
    field: string
    operator: string
    value: any
  }
}

3. WYSIWYG Designer — UX in Detail

3.1 Modi

┌─────────────────────────────────────────────────────────────────┐
│                                                                  │
│   [Bearbeiten]     [Vorschau]      [Publish ▾]                  │
│   ═══════════                                                    │
│   Aktiver Modus                                                  │
│                                                                  │
│   Bearbeiten:  Widgets auswaehlen, konfigurieren, verschieben    │
│                Inline-Toolbar bei Hover, Drag-Handles sichtbar   │
│                Click → Config-Panel oeffnet rechts               │
│                                                                  │
│   Vorschau:    Exakt wie fuer Endnutzer (keine Handles/Toolbar)  │
│                Responsive-Toggle aktiv (Desktop/Tablet/Mobile)   │
│                                                                  │
│   Publish:     ▾ Dropdown:                                       │
│                  - "Jetzt veroeffentlichen"                      │
│                  - "Zeitgesteuert" (Datum/Uhrzeit)               │
│                  - "Entwurf speichern"                           │
│                  - "Aenderungen verwerfen"                       │
│                  - "Versionshistorie"                            │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

3.2 In-Page Editing Flow

  User oeffnet CRM-Seite (z.B. "Sales Dashboard")
  ┌─ Normal-Ansicht (Published) ────────────────────────┐
  │                                                      │
  │  Seite wird gerendert wie fuer alle User.            │
  │  Oben rechts: kleiner [✏ Bearbeiten] Button          │
  │  (nur fuer User mit "page.edit" Permission)          │
  │                                                      │
  └──────────────────────────────────────────────────────┘
          │ Klick auf "Bearbeiten"
  ┌─ Edit-Modus (WYSIWYG) ─────────────────────────────┐
  │                                                      │
  │  ┌─ Floating Toolbar (oben) ──────────────────────┐ │
  │  │ [+ Widget]  [Undo] [Redo]  💻 📱  [Vorschau]   │ │
  │  │ [Speichern] [Publish] [✕ Schliessen]           │ │
  │  └────────────────────────────────────────────────┘ │
  │                                                      │
  │  Jedes Widget bekommt bei Hover:                     │
  │  ┌────────────────────────────────────┐              │
  │  │ ↕ Drag-Handle  │  ⚙ Config  │  ✕  │ ← Inline    │
  │  ├────────────────────────────────────┤              │
  │  │                                    │              │
  │  │     Widget-Inhalt (LIVE Daten)     │              │
  │  │                                    │              │
  │  ├────────────────────────────────────┤              │
  │  │ ←─────── Resize Handle ──────────→ │ ← Breite    │
  │  └────────────────────────────────────┘              │
  │                                                      │
  │  Zwischen Rows: [+ Row hier einfuegen] Linie         │
  │                                                      │
  │  Klick auf Widget → Config-Panel klappt rechts auf:  │
  │                     ┌──────────────────┐             │
  │                     │ Widget-Settings   │             │
  │                     │ Datenquelle       │             │
  │                     │ Darstellung       │             │
  │                     │ Responsive        │             │
  │                     │ Bedingungen       │             │
  │                     └──────────────────┘             │
  │                                                      │
  └──────────────────────────────────────────────────────┘
          │ Klick auf "Publish"
  ┌─ Publish-Dialog ────────────────────────────────────┐
  │                                                      │
  │  Aenderungen seit letztem Publish:                   │
  │  - 2 Widgets hinzugefuegt                            │
  │  - 1 Widget verschoben                               │
  │  - Theme-Farbe geaendert                             │
  │                                                      │
  │  [Jetzt veroeffentlichen]  [Abbrechen]              │
  │                                                      │
  └──────────────────────────────────────────────────────┘

3.3 Add widget (+ Panel)

Click [+ Widget] to open an overlay panel (no separate screen):

┌─ Widget hinzufuegen ────────────────────────────────────┐
│                                                          │
│ 🔍 [Suche...]                                           │
│                                                          │
│ ── Kennzahlen (KPIs) ─────────────────────────────────  │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐                    │
│ │  #   │ │  ↗   │ │ ±    │ │  ○   │                    │
│ │ Zahl │ │Trend │ │Vgl.  │ │Gauge │                    │
│ └──────┘ └──────┘ └──────┘ └──────┘                    │
│                                                          │
│ ── Pipeline & Deals ──────────────────────────────────  │
│ ┌──────┐ ┌──────┐ ┌──────┐                              │
│ │ ▯▯▯  │ │  ▽   │ │  ☰   │                              │
│ │Kanban│ │Funnel│ │Deals │                              │
│ └──────┘ └──────┘ └──────┘                              │
│                                                          │
│ ── Listen & Tabellen ─────────────────────────────────  │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐          │
│ │  ☰   │ │  ☰   │ │  ☰   │ │  ▤   │ │  ✓   │          │
│ │Kont. │ │Ticket│ │Aktiv.│ │Recent│ │Tasks │          │
│ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘          │
│                                                          │
│ ── Diagramme ─────────────────────────────────────────  │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐                    │
│ │ ▌▌▌  │ │  ╱   │ │  ◔   │ │  📊  │                    │
│ │ Bar  │ │ Line │ │Donut │ │Fore- │                    │
│ │      │ │      │ │      │ │cast  │                    │
│ └──────┘ └──────┘ └──────┘ └──────┘                    │
│                                                          │
│ ── Detail-Felder ─────────────────────────────────────  │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐                    │
│ │  👤  │ │  ▦   │ │  🔗  │ │  📝  │                    │
│ │Header│ │Felder│ │Relat.│ │Notes │                    │
│ └──────┘ └──────┘ └──────┘ └──────┘                    │
│                                                          │
│ ── Sonstiges ─────────────────────────────────────────  │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐          │
│ │  ⚡  │ │  🏆  │ │  📅  │ │  </> │ │  ─   │          │
│ │Quick │ │Leader│ │Kalen.│ │HTML  │ │Spacer│          │
│ │Act.  │ │board │ │      │ │      │ │      │          │
│ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘          │
│                                                          │
│ Klicke oder ziehe ein Widget auf die Seite.             │
└─────────────────────────────────────────────────────────┘

ClickWorkflow:widget → will be inserted at the end of the page → immediately drag to bold position → Config panel opens automatically.

3.4 Inline configuration

Instead of a separate Config screen, anSlide-Over Panelopens up to the right:

┌─ Widget-Einstellungen ────── [✕] ──┐
│                                      │
│ ┌─ Tabs ──────────────────────────┐ │
│ │ [Daten] [Darstellung] [Erweit.] │ │
│ └─────────────────────────────────┘ │
│                                      │
│ ── Tab: Daten ────────────────────  │
│                                      │
│ Datenquelle                          │
│ [Pipeline: Sales ▾]                  │
│                                      │
│ Filter                               │
│ Status: [● Offen  ○ Gewonnen  ○ Alle]│
│ Zeitraum: [🔗 Seitenfilter ▾]       │
│                                      │
│ Sortierung                           │
│ [Wert ▾]  [Absteigend ▾]           │
│                                      │
│ Limit: [20]                          │
│                                      │
│ ── Tab: Darstellung ──────────────  │
│                                      │
│ Titel: [Pipeline-Uebersicht]        │
│ Titel anzeigen: [✓]                 │
│                                      │
│ Card-Stil:                           │
│ [● Erhoeht  ○ Umrandet  ○ Flach]    │
│                                      │
│ Breite:                              │
│ 💻 Desktop: [═══════8═══════]  8/12  │
│ 📱 Tablet:  [═══════════12══] 12/12  │
│ 📱 Mobile:  [═══════════12══] 12/12  │
│                                      │
│ Hoehe: [Auto ▾]                     │
│ Padding: [16px]                      │
│                                      │
│ ── Tab: Erweitert ────────────────  │
│                                      │
│ Einklappbar: [✓]                    │
│ Eingeklappt bei Start: [ ]          │
│ Auto-Refresh: [30s ▾]              │
│ Skeleton-Loader: [✓]               │
│                                      │
│ Sichtbarkeit:                        │
│ [Immer ▾]                           │
│ Oder: Bedingung definieren...        │
│                                      │
└──────────────────────────────────────┘

3.5 Responsive Design in Designer

┌─ Toolbar ─────────────────────────────────────────────┐
│                                                        │
│  Viewport:  [💻 Desktop]  [📱 Tablet]  [📱 Mobile]    │
│              ═══════════                                │
│                                                        │
│  Bei Viewport-Wechsel:                                 │
│  - Canvas-Breite aendert sich (1440 → 768 → 375px)    │
│  - Grid passt sich an (span-Werte pro Breakpoint)      │
│  - Versteckte Rows/Cells werden ausgegraut             │
│  - Aenderungen gelten NUR fuer den aktiven Breakpoint  │
│                                                        │
└────────────────────────────────────────────────────────┘

Desktop (1440px):
┌──3──┐ ┌──3──┐ ┌──3──┐ ┌──3──┐
│ KPI │ │ KPI │ │ KPI │ │ KPI │
└─────┘ └─────┘ └─────┘ └─────┘
┌──────────8──────────┐ ┌──4──┐
│     Kanban           │ │Feed │
└─────────────────────┘ └─────┘

Tablet (768px):
┌──────6──────┐ ┌──────6──────┐
│    KPI      │ │    KPI      │
└─────────────┘ └─────────────┘
┌──────6──────┐ ┌──────6──────┐
│    KPI      │ │    KPI      │
└─────────────┘ └─────────────┘
┌────────────12────────────────┐
│          Kanban               │
└──────────────────────────────┘
┌────────────12────────────────┐
│           Feed                │
└──────────────────────────────┘

Mobile (375px):
┌────────────12────────────────┐
│            KPI                │ × 4
└──────────────────────────────┘
┌────────────12────────────────┐
│          Kanban               │
└──────────────────────────────┘

4. Theming engine

4.1 Theme architecture

Themes are stored per tenant and applied live via CSS Custom Properties. The theme editor is part of the WYSIWYG designer.

interface TenantTheme {
  id: string
  tenant_id: string
  name: string                        // "Corporate Blue"
  is_active: boolean

  colors: {
    primary: string                   // Hauptfarbe
    primary_hover: string
    secondary: string
    accent: string
    success: string
    warning: string
    danger: string
    info: string
    surface: string                   // Card/Widget-Hintergrund
    background: string                // Seiten-Hintergrund
    text: string
    text_muted: string
    border: string
    neutral: Record<string, string>   // 50-950 Graustufen
  }

  typography: {
    font_family: string
    font_family_mono: string
    font_size_base: string
    line_height: string
    heading_weight: string
  }

  layout: {
    border_radius: string
    border_radius_sm: string
    border_radius_lg: string
    spacing_unit: string
    sidebar_width: string
  }

  branding: {
    logo_url: string | null
    favicon_url: string | null
    login_background_url: string | null
    login_message: string | null
  }

  mode: 'light' | 'dark' | 'auto'
  dark_overrides: Partial<TenantTheme['colors']>
}

4.2 Theme Editor (integrated in designer)

The theme editor is a tab in the designer's Config panel — NOT a separate page:

┌─ Config Panel: Theme ────── [✕] ──┐
│                                     │
│ Aktives Theme: [Corporate Blue ▾]   │
│ [Neues Theme]  [Duplizieren]        │
│                                     │
│ ── Schnellauswahl ────────────────  │
│ ┌────┐┌────┐┌────┐┌────┐┌────┐    │
│ │Blue││Grn ││Purp││Org ││Slat│    │
│ └────┘└────┘└────┘└────┘└────┘    │
│ (10 Preset-Themes als Kacheln)      │
│                                     │
│ ── Farben ────────────────────────  │
│ Primary:   [■ #2563eb] [🎨]        │
│ Secondary: [■ #64748b] [🎨]        │
│ Accent:    [■ #f59e0b] [🎨]        │
│ Success:   [■ #10b981]             │
│ Warning:   [■ #f59e0b]             │
│ Danger:    [■ #ef4444]             │
│ Background:[■ #f8fafc]             │
│ Surface:   [■ #ffffff]             │
│ Text:      [■ #0f172a]             │
│                                     │
│ ── Typografie ────────────────────  │
│ Font: [Inter ▾]                    │
│ Groesse: [16px ▾]                  │
│ Heading-Gewicht: [600 ▾]          │
│                                     │
│ ── Layout ────────────────────────  │
│ Ecken-Radius: [═══8px═══]          │
│ (Slider: 0 → 20px)                 │
│                                     │
│ ── Branding ──────────────────────  │
│ Logo:    [📁 Hochladen]            │
│ Favicon: [📁 Hochladen]            │
│                                     │
│ ── Modus ─────────────────────────  │
│ [● Auto  ○ Hell  ○ Dunkel]         │
│                                     │
│ [Aenderungen live — Publish noetig] │
└─────────────────────────────────────┘

Theme changes will be displayed sofort on the live page (WYSIWYG), but only after "Publish" all users will be active.

4.3 Preset-Themes

Theme Primary Style
XyNaP Default #2563eb Modern, Clean
Corporate #140af Serioes, Business
Startup #059669 Fresh, Dynamic
Creative #7c3aed Creative
Warm Inviting
Minimal 18181b Reduced
Ocean #0891b2 Professional
Rose #e11d48 Income
Forest #166534 Trustful
Slate #475569 Timeless

4.4 CSS Custom Properties (Runtime)

:root {
  --x-primary: #2563eb;
  --x-primary-hover: #1d4ed8;
  --x-secondary: #64748b;
  --x-accent: #f59e0b;
  --x-success: #10b981;
  --x-warning: #f59e0b;
  --x-danger: #ef4444;
  --x-info: #3b82f6;
  --x-surface: #ffffff;
  --x-bg: #f8fafc;
  --x-text: #0f172a;
  --x-text-muted: #64748b;
  --x-border: #e2e8f0;
  --x-radius: 8px;
  --x-radius-sm: 4px;
  --x-radius-lg: 12px;
  --x-font: 'Inter', system-ui, sans-serif;
  --x-font-mono: 'JetBrains Mono', monospace;
}

[data-theme="dark"] {
  --x-surface: #1e293b;
  --x-bg: #0f172a;
  --x-text: #f1f5f9;
  --x-text-muted: #94a3b8;
  --x-border: #334155;
}

Five. UI Components (Widget library)

5.1 Architecture

Each widget is a self-contained cue component that: - Your own data via API - Configured viawidget_config - Theme-CSS-Variablen uses (no hardcoding) - The WYSIWYG designer can be placed - AnEdit-Overlayfor the designer - AConfig-Schemafor the Config panel delivers

interface WidgetMeta {
  type: string                        // Eindeutiger Bezeichner
  name: string                        // Anzeigename (i18n key)
  icon: string                        // Lucide Icon
  category: 'kpi' | 'pipeline' | 'list' | 'chart' | 'detail' | 'misc'
  description: string
  default_span: { desktop: number; tablet: number; mobile: number }
  min_span: number
  config_schema: JSONSchema7          // Fuer automatische Config-UI-Generierung
  default_config: Record<string, any>
  supports_page_filters: boolean      // Reagiert auf globale Seitenfilter
}

5.2 Widget catalog

KPIs

Widget Description Default chip
kpi-number Single large number with label, icon, trend arrow 3
kpi-trend Number + Sparkline (7d/30d/90d) 3
kpi-comparison Aktuell vs. previous period with Delta 3
kpi-gauge Circular progress bar (0-100%) 3
kpi-group 2-4 KPIs in a compact card 6

Pipeline & Deals

Widget Description Default chip
pipeline-kanban Kanban board with drag & drop between phases 8
pipeline-funnel Funnel visualization with conversion rates 6
deal-table Sortable, filterable deal table 12
deal-summary Compact Deal Card (fuer Detail-Pages) 4

Lists & tables

Widget Description Default chip
contact-table Contact list with search, filter, inline action 12
ticket-table Ticket list with status badges, SLA-Countdown 12
activity-timeline Chronological feed (e-mails, calls, notes) 4
task-list Tasks with Checkbox, Skill, Priority 4
recent-items Recently edited entities (deals, contacts, ...) 4

Charts

Widget Description Default chip
chart-bar Bar chart (vertical/horizontal) 6
chart-line Line diagram with optional area-fill 6
chart-donut Donut/Pie with optional Center-Total 4
chart-forecast CRM-Forecast (weighted, historical + projection) 6
chart-stacked-bar Stacked bars (e.g. deals per phase per month) 6

Detail Fields (fuer Entity-Pages)

Widget Description Default chip
entity-header Head area: Avatar, Name, Tags, Status, Actions 12
entity-fields Editable Field Group (Grid or List) 6
entity-relations Verknuepfte Entities (Deals, Tickets, Files, ...) 6
notes-panel Notes with Pinned, Add, Timeline 4
files-panel Filed with Upload 4

Other

Widget Description Default chip
quick-actions Button-Leiste (New Deal, New Contact, ...) 12
team-leaderboard Ranking to metrics (deals, sales, tickets) 4
calendar-mini Mini calendar with CRM events 4
html-embed Free HTML Block (sanitized) 6
spacer Spacer with configurable view 12
divider Horizontal separation line 12
heading Heading (H1-H4) 12
text-block Rich-Text Block (WYSIWYG Editor) 6

5.3 Widget Config Examples

// kpi-number
{
  label: "Offene Deals",
  data_source: "deals",
  aggregation: "count",
  filter: { status: "open" },
  format: "number",
  icon: "TrendingUp",
  color: "primary",
  compare_period: "previous_month"  // Zeigt +/- Delta
}

// pipeline-kanban
{
  pipeline_id: "sales-pipeline",
  show_deal_value: true,
  show_contact_name: true,
  show_owner_avatar: true,
  max_cards_per_column: 20,
  highlight_rotting: true,
  rotting_days: 14,
  compact_mode: false,
  allow_drag: true                  // Drag & Drop zwischen Phasen
}

// chart-forecast
{
  pipeline_id: null,                // Alle Pipelines
  period: "monthly",
  months_ahead: 6,
  show_weighted: true,
  show_actual: true,
  show_target: true,
  target_values: {                  // Optionale Zielwerte
    "2026-03": 50000,
    "2026-04": 55000
  }
}

// entity-fields (fuer Contact Detail Page)
{
  sections: [
    {
      title: "Kontaktdaten",
      columns: 2,
      fields: [
        { key: "email", format: "email", editable: true },
        { key: "phone", format: "phone", editable: true },
        { key: "mobile", format: "phone", editable: true },
        { key: "website", format: "url", editable: true }
      ]
    },
    {
      title: "Adresse",
      columns: 2,
      fields: [
        { key: "address.street" },
        { key: "address.city" },
        { key: "address.zip" },
        { key: "address.country" }
      ]
    },
    {
      title: "Custom Fields",
      columns: 2,
      fields: [
        { key: "custom.branche", label: "Branche" },
        { key: "custom.mitarbeiter", label: "Mitarbeiter-Anzahl", format: "number" }
      ]
    }
  ]
}

6. Publish workflow

6.1 Draft/Published System

                    ┌──────────────┐
                    │   Erstellen  │
                    └──────┬───────┘
                    ┌──────────────┐
            ┌──────│    Draft     │◄─── Bearbeiten
            │      └──────┬───────┘
            │             ▼
            │      ┌──────────────┐
            │      │   Publish    │──── Sichtbar fuer alle
            │      └──────┬───────┘
            │             │
            │             ▼
            │      ┌──────────────┐
            └─────►│  Neuer Draft │──── Aenderungen nur fuer Editor
                   └──────┬───────┘
                   ┌──────────────┐
                   │   Publish    │──── Ueberschreibt Published
                   └──────────────┘

6.2 Version history

Each publishing creates a snapshot. Rollback at any time.

interface PageVersion {
  id: string
  page_id: string
  version: number                     // Auto-increment
  content: PageContent                // Vollstaendiger Snapshot
  published_by: string
  published_at: string
  change_summary: string              // Auto-generiert oder manuell
}

6.3 Permissions

Permission Description
page.view See page (Published version)
page.edit Edit Page (Create Draft)
page.publish Draft negotiable
page.delete Page Loose
page.create Create new pages
theme.edit Change Theme settings
theme.publish Theme veroeffent

7. API endpoints

Pages

GET    /api/v1/crm/pages                            # Alle Seiten des Tenants
GET    /api/v1/crm/pages/{id}                       # Seite (published oder draft)
GET    /api/v1/crm/pages/{id}/draft                 # Nur Draft
GET    /api/v1/crm/pages/{id}/published             # Nur Published
POST   /api/v1/crm/pages                            # Neue Seite erstellen
PUT    /api/v1/crm/pages/{id}/draft                 # Draft speichern (Auto-Save)
POST   /api/v1/crm/pages/{id}/publish               # Draft veroeffentlichen
POST   /api/v1/crm/pages/{id}/discard-draft         # Draft verwerfen
DELETE /api/v1/crm/pages/{id}                       # Seite loeschen
POST   /api/v1/crm/pages/{id}/duplicate             # Seite klonen
GET    /api/v1/crm/pages/{id}/versions              # Versionshistorie
POST   /api/v1/crm/pages/{id}/rollback/{version}   # Zu Version zurueckkehren
POST   /api/v1/crm/pages/{id}/set-default           # Als Standard setzen

Themes

GET    /api/v1/crm/themes                           # Alle Themes
GET    /api/v1/crm/themes/active                    # Aktives Theme
POST   /api/v1/crm/themes                           # Neues Theme
PUT    /api/v1/crm/themes/{id}                      # Theme aktualisieren
DELETE /api/v1/crm/themes/{id}                      # Theme loeschen
POST   /api/v1/crm/themes/{id}/activate             # Theme aktivieren
GET    /api/v1/crm/themes/presets                   # Preset-Themes
POST   /api/v1/crm/themes/from-preset/{slug}        # Aus Preset erstellen
POST   /api/v1/crm/themes/{id}/export               # Als JSON exportieren
POST   /api/v1/crm/themes/import                    # Aus JSON importieren

Widgets

GET    /api/v1/crm/widgets                          # Verfuegbare Widget-Typen
GET    /api/v1/crm/widgets/{type}/schema            # Config-Schema fuer Widget
GET    /api/v1/crm/widgets/{type}/preview-data      # Mock-Daten fuer Designer-Preview

Page Templates

GET    /api/v1/crm/page-templates                   # Verfuegbare Templates
GET    /api/v1/crm/page-templates/{id}              # Template-Details
POST   /api/v1/crm/pages/from-template/{id}         # Seite aus Template erstellen
POST   /api/v1/crm/page-templates                   # Seite als Template speichern

8. DB Schema

-- CRM Pages (Seiten)
crm_pages (
    id CHAR(36) PRIMARY KEY,
    tenant_id CHAR(36) NOT NULL,
    name VARCHAR(200) NOT NULL,
    slug VARCHAR(200) NOT NULL,
    type ENUM('dashboard','detail','list','report','form','custom') NOT NULL,
    icon VARCHAR(50),
    entity_type VARCHAR(50),

    -- Versioning
    draft JSON NOT NULL,                -- PageContent (aktueller Entwurf)
    published JSON,                     -- PageContent (veroeffentlicht, NULL = noch nie)
    published_at TIMESTAMP,
    published_by CHAR(36),

    -- Meta
    is_system BOOLEAN DEFAULT FALSE,
    is_default BOOLEAN DEFAULT FALSE,
    is_public BOOLEAN DEFAULT TRUE,
    owner_id CHAR(36) NOT NULL,
    permissions JSON,                   -- ["admin", "manager", "sales"]
    sort_order INT DEFAULT 0,

    -- Navigation
    nav_section VARCHAR(50),
    nav_parent_id CHAR(36),

    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

    UNIQUE(tenant_id, slug),
    INDEX(tenant_id, type),
    INDEX(tenant_id, nav_section)
)

-- Page-Versionen (Publish-History)
crm_page_versions (
    id CHAR(36) PRIMARY KEY,
    page_id CHAR(36) NOT NULL,
    version INT NOT NULL,
    content JSON NOT NULL,              -- PageContent Snapshot
    published_by CHAR(36) NOT NULL,
    published_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    change_summary VARCHAR(500),

    INDEX(page_id, version),
    FOREIGN KEY (page_id) REFERENCES crm_pages(id) ON DELETE CASCADE
)

-- Themes
crm_themes (
    id CHAR(36) PRIMARY KEY,
    tenant_id CHAR(36) NOT NULL,
    name VARCHAR(100) NOT NULL,
    is_active BOOLEAN DEFAULT FALSE,
    colors JSON NOT NULL,
    typography JSON NOT NULL,
    layout_config JSON NOT NULL,
    branding JSON,
    mode ENUM('light','dark','auto') DEFAULT 'auto',
    dark_overrides JSON,
    preset_slug VARCHAR(50),
    created_by CHAR(36),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

    UNIQUE(tenant_id, name)
)

-- Page Templates (global, nicht tenant-spezifisch)
crm_page_templates (
    id CHAR(36) PRIMARY KEY,
    name VARCHAR(200) NOT NULL,
    description TEXT,
    type ENUM('dashboard','detail','list','report','form','custom') NOT NULL,
    entity_type VARCHAR(50),
    thumbnail_url VARCHAR(500),
    content JSON NOT NULL,              -- PageContent
    category VARCHAR(50),
    is_active BOOLEAN DEFAULT TRUE,
    sort_order INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)

-- User-Praeferenzen (welche Seite als Default)
crm_user_page_prefs (
    id CHAR(36) PRIMARY KEY,
    tenant_id CHAR(36) NOT NULL,
    user_id CHAR(36) NOT NULL,
    page_type VARCHAR(50) NOT NULL,
    page_id CHAR(36),
    widget_overrides JSON,              -- User-spezifische Widget-Einstellungen
    UNIQUE(tenant_id, user_id, page_type)
)

9. Frontend architecture

src/
  crm/
    designer/
      PageDesigner.vue                # WYSIWYG In-Page Designer (Haupt-Komponente)
      DesignerToolbar.vue             # Floating Toolbar (Edit/Preview/Publish)
      DesignerCanvas.vue              # Canvas-Wrapper (Viewport-Simulation)
      WidgetPalette.vue               # [+] Widget hinzufuegen Panel
      ConfigPanel.vue                 # Slide-Over rechts (Widget/Theme/Page Settings)
      RowEditor.vue                   # Row-Handles (+ ✕ ↑ ↓)
      CellWrapper.vue                 # Cell mit Drag/Resize/Select Overlay
      ResizeHandle.vue                # Edge-Handle fuer Spaltenbreite
      PublishDialog.vue               # Publish-Bestaetigung mit Aenderungs-Diff
      VersionHistory.vue              # Versionshistorie + Rollback

    renderer/
      PageRenderer.vue                # Rendert Published Page (fuer Endnutzer)
      RowRenderer.vue                 # Rendert eine Row
      CellRenderer.vue                # Rendert eine Cell (dynamisches Widget)

    theme/
      ThemeConfig.vue                 # Theme-Tab im Config-Panel
      ThemeProvider.vue               # Injiziert CSS Custom Properties
      ColorPicker.vue                 # Farbwahl

    widgets/
      kpi/
        KpiNumber.vue
        KpiTrend.vue
        KpiComparison.vue
        KpiGauge.vue
        KpiGroup.vue
      pipeline/
        PipelineKanban.vue
        PipelineFunnel.vue
        DealTable.vue
        DealSummary.vue
      lists/
        ContactTable.vue
        TicketTable.vue
        ActivityTimeline.vue
        TaskList.vue
        RecentItems.vue
      charts/
        ChartBar.vue
        ChartLine.vue
        ChartDonut.vue
        ChartForecast.vue
        ChartStackedBar.vue
      detail/
        EntityHeader.vue
        EntityFields.vue
        EntityRelations.vue
        NotesPanel.vue
        FilesPanel.vue
      misc/
        QuickActions.vue
        TeamLeaderboard.vue
        CalendarMini.vue
        HtmlEmbed.vue
        Spacer.vue
        Divider.vue
        Heading.vue
        TextBlock.vue

    composables/
      usePageDesigner.ts              # Designer-State (edit/preview, undo/redo, drag)
      useWidgetRegistry.ts            # Widget-Registry (type → component + meta)
      useTheme.ts                     # Theme laden, CSS-Vars setzen, Live-Update
      useAutoSave.ts                  # Draft Auto-Save (debounced, 3s)
      usePublish.ts                   # Publish-Workflow
      usePageFilters.ts               # Globale Seitenfilter (provide/inject)

    stores/
      pageStore.ts                    # Pinia: aktuelle Seite, Draft-State
      themeStore.ts                   # Pinia: aktives Theme
      designerStore.ts                # Pinia: Designer-UI-State (selected cell, panel open)

    views/
      CrmPageView.vue                 # Route: /crm/:slug — rendert Page (published)
      CrmDesignerView.vue             # Route: /crm/:slug/edit — WYSIWYG Designer
      CrmPagesListView.vue            # Route: /crm/pages — Alle Seiten verwalten
      CrmThemesView.vue               # Route: /crm/themes — Theme-Verwaltung

10. Implementation order

Phase A: Core infrastructure

  1. DB-Tabellen(crm pages, crm themes, crm page versions, crm page templates)
  2. Backend API(Pages CRUD, Themes CRUD, Publish workflow)
  3. ThemeProvider(CSS Custom Properties Runtime-Injection)
  4. PageRenderer(Row/Cell/Widget dynamic rendering)
  5. Widget Registry(Registration, Resolve, Scheme)

Phase B: Basic widgets

  1. KPI-Widgets(kpi-number, kpi-trend, kpi-comparison)
  2. Listen-Widgets(deal-table, contact-table, activity-timeline, task-list)
  3. Pipeline-Widgets(pipeline canban)
  4. Chart-Widgets(chart-bar, chart-line, chart-donut)
  5. Misc-Widgets(heading, text-block, spacer, divider, quick-actions)

Phase C: WYSIWYG Designer

  1. PageDesigner(Edit Mode Overlay on Live Position)
  2. DesignerToolbar(Edit/Preview/Publish Toggle)
  3. CellWrapper(Select, Drag, Resize Overlays)
  4. WidgetPalette([+] Panel with categories)
  5. ConfigPanel(Slide-Over with Widget/Theme/Page Tabs)
  6. Auto-Save(Debounced Draft-Save)

Phase D: Publish & Versioning

  1. Publish-Dialog(diff display, confirmation)
  2. VersionHistory(Timeline, Rollback)
  3. Draft/PublishedSplit rendering

Phase E: Advanced Widgets

  1. pipeline-funnel, chart-forecast, *chart-stacked-bar *
  2. Detail-Widgets(entity-header, entity-fields, entity-relations, notes-panel, files-panel)
  3. team leaderboard, calendar-mini, kpi-gauge, **kpi-group * *

Phase F: Polish

  1. Responsive Designer(Viewport-Toggle, Breakpoint-specific Spans)
  2. Undo/Redo(Command stack)
  3. Page Templates(Galerie, Import/Export)
  4. Theme Presets(10 Themes)
  5. Seitenfilter(Global filters affect widgets)
  6. User-Praeferenzen

11. Technical decisions

Decision Choice Mining
Designer-Ansatz In-Page Overlay (no iframe) Real WYSIWYG, no styling insulation problems
Charts Chart.js 4 (vue-chartjs) Lightweight, good vue integration, responsive
**Drag & Drop * * HTML5 DnD + @vueuse/core No extra pack, sufficient for grid layout
Grid-CSS CSS Grid (12-Col, repeat + span) Nativ, performant, responsive breakpoints
Themes JSON → CSS Custom Properties No build-Step, immediate live change
Auto-Save Debounced PUT (3s after last modification) No data loss, no excessive API load
Widget-Rendering Vue<component :is>+ Registry Standard batteries, Tree-Shakeable, Lazy-Load available
Undo/Redo Command-Pattern (Array of Snapshots) Simpel, reliable, no extra pack
Config UI Car-generated from JSON Schema Unique Config panel for all widgets

12. Delimitation

  • Kein Website-Builder, The designer is for CRM pages (Dashboards, Detail-Views, Reports), NOT for public websites. There are XyNaP.cms.
  • Kein Code-Editor— All visual, no HTML/CSS/JS access for end users.
  • No custom widgets (first) — Only included widgets. Plugin system for later planned.
  • Kein Pixel-Perfect— 12 column grid with snap, no free positioning (squarespace approach, not Figma).
  • Kein Echtzeit-Collaboration, A user edits a page simultaneously. Multi-user spaeter via Locking.