summaryrefslogtreecommitdiff
path: root/apps/web/app/reader/settings/_components/settings-shell.tsx
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-07 01:42:57 -0800
committerFuwn <[email protected]>2026-02-07 01:42:57 -0800
commit5c5b1993edd890a80870ee05607ac5f088191d4e (patch)
treea721b76bcd49ba10826c53efc87302c7a689512f /apps/web/app/reader/settings/_components/settings-shell.tsx
downloadasa.news-5c5b1993edd890a80870ee05607ac5f088191d4e.tar.xz
asa.news-5c5b1993edd890a80870ee05607ac5f088191d4e.zip
feat: asa.news RSS reader with developer tier, REST API, and webhooks
Full-stack RSS reader SaaS: Supabase + Next.js + Go worker. Includes three subscription tiers (free/pro/developer), API key auth, read-only REST API, webhook push notifications, Stripe billing with proration, and PWA support.
Diffstat (limited to 'apps/web/app/reader/settings/_components/settings-shell.tsx')
-rw-r--r--apps/web/app/reader/settings/_components/settings-shell.tsx86
1 files changed, 86 insertions, 0 deletions
diff --git a/apps/web/app/reader/settings/_components/settings-shell.tsx b/apps/web/app/reader/settings/_components/settings-shell.tsx
new file mode 100644
index 0000000..ae432f3
--- /dev/null
+++ b/apps/web/app/reader/settings/_components/settings-shell.tsx
@@ -0,0 +1,86 @@
+"use client"
+
+import { useUserInterfaceStore } from "@/lib/stores/user-interface-store"
+import { SubscriptionsSettings } from "./subscriptions-settings"
+import { FoldersSettings } from "./folders-settings"
+import { MutedKeywordsSettings } from "./muted-keywords-settings"
+import { CustomFeedsSettings } from "./custom-feeds-settings"
+import { ImportExportSettings } from "./import-export-settings"
+import { AppearanceSettings } from "./appearance-settings"
+import { AccountSettings } from "./account-settings"
+import { SecuritySettings } from "./security-settings"
+import { BillingSettings } from "./billing-settings"
+import { ApiSettings } from "./api-settings"
+import { DangerZoneSettings } from "./danger-zone-settings"
+
+const TABS = [
+ { key: "subscriptions", label: "subscriptions" },
+ { key: "folders", label: "folders" },
+ { key: "muted-keywords", label: "muted keywords" },
+ { key: "custom-feeds", label: "custom feeds" },
+ { key: "import-export", label: "import / export" },
+ { key: "appearance", label: "appearance" },
+ { key: "account", label: "account" },
+ { key: "security", label: "security" },
+ { key: "billing", label: "billing" },
+ { key: "api", label: "API" },
+ { key: "danger", label: "danger zone" },
+] as const
+
+export function SettingsShell() {
+ const activeTab = useUserInterfaceStore((state) => state.activeSettingsTab)
+ const setActiveTab = useUserInterfaceStore(
+ (state) => state.setActiveSettingsTab
+ )
+
+ return (
+ <div className="flex h-full flex-col">
+ <header className="flex items-center border-b border-border px-4 py-3">
+ <h1 className="text-text-primary">settings</h1>
+ </header>
+ <nav className="border-b border-border">
+ <select
+ value={activeTab}
+ onChange={(event) => setActiveTab(event.target.value as typeof activeTab)}
+ className="w-full border-none bg-background-primary px-4 py-2 text-text-primary outline-none md:hidden"
+ >
+ {TABS.map((tab) => (
+ <option key={tab.key} value={tab.key}>
+ {tab.label}
+ </option>
+ ))}
+ </select>
+ <div className="hidden md:flex">
+ {TABS.map((tab) => (
+ <button
+ key={tab.key}
+ onClick={() => setActiveTab(tab.key)}
+ className={`shrink-0 px-4 py-2 transition-colors ${
+ activeTab === tab.key
+ ? "border-b-2 border-text-primary text-text-primary"
+ : "text-text-dim hover:text-text-secondary"
+ }`}
+ >
+ {tab.label}
+ </button>
+ ))}
+ </div>
+ </nav>
+ <div className="flex-1 overflow-y-auto">
+ <div className="max-w-3xl">
+ {activeTab === "subscriptions" && <SubscriptionsSettings />}
+ {activeTab === "folders" && <FoldersSettings />}
+ {activeTab === "muted-keywords" && <MutedKeywordsSettings />}
+ {activeTab === "custom-feeds" && <CustomFeedsSettings />}
+ {activeTab === "import-export" && <ImportExportSettings />}
+ {activeTab === "appearance" && <AppearanceSettings />}
+ {activeTab === "account" && <AccountSettings />}
+ {activeTab === "security" && <SecuritySettings />}
+ {activeTab === "billing" && <BillingSettings />}
+ {activeTab === "api" && <ApiSettings />}
+ {activeTab === "danger" && <DangerZoneSettings />}
+ </div>
+ </div>
+ </div>
+ )
+}