Skip to content

Commit 5445126

Browse files
Merge pull request #27 from alexgrate/feature/signup-page
2 parents 65f6f59 + 094bbbf commit 5445126

File tree

5 files changed

+126
-126
lines changed

5 files changed

+126
-126
lines changed

src/app/globals.css

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -52,32 +52,32 @@
5252
--font-serif:
5353
"Georgia", "Times New Roman", serif; /* Added for headings to match the design */
5454

55-
--background: oklch(0.2768 0 0);
56-
/* Main Text Color ("We sent you a mail") */
57-
--foreground: oklch(1 0 0);
58-
--card: oklch(0.24 0.003 294);
59-
--card-foreground: oklch(0.96 0.002 294);
60-
/* Popover Background */
61-
--popover: oklch(0.24 0.003 294);
62-
--popover-foreground: oklch(0.96 0.002 294);
63-
/* Button Color (The orange/peach color) */
64-
--primary: oklch(0.7432 0.1547 40.01);
65-
/* Text Color on the button (A dark color for contrast) */
66-
--primary-foreground: oklch(1 0 0);
67-
--secondary: oklch(0.35 0.002 294);
68-
--secondary-foreground: oklch(0.96 0.002 294);
69-
--muted: oklch(0.35 0.002 294);
70-
/* Muted Text Color (The subtitle text) */
71-
--muted-foreground: oklch(0.937 0 0);
72-
--accent: oklch(0.937 0 0);
73-
--accent-foreground: oklch(0.937 0 0);
74-
/* Error/Destructive color */
75-
--destructive: oklch(0.7033 0.184 38.93);
76-
/* Border color for the OTP boxes */
77-
--border: oklch(0.4532 0 0);
78-
--input: oklch(0.4532 0 0);
79-
/* Focus Ring color */
80-
--ring: oklch(0.937 0 0);
55+
--background: oklch(0.2768 0 0);
56+
/* Main Text Color ("We sent you a mail") */
57+
--foreground: oklch(1 0 0);
58+
--card: oklch(0.24 0.003 294);
59+
--card-foreground: oklch(0.96 0.002 294);
60+
/* Popover Background */
61+
--popover: oklch(0.24 0.003 294);
62+
--popover-foreground: oklch(0.96 0.002 294);
63+
/* Button Color (The orange/peach color) */
64+
--primary: oklch(0.7432 0.1547 40.01);
65+
/* Text Color on the button (A dark color for contrast) */
66+
--primary-foreground: oklch(1 0 0);
67+
--secondary: oklch(0.35 0.002 294);
68+
--secondary-foreground: oklch(0.96 0.002 294);
69+
--muted: oklch(0.35 0.002 294);
70+
/* Muted Text Color (The subtitle text) */
71+
--muted-foreground: oklch(0.937 0 0);
72+
--accent: oklch(0.937 0 0);
73+
--accent-foreground: oklch(0.937 0 0);
74+
/* Error/Destructive color */
75+
--destructive: oklch(0.7033 0.184 38.93);
76+
/* Border color for the OTP boxes */
77+
--border: oklch(0.4532 0 0);
78+
--input: oklch(45.316% 0.00005 271.152);
79+
/* Focus Ring color */
80+
--ring: oklch(0.937 0 0);
8181

8282
--chart-1: oklch(0.488 0.243 264.376);
8383
--chart-2: oklch(0.696 0.17 162.48);

src/app/signup/page.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,17 @@ import { SignupForm } from "@/components/features/signup/signup-form";
44

