From 899b1930853722ef38a53ecd0595b3a3c8c985d5 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 14 May 2026 12:32:50 -0400 Subject: [PATCH] feat(fc2a): add TimelineSidebar and assemble GalleryView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GalleryView wires the grid + timeline + modal together. The URL is the source of truth for which image (if any) is open — clicking an item pushes ?image=N; closing the modal pops it. This makes deep links shareable and the back button work intuitively. Below 900px viewport, the timeline drops below the grid as a horizontal strip so it doesn't compete with thumbnail space on mobile. Modal store + ImageViewer are placeholders here; real implementations land in Batch 5 (Tasks 19–22). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../components/gallery/TimelineSidebar.vue | 88 +++++++++++++++++++ frontend/src/components/modal/ImageViewer.vue | 9 ++ frontend/src/router.js | 3 +- frontend/src/stores/modal.js | 10 +++ frontend/src/views/GalleryView.vue | 77 ++++++++++++++++ 5 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/gallery/TimelineSidebar.vue create mode 100644 frontend/src/components/modal/ImageViewer.vue create mode 100644 frontend/src/stores/modal.js create mode 100644 frontend/src/views/GalleryView.vue diff --git a/frontend/src/components/gallery/TimelineSidebar.vue b/frontend/src/components/gallery/TimelineSidebar.vue new file mode 100644 index 0000000..8ea5c24 --- /dev/null +++ b/frontend/src/components/gallery/TimelineSidebar.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/frontend/src/components/modal/ImageViewer.vue b/frontend/src/components/modal/ImageViewer.vue new file mode 100644 index 0000000..370b462 --- /dev/null +++ b/frontend/src/components/modal/ImageViewer.vue @@ -0,0 +1,9 @@ + + diff --git a/frontend/src/router.js b/frontend/src/router.js index c983d82..fab0176 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -1,10 +1,11 @@ import { createRouter, createWebHistory } from 'vue-router' import PlaceholderView from './views/PlaceholderView.vue' import SettingsView from './views/SettingsView.vue' +import GalleryView from './views/GalleryView.vue' const routes = [ // FC-2: image backbone - { path: '/', name: 'gallery', component: PlaceholderView, meta: { title: 'Gallery' } }, + { path: '/', name: 'gallery', component: GalleryView, meta: { title: 'Gallery' } }, { path: '/showcase', name: 'showcase', component: PlaceholderView, meta: { title: 'Showcase' } }, { path: '/tags', name: 'tags', component: PlaceholderView, meta: { title: 'Tags' } }, { path: '/settings', name: 'settings', component: SettingsView, meta: { title: 'Settings' } }, diff --git a/frontend/src/stores/modal.js b/frontend/src/stores/modal.js new file mode 100644 index 0000000..7f88020 --- /dev/null +++ b/frontend/src/stores/modal.js @@ -0,0 +1,10 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' + +// Placeholder modal store — real implementation lands in Task 19. +export const useModalStore = defineStore('modal', () => { + const currentImageId = ref(null) + function open(id) { currentImageId.value = id } + function close() { currentImageId.value = null } + return { currentImageId, open, close } +}) diff --git a/frontend/src/views/GalleryView.vue b/frontend/src/views/GalleryView.vue new file mode 100644 index 0000000..c2f9d72 --- /dev/null +++ b/frontend/src/views/GalleryView.vue @@ -0,0 +1,77 @@ + + + + +