Add agent workflows & stuff
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { OpenAiStatusPanel } from '@/components/integrations/openai-status-panel';
|
||||
|
||||
const AiSettingsPage = () => (
|
||||
<section className='max-w-3xl space-y-4'>
|
||||
<div>
|
||||
<h2 className='text-xl font-semibold'>AI</h2>
|
||||
<p className='text-muted-foreground mt-1 text-sm'>
|
||||
Configure the OpenAI key, review model, and thinking level used for
|
||||
compatibility reviews.
|
||||
</p>
|
||||
</div>
|
||||
<OpenAiStatusPanel />
|
||||
</section>
|
||||
);
|
||||
|
||||
export default AiSettingsPage;
|
||||
@@ -0,0 +1,15 @@
|
||||
import { GithubIntegrationPanel } from '@/components/integrations/github-integration-panel';
|
||||
|
||||
const IntegrationsPage = () => (
|
||||
<section className='max-w-3xl space-y-4'>
|
||||
<div>
|
||||
<h2 className='text-xl font-semibold'>Integrations</h2>
|
||||
<p className='text-muted-foreground mt-1 text-sm'>
|
||||
Provider access used by Spoon maintenance workflows.
|
||||
</p>
|
||||
</div>
|
||||
<GithubIntegrationPanel />
|
||||
</section>
|
||||
);
|
||||
|
||||
export default IntegrationsPage;
|
||||
@@ -0,0 +1,54 @@
|
||||
'use client';
|
||||
|
||||
import type { ReactNode } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { Brain, Github, Shield, User } from 'lucide-react';
|
||||
|
||||
import { cn } from '@spoon/ui';
|
||||
|
||||
const settingsItems = [
|
||||
{ href: '/settings/profile', label: 'Profile', icon: User },
|
||||
{ href: '/settings/integrations', label: 'Integrations', icon: Github },
|
||||
{ href: '/settings/ai', label: 'AI', icon: Brain },
|
||||
{ href: '/settings/security', label: 'Security', icon: Shield },
|
||||
];
|
||||
|
||||
const SettingsLayout = ({ children }: { children: ReactNode }) => {
|
||||
const pathname = usePathname();
|
||||
return (
|
||||
<main className='space-y-6'>
|
||||
<div className='flex flex-col justify-between gap-4 border-b pb-5 lg:flex-row lg:items-end'>
|
||||
<div>
|
||||
<h1 className='text-3xl font-semibold tracking-normal'>Settings</h1>
|
||||
<p className='text-muted-foreground mt-2'>
|
||||
Account, provider, AI, and security controls for this Spoon
|
||||
workspace.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='grid gap-6 xl:grid-cols-[13rem_1fr]'>
|
||||
<nav className='border-border bg-card flex gap-1 overflow-x-auto border p-2 xl:flex-col xl:self-start'>
|
||||
{settingsItems.map(({ href, label, icon: Icon }) => (
|
||||
<Link
|
||||
key={href}
|
||||
href={href}
|
||||
className={cn(
|
||||
'hover:bg-muted flex min-w-fit items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors',
|
||||
pathname === href
|
||||
? 'bg-primary/10 text-primary'
|
||||
: 'text-muted-foreground hover:text-foreground',
|
||||
)}
|
||||
>
|
||||
<Icon className='size-4' />
|
||||
{label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
<div className='min-w-0'>{children}</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsLayout;
|
||||
@@ -0,0 +1,7 @@
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
const SettingsPage = () => {
|
||||
redirect('/settings/profile');
|
||||
};
|
||||
|
||||
export default SettingsPage;
|
||||
@@ -0,0 +1,42 @@
|
||||
'use server';
|
||||
|
||||
import {
|
||||
AvatarUpload,
|
||||
ProfileHeader,
|
||||
ResetPasswordForm,
|
||||
UserInfoForm,
|
||||
} from '@/components/layout/auth/profile';
|
||||
import { preloadQuery } from 'convex/nextjs';
|
||||
|
||||
import { api } from '@spoon/backend/convex/_generated/api.js';
|
||||
import { Card, Separator } from '@spoon/ui';
|
||||
|
||||
const SettingsProfilePage = async () => {
|
||||
const preloadedUser = await preloadQuery(api.auth.getUser, {});
|
||||
const preloadedUserProvider = await preloadQuery(
|
||||
api.auth.getUserProvider,
|
||||
{},
|
||||
);
|
||||
return (
|
||||
<section className='max-w-3xl space-y-4'>
|
||||
<div>
|
||||
<h2 className='text-xl font-semibold'>Profile</h2>
|
||||
<p className='text-muted-foreground mt-1 text-sm'>
|
||||
Manage your identity, avatar, and account email.
|
||||
</p>
|
||||
</div>
|
||||
<Card className='shadow-none'>
|
||||
<ProfileHeader />
|
||||
<AvatarUpload preloadedUser={preloadedUser} />
|
||||
<Separator className='my-6' />
|
||||
<UserInfoForm
|
||||
preloadedUser={preloadedUser}
|
||||
preloadedProvider={preloadedUserProvider}
|
||||
/>
|
||||
<ResetPasswordForm preloadedProvider={preloadedUserProvider} />
|
||||
</Card>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsProfilePage;
|
||||
@@ -0,0 +1,19 @@
|
||||
import { SignOutForm } from '@/components/layout/auth/profile';
|
||||
|
||||
import { Card } from '@spoon/ui';
|
||||
|
||||
const SecuritySettingsPage = () => (
|
||||
<section className='max-w-3xl space-y-4'>
|
||||
<div>
|
||||
<h2 className='text-xl font-semibold'>Security</h2>
|
||||
<p className='text-muted-foreground mt-1 text-sm'>
|
||||
Session controls and security-sensitive account actions.
|
||||
</p>
|
||||
</div>
|
||||
<Card className='shadow-none'>
|
||||
<SignOutForm />
|
||||
</Card>
|
||||
</section>
|
||||
);
|
||||
|
||||
export default SecuritySettingsPage;
|
||||
Reference in New Issue
Block a user