import { makeAutoObservable, runInAction } from 'mobx'; import { GLOBAL_HAS_NO_RECORDINGS, SITE_ID_STORAGE_KEY, } from 'App/constants/storageKeys'; import { projectsService } from 'App/services'; import GDPR from './types/gdpr'; import Project from './types/project'; interface Config { project: Project | null; pid: number | undefined; tab: string; } export default class ProjectsStore { list: Project[] = []; instance: Project | null = null; siteId: string | null = null; active: Project | null = null; sitesLoading = true; loading = false; config: Config = { project: null, pid: undefined, tab: 'installation', }; constructor() { const storedSiteId = localStorage.getItem(SITE_ID_STORAGE_KEY); this.siteId = storedSiteId ?? null; makeAutoObservable(this); } get isMobile() { return this.active ? ['ios', 'android'].includes(this.active.platform) : false; } get activeSiteId() { return this.active?.id || this.siteId; } syncProjectInList = (project: Partial) => { const index = this.list.findIndex((site) => site.id === project.id); if (index !== -1) { this.list[index] = this.list[index].edit(project); } }; getSiteId = () => ({ siteId: this.siteId, active: this.active, }); initProject = (project: Partial) => { this.instance = new Project(project); }; setSitesLoading = (loading: boolean) => { this.sitesLoading = loading; }; setLoading = (loading: boolean) => { this.loading = loading; }; setSiteId = (siteId: string) => { localStorage.setItem(SITE_ID_STORAGE_KEY, siteId.toString()); this.siteId = siteId; this.active = this.list.find((site) => site.id! === siteId) ?? null; }; editGDPR = (gdprData: Partial) => { if (this.instance) { this.instance.gdpr.edit(gdprData); } }; editInstance = (instance: Partial) => { if (!this.instance) return; this.instance = this.instance.edit(instance); }; fetchGDPR = async (siteId: string) => { try { const response = await projectsService.fetchGDPR(siteId); runInAction(() => { if (this.instance) { Object.assign(this.instance.gdpr, response.data); } }); } catch (error) { console.error('Failed to fetch GDPR:', error); } }; saveGDPR = async (siteId: string) => { if (!this.instance) return; try { const gdprData = this.instance.gdpr.toData(); const response = await projectsService.saveGDPR(siteId, gdprData); this.editGDPR(response.data); try { this.syncProjectInList({ id: siteId, gdpr: response.data, }); } catch (error) { console.error('Failed to sync project in list:', error); } } catch (error) { console.error('Failed to save GDPR:', error); } }; fetchList = async (siteIdFromPath?: string) => { this.setSitesLoading(true); try { const response = await projectsService.fetchList(); runInAction(() => { this.list = response.data.map((data) => new Project(data)); const siteIds = this.list.map((site) => site.id); let { siteId } = this; const siteExists = siteId ? siteIds.includes(siteId) : false; if (siteIdFromPath && siteIds.includes(siteIdFromPath)) { siteId = siteIdFromPath; } else if (!siteId || !siteExists) { siteId = siteIds.includes(this.siteId) ? this.siteId : response.data[0].projectId; } const hasRecordings = this.list.some((site) => site.recorded); if (!hasRecordings) { localStorage.setItem(GLOBAL_HAS_NO_RECORDINGS, 'true'); } else { localStorage.removeItem(GLOBAL_HAS_NO_RECORDINGS); } if (siteId) { this.setSiteId(siteId); } }); } catch (error) { console.error('Failed to fetch site list:', error); } finally { this.setSitesLoading(false); } }; save = async (projectData: Partial) => { this.setLoading(true); try { const response = await projectsService.saveProject(projectData); const newSite = new Project(response.data); const index = this.list.findIndex((site) => site.id === newSite.id); if (index !== -1) { this.list[index] = newSite; } else { this.list.push(newSite); } // this.setSiteId(newSite.id!); // this.active = newSite; return newSite; } catch (error: any) { throw error || 'An error occurred while saving the project.'; } finally { this.setLoading(false); } }; updateProjectRecordingStatus = (siteId: string, status: boolean) => { const site = this.list.find((site) => site.id === siteId); if (site) { site.recorded = status; const hasRecordings = this.list.some((site) => site.recorded); if (!hasRecordings) { localStorage.setItem(GLOBAL_HAS_NO_RECORDINGS, 'true'); } else { localStorage.removeItem(GLOBAL_HAS_NO_RECORDINGS); } } }; removeProject = async (projectId: string) => { this.setLoading(true); try { await projectsService.removeProject(projectId); runInAction(() => { this.list = this.list.filter((site) => site.id !== projectId); this.setConfigProject(); if (this.active?.id === projectId) { this.setSiteId(this.list[0].id!); } }); } catch (error) { throw error || new Error('An error occurred while deleting the project.'); } finally { this.setLoading(false); } }; updateProject = async (projectId: string, projectData: Partial) => { this.setLoading(true); try { const response = await projectsService.updateProject(projectId, { name: projectData.name, platform: projectData.platform, }); runInAction(() => { const updatedSite = new Project(response.data); const index = this.list.findIndex((site) => site.id === updatedSite.id); if (index !== -1) { this.list[index] = updatedSite; } }); } catch (error) { throw error || new Error('An error occurred while updating the project.'); } finally { this.setLoading(false); } }; setConfigProject = (pid?: number) => { if (!pid) { const firstProject = this.list[0]; this.config.pid = firstProject?.projectId ?? undefined; this.config.project = firstProject ?? null; return; } const project = this.list.find((site) => site.projectId === pid); if (!project) { // set the first project as active this.setConfigProject(); } else { this.config.pid = project?.projectId ?? undefined; this.config.project = project ?? null; } }; setConfigTab = (tab: string | null) => { this.config.tab = tab ?? 'installation'; }; }