Tour and optimizations

Added driver js for virual tours.
Added conidtional homepage rendering.
Added localization for homepage and nav buttons
Added dynamic tour button to main navigation.
Separated changelog into a separate ts file.
Separated tour to ts file.
This commit is contained in:
Julio Ruiz 2026-05-31 23:01:45 -05:00
parent c827b3e711
commit 0a991082f5
11 changed files with 430 additions and 203 deletions

View File

@ -19,6 +19,9 @@
--color-carpablue: #2C4EA2; --color-carpablue: #2C4EA2;
--color-carpagreen: #6B8E23; --color-carpagreen: #6B8E23;
--color-carpared: #ff0000; --color-carpared: #ff0000;
--color-primary: #6B8E23;
--color-secondary: #2C4EA2;
} }
/* Colors for Typesense rich text */ /* Colors for Typesense rich text */

View File

@ -565,14 +565,18 @@ function metaLocation(meta: DocMeta | undefined): string {
> >
<UDashboardNavbar :title="t(navTitleKey)"> <UDashboardNavbar :title="t(navTitleKey)">
<template #leading> <template #leading>
<UDashboardSidebarCollapse /> <UDashboardSidebarCollapse :ui="{
base: 'collapse-sidebar-icon'
}" />
</template> </template>
<template #trailing> <template #trailing>
<UBadge :label="displayTotal" variant="subtle" /> <UBadge :label="displayTotal" variant="subtle" :ui="{
base: 'total-results'
}" />
</template> </template>
</UDashboardNavbar> </UDashboardNavbar>
<div class="px-4 sm:px-6 py-3 border-b border-default"> <div class="px-4 sm:px-6 py-3 border-b border-default" id="inputField">
<UInput <UInput
v-model="query" v-model="query"
icon="i-lucide-search" icon="i-lucide-search"

View File

