Update stuff & add admin link in nav for admins

This commit is contained in:
2026-03-26 23:13:05 -05:00
parent de95908156
commit afd76786e5
5 changed files with 38 additions and 13 deletions

View File

@@ -4,7 +4,7 @@ import type { Metadata, Viewport } from 'next';
import NextError from 'next/error'; import NextError from 'next/error';
import { Geist, Geist_Mono } from 'next/font/google'; import { Geist, Geist_Mono } from 'next/font/google';
import '@/app/styles.css'; import '@/app/(frontend)/styles.css';
import { useEffect } from 'react'; import { useEffect } from 'react';
import Footer from '@/components/layout/footer'; import Footer from '@/components/layout/footer';

View File

@@ -1,17 +1,17 @@
import type { Metadata, Viewport } from 'next'; import type { Metadata, Viewport } from 'next';
import { Geist, Geist_Mono } from 'next/font/google'; import { Geist, Geist_Mono } from 'next/font/google';
import { env } from '@/env'; import { env } from '@/env';
import '@/app/(frontend)/styles.css'; import '@/app/(frontend)/styles.css';
import Footer from '@/components/layout/footer'; import Footer from '@/components/layout/footer';
import Header from '@/components/layout/header'; import Header from '@/components/layout/header';
import { ConvexClientProvider } from '@/components/providers'; import { ConvexClientProvider } from '@/components/providers';
import { generateMetadata } from '@/lib/metadata'; import { generateMetadata } from '@/lib/metadata';
import { ConvexAuthNextjsServerProvider } from '@convex-dev/auth/nextjs/server'; import { ConvexAuthNextjsServerProvider } from '@convex-dev/auth/nextjs/server';
import PlausibleProvider from 'next-plausible'; import PlausibleProvider from 'next-plausible';
import { ThemeProvider, Toaster } from '@gib/ui'; import { ThemeProvider, Toaster } from '@gib/ui';
import { preloadQuery } from 'convex/nextjs';
import { api } from '@gib/backend/convex/_generated/api.js';
export const metadata: Metadata = generateMetadata(); export const metadata: Metadata = generateMetadata();
@@ -31,11 +31,12 @@ const geistMono = Geist_Mono({
variable: '--font-geist-mono', variable: '--font-geist-mono',
}); });
const RootLayout = ({ const RootLayout = async ({
children, children,
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
}>) => { }>) => {
const preloadedUser = await preloadQuery(api.auth.getUser, {});
return ( return (
<ConvexAuthNextjsServerProvider> <ConvexAuthNextjsServerProvider>
<PlausibleProvider <PlausibleProvider
@@ -54,7 +55,9 @@ const RootLayout = ({
> >
<ConvexClientProvider> <ConvexClientProvider>
<div className='flex min-h-screen flex-col'> <div className='flex min-h-screen flex-col'>
<Header /> <Header
preloadedUser={preloadedUser}
/>
{children} {children}
<Footer /> <Footer />
</div> </div>

View File

@@ -58,7 +58,7 @@ export const defaultLandingPageContent: LandingPageContent = {
badgeEmoji: '🚀', badgeEmoji: '🚀',
badgeText: 'Production-ready monorepo template', badgeText: 'Production-ready monorepo template',
headingPrefix: 'Build Full-Stack Apps with', headingPrefix: 'Build Full-Stack Apps with',
headingHighlight: 'convex monorepo', headingHighlight: 'convex-monorepo',
description: description:
'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.', '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.',
primaryCta: { primaryCta: {

View File

@@ -1,17 +1,26 @@
'use client';
import type { ComponentProps } from 'react'; import type { ComponentProps } from 'react';
import { type Preloaded, usePreloadedQuery } from 'convex/react';
import { Kanit } from 'next/font/google'; import { Kanit } from 'next/font/google';
import Image from 'next/image'; import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import { Coffee, Server, Wrench } from 'lucide-react'; import { Coffee, Server, User, Wrench } from 'lucide-react';
import { Controls } from './controls'; import { Controls } from './controls';
import { api } from '@gib/backend/convex/_generated/api.js';
type HeaderProps = {
preloadedUser: Preloaded<typeof api.auth.getUser>;
headerProps?: ComponentProps<'header'>;
};
const kanitSans = Kanit({ const kanitSans = Kanit({
subsets: ['latin'], subsets: ['latin'],
weight: ['400', '500', '600', '700'], weight: ['400', '500', '600', '700'],
}); });
export default function Header(headerProps: ComponentProps<'header'>) { export default function Header({preloadedUser, headerProps}: HeaderProps) {
const user = usePreloadedQuery(preloadedUser);
return ( return (
<header <header
className='border-border/40 bg-background/95 supports-backdrop-filter:bg-background/60 sticky top-0 z-50 w-full border-b backdrop-blur' className='border-border/40 bg-background/95 supports-backdrop-filter:bg-background/60 sticky top-0 z-50 w-full border-b backdrop-blur'
@@ -31,14 +40,14 @@ export default function Header(headerProps: ComponentProps<'header'>) {
className='w-10 lg:w-15 invert dark:invert-0' className='w-10 lg:w-15 invert dark:invert-0'
/> />
<span <span
className={`font-extrabold hidden sm:inline sm:text-xl sm:mb-1 lg:mb-3 lg:text-5xl ${kanitSans.className}`} className={`font-extrabold hidden md:inline sm:text-lg sm:mb-1 lg:mb-3 lg:text-4xl xl:text-5xl ${kanitSans.className}`}
> >
convex monorepo convex-monorepo
</span> </span>
</Link> </Link>
{/* Navigation */} {/* Navigation */}
<nav className='hidden items-center gap-6 text-xs lg:text-base font-medium sm:flex'> <nav className='hidden items-center gap-4 md:gap-6 text-xs lg:text-base font-medium sm:flex'>
<Link <Link
href='/#features' href='/#features'
className='text-foreground/60 hover:text-foreground flex items-center gap-2 transition-colors' className='text-foreground/60 hover:text-foreground flex items-center gap-2 transition-colors'
@@ -62,6 +71,18 @@ export default function Header(headerProps: ComponentProps<'header'>) {
<Coffee width={20} height={20} /> <Coffee width={20} height={20} />
Repository Repository
</Link> </Link>
{user?.isAdmin && (
<Link
href='/admin'
target='_blank'
rel='noopener noreferrer'
className='text-foreground/60 hover:text-foreground
flex items-center gap-2 transition-colors'
>
<User width={18} height={18} />
Admin
</Link>
)}
</nav> </nav>
{/* Controls (Theme + Auth) */} {/* Controls (Theme + Auth) */}

View File

@@ -18,6 +18,7 @@ const applicationTables = {
phoneVerificationTime: v.optional(v.number()), phoneVerificationTime: v.optional(v.number()),
isAnonymous: v.optional(v.boolean()), isAnonymous: v.optional(v.boolean()),
/* Fields below here are custom & not defined in authTables */ /* Fields below here are custom & not defined in authTables */
isAdmin: v.optional(v.boolean()),
themePreference: v.optional( themePreference: v.optional(
v.union(v.literal('light'), v.literal('dark'), v.literal('system')), v.union(v.literal('light'), v.literal('dark'), v.literal('system')),
), ),