├── .codeiumignore ├── .cursor └── rules │ ├── best-practices.mdc │ └── project-docs-rules.mdc ├── .cursorignore ├── .env.example ├── .eslintrc.json ├── .gitignore ├── .prettierrc ├── README.md ├── app ├── api │ └── webhooks │ │ └── route.ts ├── fonts │ ├── GeistMonoVF.woff │ └── GeistVF.woff ├── globals.css ├── icon.png ├── layout.tsx └── page.tsx ├── codeguide-backdrop.svg ├── components.json ├── components ├── providers │ ├── clerk-client-provider.tsx │ └── tanstack-client-provider.tsx └── ui │ ├── accordion.tsx │ ├── alert-dialog.tsx │ ├── alert.tsx │ ├── animated-hero.tsx │ ├── aspect-ratio.tsx │ ├── aurora-background.tsx │ ├── avatar.tsx │ ├── badge.tsx │ ├── breadcrumb.tsx │ ├── button.tsx │ ├── calendar.tsx │ ├── card.tsx │ ├── carousel.tsx │ ├── chart.tsx │ ├── checkbox.tsx │ ├── collapsible.tsx │ ├── command.tsx │ ├── context-menu.tsx │ ├── dialog.tsx │ ├── drawer.tsx │ ├── dropdown-menu.tsx │ ├── form.tsx │ ├── hover-card.tsx │ ├── input-otp.tsx │ ├── input.tsx │ ├── label.tsx │ ├── menubar.tsx │ ├── navigation-menu.tsx │ ├── pagination.tsx │ ├── popover.tsx │ ├── progress.tsx │ ├── radio-group.tsx │ ├── resizable.tsx │ ├── scroll-area.tsx │ ├── select.tsx │ ├── separator.tsx │ ├── sheet.tsx │ ├── sidebar.tsx │ ├── skeleton.tsx │ ├── slider.tsx │ ├── sonner.tsx │ ├── switch.tsx │ ├── table.tsx │ ├── tabs.tsx │ ├── textarea.tsx │ ├── toast.tsx │ ├── toaster.tsx │ ├── toggle-group.tsx │ ├── toggle.tsx │ └── tooltip.tsx ├── documentation └── starter_tech_stack_document.md ├── hooks ├── use-mobile.tsx └── use-toast.ts ├── lib └── utils.ts ├── middleware.ts ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.mjs ├── public └── codeguide-logo.png ├── supabase ├── .gitignore ├── config.toml └── migrations │ └── 20250125124435_init.sql ├── tailwind.config.ts ├── tsconfig.json ├── types └── database.types.ts └── utils ├── ai └── openai.ts ├── helpers.ts ├── stripe ├── client.ts ├── config.ts └── server.ts └── supabase ├── admin.ts ├── context.tsx └── server.ts /.codeiumignore: -------------------------------------------------------------------------------- 1 | implementation_plan.md -------------------------------------------------------------------------------- /.cursor/rules/best-practices.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Best practices to implement for the tech stack used 3 | globs: 4 | --- 5 | Next.js Best Practices: 6 | 7 | Utilize Next.js App Router for improved performance and easier routing 8 | Implement proper error boundaries to handle and display errors gracefully 9 | Use server components for better performance and reduced client-side JavaScript 10 | Leverage Next.js built-in image optimization for faster image loading 11 | Implement proper data fetching patterns using getServerSideProps or getStaticProps 12 | Use Next.js built-in internationalization features for multi-language support 13 | 14 | React Best Practices: 15 | 16 | Use functional components and hooks instead of class components for better code organization 17 | Implement proper React.memo and useMemo for performance optimization 18 | Follow the React hooks rules strictly to avoid common pitfalls 19 | Use context API or state management libraries for global state management 20 | Implement proper prop type validation using PropTypes or TypeScript 21 | Utilize React.lazy and Suspense for code-splitting and lazy loading components 22 | 23 | TypeScript Best Practices: 24 | 25 | Use TypeScript strict mode for better type safety and catching potential errors 26 | Follow proper type definitions and use interfaces or types consistently 27 | Implement comprehensive error handling using try-catch blocks and proper error types 28 | Utilize type inference where possible to reduce unnecessary type annotations 29 | Use utility types like Partial, Readonly, and Pick to create more flexible types 30 | Implement proper null and undefined checks to avoid runtime errors 31 | 32 | React Query Best Practices: 33 | 34 | Use React Query for efficient data fetching and caching 35 | Implement proper query keys to ensure correct cache invalidation 36 | Utilize query options like staleTime and cacheTime for optimal performance 37 | Implement proper error handling and loading states for a better user experience 38 | Use mutations for handling side effects and optimistic updates 39 | Leverage the useQueryClient hook for advanced cache management 40 | 41 | React Hook Form Best Practices: 42 | 43 | Use React Hook Form for efficient form handling and validation 44 | Implement proper form validation using the built-in validation methods 45 | Utilize the watch function for real-time form value monitoring 46 | Implement custom validation rules using the validate option 47 | Use the reset function to properly reset form state 48 | Leverage the useFormContext hook for nested form components 49 | 50 | Zod Best Practices: 51 | 52 | Use Zod for runtime type checking and validation 53 | Implement proper schema definitions for data validation 54 | Utilize Zod's built-in validation methods for common data types 55 | Implement custom validation rules using Zod's refine method 56 | Use Zod's infer utility to generate TypeScript types from schemas 57 | Leverage Zod's integration with React Hook Form for seamless form validation 58 | 59 | Tailwind CSS Best Practices: 60 | 61 | Use Tailwind CSS for efficient and consistent styling 62 | Implement proper responsive design using Tailwind's responsive utilities 63 | Utilize Tailwind's custom theme configuration for consistent branding 64 | Implement proper accessibility practices using Tailwind's accessibility utilities 65 | Use Tailwind's @apply directive for component-level styling 66 | Leverage Tailwind's JIT mode for faster build times and smaller CSS output 67 | 68 | Clerk Best Practices: 69 | 70 | Use Clerk for secure and scalable user authentication 71 | Implement proper user session management using Clerk's built-in features 72 | Utilize Clerk's user profile management for easy user data handling 73 | Implement proper error handling for authentication-related errors 74 | Use Clerk's built-in UI components for consistent authentication UX 75 | Leverage Clerk's organization feature for multi-tenant applications 76 | 77 | Supabase Best Practices: 78 | 79 | Use Supabase for efficient and scalable backend services 80 | Implement proper database schema design for optimal performance 81 | Utilize Supabase's real-time features for instant data updates 82 | Implement proper authentication and authorization using Supabase's built-in features 83 | Use Supabase's storage solution for efficient file handling 84 | Leverage Supabase's edge functions for serverless backend logic 85 | 86 | Stripe Best Practices: 87 | 88 | Use Stripe for secure and reliable payment processing 89 | Implement proper error handling for payment-related errors 90 | Utilize Stripe's webhooks for real-time payment event handling 91 | Implement proper PCI compliance measures when handling sensitive payment data 92 | Use Stripe's Elements for consistent and secure payment form UI 93 | Leverage Stripe's billing and subscription features for recurring payments 94 | 95 | OpenAI Best Practices: 96 | 97 | Use OpenAI's API for integrating AI-powered features 98 | Implement proper error handling for API requests 99 | Utilize rate limiting and caching to optimize API usage 100 | Implement proper data validation and sanitization for user inputs 101 | Use OpenAI's streaming feature for real-time AI responses 102 | Leverage OpenAI's fine-tuning capabilities for custom AI models -------------------------------------------------------------------------------- /.cursor/rules/project-docs-rules.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Project documentation rules 3 | globs: 4 | --- 5 | Always refer to @project_requirement_document.md for the project requirements and @app_flow_document.md for the flow of the app. Unless the user says otherwise or has defined new requirements or additional flow. -------------------------------------------------------------------------------- /.cursorignore: -------------------------------------------------------------------------------- 1 | implementation_plan.md -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Clerk Authentication 2 | NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxxx 3 | CLERK_SECRET_KEY=sk_test_xxxxxx 4 | 5 | # Supabase 6 | NEXT_PUBLIC_SUPABASE_URL=your_project_url 7 | NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key 8 | 9 | # Stripe (Optional) 10 | STRIPE_SECRET_KEY=sk_test_xxxxx 11 | NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx 12 | 13 | # OpenAI 14 | OPENAI_API_KEY=sk_test_xxxxx 15 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["next/core-web-vitals", "next/typescript"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "tabWidth": 2, 5 | "trailingComma": "es5", 6 | "printWidth": 100, 7 | "bracketSpacing": true, 8 | "arrowParens": "always", 9 | "endOfLine": "auto", 10 | "plugins": ["prettier-plugin-tailwindcss"] 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CodeGuide](/codeguide-backdrop.svg)](https://codeguide.dev) 2 | 3 | 4 | # CodeGuide Starter Pro 5 | 6 | A modern web application starter template built with Next.js 14, featuring authentication, database integration, and payment processing capabilities. 7 | 8 | ## Tech Stack 9 | 10 | - **Framework:** [Next.js 14](https://nextjs.org/) (App Router) 11 | - **Authentication:** [Clerk](https://clerk.com/) 12 | - **Database:** [Supabase](https://supabase.com/) 13 | - **Styling:** [Tailwind CSS](https://tailwindcss.com/) 14 | - **Payments:** [Stripe](https://stripe.com/) 15 | - **UI Components:** [shadcn/ui](https://ui.shadcn.com/) 16 | 17 | ## Prerequisites 18 | 19 | Before you begin, ensure you have the following: 20 | - Node.js 18+ installed 21 | - A [Clerk](https://clerk.com/) account for authentication 22 | - A [Supabase](https://supabase.com/) account for database 23 | - A [Stripe](https://stripe.com/) account for payments (optional) 24 | - Generated project documents from [CodeGuide](https://codeguide.dev/) for best development experience 25 | 26 | ## Getting Started 27 | 28 | 1. **Clone the repository** 29 | ```bash 30 | git clone 31 | cd codeguide-starter-pro 32 | ``` 33 | 34 | 2. **Install dependencies** 35 | ```bash 36 | npm install 37 | # or 38 | yarn install 39 | # or 40 | pnpm install 41 | ``` 42 | 43 | 3. **Environment Variables Setup** 44 | - Copy the `.env.example` file to `.env`: 45 | ```bash 46 | cp .env.example .env 47 | ``` 48 | - Fill in the environment variables in `.env` (see Configuration section below) 49 | 50 | 4. **Start the development server** 51 | ```bash 52 | npm run dev 53 | # or 54 | yarn dev 55 | # or 56 | pnpm dev 57 | ``` 58 | 59 | 5. **Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.** 60 | 61 | ## Configuration 62 | 63 | ### Clerk Setup 64 | 1. Go to [Clerk Dashboard](https://dashboard.clerk.com/) 65 | 2. Create a new application 66 | 3. Go to API Keys 67 | 4. Copy the `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` 68 | 69 | ### Supabase Setup 70 | 1. Go to [Supabase Dashboard](https://app.supabase.com/) 71 | 2. Create a new project 72 | 3. Go to Project Settings > API 73 | 4. Copy the `Project URL` as `NEXT_PUBLIC_SUPABASE_URL` 74 | 5. Copy the `anon` public key as `NEXT_PUBLIC_SUPABASE_ANON_KEY` 75 | 76 | ### Stripe Setup (Optional) 77 | 1. Go to [Stripe Dashboard](https://dashboard.stripe.com/) 78 | 2. Get your API keys from the Developers section 79 | 3. Add the required keys to your `.env` file 80 | 81 | ## Environment Variables 82 | 83 | Create a `.env` file in the root directory with the following variables: 84 | 85 | ```env 86 | # Clerk Authentication 87 | NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_publishable_key 88 | CLERK_SECRET_KEY=your_secret_key 89 | 90 | # Supabase 91 | NEXT_PUBLIC_SUPABASE_URL=your_supabase_url 92 | NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key 93 | 94 | # Stripe (Optional) 95 | STRIPE_SECRET_KEY=your_stripe_secret_key 96 | NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=your_stripe_publishable_key 97 | ``` 98 | 99 | ## Features 100 | 101 | - 🔐 Authentication with Clerk 102 | - 📦 Supabase Database 103 | - 💳 Stripe Payments Integration 104 | - 🎨 Modern UI with Tailwind CSS 105 | - 🚀 App Router Ready 106 | - 🔄 Real-time Updates 107 | - 📱 Responsive Design 108 | 109 | ## Project Structure 110 | 111 | ``` 112 | codeguide-starter/ 113 | ├── app/ # Next.js app router pages 114 | ├── components/ # React components 115 | ├── utils/ # Utility functions 116 | ├── public/ # Static assets 117 | ├── styles/ # Global styles 118 | ├── documentation/ # Generated documentation from CodeGuide 119 | └── supabase/ # Supabase configurations and migrations 120 | ``` 121 | 122 | ## Documentation Setup 123 | 124 | To implement the generated documentation from CodeGuide: 125 | 126 | 1. Create a `documentation` folder in the root directory: 127 | ```bash 128 | mkdir documentation 129 | ``` 130 | 131 | 2. Place all generated markdown files from CodeGuide in this directory: 132 | ```bash 133 | # Example structure 134 | documentation/ 135 | ├── project_requirements_document.md 136 | ├── app_flow_document.md 137 | ├── frontend_guideline_document.md 138 | └── backend_structure_document.md 139 | ``` 140 | 141 | 3. These documentation files will be automatically tracked by git and can be used as a reference for your project's features and implementation details. 142 | 143 | ## Contributing 144 | 145 | Contributions are welcome! Please feel free to submit a Pull Request. 146 | -------------------------------------------------------------------------------- /app/api/webhooks/route.ts: -------------------------------------------------------------------------------- 1 | import Stripe from 'stripe'; 2 | import { stripe } from '@/utils/stripe/config'; 3 | import { 4 | upsertProductRecord, 5 | upsertPriceRecord, 6 | manageSubscriptionStatusChange, 7 | deleteProductRecord, 8 | deletePriceRecord 9 | } from '@/utils/supabase/admin'; 10 | 11 | const relevantEvents = new Set([ 12 | 'product.created', 13 | 'product.updated', 14 | 'product.deleted', 15 | 'price.created', 16 | 'price.updated', 17 | 'price.deleted', 18 | 'checkout.session.completed', 19 | 'customer.subscription.created', 20 | 'customer.subscription.updated', 21 | 'customer.subscription.deleted' 22 | ]); 23 | 24 | export async function POST(req: Request) { 25 | const body = await req.text(); 26 | const sig = req.headers.get('stripe-signature') as string; 27 | const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; 28 | let event: Stripe.Event; 29 | 30 | try { 31 | if (!sig || !webhookSecret) 32 | return new Response('Webhook secret not found.', { status: 400 }); 33 | event = stripe.webhooks.constructEvent(body, sig, webhookSecret); 34 | console.log(`🔔 Webhook received: ${event.type}`); 35 | } catch (err: any) { 36 | console.log(`❌ Error message: ${err.message}`); 37 | return new Response(`Webhook Error: ${err.message}`, { status: 400 }); 38 | } 39 | 40 | if (relevantEvents.has(event.type)) { 41 | try { 42 | switch (event.type) { 43 | case 'product.created': 44 | case 'product.updated': 45 | await upsertProductRecord(event.data.object as Stripe.Product); 46 | break; 47 | case 'price.created': 48 | case 'price.updated': 49 | await upsertPriceRecord(event.data.object as Stripe.Price); 50 | break; 51 | case 'price.deleted': 52 | await deletePriceRecord(event.data.object as Stripe.Price); 53 | break; 54 | case 'product.deleted': 55 | await deleteProductRecord(event.data.object as Stripe.Product); 56 | break; 57 | case 'customer.subscription.created': 58 | case 'customer.subscription.updated': 59 | case 'customer.subscription.deleted': 60 | const subscription = event.data.object as Stripe.Subscription; 61 | await manageSubscriptionStatusChange( 62 | subscription.id, 63 | subscription.customer as string, 64 | event.type === 'customer.subscription.created' 65 | ); 66 | break; 67 | case 'checkout.session.completed': 68 | const checkoutSession = event.data.object as Stripe.Checkout.Session; 69 | if (checkoutSession.mode === 'subscription') { 70 | const subscriptionId = checkoutSession.subscription; 71 | await manageSubscriptionStatusChange( 72 | subscriptionId as string, 73 | checkoutSession.customer as string, 74 | true 75 | ); 76 | } 77 | break; 78 | default: 79 | console.log(`Unhandled event type ${event.type}`); 80 | } 81 | } catch (error) { 82 | console.log(error); 83 | return new Response( 84 | 'Webhook handler failed. View your Next.js function logs.', 85 | { 86 | status: 400 87 | } 88 | ); 89 | } 90 | } else { 91 | return new Response(`Unsupported event type: ${event.type}`); 92 | } 93 | return new Response(JSON.stringify({ received: true })); 94 | } 95 | -------------------------------------------------------------------------------- /app/fonts/GeistMonoVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGuide-dev/codeguide-starter-pro/7fcc7997d875e1d4656743ddb67bfe4d3dea1a70/app/fonts/GeistMonoVF.woff -------------------------------------------------------------------------------- /app/fonts/GeistVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGuide-dev/codeguide-starter-pro/7fcc7997d875e1d4656743ddb67bfe4d3dea1a70/app/fonts/GeistVF.woff -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Parkinsans:wght@300..800&display=swap'); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | 7 | .logo-text { 8 | font-family: Parkinsans, sans-serif; 9 | } 10 | 11 | @layer utilities { 12 | .text-balance { 13 | text-wrap: balance; 14 | } 15 | } 16 | 17 | @layer base { 18 | :root { 19 | --background: 0 0% 100%; 20 | --foreground: 240 10% 3.9%; 21 | --card: 0 0% 100%; 22 | --card-foreground: 240 10% 3.9%; 23 | --popover: 0 0% 100%; 24 | --popover-foreground: 240 10% 3.9%; 25 | --primary: 240 5.9% 10%; 26 | --primary-foreground: 0 0% 98%; 27 | --secondary: 240 4.8% 95.9%; 28 | --secondary-foreground: 240 5.9% 10%; 29 | --muted: 240 4.8% 95.9%; 30 | --muted-foreground: 240 3.8% 46.1%; 31 | --accent: 240 4.8% 95.9%; 32 | --accent-foreground: 240 5.9% 10%; 33 | --destructive: 0 84.2% 60.2%; 34 | --destructive-foreground: 0 0% 98%; 35 | --border: 240 5.9% 90%; 36 | --input: 240 5.9% 90%; 37 | --ring: 240 10% 3.9%; 38 | --chart-1: 12 76% 61%; 39 | --chart-2: 173 58% 39%; 40 | --chart-3: 197 37% 24%; 41 | --chart-4: 43 74% 66%; 42 | --chart-5: 27 87% 67%; 43 | --radius: 0.5rem; 44 | --sidebar-background: 0 0% 98%; 45 | --sidebar-foreground: 240 5.3% 26.1%; 46 | --sidebar-primary: 240 5.9% 10%; 47 | --sidebar-primary-foreground: 0 0% 98%; 48 | --sidebar-accent: 240 4.8% 95.9%; 49 | --sidebar-accent-foreground: 240 5.9% 10%; 50 | --sidebar-border: 220 13% 91%; 51 | --sidebar-ring: 217.2 91.2% 59.8%; 52 | } 53 | .dark { 54 | --background: 240 10% 3.9%; 55 | --foreground: 0 0% 98%; 56 | --card: 240 10% 3.9%; 57 | --card-foreground: 0 0% 98%; 58 | --popover: 240 10% 3.9%; 59 | --popover-foreground: 0 0% 98%; 60 | --primary: 0 0% 98%; 61 | --primary-foreground: 240 5.9% 10%; 62 | --secondary: 240 3.7% 15.9%; 63 | --secondary-foreground: 0 0% 98%; 64 | --muted: 240 3.7% 15.9%; 65 | --muted-foreground: 240 5% 64.9%; 66 | --accent: 240 3.7% 15.9%; 67 | --accent-foreground: 0 0% 98%; 68 | --destructive: 0 62.8% 30.6%; 69 | --destructive-foreground: 0 0% 98%; 70 | --border: 240 3.7% 15.9%; 71 | --input: 240 3.7% 15.9%; 72 | --ring: 240 4.9% 83.9%; 73 | --chart-1: 220 70% 50%; 74 | --chart-2: 160 60% 45%; 75 | --chart-3: 30 80% 55%; 76 | --chart-4: 280 65% 60%; 77 | --chart-5: 340 75% 55%; 78 | --sidebar-background: 240 5.9% 10%; 79 | --sidebar-foreground: 240 4.8% 95.9%; 80 | --sidebar-primary: 224.3 76.3% 48%; 81 | --sidebar-primary-foreground: 0 0% 100%; 82 | --sidebar-accent: 240 3.7% 15.9%; 83 | --sidebar-accent-foreground: 240 4.8% 95.9%; 84 | --sidebar-border: 240 3.7% 15.9%; 85 | --sidebar-ring: 217.2 91.2% 59.8%; 86 | } 87 | } 88 | 89 | @layer base { 90 | * { 91 | @apply border-border; 92 | } 93 | body { 94 | @apply bg-background text-foreground; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGuide-dev/codeguide-starter-pro/7fcc7997d875e1d4656743ddb67bfe4d3dea1a70/app/icon.png -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from 'next' 2 | import localFont from 'next/font/local' 3 | import './globals.css' 4 | import TanstackClientProvider from '@/components/providers/tanstack-client-provider' 5 | 6 | const geistSans = localFont({ 7 | src: './fonts/GeistVF.woff', 8 | variable: '--font-geist-sans', 9 | weight: '100 900', 10 | }) 11 | const geistMono = localFont({ 12 | src: './fonts/GeistMonoVF.woff', 13 | variable: '--font-geist-mono', 14 | weight: '100 900', 15 | }) 16 | 17 | export const metadata: Metadata = { 18 | title: 'CodeGuide Starter Pro', 19 | description: 'Starter kit from codeguide.dev', 20 | } 21 | 22 | export default function RootLayout({ 23 | children, 24 | }: Readonly<{ 25 | children: React.ReactNode 26 | }>) { 27 | return ( 28 | 29 | 30 | {children} 31 | 32 | 33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { Hero } from '@/components/ui/animated-hero' 4 | import Image from 'next/image' 5 | 6 | export default function Home() { 7 | return 8 | } 9 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "zinc", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /components/providers/clerk-client-provider.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { ClerkProvider } from '@clerk/nextjs' 4 | import { useTheme } from 'next-themes' 5 | import { dark } from '@clerk/themes' 6 | 7 | export default function ClerkClientProvider({ children }: { children: React.ReactNode }) { 8 | const { resolvedTheme } = useTheme() 9 | return ( 10 | 15 | {children} 16 | 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /components/providers/tanstack-client-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query' 4 | 5 | const queryClient = new QueryClient() 6 | 7 | export default function TanstackClientProvider({ children }: { children: React.ReactNode }) { 8 | return {children} 9 | } 10 | -------------------------------------------------------------------------------- /components/ui/accordion.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as AccordionPrimitive from "@radix-ui/react-accordion" 5 | import { ChevronDown } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const Accordion = AccordionPrimitive.Root 10 | 11 | const AccordionItem = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef 14 | >(({ className, ...props }, ref) => ( 15 | 20 | )) 21 | AccordionItem.displayName = "AccordionItem" 22 | 23 | const AccordionTrigger = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, children, ...props }, ref) => ( 27 | 28 | svg]:rotate-180", 32 | className 33 | )} 34 | {...props} 35 | > 36 | {children} 37 | 38 | 39 | 40 | )) 41 | AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName 42 | 43 | const AccordionContent = React.forwardRef< 44 | React.ElementRef, 45 | React.ComponentPropsWithoutRef 46 | >(({ className, children, ...props }, ref) => ( 47 | 52 |
{children}
53 |
54 | )) 55 | 56 | AccordionContent.displayName = AccordionPrimitive.Content.displayName 57 | 58 | export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } 59 | -------------------------------------------------------------------------------- /components/ui/alert-dialog.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" 5 | 6 | import { cn } from "@/lib/utils" 7 | import { buttonVariants } from "@/components/ui/button" 8 | 9 | const AlertDialog = AlertDialogPrimitive.Root 10 | 11 | const AlertDialogTrigger = AlertDialogPrimitive.Trigger 12 | 13 | const AlertDialogPortal = AlertDialogPrimitive.Portal 14 | 15 | const AlertDialogOverlay = React.forwardRef< 16 | React.ElementRef, 17 | React.ComponentPropsWithoutRef 18 | >(({ className, ...props }, ref) => ( 19 | 27 | )) 28 | AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName 29 | 30 | const AlertDialogContent = React.forwardRef< 31 | React.ElementRef, 32 | React.ComponentPropsWithoutRef 33 | >(({ className, ...props }, ref) => ( 34 | 35 | 36 | 44 | 45 | )) 46 | AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName 47 | 48 | const AlertDialogHeader = ({ 49 | className, 50 | ...props 51 | }: React.HTMLAttributes) => ( 52 |
59 | ) 60 | AlertDialogHeader.displayName = "AlertDialogHeader" 61 | 62 | const AlertDialogFooter = ({ 63 | className, 64 | ...props 65 | }: React.HTMLAttributes) => ( 66 |
73 | ) 74 | AlertDialogFooter.displayName = "AlertDialogFooter" 75 | 76 | const AlertDialogTitle = React.forwardRef< 77 | React.ElementRef, 78 | React.ComponentPropsWithoutRef 79 | >(({ className, ...props }, ref) => ( 80 | 85 | )) 86 | AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName 87 | 88 | const AlertDialogDescription = React.forwardRef< 89 | React.ElementRef, 90 | React.ComponentPropsWithoutRef 91 | >(({ className, ...props }, ref) => ( 92 | 97 | )) 98 | AlertDialogDescription.displayName = 99 | AlertDialogPrimitive.Description.displayName 100 | 101 | const AlertDialogAction = React.forwardRef< 102 | React.ElementRef, 103 | React.ComponentPropsWithoutRef 104 | >(({ className, ...props }, ref) => ( 105 | 110 | )) 111 | AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName 112 | 113 | const AlertDialogCancel = React.forwardRef< 114 | React.ElementRef, 115 | React.ComponentPropsWithoutRef 116 | >(({ className, ...props }, ref) => ( 117 | 126 | )) 127 | AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName 128 | 129 | export { 130 | AlertDialog, 131 | AlertDialogPortal, 132 | AlertDialogOverlay, 133 | AlertDialogTrigger, 134 | AlertDialogContent, 135 | AlertDialogHeader, 136 | AlertDialogFooter, 137 | AlertDialogTitle, 138 | AlertDialogDescription, 139 | AlertDialogAction, 140 | AlertDialogCancel, 141 | } 142 | -------------------------------------------------------------------------------- /components/ui/alert.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva, type VariantProps } from "class-variance-authority" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const alertVariants = cva( 7 | "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", 8 | { 9 | variants: { 10 | variant: { 11 | default: "bg-background text-foreground", 12 | destructive: 13 | "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", 14 | }, 15 | }, 16 | defaultVariants: { 17 | variant: "default", 18 | }, 19 | } 20 | ) 21 | 22 | const Alert = React.forwardRef< 23 | HTMLDivElement, 24 | React.HTMLAttributes & VariantProps 25 | >(({ className, variant, ...props }, ref) => ( 26 |
32 | )) 33 | Alert.displayName = "Alert" 34 | 35 | const AlertTitle = React.forwardRef< 36 | HTMLParagraphElement, 37 | React.HTMLAttributes 38 | >(({ className, ...props }, ref) => ( 39 |
44 | )) 45 | AlertTitle.displayName = "AlertTitle" 46 | 47 | const AlertDescription = React.forwardRef< 48 | HTMLParagraphElement, 49 | React.HTMLAttributes 50 | >(({ className, ...props }, ref) => ( 51 |
56 | )) 57 | AlertDescription.displayName = "AlertDescription" 58 | 59 | export { Alert, AlertTitle, AlertDescription } 60 | -------------------------------------------------------------------------------- /components/ui/animated-hero.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useMemo, useState } from 'react' 2 | import { motion } from 'framer-motion' 3 | import { MoveRight, PhoneCall } from 'lucide-react' 4 | import { Button } from '@/components/ui/button' 5 | import Image from 'next/image' 6 | 7 | function Hero() { 8 | const [titleNumber, setTitleNumber] = useState(0) 9 | const titles = useMemo(() => ['Modern', 'Full-stack', 'Secure', 'Scalable', 'Powerful'], []) 10 | 11 | useEffect(() => { 12 | const timeoutId = setTimeout(() => { 13 | if (titleNumber === titles.length - 1) { 14 | setTitleNumber(0) 15 | } else { 16 | setTitleNumber(titleNumber + 1) 17 | } 18 | }, 2000) 19 | return () => clearTimeout(timeoutId) 20 | }, [titleNumber, titles]) 21 | 22 | return ( 23 |
24 |
25 |
26 | 37 |
38 |

39 | 40 |   41 | {titles.map((title, index) => ( 42 | index ? -150 : 150, 55 | opacity: 0, 56 | } 57 | } 58 | > 59 | {title} 60 | 61 | ))} 62 | 63 | Starter Kit 64 |

