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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
import { createJiti } from 'jiti';
import { withSentryConfig } from '@sentry/nextjs';
import { createJiti } from 'jiti';
import { withPlausibleProxy } from 'next-plausible';
const jiti = createJiti(import.meta.url);

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,