correction bible du mande (store update temps reel)

This commit is contained in:
2026-02-27 23:23:43 +01:00
parent 23560ac9c3
commit 5268a7dd68
40 changed files with 1303 additions and 489 deletions

View File

@@ -1,11 +1,12 @@
{
"/api/ai/generate/route": "app/api/ai/generate/route.js",
"/api/auth/[...nextauth]/route": "app/api/auth/[...nextauth]/route.js",
"/api/entities/route": "app/api/entities/route.js",
"/api/projects/[id]/route": "app/api/projects/[id]/route.js",
"/api/projects/route": "app/api/projects/route.js",
"/api/user/profile/route": "app/api/user/profile/route.js",
"/dashboard/page": "app/dashboard/page.js",
"/login/page": "app/login/page.js",
"/page": "app/page.js",
"/project/[id]/page": "app/project/[id]/page.js"
"/project/[id]/page": "app/project/[id]/page.js",
"/project/[id]/world/page": "app/project/[id]/world/page.js"
}

View File

@@ -206,8 +206,11 @@ async function GET() {
const user = await prisma.user.findUnique({
where: {
id: session.user.id
},
include: {
subscriptionPlan: true
}
});
}); // Bypass Prisma type cache
if (!user) {
return __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$server$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__["NextResponse"].json({
error: 'Utilisateur non trouvé'
@@ -230,13 +233,24 @@ async function GET() {
const text = (chapter.content || '').replace(/<[^>]*>/g, ' ').trim();
return total + (text ? text.split(/\s+/).length : 0);
}, 0);
return __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$server$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__["NextResponse"].json({
const response = __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$server$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__["NextResponse"].json({
id: user.id,
email: user.email,
name: user.name,
avatar: user.avatar,
bio: user.bio,
plan: user.plan,
plan: user.planId || user.plan || 'free',
planDetails: user.subscriptionPlan ? {
id: user.subscriptionPlan.id,
name: user.subscriptionPlan.name,
displayName: user.subscriptionPlan.displayName,
price: user.subscriptionPlan.price,
description: user.subscriptionPlan.description,
features: user.subscriptionPlan.features,
maxProjects: user.subscriptionPlan.maxProjects,
maxAiActions: user.subscriptionPlan.maxAiActions,
isPopular: user.subscriptionPlan.isPopular
} : undefined,
aiActionsUsed: user.aiActionsUsed,
dailyWordGoal: user.dailyWordGoal,
writingStreak: user.writingStreak,
@@ -244,6 +258,8 @@ async function GET() {
createdAt: user.createdAt,
totalWords
});
response.headers.set('Cache-Control', 'no-store, max-age=0');
return response;
}
async function PUT(request) {
const session = await (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$lib$2f$auth$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["auth"])();

File diff suppressed because one or more lines are too long

View File

@@ -453,11 +453,6 @@ const dynamic = 'force-dynamic';
;
;
;
const PLAN_AI_LIMITS = {
free: 100,
pro: 5000,
master: 999999
};
async function POST(request) {
try {
const session = await (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$lib$2f$auth$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["auth"])();
@@ -474,11 +469,10 @@ async function POST(request) {
where: {
id: session.user.id
},
select: {
plan: true,
aiActionsUsed: true
include: {
subscriptionPlan: true
}
});
}); // Bypass Prisma client types for this relation
if (!dbUser) {
return __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$server$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__["NextResponse"].json({
error: 'Utilisateur non trouvé'
@@ -486,10 +480,11 @@ async function POST(request) {
status: 404
});
}
const limit = PLAN_AI_LIMITS[dbUser.plan] || PLAN_AI_LIMITS.free;
if (dbUser.aiActionsUsed >= limit) {
const limit = dbUser.subscriptionPlan?.maxAiActions ?? 100;
const planName = dbUser.subscriptionPlan?.displayName || 'Gratuit';
if (limit !== -1 && dbUser.aiActionsUsed >= limit) {
return __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$server$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__["NextResponse"].json({
error: `Limite de ${limit} actions IA atteinte pour le plan ${dbUser.plan}. Passez au plan supérieur !`
error: `Limite de ${limit} actions IA atteinte pour le plan ${planName}. Passez au plan supérieur !`
}, {
status: 403
});

File diff suppressed because one or more lines are too long

View File

@@ -220,12 +220,6 @@ async function GET() {
});
return __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$server$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__["NextResponse"].json(projects);
}
// Plan limits for project creation
const PLAN_PROJECT_LIMITS = {
free: 3,
pro: 20,
master: 999
};
async function POST(request) {
const session = await (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$lib$2f$auth$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["auth"])();
if (!session?.user?.id) {
@@ -235,26 +229,26 @@ async function POST(request) {
status: 401
});
}
// Check plan limits
const prisma = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$lib$2f$prisma$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["default"])();
// Check plan limit
const user = await prisma.user.findUnique({
where: {
id: session.user.id
},
select: {
plan: true
include: {
subscriptionPlan: true
}
});
const plan = user?.plan || 'free';
const limit = PLAN_PROJECT_LIMITS[plan] || PLAN_PROJECT_LIMITS.free;
}); // Cast to any to bypass Prisma type cache issues
const limit = user?.subscriptionPlan?.maxProjects ?? 3;
const planName = user?.subscriptionPlan?.displayName || 'Gratuit';
const currentCount = await prisma.project.count({
where: {
userId: session.user.id
}
});
if (currentCount >= limit) {
if (limit !== -1 && currentCount >= limit) {
return __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$server$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__["NextResponse"].json({
error: `Limite de ${limit} projets atteinte pour le plan ${plan}. Passez au plan supérieur !`
error: `Limite de ${limit} projets atteinte pour le plan ${planName}. Passez au plan supérieur !`
}, {
status: 403
});

View File

@@ -4,5 +4,5 @@
"sections": [
{"offset": {"line": 58, "column": 0}, "map": {"version":3,"sources":["file:///C:/Users/streaper2/Documents/00%20-%20projet/plumeia/src/lib/auth.ts"],"sourcesContent":["import NextAuth from 'next-auth';\r\nimport Credentials from 'next-auth/providers/credentials';\r\nimport bcrypt from 'bcryptjs';\r\n\r\nexport const { handlers, signIn, signOut, auth } = NextAuth({\r\n providers: [\r\n Credentials({\r\n name: 'credentials',\r\n credentials: {\r\n email: { label: 'Email', type: 'email' },\r\n password: { label: 'Password', type: 'password' },\r\n },\r\n async authorize(credentials) {\r\n if (!credentials?.email || !credentials?.password) return null;\r\n\r\n // Lazy import to avoid PrismaClient initialization during build\r\n const { default: getDB } = await import('./prisma');\r\n const prisma = getDB();\r\n\r\n const user = await prisma.user.findUnique({\r\n where: { email: credentials.email as string },\r\n });\r\n\r\n if (!user) return null;\r\n\r\n const isValid = await bcrypt.compare(\r\n credentials.password as string,\r\n user.hashedPassword\r\n );\r\n\r\n if (!isValid) return null;\r\n\r\n return {\r\n id: user.id,\r\n email: user.email,\r\n name: user.name,\r\n };\r\n },\r\n }),\r\n ],\r\n session: {\r\n strategy: 'jwt',\r\n },\r\n callbacks: {\r\n async jwt({ token, user }) {\r\n if (user) {\r\n token.id = user.id;\r\n }\r\n return token;\r\n },\r\n async session({ session, token }) {\r\n if (session.user && token.id) {\r\n session.user.id = token.id as string;\r\n }\r\n return session;\r\n },\r\n },\r\n pages: {\r\n signIn: '/',\r\n },\r\n});\r\n"],"names":[],"mappings":";;;;;;;;;;AAAA;AACA;AAAA;AACA;;;;AAEO,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAA,8MAAQ,EAAC;IACxD,WAAW;QACP,IAAA,mNAAW,EAAC;YACR,MAAM;YACN,aAAa;gBACT,OAAO;oBAAE,OAAO;oBAAS,MAAM;gBAAQ;gBACvC,UAAU;oBAAE,OAAO;oBAAY,MAAM;gBAAW;YACpD;YACA,MAAM,WAAU,WAAW;gBACvB,IAAI,CAAC,aAAa,SAAS,CAAC,aAAa,UAAU,OAAO;gBAE1D,gEAAgE;gBAChE,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG;gBAC3B,MAAM,SAAS;gBAEf,MAAM,OAAO,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC;oBACtC,OAAO;wBAAE,OAAO,YAAY,KAAK;oBAAW;gBAChD;gBAEA,IAAI,CAAC,MAAM,OAAO;gBAElB,MAAM,UAAU,MAAM,0LAAM,CAAC,OAAO,CAChC,YAAY,QAAQ,EACpB,KAAK,cAAc;gBAGvB,IAAI,CAAC,SAAS,OAAO;gBAErB,OAAO;oBACH,IAAI,KAAK,EAAE;oBACX,OAAO,KAAK,KAAK;oBACjB,MAAM,KAAK,IAAI;gBACnB;YACJ;QACJ;KACH;IACD,SAAS;QACL,UAAU;IACd;IACA,WAAW;QACP,MAAM,KAAI,EAAE,KAAK,EAAE,IAAI,EAAE;YACrB,IAAI,MAAM;gBACN,MAAM,EAAE,GAAG,KAAK,EAAE;YACtB;YACA,OAAO;QACX;QACA,MAAM,SAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;YAC5B,IAAI,QAAQ,IAAI,IAAI,MAAM,EAAE,EAAE;gBAC1B,QAAQ,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE;YAC9B;YACA,OAAO;QACX;IACJ;IACA,OAAO;QACH,QAAQ;IACZ;AACJ"}},
{"offset": {"line": 137, "column": 0}, "map": {"version":3,"sources":["file:///C:/Users/streaper2/Documents/00%20-%20projet/plumeia/src/lib/prisma.ts"],"sourcesContent":["import { PrismaClient } from '@prisma/client';\r\nimport { PrismaPg } from '@prisma/adapter-pg';\r\nimport { Pool } from 'pg';\r\n\r\nconst globalForPrisma = globalThis as unknown as {\r\n prisma: PrismaClient | undefined;\r\n};\r\n\r\n/**\r\n * Returns a singleton PrismaClient instance using the Prisma v7 adapter pattern.\r\n * Uses @prisma/adapter-pg with a pg Pool for direct PostgreSQL connections.\r\n */\r\nexport function getDB(): PrismaClient {\r\n if (!globalForPrisma.prisma) {\r\n const connectionString = process.env.DATABASE_URL;\r\n const pool = new Pool({ connectionString });\r\n const adapter = new PrismaPg(pool);\r\n\r\n globalForPrisma.prisma = new PrismaClient({ adapter });\r\n }\r\n return globalForPrisma.prisma;\r\n}\r\n\r\nexport default getDB;\r\n"],"names":[],"mappings":";;;;;;AAAA;AACA;AACA;;;;;;;;;AAEA,MAAM,kBAAkB;AAQjB,SAAS;IACZ,IAAI,CAAC,gBAAgB,MAAM,EAAE;QACzB,MAAM,mBAAmB,QAAQ,GAAG,CAAC,YAAY;QACjD,MAAM,OAAO,IAAI,iMAAI,CAAC;YAAE;QAAiB;QACzC,MAAM,UAAU,IAAI,qNAAQ,CAAC;QAE7B,gBAAgB,MAAM,GAAG,IAAI,kPAAY,CAAC;YAAE;QAAQ;IACxD;IACA,OAAO,gBAAgB,MAAM;AACjC;uCAEe"}},
{"offset": {"line": 176, "column": 0}, "map": {"version":3,"sources":["file:///C:/Users/streaper2/Documents/00%20-%20projet/plumeia/src/app/api/projects/route.ts"],"sourcesContent":["export const dynamic = 'force-dynamic';\r\n\r\nimport { NextRequest, NextResponse } from 'next/server';\r\nimport { auth } from '@/lib/auth';\r\nimport getDB from '@/lib/prisma';\r\n\r\n// GET /api/projects — List all user's projects\r\nexport async function GET() {\r\n const session = await auth();\r\n if (!session?.user?.id) {\r\n return NextResponse.json({ error: 'Non autorisé' }, { status: 401 });\r\n }\r\n\r\n const projects = await getDB().project.findMany({\r\n where: { userId: session.user.id },\r\n orderBy: { updatedAt: 'desc' },\r\n include: {\r\n _count: { select: { chapters: true, entities: true } },\r\n },\r\n });\r\n\r\n return NextResponse.json(projects);\r\n}\r\n\r\n// Plan limits for project creation\r\nconst PLAN_PROJECT_LIMITS: Record<string, number> = {\r\n free: 3,\r\n pro: 20,\r\n master: 999,\r\n};\r\n\r\n// POST /api/projects — Create a new project\r\nexport async function POST(request: NextRequest) {\r\n const session = await auth();\r\n if (!session?.user?.id) {\r\n return NextResponse.json({ error: 'Non autorisé' }, { status: 401 });\r\n }\r\n\r\n const prisma = getDB();\r\n\r\n // Check plan limit\r\n const user = await prisma.user.findUnique({ where: { id: session.user.id }, select: { plan: true } });\r\n const plan = user?.plan || 'free';\r\n const limit = PLAN_PROJECT_LIMITS[plan] || PLAN_PROJECT_LIMITS.free;\r\n const currentCount = await prisma.project.count({ where: { userId: session.user.id } });\r\n\r\n if (currentCount >= limit) {\r\n return NextResponse.json(\r\n { error: `Limite de ${limit} projets atteinte pour le plan ${plan}. Passez au plan supérieur !` },\r\n { status: 403 }\r\n );\r\n }\r\n\r\n const body = await request.json();\r\n\r\n const project = await prisma.project.create({\r\n data: {\r\n title: body.title || 'Nouveau Roman',\r\n author: body.author || session.user.name || 'Auteur',\r\n settings: body.settings || null,\r\n userId: session.user.id,\r\n },\r\n });\r\n\r\n return NextResponse.json(project, { status: 201 });\r\n}\r\n"],"names":[],"mappings":";;;;;;;;AAEA;AACA;AACA;;;;;AAJO,MAAM,UAAU;;;;AAOhB,eAAe;IAClB,MAAM,UAAU,MAAM,IAAA,wKAAI;IAC1B,IAAI,CAAC,SAAS,MAAM,IAAI;QACpB,OAAO,4LAAY,CAAC,IAAI,CAAC;YAAE,OAAO;QAAe,GAAG;YAAE,QAAQ;QAAI;IACtE;IAEA,MAAM,WAAW,MAAM,IAAA,6KAAK,IAAG,OAAO,CAAC,QAAQ,CAAC;QAC5C,OAAO;YAAE,QAAQ,QAAQ,IAAI,CAAC,EAAE;QAAC;QACjC,SAAS;YAAE,WAAW;QAAO;QAC7B,SAAS;YACL,QAAQ;gBAAE,QAAQ;oBAAE,UAAU;oBAAM,UAAU;gBAAK;YAAE;QACzD;IACJ;IAEA,OAAO,4LAAY,CAAC,IAAI,CAAC;AAC7B;AAEA,mCAAmC;AACnC,MAAM,sBAA8C;IAChD,MAAM;IACN,KAAK;IACL,QAAQ;AACZ;AAGO,eAAe,KAAK,OAAoB;IAC3C,MAAM,UAAU,MAAM,IAAA,wKAAI;IAC1B,IAAI,CAAC,SAAS,MAAM,IAAI;QACpB,OAAO,4LAAY,CAAC,IAAI,CAAC;YAAE,OAAO;QAAe,GAAG;YAAE,QAAQ;QAAI;IACtE;IAEA,MAAM,SAAS,IAAA,6KAAK;IAEpB,mBAAmB;IACnB,MAAM,OAAO,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO;YAAE,IAAI,QAAQ,IAAI,CAAC,EAAE;QAAC;QAAG,QAAQ;YAAE,MAAM;QAAK;IAAE;IACnG,MAAM,OAAO,MAAM,QAAQ;IAC3B,MAAM,QAAQ,mBAAmB,CAAC,KAAK,IAAI,oBAAoB,IAAI;IACnE,MAAM,eAAe,MAAM,OAAO,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO;YAAE,QAAQ,QAAQ,IAAI,CAAC,EAAE;QAAC;IAAE;IAErF,IAAI,gBAAgB,OAAO;QACvB,OAAO,4LAAY,CAAC,IAAI,CACpB;YAAE,OAAO,CAAC,UAAU,EAAE,MAAM,+BAA+B,EAAE,KAAK,4BAA4B,CAAC;QAAC,GAChG;YAAE,QAAQ;QAAI;IAEtB;IAEA,MAAM,OAAO,MAAM,QAAQ,IAAI;IAE/B,MAAM,UAAU,MAAM,OAAO,OAAO,CAAC,MAAM,CAAC;QACxC,MAAM;YACF,OAAO,KAAK,KAAK,IAAI;YACrB,QAAQ,KAAK,MAAM,IAAI,QAAQ,IAAI,CAAC,IAAI,IAAI;YAC5C,UAAU,KAAK,QAAQ,IAAI;YAC3B,QAAQ,QAAQ,IAAI,CAAC,EAAE;QAC3B;IACJ;IAEA,OAAO,4LAAY,CAAC,IAAI,CAAC,SAAS;QAAE,QAAQ;IAAI;AACpD"}}]
{"offset": {"line": 176, "column": 0}, "map": {"version":3,"sources":["file:///C:/Users/streaper2/Documents/00%20-%20projet/plumeia/src/app/api/projects/route.ts"],"sourcesContent":["export const dynamic = 'force-dynamic';\r\n\r\nimport { NextRequest, NextResponse } from 'next/server';\r\nimport { auth } from '@/lib/auth';\r\nimport getDB from '@/lib/prisma';\r\n\r\n// GET /api/projects — List all user's projects\r\nexport async function GET() {\r\n const session = await auth();\r\n if (!session?.user?.id) {\r\n return NextResponse.json({ error: 'Non autorisé' }, { status: 401 });\r\n }\r\n\r\n const projects = await getDB().project.findMany({\r\n where: { userId: session.user.id },\r\n orderBy: { updatedAt: 'desc' },\r\n include: {\r\n _count: { select: { chapters: true, entities: true } },\r\n },\r\n });\r\n\r\n return NextResponse.json(projects);\r\n}\r\n\r\n\r\n\r\n// POST /api/projects — Create a new project\r\nexport async function POST(request: NextRequest) {\r\n const session = await auth();\r\n if (!session?.user?.id) {\r\n return NextResponse.json({ error: 'Non autorisé' }, { status: 401 });\r\n }\r\n\r\n // Check plan limits\r\n const prisma = getDB();\r\n const user = await prisma.user.findUnique({\r\n where: { id: session.user.id },\r\n include: { subscriptionPlan: true }\r\n }) as any; // Cast to any to bypass Prisma type cache issues\r\n\r\n const limit = user?.subscriptionPlan?.maxProjects ?? 3;\r\n const planName = user?.subscriptionPlan?.displayName || 'Gratuit';\r\n const currentCount = await prisma.project.count({ where: { userId: session.user.id } });\r\n\r\n if (limit !== -1 && currentCount >= limit) {\r\n return NextResponse.json(\r\n { error: `Limite de ${limit} projets atteinte pour le plan ${planName}. Passez au plan supérieur !` },\r\n { status: 403 }\r\n );\r\n }\r\n\r\n const body = await request.json();\r\n\r\n const project = await prisma.project.create({\r\n data: {\r\n title: body.title || 'Nouveau Roman',\r\n author: body.author || session.user.name || 'Auteur',\r\n settings: body.settings || null,\r\n userId: session.user.id,\r\n },\r\n });\r\n\r\n return NextResponse.json(project, { status: 201 });\r\n}\r\n"],"names":[],"mappings":";;;;;;;;AAEA;AACA;AACA;;;;;AAJO,MAAM,UAAU;;;;AAOhB,eAAe;IAClB,MAAM,UAAU,MAAM,IAAA,wKAAI;IAC1B,IAAI,CAAC,SAAS,MAAM,IAAI;QACpB,OAAO,4LAAY,CAAC,IAAI,CAAC;YAAE,OAAO;QAAe,GAAG;YAAE,QAAQ;QAAI;IACtE;IAEA,MAAM,WAAW,MAAM,IAAA,6KAAK,IAAG,OAAO,CAAC,QAAQ,CAAC;QAC5C,OAAO;YAAE,QAAQ,QAAQ,IAAI,CAAC,EAAE;QAAC;QACjC,SAAS;YAAE,WAAW;QAAO;QAC7B,SAAS;YACL,QAAQ;gBAAE,QAAQ;oBAAE,UAAU;oBAAM,UAAU;gBAAK;YAAE;QACzD;IACJ;IAEA,OAAO,4LAAY,CAAC,IAAI,CAAC;AAC7B;AAKO,eAAe,KAAK,OAAoB;IAC3C,MAAM,UAAU,MAAM,IAAA,wKAAI;IAC1B,IAAI,CAAC,SAAS,MAAM,IAAI;QACpB,OAAO,4LAAY,CAAC,IAAI,CAAC;YAAE,OAAO;QAAe,GAAG;YAAE,QAAQ;QAAI;IACtE;IAEA,oBAAoB;IACpB,MAAM,SAAS,IAAA,6KAAK;IACpB,MAAM,OAAO,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC;QACtC,OAAO;YAAE,IAAI,QAAQ,IAAI,CAAC,EAAE;QAAC;QAC7B,SAAS;YAAE,kBAAkB;QAAK;IACtC,IAAW,iDAAiD;IAE5D,MAAM,QAAQ,MAAM,kBAAkB,eAAe;IACrD,MAAM,WAAW,MAAM,kBAAkB,eAAe;IACxD,MAAM,eAAe,MAAM,OAAO,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO;YAAE,QAAQ,QAAQ,IAAI,CAAC,EAAE;QAAC;IAAE;IAErF,IAAI,UAAU,CAAC,KAAK,gBAAgB,OAAO;QACvC,OAAO,4LAAY,CAAC,IAAI,CACpB;YAAE,OAAO,CAAC,UAAU,EAAE,MAAM,+BAA+B,EAAE,SAAS,4BAA4B,CAAC;QAAC,GACpG;YAAE,QAAQ;QAAI;IAEtB;IAEA,MAAM,OAAO,MAAM,QAAQ,IAAI;IAE/B,MAAM,UAAU,MAAM,OAAO,OAAO,CAAC,MAAM,CAAC;QACxC,MAAM;YACF,OAAO,KAAK,KAAK,IAAI;YACrB,QAAQ,KAAK,MAAM,IAAI,QAAQ,IAAI,CAAC,IAAI,IAAI;YAC5C,UAAU,KAAK,QAAQ,IAAI;YAC3B,QAAQ,QAAQ,IAAI,CAAC,EAAE;QAC3B;IACJ;IAEA,OAAO,4LAAY,CAAC,IAAI,CAAC,SAAS;QAAE,QAAQ;IAAI;AACpD"}}]
}

View File

@@ -552,7 +552,7 @@ const Dashboard = ({ user, projects, onSelect, onCreate, onLogout, onPricing, on
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "px-3 py-1 rounded-full bg-indigo-100 text-indigo-700 text-[10px] uppercase font-black tracking-widest",
children: user.subscription.plan
children: user.subscription.planDetails?.displayName || user.subscription.plan
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Dashboard.tsx",
lineNumber: 33,

File diff suppressed because one or more lines are too long

View File

@@ -38,7 +38,7 @@ function ProjectProvider({ value, children }) {
children: children
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/providers/ProjectProvider.tsx",
lineNumber: 26,
lineNumber: 30,
columnNumber: 12
}, this);
}
@@ -3309,7 +3309,7 @@ function ProjectLayout({ children }) {
const pathname = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$navigation$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["usePathname"])();
const projectId = params.id;
const { user, logout, incrementUsage, loading: authLoading } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$providers$2f$AuthProvider$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useAuthContext"])();
const { projects, setCurrentProjectId, updateProject, updateChapter, addChapter } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$hooks$2f$useProjects$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useProjects"])(user);
const { projects, setCurrentProjectId, updateProject, updateChapter, addChapter, createEntity, updateEntity, deleteEntity, deleteProject } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$hooks$2f$useProjects$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useProjects"])(user);
const { chatHistory, isGenerating, sendMessage } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$hooks$2f$useChat$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useChat"])();
const [currentChapterId, setCurrentChapterId] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])('');
const [isExportModalOpen, setIsExportModalOpen] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])(false);
@@ -3346,7 +3346,7 @@ function ProjectLayout({ children }) {
size: 48
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 61,
lineNumber: 62,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
@@ -3357,7 +3357,7 @@ function ProjectLayout({ children }) {
size: 20
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 63,
lineNumber: 64,
columnNumber: 21
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
@@ -3365,19 +3365,19 @@ function ProjectLayout({ children }) {
children: "PlumeIA"
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 64,
lineNumber: 65,
columnNumber: 21
}, this)
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 62,
lineNumber: 63,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 60,
lineNumber: 61,
columnNumber: 13
}, this);
}
@@ -3390,7 +3390,7 @@ function ProjectLayout({ children }) {
size: 48
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 73,
lineNumber: 74,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
@@ -3398,13 +3398,13 @@ function ProjectLayout({ children }) {
children: "Chargement du projet..."
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 74,
lineNumber: 75,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 72,
lineNumber: 73,
columnNumber: 13
}, this);
}
@@ -3442,6 +3442,10 @@ function ProjectLayout({ children }) {
setCurrentChapterId,
updateProject: (updates)=>updateProject(projectId, updates),
updateChapter: (chapterId, data)=>updateChapter(projectId, chapterId, data),
createEntity: (type, data)=>createEntity(projectId, type, data),
updateEntity: (entityId, data)=>updateEntity(projectId, entityId, data),
deleteEntity: (entityId)=>deleteEntity(projectId, entityId),
deleteProject: ()=>deleteProject(projectId),
incrementUsage
},
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$components$2f$layout$2f$EditorShell$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["default"], {
@@ -3491,7 +3495,7 @@ function ProjectLayout({ children }) {
onPrint: ()=>{}
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 135,
lineNumber: 140,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$components$2f$HelpModal$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["default"], {
@@ -3500,19 +3504,19 @@ function ProjectLayout({ children }) {
viewMode: viewMode
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 136,
lineNumber: 141,
columnNumber: 17
}, this),
children
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 103,
lineNumber: 108,
columnNumber: 13
}, this)
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/project/[id]/layout.tsx",
lineNumber: 93,
lineNumber: 94,
columnNumber: 9
}, this);
}

