Implement authentication features with login, registration, and user management; update service configurations for development and production environments.
This commit is contained in:
@@ -1,9 +1,26 @@
|
||||
import React from 'react';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import Spinner from '../common/Spinner';
|
||||
import Dropdown from '../common/Dropdown';
|
||||
import useAccount from '../../hooks/useAccount';
|
||||
import useClickListener from '../../hooks/useClickListener';
|
||||
import AuthModal from '../AuthModal';
|
||||
|
||||
function NavBarItem() {
|
||||
const { isLoggedIn, isAuthenticating, login, logout } = useAccount({ redirectReturnToUrl: window.location.origin });
|
||||
const [isExpanded, setExpanded] = useState(false);
|
||||
const menuRef = useRef(null);
|
||||
const {
|
||||
isLoggedIn,
|
||||
isAuthenticating,
|
||||
username,
|
||||
userEmail,
|
||||
openAuthModal,
|
||||
logout,
|
||||
authModalOpen,
|
||||
closeAuthModal,
|
||||
handleAuthSuccess,
|
||||
} = useAccount();
|
||||
|
||||
useClickListener(menuRef, () => setExpanded(false), true);
|
||||
|
||||
if (isAuthenticating) {
|
||||
return (
|
||||
@@ -14,41 +31,198 @@ function NavBarItem() {
|
||||
);
|
||||
}
|
||||
|
||||
const { label, icon, action } = getButtonValues(isLoggedIn, login, logout);
|
||||
if (!isLoggedIn) {
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className='text-primary md:inline hidden navbar-link-alt bg-hover px-2 py-1'
|
||||
onClick={openAuthModal}
|
||||
type='button'
|
||||
>
|
||||
<span className='icon-base mr-1 align-bottom'>login</span>
|
||||
Login
|
||||
</button>
|
||||
<button className='md:hidden inline navbar-icon-link' onClick={openAuthModal} type='button'>
|
||||
<span className='text-primary-alt icon-lg leading-tight align-middle'>login</span>
|
||||
</button>
|
||||
<AuthModal isOpen={authModalOpen} setIsOpen={closeAuthModal} onAuthSuccess={handleAuthSuccess} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='relative'>
|
||||
<button
|
||||
className='text-primary md:inline hidden navbar-link-alt bg-hover py-1 px-2'
|
||||
type='button'
|
||||
onClick={() => setExpanded(true)}
|
||||
>
|
||||
<span className='text-primary-alt icon-lg inline align-middle mr-1'>account_circle</span>
|
||||
{username}
|
||||
</button>
|
||||
<button className='md:hidden inline navbar-icon-link' onClick={() => setExpanded(true)} type='button'>
|
||||
<span className='text-primary-alt icon-lg leading-tight align-middle'>account_circle</span>
|
||||
</button>
|
||||
<div className='mt-1 absolute right-0 text-center'>
|
||||
<Dropdown show={isExpanded} innerRef={menuRef}>
|
||||
<Dropdown.Text isHeading>
|
||||
<span className='text-accent'>{username}</span>
|
||||
{userEmail && <p className='text-xs text-secondary font-normal'>{userEmail}</p>}
|
||||
</Dropdown.Text>
|
||||
<Dropdown.Separator />
|
||||
<Dropdown.Button
|
||||
className='text-left'
|
||||
icon='logout'
|
||||
onClick={() => {
|
||||
logout();
|
||||
setExpanded(false);
|
||||
}}
|
||||
>
|
||||
Logout
|
||||
</Dropdown.Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function CollapsedMenu() {
|
||||
const {
|
||||
isLoggedIn,
|
||||
isAuthenticating,
|
||||
username,
|
||||
openAuthModal,
|
||||
logout,
|
||||
authModalOpen,
|
||||
closeAuthModal,
|
||||
handleAuthSuccess,
|
||||
} = useAccount();
|
||||
|
||||
if (isAuthenticating) {
|
||||
return (
|
||||
<div className='text-primary bg-hover py-1 text-left'>
|
||||
<Spinner size={Spinner.SIZE.sm} />
|
||||
<p className='h-4 inline pl-1 font-sans-alt'>Loading...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isLoggedIn) {
|
||||
return (
|
||||
<>
|
||||
<button className='text-primary bg-hover py-1 text-left' onClick={openAuthModal} type='button'>
|
||||
<span className='text-primary-alt icon-lg inline align-middle mr-1'>login</span>
|
||||
<p className='h-4 inline pl-1 font-sans-alt'>Login</p>
|
||||
</button>
|
||||
<AuthModal isOpen={authModalOpen} setIsOpen={closeAuthModal} onAuthSuccess={handleAuthSuccess} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className='text-primary md:inline hidden navbar-link-alt bg-hover px-2 py-1'
|
||||
onClick={() => action()}
|
||||
type='button'
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
<button className='md:hidden inline navbar-icon-link' onClick={action} type='button'>
|
||||
<span className='text-primary-alt icon-lg leading-tight align-middle'>{icon}</span>
|
||||
<div className='text-primary py-1 text-left'>
|
||||
<span className='text-primary-alt icon-lg inline align-middle mr-1'>account_circle</span>
|
||||
<p className='h-4 inline pl-1 font-sans-alt text-accent'>{username}</p>
|
||||
</div>
|
||||
<button className='text-primary bg-hover py-1 text-left' onClick={logout} type='button'>
|
||||
<span className='text-primary-alt icon-lg inline align-middle mr-1'>logout</span>
|
||||
<p className='h-4 inline pl-1 font-sans-alt'>Logout</p>
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function CollapsedMenu() {
|
||||
const { isLoggedIn, login, logout } = useAccount({ redirectReturnToUrl: window.location.origin });
|
||||
const { label, icon, action } = getButtonValues(isLoggedIn, login, logout);
|
||||
function SideBarItem({ isCollapsed, onNavigate }) {
|
||||
const [isExpanded, setExpanded] = useState(false);
|
||||
const menuRef = useRef(null);
|
||||
const {
|
||||
isLoggedIn,
|
||||
isAuthenticating,
|
||||
username,
|
||||
userEmail,
|
||||
openAuthModal,
|
||||
logout,
|
||||
authModalOpen,
|
||||
closeAuthModal,
|
||||
handleAuthSuccess,
|
||||
} = useAccount();
|
||||
|
||||
useClickListener(menuRef, () => setExpanded(false), true);
|
||||
|
||||
if (isAuthenticating) {
|
||||
return (
|
||||
<div className='sidebar-nav-link w-full text-left'>
|
||||
<Spinner size={Spinner.SIZE.sm} />
|
||||
{!isCollapsed && <span className='sidebar-nav-link-label'>Loading...</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isLoggedIn) {
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className='sidebar-nav-link w-full text-left'
|
||||
type='button'
|
||||
onClick={() => {
|
||||
openAuthModal();
|
||||
if (onNavigate) {
|
||||
onNavigate();
|
||||
}
|
||||
}}
|
||||
title={isCollapsed ? 'Login' : undefined}
|
||||
>
|
||||
<span className='sidebar-nav-link-icon icon-base'>login</span>
|
||||
{!isCollapsed && <span className='sidebar-nav-link-label'>Login</span>}
|
||||
</button>
|
||||
<AuthModal isOpen={authModalOpen} setIsOpen={closeAuthModal} onAuthSuccess={handleAuthSuccess} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button className='text-primary bg-hover py-1 text-left' onClick={() => action()} type='button'>
|
||||
<span className='text-primary-alt icon-lg inline align-middle mr-1'>{icon}</span>
|
||||
<p className='h-4 inline pl-1 font-sans-alt'>{label}</p>
|
||||
</button>
|
||||
<div className='relative' ref={menuRef}>
|
||||
<button
|
||||
className='sidebar-nav-link w-full text-left'
|
||||
type='button'
|
||||
onClick={() => setExpanded(!isExpanded)}
|
||||
title={isCollapsed ? username : undefined}
|
||||
>
|
||||
<span className='sidebar-nav-link-icon icon-base'>account_circle</span>
|
||||
{!isCollapsed && (
|
||||
<>
|
||||
<span className='sidebar-nav-link-label'>{username}</span>
|
||||
<span className='ml-auto icon-sm text-primary-alt'>{isExpanded ? 'expand_less' : 'expand_more'}</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
{isExpanded && !isCollapsed && (
|
||||
<div className='bg-secondary-alt pl-4'>
|
||||
{userEmail && (
|
||||
<div className='sidebar-nav-link w-full text-left text-sm text-secondary'>
|
||||
<span className='sidebar-nav-link-icon icon-base text-primary-alt'>mail</span>
|
||||
<span className='sidebar-nav-link-label text-xs'>{userEmail}</span>
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
className='sidebar-nav-link w-full text-left text-sm'
|
||||
onClick={() => {
|
||||
logout();
|
||||
setExpanded(false);
|
||||
if (onNavigate) {
|
||||
onNavigate();
|
||||
}
|
||||
}}
|
||||
type='button'
|
||||
>
|
||||
<span className='sidebar-nav-link-icon icon-base text-primary-alt'>logout</span>
|
||||
<span className='sidebar-nav-link-label'>Logout</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getButtonValues(isLoggedIn, login, logout) {
|
||||
return {
|
||||
label: isLoggedIn ? 'Logout' : 'Login',
|
||||
icon: isLoggedIn ? 'logout' : 'login',
|
||||
action: isLoggedIn ? logout : login,
|
||||
};
|
||||
}
|
||||
|
||||
export default { NavBarItem, CollapsedMenu };
|
||||
export default { NavBarItem, CollapsedMenu, SideBarItem };
|
||||
|
||||
Reference in New Issue
Block a user