Update AGENTS.md. Start fixing old weird errors

This commit is contained in:
2026-03-26 12:05:12 -05:00
parent 0bc04dbf6b
commit d16f4287ce
96 changed files with 18195 additions and 9182 deletions

View File

@@ -252,27 +252,27 @@ const SignIn = () => {
<Tabs
defaultValue={flow}
onValueChange={(value) => setFlow(value as 'signIn' | 'signUp')}
className='items-center flex-col'
className='flex-col items-center'
>
<TabsList>
<TabsTrigger
value='signIn'
className='cursor-pointer py-2 px-6 text-2xl font-bold'
className='cursor-pointer px-6 py-2 text-2xl font-bold'
>
Sign In
</TabsTrigger>
<TabsTrigger
value='signUp'
className='cursor-pointer py-2 px-6 text-2xl font-bold'
className='cursor-pointer px-6 py-2 text-2xl font-bold'
>
Sign Up
</TabsTrigger>
</TabsList>
<TabsContent
value='signIn'
className='min-h-[560px] items-center flex flex-row'
className='flex min-h-[560px] flex-row items-center'
>
<Card className='bg-card/50 min-w-xs sm:min-w-sm py-10'>
<Card className='bg-card/50 min-w-xs py-10 sm:min-w-sm'>
<CardContent>
<Form {...signInForm}>
<form

View File

@@ -10,12 +10,12 @@ import { useEffect } from 'react';
import Footer from '@/components/layout/footer';
import Header from '@/components/layout/header';
import { ConvexClientProvider } from '@/components/providers';
import { env } from '@/env';
import { generateMetadata } from '@/lib/metadata';
import * as Sentry from '@sentry/nextjs';
import PlausibleProvider from 'next-plausible';
import { Button, ThemeProvider, Toaster } from '@gib/ui';
import { env } from '@/env';
export const metadata: Metadata = generateMetadata();

View File

@@ -1,33 +1,31 @@
export function CTA() {
return (
<section className='container mx-auto px-4 py-24'>
<div className='mx-auto max-w-4xl'>
<div className='border-border/40 from-muted/50 to-muted/30 rounded-2xl border bg-linear-to-br p-8 text-center md:p-12'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Ready to Build Something Amazing?
</h2>
<p className='text-muted-foreground mb-8 text-lg'>
Clone the repository and start building your next project with
everything pre-configured.
</p>
export const CTA = () => (
<section className='container mx-auto px-4 py-24'>
<div className='mx-auto max-w-4xl'>
<div className='border-border/40 from-muted/50 to-muted/30 rounded-2xl border bg-linear-to-br p-8 text-center md:p-12'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl'>
Ready to Build Something Amazing?
</h2>
<p className='text-muted-foreground mb-8 text-lg'>
Clone the repository and start building your next project with
everything pre-configured.
</p>
{/* Quick Start Command */}
<div className='mt-12'>
<p className='text-muted-foreground mb-3 text-sm font-medium'>
Quick Start
</p>
<div className='border-border/40 bg-background mx-auto max-w-2xl rounded-lg border p-4'>
<code className='text-sm'>
git clone https://git.gbrown.org/gib/convex-monorepo.git
<br />
cd convex-monorepo
<br />
bun i
</code>
</div>
{/* Quick Start Command */}
<div className='mt-12'>
<p className='text-muted-foreground mb-3 text-sm font-medium'>
Quick Start
</p>
<div className='border-border/40 bg-background mx-auto max-w-2xl rounded-lg border p-4'>
<code className='text-sm'>
git clone https://git.gbrown.org/gib/convex-monorepo.git
<br />
cd convex-monorepo
<br />
bun i
</code>
</div>
</div>
</div>
</section>
);
}
</div>
</section>
);

View File

@@ -57,36 +57,34 @@ const features = [
},
];
export function Features() {
return (
<section id='features' className='container mx-auto px-4 py-24'>
<div className='mx-auto max-w-6xl'>
{/* Section Header */}
<div className='mb-16 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl'>
Everything You Need to Ship Fast
</h2>
<p className='text-muted-foreground mx-auto max-w-2xl text-lg'>
A complete monorepo template with all the tools and patterns you
need for production-ready applications.
</p>
</div>
{/* Features Grid */}
<div className='grid gap-6 md:grid-cols-2 lg:grid-cols-3'>
{features.map((feature) => (
<Card key={feature.title} className='border-border/40'>
<CardHeader className='flex items-center gap-2'>
<div className='mb-2 text-3xl'>{feature.icon}</div>
<CardTitle className='text-xl'>{feature.title}</CardTitle>
</CardHeader>
<CardContent>
<p className='text-muted-foreground'>{feature.description}</p>
</CardContent>
</Card>
))}
</div>
export const Features = () => (
<section id='features' className='container mx-auto px-4 py-24'>
<div className='mx-auto max-w-6xl'>
{/* Section Header */}
<div className='mb-16 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl'>
Everything You Need to Ship Fast
</h2>
<p className='text-muted-foreground mx-auto max-w-2xl text-lg'>
A complete monorepo template with all the tools and patterns you need
for production-ready applications.
</p>
</div>
</section>
);
}
{/* Features Grid */}
<div className='grid gap-6 md:grid-cols-2 lg:grid-cols-3'>
{features.map((feature) => (
<Card key={feature.title} className='border-border/40'>
<CardHeader className='flex items-center gap-2'>
<div className='mb-2 text-3xl'>{feature.icon}</div>
<CardTitle className='text-xl'>{feature.title}</CardTitle>
</CardHeader>
<CardContent>
<p className='text-muted-foreground'>{feature.description}</p>
</CardContent>
</Card>
))}
</div>
</div>
</section>
);