55
export default function SignupPage() {
66
return (
7-
<div className="flex flex-col items-center justify-center min-h-screen bg-[#222222] px-4">
8-
<main className="w-full max-w-md">
7+
<div className="flex flex-col items-center justify-center min-h-screen background text-foreground">
8+
<main className="w-full max-w-md px-8">
99
<header className="mb-8 text-center">
10-
<h1 className="text-2xl font-medium text-white">
11-
Signup to get started
12-
</h1>
10+
<h1 className="text-2xl font-normal text-foreground leading-none" style={{ fontFamily: 'var(--font-source-serif-pro)' }}>Create an account to get started</h1>
1311
</header>
1412
<SignupForm />
15-
<div className="mt-6 text-center">
16-
<p
17-
className="text-white text-sm leading-none"
18-
style={{ fontFamily: "var(--font-manrope)" }}
19-
>
13+
<div className="mt-4 text-center">
14+
<p className="text-foreground text-sm leading-none" style={{ fontFamily: 'var(--font-manrope)' }}>
15+
2016
Already have an account?{" "}
21-
<Link href="/login" className="font-bold">
17+
<Link href="/login" className="font-bold hover:underline">
2218
Log In
2319
</Link>
2420
</p>

src/components/features/reset-password/reset-password-form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,4 @@ export const ResetPasswordForm = () => {
9494
</Form>
9595
</div>
9696
);
97-
};
97+
};

src/components/features/signup/signup-form.tsx

Lines changed: 73 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
import { Input } from "@/components/ui/input";
2020

2121
import { SignupFormSchema } from "@/lib/zod";
22-
import { EyeIcon, EyeOffIcon, MailIcon } from "lucide-react";
22+
import { EyeIcon, EyeOffIcon, MailIcon, User2, Lock, Info } from "lucide-react";
2323

