first commit

This commit is contained in:
domrichardson
2026-03-24 16:03:04 +00:00
commit df40cc57e1
80 changed files with 16766 additions and 0 deletions

View File

@@ -0,0 +1,224 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import apiClient from "../services/apiClient";
export const useSpaceStore = defineStore("space", () => {
const spaces = ref([]);
const currentSpace = ref(null);
const notes = ref([]);
const notesSkip = ref(0);
const notesLimit = ref(20);
const notesHasMore = ref(true);
const notesLoading = ref(false);
const categories = ref([]);
const categoryTree = ref([]);
const refreshSpaceData = async (spaceId) => {
await Promise.all([fetchCategories(spaceId), fetchNotes(spaceId)]);
};
const fetchSpaces = async () => {
try {
const response = await apiClient.get("/api/v1/spaces");
spaces.value = response.data || [];
} catch (error) {
console.error("Error fetching spaces:", error);
}
};
const selectSpace = async (spaceId) => {
try {
const response = await apiClient.get(`/api/v1/spaces/${spaceId}`);
currentSpace.value = response.data;
await refreshSpaceData(spaceId);
} catch (error) {
console.error("Error selecting space:", error);
}
};
const fetchCategories = async (spaceId) => {
try {
const response = await apiClient.get(`/api/v1/spaces/${spaceId}/categories`);
categoryTree.value = response.data || [];
categories.value = categoryTree.value;
} catch (error) {
console.error("Error fetching categories:", error);
categoryTree.value = [];
categories.value = [];
}
};
const fetchNotes = async (spaceId, options = {}) => {
const { reset = true, limit = notesLimit.value } = options;
if (!spaceId) {
return;
}
if (notesLoading.value) {
return;
}
if (!reset && !notesHasMore.value) {
return;
}
if (reset) {
notesSkip.value = 0;
notesHasMore.value = true;
notesLimit.value = limit;
}
try {
notesLoading.value = true;
const response = await apiClient.get(`/api/v1/spaces/${spaceId}/notes`, {
params: {
skip: notesSkip.value,
limit,
},
});
const fetchedNotes = response.data || [];
if (reset) {
notes.value = fetchedNotes;
} else {
notes.value = [...notes.value, ...fetchedNotes];
}
notesSkip.value += fetchedNotes.length;
notesHasMore.value = fetchedNotes.length === limit;
} catch (error) {
console.error("Error fetching notes:", error);
} finally {
notesLoading.value = false;
}
};
const loadMoreNotes = async (spaceId) => {
await fetchNotes(spaceId, { reset: false, limit: notesLimit.value });
};
const createSpace = async (spaceData) => {
try {
const response = await apiClient.post("/api/v1/spaces", spaceData);
spaces.value.push(response.data);
currentSpace.value = response.data;
localStorage.setItem("currentSpaceId", response.data.id);
await refreshSpaceData(response.data.id);
return response.data;
} catch (error) {
throw error.response?.data?.message || error.message;
}
};
const updateSpace = async (spaceId, spaceData) => {
try {
const response = await apiClient.put(`/api/v1/spaces/${spaceId}`, spaceData);
const index = spaces.value.findIndex((s) => s.id === spaceId);
if (index !== -1) {
spaces.value[index] = response.data;
}
if (currentSpace.value?.id === spaceId) {
currentSpace.value = response.data;
}
return response.data;
} catch (error) {
throw error.response?.data?.message || error.message;
}
};
const createCategory = async (spaceId, categoryData) => {
try {
const response = await apiClient.post(`/api/v1/spaces/${spaceId}/categories`, categoryData);
await fetchCategories(spaceId);
return response.data;
} catch (error) {
throw error.response?.data?.message || error.message;
}
};
const updateCategory = async (spaceId, categoryId, categoryData) => {
try {
const response = await apiClient.put(`/api/v1/spaces/${spaceId}/categories/${categoryId}`, categoryData);
await fetchCategories(spaceId);
return response.data;
} catch (error) {
throw error.response?.data?.message || error.message;
}
};
const deleteCategory = async (spaceId, categoryId) => {
try {
await apiClient.delete(`/api/v1/spaces/${spaceId}/categories/${categoryId}`);
await refreshSpaceData(spaceId);
} catch (error) {
throw error.response?.data?.message || error.message;
}
};
const createNote = async (spaceId, noteData) => {
try {
const response = await apiClient.post(`/api/v1/spaces/${spaceId}/notes`, noteData);
await refreshSpaceData(spaceId);
return response.data;
} catch (error) {
throw error.response?.data?.message || error.message;
}
};
const updateNote = async (spaceId, noteData) => {
try {
const response = await apiClient.put(`/api/v1/spaces/${spaceId}/notes/${noteData.id}`, noteData);
const index = notes.value.findIndex((n) => n.id === noteData.id);
if (index !== -1) {
notes.value[index] = response.data;
}
await fetchCategories(spaceId);
return response.data;
} catch (error) {
throw error.response?.data?.message || error.message;
}
};
const deleteNote = async (spaceId, noteId) => {
try {
await apiClient.delete(`/api/v1/spaces/${spaceId}/notes/${noteId}`);
notes.value = notes.value.filter((n) => n.id !== noteId);
await fetchCategories(spaceId);
} catch (error) {
throw error.response?.data?.message || error.message;
}
};
const searchNotes = async (query) => {
try {
const response = await apiClient.get(`/api/v1/spaces/${currentSpace.value.id}/notes/search`, { params: { q: query } });
notes.value = response.data || [];
notesHasMore.value = false;
notesSkip.value = notes.value.length;
} catch (error) {
console.error("Error searching notes:", error);
}
};
return {
spaces,
currentSpace,
notes,
notesHasMore,
notesLoading,
categories,
categoryTree,
fetchSpaces,
selectSpace,
fetchNotes,
loadMoreNotes,
fetchCategories,
createSpace,
updateSpace,
createCategory,
updateCategory,
deleteCategory,
createNote,
updateNote,
deleteNote,
searchNotes,
};
});