View File

@@ -9,120 +9,118 @@ const kanitSans = Kanit({
weight: ['400', '500', '600', '700'],
});
export function Hero() {
return (
<section className='container mx-auto px-4 py-24 md:py-32 lg:py-40'>
<div className='mx-auto flex max-w-5xl flex-col items-center gap-8 text-center'>
{/* Badge */}
<div className='border-border/40 bg-muted/50 inline-flex items-center rounded-full border px-3 py-1 text-sm font-medium'>
<span className='mr-2'>🚀</span>
<span>Production-ready monorepo template</span>
</div>
export const Hero = () => (
<section className='container mx-auto px-4 py-24 md:py-32 lg:py-40'>
<div className='mx-auto flex max-w-5xl flex-col items-center gap-8 text-center'>
{/* Badge */}
<div className='border-border/40 bg-muted/50 inline-flex items-center rounded-full border px-3 py-1 text-sm font-medium'>
<span className='mr-2'>🚀</span>
<span>Production-ready monorepo template</span>
</div>
{/* Heading */}
<h1 className='from-foreground to-foreground/70 bg-linear-to-br bg-clip-text text-4xl font-bold tracking-tight text-transparent sm:text-5xl md:text-6xl lg:text-7xl'>
Build Full-Stack Apps with{' '}
<span
className={`${kanitSans.className} to-accent-foreground bg-linear-to-r from-[#281A65] via-[#363354] bg-clip-text text-transparent sm:text-6xl lg:text-7xl xl:text-8xl dark:from-[#bec8e6] dark:via-[#F0EEE4] dark:to-[#FFF8E7]`}
{/* Heading */}
<h1 className='from-foreground to-foreground/70 bg-linear-to-br bg-clip-text text-4xl font-bold tracking-tight text-transparent sm:text-5xl md:text-6xl lg:text-7xl'>
Build Full-Stack Apps with{' '}
<span
className={`${kanitSans.className} to-accent-foreground bg-linear-to-r from-[#281A65] via-[#363354] bg-clip-text text-transparent sm:text-6xl lg:text-7xl xl:text-8xl dark:from-[#bec8e6] dark:via-[#F0EEE4] dark:to-[#FFF8E7]`}
>
convex monorepo
</span>
</h1>
{/* Description */}
<p className='text-muted-foreground max-w-2xl text-lg md:text-xl'>
A Turborepo starter with Next.js, Expo, and self-hosted Convex. Ship web
and mobile apps faster with shared code, type-safe backend, and complete
control over your infrastructure.
</p>
{/* CTA Buttons */}
<div className='flex flex-col gap-3 sm:flex-row'>
<Button size='lg' variant='outline' asChild>
<Link
href='https://git.gbrown.org/gib/convex-monorepo'
target='_blank'
rel='noopener noreferrer'
>
convex monorepo
</span>
</h1>
<Image
src='/misc/gitea/gitea.svg'
alt='Gitea'
width={20}
height={20}
/>
View Source Code
</Link>
</Button>
</div>
{/* Description */}
<p className='text-muted-foreground max-w-2xl text-lg md:text-xl'>
A Turborepo starter with Next.js, Expo, and self-hosted Convex. Ship
web and mobile apps faster with shared code, type-safe backend, and
complete control over your infrastructure.
</p>
{/* CTA Buttons */}
<div className='flex flex-col gap-3 sm:flex-row'>
<Button size='lg' variant='outline' asChild>
<Link
href='https://git.gbrown.org/gib/convex-monorepo'
target='_blank'
rel='noopener noreferrer'
>
<Image
src='/misc/gitea/gitea.svg'
alt='Gitea'
width={20}
height={20}
/>
View Source Code
</Link>
</Button>
{/* Features Quick List */}
<div className='text-muted-foreground mt-8 flex flex-wrap items-center justify-center gap-6 text-sm'>
<div className='flex items-center gap-2'>
<svg
className='h-5 w-5 text-green-500'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M5 13l4 4L19 7'
/>
</svg>
<span>TypeScript</span>
</div>
{/* Features Quick List */}
<div className='text-muted-foreground mt-8 flex flex-wrap items-center justify-center gap-6 text-sm'>
<div className='flex items-center gap-2'>
<svg
className='h-5 w-5 text-green-500'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M5 13l4 4L19 7'
/>
</svg>
<span>TypeScript</span>
</div>
<div className='flex items-center gap-2'>
<svg
className='h-5 w-5 text-green-500'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M5 13l4 4L19 7'
/>
</svg>
<span>Self-Hosted</span>
</div>
<div className='flex items-center gap-2'>
<svg
className='h-5 w-5 text-green-500'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M5 13l4 4L19 7'
/>
</svg>
<span>Real-time</span>
</div>
<div className='flex items-center gap-2'>
<svg
className='h-5 w-5 text-green-500'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M5 13l4 4L19 7'
/>
</svg>
<span>Auth Included</span>
</div>
<div className='flex items-center gap-2'>
<svg
className='h-5 w-5 text-green-500'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M5 13l4 4L19 7'
/>
</svg>
<span>Self-Hosted</span>
</div>
<div className='flex items-center gap-2'>
<svg
className='h-5 w-5 text-green-500'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M5 13l4 4L19 7'
/>
</svg>
<span>Real-time</span>
</div>
<div className='flex items-center gap-2'>
<svg
className='h-5 w-5 text-green-500'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M5 13l4 4L19 7'
/>
</svg>
<span>Auth Included</span>
</div>
</div>
</section>
);
}
</div>
</section>
);

