summaryrefslogtreecommitdiff
path: root/makima/frontend/src/routes/settings.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'makima/frontend/src/routes/settings.tsx')
-rw-r--r--makima/frontend/src/routes/settings.tsx64
1 files changed, 64 insertions, 0 deletions
diff --git a/makima/frontend/src/routes/settings.tsx b/makima/frontend/src/routes/settings.tsx
index 73537bd..a77ad95 100644
--- a/makima/frontend/src/routes/settings.tsx
+++ b/makima/frontend/src/routes/settings.tsx
@@ -2,6 +2,7 @@ import { useState, useEffect, type FormEvent } from "react";
import { useAuth } from "../contexts/AuthContext";
import { useNavigate } from "react-router";
import { Masthead } from "../components/Masthead";
+import { useUserSettings } from "../hooks/useUserSettings";
import {
getApiKey,
createApiKey,
@@ -267,6 +268,11 @@ export default function SettingsPage() {
const { user, isAuthConfigured, signOut } = useAuth();
const navigate = useNavigate();
+ // User settings (feature flags) state
+ const { settings: userSettings, loading: userSettingsLoading, update: updateUserSettings } = useUserSettings();
+ const [featureFlagSaving, setFeatureFlagSaving] = useState(false);
+ const [featureFlagError, setFeatureFlagError] = useState<string | null>(null);
+
// API Key state
const [apiKeyInfo, setApiKeyInfo] = useState<ApiKeyInfo | null>(null);
const [newKey, setNewKey] = useState<string | null>(null);
@@ -490,6 +496,21 @@ export default function SettingsPage() {
}
};
+ // Feature flag toggle handlers
+ const handleToggleDocumentMode = async () => {
+ if (featureFlagSaving) return;
+ setFeatureFlagError(null);
+ setFeatureFlagSaving(true);
+ try {
+ const next = !(userSettings?.documentModeEnabled ?? false);
+ await updateUserSettings({ documentModeEnabled: next });
+ } catch (err) {
+ setFeatureFlagError(err instanceof Error ? err.message : "Failed to update setting");
+ } finally {
+ setFeatureFlagSaving(false);
+ }
+ };
+
const passwordStrength = getPasswordStrength(passwordForm.newPassword);
return (
@@ -789,6 +810,49 @@ export default function SettingsPage() {
</section>
)}
+ {/* Feature Flags (POC) */}
+ <section className="border border-[rgba(117,170,252,0.25)] bg-[#0d1b2d] p-4">
+ <SectionHeader>Feature Flags (POC)</SectionHeader>
+ {featureFlagError && <ErrorAlert>{featureFlagError}</ErrorAlert>}
+ <div className="flex items-start gap-3">
+ <button
+ type="button"
+ role="switch"
+ aria-checked={userSettings?.documentModeEnabled ?? false}
+ aria-label="Document Mode for directives"
+ onClick={handleToggleDocumentMode}
+ disabled={userSettingsLoading || featureFlagSaving}
+ className={`relative shrink-0 mt-0.5 w-10 h-5 border transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${
+ userSettings?.documentModeEnabled
+ ? "bg-[#3f6fb3] border-[#75aafc]"
+ : "bg-[#0a1628] border-[rgba(117,170,252,0.35)]"
+ }`}
+ >
+ <span
+ className={`absolute top-0.5 left-0.5 w-3.5 h-3.5 transition-transform ${
+ userSettings?.documentModeEnabled
+ ? "translate-x-5 bg-white"
+ : "translate-x-0 bg-[#9bc3ff]"
+ }`}
+ />
+ </button>
+ <div className="flex-1 min-w-0">
+ <div className="font-mono text-xs text-[#9bc3ff] mb-1">
+ Document Mode for directives
+ </div>
+ <p className="font-mono text-[10px] text-[#7788aa] leading-snug">
+ Replaces the tabular directives UI with a Lexical-based interactive
+ document editor. Proof of concept; expect rough edges.
+ </p>
+ {(userSettingsLoading || featureFlagSaving) && (
+ <p className="font-mono text-[10px] text-[#556677] mt-1">
+ {userSettingsLoading ? "Loading..." : "Saving..."}
+ </p>
+ )}
+ </div>
+ </div>
+ </section>
+
{/* Danger Zone */}
{isAuthConfigured && user && (
<section className="border border-red-900/50 bg-[#0d1b2d] p-4">