# Magic Dashboard – iOS-Section Redesign

## Ziel

Das Magic-Dashboard soll klar zwischen zwei eigenen Bausteinen trennen:

1. **Desktop-Schutz** (Mac/Windows) – das Gerät, auf dem Magic läuft.
2. **iOS-Verwaltung** (eigene iPhone/iPad-Geräte) – registrierte iOS-Geräte des Users mit Status, Sternen und passenden Aktionen.

„Andere Geräte“ bleiben als sekundäre Information erhalten, sollen aber nicht den Fokus stehlen. Magic ist kein offenes Verwaltungstool für fremde Geräte.

---

## Annahmen (aus dem Abstimmungsgespräch)

- Backend-iOS-Geräte werden immer gelistet.
- Wenn ein iPhone/iPad per USB verbunden ist, werden Live-Daten (Supervision, Enrollment, Sideload, App) mit dem passenden Backend-Eintrag synchronisiert.
- Ein per USB verbundenes, aber im Backend unbekanntes iOS-Gerät wird als **„Nicht erkennbar“** markiert. Der Hinweis verweist auf: ReBreak-App installieren → anmelden → Gerät registrieren. Erst danach ist es verwaltbar.
- Supervise / Enroll / Sideload / App-Install bleiben im bestehenden Wizard (`/detect`, `/supervise`, `/enroll`, `/sideload`). Das Dashboard bietet nur den passenden Einstieg.

---

## Seitenstruktur

```
status.vue
├── Header (Profil, Logout)
├── Section: Aktives Gerät (Desktop-Hero)
│   └── DeviceHeroCard für currentBackendDevice (mac/windows)
├── Section: Meine iOS-Geräte
│   ├── UnknownIosDeviceCard (falls USB-Device nicht im Backend)
│   └── IosDeviceCard[] für jedes Backend-iOS-Gerät
│       (Sterne + Status + Action-Button)
├── Section: Weitere Geräte
│   └── DeviceListItem[] für sonstige Backend-Geräte
└── DeviceDetailSheet (weiterhin für Details/Cooldown)
```

---

## Neue Komponenten

### `IosDeviceSection.vue`

- Props:
  - `devices: ComputedDevice[]` – alle Backend-iOS-Geräte des Users
  - `iphone: IphoneDeviceState | null` – aktuell per USB erkanntes Gerät
  - `loading: boolean`
- Zeigt den Section-Header und rendert die Liste von `IosDeviceCard`s.
- Wenn `iphone` verbunden, aber kein passendes Backend-Gerät gefunden wird, wird `UnknownIosDeviceCard` angezeigt.
- Wenn noch keine Backend-iOS-Geräte geladen wurden: Hinweis „Keine iOS-Geräte geladen“ + Aktualisieren-Button.
- Wenn geladen und leer: Hinweis „Keine iOS-Geräte registriert. ReBreak-App installieren und Gerät hinzufügen.“

### `IosDeviceCard.vue`

- Props:
  - `device: ComputedDevice`
  - `iphone: IphoneDeviceState | null` – falls dieses Gerät per USB verbunden ist
  - `isConnected: boolean`
- Zeigt:
  - Name/Modell
  - Status-Badge (`active`, `pending`, `unprotected` etc.)
  - Letzte Sichtung
  - `IosStarRating` + detaillierte Sternen-Liste, wenn `isConnected`
  - Sonst Hinweis: „Zum Live-Status iPhone per USB verbinden“
- Action-Button (ableitet sich aus dem gemergten Zustand):
  - Nicht supervised → „Supervisen" → `/supervise`
  - Supervised, aber Enrollment fehlt → „Enrollen" → `/enroll`
  - Enrollment vorhanden, aber Sideload-Profil fehlt → „Sideload installieren" → `/sideload`
  - Sideload vorhanden, aber App fehlt → „App installieren" (MDM-Befehl oder Link)
  - Alles okay → „Synchronisieren" (prüft Enrollment-, Sideload- und Supervision-Status; bei Abweichungen werden fehlende Profile/MDM-Kommandos gepusht; falls die lokale MDM-Version hinter der aktuellen ReBreak-MDM-Version zurückfällt, wird ein Update gepusht und der User informiert)
  - Während der 3-Tage-Kündigungs-Grace-Period → „ReBreak entfernen" (löst Offboarding aus: MDM-Profile entfernen, Gerät unsupervised setzen, Eintrag bereinigen)

### `UnknownIosDeviceCard.vue`

- Props:
  - `iphone: IphoneDeviceState`
- Zeigt:
  - Warn-Icon + „Dieses iPhone ist nicht erkennbar"
  - Modell, iOS-Version, UDID (nur zur Info)
  - Hinweis: „Mit keinem ReBreak-Konto verbunden. Um es zu verwalten: ReBreak-App installieren, anmelden und Gerät registrieren."
  - Keine Supervise-/Enroll-Aktionen.

