Skip to content

Commit 6c658ab

Browse files
committed
Add login and signup pages
1 parent 5cd96ae commit 6c658ab

File tree

10 files changed

+293
-12
lines changed

10 files changed

+293
-12
lines changed

peerprep-fe/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"pre-commit": "pnpm format && git add -u"
1212
},
1313
"dependencies": {
14+
"@radix-ui/react-checkbox": "^1.1.1",
1415
"@radix-ui/react-dialog": "^1.1.1",
1516
"@radix-ui/react-icons": "^1.3.0",
1617
"@radix-ui/react-popover": "^1.1.1",

peerprep-fe/pnpm-lock.yaml

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

peerprep-fe/src/app/(main)/components/LandingPage.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1+
'use client';
2+
import Link from 'next/link';
3+
14
export default function LandingPage() {
25
return (
36
<div className="flex min-h-screen flex-col items-center justify-center bg-gray-900 p-6 text-gray-100">
47
<h1 className="mb-4 text-4xl font-bold">Welcome to PeerPrep</h1>
58
<p className="mb-8 text-xl">Practice coding interviews with peers</p>
69
<div className="space-x-4">
7-
<button className="rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-600">
8-
Sign Up
9-
</button>
10+
<Link href="/signup">
11+
<button className="linbg-blue-500 rounded px-4 py-2 font-bold text-white hover:bg-blue-600">
12+
Sign Up
13+
</button>
14+
</Link>
1015
<button className="rounded bg-gray-700 px-4 py-2 font-bold text-white hover:bg-gray-600">
1116
Learn More
1217
</button>

peerprep-fe/src/app/(main)/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import LandingPage from './components/LandingPage';
33

44
// TODO: Replace with actual authentication logic
55
// change this to false to see landing page
6-
const isLoggedIn = true;
6+
const isLoggedIn = false;
77

88
export default function Home() {
99
return isLoggedIn ? <LoggedIn /> : <LandingPage />;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
'use client';
2+
import { useState } from 'react';
3+
import { Button } from '@/components/ui/button';
4+
import { Checkbox } from '@/components/ui/checkbox';
5+
import { Input } from '@/components/ui/input';
6+
import Link from 'next/link';
7+
import { GithubIcon } from 'lucide-react';
8+
9+
export default function LoginForm() {
10+
const [email, setEmail] = useState('');
11+
const [password, setPassword] = useState('');
12+
13+
return (
14+
<div className="flex min-h-screen items-center justify-center bg-gray-900">
15+
<div className="w-full max-w-md space-y-6 rounded-lg bg-gray-800 p-8 shadow-xl">
16+
<div className="text-center">
17+
<h2 className="text-3xl font-bold text-white">PeerPrep</h2>
18+
<p className="text-sm text-gray-400">Sign in to your account</p>
19+
</div>
20+
<form className="space-y-4">
21+
<div>
22+
<Input
23+
type="email"
24+
placeholder="Email address"
25+
value={email}
26+
onChange={(e) => setEmail(e.target.value)}
27+
className="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 text-sm text-white placeholder-gray-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500"
28+
/>
29+
</div>
30+
<div>
31+
<Input
32+
type="password"
33+
placeholder="Password"
34+
value={password}
35+
onChange={(e) => setPassword(e.target.value)}
36+
className="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 text-sm text-white placeholder-gray-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500"
37+
/>
38+
</div>
39+
<div className="flex items-center justify-between">
40+
<div className="flex items-center">
41+
<Checkbox
42+
id="remember"
43+
className="rounded border-gray-600 text-blue-500 focus:ring-blue-500"
44+
/>
45+
<label htmlFor="remember" className="ml-2 text-sm text-gray-400">
46+
Remember me
47+
</label>
48+
</div>
49+
<a href="#" className="text-sm text-blue-500 hover:underline">
50+
Forgot your password?
51+
</a>
52+
</div>
53+
<Button className="w-full rounded-md bg-blue-600 py-2 text-sm font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-800">
54+
Sign in
55+
</Button>
56+
</form>
57+
<div className="relative">
58+
<div className="absolute inset-0 flex items-center">
59+
<div className="w-full border-t border-gray-600"></div>
60+
</div>
61+
<div className="relative flex justify-center text-sm">
62+
<span className="bg-gray-800 px-2 text-gray-400">
63+
Or continue with
64+
</span>
65+
</div>
66+
</div>
67+
<div className="grid grid-cols-2 gap-3">
68+
<Button
69+
variant="outline"
70+
className="rounded-md border border-gray-600 bg-gray-700 py-2 text-sm font-medium text-white hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-800"
71+
>
72+
<GithubIcon className="mr-2 h-5 w-5" />
73+
GitHub
74+
</Button>
75+
<Button
76+
variant="outline"
77+
className="rounded-md border border-gray-600 bg-gray-700 py-2 text-sm font-medium text-white hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-800"
78+
>
79+
<svg className="mr-2 h-5 w-5" viewBox="0 0 24 24">
80+
<path
81+
fill="currentColor"
82+
d="M12.545,10.239v3.821h5.445c-0.712,2.315-2.647,3.972-5.445,3.972c-3.332,0-6.033-2.701-6.033-6.032s2.701-6.032,6.033-6.032c1.498,0,2.866,0.549,3.921,1.453l2.814-2.814C17.503,2.988,15.139,2,12.545,2C7.021,2,2.543,6.477,2.543,12s4.478,10,10.002,10c8.396,0,10.249-7.85,9.426-11.748L12.545,10.239z"
83+
/>
84+
</svg>
85+
Google
86+
</Button>
87+
</div>
88+
<div className="flex justify-center text-center text-sm text-gray-400">
89+
Don't have an account?
90+
<span className="mx-1" />
91+
<Link href="/signup" className="text-blue-500 hover:underline">
92+
Sign up
93+
</Link>
94+
</div>
95+
</div>
96+
</div>
97+
);
98+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
'use client';
2+
import { useState } from 'react';
3+
import { Button } from '@/components/ui/button';
4+
import { Checkbox } from '@/components/ui/checkbox';
5+
import { Input } from '@/components/ui/input';
6+
import { GithubIcon } from 'lucide-react';
7+
import Link from 'next/link';
8+
9+
export default function SignUpPage() {
10+
const [email, setEmail] = useState('');
11+
const [password, setPassword] = useState('');
12+
const [confirmPassword, setConfirmPassword] = useState('');
13+
const [agreeTerms, setAgreeTerms] = useState(false);
14+
15+
return (
16+
<div className="flex min-h-screen items-center justify-center bg-gray-900">
17+
<div className="w-full max-w-md space-y-6 rounded-lg bg-gray-800 p-8 shadow-xl">
18+
<div className="text-center">
19+
<h2 className="text-3xl font-bold text-white">Create your account</h2>
20+
<p className="text-sm text-gray-400">
21+
Or
22+
<span className="mx-1" />
23+
<Link href="/signin" className="text-blue-500 hover:underline">
24+
Sign in to your existing account
25+
</Link>
26+
</p>
27+
</div>
28+
<form className="space-y-4">
29+
<div>
30+
<Input
31+
type="email"
32+
placeholder="Email address"
33+
value={email}
34+
onChange={(e) => setEmail(e.target.value)}
35+
className="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 text-sm text-white placeholder-gray-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500"
36+
/>
37+
</div>
38+
<div>
39+
<Input
40+
type="password"
41+
placeholder="Password"
42+
value={password}
43+
onChange={(e) => setPassword(e.target.value)}
44+
className="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 text-sm text-white placeholder-gray-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500"
45+
/>
46+
</div>
47+
<div>
48+
<Input
49+
type="password"
50+
placeholder="Confirm password"
51+
value={confirmPassword}
52+
onChange={(e) => setConfirmPassword(e.target.value)}
53+
className="w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 text-sm text-white placeholder-gray-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500"
54+
/>
55+
</div>
56+
<div className="flex items-center">
57+
<Checkbox
58+
id="terms"
59+
checked={agreeTerms}
60+
onCheckedChange={(checked) => setAgreeTerms(checked as boolean)}
61+
className="rounded border-gray-600 text-blue-500 focus:ring-blue-500"
62+
/>
63+
<label htmlFor="terms" className="ml-2 text-sm text-gray-400">
64+
I agree to the{' '}
65+
<Link href="#" className="text-blue-500 hover:underline">
66+
Terms of Service
67+
</Link>{' '}
68+
and{' '}
69+
<Link href="#" className="text-blue-500 hover:underline">
70+
Privacy Policy
71+
</Link>
72+
</label>
73+
</div>
74+
<Button className="w-full rounded-md bg-blue-600 py-2 text-sm font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-800">
75+
Sign up
76+
</Button>
77+
</form>
78+
<div className="relative">
79+
<div className="absolute inset-0 flex items-center">
80+
<div className="w-full border-t border-gray-600"></div>
81+
</div>
82+
<div className="relative flex justify-center text-sm">
83+
<span className="bg-gray-800 px-2 text-gray-400">
84+
Or continue with
85+
</span>
86+
</div>
87+
</div>
88+
<div className="grid grid-cols-2 gap-3">
89+
<Button
90+
variant="outline"
91+
className="rounded-md border border-gray-600 bg-gray-700 py-2 text-sm font-medium text-white hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-800"
92+
>
93+
<GithubIcon className="mr-2 h-5 w-5" />
94+
GitHub
95+
</Button>
96+
<Button
97+
variant="outline"
98+
className="rounded-md border border-gray-600 bg-gray-700 py-2 text-sm font-medium text-white hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-800"
99+
>
100+
<svg className="mr-2 h-5 w-5" viewBox="0 0 24 24">
101+
<path
102+
fill="currentColor"
103+
d="M12.545,10.239v3.821h5.445c-0.712,2.315-2.647,3.972-5.445,3.972c-3.332,0-6.033-2.701-6.033-6.032s2.701-6.032,6.033-6.032c1.498,0,2.866,0.549,3.921,1.453l2.814-2.814C17.503,2.988,15.139,2,12.545,2C7.021,2,2.543,6.477,2.543,12s4.478,10,10.002,10c8.396,0,10.249-7.85,9.426-11.748L12.545,10.239z"
104+
/>
105+
</svg>
106+
Google
107+
</Button>
108+
</div>
109+
</div>
110+
</div>
111+
);
112+
}

peerprep-fe/src/components/navbar/Navbar.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
'use client';
12
import Link from 'next/link';
23

34
export default function Navbar() {
@@ -14,9 +15,11 @@ export default function Navbar() {
1415
<Link href="/match" className="text-gray-300 hover:text-white">
1516
Match
1617
</Link>
17-
<button className="rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-600">
18-
Sign In
19-
</button>
18+
<Link href="/signin">
19+
<button className="rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-600">
20+
Sign In
21+
</button>
22+
</Link>
2023
</div>
2124
</div>
2225
</nav>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use client';
2+
3+
import * as React from 'react';
4+
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
5+
import { CheckIcon } from '@radix-ui/react-icons';
6+
7+
import { cn } from '@/lib/utils';
8+
9+
const Checkbox = React.forwardRef<
10+
React.ElementRef<typeof CheckboxPrimitive.Root>,
11+
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
12+
>(({ className, ...props }, ref) => (
13+
<CheckboxPrimitive.Root
14+
ref={ref}
15+
className={cn(
16+
'peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
17+
className,
18+
)}
19+
{...props}
20+
>
21+
<CheckboxPrimitive.Indicator
22+
className={cn('flex items-center justify-center text-current')}
23+
>
24+
<CheckIcon className="h-4 w-4" />
25+
</CheckboxPrimitive.Indicator>
26+
</CheckboxPrimitive.Root>
27+
));
28+
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
29+
30+
export { Checkbox };

question-service/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
"dotenv": "^16.4.5",
2222
"express": "^4.21.0",
2323
"mongodb": "^6.9.0",
24-
"mongoose": "^8.6.3",
25-
"prettier": "^3.3.3"
24+
"mongoose": "^8.6.3"
2625
},
2726
"devDependencies": {
2827
"@types/cors": "^2.8.17",
@@ -31,6 +30,7 @@
3130
"@types/mongoose": "^5.11.96",
3231
"@types/node": "^22.6.1",
3332
"nodemon": "^3.1.7",
33+
"prettier": "^3.3.3",
3434
"ts-node": "^10.9.2",
3535
"typescript": "^5.6.2"
3636
}

question-service/pnpm-lock.yaml

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)