feat: add notes app

This commit is contained in:
2026-10-01 19:39:20 +02:00
parent ccb8dd3d15
commit ddbb6f37b5
35 changed files with 706 additions and 52 deletions
+11
View File
@@ -0,0 +1,11 @@
<script setup lang="ts">
// Shows its content only after the shared password has been entered
defineProps<{ title: string }>()
const { data: session, refresh } = await useFetch<{ unlocked: boolean }>('/api/auth/session', { key: 'auth-session' })
</script>
<template>
<slot v-if="session?.unlocked" />
<PasswordModal v-else :title="title" @unlocked="refresh()" />
</template>
+36
View File
@@ -0,0 +1,36 @@
<script setup lang="ts">
defineProps<{ title: string }>()
const emit = defineEmits<{ unlocked: [] }>()
const password = ref('')
const error = ref<string>()
const unlocking = ref(false)
async function unlock() {
if (!password.value) return
unlocking.value = true
error.value = undefined
try {
await $fetch('/api/auth/login', { method: 'POST', body: { password: password.value } })
emit('unlocked')
} catch (e) {
error.value = errorMessage(e) ?? 'Couldn\'t unlock'
password.value = ''
} finally {
unlocking.value = false
}
}
</script>
<template>
<UModal :open="true" :dismissible="false" :close="false" :title="title" description="Enter your password to continue.">
<template #body>
<form class="space-y-4" @submit.prevent="unlock">
<UFormField label="Password" :error="error">
<UInput v-model="password" type="password" autocomplete="current-password" class="w-full" autofocus />
</UFormField>
<UButton type="submit" label="Unlock" icon="i-lucide-lock-open" :loading="unlocking" :disabled="!password" />
</form>
</template>
</UModal>
</template>
+10
View File
@@ -0,0 +1,10 @@
interface FetchErrorLike {
data?: { statusMessage?: string }
statusMessage?: string
message?: string
}
export function errorMessage(error: unknown): string | undefined {
const e = error as FetchErrorLike | null
return e?.data?.statusMessage || e?.statusMessage || e?.message
}