feat: add multi-user admin panel and featured partners toggle on home page

This commit is contained in:
AyrisAI
2026-05-17 13:48:05 +03:00
parent 36e98a3883
commit 0504f12f5b
29 changed files with 1110 additions and 182 deletions

View File

@@ -1,6 +1,9 @@
'use server'
import { cache } from 'react';
import sql from '@/lib/db';
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
// Vercel Best Practice: server-cache-react - Deduplicate data fetching per request
export const getSettings = cache(async function() {
@@ -40,16 +43,58 @@ export async function submitLead(formData: {
projectType: string;
message: string;
}) {
const fullName = `${formData.firstName} ${formData.lastName}`;
console.log(`[Lead] Submitting lead for ${fullName}...`);
try {
const fullName = `${formData.firstName} ${formData.lastName}`;
// 1. Save to Database First
await sql`
INSERT INTO leads (full_name, email, service_type, message, status)
VALUES (${fullName}, ${formData.email}, ${formData.projectType}, ${formData.message}, 'new')
`;
console.log(`[Lead] Successfully saved to database.`);
// 2. Try sending email in a separate block
try {
const settings = await getSettings();
const destEmail = settings?.contact_email || 'ayrisdev@gmail.com';
console.log(`[Lead] Attempting to send notification to ${destEmail}...`);
const emailResult = await resend.emails.send({
from: 'Muğla Dijital <onboarding@resend.dev>',
to: destEmail,
subject: `Yeni Mesaj: ${fullName} - ${formData.projectType}`,
html: `
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #eee;">
<h2 style="color: #000; border-bottom: 2px solid #ff0000; padding-bottom: 10px;">Yeni İletişim Formu Mesajı</h2>
<p><strong>Gönderen:</strong> ${fullName}</p>
<p><strong>E-posta:</strong> ${formData.email}</p>
<p><strong>Hizmet:</strong> ${formData.projectType}</p>
<p><strong>Mesaj:</strong></p>
<div style="background: #f9f9f9; padding: 15px; border-radius: 5px;">
${formData.message.replace(/\n/g, '<br/>')}
</div>
<hr style="margin-top: 30px; border: 0; border-top: 1px solid #eee;" />
<p style="font-size: 12px; color: #999;">Bu mesaj Muğla Dijital web sitesi üzerinden gönderilmiştir.</p>
</div>
`
});
if (emailResult.error) {
console.error(`[Lead] Resend Error:`, emailResult.error);
} else {
console.log(`[Lead] Email sent successfully:`, emailResult.data?.id);
}
} catch (emailErr) {
// We don't want to fail the whole action if only email fails
console.error(`[Lead] Email sending failed but DB record was saved:`, emailErr);
}
return { success: true };
} catch (error) {
console.error('Error submitting lead:', error);
return { error: 'Failed to submit' };
console.error('[Lead] Critical Error submitting lead:', error);
return { error: 'Form gönderilirken bir hata oluştu. Lütfen teknik ekiple iletişime geçin.' };
}
}
export async function getPartners() {
@@ -70,6 +115,44 @@ export async function getPartners() {
}
}
export async function getFeaturedPartners() {
try {
// Try to fetch featured partners (max 5)
const featured = await sql`
SELECT p.*, (
SELECT slug FROM projects
WHERE LOWER(TRIM(p.name)) LIKE '%' || LOWER(TRIM(title)) || '%'
OR LOWER(TRIM(title)) LIKE '%' || LOWER(TRIM(p.name)) || '%'
LIMIT 1
) as project_slug
FROM partners p
WHERE p.is_featured = true
ORDER BY p.display_order ASC
LIMIT 5
`;
if (featured.length > 0) {
return featured;
}
// Fallback to top 5 standard partners if none are marked featured
return await sql`
SELECT p.*, (
SELECT slug FROM projects
WHERE LOWER(TRIM(p.name)) LIKE '%' || LOWER(TRIM(title)) || '%'
OR LOWER(TRIM(title)) LIKE '%' || LOWER(TRIM(p.name)) || '%'
LIMIT 1
) as project_slug
FROM partners p
ORDER BY p.display_order ASC
LIMIT 5
`;
} catch (error) {
console.error('Error fetching featured partners:', error);
return [];
}
}
export const getProjectBySlug = cache(async function(slug: string) {
try {
const projects = await sql`SELECT * FROM projects WHERE slug = ${slug} LIMIT 1`;