- Replace single-file 8441-line HTML with Vue 3 SPA - Pinia stores: auth, oils, recipes, diary, ui - Composables: useApi, useDialog, useSmartPaste, useOilTranslation - 6 shared components: RecipeCard, RecipeDetailOverlay, TagPicker, etc. - 9 page views: RecipeSearch, RecipeManager, Inventory, OilReference, etc. - 14 Cypress E2E test specs (113 tests), all passing - Multi-stage Dockerfile (Node build + Python runtime) - Demo video generation scripts (TTS + subtitles + screen recording) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
57 lines
1.3 KiB
JavaScript
57 lines
1.3 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
import { api } from '../composables/useApi'
|
|
|
|
export const useDiaryStore = defineStore('diary', () => {
|
|
const userDiary = ref([])
|
|
const currentDiaryId = ref(null)
|
|
|
|
// Actions
|
|
async function loadDiary() {
|
|
const data = await api.get('/api/diary')
|
|
userDiary.value = data
|
|
}
|
|
|
|
async function createDiary(data) {
|
|
const result = await api.post('/api/diary', data)
|
|
await loadDiary()
|
|
return result
|
|
}
|
|
|
|
async function updateDiary(id, data) {
|
|
const result = await api.put(`/api/diary/${id}`, data)
|
|
await loadDiary()
|
|
return result
|
|
}
|
|
|
|
async function deleteDiary(id) {
|
|
await api.delete(`/api/diary/${id}`)
|
|
userDiary.value = userDiary.value.filter((d) => (d._id ?? d.id) !== id)
|
|
if (currentDiaryId.value === id) {
|
|
currentDiaryId.value = null
|
|
}
|
|
}
|
|
|
|
async function addEntry(diaryId, content) {
|
|
const result = await api.post(`/api/diary/${diaryId}/entries`, content)
|
|
await loadDiary()
|
|
return result
|
|
}
|
|
|
|
async function deleteEntry(entryId) {
|
|
await api.delete(`/api/diary/entries/${entryId}`)
|
|
await loadDiary()
|
|
}
|
|
|
|
return {
|
|
userDiary,
|
|
currentDiaryId,
|
|
loadDiary,
|
|
createDiary,
|
|
updateDiary,
|
|
deleteDiary,
|
|
addEntry,
|
|
deleteEntry,
|
|
}
|
|
})
|