@mytec: iteration3 done for testing

This commit is contained in:
2026-01-30 11:37:38 +02:00
parent d3fb1801a8
commit 8b11163a79
8 changed files with 498 additions and 2 deletions

View File

@@ -21,6 +21,7 @@ export const useCoverageStore = create<CoverageState>((set) => ({
radius: 10,
resolution: 200,
rsrpThreshold: -120,
heatmapOpacity: 0.7,
},
heatmapVisible: true,

View File

@@ -0,0 +1,112 @@
import { create } from 'zustand';
import { v4 as uuidv4 } from 'uuid';
import { db } from '@/db/schema.ts';
import { useSitesStore } from '@/store/sites.ts';
import { useCoverageStore } from '@/store/coverage.ts';
import type { Site, CoverageSettings } from '@/types/index.ts';
export interface Project {
id: string;
name: string;
description?: string;
sites: Site[];
coverageSettings: CoverageSettings;
createdAt: number;
updatedAt: number;
}
interface ProjectsState {
projects: Project[];
currentProjectId: string | null;
loadProjects: () => Promise<void>;
saveProject: (name: string, description?: string) => Promise<void>;
loadProject: (id: string) => Promise<Project | null>;
deleteProject: (id: string) => Promise<void>;
}
export const useProjectsStore = create<ProjectsState>((set, get) => ({
projects: [],
currentProjectId: null,
loadProjects: async () => {
const dbProjects = await db.projects.orderBy('updatedAt').reverse().toArray();
const projects: Project[] = dbProjects.map((p) => JSON.parse(p.data));
set({ projects });
},
saveProject: async (name: string, description?: string) => {
const sites = useSitesStore.getState().sites;
const coverageSettings = useCoverageStore.getState().settings;
const now = Date.now();
// Check if updating existing project with same name
const existing = get().projects.find((p) => p.name === name);
const id = existing?.id ?? uuidv4();
const project: Project = {
id,
name,
description,
sites,
coverageSettings,
createdAt: existing?.createdAt ?? now,
updatedAt: now,
};
await db.projects.put({
id,
name,
data: JSON.stringify(project),
createdAt: project.createdAt,
updatedAt: now,
});
set({ currentProjectId: id });
await get().loadProjects();
},
loadProject: async (id: string) => {
const dbProject = await db.projects.get(id);
if (!dbProject) return null;
const project: Project = JSON.parse(dbProject.data);
// Restore sites: clear existing and add project sites
const sitesStore = useSitesStore.getState();
// Clear all existing sites from DB
const currentSites = sitesStore.sites;
for (const site of currentSites) {
await sitesStore.deleteSite(site.id);
}
// Re-add project sites
for (const site of project.sites) {
await db.sites.put({
id: site.id,
data: JSON.stringify(site),
createdAt: new Date(site.createdAt).getTime(),
updatedAt: new Date(site.updatedAt).getTime(),
});
}
await sitesStore.loadSites();
// Restore coverage settings
useCoverageStore.getState().updateSettings(project.coverageSettings);
// Clear any existing coverage result (outdated for loaded project)
useCoverageStore.getState().setResult(null);
set({ currentProjectId: id });
return project;
},
deleteProject: async (id: string) => {
await db.projects.delete(id);
const { currentProjectId } = get();
if (currentProjectId === id) {
set({ currentProjectId: null });
}
await get().loadProjects();
},
}));