From 1e8cf0cb7876016cf7f6408e6e2b652ed8773d4b Mon Sep 17 00:00:00 2001 From: Daryn Date: Sun, 19 Apr 2026 18:15:39 +0100 Subject: [PATCH] Added basic module support --- app/components/ModuleItem.vue | 33 +++++++++++++++++++++++++++++++++ app/dashboard.yml | 5 +++++ app/modules/clock.ts | 35 +++++++++++++++++++++++++++++++++++ app/modules/index.ts | 7 +++++++ app/pages/[...slug].vue | 7 +++++-- app/types/module.ts | 8 ++++++++ 6 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 app/components/ModuleItem.vue create mode 100644 app/modules/clock.ts create mode 100644 app/modules/index.ts create mode 100644 app/types/module.ts diff --git a/app/components/ModuleItem.vue b/app/components/ModuleItem.vue new file mode 100644 index 0000000..943b7a0 --- /dev/null +++ b/app/components/ModuleItem.vue @@ -0,0 +1,33 @@ + + + diff --git a/app/dashboard.yml b/app/dashboard.yml index a56bc99..595164f 100644 --- a/app/dashboard.yml +++ b/app/dashboard.yml @@ -1,3 +1,8 @@ +- id: clock-widget + type: module + moduleName: clock + parentId: null + order: -1 - id: media-folder type: folder parentId: null diff --git a/app/modules/clock.ts b/app/modules/clock.ts new file mode 100644 index 0000000..752ec45 --- /dev/null +++ b/app/modules/clock.ts @@ -0,0 +1,35 @@ +import { h, ref, onMounted, onUnmounted, defineComponent } from 'vue'; +import type { DashboardModule } from '../types/module'; + +export const ClockModule: DashboardModule = { + name: 'clock', + width: 2, + height: 1, + render() { + return h(defineComponent({ + setup() { + const time = ref(new Date().toLocaleTimeString()); + let interval: any; + + onMounted(() => { + interval = setInterval(() => { + time.value = new Date().toLocaleTimeString(); + }, 1000); + }); + + onUnmounted(() => { + clearInterval(interval); + }); + + return () => h( + 'div', + { class: 'w-full h-full flex flex-col items-center justify-center p-5 rounded-2xl bg-white/10 backdrop-blur-md border border-white/10 shadow-lg text-white group cursor-default transition-all' }, + [ + h('span', { class: 'text-sm text-white/50 mb-1 uppercase tracking-widest' }, 'Local Time'), + h('span', { class: 'text-3xl font-light tracking-tight text-shadow' }, time.value) + ] + ); + } + })); + } +}; diff --git a/app/modules/index.ts b/app/modules/index.ts new file mode 100644 index 0000000..d6fb24e --- /dev/null +++ b/app/modules/index.ts @@ -0,0 +1,7 @@ +import type { DashboardModule } from '../types/module'; +import { ClockModule } from './clock'; + +// Register all modules here +export const modules: Record = { + [ClockModule.name]: ClockModule +}; diff --git a/app/pages/[...slug].vue b/app/pages/[...slug].vue index 9ae261d..7096428 100644 --- a/app/pages/[...slug].vue +++ b/app/pages/[...slug].vue @@ -70,8 +70,11 @@ const backUrl = computed(() => { - - + +
diff --git a/app/types/module.ts b/app/types/module.ts new file mode 100644 index 0000000..0ef6680 --- /dev/null +++ b/app/types/module.ts @@ -0,0 +1,8 @@ +import type { VNode } from 'vue'; + +export interface DashboardModule { + name: string; + width: number; // Number of grid columns to span + height: number; // Number of grid rows to span + render: () => VNode | any; +}