parent
754ea69bc6
commit
8d923c4135
8 changed files with 146 additions and 116 deletions
@ -0,0 +1,51 @@ |
|||||||
|
<div class='relative block hidden' id='account-dropdown'> |
||||||
|
<button |
||||||
|
class='flex h-8 w-24 items-center justify-center rounded-full bg-gradient-to-r from-blue-500 to-blue-700 py-2 px-4 text-sm font-medium text-white hover:from-blue-500 hover:to-blue-600' |
||||||
|
type='button' |
||||||
|
data-account-button |
||||||
|
> |
||||||
|
<span>Account</span> |
||||||
|
</button> |
||||||
|
|
||||||
|
<div |
||||||
|
class='absolute right-0 z-10 mt-2 hidden w-48 rounded-md bg-slate-800 py-1 shadow-xl' |
||||||
|
> |
||||||
|
<ul> |
||||||
|
<li class='px-1'> |
||||||
|
<a |
||||||
|
href='/profile' |
||||||
|
class='block rounded px-4 py-2 text-sm font-medium text-slate-100 hover:bg-slate-700' |
||||||
|
> |
||||||
|
Your Profile |
||||||
|
</a> |
||||||
|
</li> |
||||||
|
<li class='px-1'> |
||||||
|
<button |
||||||
|
class='block w-full rounded px-4 py-2 text-left text-sm font-medium text-slate-100 hover:bg-slate-700' |
||||||
|
type='button' |
||||||
|
data-logout-button |
||||||
|
> |
||||||
|
Logout |
||||||
|
</button> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Cookies from 'js-cookie'; |
||||||
|
import { TOKEN_COOKIE_NAME } from '../../lib/utils'; |
||||||
|
|
||||||
|
const accountButton = document.querySelector('[data-account-button]'); |
||||||
|
const accountMenu = accountButton?.nextElementSibling; |
||||||
|
const logoutButton = accountMenu?.querySelector('[data-logout-button]'); |
||||||
|
|
||||||
|
accountButton?.addEventListener('click', () => { |
||||||
|
accountMenu?.classList.toggle('hidden'); |
||||||
|
}); |
||||||
|
|
||||||
|
logoutButton?.addEventListener('click', () => { |
||||||
|
Cookies.remove(TOKEN_COOKIE_NAME); |
||||||
|
window.location.reload(); |
||||||
|
}); |
||||||
|
</script> |
@ -0,0 +1,40 @@ |
|||||||
|
--- |
||||||
|
import Spinner from '../Spinner.astro'; |
||||||
|
import AccountDropdown from './AccountDropdown.astro'; |
||||||
|
--- |
||||||
|
|
||||||
|
<div> |
||||||
|
<div |
||||||
|
class='flex h-8 w-24 items-center justify-center rounded-full bg-gradient-to-r from-blue-500 to-blue-700 py-2 px-4 text-sm text-white hover:from-blue-500 hover:to-blue-600' |
||||||
|
id='navigation-spinner' |
||||||
|
> |
||||||
|
<Spinner className='text-white' /> |
||||||
|
</div> |
||||||
|
|
||||||
|
<AccountDropdown /> |
||||||
|
|
||||||
|
<a |
||||||
|
id='register-button' |
||||||
|
class='hidden flex h-8 w-24 cursor-pointer items-center justify-center rounded-full bg-gradient-to-r from-blue-500 to-blue-700 py-2 px-4 text-sm font-medium text-white hover:from-blue-500 hover:to-blue-600' |
||||||
|
href='/signup' |
||||||
|
> |
||||||
|
<span>Register</span> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Cookies from 'js-cookie'; |
||||||
|
import { TOKEN_COOKIE_NAME } from '../../lib/utils'; |
||||||
|
const spinner = document.getElementById('navigation-spinner'); |
||||||
|
const registerButton = document.getElementById('register-button'); |
||||||
|
const accountDropdown = document.getElementById('account-dropdown'); |
||||||
|
spinner?.classList.add('hidden'); |
||||||
|
|
||||||
|
const token = Cookies.get(TOKEN_COOKIE_NAME); |
||||||
|
|
||||||
|
if (token) { |
||||||
|
accountDropdown?.classList.remove('hidden'); |
||||||
|
} else { |
||||||
|
registerButton?.classList.remove('hidden'); |
||||||
|
} |
||||||
|
</script> |
@ -1,56 +0,0 @@ |
|||||||
import Cookies from 'js-cookie'; |
|
||||||
import { TOKEN_COOKIE_NAME } from '../../lib/utils'; |
|
||||||
import { useEffect, useState } from 'preact/hooks'; |
|
||||||
|
|
||||||
export default function AccountDropdown() { |
|
||||||
const [isOpen, setIsOpen] = useState(false); |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
// If user click outside the dropdown, and dropdown is open then close it.
|
|
||||||
const handleOpen = () => { |
|
||||||
if (isOpen) setIsOpen(false); |
|
||||||
}; |
|
||||||
|
|
||||||
document.addEventListener('click', handleOpen); |
|
||||||
return () => document.removeEventListener('click', handleOpen); |
|
||||||
}, [isOpen]); |
|
||||||
|
|
||||||
return ( |
|
||||||
<div className="relative"> |
|
||||||
<button |
|
||||||
className="flex h-8 w-24 items-center justify-center rounded-full bg-gradient-to-r from-blue-500 to-blue-700 py-2 px-4 text-sm font-medium text-white hover:from-blue-500 hover:to-blue-600" |
|
||||||
onClick={() => setIsOpen((p) => !p)} |
|
||||||
> |
|
||||||
<span>Account</span> |
|
||||||
</button> |
|
||||||
|
|
||||||
<div |
|
||||||
className={`absolute right-0 z-10 mt-2 w-48 rounded-md bg-slate-800 py-1 shadow-xl ${ |
|
||||||
isOpen ? 'block' : 'hidden' |
|
||||||
}`}
|
|
||||||
> |
|
||||||
<ul> |
|
||||||
<li className="px-1"> |
|
||||||
<a |
|
||||||
href="/profile" |
|
||||||
className="block rounded px-4 py-2 text-sm font-medium text-slate-100 hover:bg-slate-700" |
|
||||||
> |
|
||||||
Your Profile |
|
||||||
</a> |
|
||||||
</li> |
|
||||||
<li className="px-1"> |
|
||||||
<button |
|
||||||
className="block w-full rounded px-4 py-2 text-left text-sm font-medium text-slate-100 hover:bg-slate-700" |
|
||||||
onClick={() => { |
|
||||||
Cookies.remove(TOKEN_COOKIE_NAME); |
|
||||||
window.location.reload(); |
|
||||||
}} |
|
||||||
> |
|
||||||
Logout |
|
||||||
</button> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
@ -1,55 +0,0 @@ |
|||||||
import { useAuth } from '../../hooks/use-auth'; |
|
||||||
import AccountDropdown from './account-dropdown'; |
|
||||||
|
|
||||||
export default function AccountNavigation() { |
|
||||||
const { user, isLoading } = useAuth(); |
|
||||||
|
|
||||||
console.log('user', user, isLoading); |
|
||||||
|
|
||||||
return ( |
|
||||||
<div> |
|
||||||
{isLoading ? ( |
|
||||||
<div className="flex h-8 w-24 items-center justify-center rounded-full bg-gradient-to-r from-blue-500 to-blue-700 py-2 px-4 text-sm text-white hover:from-blue-500 hover:to-blue-600"> |
|
||||||
<Spinner className="text-white" /> |
|
||||||
</div> |
|
||||||
) : ( |
|
||||||
<> |
|
||||||
{user ? ( |
|
||||||
<AccountDropdown /> |
|
||||||
) : ( |
|
||||||
<a |
|
||||||
className="flex h-8 w-24 cursor-pointer items-center justify-center rounded-full bg-gradient-to-r from-blue-500 to-blue-700 py-2 px-4 text-sm font-medium text-white hover:from-blue-500 hover:to-blue-600" |
|
||||||
href="/signup" |
|
||||||
> |
|
||||||
<span>Register</span> |
|
||||||
</a> |
|
||||||
)} |
|
||||||
</> |
|
||||||
)} |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
export function Spinner({ className }: { className?: string }) { |
|
||||||
return ( |
|
||||||
<svg |
|
||||||
className={`h-5 w-5 animate-spin ${className}`} |
|
||||||
xmlns="http://www.w3.org/2000/svg" |
|
||||||
fill="none" |
|
||||||
viewBox="0 0 24 24" |
|
||||||
> |
|
||||||
<circle |
|
||||||
className="stroke-[4px] opacity-25" |
|
||||||
cx={12} |
|
||||||
cy={12} |
|
||||||
r={10} |
|
||||||
stroke="currentColor" |
|
||||||
/> |
|
||||||
<path |
|
||||||
className="opacity-75" |
|
||||||
fill="currentColor" |
|
||||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" |
|
||||||
/> |
|
||||||
</svg> |
|
||||||
); |
|
||||||
} |
|
@ -0,0 +1,23 @@ |
|||||||
|
--- |
||||||
|
const { className = '', ...rest } = Astro.props; |
||||||
|
--- |
||||||
|
|
||||||
|
<svg |
||||||
|
class={`animate-spin h-5 w-5 ${className}`} |
||||||
|
xmlns='http://www.w3.org/2000/svg' |
||||||
|
fill='none' |
||||||
|
viewBox='0 0 24 24' |
||||||
|
{...rest} |
||||||
|
> |
||||||
|
<circle |
||||||
|
class='stroke-[4px] opacity-25' |
||||||
|
cx='12' |
||||||
|
cy='12' |
||||||
|
r='10' |
||||||
|
stroke='currentColor'></circle> |
||||||
|
<path |
||||||
|
class='opacity-75' |
||||||
|
fill='currentColor' |
||||||
|
d='M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z' |
||||||
|
></path> |
||||||
|
</svg> |
After Width: | Height: | Size: 754 B |
Loading…
Reference in new issue