Skip to content

Commit 233fc57

Browse files
committed
updated signup form, validations, supabase connections, auths, etc.
1 parent c972281 commit 233fc57

6 files changed

Lines changed: 69 additions & 0 deletions

File tree

‎apps/codebility/app/auth/actions.ts‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,34 @@ const uploadProfileImage = async (
4747
}
4848
};
4949

50+
const validateUsername = (username: string): { valid: boolean; error?: string } => {
51+
// Must be 8-30 characters
52+
if (username.length < 8) {
53+
return { valid: false, error: "Username must be at least 8 characters" };
54+
}
55+
if (username.length > 30) {
56+
return { valid: false, error: "Username must be 30 characters or less" };
57+
}
58+
59+
// Only letters, numbers, periods, and underscores
60+
const validPattern = /^[a-zA-Z0-9._]+$/;
61+
if (!validPattern.test(username)) {
62+
return { valid: false, error: "Username can only contain letters, numbers, periods, and underscores" };
63+
}
64+
65+
// Cannot start or end with a period
66+
if (username.startsWith('.') || username.endsWith('.')) {
67+
return { valid: false, error: "Username cannot start or end with a period" };
68+
}
69+
70+
// Cannot have consecutive periods
71+
if (username.includes('..')) {
72+
return { valid: false, error: "Username cannot have consecutive periods" };
73+
}
74+
75+
return { valid: true };
76+
};
77+
5078
export const signupUser = async (formData: FormData) => {
5179
try {
5280
const supabase = await createClientServerComponent();
@@ -56,6 +84,7 @@ export const signupUser = async (formData: FormData) => {
5684
const rawEmail = formData.get("email_address") as string;
5785
const email_address = rawEmail.toLowerCase();
5886
const password = formData.get("password") as string;
87+
const username = formData.get("username") as string;
5988
const tech_stacks = JSON.parse(formData.get("tech_stacks") as string) || [];
6089
const positions: { id: number; name: string }[] =
6190
(JSON.parse(formData.get("positions") as string) as {
@@ -85,6 +114,24 @@ export const signupUser = async (formData: FormData) => {
85114
return { success: false, error: "Email already exists" };
86115
}
87116

117+
if (username) {
118+
// Validate username format
119+
const usernameValidation = validateUsername(username);
120+
if (!usernameValidation.valid) {
121+
return { success: false, error: usernameValidation.error };
122+
}
123+
124+
// Check if username is already taken (case-insensitive)
125+
const { data: existingUsername } = await supabase
126+
.from("codev")
127+
.select("username")
128+
.ilike("username", username)
129+
.single();
130+
131+
if (existingUsername) {
132+
return { success: false, error: "Username is already taken" };
133+
}
134+
}
88135
// Handle profile image upload if provided
89136
const image_url = profileImage && profileImage.size > 0
90137
? await uploadProfileImage(profileImage, "profileImage", "codebility")
@@ -178,6 +225,8 @@ export const signupUser = async (formData: FormData) => {
178225
first_name: firstName,
179226
last_name: lastName,
180227
email_address,
228+
username: username || null, // ADDED: Store username if provided, otherwise null
229+
username_updated_at: username ? new Date().toISOString() : null, // ADDED: Track when username was set
181230
phone_number: formData.get("phone_number") as string,
182231
address: null,
183232
about: (formData.get("about") as string) || null,

‎apps/codebility/app/auth/sign-up/_components/SignUpForm.tsx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const SignUpForm = () => {
3535
defaultValues: {
3636
first_name: "",
3737
last_name: "",
38+
username: "",
3839
email_address: "",
3940
phone_number: "",
4041
years_of_experience: 0,

‎apps/codebility/app/auth/sign-up/_components/form-steps.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ export const FORM_STEPS: FormField[][] = [
3333
label: "Last Name",
3434
placeholder: "Enter your last name",
3535
type: "text",
36+
},
37+
{
38+
id: "username",
39+
label: "Username",
40+
placeholder: "Enter your username",
41+
type: "text",
3642
},
3743
{
3844
id: "positions",

‎apps/codebility/app/auth/sign-up/page.tsx‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const SignupFormSchema = z.object({
5151
facebook: z.string().optional(),
5252
linkedin: z.string().optional(),
5353
github: z.string().optional(),
54+
username: z.string().min(8, "Username must be at least 8 characters").optional(),
5455
discord: z.string().optional(),
5556
privacyPolicy: z.boolean().refine(val => val === true, "You must agree to the Privacy Policy"),
5657
ndaAgreement: z.boolean().refine(val => val === true, "You must agree to the Non-Disclosure Agreement"),
@@ -135,6 +136,7 @@ export default function SignUpForm() {
135136
defaultValues: {
136137
first_name: "",
137138
last_name: "",
139+
username: "",
138140
email_address: "",
139141
phone_number: "",
140142
password: "",
@@ -451,6 +453,14 @@ export default function SignUpForm() {
451453

452454
{/* Column 2 - Professional Info */}
453455
<div className="space-y-4">
456+
<FormField
457+
label="Username"
458+
name="username"
459+
placeholder="Enter your username"
460+
register={form.register}
461+
errors={form.formState.errors}
462+
required
463+
/>
454464
{/* Positions Dropdown */}
455465
<div className="space-y-1">
456466
<Label className="text-white text-base font-medium">Positions <span className="text-red-400">*</span></Label>

‎apps/codebility/lib/validations/auth.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const SignUpValidation = z
1111
.object({
1212
first_name: z.string().min(1, "First name is required"),
1313
last_name: z.string().min(1, "Last name is required"),
14+
username: z.string().min(8, "Username must be at least 8 characters"),
1415
email_address: z.string().email("Please enter a valid email"),
1516
phone_number: z
1617
.string()

‎apps/codebility/types/home/codev.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export interface Codev {
9090
id: string;
9191
first_name: string;
9292
last_name: string;
93+
username: string | null; // Added username field
94+
username_updated_at: string | null; // Track when username was last updated
9395
email_address: string;
9496
phone_number?: string;
9597
address?: string | null;

0 commit comments

Comments
 (0)