File diff suppressed because one or more lines are too long

View File

@@ -12,45 +12,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__proje
'use client';
;
;
const Pricing = ({ currentPlan, onBack, onSelectPlan })=>{
const plans = [
{
id: 'free',
name: 'Gratuit',
price: '0€',
desc: 'Idéal pour découvrir PlumeIA.',
features: [
'10 actions IA / mois',
'1 projet actif',
'Bible du monde simple'
]
},
{
id: 'pro',
name: 'Auteur Pro',
price: '12€',
desc: 'Pour les écrivains sérieux.',
features: [
'500 actions IA / mois',
'Projets illimités',
'Export Word & EPUB',
'Support prioritaire'
],
popular: true
},
{
id: 'master',
name: 'Maître Plume',
price: '29€',
desc: 'Le summum de l\'écriture IA.',
features: [
'Actions IA illimitées',
'Accès Gemini 3 Pro',
'Bible du monde avancée',
'Outils de révision avancés'
]
}
];
const Pricing = ({ plans, currentPlan, onBack, onSelectPlan, isLoading })=>{
return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "min-h-screen bg-[#eef2ff] py-20 px-8",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
@@ -64,14 +26,14 @@ const Pricing = ({ currentPlan, onBack, onSelectPlan })=>{
size: 20
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 25,
columnNumber: 13
lineNumber: 30,
columnNumber: 11
}, ("TURBOPACK compile-time value", void 0)),
" Retour"
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 24,
lineNumber: 29,
columnNumber: 9
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
@@ -82,131 +44,142 @@ const Pricing = ({ currentPlan, onBack, onSelectPlan })=>{
children: "Choisissez votre destin d'écrivain."
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 28,
columnNumber: 13
lineNumber: 33,
columnNumber: 11
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
className: "text-slate-500",
children: "Passez au plan supérieur pour libérer toute la puissance de l'IA."
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 29,
columnNumber: 13
lineNumber: 34,
columnNumber: 11
}, ("TURBOPACK compile-time value", void 0))
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 27,
lineNumber: 32,
columnNumber: 9
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "grid grid-cols-1 md:grid-cols-3 gap-8",
children: plans.map((p)=>/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: `bg-white rounded-3xl p-8 border transition-all ${p.popular ? 'border-blue-500 shadow-2xl scale-105 z-10' : 'border-indigo-100 shadow-xl'}`,
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "mb-8",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("h4", {
className: "text-xl font-bold text-slate-900 mb-2",
children: p.name
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 35,
columnNumber: 25
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-4xl font-black text-slate-900 mb-2",
children: [
p.price,
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-sm font-normal text-slate-400",
children: "/mois"
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 36,
columnNumber: 91
}, ("TURBOPACK compile-time value", void 0))
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 36,
columnNumber: 25
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
className: "text-sm text-slate-500",
children: p.desc
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 37,
columnNumber: 25
}, ("TURBOPACK compile-time value", void 0))
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 34,
columnNumber: 21
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("ul", {
className: "space-y-4 mb-10",
children: p.features.map((f, i)=>/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("li", {
className: "flex items-center gap-3 text-sm text-slate-700",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-blue-500 bg-blue-50 p-0.5 rounded-full",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$check$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__$3c$export__default__as__Check$3e$__["Check"], {
size: 14
children: [
isLoading && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
className: "text-center col-span-3 py-10",
children: "Chargement des offres..."
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 37,
columnNumber: 25
}, ("TURBOPACK compile-time value", void 0)),
!isLoading && plans.map((p)=>/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: `bg-white rounded-3xl p-8 border transition-all ${p.isPopular ? 'border-blue-500 shadow-2xl scale-105 z-10' : 'border-indigo-100 shadow-xl'}`,
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "mb-8",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("h4", {
className: "text-xl font-bold text-slate-900 mb-2",
children: p.displayName
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 41,
columnNumber: 17
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-4xl font-black text-slate-900 mb-2",
children: [
p.price,
"€",
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-sm font-normal text-slate-400",
children: "/mois"
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 42,
columnNumber: 94
columnNumber: 84
}, ("TURBOPACK compile-time value", void 0))
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 42,
columnNumber: 33
}, ("TURBOPACK compile-time value", void 0)),
f
]
}, i, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 41,
columnNumber: 29
}, ("TURBOPACK compile-time value", void 0)))
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 39,
columnNumber: 21
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("button", {
onClick: ()=>onSelectPlan(p.id),
className: `w-full py-4 rounded-2xl font-black transition-all ${p.id === currentPlan ? 'bg-slate-100 text-slate-400 cursor-default' : p.popular ? 'bg-blue-600 text-white hover:bg-blue-700' : 'bg-slate-900 text-white hover:bg-slate-800'}`,
children: p.id === currentPlan ? 'Plan Actuel' : 'Sélectionner'
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 47,
columnNumber: 21
}, ("TURBOPACK compile-time value", void 0))
]
}, p.id, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 33,
columnNumber: 17
}, ("TURBOPACK compile-time value", void 0)))
}, void 0, false, {
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 42,
columnNumber: 17
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
className: "text-sm text-slate-500",
children: p.description
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 43,
columnNumber: 17
}, ("TURBOPACK compile-time value", void 0))
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 40,
columnNumber: 15
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("ul", {
className: "space-y-4 mb-10",
children: p.features.map((f, i)=>/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("li", {
className: "flex items-center gap-3 text-sm text-slate-700",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-blue-500 bg-blue-50 p-0.5 rounded-full",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$check$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__$3c$export__default__as__Check$3e$__["Check"], {
size: 14
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 48,
columnNumber: 82
}, ("TURBOPACK compile-time value", void 0))
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 48,
columnNumber: 21
}, ("TURBOPACK compile-time value", void 0)),
f
]
}, i, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 47,
columnNumber: 19
}, ("TURBOPACK compile-time value", void 0)))
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 45,
columnNumber: 15
}, ("TURBOPACK compile-time value", void 0)),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("button", {
onClick: ()=>onSelectPlan(p.id),
className: `w-full py-4 rounded-2xl font-black transition-all ${p.id === currentPlan ? 'bg-slate-100 text-slate-400 cursor-default' : p.isPopular ? 'bg-blue-600 text-white hover:bg-blue-700' : 'bg-slate-900 text-white hover:bg-slate-800'}`,
children: p.id === currentPlan ? 'Plan Actuel' : 'Sélectionner'
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 53,
columnNumber: 15
}, ("TURBOPACK compile-time value", void 0))
]
}, p.id, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 39,
columnNumber: 13
}, ("TURBOPACK compile-time value", void 0)))
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 31,
lineNumber: 36,
columnNumber: 9
}, ("TURBOPACK compile-time value", void 0))
]
}, void 0, true, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 23,
lineNumber: 28,
columnNumber: 7
}, ("TURBOPACK compile-time value", void 0))
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx",
lineNumber: 22,
lineNumber: 27,
columnNumber: 5
}, ("TURBOPACK compile-time value", void 0));
};
@@ -238,6 +211,7 @@ __turbopack_context__.s([
()=>PricingPage
]);
var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/Documents/00 - projet/plumeia/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react-jsx-dev-runtime.js [app-ssr] (ecmascript)");
var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/Documents/00 - projet/plumeia/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react.js [app-ssr] (ecmascript)");
var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$components$2f$Pricing$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/Documents/00 - projet/plumeia/src/components/Pricing.tsx [app-ssr] (ecmascript)");
var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$navigation$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/Documents/00 - projet/plumeia/node_modules/next/navigation.js [app-ssr] (ecmascript)");
var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$providers$2f$AuthProvider$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/Documents/00 - projet/plumeia/src/providers/AuthProvider.tsx [app-ssr] (ecmascript)");
@@ -246,16 +220,32 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__proje
;
;
;
;
function PricingPage() {
const router = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$navigation$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useRouter"])();
const { user } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$providers$2f$AuthProvider$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useAuthContext"])();
const [plans, setPlans] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])([]);
const [isLoading, setIsLoading] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])(true);
(0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useEffect"])(()=>{
fetch('/api/plans', {
cache: 'no-store'
}).then((res)=>res.json()).then((data)=>{
setPlans(data);
setIsLoading(false);
}).catch((err)=>{
console.error(err);
setIsLoading(false);
});
}, []);
return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$src$2f$components$2f$Pricing$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["default"], {
plans: plans,
isLoading: isLoading,
currentPlan: user?.subscription.plan || 'free',
onBack: ()=>router.push(user ? '/dashboard' : '/'),
onSelectPlan: ()=>router.push(user ? '/checkout' : '/login')
}, void 0, false, {
fileName: "[project]/Documents/00 - projet/plumeia/src/app/pricing/page.tsx",
lineNumber: 12,
lineNumber: 29,
columnNumber: 9
}, this);
}

