Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: added profile dropdown and logout #1887

Merged
merged 1 commit into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 71 additions & 5 deletions nuxt-pinia-tailwind/components/TheNavBar/TheNavBar.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,79 @@
<template>
<header class="bg-gray-900 flex justify-between items-center py-4 px-8">
<div>
<nuxt-link to="/">
<GithubLogo />
</nuxt-link>
<nuxt-link to="/">
<GithubLogo />
</nuxt-link>
<div
v-closable="{ exclude: ['button'], handler: 'onClose' }"
class="relative"
>
<button
class="w-10 h-10 bg-slate-400 rounded-full"
@click="showDropdown = !showDropdown"
>
<img
:src="avatarURL"
alt="user avatar"
class="w-full h-full rounded-full"
/>
</button>
<div
v-if="showDropdown"
class="absolute right-0 top-12 bg-white rounded-lg w-40 z-40 shadow-lg"
>
<nuxt-link
to="hdjerry"
class="flex justify-center items-center p-2 font-medium text-center w-full"
@click="onClose"
>
{{ username }}
</nuxt-link>
<button
class="border-t border-t-slate-300 flex justify-center items-center p-2 w-full h-full cursor-pointer"
@click="signOut"
>
Sign Out
</button>
</div>
</div>
</header>
</template>

<script lang="ts">
export default {};
import {
useContext,
ref,
computed,
defineComponent,
} from '@nuxtjs/composition-api';

export default defineComponent({
setup() {
const { $auth } = useContext();
const showDropdown = ref<boolean>(false);

const onClose = () => {
showDropdown.value = false;
};

const signOut = async () => {
try {
await $auth.logout();
} catch (error: any) {
throw new Error(error);
}
};

const avatarURL = computed(() => $auth.user.avatar_url);
const username = computed(() => $auth.user.login);

return {
showDropdown,
onClose,
signOut,
avatarURL,
username,
};
},
});
</script>
50 changes: 50 additions & 0 deletions nuxt-pinia-tailwind/layouts/LoggedIn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,53 @@
<Nuxt />
</div>
</template>

<script lang="ts">
import Vue from 'vue';
import { DirectiveBinding } from 'vue/types/options';

let handleOutsideClick: (e: any) => void;
Vue.directive('closable', {
bind(el: HTMLElement, binding: DirectiveBinding, vnode: any) {
// Here's the click/touchstart handler
// (it is registered below)
handleOutsideClick = (e) => {
e.stopPropagation();
// Get the handler method name and the exclude array
// from the object used in v-closable
const { handler, exclude } = binding.value;
// This variable indicates if the clicked element is excluded
let clickedOnExcludedEl = false;
exclude.forEach((refName: string) => {
// We only run this code if we haven't detected
// any excluded element yet
if (!clickedOnExcludedEl) {
// Get the element using the reference name
const excludedEl = vnode.context.$refs[refName];
// See if this excluded element
// is the same element the user just clicked on
clickedOnExcludedEl = excludedEl?.contains(e.target);
}
});
// We check to see if the clicked element is not
// the dialog element and not excluded
if (!el.contains(e.target) && !clickedOnExcludedEl) {
// If the clicked element is outside the dialog
// and not the button, then call the outside-click handler
// from the same component this directive is used in
vnode?.context[handler]();
}
};
// Register click/touchstart event listeners on the whole page
document.addEventListener('click', handleOutsideClick);
document.addEventListener('touchstart', handleOutsideClick);
},
unbind() {
// If the element that has v-closable is removed, then
// unbind click/touchstart listeners from the whole page
document.removeEventListener('click', handleOutsideClick);
document.removeEventListener('touchstart', handleOutsideClick);
},
});
export default {};
</script>
Loading