View File

@@ -36,44 +36,42 @@ const techStack = [
},
];
export function TechStack() {
return (
<section id='tech-stack' className='border-border/40 bg-muted/30 border-t'>
<div className='container mx-auto px-4 py-24'>
<div className='mx-auto max-w-6xl'>
{/* Section Header */}
<div className='mb-16 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl'>
Modern Tech Stack
</h2>
<p className='text-muted-foreground mx-auto max-w-2xl text-lg'>
Built with the latest and greatest tools for maximum productivity
and performance.
</p>
</div>
export const TechStack = () => (
<section id='tech-stack' className='border-border/40 bg-muted/30 border-t'>
<div className='container mx-auto px-4 py-24'>
<div className='mx-auto max-w-6xl'>
{/* Section Header */}
<div className='mb-16 text-center'>
<h2 className='mb-4 text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl'>
Modern Tech Stack
</h2>
<p className='text-muted-foreground mx-auto max-w-2xl text-lg'>
Built with the latest and greatest tools for maximum productivity
and performance.
</p>
</div>
{/* Tech Stack Grid */}
<div className='grid gap-12 md:grid-cols-3'>
{techStack.map((stack) => (
<div key={stack.category}>
<h3 className='mb-6 text-xl font-semibold'>{stack.category}</h3>
<ul className='space-y-4'>
{stack.technologies.map((tech) => (
<li key={tech.name}>
<div className='text-foreground font-medium'>
{tech.name}
</div>
<div className='text-muted-foreground text-sm'>
{tech.description}
</div>
</li>
))}
</ul>
</div>
))}
</div>
{/* Tech Stack Grid */}
<div className='grid gap-12 md:grid-cols-3'>
{techStack.map((stack) => (
<div key={stack.category}>
<h3 className='mb-6 text-xl font-semibold'>{stack.category}</h3>
<ul className='space-y-4'>
{stack.technologies.map((tech) => (
<li key={tech.name}>
<div className='text-foreground font-medium'>
{tech.name}
</div>
<div className='text-muted-foreground text-sm'>
{tech.description}
</div>
</li>
))}
</ul>
</div>
))}
</div>
</div>
</section>
);
}
</div>
</section>
);

