diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 8614099..d3fa27b 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -10,8 +10,24 @@ const manualTopics = ref([]) const selectedTopic = ref(null) const previewGuide = ref(null) const showBausteine = ref(false) +const sidebarPinned = ref(localStorage.getItem('sidebarPinned') !== 'false') +const sidebarSticky = ref(false) let pollTimer = null +function toggleSidebarPin() { + sidebarPinned.value = !sidebarPinned.value + localStorage.setItem('sidebarPinned', sidebarPinned.value ? 'true' : 'false') + if (sidebarPinned.value) sidebarSticky.value = false +} + +function clickHoverZone() { + sidebarSticky.value = !sidebarSticky.value +} + +function onSidebarLeave() { + if (!sidebarPinned.value) sidebarSticky.value = false +} + const topics = computed(() => { const topicDates = {} for (const g of guides.value) { @@ -25,7 +41,19 @@ const topics = computed(() => { return Object.keys(topicDates).sort((a, b) => topicDates[b].localeCompare(topicDates[a])) }) -const guidesByFormat = computed(() => { +const doneByFormat = computed(() => { + const map = {} + for (const g of guides.value) { + if (g.topic !== selectedTopic.value) continue + if (g.status !== 'done') continue + if (!map[g.format] || g.created_at > map[g.format].created_at) { + map[g.format] = g + } + } + return map +}) + +const latestByFormat = computed(() => { const map = {} for (const g of guides.value) { if (g.topic !== selectedTopic.value) continue @@ -51,9 +79,9 @@ async function loadGuides() { const FORMAT_ORDER = ['OnePager', 'Cheatsheet', 'MiniGuide', 'BeginnerGuide', 'IntermediateGuide', 'ExtendedGuide'] function autoPreview() { - const map = guidesByFormat.value + const map = doneByFormat.value for (const f of FORMAT_ORDER) { - if (map[f]?.status === 'done') { + if (map[f]) { previewGuide.value = map[f] return } @@ -164,13 +192,16 @@ onUnmounted(() => {