85 lines
3.3 KiB
Vue
85 lines
3.3 KiB
Vue
<template>
|
|
<div class="min-h-screen flex flex-col bg-gray-50 dark:bg-gray-950 transition-colors duration-300 font-sans" :class="{ 'lg:h-screen': $route.name === 'editor' }">
|
|
<!-- Navbar -->
|
|
<Navbar @open-help="openHelpModal" />
|
|
|
|
<div class="flex flex-col flex-1 relative z-10 p-4 sm:p-6 lg:p-8 pt-6" :class="{ 'lg:overflow-hidden': $route.name === 'editor' }">
|
|
<Breadcrumbs class="mb-6" />
|
|
|
|
<router-view v-slot="{ Component }">
|
|
<component :is="Component" />
|
|
</router-view>
|
|
</div>
|
|
|
|
<HelpModal :is-open="isHelpModalOpen" @close="closeHelpModal" />
|
|
<FeedbackModal :is-open="isFeedbackModalOpen" @close="closeFeedbackModal" />
|
|
|
|
<!-- One-time feedback popup -->
|
|
<div v-if="showFeedbackPopup" class="fixed bottom-6 right-6 z-50 flex items-center justify-center">
|
|
<div class="max-w-sm p-4 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-2xl glass-panel relative">
|
|
<button @click="handleFeedbackPopupResponse(false)" class="absolute top-2 right-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200" title="Close">
|
|
<i class="fas fa-times text-sm"></i>
|
|
</button>
|
|
<div class="flex gap-4">
|
|
<div class="text-3xl">💬</div>
|
|
<div>
|
|
<h3 class="text-sm font-bold text-gray-900 dark:text-gray-100 mb-1">Help us improve!</h3>
|
|
<p class="text-xs text-gray-600 dark:text-gray-300 mb-3 leading-relaxed">Enjoying Spritesheet Generator? We'd love your feedback.</p>
|
|
<div class="flex gap-2">
|
|
<button @click="handleFeedbackPopupResponse(true)" class="px-3 py-1.5 text-xs font-medium text-white bg-indigo-600 hover:bg-indigo-700 rounded-lg transition-colors shadow-sm">Share feedback</button>
|
|
<button @click="handleFeedbackPopupResponse(false)" class="px-3 py-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-colors">No thanks</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue';
|
|
import { RouterView } from 'vue-router';
|
|
import Navbar from './components/layout/Navbar.vue';
|
|
import HelpModal from './components/HelpModal.vue';
|
|
import FeedbackModal from './components/FeedbackModal.vue';
|
|
import Breadcrumbs from './components/Breadcrumbs.vue';
|
|
|
|
const isHelpModalOpen = ref(false);
|
|
const isFeedbackModalOpen = ref(false);
|
|
const showFeedbackPopup = ref(false);
|
|
|
|
const openHelpModal = () => {
|
|
isHelpModalOpen.value = true;
|
|
};
|
|
|
|
const closeHelpModal = () => {
|
|
isHelpModalOpen.value = false;
|
|
};
|
|
|
|
const openFeedbackModal = () => {
|
|
isFeedbackModalOpen.value = true;
|
|
};
|
|
|
|
const closeFeedbackModal = () => {
|
|
isFeedbackModalOpen.value = false;
|
|
};
|
|
|
|
onMounted(() => {
|
|
const hasShownFeedbackPopup = localStorage.getItem('hasShownFeedbackPopup');
|
|
if (!hasShownFeedbackPopup) {
|
|
setTimeout(() => {
|
|
showFeedbackPopup.value = true;
|
|
}, 10000);
|
|
}
|
|
});
|
|
|
|
const handleFeedbackPopupResponse = (showModal: boolean) => {
|
|
showFeedbackPopup.value = false;
|
|
localStorage.setItem('hasShownFeedbackPopup', 'true');
|
|
|
|
if (showModal) {
|
|
openFeedbackModal();
|
|
}
|
|
};
|
|
</script>
|