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:
@@ -224,19 +224,26 @@ export default function UsersPage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Header */}
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-3xl font-bold text-gray-900">User Management</h2>
|
||||
<button
|
||||
onClick={() => {
|
||||
setFormData({ username: "", email: "", password: "", role: "VIEWER" });
|
||||
setShowAddModal(true);
|
||||
}}
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
|
||||
>
|
||||
Add User
|
||||
</button>
|
||||
<div className="space-y-8">
|
||||
{/* Hero Section with Gradient */}
|
||||
<div className="relative overflow-hidden rounded-2xl bg-gradient-to-br from-violet-600 via-purple-700 to-fuchsia-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 flex justify-between items-center">
|
||||
<div>
|
||||
<h2 className="text-4xl font-bold text-white mb-2">User Management</h2>
|
||||
<p className="text-violet-100 text-lg">Verwalte Benutzerkonten und Berechtigungen</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => {
|
||||
setFormData({ username: "", email: "", password: "", role: "VIEWER" });
|
||||
setShowAddModal(true);
|
||||
}}
|
||||
className="px-6 py-3 bg-white text-violet-700 rounded-xl hover:bg-violet-50 font-semibold shadow-lg hover:shadow-xl transition-all transform hover:-translate-y-0.5"
|
||||
>
|
||||
+ Add User
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Users Grid */}
|
||||
@@ -244,38 +251,50 @@ export default function UsersPage() {
|
||||
{users.map((user) => (
|
||||
<div
|
||||
key={user.id}
|
||||
className="bg-white rounded-lg shadow-md p-6 border-l-4"
|
||||
style={{
|
||||
borderLeftColor: user.role === "ADMIN" ? "#ef4444" : "#3b82f6",
|
||||
}}
|
||||
className="group relative overflow-hidden bg-white rounded-2xl shadow-lg hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-1 p-6"
|
||||
>
|
||||
<div className={`absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity bg-gradient-to-br ${
|
||||
user.role === "ADMIN" ? "from-red-50 to-orange-50" : "from-blue-50 to-indigo-50"
|
||||
}`}></div>
|
||||
<div className="relative">
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<span
|
||||
className={`px-2 py-1 text-xs font-medium rounded ${
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`w-12 h-12 rounded-xl shadow-lg flex items-center justify-center text-2xl ring-2 ring-white transform group-hover:scale-110 transition-transform ${
|
||||
user.role === "ADMIN"
|
||||
? "bg-red-100 text-red-800"
|
||||
: "bg-blue-100 text-blue-800"
|
||||
}`}
|
||||
>
|
||||
{user.role}
|
||||
</span>
|
||||
? "bg-gradient-to-br from-red-500 to-orange-600"
|
||||
: "bg-gradient-to-br from-blue-500 to-indigo-600"
|
||||
}`}>
|
||||
{user.role === "ADMIN" ? "👑" : "👤"}
|
||||
</div>
|
||||
<span
|
||||
className={`px-3 py-1.5 text-xs font-bold rounded-lg shadow-md ${
|
||||
user.role === "ADMIN"
|
||||
? "bg-gradient-to-r from-red-500 to-orange-600 text-white"
|
||||
: "bg-gradient-to-r from-blue-500 to-indigo-600 text-white"
|
||||
}`}
|
||||
>
|
||||
{user.role}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2 text-sm mb-4">
|
||||
<p>
|
||||
<span className="font-medium text-gray-700">Username:</span>{" "}
|
||||
<span className="text-gray-900">{user.username}</span>
|
||||
<div className="bg-gradient-to-br from-gray-50 to-slate-50 rounded-xl p-4 mb-4 border border-gray-200 space-y-2 text-sm">
|
||||
<p className="flex items-center justify-between">
|
||||
<span className="font-semibold text-gray-700">Username:</span>
|
||||
<span className="text-gray-900 font-mono bg-white px-2 py-0.5 rounded">{user.username}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium text-gray-700">Email:</span>{" "}
|
||||
<p className="flex items-center justify-between">
|
||||
<span className="font-semibold text-gray-700">Email:</span>
|
||||
<span className="text-gray-900">{user.email || "—"}</span>
|
||||
</p>
|
||||
<p className="text-gray-600">
|
||||
Created: {new Date(user.createdAt).toLocaleDateString()}
|
||||
<p className="flex items-center justify-between text-gray-600">
|
||||
<span>Created:</span>
|
||||
<span>{new Date(user.createdAt).toLocaleDateString()}</span>
|
||||
</p>
|
||||
{user.lastLoginAt && (
|
||||
<p className="text-gray-600">
|
||||
Last login: {new Date(user.lastLoginAt).toLocaleString()}
|
||||
<p className="flex items-center justify-between text-gray-600">
|
||||
<span>Last login:</span>
|
||||
<span>{new Date(user.lastLoginAt).toLocaleString()}</span>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
@@ -283,13 +302,13 @@ export default function UsersPage() {
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={() => openEditModal(user)}
|
||||
className="flex-1 px-3 py-2 bg-blue-600 text-white text-sm rounded-md hover:bg-blue-700"
|
||||
className="flex-1 px-4 py-2.5 bg-gradient-to-r from-blue-600 to-blue-700 text-white text-sm font-semibold rounded-lg hover:from-blue-700 hover:to-blue-800 shadow-md hover:shadow-lg transition-all"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
onClick={() => openDeleteModal(user)}
|
||||
className="flex-1 px-3 py-2 bg-red-600 text-white text-sm rounded-md hover:bg-red-700"
|
||||
className="flex-1 px-4 py-2.5 bg-gradient-to-r from-red-600 to-red-700 text-white text-sm font-semibold rounded-lg hover:from-red-700 hover:to-red-800 shadow-md hover:shadow-lg transition-all"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
@@ -300,15 +319,15 @@ export default function UsersPage() {
|
||||
<div className="flex gap-2 mt-2">
|
||||
<button
|
||||
onClick={() => handleResendWelcome(user)}
|
||||
className="flex-1 px-3 py-2 bg-green-600 text-white text-xs rounded-md hover:bg-green-700"
|
||||
className="flex-1 px-3 py-2 bg-gradient-to-r from-green-500 to-emerald-600 text-white text-xs font-semibold rounded-lg hover:from-green-600 hover:to-emerald-700 shadow-md hover:shadow-lg transition-all"
|
||||
>
|
||||
Resend Welcome
|
||||
📧 Resend Welcome
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleSendPasswordReset(user)}
|
||||
className="flex-1 px-3 py-2 bg-orange-600 text-white text-xs rounded-md hover:bg-orange-700"
|
||||
className="flex-1 px-3 py-2 bg-gradient-to-r from-orange-500 to-red-500 text-white text-xs font-semibold rounded-lg hover:from-orange-600 hover:to-red-600 shadow-md hover:shadow-lg transition-all"
|
||||
>
|
||||
Reset Password
|
||||
🔑 Reset Password
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
@@ -317,8 +336,10 @@ export default function UsersPage() {
|
||||
</div>
|
||||
|
||||
{users.length === 0 && (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-gray-600">No users found. Create your first user!</p>
|
||||
<div className="relative overflow-hidden bg-gradient-to-br from-gray-50 to-slate-50 rounded-2xl shadow-lg p-12 text-center border border-gray-200">
|
||||
<div className="absolute top-0 right-0 text-9xl opacity-5">👤</div>
|
||||
<p className="text-xl font-semibold text-gray-600 mb-2">Keine Benutzer gefunden</p>
|
||||
<p className="text-gray-500">Erstelle deinen ersten Benutzer!</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user