Skip to content

Commit

Permalink
feat: add login page
Browse files Browse the repository at this point in the history
  • Loading branch information
hariscs committed Mar 25, 2024
1 parent b24066d commit 1a82d73
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 3 deletions.
2 changes: 1 addition & 1 deletion apps/api/src/controllers/user_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export async function login_user(req: Request, res: Response): Promise<void> {
return
}
generate_token(res, user._id.toString())
res.status(200).json(user)
res.status(200).json({ message: 'User logged in successfully' })
} catch (error) {
log('Error fetching user:', error)
res.status(500).json({ error: 'Internal server error' })
Expand Down
7 changes: 6 additions & 1 deletion apps/api/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ export const createServer = (): Express => {
.use(morgan('dev'))
.use(urlencoded({ extended: true }))
.use(json())
.use(cors())
.use(
cors({
origin: true,
credentials: true,
})
)
.use(cookieParser())
.get('/health', (_, res) => {
return res.json({ ok: true })
Expand Down
115 changes: 115 additions & 0 deletions apps/frontend/src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
'use client'

import { Button } from '@/components/Button'
import { useState } from 'react'

export default function Login() {
const [error, setError] = useState('')
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
const formData = new FormData(e.target as HTMLFormElement)
const email = formData.get('email')
const password = formData.get('password')
if (!email || !password) {
return setError('Both fields are required')
}
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_BASE_API}/user/login`,
{
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
}
)
if (!response.ok) {
const data = await response.json()
// throw new Error(data.message)
console.log(data)
setError(data.error)
}
const data = await response.json()
setError('')
console.log(data)
} catch (error) {
setError('some thing went wrong')
}
}

async function getUser() {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_BASE_API}/user/profile`,
{
method: 'GET',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
}
)
const data = await response.json()
console.log(data)
} catch (error) {
console.log(error)
}
}

async function logOutUser() {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_BASE_API}/user/logout`,
{
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
}
)
const data = await response.json()
console.log(data)
} catch (error) {
console.log(error)
}
}

return (
<div className="flex h-screen items-center justify-center">
{/* <button onClick={getUser}>get user</button> */}
{/* <button onClick={logOutUser}>logout user</button> */}
<div className="w-96">
<h1 className="mb-6 text-center text-4xl font-bold">Login</h1>
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
<div>
<label htmlFor="email" id="email" className="sr-only">
email
</label>
<input
name="email"
type="email"
placeholder="Email"
className="w-full rounded border border-gray-200 p-3"
/>
</div>
<div>
<label htmlFor="password" id="password" className="sr-only">
password
</label>
<input
name="password"
type="password"
placeholder="Password"
className="w-full rounded border border-gray-200 p-3"
/>
</div>
{error && <p className="text-danger">{error}</p>}
<Button type="submit">Submit</Button>
</form>
</div>
</div>
)
}
32 changes: 32 additions & 0 deletions apps/frontend/src/app/post-job/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default function PostJob() {
return (
<div className="flex h-screen items-center justify-center">
<div className="w-96">
<h1 className="mb-6 text-center text-4xl font-bold">Post a Job</h1>
<form className="flex flex-col gap-4">
<input
type="text"
placeholder="Title"
className="rounded border border-gray-200 p-3"
/>
<input
type="text"
placeholder="Company"
className="rounded border border-gray-200 p-3"
/>
<input
type="text"
placeholder="Location"
className="rounded border border-gray-200 p-3"
/>
<input
type="text"
placeholder="Description"
className="rounded border border-gray-200 p-3"
/>
<button className="bg-primary rounded p-3 text-white">Post</button>
</form>
</div>
</div>
)
}
26 changes: 26 additions & 0 deletions apps/frontend/src/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export function Button({
handleClick,
children,
type = 'button',
variant = 'primary',
outline = false,
disabled = false,
}: {
handleClick?: () => void
children: React.ReactNode
type?: 'button' | 'submit' | 'reset'
variant?: 'primary' | 'secondary'
outline?: boolean
disabled?: boolean
}) {
return (
<button
disabled={disabled}
onClick={handleClick}
type={type}
className="bg-primary rounded p-3 font-medium uppercase text-white shadow-md transition-all hover:opacity-80 hover:shadow-lg"
>
{children}
</button>
)
}
2 changes: 1 addition & 1 deletion apps/frontend/src/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Pill } from '.'
export function Card({ job }: { job: Job }) {
return (
<div
className={`${job.featured ? 'border-primary border-l-4' : null} flex flex-col justify-between gap-4 rounded bg-white p-4 font-semibold shadow-lg md:flex-row md:items-center md:gap-8 md:px-6 md:py-8`}
className={`${job.featured && 'border-primary border-l-4'} flex flex-col justify-between gap-4 rounded bg-white p-4 font-semibold shadow-lg md:flex-row md:items-center md:gap-8 md:px-6 md:py-8`}
>
<div className="md:flex md:items-center md:gap-4">
<Image
Expand Down

0 comments on commit 1a82d73

Please sign in to comment.