From 8959aa7f5aae699eeaebfb284df2d800d489c829 Mon Sep 17 00:00:00 2001 From: mARTin Date: Wed, 11 Mar 2026 08:53:30 +0100 Subject: [PATCH] feat: move someday controls to horizontal tab bar, remove label column Replace the someday-label-column with a unified horizontal tab bar containing: collapse chevron, "any day" label, new list icon (ListPlus), new tab icon (FolderPlus), divider, then tab buttons. All icons have tooltips. Inline input for creating new tabs directly in the bar. v1.27.0 Co-Authored-By: Claude Opus 4.6 --- package.json | 2 +- src/app/globals.css | 27 +++ src/components/WeeklyView.tsx | 318 ++++++++++++++-------------------- 3 files changed, 157 insertions(+), 190 deletions(-) diff --git a/package.json b/package.json index 989ff02..0f561ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.26.2", + "version": "1.27.0", "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 e461b54..55d076e 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1509,6 +1509,33 @@ h3 { display: none; } +.someday-bar-icon-btn { + background: none; + border: none; + cursor: pointer; + color: var(--weekly-text-light, #999); + padding: 3px; + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + transition: background 0.15s, color 0.15s; + flex-shrink: 0; +} + +.someday-bar-icon-btn:hover { + background: var(--weekly-hover-bg, rgba(0, 0, 0, 0.06)); + color: var(--weekly-text, #333); +} + +.someday-tabs-bar-divider { + width: 1px; + height: 16px; + background: var(--weekly-border, #e5e7eb); + flex-shrink: 0; + margin: 0 2px; +} + /* Someday Tab Buttons (horizontal) */ .someday-tab-btn-h { background: none; diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index 054d903..59b5c95 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -54,6 +54,8 @@ import { PanelLeftOpen, Type, FolderOpen, + FolderPlus, + ListPlus, Circle, X, Cable, @@ -256,6 +258,7 @@ const translations: Record = { confirmPassword: "Confirm Password", someday: "SOMEDAY", lists: "Lists", + newList: "New list", allTabs: "All", newTab: "New tab", newTabName: "New tab name:", @@ -449,6 +452,7 @@ const translations: Record = { confirmPassword: "Passwort bestätigen", someday: "IRGENDWANN", lists: "Listen", + newList: "Neue Liste", allTabs: "Alle", newTab: "Neuer Tab", newTabName: "Neuer Tab-Name:", @@ -641,6 +645,7 @@ const translations: Record = { confirmPassword: "Confirmer le mot de passe", someday: "UN JOUR", lists: "Listes", + newList: "Nouvelle liste", allTabs: "Tous", newTab: "Nouvel onglet", newTabName: "Nom du nouvel onglet :", @@ -833,6 +838,7 @@ const translations: Record = { confirmPassword: "Confirmar contraseña", someday: "ALGÚN DÍA", lists: "Listas", + newList: "Nueva lista", allTabs: "Todas", newTab: "Nueva pestaña", newTabName: "Nombre de nueva pestaña:", @@ -1025,6 +1031,7 @@ const translations: Record = { confirmPassword: "Conferma password", someday: "UN GIORNO", lists: "Liste", + newList: "Nuova lista", allTabs: "Tutte", newTab: "Nuova scheda", newTabName: "Nome nuova scheda:", @@ -1461,6 +1468,8 @@ export default function WeeklyView() { const [renamingTabValue, setRenamingTabValue] = useState(""); const [newTabForListId, setNewTabForListId] = useState(null); const [newTabNameValue, setNewTabNameValue] = useState(""); + const [creatingNewTab, setCreatingNewTab] = useState(false); + const [creatingNewTabName, setCreatingNewTabName] = useState(""); useEffect(() => { if (typeof window !== "undefined") { @@ -6362,203 +6371,134 @@ export default function WeeklyView() { ref={somedaySectionRefCb} className={`weekly-someday ${somedayExpanded ? "expanded" : "collapsed"} transition-colors duration-200`} > -
- {showTimeGrid && ( -
+
setSomedayExpanded(!somedayExpanded)} + style={{ + cursor: "pointer", + display: "flex", + alignItems: "center", + gap: "4px", + marginRight: "4px", + }} + title={somedayExpanded ? "Collapse" : "Expand"} + > + -
setSomedayExpanded(!somedayExpanded)} - style={{ - cursor: "pointer", - display: "flex", - flexDirection: "column", - alignItems: "center", - gap: "0px", - }} - title={somedayExpanded ? "Collapse" : "Expand"} - > - - any day - - - {somedayLists.length}{" "} - {translations[language]?.lists || translations["en"].lists} - -
- -
- )} - {!showTimeGrid && ( -
+ + any day + +
+ + + {creatingNewTab && ( + setCreatingNewTabName(e.target.value)} + onBlur={() => { + if (creatingNewTabName.trim()) { + setSomedayTab(creatingNewTabName.trim()); + } + setCreatingNewTab(false); + }} + onKeyDown={(e) => { + if (e.key === "Enter") e.currentTarget.blur(); + if (e.key === "Escape") setCreatingNewTab(false); + }} + placeholder={t.newTab} + autoFocus style={{ - display: "flex", - alignItems: "center", - padding: "4px 8px", - gap: "6px", + fontSize: "0.75rem", + border: "1px solid var(--weekly-border)", + borderRadius: "3px", + padding: "2px 6px", + background: "var(--weekly-bg)", + color: "var(--weekly-text)", + width: "80px", }} - > -
setSomedayExpanded(!somedayExpanded)} - style={{ - cursor: "pointer", - display: "flex", - alignItems: "center", - gap: "6px", - }} - title={somedayExpanded ? "Collapse" : "Expand"} - > - - any day - - - {somedayLists.length}{" "} - {translations[language]?.lists || translations["en"].lists} - -
- -
+ /> )} -
- {/* Horizontal tab bar above grid */} - {somedayExpanded && somedayTabs.length > 0 && ( -
+
+ + {somedayTabs.map(tab => ( + editingTabName === tab ? ( + setRenamingTabValue(e.target.value)} + onBlur={() => { + renameTab(tab, renamingTabValue); + setEditingTabName(null); + }} + onKeyDown={(e) => { + if (e.key === "Enter") e.currentTarget.blur(); + if (e.key === "Escape") setEditingTabName(null); + }} + autoFocus + style={{ + fontSize: "0.75rem", + border: "1px solid var(--weekly-border)", + borderRadius: "3px", + padding: "2px 6px", + background: "var(--weekly-bg)", + color: "var(--weekly-text)", + width: "80px", + }} + /> + ) : ( +
- {somedayTabs.map(tab => ( - editingTabName === tab ? ( - setRenamingTabValue(e.target.value)} - onBlur={() => { - renameTab(tab, renamingTabValue); - setEditingTabName(null); - }} - onKeyDown={(e) => { - if (e.key === "Enter") e.currentTarget.blur(); - if (e.key === "Escape") setEditingTabName(null); - }} - autoFocus - style={{ - fontSize: "0.75rem", - border: "1px solid var(--weekly-border)", - borderRadius: "3px", - padding: "2px 6px", - background: "var(--weekly-bg)", - color: "var(--weekly-text)", - width: "80px", - }} - /> - ) : ( -
- - -
- ) - ))} + className={`someday-tab-btn-h ${activeSomedayTab === tab ? "active" : ""}`} + onClick={() => setSomedayTab(tab)} + onDoubleClick={() => { + setEditingTabName(tab); + setRenamingTabValue(tab); + }} + title={t.renameTab} + >{tab} {somedayLists.filter(l => l.tab === tab).length} +
- )} + ) + ))} +
+
+
{somedayExpanded && (