feat(app): store settings in the local storage

This commit is contained in:
2025-12-28 23:56:23 +01:00
parent 143ea33246
commit 469c0e7dcb
3 changed files with 56 additions and 19 deletions

View File

@@ -1,20 +1,57 @@
import { z } from "zod/mini";
const STORAGE_ID = "app_settings";
const settingsSchema = z.object({
color: z.object({
col: z.number(),
row: z.number(),
}),
});
type Settings = z.infer<typeof settingsSchema>;
const defaultSettings = (): Settings => ({
color: { col: 0, row: 0 },
});
const loadSettings = (): Settings => {
const stored = localStorage.getItem(STORAGE_ID);
try {
const result = settingsSchema.safeParse(JSON.parse(stored ?? ""));
if (result.success) {
return result.data;
}
} catch {
// JSON.parse failed
}
const settings = defaultSettings();
saveSettings(settings);
return settings;
};
const saveSettings = (settings: Settings) => {
localStorage.setItem(STORAGE_ID, JSON.stringify(settings));
};
export const useAppStore = defineStore("app", { export const useAppStore = defineStore("app", {
state: () => ({ state: () => ({
booted: false, booted: false,
_color: { col: 0, row: 0 }, settings: loadSettings(),
}), }),
actions: { actions: {
setColor(col: number, row: number) { setColor(col: number, row: number) {
this._color = { col, row }; this.settings.color = { col, row };
}, },
}, },
getters: { getters: {
color: (state) => ({ color: (state) => ({
col: state._color.col, col: state.settings.color.col,
row: state._color.row, row: state.settings.color.row,
hex: APP_COLORS[state._color.row]![state._color.col]!, hex: APP_COLORS[state.settings.color.row]![state.settings.color.col]!,
}), }),
}, },
}); });

View File

@@ -19,7 +19,8 @@
"pinia": "3.0.4", "pinia": "3.0.4",
"three": "^0.182.0", "three": "^0.182.0",
"vue": "3.5.25", "vue": "3.5.25",
"vue-router": "4.6.3" "vue-router": "4.6.3",
"zod": "^4.2.1"
}, },
"devDependencies": { "devDependencies": {
"@nuxt/content": "3.8.2", "@nuxt/content": "3.8.2",
@@ -34,7 +35,6 @@
"eslint": "9.39.1", "eslint": "9.39.1",
"nuxt": "4.2.1", "nuxt": "4.2.1",
"prettier": "3.6.2", "prettier": "3.6.2",
"typescript": "5.9.3", "typescript": "5.9.3"
"zod": "4.1.12"
} }
} }

22
pnpm-lock.yaml generated
View File

