Files
portfolio/vite.config.ts
Patrick Lambino 37321c19ed last fix
2026-04-01 20:59:34 +08:00

109 lines
5.1 KiB
TypeScript

import path from "path"
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'
import { Resend } from 'resend'
// https://vite.dev/config/
export default defineConfig(({ mode }) => {
// Load env file based on `mode` in the current working directory.
// Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
const env = loadEnv(mode, process.cwd(), '')
const resend = new Resend(env.RESEND_API_KEY)
return {
plugins: [
react(),
{
name: 'resend-api-middleware',
configureServer(server) {
server.middlewares.use(async (req, res, next) => {
if (req.url === '/api/send-email' && req.method === 'POST') {
let body = ''
req.on('data', (chunk: Buffer) => {
body += chunk.toString()
})
req.on('end', async () => {
try {
const { name, email, subject, message } = JSON.parse(body)
const { data, error } = await resend.emails.send({
from: 'Portfolio Contact <onboarding@resend.dev>',
to: 'lambino.patrick.competente@gmail.com',
subject: `[Portfolio Dev] ${subject}`,
replyTo: email,
html: `
<div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; padding: 40px; background-color: #ffffff; color: #000000; border: 1px solid #e5e7eb; border-radius: 12px; max-width: 600px; margin: 0 auto; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);">
<div style="border-bottom: 2px solid #000000; padding-bottom: 20px; margin-bottom: 30px;">
<h1 style="margin: 0; font-size: 24px; font-weight: 800; letter-spacing: -0.025em; text-transform: uppercase;">New Connection</h1>
<p style="margin: 5px 0 0 0; color: #6b7280; font-size: 14px;">Incoming message from your portfolio website (Local Dev)</p>
</div>
<div style="margin-bottom: 30px;">
<div style="margin-bottom: 15px;">
<span style="display: block; font-size: 12px; font-weight: 600; text-transform: uppercase; color: #9ca3af; margin-bottom: 4px;">From</span>
<p style="margin: 0; font-size: 16px; font-weight: 500;">${name} &lt;${email}&gt;</p>
</div>
<div style="margin-bottom: 15px;">
<span style="display: block; font-size: 12px; font-weight: 600; text-transform: uppercase; color: #9ca3af; margin-bottom: 4px;">Subject</span>
<p style="margin: 0; font-size: 16px; font-weight: 500;">${subject}</p>
</div>
</div>
<div style="background-color: #f9fafb; padding: 25px; border-radius: 8px; border-left: 4px solid #000000;">
<span style="display: block; font-size: 12px; font-weight: 600; text-transform: uppercase; color: #9ca3af; margin-bottom: 10px;">Message Content</span>
<p style="margin: 0; font-size: 16px; line-height: 1.6; white-space: pre-wrap; color: #1f2937;">${message}</p>
</div>
<div style="margin-top: 40px; padding-top: 20px; border-top: 1px solid #f3f4f6; text-align: center;">
<p style="margin: 0; font-size: 12px; color: #9ca3af;">
This email was automatically generated and sent from your portfolio contact form (Local Dev).
</p>
</div>
</div>
`,
})
res.setHeader('Content-Type', 'application/json')
if (error) {
res.statusCode = 400
res.end(JSON.stringify({ error }))
} else {
res.statusCode = 200
res.end(JSON.stringify({ success: true, data }))
}
} catch (err: any) {
res.statusCode = 500
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify({ error: 'Internal Server Error', message: err.message }))
}
})
} else {
next()
}
})
}
}
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
server: {
// Use undefined origin in development to allow loading from localhost.
origin: mode === 'development' ? undefined : 'https://portfolio.patricklmbn.online',
allowedHosts: true,
host: true,
port: 5412,
strictPort: true,
cors: true,
hmr: {
// Use localhost for HMR when in development mode for better reliability.
host: mode === 'development' ? 'localhost' : 'portfolio.patricklmbn.online',
clientPort: mode === 'development' ? 5412 : 443,
}
}
}
})