chore: formatting the code of recent changes

This commit is contained in:
Akhileshrangani4 2024-11-29 13:05:35 -05:00
parent fbc56dc7fd
commit ba7a1dcc2c
13 changed files with 956 additions and 911 deletions

View File

@ -325,7 +325,18 @@ export default {
const body = await request.json() const body = await request.json()
const { id, name, email, username, avatarUrl, createdAt, generations, tier, tierExpiresAt, lastResetDate } = userSchema.parse(body) const {
id,
name,
email,
username,
avatarUrl,
createdAt,
generations,
tier,
tierExpiresAt,
lastResetDate,
} = userSchema.parse(body)
const res = await db const res = await db
.insert(user) .insert(user)
.values({ .values({
@ -418,7 +429,10 @@ export default {
return json({ exists: !!exists }) return json({ exists: !!exists })
} }
return methodNotAllowed return methodNotAllowed
} else if (path === "/api/user/increment-generations" && method === "POST") { } else if (
path === "/api/user/increment-generations" &&
method === "POST"
) {
const schema = z.object({ const schema = z.object({
userId: z.string(), userId: z.string(),
}) })
@ -449,7 +463,7 @@ export default {
tier, tier,
tierExpiresAt: tierExpiresAt.getTime(), tierExpiresAt: tierExpiresAt.getTime(),
// Reset generations when upgrading tier // Reset generations when upgrading tier
generations: 0 generations: 0,
}) })
.where(eq(user.id, userId)) .where(eq(user.id, userId))
.get() .get()
@ -472,14 +486,19 @@ export default {
} }
const now = new Date() const now = new Date()
const lastReset = dbUser.lastResetDate ? new Date(dbUser.lastResetDate) : new Date(0) const lastReset = dbUser.lastResetDate
? new Date(dbUser.lastResetDate)
: new Date(0)
if (now.getMonth() !== lastReset.getMonth() || now.getFullYear() !== lastReset.getFullYear()) { if (
now.getMonth() !== lastReset.getMonth() ||
now.getFullYear() !== lastReset.getFullYear()
) {
await db await db
.update(user) .update(user)
.set({ .set({
generations: 0, generations: 0,
lastResetDate: now.getTime() lastResetDate: now.getTime(),
}) })
.where(eq(user.id, userId)) .where(eq(user.id, userId))
.get() .get()

View File

@ -43,7 +43,8 @@ export async function POST(request: Request) {
const userData = await dbUser.json() const userData = await dbUser.json()
// Get tier settings // Get tier settings
const tierSettings = TIERS[userData.tier as keyof typeof TIERS] || TIERS.FREE const tierSettings =
TIERS[userData.tier as keyof typeof TIERS] || TIERS.FREE
if (userData.generations >= tierSettings.generations) { if (userData.generations >= tierSettings.generations) {
return new Response( return new Response(
`AI generation limit reached for your ${userData.tier || "FREE"} tier`, `AI generation limit reached for your ${userData.tier || "FREE"} tier`,
@ -58,27 +59,29 @@ export async function POST(request: Request) {
isEditMode, isEditMode,
fileName, fileName,
line, line,
templateType templateType,
} = await request.json() } = await request.json()
// Get template configuration // Get template configuration
const templateConfig = templateConfigs[templateType] const templateConfig = templateConfigs[templateType]
// Create template context // Create template context
const templateContext = templateConfig ? ` const templateContext = templateConfig
? `
Project Template: ${templateConfig.name} Project Template: ${templateConfig.name}
File Structure: File Structure:
${Object.entries(templateConfig.fileStructure) ${Object.entries(templateConfig.fileStructure)
.map(([path, info]) => `${path} - ${info.description}`) .map(([path, info]) => `${path} - ${info.description}`)
.join('\n')} .join("\n")}
Conventions: Conventions:
${templateConfig.conventions.join('\n')} ${templateConfig.conventions.join("\n")}
Dependencies: Dependencies:
${JSON.stringify(templateConfig.dependencies, null, 2)} ${JSON.stringify(templateConfig.dependencies, null, 2)}
` : '' `
: ""
// Create system message based on mode // Create system message based on mode
let systemMessage let systemMessage
@ -146,7 +149,10 @@ ${activeFileContent ? `Active File Content:\n${activeFileContent}\n` : ""}`
new ReadableStream({ new ReadableStream({
async start(controller) { async start(controller) {
for await (const chunk of stream) { for await (const chunk of stream) {
if (chunk.type === "content_block_delta" && chunk.delta.type === "text_delta") { if (
chunk.type === "content_block_delta" &&
chunk.delta.type === "text_delta"
) {
controller.enqueue(encoder.encode(chunk.delta.text)) controller.enqueue(encoder.encode(chunk.delta.text))
} }
} }

View File

@ -75,8 +75,8 @@ export default function AIChat({
useEffect(() => { useEffect(() => {
const container = chatContainerRef.current const container = chatContainerRef.current
if (container) { if (container) {
container.addEventListener('scroll', handleScroll) container.addEventListener("scroll", handleScroll)
return () => container.removeEventListener('scroll', handleScroll) return () => container.removeEventListener("scroll", handleScroll)
} }
}, []) }, [])

View File

@ -131,8 +131,7 @@ export const handleSend = async (
})) }))
// Fetch AI response for chat message component // Fetch AI response for chat message component
const response = await fetch("/api/ai", const response = await fetch("/api/ai", {
{
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@ -145,8 +144,7 @@ export const handleSend = async (
templateType: templateType, templateType: templateType,
}), }),
signal: abortControllerRef.current.signal, signal: abortControllerRef.current.signal,
} })
)
// Throw error if response is not ok // Throw error if response is not ok
if (!response.ok) { if (!response.ok) {
@ -201,7 +199,8 @@ export const handleSend = async (
console.error("Error fetching AI response:", error) console.error("Error fetching AI response:", error)
const errorMessage = { const errorMessage = {
role: "assistant" as const, role: "assistant" as const,
content: error.message || "Sorry, I encountered an error. Please try again.", content:
error.message || "Sorry, I encountered an error. Please try again.",
} }
setMessages((prev) => [...prev, errorMessage]) setMessages((prev) => [...prev, errorMessage])
} }

View File

@ -66,15 +66,17 @@ export default function GenerateInput({
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
messages: [{ messages: [
{
role: "user", role: "user",
content: regenerate ? currentPrompt : input content: regenerate ? currentPrompt : input,
}], },
],
context: null, context: null,
activeFileContent: data.code, activeFileContent: data.code,
isEditMode: true, isEditMode: true,
fileName: data.fileName, fileName: data.fileName,
line: data.line line: data.line,
}), }),
}) })

View File

@ -231,7 +231,10 @@ function ProfileCard({
<div className="flex flex-col items-center gap-2"> <div className="flex flex-col items-center gap-2">
<p className="text-xs text-muted-foreground">{joinedAt}</p> <p className="text-xs text-muted-foreground">{joinedAt}</p>
{typeof generations === "number" && ( {typeof generations === "number" && (
<SubscriptionBadge generations={generations} tier={tier as keyof typeof TIERS} /> <SubscriptionBadge
generations={generations}
tier={tier as keyof typeof TIERS}
/>
)} )}
</div> </div>
</> </>
@ -445,7 +448,13 @@ const StatsItem = ({ icon: Icon, label }: StatsItemProps) => (
// #endregion // #endregion
// #region Sub Badge // #region Sub Badge
const SubscriptionBadge = ({ generations, tier = "FREE" }: { generations: number, tier?: keyof typeof TIERS }) => { const SubscriptionBadge = ({
generations,
tier = "FREE",
}: {
generations: number
tier?: keyof typeof TIERS
}) => {
return ( return (
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
<Badge variant="secondary" className="text-sm cursor-pointer"> <Badge variant="secondary" className="text-sm cursor-pointer">

View File

@ -43,7 +43,11 @@ const TIER_INFO = {
}, },
} as const } as const
export default function UserButton({ userData: initialUserData }: { userData: User }) { export default function UserButton({
userData: initialUserData,
}: {
userData: User
}) {
const [userData, setUserData] = useState<User>(initialUserData) const [userData, setUserData] = useState<User>(initialUserData)
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
const { signOut } = useClerk() const { signOut } = useClerk()
@ -57,7 +61,7 @@ export default function UserButton({ userData: initialUserData }: { userData: Us
headers: { headers: {
Authorization: `${process.env.NEXT_PUBLIC_WORKERS_KEY}`, Authorization: `${process.env.NEXT_PUBLIC_WORKERS_KEY}`,
}, },
cache: 'no-store' cache: "no-store",
} }
) )
if (res.ok) { if (res.ok) {
@ -75,9 +79,12 @@ export default function UserButton({ userData: initialUserData }: { userData: Us
} }
}, [isOpen]) }, [isOpen])
const tierInfo = TIER_INFO[userData.tier as keyof typeof TIER_INFO] || TIER_INFO.FREE const tierInfo =
TIER_INFO[userData.tier as keyof typeof TIER_INFO] || TIER_INFO.FREE
const TierIcon = tierInfo.icon const TierIcon = tierInfo.icon
const usagePercentage = Math.floor((userData.generations || 0) * 100 / tierInfo.limit) const usagePercentage = Math.floor(
((userData.generations || 0) * 100) / tierInfo.limit
)
const handleUpgrade = async () => { const handleUpgrade = async () => {
router.push(`/@${userData.username}`) router.push(`/@${userData.username}`)
@ -98,7 +105,6 @@ export default function UserButton({ userData: initialUserData }: { userData: Us
<DropdownMenuSeparator /> <DropdownMenuSeparator />
<DropdownMenuItem className="cursor-pointer" asChild> <DropdownMenuItem className="cursor-pointer" asChild>
<Link href={"/dashboard"}> <Link href={"/dashboard"}>
<LayoutDashboard className="mr-2 size-4" /> <LayoutDashboard className="mr-2 size-4" />
@ -114,12 +120,13 @@ export default function UserButton({ userData: initialUserData }: { userData: Us
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuSeparator /> <DropdownMenuSeparator />
<div className="py-1.5 px-2 w-full"> <div className="py-1.5 px-2 w-full">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">
<TierIcon className={`h-4 w-4 ${tierInfo.color}`} /> <TierIcon className={`h-4 w-4 ${tierInfo.color}`} />
<span className="text-sm font-medium">{userData.tier || "FREE"} Plan</span> <span className="text-sm font-medium">
{userData.tier || "FREE"} Plan
</span>
</div> </div>
{(userData.tier === "FREE" || userData.tier === "PRO") && ( {(userData.tier === "FREE" || userData.tier === "PRO") && (
<Button <Button
@ -139,15 +146,19 @@ export default function UserButton({ userData: initialUserData }: { userData: Us
<div className="w-full"> <div className="w-full">
<div className="flex items-center justify-between text-sm text-muted-foreground mb-2"> <div className="flex items-center justify-between text-sm text-muted-foreground mb-2">
<span>AI Usage</span> <span>AI Usage</span>
<span>{userData.generations}/{tierInfo.limit}</span> <span>
{userData.generations}/{tierInfo.limit}
</span>
</div> </div>
<div className="rounded-full w-full h-2 overflow-hidden bg-secondary mb-1"> <div className="rounded-full w-full h-2 overflow-hidden bg-secondary mb-1">
<div <div
className={`h-full rounded-full transition-all duration-300 ${ className={`h-full rounded-full transition-all duration-300 ${
usagePercentage > 90 ? 'bg-red-500' : usagePercentage > 90
usagePercentage > 75 ? 'bg-yellow-500' : ? "bg-red-500"
tierInfo.color.replace('text-', 'bg-') : usagePercentage > 75
? "bg-yellow-500"
: tierInfo.color.replace("text-", "bg-")
}`} }`}
style={{ style={{
width: `${Math.min(usagePercentage, 100)}%`, width: `${Math.min(usagePercentage, 100)}%`,
@ -173,4 +184,3 @@ export default function UserButton({ userData: initialUserData }: { userData: Us
</DropdownMenu> </DropdownMenu>
) )
} }

View File

@ -38,6 +38,6 @@ export const projectTemplates: {
name: "PHP", name: "PHP",
description: "PHP development environment", description: "PHP development environment",
icon: "/project-icons/php.svg", icon: "/project-icons/php.svg",
disabled: false disabled: false,
}, },
] ]

View File

@ -1,7 +1,7 @@
export interface TemplateConfig { export interface TemplateConfig {
id: string id: string
name: string, name: string
runCommand: string, runCommand: string
fileStructure: { fileStructure: {
[key: string]: { [key: string]: {
purpose: string purpose: string
@ -15,9 +15,9 @@ export interface TemplateConfig {
scripts?: { scripts?: {
[key: string]: string [key: string]: string
} }
} }
export const templateConfigs: { [key: string]: TemplateConfig } = { export const templateConfigs: { [key: string]: TemplateConfig } = {
reactjs: { reactjs: {
id: "reactjs", id: "reactjs",
name: "React", name: "React",
@ -25,67 +25,67 @@ export interface TemplateConfig {
fileStructure: { fileStructure: {
"src/": { "src/": {
purpose: "source", purpose: "source",
description: "Contains all React components and application logic" description: "Contains all React components and application logic",
}, },
"src/components/": { "src/components/": {
purpose: "components", purpose: "components",
description: "Reusable React components" description: "Reusable React components",
}, },
"src/lib/": { "src/lib/": {
purpose: "utilities", purpose: "utilities",
description: "Utility functions and shared code" description: "Utility functions and shared code",
}, },
"src/App.tsx": { "src/App.tsx": {
purpose: "entry", purpose: "entry",
description: "Main application component" description: "Main application component",
}, },
"src/index.tsx": { "src/index.tsx": {
purpose: "entry", purpose: "entry",
description: "Application entry point" description: "Application entry point",
}, },
"src/index.css": { "src/index.css": {
purpose: "styles", purpose: "styles",
description: "Global CSS styles" description: "Global CSS styles",
}, },
"public/": { "public/": {
purpose: "static", purpose: "static",
description: "Static assets and index.html" description: "Static assets and index.html",
}, },
"tsconfig.json": { "tsconfig.json": {
purpose: "config", purpose: "config",
description: "TypeScript configuration" description: "TypeScript configuration",
}, },
"vite.config.ts": { "vite.config.ts": {
purpose: "config", purpose: "config",
description: "Vite bundler configuration" description: "Vite bundler configuration",
}, },
"package.json": { "package.json": {
purpose: "config", purpose: "config",
description: "Project dependencies and scripts" description: "Project dependencies and scripts",
} },
}, },
conventions: [ conventions: [
"Use functional components with hooks", "Use functional components with hooks",
"Follow React naming conventions (PascalCase for components)", "Follow React naming conventions (PascalCase for components)",
"Keep components small and focused", "Keep components small and focused",
"Use TypeScript for type safety" "Use TypeScript for type safety",
], ],
dependencies: { dependencies: {
"@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-slot": "^1.1.0",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", clsx: "^2.1.1",
"lucide-react": "^0.441.0", "lucide-react": "^0.441.0",
"react": "^18.3.1", react: "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"tailwind-merge": "^2.5.2", "tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7" "tailwindcss-animate": "^1.0.7",
}, },
scripts: { scripts: {
"dev": "vite", dev: "vite",
"build": "tsc && vite build", build: "tsc && vite build",
"preview": "vite preview", preview: "vite preview",
} },
}, },
// Next.js template config // Next.js template config
nextjs: { nextjs: {
@ -95,71 +95,71 @@ export interface TemplateConfig {
fileStructure: { fileStructure: {
"pages/": { "pages/": {
purpose: "routing", purpose: "routing",
description: "Page components and API routes" description: "Page components and API routes",
}, },
"pages/api/": { "pages/api/": {
purpose: "api", purpose: "api",
description: "API route handlers" description: "API route handlers",
}, },
"pages/_app.tsx": { "pages/_app.tsx": {
purpose: "entry", purpose: "entry",
description: "Application wrapper component" description: "Application wrapper component",
}, },
"pages/index.tsx": { "pages/index.tsx": {
purpose: "page", purpose: "page",
description: "Homepage component" description: "Homepage component",
}, },
"public/": { "public/": {
purpose: "static", purpose: "static",
description: "Static assets and files" description: "Static assets and files",
}, },
"styles/": { "styles/": {
purpose: "styles", purpose: "styles",
description: "CSS modules and global styles" description: "CSS modules and global styles",
}, },
"styles/globals.css": { "styles/globals.css": {
purpose: "styles", purpose: "styles",
description: "Global CSS styles" description: "Global CSS styles",
}, },
"styles/Home.module.css": { "styles/Home.module.css": {
purpose: "styles", purpose: "styles",
description: "Homepage-specific styles" description: "Homepage-specific styles",
}, },
"next.config.js": { "next.config.js": {
purpose: "config", purpose: "config",
description: "Next.js configuration" description: "Next.js configuration",
}, },
"next-env.d.ts": { "next-env.d.ts": {
purpose: "types", purpose: "types",
description: "Next.js TypeScript declarations" description: "Next.js TypeScript declarations",
}, },
"tsconfig.json": { "tsconfig.json": {
purpose: "config", purpose: "config",
description: "TypeScript configuration" description: "TypeScript configuration",
}, },
"package.json": { "package.json": {
purpose: "config", purpose: "config",
description: "Project dependencies and scripts" description: "Project dependencies and scripts",
} },
}, },
conventions: [ conventions: [
"Use file-system based routing", "Use file-system based routing",
"Keep API routes in pages/api", "Keep API routes in pages/api",
"Use CSS Modules for component styles", "Use CSS Modules for component styles",
"Follow Next.js data fetching patterns" "Follow Next.js data fetching patterns",
], ],
dependencies: { dependencies: {
"next": "^14.1.0", next: "^14.1.0",
"react": "^18.2.0", react: "^18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"tailwindcss": "^3.4.1" tailwindcss: "^3.4.1",
}, },
scripts: { scripts: {
"dev": "next dev", dev: "next dev",
"build": "next build", build: "next build",
"start": "next start", start: "next start",
"lint": "next lint", lint: "next lint",
} },
}, },
// Streamlit template config // Streamlit template config
streamlit: { streamlit: {
@ -169,35 +169,35 @@ export interface TemplateConfig {
fileStructure: { fileStructure: {
"main.py": { "main.py": {
purpose: "entry", purpose: "entry",
description: "Main Streamlit application file" description: "Main Streamlit application file",
}, },
"requirements.txt": { "requirements.txt": {
purpose: "dependencies", purpose: "dependencies",
description: "Python package dependencies" description: "Python package dependencies",
}, },
"Procfile": { Procfile: {
purpose: "deployment", purpose: "deployment",
description: "Deployment configuration for hosting platforms" description: "Deployment configuration for hosting platforms",
}, },
"venv/": { "venv/": {
purpose: "environment", purpose: "environment",
description: "Python virtual environment directory" description: "Python virtual environment directory",
} },
}, },
conventions: [ conventions: [
"Use Streamlit components for UI", "Use Streamlit components for UI",
"Follow PEP 8 style guide", "Follow PEP 8 style guide",
"Keep dependencies in requirements.txt", "Keep dependencies in requirements.txt",
"Use virtual environment for isolation" "Use virtual environment for isolation",
], ],
dependencies: { dependencies: {
"streamlit": "^1.40.0", streamlit: "^1.40.0",
"altair": "^5.5.0" altair: "^5.5.0",
}, },
scripts: { scripts: {
"start": "streamlit run main.py", start: "streamlit run main.py",
"dev": "./venv/bin/streamlit run main.py --server.runOnSave true" dev: "./venv/bin/streamlit run main.py --server.runOnSave true",
} },
}, },
// HTML template config // HTML template config
vanillajs: { vanillajs: {
@ -207,43 +207,43 @@ export interface TemplateConfig {
fileStructure: { fileStructure: {
"index.html": { "index.html": {
purpose: "entry", purpose: "entry",
description: "Main HTML entry point" description: "Main HTML entry point",
}, },
"style.css": { "style.css": {
purpose: "styles", purpose: "styles",
description: "Global CSS styles" description: "Global CSS styles",
}, },
"script.js": { "script.js": {
purpose: "scripts", purpose: "scripts",
description: "JavaScript application logic" description: "JavaScript application logic",
}, },
"package.json": { "package.json": {
purpose: "config", purpose: "config",
description: "Project dependencies and scripts" description: "Project dependencies and scripts",
}, },
"package-lock.json": { "package-lock.json": {
purpose: "config", purpose: "config",
description: "Locked dependency versions" description: "Locked dependency versions",
}, },
"vite.config.js": { "vite.config.js": {
purpose: "config", purpose: "config",
description: "Vite bundler configuration" description: "Vite bundler configuration",
} },
}, },
conventions: [ conventions: [
"Use semantic HTML elements", "Use semantic HTML elements",
"Keep CSS modular and organized", "Keep CSS modular and organized",
"Write clean, modular JavaScript", "Write clean, modular JavaScript",
"Follow modern ES6+ practices" "Follow modern ES6+ practices",
], ],
dependencies: { dependencies: {
"vite": "^5.0.12" vite: "^5.0.12",
}, },
scripts: { scripts: {
"dev": "vite", dev: "vite",
"build": "vite build", build: "vite build",
"preview": "vite preview" preview: "vite preview",
} },
}, },
// PHP template config // PHP template config
php: { php: {
@ -253,38 +253,38 @@ export interface TemplateConfig {
fileStructure: { fileStructure: {
"index.php": { "index.php": {
purpose: "entry", purpose: "entry",
description: "Main PHP entry point" description: "Main PHP entry point",
}, },
"package.json": { "package.json": {
purpose: "config", purpose: "config",
description: "Frontend dependencies and scripts" description: "Frontend dependencies and scripts",
}, },
"package-lock.json": { "package-lock.json": {
purpose: "config", purpose: "config",
description: "Locked dependency versions" description: "Locked dependency versions",
}, },
"vite.config.js": { "vite.config.js": {
purpose: "config", purpose: "config",
description: "Vite configuration for frontend assets" description: "Vite configuration for frontend assets",
}, },
"node_modules/": { "node_modules/": {
purpose: "dependencies", purpose: "dependencies",
description: "Frontend dependency files" description: "Frontend dependency files",
} },
}, },
conventions: [ conventions: [
"Follow PSR-12 coding standards", "Follow PSR-12 coding standards",
"Use modern PHP 8+ features", "Use modern PHP 8+ features",
"Organize assets with Vite", "Organize assets with Vite",
"Keep PHP logic separate from presentation" "Keep PHP logic separate from presentation",
], ],
dependencies: { dependencies: {
"vite": "^5.0.0" vite: "^5.0.0",
}, },
scripts: { scripts: {
"dev": "vite", dev: "vite",
"build": "vite build", build: "vite build",
"preview": "vite preview" preview: "vite preview",
} },
} },
} }