Skip to content

Commit

Permalink
Align authentication with designs (#43)
Browse files Browse the repository at this point in the history
* Authentication Menu Refactor

* Transform menu orgiin

* Better functionality/ready for deploy

* Delete unused stuff
  • Loading branch information
cmyui authored Aug 10, 2024
1 parent efaffea commit 2e9414a
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 118 deletions.
4 changes: 0 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ import { AboutPage } from "./pages/AboutPage"
import { ContactPage } from "./pages/ContactPage"
import { HomePage } from "./pages/HomePage"
import { LeaderboardsPage } from "./pages/LeaderboardsPage"
import { LoginPage } from "./pages/LoginPage"
import { PrivacyPolicyPage } from "./pages/PrivacyPolicyPage"
import { ProfilePage } from "./pages/ProfilePage"
import { RegisterPage } from "./pages/RegisterPage"
import { ScorePage } from "./pages/ScorePage"
import { SupportPage } from "./pages/SupportPage"
import { TeamPage } from "./pages/TeamPage"
Expand Down Expand Up @@ -67,8 +65,6 @@ const router = createBrowserRouter(
<Route element={<AppLayout />}>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
<Route path="/register" element={<RegisterPage />} />
<Route path="login" element={<LoginPage />} />
<Route path="/leaderboards" element={<LeaderboardsPage />} />
<Route path="/u/:userId" element={<ProfilePage />} />
<Route path="/u/:userId/settings" element={<UserSettingsPage />} />
Expand Down
226 changes: 212 additions & 14 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as amplitude from "@amplitude/analytics-browser"
import {
Alert,
Autocomplete,
Avatar,
Box,
Expand All @@ -16,13 +17,14 @@ import {
import { useEffect, useMemo, useState } from "react"
import { Link, useLocation, useNavigate } from "react-router-dom"

import { logout } from "../adapters/akatsuki-api/authentication"
import { authenticate, logout } from "../adapters/akatsuki-api/authentication"
import {
searchUsers,
SingleUserSearchResult,
} from "../adapters/akatsuki-api/search"
import HomepageBanner from "../components/images/banners/homepage_banner.svg"
import { Identity, useIdentityContext } from "../context/identity"
import { LoginDoorIcon } from "./images/icons/LoginDoorIcon"
import { UserFriendsIcon } from "./images/icons/UserFriendsIcon"
import { UserLogoutIcon } from "./images/icons/UserLogoutIcon"
import { UserProfileIcon } from "./images/icons/UserProfileIcon"
Expand All @@ -34,6 +36,207 @@ const PAGES_WITH_VISIBLE_OUTLINE = ["/"]
const shouldUseVisibleOutline = (pagePathName: string) =>
PAGES_WITH_VISIBLE_OUTLINE.includes(pagePathName)

export const AuthenticationSettingsMenu = ({
identity,
setIdentity,
}: {
identity: Identity | null
setIdentity: (identity: Identity | null) => void
}) => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
const open = Boolean(anchorEl)
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}

const [username, setUsername] = useState("")
const [password, setPassword] = useState("")

const [loading, setLoading] = useState(false)
const [loginError, setLoginError] = useState("")

const handleLogin = async () => {
let identity
try {
setLoading(true)
identity = await authenticate({ username, password })
} catch (e: any) {
setLoading(false)
setLoginError(e.message)
return
}

amplitude.setUserId(String(identity.userId))
setLoading(false)
setLoginError("")
setIdentity(identity)
}

return (
<>
<Button
aria-label="authentication-settings-button"
id="authentication-settings-button"
aria-controls={open ? "authentication-settings-button" : undefined}
aria-expanded={open ? "true" : undefined}
aria-haspopup="true"
onClick={handleClick}
sx={{
textTransform: "none",
p: 2,
borderRadius: 8,
color: "white",
}}
>
<Typography variant="body1">Log in or Register</Typography>
</Button>
<Menu
id="authentication-settings-menu"
MenuListProps={{
"aria-labelledby": "authentication-settings-button",
sx: {
bgcolor: "#191527",
paddingTop: 0,
p: 1.5,
},
}}
slotProps={{ paper: { sx: { width: 326, borderRadius: 3 } } }}
anchorEl={anchorEl}
open={open}
onClose={handleClose}
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Tab") {
e?.stopPropagation()
}
}}
transformOrigin={{ vertical: "top", horizontal: "center" }}
>
<TextField
fullWidth
id="username"
label="Username / Email"
type="text"
autoComplete="username"
InputProps={{
sx: { borderRadius: 3, bgcolor: "#110E1B" },
}}
onInput={(e: React.ChangeEvent<HTMLInputElement>) =>
setUsername(e.target.value)
}
onKeyDown={async (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter" && username && password) {
await handleLogin()
} else if (e.key === "Tab") {
e?.stopPropagation()
}
}}
/>
<TextField
fullWidth
id="password"
label="Password"
type="password"
autoComplete="current-password"
InputProps={{
sx: {
borderRadius: 3,
bgcolor: "#110E1B",
borderColor: "red",
mt: 1,
},
}}
InputLabelProps={{ sx: { mt: 1 } }}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setPassword(e.target.value)
}
onKeyDown={async (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter" && username && password) {
await handleLogin()
}
if (e.key === "Tab") {
e?.stopPropagation()
}
}}
/>
{loginError && (
<Alert sx={{ mt: 1 }} severity="error">
{loginError}
</Alert>
)}
<Button
fullWidth
variant="contained"
onClick={handleLogin}
sx={{
backgroundImage:
"linear-gradient(90.09deg, #387EFC -0.08%, #C940FD 99.3%)",
mt: 1.5,
borderRadius: 3,
}}
onKeyDown={(e: any) => {
if (e.key === "Tab") {
e?.stopPropagation()
}
}}
disabled={loading}
>
<Stack direction="row" alignItems="center">
<Box width={24} height={24}>
<LoginDoorIcon />
</Box>
<Typography variant="body2">Log In</Typography>
</Stack>
</Button>
<Stack direction="row" justifyContent="space-around">
<Box sx={{ width: "45%", height: 2, bgcolor: "#3B345F", mt: 1.5 }} />
<Typography variant="body1">or</Typography>
<Box sx={{ width: "45%", height: 2, bgcolor: "#3B345F", mt: 1.5 }} />
</Stack>
<Stack direction="row" spacing={1} justifyContent="space-around">
<Button
fullWidth
disabled
sx={{
textTransform: "none",
color: "white",
bgcolor: "#262238",
p: 1.25,
borderRadius: 3,
}}
onKeyDown={(e: any) => {
if (e.key === "Tab") {
e?.stopPropagation()
}
}}
>
<Typography variant="body1">Reset Password</Typography>
</Button>
<Button
fullWidth
disabled
sx={{
textTransform: "none",
color: "white",
bgcolor: "#262238",
borderRadius: 3,
}}
onKeyDown={(e: any) => {
if (e.key === "Tab") {
e?.stopPropagation()
}
}}
>
<Typography variant="body1">Create Account</Typography>
</Button>
</Stack>
</Menu>
</>
)
}