File diff suppressed because one or more lines are too long

View File

@@ -187,20 +187,6 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__proje
;
;
;
const PLAN_LIMITS = {
free: {
aiActions: 100,
projects: 3
},
pro: {
aiActions: 5000,
projects: 20
},
master: {
aiActions: 999999,
projects: 999
}
};
const useAuth = ()=>{
const { data: session, status } = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2d$auth$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useSession"])();
const [user, setUser] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])(null);
@@ -208,9 +194,16 @@ const useAuth = ()=>{
// Fetch real profile from DB when session is available
(0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$00__$2d$__projet$2f$plumeia$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useEffect"])(()=>{
if (session?.user?.id) {
fetch('/api/user/profile').then((res)=>res.json()).then((dbUser)=>{
const plan = dbUser.plan || 'free';
const limits = PLAN_LIMITS[plan] || PLAN_LIMITS.free;
fetch('/api/user/profile', {
cache: 'no-store'
}).then((res)=>res.json()).then((dbUser)=>{
const planId = dbUser.plan || 'free';
const planDetails = dbUser.planDetails || {
id: 'free',
displayName: 'Gratuit',
maxAiActions: 100,
maxProjects: 3
};
setUser({
id: dbUser.id,
email: dbUser.email,
@@ -218,14 +211,15 @@ const useAuth = ()=>{
avatar: dbUser.avatar,
bio: dbUser.bio,
subscription: {
plan,
plan: planId,
planDetails: planDetails,
startDate: new Date(dbUser.createdAt).getTime(),
status: 'active'
},
usage: {
aiActionsCurrent: dbUser.aiActionsUsed || 0,
aiActionsLimit: limits.aiActions,
projectsLimit: limits.projects
aiActionsLimit: planDetails.maxAiActions,
projectsLimit: planDetails.maxProjects
},
preferences: {
theme: 'light',

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
self.__NEXT_FONT_MANIFEST="{\n \"app\": {\n \"[project]/Documents/00 - projet/plumeia/src/app/dashboard/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\n \"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2\"\n ],\n \"[project]/Documents/00 - projet/plumeia/src/app/login/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\n \"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2\"\n ],\n \"[project]/Documents/00 - projet/plumeia/src/app/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\n \"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2\"\n ],\n \"[project]/Documents/00 - projet/plumeia/src/app/project/[id]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\n \"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2\"\n ]\n },\n \"appUsingSizeAdjust\": true,\n \"pages\": {},\n \"pagesUsingSizeAdjust\": false\n}"
self.__NEXT_FONT_MANIFEST="{\n \"app\": {\n \"[project]/Documents/00 - projet/plumeia/src/app/dashboard/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\n \"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2\"\n ],\n \"[project]/Documents/00 - projet/plumeia/src/app/login/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\n \"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2\"\n ],\n \"[project]/Documents/00 - projet/plumeia/src/app/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\n \"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2\"\n ],\n \"[project]/Documents/00 - projet/plumeia/src/app/project/[id]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\n \"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2\"\n ],\n \"[project]/Documents/00 - projet/plumeia/src/app/project/[id]/world/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\n \"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2\"\n ]\n },\n \"appUsingSizeAdjust\": true,\n \"pages\": {},\n \"pagesUsingSizeAdjust\": false\n}"

View File

@@ -15,6 +15,10 @@
"[project]/Documents/00 - projet/plumeia/src/app/project/[id]/page": [
"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2",
"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2"
],
"[project]/Documents/00 - projet/plumeia/src/app/project/[id]/world/page": [
"static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2",
"static/media/248e1dc0efc99276-s.p.8a6b2436.woff2"
]
},
"appUsingSizeAdjust": true,