-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat: added contact page #345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1a3faf0
ba62489
e305bc4
1a15309
79429b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| NEXT_PUBLIC_FASTAPI_BACKEND_URL=http://localhost:8000 | ||
| NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE=LOCAL or GOOGLE | ||
| NEXT_PUBLIC_ETL_SERVICE=UNSTRUCTURED or LLAMACLOUD or DOCLING | ||
| NEXT_PUBLIC_ETL_SERVICE=UNSTRUCTURED or LLAMACLOUD or DOCLING | ||
| # Contact Form Vars - OPTIONAL | ||
| DATABASE_URL=postgresql://postgres:[YOUR-PASSWORD]@db.sdsf.supabase.co:5432/postgres |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import { type NextRequest, NextResponse } from "next/server"; | ||
| import { z } from "zod"; | ||
| import { db } from "@/app/db"; | ||
| import { usersTable } from "@/app/db/schema"; | ||
|
|
||
| // Define validation schema matching the database schema | ||
| const contactSchema = z.object({ | ||
| 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"), | ||
| company: z.string().min(1, "Company is required").max(255, "Company name is too long"), | ||
| message: z.string().optional().default(""), | ||
| }); | ||
|
|
||
| export async function POST(request: NextRequest) { | ||
| try { | ||
| const body = await request.json(); | ||
|
|
||
| // Validate the request body | ||
| const validatedData = contactSchema.parse(body); | ||
|
|
||
| // Insert into database | ||
| const result = await db | ||
| .insert(usersTable) | ||
| .values({ | ||
| name: validatedData.name, | ||
| email: validatedData.email, | ||
| company: validatedData.company, | ||
| message: validatedData.message, | ||
| }) | ||
| .returning(); | ||
|
|
||
| return NextResponse.json( | ||
| { | ||
| success: true, | ||
| message: "Contact form submitted successfully", | ||
| data: result[0], | ||
| }, | ||
| { status: 201 } | ||
| ); | ||
| } catch (error) { | ||
| if (error instanceof z.ZodError) { | ||
| return NextResponse.json( | ||
| { | ||
| success: false, | ||
| message: "Validation error", | ||
| errors: error.errors, | ||
| }, | ||
| { status: 400 } | ||
| ); | ||
| } | ||
|
|
||
| console.error("Error submitting contact form:", error); | ||
| return NextResponse.json( | ||
| { | ||
| success: false, | ||
| message: "Failed to submit contact form", | ||
| }, | ||
| { status: 500 } | ||
| ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import React from 'react' | ||
| import { ContactFormGridWithDetails } from '@/components/contact/contact-form' | ||
|
|
||
| const page = () => { | ||
| return ( | ||
| <div> | ||
| <ContactFormGridWithDetails /> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| export default page | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| "use client"; | ||
|
|
||
| import { format } from "date-fns"; | ||
| import { AnimatePresence, motion, type Variants } from "framer-motion"; | ||
| import { AnimatePresence, motion, type Variants } from "motion/react"; | ||
|
Comment on lines
3
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix import order to resolve pipeline failure. The pipeline reports an import/export sorting issue. The Biome linter requires imports to be organized in a specific order. Please run your code formatter/linter to fix the import order: # Fix import order with Biome
npx biome check --apply .🧰 Tools🪛 GitHub Actions: Code Quality Checks[error] 3-3: The imports and exports are not sorted. Organize imports (Biome) to fix order. 🤖 Prompt for AI Agents |
||
| import { | ||
| Calendar, | ||
| CheckCircle, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| "use client"; | ||
|
|
||
| import { motion } from "framer-motion"; | ||
| import { motion } from "motion/react"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 🧩 Analysis chainVerify the motion/react import path. The import has been changed from Please verify this import path change by checking:
🏁 Script executed: #!/bin/bash
# Verify the motion/react import and package installation
echo "=== Checking package.json for motion-related dependencies ==="
cat package.json | jq '.dependencies, .devDependencies' | grep -i motion
echo -e "\n=== Checking if motion is a separate package or export from framer-motion ==="
# Check package-lock or yarn.lock for motion package
if [ -f package-lock.json ]; then
cat package-lock.json | jq '.packages | keys[]' | grep motion || echo "No motion package found in package-lock.json"
elif [ -f yarn.lock ]; then
grep '"motion@' yarn.lock || echo "No motion package found in yarn.lock"
fi
echo -e "\n=== Searching for other files using motion/react ==="
rg -l "from ['\"]motion/react['\"]" --type ts --type tsx || echo "No other files found"
echo -e "\n=== Searching for files still using framer-motion ==="
rg -l "from ['\"]framer-motion['\"]" --type ts --type tsx | head -5 || echo "No files using framer-motion found"Length of output: 371 🏁 Script executed: #!/bin/bash
# Locate all package.json and lock files within 4 directory levels
echo "=== Found package.json files ==="
fd --max-depth 4 package.json -t f
echo -e "\n=== Found lock files ==="
fd --max-depth 4 package-lock.json -t f
fd --max-depth 4 yarn.lock -t f
fd --max-depth 4 pnpm-lock.yaml -t f
# For each package.json found, print the dependencies section
for f in $(fd --max-depth 4 package.json -t f); do
echo -e "\n=== Dependencies in $f ==="
jq '.dependencies, .devDependencies' "$f"
doneLength of output: 3875 🏁 Script executed: #!/bin/bash
# Search for framer-motion imports in surfsense_web
rg -g '*.tsx' -n "from ['\"]framer-motion['\"]" surfsense_web || echo "No framer-motion imports found"
rg -g '*.ts' -n "from ['\"]framer-motion['\"]" surfsense_web || echo "No framer-motion imports found"
echo "------"
# Search for motion/react imports in surfsense_web
rg -g '*.tsx' -n "from ['\"]motion/react['\"]" surfsense_web || echo "No motion/react imports found"
rg -g '*.ts' -n "from ['\"]motion/react['\"]" surfsense_web || echo "No motion/react imports found"Length of output: 5516 Unify animation imports: Replace the lone 🤖 Prompt for AI Agents |
||
| import { useRouter } from "next/navigation"; | ||
| import { toast } from "sonner"; | ||
| import { SearchSpaceForm } from "@/components/search-space-form"; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| import { drizzle } from "drizzle-orm/postgres-js"; | ||
| import postgres from "postgres"; | ||
| import * as schema from "./schema"; | ||
|
|
||
| const client = postgres(process.env.DATABASE_URL!); | ||
| export const db = drizzle({ client, schema }); | ||
|
Comment on lines
+5
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add validation for DATABASE_URL to prevent runtime crashes. The non-null assertion on Apply this diff to add proper validation: +if (!process.env.DATABASE_URL) {
+ throw new Error(
+ 'DATABASE_URL is not defined. Please set it in your .env file or disable the contact form feature.'
+ );
+}
+
const client = postgres(process.env.DATABASE_URL);
export const db = drizzle({ client, schema });Additionally, consider connection pool configuration for production: -const client = postgres(process.env.DATABASE_URL);
+const client = postgres(process.env.DATABASE_URL, {
+ max: 10, // Maximum pool size
+ idle_timeout: 20, // Close idle connections after 20s
+ connect_timeout: 10, // Connection timeout in seconds
+});
🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,9 @@ | ||||||
| import { integer, pgTable, text, varchar } from "drizzle-orm/pg-core"; | ||||||
|
|
||||||
| export const usersTable = pgTable("users", { | ||||||
| id: integer().primaryKey().generatedAlwaysAsIdentity(), | ||||||
| name: varchar({ length: 255 }).notNull(), | ||||||
| email: varchar({ length: 255 }).notNull().unique(), | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the unique constraint on contact emails Line [6]: Marking - email: varchar({ length: 255 }).notNull().unique(),
+ email: varchar({ length: 255 }).notNull(),📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| company: varchar({ length: 255 }).notNull(), | ||||||
| message: text().default(""), | ||||||
| }); | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import React from 'react' | ||
| import PricingBasic from '@/components/pricing/pricing-section' | ||
|
|
||
| const page = () => { | ||
| return ( | ||
| <div> | ||
| <PricingBasic /> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| export default page |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix formatting and consider adding page metadata.
The pipeline indicates a Prettier formatting issue that must be resolved.
Run Prettier to fix:
Additionally, consider adding page metadata for SEO:
import React from 'react' import { ContactFormGridWithDetails } from '@/components/contact/contact-form' +import { Metadata } from 'next' + +export const metadata: Metadata = { + title: 'Contact Us | SurfSense', + description: 'Get in touch with the SurfSense team', +} const page = () => { return ( - <div> - <ContactFormGridWithDetails /> - </div> + <ContactFormGridWithDetails /> ) } export default page🧰 Tools
🪛 GitHub Actions: Code Quality Checks
[error] 1-1: Prettier formatting check failed. The formatter would rewrite content in this file. Run the formatter (e.g., 'prettier --write') to fix code style issues.
🤖 Prompt for AI Agents