export const ProfileSettingsMenu = ({
identity,
setIdentity,
Expand Down Expand Up @@ -92,7 +295,10 @@ export const ProfileSettingsMenu = ({
id="profile-settings-menu"
MenuListProps={{
"aria-labelledby": "profile-settings-button",
sx: { bgcolor: "#191527", paddingTop: 0 },
sx: {
bgcolor: "#191527",
paddingTop: 0,
},
}}
slotProps={{ paper: { sx: { width: 242 } } }}
anchorEl={anchorEl}
Expand Down Expand Up @@ -305,18 +511,10 @@ export default function Navbar() {
setIdentity={setIdentity}
/>
) : (
<>
<Link to="/login">
<Button sx={{ color: "white", textTransform: "none" }}>
<Typography variant="body1">Login</Typography>
</Button>
</Link>
<Link to="/register">
<Button sx={{ color: "white", textTransform: "none" }}>
<Typography variant="body1">Register</Typography>
</Button>
</Link>
</>
<AuthenticationSettingsMenu
identity={identity}
setIdentity={setIdentity}
/>
)}
</Stack>
</Stack>
Expand Down
46 changes: 46 additions & 0 deletions src/components/images/icons/LoginDoorIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
export const LoginDoorIcon = () => {
return (
<svg
width="100%"
height="100%"
viewBox="0 0 24 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_716_2846)">
<path
d="M2.25 21.5H21.75"
stroke="white"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M5.25 21.5V4.25C5.25 4.05109 5.32902 3.86032 5.46967 3.71967C5.61032 3.57902 5.80109 3.5 6 3.5H18C18.1989 3.5 18.3897 3.57902 18.5303 3.71967C18.671 3.86032 18.75 4.05109 18.75 4.25V21.5"
stroke="white"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M15.75 21.5V6.25C15.75 6.05109 15.671 5.86032 15.5303 5.71967C15.3897 5.57902 15.1989 5.5 15 5.5L5.5 4"
stroke="white"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M12.375 14C12.9963 14 13.5 13.4963 13.5 12.875C13.5 12.2537 12.9963 11.75 12.375 11.75C11.7537 11.75 11.25 12.2537 11.25 12.875C11.25 13.4963 11.7537 14 12.375 14Z"
fill="white"
/>
</g>
<defs>
<clipPath id="clip0_716_2846">
<rect
width="24"
height="24"
fill="white"
transform="translate(0 0.5)"
/>
</clipPath>
</defs>
</svg>
)
}
7 changes: 4 additions & 3 deletions src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ export const HomePage = () => {
<Typography variant="body1">Get Started!</Typography>
</Button>
</Link>
<Link to="/login">
{/* TODO: hook this up to open the navbar auth menu */}
{/* <Link to="/register">
<Button
variant="contained"
sx={{
Expand All @@ -89,9 +90,9 @@ export const HomePage = () => {
py: 1,
}}
>
<Typography variant="body1">Sign In</Typography>
<Typography variant="body1">Sign up</Typography>
</Button>
</Link>
</Link> */}
</Stack>
</Stack>
</Grid>
Expand Down
Loading

0 comments on commit 2e9414a

Please sign in to comment.