diff --git a/backend/prisma/migrations/20250622010625_add_user_names/migration.sql b/backend/prisma/migrations/20250622010625_add_user_names/migration.sql new file mode 100644 index 0000000..3f75c5f --- /dev/null +++ b/backend/prisma/migrations/20250622010625_add_user_names/migration.sql @@ -0,0 +1,17 @@ +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_users" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "email" TEXT NOT NULL, + "first_name" TEXT NOT NULL DEFAULT '', + "last_name" TEXT NOT NULL DEFAULT '', + "pass_hash" TEXT NOT NULL, + "created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); +INSERT INTO "new_users" ("created_at", "email", "id", "pass_hash") SELECT "created_at", "email", "id", "pass_hash" FROM "users"; +DROP TABLE "users"; +ALTER TABLE "new_users" RENAME TO "users"; +CREATE UNIQUE INDEX "users_email_key" ON "users"("email"); +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 7c9b9e0..690c85f 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -13,6 +13,8 @@ datasource db { model User { id Int @id @default(autoincrement()) email String @unique + firstName String @default("") @map("first_name") + lastName String @default("") @map("last_name") passHash String @map("pass_hash") createdAt DateTime @default(now()) @map("created_at") diff --git a/backend/src/routes/auth.js b/backend/src/routes/auth.js index 65a652d..bea98da 100644 --- a/backend/src/routes/auth.js +++ b/backend/src/routes/auth.js @@ -22,7 +22,7 @@ const router = Router(); */ router.post("/signup", validateRequest(signupSchema), async (req, res) => { try { - const { email, password } = req.validatedData; + const { email, firstName, lastName, password } = req.validatedData; // Check if user already exists const existingUser = await prisma.user.findUnique({ @@ -43,11 +43,15 @@ router.post("/signup", validateRequest(signupSchema), async (req, res) => { const user = await prisma.user.create({ data: { email, + firstName, + lastName, passHash, }, select: { id: true, email: true, + firstName: true, + lastName: true, createdAt: true, }, }); @@ -120,6 +124,8 @@ router.post("/login", validateRequest(loginSchema), async (req, res) => { user: { id: user.id, email: user.email, + firstName: user.firstName, + lastName: user.lastName, createdAt: user.createdAt, }, tokens: { diff --git a/backend/src/utils/validation.js b/backend/src/utils/validation.js index b729815..8b9ead9 100644 --- a/backend/src/utils/validation.js +++ b/backend/src/utils/validation.js @@ -3,6 +3,14 @@ import { z } from "zod"; // Auth validation schemas export const signupSchema = z.object({ email: z.string().email("Invalid email format"), + firstName: z + .string() + .min(1, "First name is required") + .max(50, "First name must be less than 50 characters"), + lastName: z + .string() + .min(1, "Last name is required") + .max(50, "Last name must be less than 50 characters"), password: z .string() .min(8, "Password must be at least 8 characters") @@ -29,22 +37,26 @@ export const eb1aAssessmentSchema = z.object({ z.string(), z.array(z.string()), z.object({ - user: z.object({ - educationLevel: z.string().optional() - }).optional(), - startupAchievements: z.object({ - funding: z.string().optional(), - traction: z.string().optional(), - awards: z.array(z.string()).optional(), - patents: z.array(z.string()).optional() - }).optional(), + user: z + .object({ + educationLevel: z.string().optional(), + }) + .optional(), + startupAchievements: z + .object({ + funding: z.string().optional(), + traction: z.string().optional(), + awards: z.array(z.string()).optional(), + patents: z.array(z.string()).optional(), + }) + .optional(), media: z.array(z.string()).optional(), speakingExperience: z.array(z.string()).optional(), publications: z.array(z.string()).optional(), references: z.array(z.string()).optional(), - usContacts: z.array(z.string()).optional() - }) - ]) + usContacts: z.array(z.string()).optional(), + }), + ]), }); /** diff --git a/frontend/src/components/auth/SignupForm.tsx b/frontend/src/components/auth/SignupForm.tsx index fb3d0ff..d52eb16 100644 --- a/frontend/src/components/auth/SignupForm.tsx +++ b/frontend/src/components/auth/SignupForm.tsx @@ -7,6 +7,8 @@ interface SignupFormProps { const SignupForm: React.FC = ({ onSwitchToLogin }) => { const [formData, setFormData] = useState({ + firstName: "", + lastName: "", email: "", password: "", confirmPassword: "", @@ -34,7 +36,12 @@ const SignupForm: React.FC = ({ onSwitchToLogin }) => { return; } - const result = await signup(formData.email, formData.password); + const result = await signup( + formData.email, + formData.firstName, + formData.lastName, + formData.password + ); if (result.success) { console.log("Signup successful:", result.user); @@ -43,6 +50,8 @@ const SignupForm: React.FC = ({ onSwitchToLogin }) => { const isFormValid = () => { return ( + formData.firstName.trim() && + formData.lastName.trim() && formData.email && formData.password && formData.confirmPassword && @@ -67,6 +76,44 @@ const SignupForm: React.FC = ({ onSwitchToLogin }) => { )}
+
+ + +
+ +
+ + +
+