65 | 66 |

67 | Start building with a modern web application template featuring authentication, 68 | database integration, and payment processing. Built with Next.js 14, Clerk, Supabase, 69 | and Stripe to accelerate your development process. 70 |

71 |
72 |
73 | 76 |
77 |
78 |
79 |
80 | ) 81 | } 82 | 83 | export { Hero } 84 | -------------------------------------------------------------------------------- /components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 4 | 5 | const AspectRatio = AspectRatioPrimitive.Root 6 | 7 | export { AspectRatio } 8 | -------------------------------------------------------------------------------- /components/ui/aurora-background.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { cn } from "@/lib/utils"; 3 | import React, { ReactNode } from "react"; 4 | 5 | interface AuroraBackgroundProps extends React.HTMLProps { 6 | children: ReactNode; 7 | showRadialGradient?: boolean; 8 | } 9 | 10 | export const AuroraBackground = ({ 11 | className, 12 | children, 13 | showRadialGradient = true, 14 | ...props 15 | }: AuroraBackgroundProps) => { 16 | return ( 17 |
18 |
25 |
26 |
49 |
50 | {children} 51 |
52 |
53 | ); 54 | }; 55 | -------------------------------------------------------------------------------- /components/ui/avatar.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as AvatarPrimitive from "@radix-ui/react-avatar" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Avatar = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | )) 21 | Avatar.displayName = AvatarPrimitive.Root.displayName 22 | 23 | const AvatarImage = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => ( 27 | 32 | )) 33 | AvatarImage.displayName = AvatarPrimitive.Image.displayName 34 | 35 | const AvatarFallback = React.forwardRef< 36 | React.ElementRef, 37 | React.ComponentPropsWithoutRef 38 | >(({ className, ...props }, ref) => ( 39 | 47 | )) 48 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName 49 | 50 | export { Avatar, AvatarImage, AvatarFallback } 51 | -------------------------------------------------------------------------------- /components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva, type VariantProps } from "class-variance-authority" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const badgeVariants = cva( 7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", 8 | { 9 | variants: { 10 | variant: { 11 | default: 12 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", 13 | secondary: 14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", 15 | destructive: 16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", 17 | outline: "text-foreground", 18 | }, 19 | }, 20 | defaultVariants: { 21 | variant: "default", 22 | }, 23 | } 24 | ) 25 | 26 | export interface BadgeProps 27 | extends React.HTMLAttributes, 28 | VariantProps {} 29 | 30 | function Badge({ className, variant, ...props }: BadgeProps) { 31 | return ( 32 |
33 | ) 34 | } 35 | 36 | export { Badge, badgeVariants } 37 | -------------------------------------------------------------------------------- /components/ui/breadcrumb.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { ChevronRight, MoreHorizontal } from "lucide-react" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const Breadcrumb = React.forwardRef< 8 | HTMLElement, 9 | React.ComponentPropsWithoutRef<"nav"> & { 10 | separator?: React.ReactNode 11 | } 12 | >(({ ...props }, ref) =>