edee7b9f28
- Auto-Recovery in adapter.js: wenn Cloud-Modus gesetzt + lokale Daten vorhanden + keine Cloud-Session → Cloud-Konfiguration wird beim nächsten App-Start automatisch zurückgenommen. Marker rapport_080_recovery verhindert wiederholte Auslösung. - UpdateNotifier wird in allen Pre-Login-Screens gerendert (BackendChoice, Setup, MigrationScreen, CloudSetup, Login) — so kann ein hängender Wizard sich via Auto-Update selbst befreien. - Tauri-Builds ignorieren VITE_SUPABASE_URL aus dem Build. Desktop-User geben die Server-URL immer aktiv im Login ein, statt eine irrelevante Default-IP vorgesetzt zu bekommen. - Anon-Key bleibt aus dem Build (kein Geheimnis, pro Cloud-Instanz fix). - BackendChoice zeigt nur dann eine vorkonfigurierte URL, wenn nicht in Tauri. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
117 lines
4.7 KiB
React
117 lines
4.7 KiB
React
import React from "react";
|
|
|
|
// Erst-Screen einer frischen Rapport-Installation: «Lokal oder Cloud?».
|
|
// Wird angezeigt, solange `localStorage["rapport_backend_chosen"]` nicht
|
|
// gesetzt ist UND noch keine lokalen Daten existieren. Sobald der User
|
|
// gewählt hat, reloaded die App und der jeweilige Wizard übernimmt:
|
|
// Lokal → bestehender Setup.jsx
|
|
// Cloud → Login mit Init-Modus oder Login-Modus (je nach Studio-Vorhandensein)
|
|
|
|
// Tauri-User geben die Server-URL immer aktiv ein. Build-time-URL ist nur
|
|
// für Web-Deploy gedacht (z.B. app.rapport.kgva.ch → 127.0.0.1:54321 lokal).
|
|
const isTauri = typeof window !== "undefined" && !!window.__TAURI_INTERNALS__;
|
|
const envCloudUrl = isTauri ? "" : (import.meta.env.VITE_SUPABASE_URL || "");
|
|
|
|
export default function BackendChoice() {
|
|
const pick = (backend, cloudUrl = "") => {
|
|
localStorage.setItem("rapport_backend_chosen", "1");
|
|
localStorage.setItem("rapport_backend", backend);
|
|
if (backend === "cloud" && cloudUrl) {
|
|
localStorage.setItem("rapport_cloud_url", cloudUrl.replace(/\/+$/, ""));
|
|
}
|
|
window.location.reload();
|
|
};
|
|
|
|
return (
|
|
<div style={{
|
|
minHeight: "100vh", minWidth: "100vw",
|
|
background: "#ebe7e1",
|
|
display: "flex", alignItems: "center", justifyContent: "center",
|
|
fontFamily: "'DM Mono', 'Courier New', monospace",
|
|
position: "fixed", inset: 0, zIndex: 9999,
|
|
padding: 20,
|
|
}}>
|
|
<style>{`
|
|
@keyframes bc-fade-in {
|
|
from { opacity: 0; transform: translateY(16px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
.bc-card { animation: bc-fade-in 0.5s cubic-bezier(0.22,1,0.36,1) both; }
|
|
.bc-option {
|
|
width: 100%;
|
|
background: #fdfcfa;
|
|
border: 1.5px solid #ddd8d0;
|
|
border-radius: 14px;
|
|
padding: 22px 24px;
|
|
cursor: pointer;
|
|
font-family: inherit;
|
|
text-align: left;
|
|
transition: all 0.18s;
|
|
margin-bottom: 12px;
|
|
}
|
|
.bc-option:hover {
|
|
border-color: #9a7858;
|
|
box-shadow: 0 4px 16px rgba(154,120,88,0.12);
|
|
transform: translateY(-1px);
|
|
}
|
|
.bc-title {
|
|
font-size: 14px; font-weight: 500; color: #1a1a18; margin-bottom: 4px;
|
|
letter-spacing: 0.02em;
|
|
}
|
|
.bc-desc {
|
|
font-size: 12px; color: #888; line-height: 1.5;
|
|
}
|
|
`}</style>
|
|
|
|
<div className="bc-card" style={{
|
|
background: "transparent",
|
|
width: "100%", maxWidth: 460,
|
|
}}>
|
|
<div style={{ textAlign: "center", marginBottom: 36 }}>
|
|
<div style={{ fontFamily: "Krungthep, 'Archivo Black', sans-serif", fontSize: 40, color: "#1a1a18", letterSpacing: "-0.02em", lineHeight: 1 }}>
|
|
RAPPORT
|
|
</div>
|
|
<div style={{ fontSize: 10, color: "#b0aca4", letterSpacing: "0.22em", marginTop: 10, fontWeight: 500 }}>
|
|
ERSTE EINRICHTUNG
|
|
</div>
|
|
<div style={{ width: 40, height: 1.5, background: "#ddd8d0", margin: "20px auto 0" }} />
|
|
</div>
|
|
|
|
<p style={{ fontSize: 13, color: "#666", marginBottom: 26, textAlign: "center", lineHeight: 1.6 }}>
|
|
Wie möchten Sie Rapport nutzen?
|
|
</p>
|
|
|
|
<button className="bc-option" onClick={() => pick("local")}>
|
|
<div className="bc-title">Lokal auf diesem Gerät</div>
|
|
<div className="bc-desc">
|
|
Daten liegen ausschliesslich in diesem Browser / dieser App. Kein Server nötig.
|
|
Ideal zum Ausprobieren oder als Solo-Setup.
|
|
</div>
|
|
</button>
|
|
|
|
{envCloudUrl ? (
|
|
<button className="bc-option" onClick={() => pick("cloud", envCloudUrl)}>
|
|
<div className="bc-title">Mit Cloud-Server verbinden</div>
|
|
<div className="bc-desc">
|
|
Daten liegen auf dem konfigurierten Server. Mehrere Geräte / Mitarbeiter
|
|
können gemeinsam arbeiten. Vorkonfiguriert: <code style={{ fontSize: 11, color: "#9a7858" }}>{(() => { try { return new URL(envCloudUrl).host; } catch { return envCloudUrl; } })()}</code>
|
|
</div>
|
|
</button>
|
|
) : (
|
|
<button className="bc-option" onClick={() => pick("cloud")}>
|
|
<div className="bc-title">Mit Cloud-Server verbinden</div>
|
|
<div className="bc-desc">
|
|
Daten liegen auf einem Supabase-Server (z.B. Mac Mini im Büro, Docker im LAN).
|
|
Die Server-Adresse geben Sie im nächsten Schritt ein.
|
|
</div>
|
|
</button>
|
|
)}
|
|
|
|
<div style={{ marginTop: 24, fontSize: 11, color: "#aaa", textAlign: "center", lineHeight: 1.6 }}>
|
|
Sie können später in den Einstellungen wechseln.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|