diff --git a/src/App.vue b/src/App.vue index 92ede46..a1c288b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,19 +1,39 @@ - + diff --git a/src/components/MacroplanGrid.vue b/src/components/MacroplanGrid.vue new file mode 100644 index 0000000..e65959e --- /dev/null +++ b/src/components/MacroplanGrid.vue @@ -0,0 +1,341 @@ + + + + + diff --git a/src/components/PlanEditor.vue b/src/components/PlanEditor.vue new file mode 100644 index 0000000..e12b839 --- /dev/null +++ b/src/components/PlanEditor.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/src/composables/useMacroplan.ts b/src/composables/useMacroplan.ts new file mode 100644 index 0000000..682c1e0 --- /dev/null +++ b/src/composables/useMacroplan.ts @@ -0,0 +1,50 @@ +import { ref, computed, watch } from 'vue' +import { parseMacroplan } from '../model/parse' +import { buildPlan } from '../model/plan' +import type { Plan } from '../model/types' +import { SAMPLE_PLAN } from '../data/sample' + +const STORAGE_KEY = 'macroplan:source' + +/** + * Authoring state for a single Macroplan: the TOML source (autosaved to + * localStorage), the parsed Plan, and the current parse error. The last + * successfully-parsed Plan keeps rendering through transient typos (F3). + */ +export function useMacroplan() { + const source = ref(localStorage.getItem(STORAGE_KEY) ?? SAMPLE_PLAN) + const lastGood = ref(null) + + const parsed = computed<{ plan: Plan | null; error: string | null }>(() => { + try { + return { plan: buildPlan(parseMacroplan(source.value)), error: null } + } catch (e) { + return { plan: null, error: e instanceof Error ? e.message : String(e) } + } + }) + + watch( + parsed, + (p) => { + if (p.plan) lastGood.value = p.plan + }, + { immediate: true }, + ) + + watch(source, (v) => { + try { + localStorage.setItem(STORAGE_KEY, v) + } catch { + /* localStorage may be full or blocked — autosave is best-effort */ + } + }) + + return { + source, + plan: computed(() => parsed.value.plan ?? lastGood.value), + error: computed(() => parsed.value.error), + resetToSample: () => { + source.value = SAMPLE_PLAN + }, + } +}