Polish: per-route titles and a way to sign out
There was no sign-out control anywhere. Easy to miss when you develop permanently signed in, and a stranded feeling for anyone on a shared machine. Clearing the identity provider's session is sufficient — PIG holds no session of its own — and the auth listener returns to sign-in without a reload. A hard redirect follows regardless, so a failed provider call cannot leave a half-signed-out interface. Every route now sets its own document title. A single static title makes browser history and a wall of tabs useless: every entry reads "pig" and nobody can tell the margin view from the pipeline. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,12 +6,13 @@
|
||||
* devices rather than being a per-browser quirk.
|
||||
*/
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { Check, Monitor, Moon, Sun, Terminal } from 'lucide-react';
|
||||
import { get, patch } from '@/lib/api';
|
||||
import { Check, LogOut, Monitor, Moon, Sun, Terminal } from 'lucide-react';
|
||||
import { get, getSupabase, patch } from '@/lib/api';
|
||||
import { useTheme } from '@/lib/theme';
|
||||
import { getAccent, THEME_MODES, type ThemeMode } from '@pig/core';
|
||||
import { Badge, Button, Card, CardContent, CardHeader, CardTitle, Input } from '@/components/ui';
|
||||
import { useState } from 'react';
|
||||
import { usePageTitle } from '@/lib/title';
|
||||
|
||||
interface Me {
|
||||
id: string;
|
||||
@@ -23,6 +24,7 @@ interface Me {
|
||||
}
|
||||
|
||||
export function Settings() {
|
||||
usePageTitle('Settings');
|
||||
const { data: me } = useQuery({ queryKey: ['me'], queryFn: () => get<Me>('/api/me') });
|
||||
|
||||
return (
|
||||
@@ -34,6 +36,7 @@ export function Settings() {
|
||||
<Appearance />
|
||||
<Profile me={me} />
|
||||
<ConnectAgent />
|
||||
<SessionCard />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -236,3 +239,47 @@ claude mcp add pig -- npx -y @pig/mcp`}</code>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signing out.
|
||||
*
|
||||
* There was no way to do this at all until now, which is an easy omission to
|
||||
* make when developing signed in and a genuinely stranded feeling for anyone
|
||||
* on a shared machine.
|
||||
*
|
||||
* Clearing the identity provider's session is enough: PIG holds no session of
|
||||
* its own, and the auth listener in App.tsx notices and returns to sign-in
|
||||
* without a reload.
|
||||
*/
|
||||
function SessionCard() {
|
||||
const [busy, setBusy] = useState(false);
|
||||
|
||||
async function signOut() {
|
||||
setBusy(true);
|
||||
try {
|
||||
await getSupabase()?.auth.signOut();
|
||||
} finally {
|
||||
// Belt and braces: if the provider call fails, a reload still lands on
|
||||
// the sign-in screen rather than leaving a half-signed-out interface.
|
||||
window.location.href = '/';
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">Session</CardTitle>
|
||||
<p className="text-sm text-muted">
|
||||
Signing out clears this browser only. API keys you have issued keep working —
|
||||
revoke those separately.
|
||||
</p>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Button variant="outline" onClick={signOut} disabled={busy}>
|
||||
<LogOut className="h-4 w-4" aria-hidden />
|
||||
{busy ? 'Signing out…' : 'Sign out'}
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user