feat: contact to frontpage and biome

This commit is contained in:
DESKTOP-RTLN3BA\$punk 2025-09-30 22:15:55 -07:00
parent e305bc4796
commit 1a1530957a
4 changed files with 65 additions and 64 deletions

View file

@ -1,59 +1,61 @@
import { NextRequest, NextResponse } from 'next/server'; import { type NextRequest, NextResponse } from "next/server";
import { db } from '@/app/db'; import { z } from "zod";
import { usersTable } from '@/app/db/schema'; import { db } from "@/app/db";
import { z } from 'zod'; import { usersTable } from "@/app/db/schema";
// Define validation schema matching the database schema // Define validation schema matching the database schema
const contactSchema = z.object({ const contactSchema = z.object({
name: z.string().min(1, 'Name is required').max(255, 'Name is too long'), name: z.string().min(1, "Name is required").max(255, "Name is too long"),
email: z.string().email('Invalid email address').max(255, 'Email is too long'), email: z.string().email("Invalid email address").max(255, "Email is too long"),
company: z.string().min(1, 'Company is required').max(255, 'Company name is too long'), company: z.string().min(1, "Company is required").max(255, "Company name is too long"),
message: z.string().optional().default(''), message: z.string().optional().default(""),
}); });
export async function POST(request: NextRequest) { export async function POST(request: NextRequest) {
try { try {
const body = await request.json(); const body = await request.json();
// Validate the request body // Validate the request body
const validatedData = contactSchema.parse(body); const validatedData = contactSchema.parse(body);
// Insert into database // Insert into database
const result = await db.insert(usersTable).values({ const result = await db
name: validatedData.name, .insert(usersTable)
email: validatedData.email, .values({
company: validatedData.company, name: validatedData.name,
message: validatedData.message, email: validatedData.email,
}).returning(); company: validatedData.company,
message: validatedData.message,
})
.returning();
return NextResponse.json( return NextResponse.json(
{ {
success: true, success: true,
message: 'Contact form submitted successfully', message: "Contact form submitted successfully",
data: result[0] data: result[0],
}, },
{ status: 201 } { status: 201 }
); );
} catch (error) { } catch (error) {
if (error instanceof z.ZodError) { if (error instanceof z.ZodError) {
return NextResponse.json( return NextResponse.json(
{ {
success: false, success: false,
message: 'Validation error', message: "Validation error",
errors: error.errors errors: error.errors,
}, },
{ status: 400 } { status: 400 }
); );
} }
console.error('Error submitting contact form:', error); console.error("Error submitting contact form:", error);
return NextResponse.json( return NextResponse.json(
{ {
success: false, success: false,
message: 'Failed to submit contact form' message: "Failed to submit contact form",
}, },
{ status: 500 } { status: 500 }
); );
} }
} }

View file

@ -1,6 +1,6 @@
import { drizzle } from 'drizzle-orm/postgres-js' import { drizzle } from "drizzle-orm/postgres-js";
import postgres from 'postgres' import postgres from "postgres";
import * as schema from './schema' import * as schema from "./schema";
const client = postgres(process.env.DATABASE_URL!) const client = postgres(process.env.DATABASE_URL!);
export const db = drizzle({ client, schema }); export const db = drizzle({ client, schema });

View file

@ -1,9 +1,9 @@
import { integer, pgTable, text, varchar } from "drizzle-orm/pg-core"; import { integer, pgTable, text, varchar } from "drizzle-orm/pg-core";
export const usersTable = pgTable("users", { export const usersTable = pgTable("users", {
id: integer().primaryKey().generatedAlwaysAsIdentity(), id: integer().primaryKey().generatedAlwaysAsIdentity(),
name: varchar({ length: 255 }).notNull(), name: varchar({ length: 255 }).notNull(),
email: varchar({ length: 255 }).notNull().unique(), email: varchar({ length: 255 }).notNull().unique(),
company: varchar({ length: 255 }).notNull(), company: varchar({ length: 255 }).notNull(),
message: text().default(''), message: text().default(""),
}); });

View file

@ -76,11 +76,10 @@ export function ContactFormGridWithDetails() {
</FeatureIconContainer> </FeatureIconContainer>
</div> </div>
<h2 className="mt-9 bg-gradient-to-b from-neutral-800 to-neutral-900 bg-clip-text text-left text-xl font-bold text-transparent md:text-3xl lg:text-5xl dark:from-neutral-200 dark:to-neutral-300"> <h2 className="mt-9 bg-gradient-to-b from-neutral-800 to-neutral-900 bg-clip-text text-left text-xl font-bold text-transparent md:text-3xl lg:text-5xl dark:from-neutral-200 dark:to-neutral-300">
Contact us Contact
</h2> </h2>
<p className="mt-8 max-w-lg text-center text-base text-neutral-600 md:text-left dark:text-neutral-400"> <p className="mt-8 max-w-lg text-center text-base text-neutral-600 md:text-left dark:text-neutral-400">
We are always looking for ways to improve our products and services. Contact us and let us We'd love to Hear From You.
know how we can help you.
</p> </p>
<div className="mt-10 hidden flex-col items-center gap-4 md:flex-row lg:flex"> <div className="mt-10 hidden flex-col items-center gap-4 md:flex-row lg:flex">