Apply modern SaaS design to all admin pages

Modernize all admin interface pages with consistent design language:
- Add hero sections with gradient backgrounds and blur effects
- Implement modern card designs with hover animations
- Use gradient buttons with shadow effects
- Add emoji icons in colored containers
- Apply consistent color themes per page
- Enhance user experience with smooth transitions

Pages updated:
- /admin/devices (purple theme)
- /admin/mqtt (cyan/blue theme)
- /admin/setup (emerald theme)
- /admin/users (violet theme)
- /admin/settings (indigo theme)
- /admin/emails (pink/rose theme)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 23:31:25 +00:00
parent 5f637817ce
commit a39b53151e
6 changed files with 392 additions and 243 deletions

View File

@@ -12,26 +12,38 @@ export default function SetupGuidePage() {
};
return (
<div className="max-w-4xl mx-auto">
<div className="bg-white rounded-lg shadow-lg p-8">
<h1 className="text-4xl font-bold text-gray-900 mb-4">
📱 OwnTracks App Setup Anleitung
</h1>
<p className="text-gray-600 mb-8">
Diese Anleitung erklärt Schritt-für-Schritt, wie Sie die OwnTracks App
auf Ihrem Smartphone installieren und mit dem Location Tracker System verbinden.
</p>
<div className="max-w-5xl mx-auto space-y-8">
{/* Hero Section with Gradient */}
<div className="relative overflow-hidden rounded-2xl bg-gradient-to-br from-emerald-600 via-teal-700 to-cyan-800 p-8 shadow-xl">
<div className="absolute top-0 right-0 -mt-4 -mr-4 h-40 w-40 rounded-full bg-white/10 blur-3xl"></div>
<div className="absolute bottom-0 left-0 -mb-4 -ml-4 h-40 w-40 rounded-full bg-white/10 blur-3xl"></div>
<div className="relative">
<h1 className="text-4xl font-bold text-white mb-3 flex items-center gap-3">
<span className="text-5xl">📱</span>
OwnTracks App Setup Anleitung
</h1>
<p className="text-emerald-100 text-lg">
Diese Anleitung erklärt Schritt-für-Schritt, wie Sie die OwnTracks App
auf Ihrem Smartphone installieren und mit dem Location Tracker System verbinden.
</p>
</div>
</div>
<div className="bg-white rounded-2xl shadow-lg p-8">
{/* Table of Contents */}
<div className="bg-blue-50 border border-blue-200 rounded-lg p-6 mb-8">
<h2 className="text-xl font-bold text-gray-900 mb-3">📋 Inhaltsverzeichnis</h2>
<ul className="space-y-2 text-sm">
<li><a href="#installation" className="text-blue-600 hover:underline">1. Installation</a></li>
<li><a href="#credentials" className="text-blue-600 hover:underline">2. MQTT Credentials erhalten</a></li>
<li><a href="#configuration" className="text-blue-600 hover:underline">3. App Konfiguration</a></li>
<li><a href="#testing" className="text-blue-600 hover:underline">5. Verbindung testen</a></li>
<li><a href="#ports" className="text-blue-600 hover:underline">6. Port 1883 vs. 9001</a></li>
<li><a href="#troubleshooting" className="text-blue-600 hover:underline">7. Troubleshooting</a></li>
<div className="bg-gradient-to-br from-blue-50 to-indigo-50 border-2 border-blue-200 rounded-2xl p-6 mb-8 shadow-md">
<h2 className="text-xl font-bold text-gray-900 mb-4 flex items-center gap-2">
<span className="text-2xl">📋</span>
Inhaltsverzeichnis
</h2>
<ul className="grid grid-cols-1 md:grid-cols-2 gap-3">
<li><a href="#installation" className="flex items-center gap-2 text-blue-700 hover:text-blue-900 font-semibold hover:underline bg-white px-4 py-2 rounded-lg shadow-sm hover:shadow-md transition-all"> 1. Installation</a></li>
<li><a href="#credentials" className="flex items-center gap-2 text-blue-700 hover:text-blue-900 font-semibold hover:underline bg-white px-4 py-2 rounded-lg shadow-sm hover:shadow-md transition-all"> 2. MQTT Credentials erhalten</a></li>
<li><a href="#configuration" className="flex items-center gap-2 text-blue-700 hover:text-blue-900 font-semibold hover:underline bg-white px-4 py-2 rounded-lg shadow-sm hover:shadow-md transition-all"> 3. App Konfiguration</a></li>
<li><a href="#testing" className="flex items-center gap-2 text-blue-700 hover:text-blue-900 font-semibold hover:underline bg-white px-4 py-2 rounded-lg shadow-sm hover:shadow-md transition-all"> 5. Verbindung testen</a></li>
<li><a href="#ports" className="flex items-center gap-2 text-blue-700 hover:text-blue-900 font-semibold hover:underline bg-white px-4 py-2 rounded-lg shadow-sm hover:shadow-md transition-all"> 6. Port 1883 vs. 9001</a></li>
<li><a href="#troubleshooting" className="flex items-center gap-2 text-blue-700 hover:text-blue-900 font-semibold hover:underline bg-white px-4 py-2 rounded-lg shadow-sm hover:shadow-md transition-all"> 7. Troubleshooting</a></li>
</ul>
</div>
@@ -44,8 +56,11 @@ export default function SetupGuidePage() {
onToggle={() => toggleSection("1")}
>
<div className="grid md:grid-cols-2 gap-6">
<div className="border rounded-lg p-4">
<h4 className="font-bold text-lg mb-2">🍎 iOS (iPhone/iPad)</h4>
<div className="bg-gradient-to-br from-blue-50 to-indigo-50 border-2 border-blue-200 rounded-xl p-5 shadow-md hover:shadow-lg transition-shadow">
<h4 className="font-bold text-lg mb-3 flex items-center gap-2">
<span className="text-2xl">🍎</span>
iOS (iPhone/iPad)
</h4>
<ol className="list-decimal list-inside space-y-2 text-sm">
<li>Öffnen Sie den <strong>App Store</strong></li>
<li>Suchen Sie nach <strong>"OwnTracks"</strong></li>
@@ -55,13 +70,16 @@ export default function SetupGuidePage() {
href="https://apps.apple.com/app/owntracks/id692424691"
target="_blank"
rel="noopener noreferrer"
className="inline-block mt-3 text-blue-600 hover:underline text-sm"
className="inline-block mt-3 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 text-sm font-semibold shadow-md hover:shadow-lg transition-all"
>
App Store Link
</a>
</div>
<div className="border rounded-lg p-4">
<h4 className="font-bold text-lg mb-2">🤖 Android</h4>
<div className="bg-gradient-to-br from-green-50 to-emerald-50 border-2 border-green-200 rounded-xl p-5 shadow-md hover:shadow-lg transition-shadow">
<h4 className="font-bold text-lg mb-3 flex items-center gap-2">
<span className="text-2xl">🤖</span>
Android
</h4>
<ol className="list-decimal list-inside space-y-2 text-sm">
<li>Öffnen Sie den <strong>Google Play Store</strong></li>
<li>Suchen Sie nach <strong>"OwnTracks"</strong></li>
@@ -71,7 +89,7 @@ export default function SetupGuidePage() {
href="https://play.google.com/store/apps/details?id=org.owntracks.android"
target="_blank"
rel="noopener noreferrer"
className="inline-block mt-3 text-blue-600 hover:underline text-sm"
className="inline-block mt-3 px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 text-sm font-semibold shadow-md hover:shadow-lg transition-all"
>
Play Store Link
</a>
@@ -87,8 +105,11 @@ export default function SetupGuidePage() {
isOpen={openSections["2"]}
onToggle={() => toggleSection("2")}
>
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4 mb-4">
<p className="text-sm font-semibold"> Wichtig: Bevor Sie die App konfigurieren, benötigen Sie MQTT-Zugangsdaten!</p>
<div className="bg-gradient-to-r from-yellow-50 to-orange-50 border-2 border-yellow-300 rounded-xl p-5 mb-6 shadow-md">
<p className="text-sm font-bold text-yellow-900 flex items-center gap-2">
<span className="text-xl"></span>
Wichtig: Bevor Sie die App konfigurieren, benötigen Sie MQTT-Zugangsdaten!
</p>
</div>
<ol className="list-decimal list-inside space-y-3 text-sm">
<li>Navigieren Sie zu <a href="/admin/mqtt" className="text-blue-600 hover:underline font-semibold">MQTT Provisioning</a></li>
@@ -234,14 +255,20 @@ export default function SetupGuidePage() {
</Section>
{/* Quick Start Checklist */}
<div className="bg-green-50 border border-green-200 rounded-lg p-6 mt-8">
<h3 className="text-xl font-bold text-gray-900 mb-4"> Schnellstart-Checkliste</h3>
<div className="bg-gradient-to-br from-green-50 to-emerald-50 border-2 border-green-200 rounded-2xl shadow-lg p-6 mt-8">
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center gap-2">
<span className="text-2xl"></span>
Schnellstart-Checkliste
</h3>
<ChecklistItems />
</div>
{/* Support Section */}
<div className="bg-gray-50 border border-gray-200 rounded-lg p-6 mt-8">
<h3 className="text-xl font-bold text-gray-900 mb-3">📞 Weiterführende Informationen</h3>
<div className="bg-gradient-to-br from-slate-50 to-gray-50 border-2 border-gray-200 rounded-2xl shadow-lg p-6 mt-8">
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center gap-2">
<span className="text-2xl">📞</span>
Weiterführende Informationen
</h3>
<div className="grid md:grid-cols-2 gap-4 text-sm">
<div>
<h4 className="font-semibold mb-2">OwnTracks Dokumentation:</h4>
@@ -282,19 +309,20 @@ function Section({
children: React.ReactNode;
}) {
return (
<div id={id} className="border-b border-gray-200 py-6">
<div id={id} className="bg-white rounded-2xl shadow-lg overflow-hidden mb-6 border border-gray-200">
<button
onClick={onToggle}
className="flex items-center justify-between w-full text-left hover:bg-gray-50 p-2 rounded"
className="flex items-center justify-between w-full text-left bg-gradient-to-r from-gray-50 to-slate-50 hover:from-blue-50 hover:to-indigo-50 px-6 py-5 transition-all"
>
<h2 className="text-2xl font-bold text-gray-900">
{icon} {title}
<h2 className="text-2xl font-bold text-gray-900 flex items-center gap-3">
<span className="text-3xl">{icon}</span>
{title}
</h2>
<span className="text-2xl text-gray-400">
<span className={`text-3xl font-bold transition-transform ${isOpen ? 'rotate-180' : ''}`}>
{isOpen ? "" : "+"}
</span>
</button>
{isOpen && <div className="mt-4">{children}</div>}
{isOpen && <div className="p-6 bg-white border-t border-gray-200">{children}</div>}
</div>
);
}
@@ -345,7 +373,7 @@ function ConfigTable() {
function PortComparison() {
return (
<div className="grid md:grid-cols-2 gap-6">
<div className="border-2 border-green-500 rounded-lg p-4 bg-green-50">
<div className="border-2 border-green-400 rounded-xl p-6 bg-gradient-to-br from-green-50 to-emerald-50 shadow-lg hover:shadow-xl transition-shadow">
<h4 className="font-bold text-lg mb-3 text-green-800">Port 1883 (Standard MQTT)</h4>
<ul className="space-y-2 text-sm">
<li> <strong>Protokoll:</strong> Standard MQTT (TCP)</li>
@@ -360,7 +388,7 @@ function PortComparison() {
Websockets: DEAKTIVIERT
</div>
</div>
<div className="border-2 border-blue-500 rounded-lg p-4 bg-blue-50">
<div className="border-2 border-blue-400 rounded-xl p-6 bg-gradient-to-br from-blue-50 to-indigo-50 shadow-lg hover:shadow-xl transition-shadow">
<h4 className="font-bold text-lg mb-3 text-blue-800">Port 9001 (MQTT over WebSockets)</h4>
<ul className="space-y-2 text-sm">
<li> <strong>Protokoll:</strong> MQTT über WebSocket</li>
@@ -416,8 +444,11 @@ function TroubleshootingSection() {
function TroubleshootingItem({ problem, solutions }: { problem: string; solutions: string[] }) {
return (
<div className="border border-gray-300 rounded-lg p-4">
<h4 className="font-bold text-red-600 mb-2"> {problem}</h4>
<div className="bg-gradient-to-br from-red-50 to-orange-50 border-2 border-red-200 rounded-xl p-5 shadow-md hover:shadow-lg transition-shadow">
<h4 className="font-bold text-red-700 mb-3 text-lg flex items-center gap-2">
<span className="text-xl"></span>
{problem}
</h4>
<ul className="space-y-1 text-sm">
{solutions.map((solution, i) => (
<li key={i} className="flex items-start gap-2">