Initial commit

This commit is contained in:
2026-04-17 23:26:01 +00:00
commit 2ea4ca5d52
409 changed files with 63459 additions and 0 deletions

150
app/app.vue Normal file
View File

@@ -0,0 +1,150 @@
<template>
<UApp
:locale="locales[locale]"
>
<div class="inside-safe-area">
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</div>
</UApp>
</template>
<script setup lang="ts">
import * as locales from '@nuxt/ui/locale'
import type { URLOpenListenerEvent } from '@capacitor/app'
import { Capacitor } from '@capacitor/core'
import { App } from '@capacitor/app'
import type {
Token,
ActionPerformed,
PushNotificationSchema } from '@capacitor/push-notifications'
import {
PushNotifications
} from '@capacitor/push-notifications'
import type { UsersLanguageOptions } from './types/pocketbase.types'
const { locale, t, setLocale } = useI18n()
const lang = computed(() => locales[locale.value].code)
const dir = computed(() => locales[locale.value].dir)
useHead({
meta: [
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
],
link: [
{ rel: 'icon', href: '/favicon.ico' }
],
htmlAttrs: {
lang,
dir
}
})
const title = t('hero.title')
const description = t('hero.description')
useSeoMeta({
title,
description,
ogTitle: title,
ogDescription: description
})
const { isAuthenticated } = storeToRefs(useUser())
const { addFcmToken } = useNotifications()
const toast = useToast()
const registerPushNotifications = async () => {
if (Capacitor.isNativePlatform() && isAuthenticated.value) {
// Request permission to use push notifications
// iOS will prompt user and return if they granted permission or not
// Android will just grant without prompting
PushNotifications.requestPermissions().then((result) => {
if (result.receive === 'granted') {
// Register with Apple / Google to receive push via APNS/FCM
PushNotifications.register()
} else {
// Show some error
}
})
// On success, we should be able to receive notifications
PushNotifications.addListener('registration',
(token: Token) => {
// Add the FCM token for the current user
addFcmToken(token.value)
}
)
// Some issue with our setup and push will not work
PushNotifications.addListener('registrationError',
(error) => {
console.warn('Error on push notification registration:', JSON.stringify(error))
}
)
// Show the notification payload as toast message if the app is open on our device
PushNotifications.addListener('pushNotificationReceived',
(notification: PushNotificationSchema) => {
toast.add({
title: notification.title,
description: notification.subtitle ?? notification.body,
color: 'primary'
})
}
)
// Method called when tapping on a notification
PushNotifications.addListener('pushNotificationActionPerformed',
(notification: ActionPerformed) => {
console.log('Push action performed:', JSON.stringify(notification))
}
)
}
}
// handle locale based on user prefs
const { updateUser, user } = useUser()
watch(isAuthenticated, async () => {
if (isAuthenticated.value) {
// Fetch the user profile after successful sign-in
const prefLanguage = user?.language
if (prefLanguage) {
// Set the locale based on the user's profile locale
setLocale(prefLanguage)
} else {
// If the locale was not yet saved to the profile, update it
updateUser({ language: locale.value as UsersLanguageOptions })
}
// Register push notifications after successful sign-in
registerPushNotifications()
}
}, { immediate: true })
// Activate Capacitor features if we are on native platform (Android/iOS)
if (Capacitor.isNativePlatform()) {
const router = useRouter()
// Register and handle deep links
App.addListener('appUrlOpen', function (event: URLOpenListenerEvent) {
const slug = event.url.split('.app').pop()
if (slug) {
router.push({
path: slug
})
}
})
}
</script>
<style>
/* Safe area insets needed for mobile app to avoid notches and safe areas */
.inside-safe-area {
margin-top: env(safe-area-inset-top, unset);
padding-right: env(safe-area-inset-right, unset);
padding-bottom: env(safe-area-inset-bottom, unset);
padding-left: env(safe-area-inset-left, unset);
}
</style>