---

## Datenfluss

1. User klickt in `status.vue` auf **Aktualisieren**.
2. `protection.refresh()` wird aufgerufen:
   - `detectIphoneState()` lädt das per USB verbundene iOS-Gerät.
   - `getMagicDevices()` lädt alle Backend-Geräte in den shared `useMagicDevices`-State.
3. `useDeviceStatus` liefert weiterhin:
   - `currentBackendDevice` (Desktop)
   - `otherDevices` (alles außer current)
4. `IosDeviceSection` erhält die Liste aller `otherDevices`, filtert intern auf `platform === 'ios'` und versucht, das verbundene `iphone` per Modell + Name zuzuordnen.
5. Action-Buttons leiten den User basierend auf dem gemergten Live-Status in den passenden Wizard-Schritt weiter.

### iOS-Matching

Da Backend-`deviceId` (Capacitor-UUID) nicht mit USB-UDID übereinstimmt, erfolgt das Matching über:

- `device.model` (Backend) ↔ `iphone.productType` (USB)
- `device.name` (Backend) ↔ `iphone.name` (USB) als Fallback / Verfeinerung

Sind mehrere Geräte mit identischem Modell vorhanden, wird das erste passende (`name` match) als verbunden markiert; bei Unklarheit wird das `iphone` nicht zugeordnet und erscheint als `UnknownIosDeviceCard`.

---

## Bestehende Komponenten – Anpassungen

### `DeviceHeroCard.vue`

- Keine iOS-Sterne mehr anzeigen (`showIosStars` bleibt aber für zukünftige Flexibilität).
- Aktionen bleiben auf Desktop-Schutz beschränkt.

### `DeviceListItem.vue`

- Wird für „Weitere Geräte“ (andere Desktops) weiterverwendet.
- iOS-Geräte verschwinden aus dieser Liste und werden in der neuen iOS-Section angezeigt.

### `DeviceDetailSheet.vue`

- iOS-Sterne-Anzeige gilt für jedes iOS-Gerät, das gerade per USB verbunden ist (nicht nur `isCurrent`, da iOS-Geräte nie „current" sind).
- Cooldown-Steuerung bleibt nur für `isCurrent`-Desktop-Geräte.

### `useDeviceStatus.ts`

- Entfernt den Debug-`watchEffect` (bereits erledigt).
- Fügt optional `iosDevices` und `desktopDevices` als getrennte Derived Lists hinzu, damit `status.vue` weniger Filter-Logik enthält.

---

## On-Demand-Verhalten bleibt erhalten

- Kein automatisches Polling mehr.
- Sterne/Status werden nur beim manuellen Refresh aktualisiert.
- Das verhindert erneut Log-Spam durch wiederholte `detect_iphone_state`-Aufrufe.

---

## Fehlerbehandlung

- Wenn `detectIphoneState` fehlschlägt: Fehler nur in `protection.lastError`; iOS-Section zeigt Backend-Liste weiterhin an.
- Wenn `getMagicDevices` fehlschägt: `error`-Banner in `status.vue`.
- Wenn Matching mehrdeutig: `UnknownIosDeviceCard` statt falscher Zuordnung.

---

## Kündigungs-Grace-Period & Offboarding

- Solange das Gerät enrolled ist **und** das Abo aktiv ist, wird **nichts** deinstalliert.
- Nach einer Kündigung bleibt das iOS-Gerät für **3 Tage** in der Liste sichtbar.
- Der Button **„ReBreak entfernen"** ist **unsichtbar oder disabled**, solange die Grace-Period noch nicht begonnen hat.
- Sobald die Grace-Period läuft, erscheint der Button ohne zusätzliche Sicherheitsabfrage.
- Ein Klick darauf startet das Offboarding:
  1. MDM-Enrollment-Profil und Sideload-Profil vom Gerät entfernen.
  2. Gerät aus dem Supervised-Modus zurücksetzen.
  3. Backend-Eintrag für das iOS-Gerät bereinigen.
- **Backend-Abhängigkeit:** Es braucht ein Feld/Endpoint, der die Kündigung + verbleibende Grace-Period erkennbar macht (z. B. `subscriptionCancelledAt` im Profil oder dedizierter `/api/magic/subscription-status`). Das Offboarding selbst braucht einen neuen API-Endpoint oder Tauri-Command, der MDM-Remove + Unsupervise orchestriert.

---

## Offene Punkte / Nächste Schritte

1. Existiert bereits ein Backend-Feld/Endpoint für Kündigung + Grace-Period, oder muss der gebaut werden?
2. Wie wird die „aktuelle ReBreak-MDM-Version" bestimmt – ist sie im Profil hinterlegt, im Backend konfiguriert oder über eine Tauri-Funktion verfügbar?
3. Soll die App-Installation via MDM direkt aus dem Dashboard auslösbar sein, oder reicht ein Verweis auf `/sideload`?
