Skip to content

Commit

Permalink
feat: major updates using drawer and moving styles around
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcoEscaleira committed Feb 4, 2024
1 parent 000325f commit ed2dd4c
Show file tree
Hide file tree
Showing 13 changed files with 269 additions and 235 deletions.
3 changes: 0 additions & 3 deletions .env.local

This file was deleted.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"dependencies": {
"@apollo/client": "^3.9.2",
"@hookform/resolvers": "^3.3.4",
"@material-tailwind/react": "^2.1.8",
"@material-tailwind/react": "^2.1.0",
"@vercel/analytics": "^1.1.2",
"date-fns": "^3.3.1",
"graphql": "^16.8.1",
Expand All @@ -40,7 +40,7 @@
"@redux-devtools/extension": "^3.3.0",
"@types/mapbox-gl": "2.7.20",
"@types/node": "20.9.2",
"@types/react": "18.2.42",
"@types/react": "18.2.19",
"@types/react-dom": "18.2.18",
"@types/react-modal": "3.16.3",
"@types/react-simple-maps": "3.0.4",
Expand Down
20 changes: 1 addition & 19 deletions src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,3 @@
import { Link } from "react-router-dom";

export function Footer() {
return (
<footer className="absolute bottom-0 left-0 flex w-full justify-center">
<section className="container flex items-center justify-between p-6 sm:p-4">
<Link to="/">
<img src="/images/mtc-logo.svg" width={58} height={54} alt="Planet Earth" className="" />
</Link>

<nav className="flex flex-grow justify-center">
<Link to="/about" className="text-sky-400 underline">
About
</Link>
</nav>

<span></span>
</section>
</footer>
);
return <footer className="absolute bottom-0 left-0 flex w-full justify-center"></footer>;
}
103 changes: 91 additions & 12 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { useEffect, useState } from "react";
import { useQuery } from "@apollo/client";
import { Drawer, Typography } from "@material-tailwind/react";
import { Menu } from "lucide-react";
import { LoginModal } from "@components/Login/LoginModal.tsx";
import { useLazyQuery, useQuery } from "@apollo/client";
import { Button, Drawer, IconButton, List, ListItem, ListItemPrefix, Typography } from "@material-tailwind/react";
import { Menu, Home, Play, FileQuestion, X, CircleUserRound } from "lucide-react";
import { Link } from "react-router-dom";
import { toast } from "react-toastify";
import { LoginForm } from "@components/Login/LoginForm.tsx";
import { gql } from "@generated/index.ts";
import { useUserStore } from "@state/userStore.ts";

const LOGOUT_USER = gql(/* GraphQL */ `
query Query {
logoutUser
}
`);

const GET_USER = gql(/* GraphQL */ `
query GetMe {
getCurrentlyLoggedInUser {
Expand All @@ -23,10 +31,11 @@ const GET_USER = gql(/* GraphQL */ `

export function Header() {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const { user, setUser, setIsSessionLoading } = useUserStore();
const { user, setUser, setIsSessionLoading, resetUser } = useUserStore();
const isLoggedIn = !!user.userId;

const { data, loading, refetch } = useQuery(GET_USER);
const [makeLogout] = useLazyQuery(LOGOUT_USER);

useEffect(() => {
if (!loading) {
Expand All @@ -49,23 +58,93 @@ export function Header() {
}
}, [data, loading]);

const toggleDrawer = () => setIsDrawerOpen(!isDrawerOpen);

return (
<>
<header className="absolute left-0 top-0 z-10 w-full px-4 py-2 sm:px-6 sm:py-4">
<div className="flex items-center justify-end">
<Menu onClick={() => setIsDrawerOpen(true)} className="h-10 w-8 cursor-pointer sm:w-10" />
<div className="flex items-center justify-between">
<Link to="/">
<img src="/images/mtc-logo.svg" width={58} height={54} alt="Planet Earth" className="" />
</Link>
<IconButton onClick={toggleDrawer}>
<Menu />
</IconButton>
</div>
</header>

<Drawer open={isDrawerOpen} onClose={() => setIsDrawerOpen(false)} placement="right" className="p-4">
<div className="flex flex-col items-center justify-between">
<Typography variant="h3" color="blue-gray">
Hello explorer!
<Drawer open={isDrawerOpen} size={360} onClose={toggleDrawer} placement="right" className="p-4">
<div className="absolute right-3 top-3">
<IconButton onClick={() => setIsDrawerOpen(false)} variant="text">
<X />
</IconButton>
</div>

<div className="flex flex-col items-center">
<Typography variant="h3" color="blue-gray" textGradient>
Hello {user.firstName || "explorer"}!
</Typography>
{!isLoggedIn && <Typography color="blue-gray">Get started and login to your account</Typography>}

<List className="mt-8 w-full">
<Link to="/" onClick={toggleDrawer}>
<ListItem>
<ListItemPrefix>
<Home />
</ListItemPrefix>
Home
</ListItem>
</Link>
<Link to="/game" onClick={toggleDrawer}>
<ListItem>
<ListItemPrefix>
<Play />
</ListItemPrefix>
Game
</ListItem>
</Link>
<Link to="/about" onClick={toggleDrawer}>
<ListItem>
<ListItemPrefix>
<FileQuestion />
</ListItemPrefix>
About
</ListItem>
</Link>
{isLoggedIn && (
<Link to="/profile" onClick={toggleDrawer}>
<ListItem>
<ListItemPrefix>
<CircleUserRound />
</ListItemPrefix>
Profile
</ListItem>
</Link>
)}
</List>

{!isLoggedIn && (
<LoginForm
handleLoginSuccess={async () => {
await refetch();
toggleDrawer();
}}
/>
)}
{isLoggedIn && (
<Button
onClick={async () => {
await makeLogout();
resetUser();
toast.success("Logout successful");
toggleDrawer();
}}
>
Logout
</Button>
)}
</div>
</Drawer>
<LoginModal refetchUser={refetch} />
</>
);
}
2 changes: 1 addition & 1 deletion src/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function Layout() {
return (
<>
<Header />
<main className="relative flex h-screen w-screen flex-col">
<main className="relative flex h-screen w-screen flex-col items-center">
<Outlet />
</main>
<Footer />
Expand Down
105 changes: 105 additions & 0 deletions src/components/Login/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { useMutation } from "@apollo/client";
import { zodResolver } from "@hookform/resolvers/zod";
import { Button, Input, Typography } from "@material-tailwind/react";
import { SubmitHandler, useForm } from "react-hook-form";
import { Link } from "react-router-dom";
import { toast } from "react-toastify";
import { z } from "zod";
import { gql } from "@generated/index.ts";

const LOGIN_USER = gql(/* GraphQL */ `
mutation LoginUser($input: LoginInput!) {
loginUser(input: $input) {
access_token
}
}
`);

const formSchema = z.object({
email: z.string().email(),
password: z.string().min(1),
});

export function LoginForm({ handleLoginSuccess }: { handleLoginSuccess: () => Promise<void> }) {
const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
email: "",
password: "",
},
});

const [loginMutation, { loading: isLoadingLogin, error: mutationError }] = useMutation(LOGIN_USER, {
onCompleted: async data => {
data.loginUser.access_token && (await handleLoginSuccess());
toast.success("Logged in successfully!");
reset();
},
});

const onSubmit: SubmitHandler<z.infer<typeof formSchema>> = async (values, event) => {
event?.preventDefault();

try {
await loginMutation({
variables: {
input: {
email: values.email,
password: values.password,
},
},
});
} catch (e) {
console.log("Something went wrong", e);
}
};

return (
<div className="w-full p-4">
<div className="flex w-96 items-center justify-between rounded-t border-b pb-2">
<Typography variant="h4" color="blue-gray">
Sign in
</Typography>
</div>

<form onSubmit={handleSubmit(onSubmit)} className="space-y-3 py-4">
<Input
{...register("email")}
name="email"
size="lg"
label="Email address"
placeholder="[email protected]"
error={!!errors.email}
/>

<Input
{...register("password")}
name="password"
size="lg"
type="password"
label="Password"
placeholder="*******"
error={!!errors.password}
/>

{mutationError?.message && <p className="text-sm text-red-500">{mutationError.message}</p>}

<Button type="submit" disabled={isLoadingLogin} loading={isLoadingLogin}>
Login to your account
</Button>

<div className="text-sm font-medium text-gray-500">
Not registered?&nbsp;
<Link to="/register" className="text-blue-700 hover:underline">
Create an account
</Link>
</div>
</form>
</div>
);
}
Loading

0 comments on commit ed2dd4c

Please sign in to comment.