2424
export const SignupForm = () => {
2525
const router = useRouter();
@@ -33,6 +33,8 @@ export const SignupForm = () => {
3333
const form = useForm<z.infer<typeof SignupFormSchema>>({
3434
resolver: zodResolver(SignupFormSchema),
3535
defaultValues: {
36+
first_name: "",
37+
last_name: "",
3638
username: "",
3739
email: "",
3840
password: "",
@@ -52,32 +54,67 @@ export const SignupForm = () => {
5254
onSubmit={form.handleSubmit(onSubmit)}
5355
className="space-y-6"
5456
>
57+
<div className="flex space-x-4">
58+
<FormField
59+
control={form.control}
60+
name="first_name"
61+
render={({ field }) => (
62+
<FormItem className="space-y-2">
63+
<FormLabel htmlFor="first_name" className="text-foreground text-sm leading-none" style={{ fontFamily: 'var(--font-manrope)' }}>First name</FormLabel>
64+
<FormControl>
65+
<Input
66+
id="first_name"
67+
autoComplete="given-name"
68+
placeholder="First name"
69+
className="background border rounded-md h-12 text-input focus:text-foreground placeholder:text-input"
70+
{...field}
71+
/>
72+
</FormControl>
73+
<FormMessage className="text-destructive" />
74+
</FormItem>
75+
)}
76+
/>
77+
78+
<FormField
79+
control={form.control}
80+
name="last_name"
81+
render={({ field }) => (
82+
<FormItem className="space-y-2">
83+
<FormLabel htmlFor="last_name" className="text-foreground text-sm leading-none" style={{ fontFamily: 'var(--font-manrope)' }}>Last name</FormLabel>
84+
<FormControl>
85+
<Input
86+
id="last_name"
87+
autoComplete="family-name"
88+
placeholder="Last name"
89+
className="background border rounded-md h-12 text-input focus:text-foreground placeholder:text-input"
90+
{...field}
91+
/>
92+
</FormControl>
93+
<FormMessage className="text-destructive" />
94+
</FormItem>
95+
)}
96+
/>
97+
</div>
98+
5599
<FormField
56100
control={form.control}
57101
name="username"
58102
render={({ field }) => (
59103
<FormItem className="space-y-2">
60-
<FormLabel
61-
className="text-white text-sm leading-none"
62-
style={{ fontFamily: "var(--font-manrope)" }}
63-
>
64-
Username
65-
</FormLabel>
104+
<FormLabel htmlFor="username" className="text-foreground text-sm leading-none" style={{ fontFamily: 'var(--font-manrope)' }}>Username</FormLabel>
66105
<FormControl>
67106
<div className="relative">
68-
<img
69-
src="/icons/user-icon.svg"
70-
alt="user"
71-
className="absolute left-3 top-1/2 -translate-y-1/2 size-5"
72-
/>
73-
<Input
74-
placeholder="Enter username"
75-
className="bg-[#222222] border border-[#444444] rounded-md pl-10 h-12 text-white"
107+
<User2 className="absolute left-3 top-1/2 -translate-y-1/2 text-input size-5" />
108+
<Input
109+
id="username"
110+
autoComplete="username"
111+
placeholder="Enter username"
112+
className="background border rounded-md pl-10 h-12 text-input focus:text-foreground placeholder:text-input"
76113
{...field}
77114
/>
78115
</div>
79116
</FormControl>
80-
<FormMessage className="text-[#FF7A50]" />
117+
<FormMessage className="text-destructive" />
81118
</FormItem>
82119
)}
83120
/>
@@ -86,23 +123,20 @@ export const SignupForm = () => {
86123
name="email"
87124
render={({ field }) => (
88125
<FormItem className="space-y-2">
89-
<FormLabel
90-
className="text-white text-sm leading-none"
91-
style={{ fontFamily: "var(--font-manrope)" }}
92-
>
93-
Email
94-
</FormLabel>
126+
<FormLabel htmlFor="email" className="text-foreground text-sm leading-none" style={{ fontFamily: 'var(--font-manrope)' }}>Email</FormLabel>
95127
<FormControl>
96128
<div className="relative">
97-
<MailIcon className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 size-5" />
129+
<MailIcon className="absolute left-3 top-1/2 -translate-y-1/2 text-input size-5" />
98130
<Input
131+
id="email"
132+
autoComplete="email"
99133
placeholder="Enter email"
100-
className="bg-[#222222] border border-[#444444] rounded-md pl-10 h-12 text-white"
134+
className="background border rounded-md pl-10 h-12 text-input focus:text-foreground placeholder:text-input"
101135
{...field}
102136
/>
103137
</div>
104138
</FormControl>
105-
<FormMessage className="text-[#FF7A50]" />
139+
<FormMessage className="text-destructive" />
106140
</FormItem>
107141
)}
108142
/>
@@ -112,56 +146,27 @@ export const SignupForm = () => {
112146
name="password"
113147
render={({ field }) => (
114148
<FormItem className="space-y-2">
115-
<FormLabel
116-
htmlFor="password"
117-
className="text-white text-sm leading-none"
118-
style={{ fontFamily: "var(--font-manrope)" }}
119-
>
120-
Password
121-
</FormLabel>
149+
<FormLabel htmlFor="password" className="text-foreground text-sm leading-none" style={{ fontFamily: 'var(--font-manrope)' }}>Password</FormLabel>
122150
<FormControl>
123151
<div className="relative">
152+
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 text-input size-5" />
124153
<Input
125154
type={showPassword ? "text" : "password"}
126155
aria-describedby="password-constraints"
127-
autoComplete="current-password"
156+
autoComplete="new-password"
128157
id="password"
129158
placeholder="Enter Password"
130-
className="bg-[#222222] border border-[#444444] rounded-md pl-10 pr-10 h-12 text-white"
159+
className="background border rounded-md pl-10 pr-10 h-12 text-input focus:text-foreground placeholder:text-input"
131160
{...field}
132161
/>
133-
<div className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">
134-
<svg
135-
width="20"
136-
height="20"
137-
viewBox="0 0 20 20"
138-
fill="none"
139-
xmlns="http://www.w3.org/2000/svg"
140-
>
141-
<path
142-
d="M15.8333 9.16663H4.16667C3.24619 9.16663 2.5 9.91282 2.5 10.8333V16.6666C2.5 17.5871 3.24619 18.3333 4.16667 18.3333H15.8333C16.7538 18.3333 17.5 17.5871 17.5 16.6666V10.8333C17.5 9.91282 16.7538 9.16663 15.8333 9.16663Z"
143-
stroke="#9CA3AF"
144-
strokeWidth="1.5"
145-
strokeLinecap="round"
146-
strokeLinejoin="round"
147-
/>
148-
<path
149-
d="M5.83325 9.16663V5.83329C5.83325 4.72822 6.27224 3.66842 7.05364 2.88701C7.83504 2.10561 8.89485 1.66663 9.99992 1.66663C11.105 1.66663 12.1648 2.10561 12.9462 2.88701C13.7276 3.66842 14.1666 4.72822 14.1666 5.83329V9.16663"
150-
stroke="#9CA3AF"
151-
strokeWidth="1.5"
152-
strokeLinecap="round"
153-
strokeLinejoin="round"
154-
/>
155-
</svg>
156-
</div>
157162
<Button
158163
type="button"
159164
id="toggle-password"
160165
aria-label="Show password as plain text. Warning: this will display your password on the screen."
161166
variant="ghost"
162167
size="icon"
163168
onClick={togglePasswordVisibility}
164-
className="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:bg-transparent"
169+
className="absolute right-2 top-1/2 -translate-y-1/2 text-input hover:bg-transparent"
165170
>
166171
{showPassword ? (
167172
<EyeOffIcon aria-hidden="true" className="size-5" />
@@ -174,38 +179,19 @@ export const SignupForm = () => {
174179
</Button>
175180
</div>
176181
</FormControl>
177-
<div className="flex items-center space-x-2 text-[#9E9E9E] text-sm">
178-
<svg
179-
width="16"
180-
height="16"
181-
viewBox="0 0 16 16"
182-
fill="none"
183-
xmlns="http://www.w3.org/2000/svg"
184-
>
185-
<path
186-
d="M8 1C4.13401 1 1 4.13401 1 8C1 11.866 4.13401 15 8 15C11.866 15 15 11.866 15 8C15 4.13401 11.866 1 8 1ZM8 11.5C7.44772 11.5 7 11.0523 7 10.5C7 9.94772 7.44772 9.5 8 9.5C8.55228 9.5 9 9.94772 9 10.5C9 11.0523 8.55228 11.5 8 11.5ZM8 8.5C7.44772 8.5 7 8.05228 7 7.5V4.5C7 3.94772 7.44772 3.5 8 3.5C8.55228 3.5 9 3.94772 9 4.5V7.5C9 8.05228 8.55228 8.5 8 8.5Z"
187-
fill="#9CA3AF"
188-
/>
189-
</svg>
190-
<span
191-
style={{
192-
fontFamily: "var(--font-manrope)",
193-
fontSize: "12px",
194-
}}
195-
className="text-[#9E9E9E]"
196-
>
197-
Must contain 1 uppercase letter, 1 number and a minimum of 8
198-
characters
199-
</span>
182+
<div className="flex items-center space-x-2 text-muted-foreground text-sm">
183+
<Info className="size-4 text-[#9CA3AF]" />
184+
<span style={{ fontFamily: 'var(--font-manrope)', fontSize: '12px' }} className="text-[#565656]">Must contain 1 uppercase letter, 1 number and a minimum of 8 characters</span>
200185
</div>
201-
<FormMessage className="text-red-500" />
186+
<FormMessage className="text-destructive" />
202187
</FormItem>
203188
)}
204189
/>
205-
<Button
206-
type="submit"
207-
className="w-full bg-[#FF7A50] hover:bg-[#FF7A50]/90 text-white py-3 rounded-md h-12 font-semibold text-sm leading-none"
208-
style={{ fontFamily: "var(--font-source-serif-pro)" }}
190+
<Button
191+
type="submit"
192+
className="w-full bg-primary hover:bg-primary/90 text-primary-foreground py-3 rounded-md h-12 font-semibold text-sm leading-none"
193+
style={{ fontFamily: 'var(--font-source-serif-pro)' }}
194+
209195
>
210196
Create account
211197
</Button>

src/lib/zod.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,29 @@ export const LoginFormSchema = z
3636

3737
export const SignupFormSchema = z
3838
.object({
39+
first_name: z
40+
.string()
41+
.trim()
42+
.min(1, {
43+
message: "First name is required.",
44+
})
45+
.max(30, {
46+
message: "First name cannot exceed 30 characters.",
47+
}),
48+
last_name: z
49+
.string()
50+
.trim()
51+
.min(1, {
52+
message: "Last name is required",
53+
})
54+
.max(30, {
55+
message: "Last name cannot exceed 30 characters.",
56+
}),
3957
username: z
4058
.string()
4159
.trim()
4260
.min(1, {
43-
message: "Username must start with a letter.",
61+
message: "Username is required.",
4462
})
4563
.max(30, {
4664
message: "Username cannot exceed 30 characters.",

0 commit comments

Comments
 (0)