{children || }
@@ -150,22 +141,7 @@ export function AppLayout({
{!isMobile && }
{/* Mobile bottom nav */}
- {isMobile && (
-
- )}
+ {isMobile &&
+ {/* Mobile header */}
+
+ );
+ }
+
return (
+
+
+ {/* Mobile pill strip nav */}
+ {t.settings.heading}
+ +
+ {visibleNavItems.map((item) => (
+
+ ))}
+
+
+ {/* Mobile content */}
+
+ {section === "general" && }
+ {section === "system" && }
+ {section === "security" && }
+ {section === "people" && }
+ {section === "teams" && }
+ {section === "roles" && }
+ {section === "audit-log" && }
+ {section === "api-keys" && }
+ {section === "ai-features" && }
+ {section === "tools" && }
+ {section === "analytics" && }
+ {section === "about" && }
+
+
{/* Backdrop */}
@@ -249,7 +305,7 @@ interface UserEntry {
}
interface TeamEntry {
- id: number;
+ id: string;
name: string;
memberCount: number;
createdAt: string;
@@ -624,6 +680,7 @@ function SecuritySection() {
const [confirmPassword, setConfirmPassword] = useState("");
const [showCurrent, setShowCurrent] = useState(false);
const [showNew, setShowNew] = useState(false);
+ const [showConfirm, setShowConfirm] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
@@ -709,14 +766,24 @@ function SecuritySection() {
- setConfirmPassword(e.target.value)}
- placeholder={t.settings.security.confirmPasswordPlaceholder}
- className="w-full px-3 py-2 rounded-lg border border-border bg-background text-sm text-foreground"
- required
- />
+
+ setConfirmPassword(e.target.value)}
+ placeholder={t.settings.security.confirmPasswordPlaceholder}
+ className="w-full px-3 py-2 pe-10 rounded-lg border border-border bg-background text-sm text-foreground"
+ required
+ />
+
+
{message && (
([]); const [maxUsers, setMaxUsers] = useState(5); const [loading, setLoading] = useState(true); @@ -1029,7 +1097,7 @@ function PeopleSection() {
{t.settings.people.newMemberHeading}
-
+
- {/* Table header */}
-
- {t.settings.people.tableHeaderUser}
- {t.settings.people.tableHeaderRole}
- {t.settings.people.tableHeaderTeam}
-
-
+ {/* Table header (desktop only) */}
+ {!isMobile && (
+
+ {t.settings.people.tableHeaderUser}
+ {t.settings.people.tableHeaderRole}
+ {t.settings.people.tableHeaderTeam}
+
+
+ )}
{/* Table rows */}
{filteredUsers.length === 0 ? (
@@ -1277,45 +1347,91 @@ function PeopleSection() {
filteredUsers.map((u) => (
- {/* User cell */}
-
-
+ {isMobile ? (
+ <>
+ {/* Mobile card layout */}
+
- {u.username.charAt(0).toUpperCase()}
-
- {u.username}
- {u.hasOidcLink && u.hasLocalPassword !== false && (
-
- {t.auth.methodBoth}
-
- )}
- {u.hasOidcLink && u.hasLocalPassword === false && (
-
- {t.auth.methodOidc}
-
- )}
-
+ {u.username.charAt(0).toUpperCase()}
+
+
+
+ >
+ ) : (
+ <>
+ {/* Desktop row layout */}
+
+
+ {u.username}
+
+ {u.hasOidcLink && u.hasLocalPassword !== false && (
+
+ {t.auth.methodBoth}
+
+ )}
+ {u.hasOidcLink && u.hasLocalPassword === false && (
+
+ {t.auth.methodOidc}
+
+ )}
+
+
+
+ {u.role}
+
+ {u.team}
+
+
+
- {/* Role badge */}
-
+ {u.username.charAt(0).toUpperCase()}
+
+
+ {u.username}
+
+ {u.hasOidcLink && u.hasLocalPassword !== false && (
+
+ {t.auth.methodBoth}
+
+ )}
+ {u.hasOidcLink && u.hasLocalPassword === false && (
+
+ {t.auth.methodOidc}
+
+ )}
+
-
- {u.role}
-
-
+ {/* Role badge */}
+
+
+ {u.role}
+
+
- {/* Team */}
- {u.team}
+ {/* Team */}
+ {u.team}
+ >
+ )}
{/* Actions */}
-
+