@ -4,6 +4,9 @@ import { storeToRefs } from 'pinia'
import type { NavigationMenuItem } from '@nuxt/ui' import type { NavigationMenuItem } from '@nuxt/ui'
import { useFavoritesStore } from '~/stores/favorites' import { useFavoritesStore } from '~/stores/favorites'
import { useHistoryStore } from '~/stores/history' import { useHistoryStore } from '~/stores/history'
import { chatPalette } from '#build/ui'
const unlocked = ref(useDevMode())
const { locale, locales, setLocale } = useI18n() const { locale, locales, setLocale } = useI18n()
@ -18,28 +21,31 @@ const { total: favTotal } = storeToRefs(favorites)
const history = useHistoryStore() const history = useHistoryStore()
const { total: histTotal } = storeToRefs(history) const { total: histTotal } = storeToRefs(history)
const links = computed(() => { const links = computed(() => {
return [ const links = [
{ {
id: 'bible-studies',
label: t('nav.bible_studies'), label: t('nav.bible_studies'),
icon: 'ph:books', icon: 'ph-books',
to: '/estudios-biblicos', to: '/estudios-biblicos',
onSelect: () => { open.value = false } onSelect: () => { open.value = false },
}, },
{ {
id: 'conferences',
label: t('nav.conferences'), label: t('nav.conferences'),
icon: 'ph:books', icon: 'ph-books',
to: '/conferencias', to: '/conferencias',
onSelect: () => { open.value = false } onSelect: () => { open.value = false }
}, },
{ {
id: 'betweenthelines',
label: t('nav.between_the_lines'), label: t('nav.between_the_lines'),
icon: 'ph:list-magnifying-glass', icon: 'ph-list-magnifying-glass',
to: '/entrelineas', to: '/entrelineas',
onSelect: () => { open.value = false } onSelect: () => { open.value = false }
}, },
{ {
id: 'favorites',
label: t('nav.my_list'), label: t('nav.my_list'),
icon: 'i-lucide-bookmark', icon: 'i-lucide-bookmark',
to: '/favoritos', to: '/favoritos',
@ -47,6 +53,7 @@ const links = computed(() => {
onSelect: () => { open.value = false } onSelect: () => { open.value = false }
}, },
{ {
id: 'history',
label: t('nav.history'), label: t('nav.history'),
icon: 'i-lucide-history', icon: 'i-lucide-history',
to: '/historial', to: '/historial',
@ -54,24 +61,47 @@ const links = computed(() => {
onSelect: () => { open.value = false } onSelect: () => { open.value = false }
}, },
{ {
id: 'changelog',
label: t('nav.changelog'), label: t('nav.changelog'),
icon: 'i-lucide-megaphone', icon: 'i-lucide-megaphone',
to: '/changelog', to: '/changelog',
onSelect: () => { open.value = false } onSelect: () => { open.value = false }
}, },
{ {
id: 'settings',
label: t('nav.settings'), label: t('nav.settings'),
icon: 'i-lucide-settings', icon: 'i-lucide-settings',
to: '/configuracion', to: '/configuracion',
onSelect: () => { open.value = false } onSelect: () => { open.value = false }
}, },
{ {
id: 'feedback',
label: t('feedback.title'), label: t('feedback.title'),
icon: 'i-lucide-bug', icon: 'i-lucide-bug',
to: '/feedback', to: '/feedback',
onSelect: () => { open.value = false } onSelect: () => { open.value = false }
},
{
id: 'wizard',
class: 'hidden sm:flex mt-4 border-t-2 border-gray-300 pt-4',
label: t('nav.tour'),
icon: 'ph-student',
onSelect: () => start( tourConfig ),
chip: {
color: 'error'
}
} }
] satisfies NavigationMenuItem[] ] satisfies NavigationMenuItem[]
const homeLink = {
id: 'home',
label: t('nav.tour'),
icon: 'ph-house',
to: '/'
}
return [ homeLink,...links]
}) })
</script> </script>
@ -90,6 +120,7 @@ const links = computed(() => {
<div v-if="!collapsed" class="mt-2 flex justify-center"> <div v-if="!collapsed" class="mt-2 flex justify-center">
<img src="/logo.svg" class="w-full" alt="Buscador - La Gran Carpa Catedral" /> <img src="/logo.svg" class="w-full" alt="Buscador - La Gran Carpa Catedral" />
</div> </div>
<img v-if="collapsed" src="/logo_round.svg" class="w-full" alt="Buscador - La Gran Carpa Catedral" />
</template> </template>
<template #default="{ collapsed }"> <template #default="{ collapsed }">
@ -101,15 +132,29 @@ const links = computed(() => {
popover popover
color="neutral" color="neutral"
variant="link" variant="link"
/> >
<template #item="{item}">
<div :id="item.id" class="group relative w-full flex items-center gap-1.5 font-medium text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2 focus-visible:before:ring-inverted flex-row">
<UChip :color="item.chip?.color" :show="item.chip?.color ? true : false" inset>
<UIcon :name="item.icon" class="text-2xl" />
</UChip>
<div :class="!collapsed ? 'flex justify-between w-full' : 'hidden'" >{{ item.label }}
<UBadge v-if="item.badge" variant="outline" color="neutral" size="sm" :label="item.badge" />
</div>
</div>
</template>
</UNavigationMenu>
</template> </template>
<template #footer="{ collapsed }"> <template #footer="{ collapsed }">
<ULocaleSelect <div id="localeSelector">
:model-value="$i18n.locale.value" <ULocaleSelect
:locales="Object.values(locales)" :model-value="$i18n.locale.value"
@update:model-value="setLocale($event)" :locales="Object.values(locales)"
/> @update:model-value="setLocale($event)"
/>
</div>
</template> </template>
</UDashboardSidebar> </UDashboardSidebar>

View File

@ -1,127 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
const { $i18n } = useNuxtApp() const { $i18n } = useNuxtApp()
const t = $i18n.t const t = $i18n.t
interface ChangeEntry {
type: 'nuevo' | 'mejora' | 'fix' | 'eliminado'
text: string
}
interface Release {
version: string
date: string
title: string
description?: string
changes: ChangeEntry[]
}
const releases: Release[] = [
{
version: '0.6',
date: '31 de mayo, 2026',
title: 'Feedback con traducciones, bloqueo de Entrelíneas y acceso desarrollador',
changes: [
{ type: 'nuevo', text: 'Página de Feedback con traducciones completas en 4 idiomas' },
{ type: 'nuevo', text: 'Sistema de bloqueo por clave de desarrollador para secciones en desarrollo' },
{ type: 'nuevo', text: 'Acceso de desarrollador en Configuración con desbloqueo por clave' },
{ type: 'nuevo', text: 'Banner visual mejorado para Entrelíneas cuando está bloqueado' },
{ type: 'mejora', text: 'Traducciones añadidas al componente BugReportInput' },
{ type: 'mejora', text: 'Nombre del tab Feedback ahora usa traducciones' },
{ type: 'mejora', text: 'Textos del banner de Entrelíneas traducidos a 4 idiomas' }
]
},
{
version: '0.5',
date: '30 de mayo, 2026',
title: 'Soporte de HTML en Entrelíneas',
description: 'El visor de Entrelíneas ahora renderiza contenido en HTML además de texto plano.',
changes: [
{ type: 'nuevo', text: 'Renderizado de contenido HTML en el detalle de Entrelíneas' },
{ type: 'mejora', text: 'Los fragmentos HTML se muestran con formato original preservado' },
{ type: 'fix', text: 'Corrección de errores de sintaxis en el componente de detalle' },
{ type: 'mejora', text: 'El historial ahora muestra correctamente documentos de Entrelíneas con HTML' }
]
},
{
version: '0.4',
date: '26 de mayo, 2026',
title: 'Mejoras de interfaz y exploracion',
changes: [
{ type: 'mejora', text: 'El código del documento aparece visible en la pantalla de detalle' },
{ type: 'mejora', text: 'El badge "Borrador" solo se muestra cuando el documento es borrador' },
{ type: 'mejora', text: 'Tooltip mejorado al copiar párrafos al portapapeles' },
{ type: 'mejora', text: 'El explorador filtra resultados mostrando solo ítems con párrafos' },
{ type: 'mejora', text: 'Panel lateral preparado para notas y resaltados (próximamente)' },
{ type: 'fix', text: 'Posicionamiento del panel lateral corregido en documentos cortos' },
{ type: 'fix', text: 'Corrección de traducciones en francés' },
{ type: 'fix', text: 'Ajustes visuales en múltiples vistas' }
]
},
{
version: '0.3',
date: '25 de mayo, 2026',
title: 'Portapapeles y corrección de bugs',
changes: [
{ type: 'nuevo', text: 'Panel de copiado mejorado al seleccionar párrafos' },
{ type: 'mejora', text: 'Función de copiar al portapapeles más robusta e independiente' },
{ type: 'fix', text: 'Corrección de bug al guardar y mostrar favoritos' },
{ type: 'fix', text: 'Corrección de bug en la carga de referencias' },
{ type: 'fix', text: 'Corrección de bug en el detalle de publicaciones de referencia' }
]
},
{
version: '0.2',
date: '2124 de mayo, 2026',
title: 'Conferencias, copiar párrafos y estabilidad',
changes: [
{ type: 'nuevo', text: 'Soporte de documentos de Conferencias y Actividades' },
{ type: 'nuevo', text: 'Clic en párrafo para copiarlo directamente al portapapeles' },
{ type: 'nuevo', text: 'Zoom de imagen en el visor de Entrelíneas' },
{ type: 'mejora', text: 'Número de párrafo más discreto en el detalle del documento' },
{ type: 'mejora', text: 'Publicación del documento visible en todas las vistas y traducida' },
{ type: 'mejora', text: 'Corrección de estilos visuales para contenido antiguo' },
{ type: 'fix', text: 'Corrección de bug en favoritos (detalle)' },
{ type: 'fix', text: 'Badge "Borrador" agregado en lista y detalle de Estudios Bíblicos' },
{ type: 'fix', text: 'Rutas de navegación migradas correctamente a nuevo motor de búsqueda' },
{ type: 'fix', text: 'Corrección de scroll infinito en móvil para Entrelíneas' }
]
},
{
version: '0.1',
date: '1012 de mayo, 2026',
title: 'Historial, Favoritos y multilengua',
description: 'Primera versión funcional con las secciones principales activas.',
changes: [
{ type: 'nuevo', text: 'Historial de búsqueda y exploración' },
{ type: 'nuevo', text: 'Favoritos: guarda y accede a documentos desde Mi Listado' },
{ type: 'nuevo', text: 'Selector de idioma: Español, English, Français, Português' },
{ type: 'nuevo', text: 'Cantidad aproximada de resultados visible en los listados' },
{ type: 'mejora', text: 'Paginación configurable: scroll infinito o páginas numeradas' },
{ type: 'mejora', text: 'Ajuste de cantidad de resultados por página en Configuración' },
{ type: 'fix', text: 'Corrección de traducciones en el menú principal' },
{ type: 'fix', text: 'Ajustes de colores y badges en listas de resultados' }
]
},
{
version: '0.0.1',
date: '7 de mayo, 2026',
title: 'Lanzamiento inicial',
description: 'Primera versión del buscador con Estudios Bíblicos y Entrelíneas.',
changes: [
{ type: 'nuevo', text: 'Búsqueda en Estudios Bíblicos' },
{ type: 'nuevo', text: 'Visor de Entrelíneas con imagen y texto' },
{ type: 'nuevo', text: 'Búsqueda por palabras o por frase exacta' },
{ type: 'nuevo', text: 'Estructura base de la aplicación' }
]
}
]
const typeConfig: Record<ChangeEntry['type'], { label: string; color: string }> = {
nuevo: { label: 'Nuevo', color: 'success' },
mejora: { label: 'Mejora', color: 'info' },
fix: { label: 'Fix', color: 'warning' },
eliminado: { label: 'Eliminado', color: 'error' }
}
</script> </script>
<template> <template>

View File

@ -1,10 +1,79 @@
<script setup lang="ts"> <script setup lang="ts">
// Home redirects straight to the search experience. // Home redirects straight to the search experience.
definePageMeta({ import type { ButtonProps } from '@nuxt/ui'
middleware: () => navigateTo('/estudios-biblicos', { redirectCode: 302 }) import { useSettingsStore } from '~/stores/settings'
})
// const { unlocked } = useDevMode()
// if( !unlocked ){
// definePageMeta({
// middleware: () => navigateTo('/estudios-biblicos', { redirectCode: 302 })
// })
// }
const { $i18n } = useNuxtApp()
const t = $i18n.t
const release = releases[0]
const links = ref<ButtonProps[]>([
{
label: t('nav.tour'),
icon: 'ph-student',
color: 'error',
class: 'hidden sm:flex',
onClick: () => start( tourConfig )
},
{
label: t('nav.bible_studies'),
to: '/estudios-biblicos',
icon: 'ph-books',
color: 'primary'
},
{
label: t('nav.conferences'),
to: '/conferences',
icon: 'ph-books',
color: 'secondary'
},
])
</script> </script>
<template> <template>
<div />
<UDashboardPanel id="changelog-panel" grow>
<UDashboardNavbar :title="t('nav.home')">
<template #leading>
<UDashboardSidebarCollapse />
</template>
</UDashboardNavbar>
<UPage>
<UPageHero title="Buscador Carpa"
:description="$t('home.instructions')"
:headline="`${release?.date}`" orientation="horizontal"
:links="links"
>
<UPageCard variant="soft" icon="ph-git-branch" :title="release?.title" :description="release?.description">
<template #header>
v{{ release?.version }}
</template>
<!-- Lista de cambios -->
<ul class="space-y-2">
<li v-for="(change, i) in release?.changes" :key="i" class="flex items-start gap-2 text-sm">
<UBadge :color="typeConfig[change.type].color as any" variant="subtle" size="xs" class="mt-0.5 shrink-0">
{{ typeConfig[change.type].label }}
</UBadge>
<span class="text-default">{{ change.text }}</span>
</li>
</ul>
</UPageCard>
</UPageHero>
</UPage>
</UDashboardPanel>
</template> </template>

131
app/utils/changelog.ts Normal file
View File

@ -0,0 +1,131 @@
export const typeConfig: Record<ChangeEntry['type'], { label: string; color: string }> = {
nuevo: { label: 'Nuevo', color: 'success' },
mejora: { label: 'Mejora', color: 'info' },
fix: { label: 'Fix', color: 'warning' },
eliminado: { label: 'Eliminado', color: 'error' }
}
export interface ChangeEntry {
type: 'nuevo' | 'mejora' | 'fix' | 'eliminado'
text: string
}
export interface Release {
version: string
date: string
title: string
description?: string
changes: ChangeEntry[]
}
export const releases: Release[] = [
{
version: '0.7',
date: '31 de mayo, 2026 11:50PM',
title: 'Tour y optimizaciones',
changes: [
{ type: 'nuevo', text: 'Agregado tour virtual con localizacion para explicar funcionamiento del buscador'},
{ type: 'nuevo', text: 'Agregada pagina de inicio que muestra la version mas reciente del changelog' },
{ type: 'mejora', text: 'Separacion de changelog a un TS aparte para utilizar en changelog y en el home sin duplicacion de codigo'},
{ type: 'nuevo', text: 'Finalizado flow de automatizacion entre backend y typesense'}
]
},
{
version: '0.6',
date: '31 de mayo, 2026',
title: 'Feedback con traducciones, bloqueo de Entrelíneas y acceso desarrollador',
changes: [
{ type: 'nuevo', text: 'Página de Feedback con traducciones completas en 4 idiomas' },
{ type: 'nuevo', text: 'Sistema de bloqueo por clave de desarrollador para secciones en desarrollo' },
{ type: 'nuevo', text: 'Acceso de desarrollador en Configuración con desbloqueo por clave' },
{ type: 'nuevo', text: 'Banner visual mejorado para Entrelíneas cuando está bloqueado' },
{ type: 'mejora', text: 'Traducciones añadidas al componente BugReportInput' },
{ type: 'mejora', text: 'Nombre del tab Feedback ahora usa traducciones' },
{ type: 'mejora', text: 'Textos del banner de Entrelíneas traducidos a 4 idiomas' }
]
},
{
version: '0.5',
date: '30 de mayo, 2026',
title: 'Soporte de HTML en Entrelíneas',
description: 'El visor de Entrelíneas ahora renderiza contenido en HTML además de texto plano.',
changes: [
{ type: 'nuevo', text: 'Renderizado de contenido HTML en el detalle de Entrelíneas' },
{ type: 'mejora', text: 'Los fragmentos HTML se muestran con formato original preservado' },
{ type: 'fix', text: 'Corrección de errores de sintaxis en el componente de detalle' },
{ type: 'mejora', text: 'El historial ahora muestra correctamente documentos de Entrelíneas con HTML' }
]
},
{
version: '0.4',
date: '26 de mayo, 2026',
title: 'Mejoras de interfaz y exploracion',
changes: [
{ type: 'mejora', text: 'El código del documento aparece visible en la pantalla de detalle' },
{ type: 'mejora', text: 'El badge "Borrador" solo se muestra cuando el documento es borrador' },
{ type: 'mejora', text: 'Tooltip mejorado al copiar párrafos al portapapeles' },
{ type: 'mejora', text: 'El explorador filtra resultados mostrando solo ítems con párrafos' },
{ type: 'mejora', text: 'Panel lateral preparado para notas y resaltados (próximamente)' },
{ type: 'fix', text: 'Posicionamiento del panel lateral corregido en documentos cortos' },
{ type: 'fix', text: 'Corrección de traducciones en francés' },
{ type: 'fix', text: 'Ajustes visuales en múltiples vistas' }
]
},
{
version: '0.3',
date: '25 de mayo, 2026',
title: 'Portapapeles y corrección de bugs',
changes: [
{ type: 'nuevo', text: 'Panel de copiado mejorado al seleccionar párrafos' },
{ type: 'mejora', text: 'Función de copiar al portapapeles más robusta e independiente' },
{ type: 'fix', text: 'Corrección de bug al guardar y mostrar favoritos' },
{ type: 'fix', text: 'Corrección de bug en la carga de referencias' },
{ type: 'fix', text: 'Corrección de bug en el detalle de publicaciones de referencia' }
]
},
{
version: '0.2',
date: '2124 de mayo, 2026',
title: 'Conferencias, copiar párrafos y estabilidad',
changes: [
{ type: 'nuevo', text: 'Soporte de documentos de Conferencias y Actividades' },
{ type: 'nuevo', text: 'Clic en párrafo para copiarlo directamente al portapapeles' },
{ type: 'nuevo', text: 'Zoom de imagen en el visor de Entrelíneas' },
{ type: 'mejora', text: 'Número de párrafo más discreto en el detalle del documento' },
{ type: 'mejora', text: 'Publicación del documento visible en todas las vistas y traducida' },
{ type: 'mejora', text: 'Corrección de estilos visuales para contenido antiguo' },
{ type: 'fix', text: 'Corrección de bug en favoritos (detalle)' },
{ type: 'fix', text: 'Badge "Borrador" agregado en lista y detalle de Estudios Bíblicos' },
{ type: 'fix', text: 'Rutas de navegación migradas correctamente a nuevo motor de búsqueda' },
{ type: 'fix', text: 'Corrección de scroll infinito en móvil para Entrelíneas' }
]
},
{
version: '0.1',
date: '1012 de mayo, 2026',
title: 'Historial, Favoritos y multilengua',
description: 'Primera versión funcional con las secciones principales activas.',
changes: [
{ type: 'nuevo', text: 'Historial de búsqueda y exploración' },
{ type: 'nuevo', text: 'Favoritos: guarda y accede a documentos desde Mi Listado' },
{ type: 'nuevo', text: 'Selector de idioma: Español, English, Français, Português' },
{ type: 'nuevo', text: 'Cantidad aproximada de resultados visible en los listados' },
{ type: 'mejora', text: 'Paginación configurable: scroll infinito o páginas numeradas' },
{ type: 'mejora', text: 'Ajuste de cantidad de resultados por página en Configuración' },
{ type: 'fix', text: 'Corrección de traducciones en el menú principal' },
{ type: 'fix', text: 'Ajustes de colores y badges en listas de resultados' }
]
},
{
version: '0.0.1',
date: '7 de mayo, 2026',
title: 'Lanzamiento inicial',
description: 'Primera versión del buscador con Estudios Bíblicos y Entrelíneas.',
changes: [
{ type: 'nuevo', text: 'Búsqueda en Estudios Bíblicos' },
{ type: 'nuevo', text: 'Visor de Entrelíneas con imagen y texto' },
{ type: 'nuevo', text: 'Búsqueda por palabras o por frase exacta' },
{ type: 'nuevo', text: 'Estructura base de la aplicación' }
]
}
]

106
app/utils/guidedTour.ts Normal file
View File

@ -0,0 +1,106 @@
const { $i18n } = useNuxtApp();
const t = $i18n.t;
export const { start } = useDriver("onboarding");
export const steps = [
{
element: "#bible-studies",
popover: {
title: t('nav.bible_studies'),
description: t('nav.bible_studies_tour_description'),
side: "right",
},
},
{
element: "#conferences",
popover: {
title: t('nav.conferences'),
description: t('nav.conferences_tour_description'),
side: "right",
},
},
{
element: "#betweenthelines",
popover: {
title: t('nav.between_the_lines'),
description: t('nav.betweenthelines_tour_description'),
side: "right",
},
},
{
element: "#favorites",
popover: {
title: t('nav.my_list'),
description: t('nav.favorites_tour_description'),
side: "right",
},
},
{
element: "#history",
popover: {
title: t('nav.history'),
description: t('nav.history_tour_description'),
side: "right",
},
},
{
element: "#changelog",
popover: {
title: t('nav.changelog'),
description: t('nav.changelog_tour_description'),
side: "right",
},
},
{
element: "#settings",
popover: {
title: t('nav.settings'),
description: t('nav.settings_tour_description'),
side: "right",
},
},
{
element: "#feedback",
popover: {
title: t('feedback.title'),
description: t('nav.feedback_tour_description'),
side: "right",
},
},
{
element: "#localeSelector",
popover: {
title: t('nav.localeselector'),
description: t('nav.localeselector_tour_description'),
side: "right",
},
},
{
element: ".collapse-sidebar-icon",
popover: {
title: t('search.collapse'),
description: t('search.collapse_sidebar_tour_description'),
side: "bottom"
}
},
{
element: ".total-results",
popover: {
title: t('search.total_results'),
description: t('search.total_results_tour_description'),
side: "bottom"
}
}
]
export const tourConfig = {
nextBtnText: t('tour.next'),
prevBtnText: t('tour.prev'),
doneBtnText: t('tour.done'),
progressText: t('tour.progress'),
showProgress: true,
animate: true,
smoothScroll: true,
steps: steps,
}

View File

@ -1,6 +1,6 @@
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({ export default defineNuxtConfig({
modules: ['@nuxt/eslint', '@nuxt/ui', '@vueuse/nuxt', '@nuxtjs/i18n', '@pinia/nuxt', '@sfxcode/nuxt-typesense'], modules: ['@nuxt/eslint', '@nuxt/ui', '@vueuse/nuxt', '@nuxtjs/i18n', '@pinia/nuxt', '@sfxcode/nuxt-typesense','nuxt-driver.js'],
app: { app: {
head: { head: {

93
package-lock.json generated
View File

@ -23,6 +23,7 @@
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"dayjs": "^1.11.20", "dayjs": "^1.11.20",
"nuxt": "^4.4.2", "nuxt": "^4.4.2",
"nuxt-driver.js": "^0.1.1",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"scule": "^1.3.0", "scule": "^1.3.0",
"tailwindcss": "^4.2.4", "tailwindcss": "^4.2.4",
@ -2155,12 +2156,6 @@
} }
} }
}, },
"node_modules/@nuxt/cli/node_modules/std-env": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"license": "MIT"
},
"node_modules/@nuxt/devalue": { "node_modules/@nuxt/devalue": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-2.0.2.tgz",
@ -2387,25 +2382,25 @@
} }
}, },
"node_modules/@nuxt/icon": { "node_modules/@nuxt/icon": {
"version": "2.2.1", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/@nuxt/icon/-/icon-2.2.1.tgz", "resolved": "https://registry.npmjs.org/@nuxt/icon/-/icon-2.2.2.tgz",
"integrity": "sha512-GI840yYGuvHI0BGDQ63d6rAxGzG96jQcWrnaWIQKlyQo/7sx9PjXkSHckXUXyX1MCr9zY6U25Td6OatfY6Hklw==", "integrity": "sha512-K9wINW21M9x5GcKF5JEXzPKAT/Kfxl/vdnEyppw54hh5qoLcdi5HmsYoTfDP9gbJ6Z1T6IdH5JxBWk72HMe1Zg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@iconify/collections": "^1.0.641", "@iconify/collections": "^1.0.679",
"@iconify/types": "^2.0.0", "@iconify/types": "^2.0.0",
"@iconify/utils": "^3.1.0", "@iconify/utils": "^3.1.1",
"@iconify/vue": "^5.0.0", "@iconify/vue": "^5.0.0",
"@nuxt/devtools-kit": "^3.1.1", "@nuxt/devtools-kit": "^3.2.4",
"@nuxt/kit": "^4.2.2", "@nuxt/kit": "^4.4.4",
"consola": "^3.4.2", "consola": "^3.4.2",
"local-pkg": "^1.1.2", "local-pkg": "^1.1.2",
"mlly": "^1.8.0", "mlly": "^1.8.2",
"ohash": "^2.0.11", "ohash": "^2.0.11",
"pathe": "^2.0.3", "pathe": "^2.0.3",
"picomatch": "^4.0.3", "picomatch": "^4.0.4",
"std-env": "^3.10.0", "std-env": "^4.1.0",
"tinyglobby": "^0.2.15" "tinyglobby": "^0.2.16"
} }
}, },
"node_modules/@nuxt/kit": { "node_modules/@nuxt/kit": {
@ -2503,12 +2498,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/@nuxt/nitro-server/node_modules/std-env": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"license": "MIT"
},
"node_modules/@nuxt/schema": { "node_modules/@nuxt/schema": {
"version": "4.4.4", "version": "4.4.4",
"resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-4.4.4.tgz", "resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-4.4.4.tgz",
@ -2525,12 +2514,6 @@
"node": "^14.18.0 || >=16.10.0" "node": "^14.18.0 || >=16.10.0"
} }
}, },
"node_modules/@nuxt/schema/node_modules/std-env": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"license": "MIT"
},
"node_modules/@nuxt/telemetry": { "node_modules/@nuxt/telemetry": {
"version": "2.8.0", "version": "2.8.0",
"resolved": "https://registry.npmjs.org/@nuxt/telemetry/-/telemetry-2.8.0.tgz", "resolved": "https://registry.npmjs.org/@nuxt/telemetry/-/telemetry-2.8.0.tgz",
@ -2559,12 +2542,6 @@
"integrity": "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==", "integrity": "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@nuxt/telemetry/node_modules/std-env": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"license": "MIT"
},
"node_modules/@nuxt/ui": { "node_modules/@nuxt/ui": {
"version": "4.7.1", "version": "4.7.1",
"resolved": "https://registry.npmjs.org/@nuxt/ui/-/ui-4.7.1.tgz", "resolved": "https://registry.npmjs.org/@nuxt/ui/-/ui-4.7.1.tgz",
@ -2763,12 +2740,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/@nuxt/vite-builder/node_modules/std-env": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"license": "MIT"
},
"node_modules/@nuxtjs/color-mode": { "node_modules/@nuxtjs/color-mode": {
"version": "3.5.2", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/@nuxtjs/color-mode/-/color-mode-3.5.2.tgz", "resolved": "https://registry.npmjs.org/@nuxtjs/color-mode/-/color-mode-3.5.2.tgz",
@ -10445,6 +10416,12 @@
"url": "https://dotenvx.com" "url": "https://dotenvx.com"
} }
}, },
"node_modules/driver.js": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/driver.js/-/driver.js-1.4.0.tgz",
"integrity": "sha512-Gm64jm6PmcU+si21sQhBrTAM1JvUrR0QhNmjkprNLxohOBzul9+pNHXgQaT9lW84gwg9GMLB3NZGuGolsz5uew==",
"license": "MIT"
},
"node_modules/dunder-proto": { "node_modules/dunder-proto": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@ -13297,12 +13274,6 @@
"listhen": "bin/listhen.mjs" "listhen": "bin/listhen.mjs"
} }
}, },
"node_modules/listhen/node_modules/std-env": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"license": "MIT"
},
"node_modules/load-tsconfig": { "node_modules/load-tsconfig": {
"version": "0.2.5", "version": "0.2.5",
"resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
@ -14406,12 +14377,6 @@
"node": ">= 12" "node": ">= 12"
} }
}, },
"node_modules/nitropack/node_modules/std-env": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"license": "MIT"
},
"node_modules/nitropack/node_modules/unimport": { "node_modules/nitropack/node_modules/unimport": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/unimport/-/unimport-6.2.0.tgz", "resolved": "https://registry.npmjs.org/unimport/-/unimport-6.2.0.tgz",
@ -14654,6 +14619,16 @@
} }
} }
}, },
"node_modules/nuxt-driver.js": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/nuxt-driver.js/-/nuxt-driver.js-0.1.1.tgz",
"integrity": "sha512-K8SJBzLD8oyu3mhp2vv6F6/SUEaXSp067iGLCPDiMGh4w86VdDArapPmyylH9ZvYq/aeltVPbS6S/uOuVtAXHw==",
"license": "MIT",
"dependencies": {
"@nuxt/kit": "^4.4.4",
"driver.js": "^1.4.0"
}
},
"node_modules/nuxt/node_modules/cookie-es": { "node_modules/nuxt/node_modules/cookie-es": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-2.0.1.tgz", "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-2.0.1.tgz",
@ -14681,12 +14656,6 @@
"@types/estree": "^1.0.0" "@types/estree": "^1.0.0"
} }
}, },
"node_modules/nuxt/node_modules/std-env": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"license": "MIT"
},
"node_modules/nuxt/node_modules/unimport": { "node_modules/nuxt/node_modules/unimport": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/unimport/-/unimport-6.2.0.tgz", "resolved": "https://registry.npmjs.org/unimport/-/unimport-6.2.0.tgz",
@ -16778,9 +16747,9 @@
} }
}, },
"node_modules/std-env": { "node_modules/std-env": {
"version": "3.10.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/streamx": { "node_modules/streamx": {

View File

@ -27,6 +27,7 @@
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"dayjs": "^1.11.20", "dayjs": "^1.11.20",
"nuxt": "^4.4.2", "nuxt": "^4.4.2",
"nuxt-driver.js": "^0.1.1",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"scule": "^1.3.0", "scule": "^1.3.0",
"tailwindcss": "^4.2.4", "tailwindcss": "^4.2.4",

20
public/logo_round.svg Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 1000 1000" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g>
<clipPath id="_clip1">
<circle cx="500" cy="500" r="470"/>
</clipPath>
<g clip-path="url(#_clip1)">
<g transform="matrix(41.330743,0,0,41.330743,-2116.926503,-46.100585)">
<path d="M88.473,25.492C79.652,22.367 63.422,23.441 59.117,25.473C77.457,13.191 100.926,2.789 128.516,0.344C134.094,-0.098 141.602,-0.145 148.871,0.402C183.086,2.969 210.52,21.004 226.969,43C211.91,29.102 187.027,10.215 147.359,10.215C116.781,10.215 93.781,22.441 88.473,25.492Z" style="fill:rgb(236,27,35);"/>
</g>
<g transform="matrix(41.330743,0,0,41.330743,-2116.926503,-46.100585)">
<path d="M29.234,25.473C20.656,22.078 4.145,23.656 0.199,25.418C22.531,9.531 54.453,-1.191 101.211,0.512C57.047,3.617 32.789,23.152 29.234,25.473Z" style="fill:rgb(45,77,162);"/>
</g>
<g transform="matrix(41.330743,0,0,41.330743,-2116.926503,-46.100585)">
<path d="M59.117,25.535C50.535,22.141 33.18,23.711 29.234,25.473C51.57,9.586 79.883,-2.051 128.961,0.473C94.258,2.949 69.059,19.316 59.117,25.535Z" style="fill:rgb(254,254,254);"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB