signup & login UI
This commit is contained in:
48
AceJobAgency.client/src/components/LoginView.tsx
Normal file
48
AceJobAgency.client/src/components/LoginView.tsx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { Input, Checkbox, Button, Link } from "@heroui/react";
|
||||||
|
import { IconMail, IconLock } from "@tabler/icons-react";
|
||||||
|
|
||||||
|
export default function LoginView({ onSignup }: { onSignup: () => void }) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-6">
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<p className="text-3xl">Welcome back!</p>
|
||||||
|
<p className="text-md opacity-50">
|
||||||
|
Let us know who you are, and we will let you in.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<Input endContent={<IconMail />} label="Email" />
|
||||||
|
<Input endContent={<IconLock />} label="Password" type="password" />
|
||||||
|
</div>
|
||||||
|
<div className="flex py-2 px-1 justify-between">
|
||||||
|
<Checkbox
|
||||||
|
classNames={{
|
||||||
|
label: "text-small",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Remember me
|
||||||
|
</Checkbox>
|
||||||
|
<Link color="primary" href="#" size="sm">
|
||||||
|
Forgot password?
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-4 w-full">
|
||||||
|
<Button color="primary" className="w-full">
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
<div className="flex flex-row gap-2 w-full justify-center *:my-auto">
|
||||||
|
<p className="text-sm">Don't have an account?</p>
|
||||||
|
<Link
|
||||||
|
color="primary"
|
||||||
|
onPress={() => {
|
||||||
|
onSignup();
|
||||||
|
}}
|
||||||
|
className="text-sm"
|
||||||
|
>
|
||||||
|
Sign up
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,15 +1,26 @@
|
|||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Link,
|
Link,
|
||||||
|
Modal,
|
||||||
|
ModalBody,
|
||||||
|
ModalContent,
|
||||||
|
ModalHeader,
|
||||||
|
ModalFooter,
|
||||||
Navbar,
|
Navbar,
|
||||||
NavbarBrand,
|
NavbarBrand,
|
||||||
NavbarContent,
|
NavbarContent,
|
||||||
NavbarItem,
|
NavbarItem,
|
||||||
|
useDisclosure,
|
||||||
} from "@heroui/react";
|
} from "@heroui/react";
|
||||||
|
import { useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import SignupView from "./SignupView";
|
||||||
|
import LoginView from "./LoginView";
|
||||||
|
|
||||||
export default function NavigationBar() {
|
export default function NavigationBar() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
||||||
|
const [isSignup, setIsSignup] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Navbar className="border-b-[1px] border-neutral-500/25">
|
<Navbar className="border-b-[1px] border-neutral-500/25">
|
||||||
@@ -32,7 +43,8 @@ export default function NavigationBar() {
|
|||||||
<NavbarItem className="hidden lg:flex">
|
<NavbarItem className="hidden lg:flex">
|
||||||
<Button
|
<Button
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
navigate("/login");
|
setIsSignup(false);
|
||||||
|
onOpen();
|
||||||
}}
|
}}
|
||||||
variant="light"
|
variant="light"
|
||||||
>
|
>
|
||||||
@@ -42,7 +54,8 @@ export default function NavigationBar() {
|
|||||||
<NavbarItem>
|
<NavbarItem>
|
||||||
<Button
|
<Button
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
navigate("/signup");
|
setIsSignup(true);
|
||||||
|
onOpen();
|
||||||
}}
|
}}
|
||||||
variant="bordered"
|
variant="bordered"
|
||||||
>
|
>
|
||||||
@@ -50,6 +63,32 @@ export default function NavigationBar() {
|
|||||||
</Button>
|
</Button>
|
||||||
</NavbarItem>
|
</NavbarItem>
|
||||||
</NavbarContent>
|
</NavbarContent>
|
||||||
|
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
||||||
|
<ModalContent>
|
||||||
|
{() => (
|
||||||
|
<>
|
||||||
|
<ModalHeader />
|
||||||
|
<ModalBody>
|
||||||
|
{isSignup ? (
|
||||||
|
<SignupView
|
||||||
|
onLogin={() => {
|
||||||
|
setIsSignup(false);
|
||||||
|
}}
|
||||||
|
email=""
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<LoginView
|
||||||
|
onSignup={() => {
|
||||||
|
setIsSignup(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
</Navbar>
|
</Navbar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
72
AceJobAgency.client/src/components/SignupView.tsx
Normal file
72
AceJobAgency.client/src/components/SignupView.tsx
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import {
|
||||||
|
Input,
|
||||||
|
Button,
|
||||||
|
Link,
|
||||||
|
Select,
|
||||||
|
SelectItem,
|
||||||
|
DatePicker,
|
||||||
|
} from "@heroui/react";
|
||||||
|
import { IconMail, IconLock } from "@tabler/icons-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export default function SignupView({
|
||||||
|
onLogin,
|
||||||
|
email = "",
|
||||||
|
}: {
|
||||||
|
onLogin: () => void;
|
||||||
|
email: string;
|
||||||
|
}) {
|
||||||
|
const [emailValue, setEmailValue] = useState(email);
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-6">
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<p className="text-3xl">Welcome!</p>
|
||||||
|
<p className="text-md opacity-50">Become a membership today!</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex flex-row gap-2">
|
||||||
|
<Input label="First name" />
|
||||||
|
<Input label="Last name" />
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
endContent={<IconMail />}
|
||||||
|
label="Email"
|
||||||
|
type="email"
|
||||||
|
value={emailValue}
|
||||||
|
onValueChange={setEmailValue}
|
||||||
|
/>
|
||||||
|
<Input label="NRIC" />
|
||||||
|
<div className="flex flex-row gap-2">
|
||||||
|
<Select label="Gender">
|
||||||
|
<SelectItem>Male</SelectItem>
|
||||||
|
<SelectItem>Female</SelectItem>
|
||||||
|
</Select>
|
||||||
|
<DatePicker label="Date of birth" />
|
||||||
|
</div>
|
||||||
|
<Input endContent={<IconLock />} label="Password" type="password" />
|
||||||
|
<Input
|
||||||
|
endContent={<IconLock />}
|
||||||
|
label="Confirm password"
|
||||||
|
type="password"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-4 w-full">
|
||||||
|
<Button color="primary" className="w-full">
|
||||||
|
Sign up
|
||||||
|
</Button>
|
||||||
|
<div className="flex flex-row gap-2 w-full justify-center *:my-auto">
|
||||||
|
<p className="text-sm">Already have an account?</p>
|
||||||
|
<Link
|
||||||
|
color="primary"
|
||||||
|
onPress={() => {
|
||||||
|
onLogin();
|
||||||
|
}}
|
||||||
|
className="text-sm"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,23 @@
|
|||||||
import { Button, Card, Input } from "@heroui/react";
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Input,
|
||||||
|
Modal,
|
||||||
|
ModalBody,
|
||||||
|
ModalContent,
|
||||||
|
ModalFooter,
|
||||||
|
ModalHeader,
|
||||||
|
useDisclosure,
|
||||||
|
} from "@heroui/react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import LoginView from "../components/LoginView";
|
||||||
|
import SignupView from "../components/SignupView";
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
|
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
||||||
|
const [isSignup, setIsSignup] = useState(false);
|
||||||
|
const [emailValue, setEmailValue] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="absolute inset-0 w-full h-full flex flex-col justify-center bg-indigo-500/10 dark:bg-indigo-500/20">
|
<div className="absolute inset-0 w-full h-full flex flex-col justify-center bg-indigo-500/10 dark:bg-indigo-500/20">
|
||||||
<div className="relative m-auto w-max h-max flex flex-col gap-10 justify-center text-center *:mx-auto">
|
<div className="relative m-auto w-max h-max flex flex-col gap-10 justify-center text-center *:mx-auto">
|
||||||
@@ -16,13 +33,51 @@ export default function HomePage() {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Card className="flex flex-row gap-2 p-2">
|
<Card className="flex flex-row gap-2 p-2">
|
||||||
<Input placeholder="Enter your email" size="lg" />
|
<Input
|
||||||
<Button color="primary" size="lg">
|
placeholder="Enter your email"
|
||||||
|
size="lg"
|
||||||
|
value={emailValue}
|
||||||
|
onValueChange={setEmailValue}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
size="lg"
|
||||||
|
onPress={() => {
|
||||||
|
setIsSignup(true);
|
||||||
|
onOpen();
|
||||||
|
}}
|
||||||
|
>
|
||||||
Sign up
|
Sign up
|
||||||
</Button>
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
||||||
|
<ModalContent>
|
||||||
|
{() => (
|
||||||
|
<>
|
||||||
|
<ModalHeader />
|
||||||
|
<ModalBody>
|
||||||
|
{isSignup ? (
|
||||||
|
<SignupView
|
||||||
|
onLogin={() => {
|
||||||
|
setIsSignup(false);
|
||||||
|
}}
|
||||||
|
email={emailValue}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<LoginView
|
||||||
|
onSignup={() => {
|
||||||
|
setIsSignup(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user