Starter Prompt Assistance
This commit is contained in:
42
docs/business/starter-prompt.md
Normal file
42
docs/business/starter-prompt.md
Normal file
@@ -0,0 +1,42 @@
|
||||
I'm working with a Next.js boilerplate project that includes authentication, database integration, and AI capabilities. Here's what's already set up:
|
||||
|
||||
## Current Boilerplate Structure
|
||||
|
||||
- **Authentication**: Better Auth with Google OAuth integration
|
||||
- **Database**: Drizzle ORM with PostgreSQL setup
|
||||
- **AI Integration**: Vercel AI SDK with OpenAI integration
|
||||
- **UI**: shadcn/ui components with Tailwind CSS
|
||||
- **Current Routes**:
|
||||
- `/` - Home page with setup instructions and feature overview
|
||||
- `/dashboard` - Protected dashboard page (requires authentication)
|
||||
- `/chat` - AI chat interface (requires OpenAI API key)
|
||||
|
||||
## Important Context
|
||||
|
||||
This is a **boilerplate/starter template** - all existing pages and components are meant to be examples and should be **replaced or heavily modified** to build the actual application. Don't hesitate to:
|
||||
|
||||
- Override existing pages completely
|
||||
- Modify or replace components
|
||||
- Change the routing structure
|
||||
- Update the database schema as needed
|
||||
- Customize the authentication flow
|
||||
- Adapt the AI integration for specific use cases
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- Next.js 15 with App Router
|
||||
- TypeScript
|
||||
- Tailwind CSS
|
||||
- Better Auth for authentication
|
||||
- Drizzle ORM + PostgreSQL
|
||||
- Vercel AI SDK
|
||||
- shadcn/ui components
|
||||
- Lucide React icons
|
||||
|
||||
## What I Want to Build
|
||||
|
||||
Basic todo list app with the ability for users to add, remove, update, complete and view todos.
|
||||
|
||||
## Request
|
||||
|
||||
Please help me transform this boilerplate into my actual application. Feel free to modify, replace, or completely rewrite any existing code to match my project requirements. The current implementation is just a starting point - treat it as scaffolding that can be changed as needed.
|
||||
@@ -16,6 +16,7 @@
|
||||
"@ai-sdk/openai": "^2.0.9",
|
||||
"@ai-sdk/react": "^2.0.9",
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-dialog": "^1.1.14",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"ai": "^5.0.9",
|
||||
"better-auth": "^1.3.4",
|
||||
|
||||
997
pnpm-lock.yaml
generated
997
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@ import Link from "next/link";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { SetupChecklist } from "@/components/setup-checklist";
|
||||
import { useDiagnostics } from "@/hooks/use-diagnostics";
|
||||
import { StarterPromptModal } from "@/components/starter-prompt-modal";
|
||||
|
||||
export default function Home() {
|
||||
const { isAuthReady, isAiReady, loading } = useDiagnostics();
|
||||
@@ -120,10 +121,11 @@ export default function Home() {
|
||||
</div>
|
||||
<div className="p-4 border rounded-lg">
|
||||
<h4 className="font-medium mb-2">4. Start building</h4>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
<p className="text-sm text-muted-foreground mb-3">
|
||||
Customize the components, add your own pages, and build your
|
||||
application on top of this solid foundation.
|
||||
</p>
|
||||
<StarterPromptModal />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
141
src/components/starter-prompt-modal.tsx
Normal file
141
src/components/starter-prompt-modal.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Copy, Check } from "lucide-react";
|
||||
|
||||
const STARTER_PROMPT = `I'm working with a Next.js boilerplate project that includes authentication, database integration, and AI capabilities. Here's what's already set up:
|
||||
|
||||
## Current Boilerplate Structure
|
||||
- **Authentication**: Better Auth with Google OAuth integration
|
||||
- **Database**: Drizzle ORM with PostgreSQL setup
|
||||
- **AI Integration**: Vercel AI SDK with OpenAI integration
|
||||
- **UI**: shadcn/ui components with Tailwind CSS
|
||||
- **Current Routes**:
|
||||
- \`/\` - Home page with setup instructions and feature overview
|
||||
- \`/dashboard\` - Protected dashboard page (requires authentication)
|
||||
- \`/chat\` - AI chat interface (requires OpenAI API key)
|
||||
|
||||
## Important Context
|
||||
This is a **boilerplate/starter template** - all existing pages and components are meant to be examples and should be **replaced or heavily modified** to build the actual application. Don't hesitate to:
|
||||
|
||||
- Override existing pages completely
|
||||
- Modify or replace components
|
||||
- Change the routing structure
|
||||
- Update the database schema as needed
|
||||
- Customize the authentication flow
|
||||
- Adapt the AI integration for specific use cases
|
||||
|
||||
## Tech Stack
|
||||
- Next.js 15 with App Router
|
||||
- TypeScript
|
||||
- Tailwind CSS
|
||||
- Better Auth for authentication
|
||||
- Drizzle ORM + PostgreSQL
|
||||
- Vercel AI SDK
|
||||
- shadcn/ui components
|
||||
- Lucide React icons
|
||||
|
||||
## What I Want to Build
|
||||
[PROJECT_DESCRIPTION]
|
||||
|
||||
## Request
|
||||
Please help me transform this boilerplate into my actual application. Feel free to modify, replace, or completely rewrite any existing code to match my project requirements. The current implementation is just a starting point - treat it as scaffolding that can be changed as needed.`;
|
||||
|
||||
export function StarterPromptModal() {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [projectDescription, setProjectDescription] = useState("");
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopy = async () => {
|
||||
const finalPrompt = projectDescription.trim()
|
||||
? STARTER_PROMPT.replace(
|
||||
"[PROJECT_DESCRIPTION]",
|
||||
projectDescription.trim()
|
||||
)
|
||||
: STARTER_PROMPT.replace("\n[PROJECT_DESCRIPTION]\n", "");
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(finalPrompt);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
} catch (err) {
|
||||
console.error("Failed to copy text: ", err);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button size="sm" className="w-full">
|
||||
<Copy className="w-4 h-4 mr-2" />
|
||||
Get AI Starter Prompt
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-w-2xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Generate AI Starter Prompt</DialogTitle>
|
||||
<DialogDescription>
|
||||
Create a comprehensive prompt to help AI agents create your project
|
||||
for you.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="project-description"
|
||||
className="text-sm font-medium mb-2 block"
|
||||
>
|
||||
Describe your project (optional)
|
||||
</label>
|
||||
<textarea
|
||||
id="project-description"
|
||||
placeholder="e.g., A task management app for teams with real-time collaboration, project timelines, and AI-powered task prioritization..."
|
||||
value={projectDescription}
|
||||
onChange={(e) => setProjectDescription(e.target.value)}
|
||||
className="w-full h-24 px-3 py-2 border rounded-md resize-none text-sm"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground mt-1">
|
||||
Optional: Add details about your project to get a more tailored
|
||||
prompt
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Button onClick={handleCopy} className="flex-1">
|
||||
{copied ? (
|
||||
<>
|
||||
<Check className="w-4 h-4 mr-2" />
|
||||
Copied!
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Copy className="w-4 h-4 mr-2" />
|
||||
Copy Starter Prompt
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
<Button variant="outline" onClick={() => setIsOpen(false)}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="text-xs text-muted-foreground border-t pt-3">
|
||||
<strong>How to use:</strong> Copy this prompt and paste it into
|
||||
Claude Code, Cursor, or any AI coding assistant to get started with
|
||||
your project.
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
143
src/components/ui/dialog.tsx
Normal file
143
src/components/ui/dialog.tsx
Normal file
@@ -0,0 +1,143 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
||||
import { XIcon } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function Dialog({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
||||
return <DialogPrimitive.Root data-slot="dialog" {...props} />
|
||||
}
|
||||
|
||||
function DialogTrigger({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
||||
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
|
||||
}
|
||||
|
||||
function DialogPortal({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
||||
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
|
||||
}
|
||||
|
||||
function DialogClose({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
||||
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
|
||||
}
|
||||
|
||||
function DialogOverlay({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
||||
return (
|
||||
<DialogPrimitive.Overlay
|
||||
data-slot="dialog-overlay"
|
||||
className={cn(
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogContent({
|
||||
className,
|
||||
children,
|
||||
showCloseButton = true,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
||||
showCloseButton?: boolean
|
||||
}) {
|
||||
return (
|
||||
<DialogPortal data-slot="dialog-portal">
|
||||
<DialogOverlay />
|
||||
<DialogPrimitive.Content
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close
|
||||
data-slot="dialog-close"
|
||||
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
||||
>
|
||||
<XIcon />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
)}
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPortal>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div
|
||||
data-slot="dialog-header"
|
||||
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div
|
||||
data-slot="dialog-footer"
|
||||
className={cn(
|
||||
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogTitle({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
||||
return (
|
||||
<DialogPrimitive.Title
|
||||
data-slot="dialog-title"
|
||||
className={cn("text-lg leading-none font-semibold", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogDescription({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
||||
return (
|
||||
<DialogPrimitive.Description
|
||||
data-slot="dialog-description"
|
||||
className={cn("text-muted-foreground text-sm", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogOverlay,
|
||||
DialogPortal,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
}
|
||||
Reference in New Issue
Block a user