You've been invited to join an organization. Please log in or sign up to accept.
diff --git a/src/routes/login.tsx b/src/routes/login.tsx
index c24e6d2..482c9d7 100644
--- a/src/routes/login.tsx
+++ b/src/routes/login.tsx
@@ -3,6 +3,8 @@ import { useSearchParams } from 'react-router'
import BaseLayout from '~/components/BaseLayout'
+export const handle = { title: 'Log in — Underlay' }
+
export default function LoginPage() {
const [params] = useSearchParams()
const error = params.get('error')
diff --git a/src/routes/logout.tsx b/src/routes/logout.tsx
index 404493f..8eff63f 100644
--- a/src/routes/logout.tsx
+++ b/src/routes/logout.tsx
@@ -1,11 +1,13 @@
import { useEffect } from 'react'
import BaseLayout from '~/components/BaseLayout'
+import { useAppContext } from '~/lib/app-context'
import { authClient } from '~/lib/auth-client'
-import { useSSRData } from '~/lib/ssr-data'
+
+export const handle = { title: 'Log out — Underlay' }
export default function LogoutPage() {
- const kfAuthUrl = useSSRData('kfAuthUrl')
+ const { kfAuthUrl } = useAppContext()
useEffect(() => {
authClient.signOut().then(() => {
diff --git a/src/routes/query.tsx b/src/routes/query.tsx
index 5179f0d..59cf3dc 100644
--- a/src/routes/query.tsx
+++ b/src/routes/query.tsx
@@ -2,14 +2,12 @@ import { Link } from 'react-router'
import QueryExplorer from '~/components/QueryExplorer'
import UserMenu from '~/components/UserMenu'
-import { useSSRData } from '~/lib/ssr-data'
+import { useAppContext } from '~/lib/app-context'
+
+export const handle = { title: 'Query Explorer — Underlay' }
export default function QueryPage() {
- const currentUser = useSSRData<{
- slug: string
- displayName: string
- orgs?: { slug: string; displayName: string }[]
- } | null>('currentUser')
+ const { currentUser } = useAppContext()
return (
diff --git a/src/routes/reset-password.tsx b/src/routes/reset-password.tsx
index 7338c4e..61b69da 100644
--- a/src/routes/reset-password.tsx
+++ b/src/routes/reset-password.tsx
@@ -2,6 +2,8 @@ import { useEffect } from 'react'
import BaseLayout from '~/components/BaseLayout'
+export const handle = { title: 'Reset password — Underlay' }
+
export default function ResetPasswordPage() {
useEffect(() => {
window.location.href = '/login'
diff --git a/src/routes/schemas/[id].tsx b/src/routes/schemas/[id].tsx
index b18387b..76a944a 100644
--- a/src/routes/schemas/[id].tsx
+++ b/src/routes/schemas/[id].tsx
@@ -3,7 +3,6 @@ import { Link, useParams } from 'react-router'
import BaseLayout from '~/components/BaseLayout'
import SchemaLabelManager from '~/components/SchemaLabelManager'
-import { useSSRData } from '~/lib/ssr-data'
interface SchemaData {
id: number
@@ -14,9 +13,11 @@ interface SchemaData {
usage?: { slug: string; semver: string; versionNumber: number; collection: string }[]
}
+export const handle = { title: 'Schema — Underlay' }
+
export default function SchemaDetailPage() {
const params = useParams()
- const schemaId = useSSRData
('schemaId') ?? params.id
+ const schemaId = params.id
const [schema, setSchema] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState('')
diff --git a/src/routes/schemas/index.tsx b/src/routes/schemas/index.tsx
index 4e50b11..2be37a5 100644
--- a/src/routes/schemas/index.tsx
+++ b/src/routes/schemas/index.tsx
@@ -1,6 +1,8 @@
import BaseLayout from '~/components/BaseLayout'
import SchemaBrowser from '~/components/SchemaBrowser'
+export const handle = { title: 'Schemas — Underlay' }
+
export default function SchemasPage() {
return (
diff --git a/src/routes/settings/avatar.tsx b/src/routes/settings/avatar.tsx
index 2106df0..1eaa9b8 100644
--- a/src/routes/settings/avatar.tsx
+++ b/src/routes/settings/avatar.tsx
@@ -1,16 +1,18 @@
import { type FormEvent, useState } from 'react'
-import { Link } from 'react-router'
+import { Link, Navigate } from 'react-router'
import BaseLayout from '~/components/BaseLayout'
-import { useSSRData } from '~/lib/ssr-data'
+import { useAppContext } from '~/lib/app-context'
+
+export const handle = { title: 'Avatar — Underlay', requireAuth: true }
export default function SettingsAvatar() {
- const me = useSSRData('currentUser')
+ const { currentUser } = useAppContext()
const [success, setSuccess] = useState('')
const [error, setError] = useState('')
const [submitting, setSubmitting] = useState(false)
- const [avatarUrl, setAvatarUrl] = useState(me?.avatarUrl ?? '')
+ const [avatarUrl, setAvatarUrl] = useState(currentUser?.avatarUrl ?? '')
async function handleUpload(e: FormEvent) {
e.preventDefault()
@@ -50,7 +52,7 @@ export default function SettingsAvatar() {
}
}
- if (!me) return null
+ if (!currentUser) return
return (
@@ -100,7 +102,7 @@ export default function SettingsAvatar() {
/>
) : (
- {me.displayName?.charAt(0)?.toUpperCase() ?? '?'}
+ {currentUser.displayName?.charAt(0)?.toUpperCase() ?? '?'}
)}
diff --git a/src/routes/settings/index.tsx b/src/routes/settings/index.tsx
index 18289d4..e8e99cc 100644
--- a/src/routes/settings/index.tsx
+++ b/src/routes/settings/index.tsx
@@ -1,24 +1,25 @@
import { type FormEvent, useState } from 'react'
-import { Link } from 'react-router'
+import { Link, Navigate } from 'react-router'
import BaseLayout from '~/components/BaseLayout'
-import { useSSRData } from '~/lib/ssr-data'
+import { useAppContext } from '~/lib/app-context'
+
+export const handle = { title: 'Settings — Underlay', requireAuth: true }
export default function Settings() {
- const me = useSSRData
('currentUser')
- const kfAccountUrl = useSSRData('kfAccountUrl')
+ const { currentUser, kfAccountUrl } = useAppContext()
const [success, setSuccess] = useState('')
const [error, setError] = useState('')
// Profile form (Underlay-specific fields only — name/email/avatar managed by KF Auth)
- const [slugValue, setSlugValue] = useState(me?.slug ?? '')
- const [bio, setBio] = useState(me?.bio ?? '')
- const [website, setWebsite] = useState(me?.website ?? '')
- const [location, setLocation] = useState(me?.location ?? '')
+ const [slugValue, setSlugValue] = useState(currentUser?.slug ?? '')
+ const [bio, setBio] = useState(currentUser?.bio ?? '')
+ const [website, setWebsite] = useState(currentUser?.website ?? '')
+ const [location, setLocation] = useState(currentUser?.location ?? '')
// Notifications
- const notifPrefs = (me?.notificationPrefs as Record) ?? {}
+ const notifPrefs = (currentUser?.notificationPrefs as Record) ?? {}
const [collectionActivity, setCollectionActivity] = useState(
notifPrefs.collectionActivity ?? true,
)
@@ -39,7 +40,7 @@ export default function Settings() {
e.preventDefault()
clearMessages()
setSubmitting('profile')
- const slugChanged = slugValue.trim() !== '' && slugValue.trim() !== me?.slug
+ const slugChanged = slugValue.trim() !== '' && slugValue.trim() !== currentUser?.slug
try {
const payload: Record = { bio, website, location }
if (slugChanged) payload.slug = slugValue.trim()
@@ -110,7 +111,7 @@ export default function Settings() {
}
}
- if (!me) return null
+ if (!currentUser) return
return (
@@ -145,20 +146,20 @@ export default function Settings() {
Profile
- {me.avatarUrl ? (
+ {currentUser.avatarUrl ? (

) : (
- {me.displayName?.charAt(0)?.toUpperCase() ?? '?'}
+ {currentUser.displayName?.charAt(0)?.toUpperCase() ?? '?'}
)}