fix: remove pg adapter, use standard PrismaClient - add prisma db push to Dockerfile CMD
This commit is contained in:
+8
-1
@@ -21,9 +21,15 @@ FROM base AS runner
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
RUN apk add --no-cache libc6-compat
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
|
||||
# node_modules for prisma CLI at runtime
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/prisma ./prisma
|
||||
COPY --from=builder /app/prisma.config.ts ./prisma.config.ts
|
||||
RUN mkdir .next && chown nextjs:nodejs .next
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
@@ -31,4 +37,5 @@ USER nextjs
|
||||
EXPOSE 3000
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME="0.0.0.0"
|
||||
CMD ["node", "server.js"]
|
||||
# Push schema (idempotent, safe to run on every start) then start server
|
||||
CMD sh -c "npx prisma db push --skip-generate 2>&1 | tail -5 && node server.js"
|
||||
|
||||
@@ -1,34 +1,24 @@
|
||||
import { Pool } from 'pg';
|
||||
import { PrismaPg } from '@prisma/adapter-pg';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const connectionString =
|
||||
process.env.DATABASE_URL ||
|
||||
'postgres://postgres:mBTWE2cDKGExtpktguD3HPe8y9Xr9kWFYdxV4WHQKISLLGoBAS4UdtfSCfXwvPpq@65.109.236.58:37298/postgres';
|
||||
|
||||
const pool = new Pool({ connectionString });
|
||||
const adapter = new PrismaPg(pool);
|
||||
|
||||
const globalForPrisma = globalThis as unknown as {
|
||||
prisma: PrismaClient | undefined;
|
||||
};
|
||||
|
||||
function getPrismaClient(): PrismaClient {
|
||||
if (process.env.NODE_ENV !== 'production' && globalForPrisma.prisma) {
|
||||
// Ensure all models (category, cheatsheet, prompt) exist on cached client
|
||||
if (
|
||||
(globalForPrisma.prisma as any).category &&
|
||||
(globalForPrisma.prisma as any).cheatsheet &&
|
||||
(globalForPrisma.prisma as any).prompt
|
||||
) {
|
||||
return globalForPrisma.prisma;
|
||||
}
|
||||
function createPrismaClient() {
|
||||
const databaseUrl = process.env.DATABASE_URL;
|
||||
|
||||
if (!databaseUrl) {
|
||||
console.error('[DB] DATABASE_URL is not set! Using fallback connection string.');
|
||||
}
|
||||
const client = new PrismaClient({ adapter });
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
globalForPrisma.prisma = client;
|
||||
}
|
||||
return client;
|
||||
|
||||
return new PrismaClient({
|
||||
log: process.env.NODE_ENV === 'development' ? ['error', 'warn'] : ['error'],
|
||||
});
|
||||
}
|
||||
|
||||
export const db = getPrismaClient();
|
||||
export const db =
|
||||
globalForPrisma.prisma ?? createPrismaClient();
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
globalForPrisma.prisma = db;
|
||||
}
|
||||
|
||||
Generated
+2
-196
@@ -9,7 +9,6 @@
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@base-ui/react": "^1.5.0",
|
||||
"@prisma/adapter-pg": "^7.9.0",
|
||||
"@prisma/client": "^7.8.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"cloudinary": "^2.10.0",
|
||||
@@ -20,7 +19,6 @@
|
||||
"next": "16.2.9",
|
||||
"next-auth": "^5.0.0-beta.31",
|
||||
"next-intl": "^4.13.0",
|
||||
"pg": "^8.22.0",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"shadcn": "^4.11.0",
|
||||
@@ -30,7 +28,6 @@
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/pg": "^8.20.0",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"eslint": "^9",
|
||||
@@ -2251,18 +2248,6 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/adapter-pg": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/adapter-pg/-/adapter-pg-7.9.0.tgz",
|
||||
"integrity": "sha512-kPYuFvNTlqnaFf2UpXBBG3ycTT3PL76uSZtLFBEwDytjMMUW8ZHrsb9cSNIarzdPW5EXWmBOeOq9/MVjMtbWkA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/driver-adapter-utils": "7.9.0",
|
||||
"@types/pg": "^8.16.0",
|
||||
"pg": "^8.16.3",
|
||||
"postgres-array": "3.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/client": {
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-7.8.0.tgz",
|
||||
@@ -2339,21 +2324,6 @@
|
||||
"zeptomatch": "2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/driver-adapter-utils": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/driver-adapter-utils/-/driver-adapter-utils-7.9.0.tgz",
|
||||
"integrity": "sha512-fFXujitfMyjk3kOd1Tbs5FXBm6i2OWwEhaP5lHgkUM99jHpPEQwCWj+z/WKPFq6EDMThE1zGzSlVegtR0Pmu2w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "7.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/driver-adapter-utils/node_modules/@prisma/debug": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-7.9.0.tgz",
|
||||
"integrity": "sha512-i0KdVQuKUE6N9NloHs+sUNAk2c9svR3myBndQbA3BoeoArsSpwtNgTdHZL+wBtCLCcdS2OOC/PKhgTe36jkF5A==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/engines": {
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-7.8.0.tgz",
|
||||
@@ -3275,22 +3245,12 @@
|
||||
"version": "20.19.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz",
|
||||
"integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/pg": {
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.20.0.tgz",
|
||||
"integrity": "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"pg-protocol": "*",
|
||||
"pg-types": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.2.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
|
||||
@@ -9058,104 +9018,6 @@
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pg": {
|
||||
"version": "8.22.0",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.22.0.tgz",
|
||||
"integrity": "sha512-8wih1vVIBMxoUM2oB4soJsD9tDnDpLv4OXBJ+EJzFsvycD+lfyIreC2gGHq78f8jbLLt+bvlPTFdFZfJkOuzAA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pg-connection-string": "^2.14.0",
|
||||
"pg-pool": "^3.14.0",
|
||||
"pg-protocol": "^1.15.0",
|
||||
"pg-types": "2.2.0",
|
||||
"pgpass": "1.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"pg-cloudflare": "^1.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"pg-native": ">=3.0.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"pg-native": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pg-cloudflare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz",
|
||||
"integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/pg-connection-string": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.0.tgz",
|
||||
"integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pg-int8": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-pool": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz",
|
||||
"integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"pg": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-protocol": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.15.0.tgz",
|
||||
"integrity": "sha512-cq9sECI5s0+uPUXjbz8ioyPJni6RzsRib0US67i5IoTZKw8fNeYlVE7u8F4dG7vEJJtc5wdD1K189lCCUwqWTQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pg-types": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
|
||||
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pg-int8": "1.0.1",
|
||||
"postgres-array": "~2.0.0",
|
||||
"postgres-bytea": "~1.0.0",
|
||||
"postgres-date": "~1.0.4",
|
||||
"postgres-interval": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-types/node_modules/postgres-array": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
||||
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/pgpass": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
|
||||
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"split2": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
@@ -9266,45 +9128,6 @@
|
||||
"url": "https://github.com/sponsors/porsager"
|
||||
}
|
||||
},
|
||||
"node_modules/postgres-array": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.4.tgz",
|
||||
"integrity": "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/postgres-bytea": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz",
|
||||
"integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postgres-date": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
|
||||
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postgres-interval": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
|
||||
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"xtend": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/powershell-utils": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
|
||||
@@ -10279,15 +10102,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/split2": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/sqlstring": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
|
||||
@@ -10976,6 +10790,7 @@
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unicorn-magic": {
|
||||
@@ -11300,15 +11115,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@base-ui/react": "^1.5.0",
|
||||
"@prisma/adapter-pg": "^7.9.0",
|
||||
"@prisma/client": "^7.8.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"cloudinary": "^2.10.0",
|
||||
@@ -21,7 +20,6 @@
|
||||
"next": "16.2.9",
|
||||
"next-auth": "^5.0.0-beta.31",
|
||||
"next-intl": "^4.13.0",
|
||||
"pg": "^8.22.0",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"shadcn": "^4.11.0",
|
||||
@@ -31,7 +29,6 @@
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/pg": "^8.20.0",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"eslint": "^9",
|
||||
|
||||
+12
-17
@@ -1,12 +1,6 @@
|
||||
import { Pool } from 'pg';
|
||||
import { PrismaPg } from '@prisma/adapter-pg';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const connectionString = process.env.DATABASE_URL || 'postgres://postgres:mBTWE2cDKGExtpktguD3HPe8y9Xr9kWFYdxV4WHQKISLLGoBAS4UdtfSCfXwvPpq@65.109.236.58:37298/postgres';
|
||||
|
||||
const pool = new Pool({ connectionString });
|
||||
const adapter = new PrismaPg(pool);
|
||||
const db = new PrismaClient({ adapter });
|
||||
const db = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log('Seeding PostgreSQL database...');
|
||||
@@ -47,19 +41,19 @@ async function main() {
|
||||
fileName: 'app/actions.ts',
|
||||
language: 'typescript',
|
||||
description: 'Server Action function handling form submission',
|
||||
code: `'use server'\n\nimport { revalidatePath } from 'next/cache';\n\nexport async function submitProjectIdea(formData: FormData) {\n const title = formData.get('title') as string;\n const description = formData.get('description') as string;\n\n if (!title || title.length < 3) {\n return { success: false, error: 'Title must be at least 3 characters long.' };\n }\n\n // Database insertion simulation\n console.log('Saved Idea:', { title, description });\n\n revalidatePath('/ideas');\n return { success: true, message: 'Your idea was submitted successfully!' };\n}`
|
||||
code: `'use server'\n\nimport { revalidatePath } from 'next/cache';\n\nexport async function submitProjectIdea(formData: FormData) {\n const title = formData.get('title') as string;\n const description = formData.get('description') as string;\n\n if (!title || title.length < 3) {\n return { success: false, error: 'Title must be at least 3 characters long.' };\n }\n\n console.log('Saved Idea:', { title, description });\n\n revalidatePath('/ideas');\n return { success: true, message: 'Your idea was submitted successfully!' };\n}`
|
||||
},
|
||||
{
|
||||
fileName: 'proxy.ts',
|
||||
language: 'typescript',
|
||||
description: 'Next.js 16 proxy configuration (middleware alternative)',
|
||||
code: `import { NextRequest, NextResponse } from 'next/server';\nimport createMiddleware from 'next-intl/middleware';\nimport { routing } from '@/i18n/routing';\n\nconst intlMiddleware = createMiddleware(routing);\n\nexport async function proxy(request: NextRequest) {\n if (request.nextUrl.pathname.includes('/admin')) {\n // Auth check logic\n }\n return intlMiddleware(request);\n}\n\nexport const config = {\n matcher: ['/((?!api|_next|_vercel|.*\\\\..*).*)']\n};`
|
||||
code: `import { NextRequest, NextResponse } from 'next/server';\nimport createMiddleware from 'next-intl/middleware';\nimport { routing } from '@/i18n/routing';\n\nconst intlMiddleware = createMiddleware(routing);\n\nexport async function proxy(request: NextRequest) {\n if (request.nextUrl.pathname.includes('/admin')) {\n // Auth check logic\n }\n return intlMiddleware(request);\n}\n\nexport const config = {\n matcher: ['/((?!api|_next|_vercel|.*\\\\..*).*)'],\n};`
|
||||
},
|
||||
{
|
||||
fileName: 'components/IdeaForm.tsx',
|
||||
language: 'tsx',
|
||||
description: 'Client Form component using useActionState',
|
||||
code: `'use client';\n\nimport { useActionState } from 'react';\nimport { submitProjectIdea } from '@/app/actions';\n\nexport function IdeaForm() {\n const [state, formAction, isPending] = useActionState(submitProjectIdea, null);\n\n return (\n <form action={formAction} className="space-y-4 max-w-md p-6 bg-slate-900 rounded-xl border border-slate-800">\n <h3 className="text-xl font-bold text-white">Add New Idea</h3>\n \n <div>\n <label className="block text-sm text-slate-400 mb-1">Idea Title</label>\n <input name="title" required className="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white" />\n </div>\n\n <button disabled={isPending} className="w-full py-2.5 bg-red-600 hover:bg-red-500 text-white rounded-lg font-medium">\n {isPending ? 'Submitting...' : 'Share Idea'}\n </button>\n\n {state?.error && <p className="text-red-400 text-sm">{state.error}</p>}\n {state?.success && <p className="text-emerald-400 text-sm">{state.message}</p>}\n </form>\n );\n}`
|
||||
code: `'use client';\n\nimport { useActionState } from 'react';\nimport { submitProjectIdea } from '@/app/actions';\n\nexport function IdeaForm() {\n const [state, formAction, isPending] = useActionState(submitProjectIdea, null);\n\n return (\n <form action={formAction} className="space-y-4 max-w-md p-6 bg-slate-900 rounded-xl border border-slate-800">\n <h3 className="text-xl font-bold text-white">Add New Idea</h3>\n <div>\n <label className="block text-sm text-slate-400 mb-1">Idea Title</label>\n <input name="title" required className="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white" />\n </div>\n <button disabled={isPending} className="w-full py-2.5 bg-red-600 hover:bg-red-500 text-white rounded-lg font-medium">\n {isPending ? 'Submitting...' : 'Share Idea'}\n </button>\n {state?.error && <p className="text-red-400 text-sm">{state.error}</p>}\n {state?.success && <p className="text-emerald-400 text-sm">{state.message}</p>}\n </form>\n );\n}`
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -112,9 +106,9 @@ async function main() {
|
||||
likesCount: 1450,
|
||||
summary: 'Build an autonomous AI agent in Python that crawls web data, summarizes tech news, and generates structured reports automatically.',
|
||||
notesMarkdown: [
|
||||
'🤖 AI agents are configured with role, goal, and backstory.',
|
||||
'🤖 Equip agents with real-time web search using Serper API or Tavily.',
|
||||
'🤖 Gemini 1.5 Flash provides high token throughput with minimal latency.'
|
||||
'AI agents are configured with role, goal, and backstory.',
|
||||
'Equip agents with real-time web search using Serper API or Tavily.',
|
||||
'Gemini 1.5 Flash provides high token throughput with minimal latency.'
|
||||
],
|
||||
codeSnippets: {
|
||||
create: [
|
||||
@@ -167,9 +161,9 @@ async function main() {
|
||||
likesCount: 2600,
|
||||
summary: 'Learn CSS-first configuration in Tailwind CSS v4 using @import "tailwindcss";, OKLCH color spaces, and advanced glassmorphism component design.',
|
||||
notesMarkdown: [
|
||||
'🎨 In Tailwind v4, @theme directive in globals.css replaces tailwind.config.js.',
|
||||
'🎨 OKLCH color space ensures consistent perceived contrast across light and dark modes.',
|
||||
'🎨 @custom-variant dark provides flexible dark mode scoping.'
|
||||
'In Tailwind v4, @theme directive in globals.css replaces tailwind.config.js.',
|
||||
'OKLCH color space ensures consistent perceived contrast across light and dark modes.',
|
||||
'@custom-variant dark provides flexible dark mode scoping.'
|
||||
],
|
||||
codeSnippets: {
|
||||
create: [
|
||||
@@ -252,6 +246,7 @@ async function main() {
|
||||
description: 'System prompt to instruct AI agents to build production-ready Next.js 16 App Router code with Server Actions and Prisma.',
|
||||
content: `You are a Senior Next.js 16 Architect. Always use TypeScript strict mode, App Router, proxy.ts for middleware, Server Actions with Zod validation, and Prisma ORM. Never write client components unless interactivity (onClick, useState) is required.`,
|
||||
tags: ['Next.js', 'System Prompt', 'AI Architecture'],
|
||||
isOpen: false,
|
||||
}
|
||||
});
|
||||
|
||||
@@ -263,6 +258,7 @@ async function main() {
|
||||
description: 'Instructs AI to design modern dark-mode interfaces with Tailwind CSS v4, subtle glows, and micro-animations.',
|
||||
content: `Act as a Lead UI/UX Engineer specializing in sleek dark mode interfaces. Use HSL/OKLCH color palettes, slate-950 backgrounds, red-500/10 glows, rounded-2xl containers, and Framer Motion micro-interactions. Avoid generic colors or white backgrounds.`,
|
||||
tags: ['UI/UX', 'Tailwind CSS', 'Design System'],
|
||||
isOpen: false,
|
||||
}
|
||||
});
|
||||
|
||||
@@ -276,5 +272,4 @@ main()
|
||||
})
|
||||
.finally(async () => {
|
||||
await db.$disconnect();
|
||||
await pool.end();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user