View File

@@ -1,4 +1,5 @@
'use client';
import { CardDescription, CardHeader, CardTitle } from '@gib/ui';
const ProfileHeader = () => {

View File

@@ -53,7 +53,7 @@ export const UserInfoForm = ({
const userProvider = usePreloadedQuery(preloadedProvider);
const providerMap: Record<string, string> = {
unknown: 'Provider',
authentik: 'Gib\'s Auth',
authentik: "Gib's Auth",
};
const [loading, setLoading] = useState(false);
@@ -150,7 +150,8 @@ export const UserInfoForm = ({
</FormDescription>
) : (
<FormDescription>
Email is managed through your {providerMap[userProvider ?? 'unknown']} account
Email is managed through your{' '}
{providerMap[userProvider ?? 'unknown']} account
</FormDescription>
)}
<FormMessage />

View File

@@ -28,7 +28,7 @@ export default function Header(headerProps: ComponentProps<'header'>) {
alt='Convex Monorepo'
width={50}
height={50}
className='invert dark:invert-0 w-15'
className='w-15 invert dark:invert-0'
/>
<span
className={`mb-3 hidden font-extrabold lg:inline lg:text-5xl ${kanitSans.className}`}

View File

@@ -7,10 +7,8 @@ import { ConvexReactClient } from 'convex/react';
const convex = new ConvexReactClient(env.NEXT_PUBLIC_CONVEX_URL);
export function ConvexClientProvider({ children }: { children: ReactNode }) {
return (
<ConvexAuthNextjsProvider client={convex}>
{children}
</ConvexAuthNextjsProvider>
);
}
export const ConvexClientProvider = ({ children }: { children: ReactNode }) => (
<ConvexAuthNextjsProvider client={convex}>
{children}
</ConvexAuthNextjsProvider>
);

View File

@@ -38,7 +38,8 @@ export const env = createEnv({
NEXT_PUBLIC_SENTRY_DSN: process.env.NEXT_PUBLIC_SENTRY_DSN,
NEXT_PUBLIC_SENTRY_URL: process.env.NEXT_PUBLIC_SENTRY_URL,
NEXT_PUBLIC_SENTRY_ORG: process.env.NEXT_PUBLIC_SENTRY_ORG,
NEXT_PUBLIC_SENTRY_PROJECT_NAME: process.env.NEXT_PUBLIC_SENTRY_PROJECT_NAME,
NEXT_PUBLIC_SENTRY_PROJECT_NAME:
process.env.NEXT_PUBLIC_SENTRY_PROJECT_NAME,
},
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
emptyStringAsUndefined: true,

View File

@@ -1,6 +1,6 @@
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from '@sentry/nextjs';
import { env } from '@/env';
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_DSN,

View File

@@ -1,5 +1,5 @@
import * as Sentry from '@sentry/nextjs';
import { env } from '@/env';
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: env.NEXT_PUBLIC_SENTRY_DSN,