Files
takerofnotes-website/components/PreviewBanner.vue
2026-06-01 11:08:03 -04:00

107 lines
2.4 KiB
Vue

<template>
<div v-if="isPreview" class="preview-banner theme-dark">
<div class="preview-banner__content">
<div class="preview-banner__info">
<span class="preview-banner__label">Preview Mode</span>
<span class="preview-banner__status">{{ status }}</span>
</div>
<a
:href="exitPreviewUrl"
class="preview-banner__exit"
@click="exitPreview"
>
Exit Preview
</a>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
isPreview: {
type: Boolean,
default: false,
},
status: {
type: String,
default: 'published',
},
})
const exitPreviewUrl = computed(() => {
if (typeof window === 'undefined') return '/'
const url = new URL(window.location.href)
url.searchParams.delete('preview')
url.searchParams.delete('status')
url.searchParams.delete('documentId')
url.searchParams.delete('uid')
return url.toString()
})
const exitPreview = (event) => {
// For better UX, we can use client-side navigation instead of full page reload
event.preventDefault()
if (typeof window !== 'undefined') {
window.location.href = exitPreviewUrl.value
}
}
</script>
<style lang="scss" scoped>
.preview-banner {
position: fixed;
top: 0;
left: 0;
right: 0;
background: var(--theme-accent);
color: var(--theme-bg);
z-index: 9999;
padding: 8px 16px;
&__content {
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1200px;
margin: 0 auto;
font-size: 14px;
font-weight: 500;
}
&__info {
display: flex;
align-items: center;
gap: 12px;
}
&__label {
font-weight: 600;
}
&__status {
background: rgba(255, 255, 255, 0.2);
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
text-transform: capitalize;
}
&__exit {
color: var(--theme-bg);
text-decoration: none;
padding: 4px 12px;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 4px;
transition: all 0.2s ease;
&:hover {
background: rgba(255, 255, 255, 0.15);
border-color: rgba(255, 255, 255, 0.5);
}
}
}
</style>