@@ -15,7 +15,7 @@ importers:
version: 5.2.0(three@0.182.0)(vue@3.5.25(typescript@5.9.3)) version: 5.2.0(three@0.182.0)(vue@3.5.25(typescript@5.9.3))
"@tresjs/nuxt": "@tresjs/nuxt":
specifier: ^5.1.2 specifier: ^5.1.2
version: 5.1.2(@babel/parser@7.28.5)(@nuxt/content@3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1))(@rollup/pluginutils@5.3.0(rollup@4.53.3))(change-case@5.4.4)(db0@0.3.4(better-sqlite3@12.4.1))(embla-carousel@8.6.0)(esbuild@0.27.1)(ioredis@5.8.2)(magicast@0.5.1)(three@0.182.0)(typescript@5.9.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))(zod@4.1.12) version: 5.1.2(@babel/parser@7.28.5)(@nuxt/content@3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1))(@rollup/pluginutils@5.3.0(rollup@4.53.3))(change-case@5.4.4)(db0@0.3.4(better-sqlite3@12.4.1))(embla-carousel@8.6.0)(esbuild@0.27.1)(ioredis@5.8.2)(magicast@0.5.1)(three@0.182.0)(typescript@5.9.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))(zod@4.2.1)
gsap: gsap:
specifier: 3.13.0 specifier: 3.13.0
version: 3.13.0 version: 3.13.0
@@ -31,6 +31,9 @@ importers:
vue-router: vue-router:
specifier: 4.6.3 specifier: 4.6.3
version: 4.6.3(vue@3.5.25(typescript@5.9.3)) version: 4.6.3(vue@3.5.25(typescript@5.9.3))
zod:
specifier: ^4.2.1
version: 4.2.1
devDependencies: devDependencies:
"@nuxt/content": "@nuxt/content":
specifier: 3.8.2 specifier: 3.8.2
@@ -71,9 +74,6 @@ importers:
typescript: typescript:
specifier: 5.9.3 specifier: 5.9.3
version: 5.9.3 version: 5.9.3
zod:
specifier: 4.1.12
version: 4.1.12
packages: packages:
"@alloc/quick-lru@5.2.0": "@alloc/quick-lru@5.2.0":
@@ -9623,10 +9623,10 @@ packages:
integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==, integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==,
} }
zod@4.1.12: zod@4.2.1:
resolution: resolution:
{ {
integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==, integrity: sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==,
} }
zwitch@2.0.4: zwitch@2.0.4:
@@ -10815,7 +10815,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- magicast - magicast
"@nuxt/ui@4.2.1(@babel/parser@7.28.5)(@nuxt/content@3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1))(change-case@5.4.4)(db0@0.3.4(better-sqlite3@12.4.1))(embla-carousel@8.6.0)(ioredis@5.8.2)(magicast@0.5.1)(typescript@5.9.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))(zod@4.1.12)": "@nuxt/ui@4.2.1(@babel/parser@7.28.5)(@nuxt/content@3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1))(change-case@5.4.4)(db0@0.3.4(better-sqlite3@12.4.1))(embla-carousel@8.6.0)(ioredis@5.8.2)(magicast@0.5.1)(typescript@5.9.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))(zod@4.2.1)":
dependencies: dependencies:
"@iconify/vue": 5.0.0(vue@3.5.25(typescript@5.9.3)) "@iconify/vue": 5.0.0(vue@3.5.25(typescript@5.9.3))
"@internationalized/date": 3.10.0 "@internationalized/date": 3.10.0
@@ -10866,7 +10866,7 @@ snapshots:
optionalDependencies: optionalDependencies:
"@nuxt/content": 3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1) "@nuxt/content": 3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1)
vue-router: 4.6.3(vue@3.5.25(typescript@5.9.3)) vue-router: 4.6.3(vue@3.5.25(typescript@5.9.3))
zod: 4.1.12 zod: 4.2.1
transitivePeerDependencies: transitivePeerDependencies:
- "@azure/app-configuration" - "@azure/app-configuration"
- "@azure/cosmos" - "@azure/cosmos"
@@ -11737,10 +11737,10 @@ snapshots:
three: 0.182.0 three: 0.182.0
vue: 3.5.25(typescript@5.9.3) vue: 3.5.25(typescript@5.9.3)
"@tresjs/nuxt@5.1.2(@babel/parser@7.28.5)(@nuxt/content@3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1))(@rollup/pluginutils@5.3.0(rollup@4.53.3))(change-case@5.4.4)(db0@0.3.4(better-sqlite3@12.4.1))(embla-carousel@8.6.0)(esbuild@0.27.1)(ioredis@5.8.2)(magicast@0.5.1)(three@0.182.0)(typescript@5.9.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))(zod@4.1.12)": "@tresjs/nuxt@5.1.2(@babel/parser@7.28.5)(@nuxt/content@3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1))(@rollup/pluginutils@5.3.0(rollup@4.53.3))(change-case@5.4.4)(db0@0.3.4(better-sqlite3@12.4.1))(embla-carousel@8.6.0)(esbuild@0.27.1)(ioredis@5.8.2)(magicast@0.5.1)(three@0.182.0)(typescript@5.9.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))(zod@4.2.1)":
dependencies: dependencies:
"@nuxt/kit": 4.1.2(magicast@0.5.1) "@nuxt/kit": 4.1.2(magicast@0.5.1)
"@nuxt/ui": 4.2.1(@babel/parser@7.28.5)(@nuxt/content@3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1))(change-case@5.4.4)(db0@0.3.4(better-sqlite3@12.4.1))(embla-carousel@8.6.0)(ioredis@5.8.2)(magicast@0.5.1)(typescript@5.9.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))(zod@4.1.12) "@nuxt/ui": 4.2.1(@babel/parser@7.28.5)(@nuxt/content@3.8.2(better-sqlite3@12.4.1)(magicast@0.5.1))(change-case@5.4.4)(db0@0.3.4(better-sqlite3@12.4.1))(embla-carousel@8.6.0)(ioredis@5.8.2)(magicast@0.5.1)(typescript@5.9.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))(zod@4.2.1)
"@tresjs/core": 5.2.0(three@0.182.0)(vue@3.5.25(typescript@5.9.3)) "@tresjs/core": 5.2.0(three@0.182.0)(vue@3.5.25(typescript@5.9.3))
defu: 6.1.4 defu: 6.1.4
mlly: 1.8.0 mlly: 1.8.0
@@ -16378,6 +16378,6 @@ snapshots:
zod@3.25.76: {} zod@3.25.76: {}
zod@4.1.12: {} zod@4.2.1: {}
zwitch@2.0.4: {} zwitch@2.0.4: {}