Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Logout button will now actually logout the user (#12)
* bug: Upgraded Next to fix issue with comments in production output See vercel/next.js#36998 for details * bug: Improved placement of logout menu Also added listener to close the menu when a click is registered outside of the component * refactor: Moved login menu to individual files for better seperation * feat: Implemented logout functionality
- Loading branch information
1 parent
235de3d
commit a9bed30
Showing
9 changed files
with
198 additions
and
163 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import React from 'react'; | ||
|
||
interface LoginButtonProps { | ||
authorizeUrl: string; | ||
} | ||
|
||
const LoginButton: React.FC<LoginButtonProps> = ({ authorizeUrl }) => ( | ||
<a className="btn btn-primary" href={authorizeUrl}> | ||
Login | ||
</a> | ||
); | ||
|
||
export default LoginButton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import React from 'react'; | ||
import { IoLogOutOutline } from 'react-icons/io5'; | ||
|
||
interface LoginMenuProps { | ||
isOpen: boolean; | ||
logoutUrl: string; | ||
} | ||
|
||
const LoginMenu: React.FC<LoginMenuProps> = ({ isOpen, logoutUrl }) => ( | ||
<div | ||
className={`${ | ||
isOpen ? '' : 'hidden' | ||
} absolute top-full right-0 z-10 rounded bg-gray-100 py-4 shadow outline group-hover:block dark:bg-gray-700`} | ||
> | ||
<a | ||
href={logoutUrl} | ||
className="btn flex items-center space-x-2 hover:text-gray-900 hover:underline dark:hover:text-gray-400" | ||
> | ||
<IoLogOutOutline className="inline" /> | ||
<span className="align-middle">Logout</span> | ||
</a> | ||
</div> | ||
); | ||
|
||
export default LoginMenu; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,50 @@ | ||
import React, { useState } from 'react'; | ||
import { IoLogOutOutline } from 'react-icons/io5'; | ||
import { useOnOutsideMouseDown } from '@oliverflecke/components-react'; | ||
import React, { useCallback, useRef, useState } from 'react'; | ||
import { User } from 'utils/githubAuth'; | ||
import LoginButton from './LoginButton'; | ||
import LoginMenu from './LoginMenuProps'; | ||
import UserAvatar from './UserAvatarProps'; | ||
|
||
interface LoginStateProps { | ||
user: User | null; | ||
authorizeUrl: string; | ||
logout?: () => void; | ||
logoutUrl: string; | ||
} | ||
|
||
const LoginState: React.FC<LoginStateProps> = ({ user, authorizeUrl, logout }: LoginStateProps) => { | ||
const LoginState: React.FC<LoginStateProps> = ({ user, authorizeUrl, logoutUrl }) => | ||
user === null ? ( | ||
<LoginButton authorizeUrl={authorizeUrl} /> | ||
) : ( | ||
<LoginDropDownMenu user={user} logoutUrl={logoutUrl} /> | ||
); | ||
|
||
export default LoginState; | ||
|
||
interface LoginDropDownMenuProps { | ||
user: User; | ||
logoutUrl: string; | ||
} | ||
|
||
const LoginDropDownMenu: React.FC<LoginDropDownMenuProps> = ({ user, logoutUrl }) => { | ||
const [isOpen, setIsOpen] = useState(false); | ||
|
||
if (user === null) { | ||
return <LoginButton authorizeUrl={authorizeUrl} />; | ||
} | ||
const ref = useRef<HTMLDivElement>(null); | ||
useOnOutsideMouseDown( | ||
ref, | ||
useCallback(() => setIsOpen(false), []) | ||
); | ||
|
||
console.debug(logoutUrl); | ||
|
||
return ( | ||
<div className="flex items-center space-x-4"> | ||
<div ref={ref} className="relative flex items-center space-x-4"> | ||
<span className="hidden sm:inline">{user.login}</span> | ||
<div className="group" onMouseLeave={() => setIsOpen(false)}> | ||
<button onClick={() => setIsOpen((x) => !x)}> | ||
<div className="group"> | ||
<button onClick={() => setIsOpen(x => !x)}> | ||
<UserAvatar user={user} /> | ||
</button> | ||
</div> | ||
<Menu isOpen={isOpen} logout={logout} /> | ||
<LoginMenu isOpen={isOpen} logoutUrl={logoutUrl} /> | ||
</div> | ||
); | ||
}; | ||
|
||
export default LoginState; | ||
|
||
interface LoginButtonProps { | ||
authorizeUrl: string; | ||
} | ||
|
||
const LoginButton = ({ authorizeUrl }: LoginButtonProps) => ( | ||
<a className="btn btn-primary" href={authorizeUrl}> | ||
Login | ||
</a> | ||
); | ||
|
||
interface UserAvatarProps { | ||
user: User; | ||
} | ||
|
||
const UserAvatar = ({ user }: UserAvatarProps) => ( | ||
<img | ||
src={user.avatar_url} | ||
alt="Avatar of the logged in user" | ||
className="max-h-10 rounded-full" | ||
loading="lazy" | ||
/> | ||
); | ||
|
||
interface MenuProps { | ||
isOpen: boolean; | ||
logout?: () => void; | ||
} | ||
|
||
const Menu = ({ isOpen, logout }: MenuProps) => ( | ||
<div | ||
className={`${ | ||
isOpen ? '' : 'hidden' | ||
} group-hover:block absolute right-0 rounded py-4 shadow bg-gray-100 dark:bg-gray-700`} | ||
> | ||
<button | ||
onClick={logout} | ||
className="btn flex items-center space-x-2 hover:text-gray-900 dark:hover:text-gray-400 hover:underline" | ||
> | ||
<IoLogOutOutline className="inline" /> | ||
<span className="align-middle">Logout</span> | ||
</button> | ||
</div> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import React from 'react'; | ||
import { User } from 'utils/githubAuth'; | ||
|
||
interface UserAvatarProps { | ||
user: User; | ||
} | ||
|
||
const UserAvatar: React.FC<UserAvatarProps> = ({ user }) => ( | ||
<img | ||
src={`${user.avatar_url}&s=80`} | ||
alt="Avatar of the logged in user" | ||
className="max-h-10 rounded-full" | ||
loading="lazy" | ||
/> | ||
); | ||
|
||
export default UserAvatar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.