feat: Integrate Logout Confirmation Dialog in Navbar

- Add a state variable to manage the visibility of the Logout Confirmation dialog in Navbar.vue.
- Update the LogoutConfirmDialog component to accept an isOpen prop and emit an update event for improved visibility control.
- Refactor the logout button in Navbar.vue to trigger the confirmation dialog, enhancing user experience by preventing accidental logouts.
This commit is contained in:
padreug 2025-08-10 23:09:10 +02:00
parent a27e4f41a6
commit 1631c23717
2 changed files with 20 additions and 6 deletions

View file

@ -27,6 +27,7 @@ const { theme, setTheme } = useTheme()
const isOpen = ref(false) const isOpen = ref(false)
const showLoginDialog = ref(false) const showLoginDialog = ref(false)
const showProfileDialog = ref(false) const showProfileDialog = ref(false)
const showLogoutConfirm = ref(false)
const marketPreloader = useMarketPreloader() const marketPreloader = useMarketPreloader()
const navigation = computed<NavigationItem[]>(() => [ const navigation = computed<NavigationItem[]>(() => [
@ -242,10 +243,10 @@ const handleLogout = async () => {
<Activity class="h-4 w-4" /> <Activity class="h-4 w-4" />
Relay Hub Status Relay Hub Status
</Button> </Button>
<LogoutConfirmDialog variant="destructive" size="sm" class="w-full justify-start gap-2" @confirm="handleLogout"> <Button variant="destructive" size="sm" class="w-full justify-start gap-2" @click="() => showLogoutConfirm = true">
<LogOut class="h-4 w-4" /> <LogOut class="h-4 w-4" />
Logout Logout
</LogoutConfirmDialog> </Button>
</div> </div>
</div> </div>
</div> </div>
@ -278,5 +279,8 @@ const handleLogout = async () => {
<!-- Profile Dialog --> <!-- Profile Dialog -->
<ProfileDialog v-model:is-open="showProfileDialog" /> <ProfileDialog v-model:is-open="showProfileDialog" />
<!-- Logout Confirmation Dialog -->
<LogoutConfirmDialog v-model:is-open="showLogoutConfirm" @confirm="handleLogout" />
</nav> </nav>
</template> </template>

View file

@ -14,10 +14,12 @@ interface Props {
size?: 'default' | 'sm' | 'lg' | 'icon' size?: 'default' | 'sm' | 'lg' | 'icon'
class?: string class?: string
children?: any children?: any
isOpen?: boolean
} }
interface Emits { interface Emits {
(e: 'confirm'): void (e: 'confirm'): void
(e: 'update:isOpen', value: boolean): void
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
@ -27,14 +29,22 @@ const props = withDefaults(defineProps<Props>(), {
// Default classes for the logout button styling // Default classes for the logout button styling
const defaultClasses = computed(() => { const defaultClasses = computed(() => {
if (props.class) return props.class const baseClasses = 'gap-2 text-destructive hover:text-destructive/90 hover:bg-destructive/10'
if (props.class) {
// Merge custom classes with base classes, ensuring red styling is preserved
return `${props.class} ${baseClasses}`
}
// Default styling that matches the original red logout button // Default styling that matches the original red logout button
return 'gap-2 text-destructive hover:text-destructive/90 hover:bg-destructive/10' return baseClasses
}) })
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
const isOpen = ref(false) const isOpen = computed({
get: () => props.isOpen ?? false,
set: (value: boolean) => emit('update:isOpen', value)
})
const handleConfirm = () => { const handleConfirm = () => {
isOpen.value = false isOpen.value = false
@ -48,7 +58,7 @@ const handleCancel = () => {
<template> <template>
<Dialog v-model:open="isOpen"> <Dialog v-model:open="isOpen">
<DialogTrigger as-child> <DialogTrigger v-if="props.isOpen === undefined" as-child>
<slot> <slot>
<Button :variant="variant" :size="size" :class="defaultClasses"> <Button :variant="variant" :size="size" :class="defaultClasses">
<LogOut class="h-4 w-4" /> <LogOut class="h-4 w-4" />