Update Dockerfile and Next.js configuration; enhance contact components
Some checks failed
CI/CD Pipeline / test (push) Successful in 10m55s
CI/CD Pipeline / security (push) Failing after 5m20s
CI/CD Pipeline / build (push) Has been skipped
CI/CD Pipeline / deploy (push) Has been skipped

- Modify Dockerfile to install curl without recommended packages for a leaner image.
- Update Next.js configuration to set outputFileTracingRoot for better Docker compatibility.
- Revise contact components to improve messaging and clarity, changing "Get In Touch" to "Contact Me" and enhancing descriptions for collaboration opportunities.
- Clean up Prisma schema by removing unnecessary comments and restructuring the Project model for clarity.
This commit is contained in:
2025-09-11 10:13:35 +02:00
parent 09d925745d
commit 519ca43168
6 changed files with 84 additions and 99 deletions

View File

@@ -4,7 +4,7 @@ FROM node:20 AS base
# Install dependencies only when needed # Install dependencies only when needed
FROM base AS deps FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*
WORKDIR /app WORKDIR /app
# Install dependencies based on the preferred package manager # Install dependencies based on the preferred package manager

View File

@@ -93,10 +93,10 @@ const Contact = () => {
className="text-center mb-16" className="text-center mb-16"
> >
<h2 className="text-4xl md:text-5xl font-bold mb-6 gradient-text"> <h2 className="text-4xl md:text-5xl font-bold mb-6 gradient-text">
Get In Touch Contact Me
</h2> </h2>
<p className="text-xl text-gray-400 max-w-2xl mx-auto"> <p className="text-xl text-gray-400 max-w-2xl mx-auto">
Have a project in mind or want to collaborate? I would love to hear from you! Interested in working together or have questions about my projects? Feel free to reach out!
</p> </p>
</motion.div> </motion.div>
@@ -111,11 +111,11 @@ const Contact = () => {
> >
<div> <div>
<h3 className="text-2xl font-bold text-white mb-6"> <h3 className="text-2xl font-bold text-white mb-6">
Let&apos;s Connect Get In Touch
</h3> </h3>
<p className="text-gray-400 leading-relaxed"> <p className="text-gray-400 leading-relaxed">
I&apos;m always open to discussing new opportunities, interesting projects, I&apos;m always available to discuss new opportunities, interesting projects,
or just having a chat about technology and innovation. or simply chat about technology and innovation.
</p> </p>
</div> </div>

View File

@@ -216,7 +216,7 @@ const Hero = () => {
whileTap={{ scale: 0.95 }} whileTap={{ scale: 0.95 }}
className="px-8 py-4 text-lg font-semibold border-2 border-gray-600 text-gray-300 hover:text-white hover:border-gray-500 rounded-lg transition-all duration-200" className="px-8 py-4 text-lg font-semibold border-2 border-gray-600 text-gray-300 hover:text-white hover:border-gray-500 rounded-lg transition-all duration-200"
> >
Get In Touch Contact Me
</motion.a> </motion.a>
</motion.div> </motion.div>

View File

@@ -42,7 +42,7 @@ export const metadata: Metadata = {
authors: [{name: "Dennis Konkol", url: "https://dk0.dev"}], authors: [{name: "Dennis Konkol", url: "https://dk0.dev"}],
openGraph: { openGraph: {
title: "Dennis Konkol | Portfolio", title: "Dennis Konkol | Portfolio",
description: "Explore my projects and get in touch!", description: "Explore my projects and contact me for collaboration opportunities!",
url: "https://dk0.dev", url: "https://dk0.dev",
siteName: "Dennis Konkol Portfolio", siteName: "Dennis Konkol Portfolio",
images: [ images: [

View File

@@ -8,6 +8,7 @@ dotenv.config({ path: path.resolve(__dirname, '.env') });
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
// Enable standalone output for Docker // Enable standalone output for Docker
output: 'standalone', output: 'standalone',
outputFileTracingRoot: path.join(__dirname, '../../'),
// Optimize for production // Optimize for production
compress: true, compress: true,
@@ -42,8 +43,7 @@ const nextConfig: NextConfig = {
minimumCacheTTL: 60, minimumCacheTTL: 60,
}, },
// Disable static generation for dynamic routes // Dynamic routes are handled automatically by Next.js
generateStaticParams: false,
// Add cache-busting headers // Add cache-busting headers
async headers() { async headers() {

View File

@@ -1,6 +1,3 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client { generator client {
provider = "prisma-client-js" provider = "prisma-client-js"
} }
@@ -11,46 +8,37 @@ datasource db {
} }
model Project { model Project {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
title String @db.VarChar(255) title String @db.VarChar(255)
description String @db.Text description String
content String @db.Text content String
tags String[] @default([]) tags String[] @default([])
featured Boolean @default(false) featured Boolean @default(false)
category String @db.VarChar(100) category String @db.VarChar(100)
date String @db.VarChar(10) date String @db.VarChar(10)
github String? @db.VarChar(500) github String? @db.VarChar(500)
live String? @db.VarChar(500) live String? @db.VarChar(500)
published Boolean @default(true) published Boolean @default(true)
imageUrl String? @db.VarChar(500) imageUrl String? @db.VarChar(500)
metaDescription String? @db.Text metaDescription String?
keywords String? @db.Text keywords String?
ogImage String? @db.VarChar(500) ogImage String? @db.VarChar(500)
schema Json? schema Json?
difficulty Difficulty @default(INTERMEDIATE)
timeToComplete String? @db.VarChar(100)
technologies String[] @default([])
challenges String[] @default([])
lessonsLearned String[] @default([])
futureImprovements String[] @default([])
demoVideo String? @db.VarChar(500)
screenshots String[] @default([])
colorScheme String @default("Dark") @db.VarChar(100)
accessibility Boolean @default(true)
performance Json @default("{\"loadTime\": \"1.5s\", \"bundleSize\": \"50KB\", \"lighthouse\": 90}")
analytics Json @default("{\"likes\": 0, \"views\": 0, \"shares\": 0}")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// Advanced features
difficulty Difficulty @default(INTERMEDIATE)
timeToComplete String? @db.VarChar(100)
technologies String[] @default([])
challenges String[] @default([])
lessonsLearned String[] @default([])
futureImprovements String[] @default([])
demoVideo String? @db.VarChar(500)
screenshots String[] @default([])
colorScheme String @db.VarChar(100) @default("Dark")
accessibility Boolean @default(true)
// Performance metrics
performance Json @default("{\"lighthouse\": 90, \"bundleSize\": \"50KB\", \"loadTime\": \"1.5s\"}")
// Analytics
analytics Json @default("{\"views\": 0, \"likes\": 0, \"shares\": 0}")
// Timestamps
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// Indexes for performance
@@index([category]) @@index([category])
@@index([featured]) @@index([featured])
@@index([published]) @@index([published])
@@ -59,6 +47,49 @@ model Project {
@@index([tags]) @@index([tags])
} }
model PageView {
id Int @id @default(autoincrement())
projectId Int? @map("project_id")
page String @db.VarChar(100)
ip String? @db.VarChar(45)
userAgent String? @map("user_agent")
referrer String? @db.VarChar(500)
timestamp DateTime @default(now())
@@index([projectId])
@@index([timestamp])
@@index([page])
}
model UserInteraction {
id Int @id @default(autoincrement())
projectId Int @map("project_id")
type InteractionType
ip String? @db.VarChar(45)
userAgent String? @map("user_agent")
timestamp DateTime @default(now())
@@index([projectId])
@@index([type])
@@index([timestamp])
}
model Contact {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
email String @db.VarChar(255)
subject String @db.VarChar(500)
message String
responded Boolean @default(false)
responseTemplate String? @map("response_template") @db.VarChar(50)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([email])
@@index([responded])
@@index([createdAt])
}
enum Difficulty { enum Difficulty {
BEGINNER BEGINNER
INTERMEDIATE INTERMEDIATE
@@ -66,55 +97,9 @@ enum Difficulty {
EXPERT EXPERT
} }
// Analytics tracking
model PageView {
id Int @id @default(autoincrement())
projectId Int? @map("project_id")
page String @db.VarChar(100)
ip String? @db.VarChar(45)
userAgent String? @db.Text @map("user_agent")
referrer String? @db.VarChar(500)
timestamp DateTime @default(now())
@@index([projectId])
@@index([timestamp])
@@index([page])
}
// User interactions
model UserInteraction {
id Int @id @default(autoincrement())
projectId Int @map("project_id")
type InteractionType
ip String? @db.VarChar(45)
userAgent String? @db.Text @map("user_agent")
timestamp DateTime @default(now())
@@index([projectId])
@@index([type])
@@index([timestamp])
}
enum InteractionType { enum InteractionType {
LIKE LIKE
SHARE SHARE
BOOKMARK BOOKMARK
COMMENT COMMENT
} }
// Contact form submissions
model Contact {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
email String @db.VarChar(255)
subject String @db.VarChar(500)
message String @db.Text
responded Boolean @default(false)
responseTemplate String? @db.VarChar(50) @map("response_template")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([email])
@@index([responded])
@@index([createdAt])
}