import { PrismaClient } from '@prisma/client'
import { PrismaPg } from '@prisma/adapter-pg'
import { betterAuth } from 'better-auth'
import { emailOTP } from 'better-auth/plugins'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL
})
export const prisma = new PrismaClient({
adapter
})
export const auth = betterAuth({
database: prismaAdapter(prisma),
plugins: [
emailOTP({
otpLength: 6,
expiresIn: 300,
}),
],
})
export async function getPublishedProjects() {
return prisma.project.findMany({
where: { status: 'published' },
orderBy: [
{ featured: 'desc' },
{ sortOrder: 'asc' },
],
})
}
"use server"
export async function createProjectAction(
data: FormData
) {
const session = await auth.api
.getSession({ headers })
if (!session) throw new Error()
const validated = schema.parse(data)
const result = await createProject(validated)
revalidatePath("/admin/projects")
revalidatePath("/")
return result
}
const projectSchema = z.object({
title: z.string().min(1),
slug: z.string().min(1),
description: z.string().min(10),
status: z.enum([
'draft',
'published',
'archived'
]),
techStack: z.array(z.string()),
featured: z.boolean(),
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="fr">
<body>
<ThemeProvider>
<MotionProvider>
{children}
</MotionProvider>
</ThemeProvider>
</body>
</html>
)
}import { PrismaClient } from '@prisma/client'
import { PrismaPg } from '@prisma/adapter-pg'
import { betterAuth } from 'better-auth'
import { emailOTP } from 'better-auth/plugins'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL
})
export const prisma = new PrismaClient({
adapter
})
export const auth = betterAuth({
database: prismaAdapter(prisma),
plugins: [
emailOTP({
otpLength: 6,
expiresIn: 300,
}),
],
})
export async function getPublishedProjects() {
return prisma.project.findMany({
where: { status: 'published' },
orderBy: [
{ featured: 'desc' },
{ sortOrder: 'asc' },
],
})
}
"use server"
export async function createProjectAction(
data: FormData
) {
const session = await auth.api
.getSession({ headers })
if (!session) throw new Error()
const validated = schema.parse(data)
const result = await createProject(validated)
revalidatePath("/admin/projects")
revalidatePath("/")
return result
}
const projectSchema = z.object({
title: z.string().min(1),
slug: z.string().min(1),
description: z.string().min(10),
status: z.enum([
'draft',
'published',
'archived'
]),
techStack: z.array(z.string()),
featured: z.boolean(),
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="fr">
<body>
<ThemeProvider>
<MotionProvider>
{children}
</MotionProvider>
</ThemeProvider>
</body>
</html>
)
}
"use client"
import { m, useScroll } from 'motion/react'
import { useReducedMotion } from 'motion/react'
export function FadeIn({
children,
delay = 0,
direction = "up",
}: FadeInProps) {
const prefersReducedMotion =
useReducedMotion()
return (
<m.div
initial={{ opacity: 0, y: 24 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{
duration: 0.5,
delay,
ease: "easeOut"
}}
>
{children}
</m.div>
)
}
// Claude Code agent workflow
const agent = defineAgent({
name: 'researcher',
tools: [Glob, Grep, Read],
prompt: 'Explore the codebase',
})
await agent.run({
task: 'Find all API routes',
maxTurns: 10,
})
// Skill definition
const skill = defineSkill({
name: 'deploy',
steps: [
'step-00-init.md',
'step-01-build.md',
'step-02-deploy.md',
],
})
export function Hero({ profile }) {
const name = profile?.name
const nameParts = name.split(" ")
const firstName = nameParts[0]
const lastName = nameParts.at(-1)
return (
<section className="min-h-svh">
<h1>
{firstName}{" "}
<span className="text-gradient">
{lastName}
</span>
</h1>
<p>{profile?.tagline}</p>
<Button asChild>
<a href="#contact">
Discutons de votre projet
</a>
</Button>
</section>
)
}
function useScrollProgress() {
const { scrollYProgress } = useScroll()
return useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
})
}
const config = defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: process.env.DATABASE_URL,
},
})"use client"
import { m, useScroll } from 'motion/react'
import { useReducedMotion } from 'motion/react'
export function FadeIn({
children,
delay = 0,
direction = "up",
}: FadeInProps) {
const prefersReducedMotion =
useReducedMotion()
return (
<m.div
initial={{ opacity: 0, y: 24 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{
duration: 0.5,
delay,
ease: "easeOut"
}}
>
{children}
</m.div>
)
}
// Claude Code agent workflow
const agent = defineAgent({
name: 'researcher',
tools: [Glob, Grep, Read],
prompt: 'Explore the codebase',
})
await agent.run({
task: 'Find all API routes',
maxTurns: 10,
})
// Skill definition
const skill = defineSkill({
name: 'deploy',
steps: [
'step-00-init.md',
'step-01-build.md',
'step-02-deploy.md',
],
})
export function Hero({ profile }) {
const name = profile?.name
const nameParts = name.split(" ")
const firstName = nameParts[0]
const lastName = nameParts.at(-1)
return (
<section className="min-h-svh">
<h1>
{firstName}{" "}
<span className="text-gradient">
{lastName}
</span>
</h1>
<p>{profile?.tagline}</p>
<Button asChild>
<a href="#contact">
Discutons de votre projet
</a>
</Button>
</section>
)
}
function useScrollProgress() {
const { scrollYProgress } = useScroll()
return useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
})
}
const config = defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: process.env.DATABASE_URL,
},
})