vcard4reseller/frontend/src/components/Modal.vue
Thomas Peterson ebaf509a2f Fundament: Symfony+API-Platform-Backend & Vue-SPA (Phase 0–2)
Stack & Setup
- Dockerisierte Dev-Umgebung (PHP 8.4-FPM, Nginx, MariaDB 11.4)
- Symfony 7.4 + API Platform 4.3, Doctrine ORM, LexikJWT, Messenger
- Vue 3 + TS (Vite), Vue Router, Pinia, Axios

Kern-Domäne & Auth
- Entitäten: User, PlatformPlan, Reseller, Company, Domain, Location,
  Employee, ContactLink (UUIDv7)
- JWT-Login (/api/login), Rollen-Hierarchie, /api/me
- Mandantentrennung via API-Platform-Query-Extension (Lesen) +
  TenantStampProcessor (Schreiben)

Öffentliche Profile (SSR)
- Profil-Landingpage, vCard-Download, QR-Code im Marken-Look
- Stabiler NFC/QR-Kurz-Link /t/{code} -> Redirect aufs aktuelle Profil
- Firmenspezifisches Branding (Farben/Logo) auf der Profilseite

Verwaltungsoberfläche (SPA)
- Brand-Look (dunkle Sidebar), rollenbasierte Navigation
- Dashboard, Reseller (+Provisioning), Firmen, Mitarbeiter, Standorte,
  Domains, Design/Branding mit Live-Vorschau

Konzept & Doku: docs/KONZEPT.md (inkl. Wallet/Sync §12), README.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 11:12:53 +02:00

33 lines
1.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
defineProps<{ title: string }>()
const emit = defineEmits<{ close: [] }>()
</script>
<template>
<div class="overlay" @click.self="emit('close')">
<div class="card modal">
<header class="modal__head">
<h3>{{ title }}</h3>
<button class="x" @click="emit('close')" aria-label="Schließen">×</button>
</header>
<div class="modal__body">
<slot />
</div>
</div>
</div>
</template>
<style scoped>
.overlay {
position: fixed; inset: 0; background: rgba(20, 20, 20, .45);
display: flex; align-items: center; justify-content: center; padding: 1rem; z-index: 50;
}
.modal { width: 100%; max-width: 480px; max-height: 90vh; overflow: auto; }
.modal__head {
display: flex; align-items: center; justify-content: space-between;
padding: 1.1rem 1.4rem; border-bottom: 1px solid var(--line);
}
.modal__body { padding: 1.4rem; }
.x { background: none; border: none; font-size: 1.6rem; line-height: 1; cursor: pointer; color: var(--muted); }
</style>