From 5e829320cf6b2ac146e5cbae03e5cc5f838bdea8 Mon Sep 17 00:00:00 2001 From: Joakim Date: Sat, 14 Feb 2026 17:35:07 +0100 Subject: [PATCH] feat(web): rewrite home page as single-screen CLI-passthrough orchestrator Replace multi-page task management with single-screen layout: Header with report picker at top, scrollable TaskList in the middle, and InputBar with property pills fixed at the bottom. Owns state for active report, task loading, input parsing, and task completion. Co-Authored-By: Claude Opus 4.6 --- opal-web/src/routes/+page.svelte | 215 ++++++++++--------------------- 1 file changed, 65 insertions(+), 150 deletions(-) diff --git a/opal-web/src/routes/+page.svelte b/opal-web/src/routes/+page.svelte index c08de5a..222ba53 100644 --- a/opal-web/src/routes/+page.svelte +++ b/opal-web/src/routes/+page.svelte @@ -2,175 +2,90 @@ import { onMount } from 'svelte'; import { goto } from '$app/navigation'; import { authStore } from '$lib/stores/auth.js'; - import { tasksStore, pendingTasks, completedTasks } from '$lib/stores/tasks.js'; + import { tasksStore } from '$lib/stores/tasks.js'; + import Header from '$lib/components/Header.svelte'; import TaskList from '$lib/components/TaskList.svelte'; - import Button from '$lib/components/ui/Button.svelte'; - + import InputBar from '$lib/components/InputBar.svelte'; + + let activeReport = 'list'; + /** @type {import('$lib/api/types.js').Task[]} */ + let tasks = []; let loading = true; - let showCompleted = false; - - $: displayTasks = showCompleted ? $completedTasks : $pendingTasks; - - onMount(async () => { - // Redirect to login if not authenticated + let inputError = ''; + + // Subscribe to store + const unsubscribe = tasksStore.subscribe(value => { + tasks = value; + }); + + onMount(() => { if (!$authStore.isAuthenticated) { goto('/auth/login'); return; } - - // Load tasks + + loadReport(activeReport); + + return unsubscribe; + }); + + /** + * @param {string} reportName + */ + async function loadReport(reportName) { + loading = true; + inputError = ''; try { - await tasksStore.load({ status: showCompleted ? 'C' : 'P' }); + await tasksStore.loadReport(reportName); } catch (error) { - console.error('Failed to load tasks:', error); + console.error('Failed to load report:', error); } finally { loading = false; } - }); - + } + + /** + * @param {string} reportName + */ + function handleReportChange(reportName) { + activeReport = reportName; + loadReport(reportName); + } + + /** + * @param {string} input + */ + async function handleSubmit(input) { + inputError = ''; + try { + await tasksStore.parseAndCreate(input); + } catch (error) { + inputError = error instanceof Error ? error.message : 'Failed to create task'; + } + } + /** - * Toggle task completion * @param {string} uuid */ - async function handleToggle(uuid) { + async function handleComplete(uuid) { try { await tasksStore.complete(uuid); - // Reload tasks - await tasksStore.load({ status: showCompleted ? 'C' : 'P' }); } catch (error) { - console.error('Failed to toggle task:', error); - } - } - - /** - * Navigate to task detail - * @param {string} uuid - */ - function handleTaskClick(uuid) { - goto(`/tasks/${uuid}`); - } - - /** - * Toggle between pending and completed view - */ - async function toggleView() { - showCompleted = !showCompleted; - loading = true; - try { - await tasksStore.load({ status: showCompleted ? 'C' : 'P' }); - } catch (error) { - console.error('Failed to load tasks:', error); - } finally { - loading = false; + console.error('Failed to complete task:', error); } } -
-
-
-

Tasks

- - - - - New - -
- -
- - -
- - -
-
+
- + + +