Files
miniplan/public/src/App.vue
T
walamana 87812d02d3
Deploy Miniplan / build (push) Successful in 59s
feat: show notification to install miniplan as app
2026-07-21 16:38:05 +02:00

150 lines
3.4 KiB
Vue

<script setup lang="ts">
import {RouterLink, RouterView} from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
import LoginPanel from "@/components/LoginPanel.vue";
import {onMounted, ref} from "vue";
import {Auth} from "@/services/auth";
import DialogHost from "@/components/dialog/DialogHost.vue";
import {LoginService} from "@/services/LoginService";
import {Dialogs} from "@/services/DialogService";
import InstallPWADialog from "@/components/dialog/InstallPWADialog.vue";
let showPopup = ref(false)
let loggedIn = ref(false)
Auth.loggedInSubject.subscribe((isLoggedIn) => {
loggedIn.value = isLoggedIn
})
function logout(){
Auth.logout()
}
function print(){
window.print()
}
onMounted(async () => {
Auth.checkForToken()
if (Auth.getToken()) {
await Auth.refreshToken()
}
})
LoginService.subject.subscribe(() => {
showPopup.value = true
})
const installEvent = ref<Event>()
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault()
console.log("beforeinstallprompt")
installEvent.value = e
scheduleInstallDialog()
})
function scheduleInstallDialog() {
if (isPwa()) return
if (localStorage.getItem('installPromptDismissed')) return
if (!installEvent.value) return
Dialogs.createDialog(InstallPWADialog, {
onPositive(dontShowAgain: boolean) {
if (dontShowAgain) localStorage.setItem('installPromptDismissed', 'true')
;(installEvent.value as any).prompt()
},
onNegative(dontShowAgain: boolean) {
if (dontShowAgain) localStorage.setItem('installPromptDismissed', 'true')
},
onDismiss() {}
}, {})
}
function isPwa() {
return window.matchMedia('(display-mode: standalone)').matches
}
window.addEventListener('appinstalled', () => {
localStorage.setItem('installPromptDismissed', 'true')
})
</script>
<template>
<nav class="no-print">
<div class="left">
<img src="./assets/minis_logo.png" style="height: 40px"/>
Miniplan App
</div>
<div class="right">
<button class="flat" @click="print"><i>print</i>Drucken</button>
<button v-if="!loggedIn" class="flat" @click="showPopup = true"><i>login</i> Einloggen</button>
<button v-if="loggedIn" class="flat" @click="logout"><i>logout</i> Abmelden</button>
</div>
</nav>
<RouterView/>
<div class="popup-container" :class="{show: showPopup}" @click.self="showPopup = false">
<LoginPanel :active="showPopup" @success="showPopup = false"/>
</div>
<DialogHost/>
</template>
<style scoped lang="less">
nav {
display: flex;
align-items: center;
padding: 10px 32px;
border-bottom: 1px solid #d7d5d5;
font-weight: 700;
.left {
display: flex;
align-items: center;
width: 100%;
gap: 20px;
}
.right {
flex-shrink: 0;
}
@media print{
display: none;
}
}
.popup-container {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
background: rgba(0, 0, 0, 0.3);
transition: 200ms opacity;
opacity: 0;
pointer-events: none;
* {
pointer-events: none;
}
&.show {
pointer-events: auto;
* {
pointer-events: auto;
}
opacity: 1;
}
}
</style>