From 50aa310a2d2c615eae650e0fd994e0e93d851680 Mon Sep 17 00:00:00 2001 From: mARTin-B78 Date: Mon, 11 May 2026 10:16:21 +0200 Subject: [PATCH] =?UTF-8?q?feat(design):=20AnyDay=20area=20polish=20?= =?UTF-8?q?=E2=80=94=20tabs,=20cards,=20flyout=20menu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSS: - .weekly-someday padding: 0 (no left/right border bleed) - .someday-tabs-bar: removed border-bottom + bg, padding 0 12px - Tabs: underline-style (border-bottom: 3px accent on active), transparent bg — active tab visually merges with someday area - Active count badge: accent-tinted instead of white-on-blue - .weekly-someday-list: 300px wide (restored from 240px) - .task-list-slot: min-height instead of fixed height + top/bottom padding so two-line tasks expand properly instead of being clipped JSX: - Combined provider icon + tab-assign + edit-style + delete into a single flyout menu per card header (trigger = provider icon if synced, else pencil) - Flyout: "Open in Google/Apple/…", "Assign to tab", "Edit style", "Delete" - Added menuOpenListId state to track open flyout v1.107.1 --- package.json | 2 +- src/app/globals.css | 57 ++++----- src/components/WeeklyView.tsx | 222 ++++++++++++++-------------------- 3 files changed, 119 insertions(+), 162 deletions(-) diff --git a/package.json b/package.json index 236e52b..42ac3ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.107.0", + "version": "1.107.1", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/app/globals.css b/src/app/globals.css index 6f0e7e1..bbdd5c2 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1278,7 +1278,7 @@ h3 { .weekly-someday { background-color: #f9f9f9; width: 100%; - padding: 0 1rem; + padding: 0; position: relative; flex-shrink: 0; } @@ -1417,8 +1417,8 @@ h3 { .weekly-someday-list { padding: 0; min-height: 200px; - flex: 0 0 240px; - width: 240px; + flex: 0 0 300px; + width: 300px; transition: transform 0.2s ease, opacity 0.2s ease, box-shadow 0.2s ease; max-width: 100%; display: flex; @@ -1443,13 +1443,15 @@ h3 { } .task-list-slot { - height: 38px; + min-height: 38px; width: 100%; position: relative; display: flex; align-items: center; border-bottom: 1px solid var(--weekly-border); box-sizing: border-box; + padding-top: 4px; + padding-bottom: 4px; } .task-list-slot.drop-target { @@ -1609,12 +1611,10 @@ h3 { display: flex; flex-direction: row; align-items: center; - gap: 4px; - padding: 8px 12px; - border-bottom: 2px solid var(--weekly-border); + gap: 2px; + padding: 0px 12px; overflow-x: auto; scrollbar-width: none; - background: var(--weekly-bg); } .someday-tabs-bar::-webkit-scrollbar { @@ -1642,45 +1642,47 @@ h3 { .someday-tabs-bar-divider { width: 1px; - height: 20px; + height: 16px; background: var(--weekly-border, #e5e7eb); flex-shrink: 0; margin: 0 4px; } -/* Someday Tab Buttons (horizontal) */ + +/* Someday Tab Buttons (horizontal) — underline style */ .someday-tab-btn-h { - background: var(--weekly-hover-bg, rgba(0, 0, 0, 0.05)); - border: 1px solid transparent; + background: transparent; + border: none; + border-bottom: 3px solid transparent; cursor: pointer; - color: var(--weekly-text, #444); + color: var(--weekly-text-light, #888); font-size: 0.8rem; - font-weight: 600; - padding: 5px 13px; - border-radius: 20px; + font-weight: 500; + padding: 8px 10px 7px; + border-radius: 0; white-space: nowrap; - transition: background 0.15s, color 0.15s, box-shadow 0.15s; + transition: color 0.15s, border-color 0.15s; display: inline-flex; align-items: center; gap: 5px; } .someday-tab-btn-h:hover { - background: var(--weekly-border, rgba(0, 0, 0, 0.1)); - color: var(--weekly-text, #222); + color: var(--weekly-text, #333); + background: transparent; } .someday-tab-btn-h.active { - background: var(--weekly-accent, #6366f1); - color: #fff; - border-color: transparent; - box-shadow: 0 2px 8px rgba(99, 102, 241, 0.35); + color: var(--weekly-text, #222); + font-weight: 700; + border-bottom-color: var(--weekly-accent, #6366f1); + background: transparent; + box-shadow: none; } .someday-tab-btn-h.drag-over { outline: 2px dashed var(--weekly-accent, #6366f1); outline-offset: -1px; - background: rgba(99, 102, 241, 0.12); } .someday-tab-count { @@ -1691,15 +1693,16 @@ h3 { height: 18px; padding: 0 5px; border-radius: 9px; - background: rgba(0, 0, 0, 0.1); + background: rgba(0, 0, 0, 0.07); font-size: 0.65rem; font-weight: 700; line-height: 1; + color: var(--weekly-text-light, #888); } .someday-tab-btn-h.active .someday-tab-count { - background: rgba(255, 255, 255, 0.3); - color: #fff; + background: rgba(99, 102, 241, 0.12); + color: var(--weekly-accent, #6366f1); } /* Someday Tab Wrapper with dissolve button */ diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index 077991a..7956fa0 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -720,6 +720,7 @@ export default function WeeklyView() { const [editingTaskId, setEditingTaskId] = useState(null); const [draggingListId, setDraggingListId] = useState(null); const [listToDelete, setListToDelete] = useState(null); + const [menuOpenListId, setMenuOpenListId] = useState(null); // Punkt 7+8: per-list color/icon edit popover, and per-tab settings popover const [editingListVisualsId, setEditingListVisualsId] = useState(null); const [editingTabVisualsName, setEditingTabVisualsName] = useState(null); @@ -8419,143 +8420,96 @@ export default function WeeklyView() { if (e.key === "Enter") e.currentTarget.blur(); }} /> - {list.externalProvider && (() => { - const providerUrl = list.externalProvider === "google" ? "https://tasks.google.com/tasks/" : - list.externalProvider === "outlook" ? "https://to-do.live.com/tasks/" : - list.externalProvider === "apple" ? "https://www.icloud.com/reminders/" : null; - const iconContent = ( - - {list.externalProvider === "outlook" ? ( - - ) : list.externalProvider === "google" ? ( - - ) : list.externalProvider === "apple" ? ( - - ) : list.externalProvider === "synology" ? ( - - ) : list.externalProvider === "notion" ? ( - - ) : ( - - )} - - ); - return providerUrl ? ( - e.stopPropagation()}> - {iconContent} - - ) : iconContent; - })()} -
- - -
- {newTabForListId === list.id && ( - setNewTabNameValue(e.target.value)} - onBlur={() => { - if (newTabNameValue.trim()) { - assignListToTab(list.id, newTabNameValue.trim()); - } - setNewTabForListId(null); - setNewTabNameValue(""); - }} - onKeyDown={(e) => { - if (e.key === "Enter") e.currentTarget.blur(); - if (e.key === "Escape") { + {list.externalProvider === "google" ? : + list.externalProvider === "outlook" ? : + list.externalProvider === "apple" ? : + list.externalProvider === "synology" ? : + list.externalProvider === "notion" ? : + } + + {menuOpenListId === list.id && ( + <> +
{ e.stopPropagation(); setMenuOpenListId(null); }} /> +
+ {/* Provider link */} + {list.externalProvider && (() => { + const providerUrl = list.externalProvider === "google" ? "https://tasks.google.com/tasks/" : list.externalProvider === "outlook" ? "https://to-do.live.com/tasks/" : list.externalProvider === "apple" ? "https://www.icloud.com/reminders/" : null; + const providerName = list.externalProvider === "outlook" ? "Microsoft" : list.externalProvider === "google" ? "Google" : list.externalProvider === "apple" ? "Apple" : list.externalProvider === "notion" ? "Notion" : list.externalProvider; + return providerUrl ? ( + { e.stopPropagation(); setMenuOpenListId(null); }} style={{ display: "flex", alignItems: "center", gap: "8px", padding: "8px 12px", fontSize: "0.8rem", color: darkMode ? "#e5e7eb" : "#374151", textDecoration: "none" }}> + {list.externalProvider === "google" ? : list.externalProvider === "outlook" ? : list.externalProvider === "apple" ? : } + {profile.language === "de" ? `In ${providerName} öffnen` : `Open in ${providerName}`} + + ) : null; + })()} + {/* Assign to tab */} +
+ + {profile.language === "de" ? "Tab zuweisen" : "Assign to tab"}{list.tab ? ` (${list.tab})` : ""} + +
+ {/* Edit style */} + +
+ {/* Delete */} + +
+ + )} + {newTabForListId === list.id && ( + setNewTabNameValue(e.target.value)} + onBlur={() => { + if (newTabNameValue.trim()) assignListToTab(list.id, newTabNameValue.trim()); setNewTabForListId(null); setNewTabNameValue(""); - } - }} - placeholder={t.newTabName || "Tab name..."} - autoFocus - onClick={(e) => e.stopPropagation()} - style={{ - fontSize: "0.7rem", - border: "1px solid var(--weekly-border)", - borderRadius: "4px", - padding: "2px 6px", - background: "var(--weekly-bg)", - color: "var(--weekly-text)", - width: "80px", - outline: "none", - }} - /> - )} - - + }} + onKeyDown={(e) => { + if (e.key === "Enter") e.currentTarget.blur(); + if (e.key === "Escape") { setNewTabForListId(null); setNewTabNameValue(""); } + }} + placeholder={t.newTabName || "Tab name..."} + autoFocus + onClick={(e) => e.stopPropagation()} + style={{ fontSize: "0.7rem", border: "1px solid var(--weekly-border)", borderRadius: "4px", padding: "2px 6px", background: "var(--weekly-bg)", color: "var(--weekly-text)", width: "80px", outline: "none" }} + /> + )} +
)}