fix: :15/:30/:45 toggle now works in left rail flyout and all sidebar panels

Was calling setShowSubHourSlots (local state) + saveSetting, but effectiveShowSubHourSlots
reads from profile via getEffective — so the toggle had no visible effect. Fixed all 5
occurrences to use saveViewSetting("showSubHourSlots", ..., true) matching the Settings
sidebar behavior.

v1.110.3
This commit is contained in:
mARTin-B78 2026-05-11 14:06:51 +02:00
parent ab8d96a810
commit 27756e5bf5
2 changed files with 6 additions and 6 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "my-weekly-todo-list", "name": "my-weekly-todo-list",
"version": "1.110.2", "version": "1.110.3",
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -5748,7 +5748,7 @@ export default function WeeklyView() {
<div style={{ display: "flex", gap: "4px" }}>{[1, 2, 3, 5, 7].map((num) => (<button key={num} onClick={() => { setViewDays(num); savedViewDaysRef.current = num; saveSetting("viewDays", num); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: viewDays === num ? 700 : 400, background: viewDays === num ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: viewDays === num ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{num}</button>))}</div> <div style={{ display: "flex", gap: "4px" }}>{[1, 2, 3, 5, 7].map((num) => (<button key={num} onClick={() => { setViewDays(num); savedViewDaysRef.current = num; saveSetting("viewDays", num); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: viewDays === num ? 700 : 400, background: viewDays === num ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: viewDays === num ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{num}</button>))}</div>
</div> </div>
{profile.showTimeGrid && (<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Zeitfenster" : "Slot"}</span><div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div></div>)} {profile.showTimeGrid && (<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Zeitfenster" : "Slot"}</span><div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div></div>)}
{profile.showTimeGrid && (<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { const v = !effectiveShowSubHourSlots; setShowSubHourSlots(v); saveSetting("showSubHourSlots", v); }} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>)} {profile.showTimeGrid && (<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { saveViewSetting("showSubHourSlots", !effectiveShowSubHourSlots, true); }} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>)}
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{profile.language === "de" ? "Textgröße" : "Text size"}</span><div style={{ display: "flex", gap: "4px" }}>{(["S", "M", "L"] as const).map((size) => (<button key={size} onClick={() => { setFontSize(size); saveSetting("fontSize", size); }} style={{ padding: "4px 10px", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: profile.fontSize === size ? 700 : 400, background: profile.fontSize === size ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: profile.fontSize === size ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>{size}</button>))}</div></div> <div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{profile.language === "de" ? "Textgröße" : "Text size"}</span><div style={{ display: "flex", gap: "4px" }}>{(["S", "M", "L"] as const).map((size) => (<button key={size} onClick={() => { setFontSize(size); saveSetting("fontSize", size); }} style={{ padding: "4px 10px", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: profile.fontSize === size ? 700 : 400, background: profile.fontSize === size ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: profile.fontSize === size ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>{size}</button>))}</div></div>
<div style={{ borderTop: `1px solid ${darkMode ? "#333" : "#e5e7eb"}`, paddingTop: "4px" }} /> <div style={{ borderTop: `1px solid ${darkMode ? "#333" : "#e5e7eb"}`, paddingTop: "4px" }} />
{[{ label: profile.language === "de" ? "Irgendwann" : "Someday", value: effectiveShowSomeday, toggle: () => saveViewSetting("showSomeday", !effectiveShowSomeday, true) }, { label: profile.language === "de" ? "Ganztägig" : "All-day", value: effectiveShowAllDay, toggle: () => saveViewSetting("showAllDayEvents", !effectiveShowAllDay, true) }, { label: profile.language === "de" ? "Checkboxen" : "Checkboxes", value: effectiveShowTaskCheckboxes, toggle: () => saveViewSetting("showTaskCheckboxes", !effectiveShowTaskCheckboxes, true) }, { label: profile.language === "de" ? "Projekt-Icons" : "Project Icons", value: effectiveShowProjectIcons, toggle: () => saveViewSetting("showProjectIcons", !effectiveShowProjectIcons, true) }, { label: profile.language === "de" ? "Prioritäts-Icons" : "Priority Icons", value: effectiveShowPriorityIcons, toggle: () => saveViewSetting("showPriorityIcons", !effectiveShowPriorityIcons, true) }, ...((profile.weatherEnabled || profile.weatherLat || profile.weatherLon) ? [{ label: profile.language === "de" ? "Wetter" : "Weather", value: effectiveWeatherEnabled, toggle: () => { const v = !effectiveWeatherEnabled; setProfile((p: any) => ({ ...p, weatherEnabled: v })); saveViewSetting("weatherEnabled", v, true); } }] : []) ].map(({ label, value, toggle }) => (<div key={label} style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{label}</span><button onClick={toggle} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{value ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>))} {[{ label: profile.language === "de" ? "Irgendwann" : "Someday", value: effectiveShowSomeday, toggle: () => saveViewSetting("showSomeday", !effectiveShowSomeday, true) }, { label: profile.language === "de" ? "Ganztägig" : "All-day", value: effectiveShowAllDay, toggle: () => saveViewSetting("showAllDayEvents", !effectiveShowAllDay, true) }, { label: profile.language === "de" ? "Checkboxen" : "Checkboxes", value: effectiveShowTaskCheckboxes, toggle: () => saveViewSetting("showTaskCheckboxes", !effectiveShowTaskCheckboxes, true) }, { label: profile.language === "de" ? "Projekt-Icons" : "Project Icons", value: effectiveShowProjectIcons, toggle: () => saveViewSetting("showProjectIcons", !effectiveShowProjectIcons, true) }, { label: profile.language === "de" ? "Prioritäts-Icons" : "Priority Icons", value: effectiveShowPriorityIcons, toggle: () => saveViewSetting("showPriorityIcons", !effectiveShowPriorityIcons, true) }, ...((profile.weatherEnabled || profile.weatherLat || profile.weatherLon) ? [{ label: profile.language === "de" ? "Wetter" : "Weather", value: effectiveWeatherEnabled, toggle: () => { const v = !effectiveWeatherEnabled; setProfile((p: any) => ({ ...p, weatherEnabled: v })); saveViewSetting("weatherEnabled", v, true); } }] : []) ].map(({ label, value, toggle }) => (<div key={label} style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{label}</span><button onClick={toggle} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{value ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>))}
@ -5806,7 +5806,7 @@ export default function WeeklyView() {
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Ansicht" : "View"}</span><div style={{ display: "flex", gap: "4px" }}>{[{ key: "simple", icon: <Calendar size={13} /> }, { key: "calendar", icon: <CalendarDays size={13} /> }, { key: "list", icon: <ListTodo size={13} /> }, { key: "kanban", icon: <Kanban size={13} /> }, { key: "priority", icon: <Target size={13} /> }].map((v) => (<button key={v.key} onClick={() => { setViewStyle(v.key as any); saveSetting("viewStyle", v.key); if (v.key === "list") { setShowTimeGrid(false); saveSetting("showTimeGrid", false); } if (v.key === "simple" || v.key === "calendar") { setShowTimeGrid(true); saveSetting("showTimeGrid", true); } if (v.key === "priority" || v.key === "kanban") { setShowTimeGrid(false); saveSetting("showTimeGrid", false); } }} style={{ flex: 1, padding: "5px 0", borderRadius: "6px", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: profile.viewStyle === v.key ? 700 : 400, background: profile.viewStyle === v.key ? "var(--accent)" : (darkMode ? "#1f2937" : "#e5e7eb"), color: profile.viewStyle === v.key ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{v.icon}</button>))}</div></div> <div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Ansicht" : "View"}</span><div style={{ display: "flex", gap: "4px" }}>{[{ key: "simple", icon: <Calendar size={13} /> }, { key: "calendar", icon: <CalendarDays size={13} /> }, { key: "list", icon: <ListTodo size={13} /> }, { key: "kanban", icon: <Kanban size={13} /> }, { key: "priority", icon: <Target size={13} /> }].map((v) => (<button key={v.key} onClick={() => { setViewStyle(v.key as any); saveSetting("viewStyle", v.key); if (v.key === "list") { setShowTimeGrid(false); saveSetting("showTimeGrid", false); } if (v.key === "simple" || v.key === "calendar") { setShowTimeGrid(true); saveSetting("showTimeGrid", true); } if (v.key === "priority" || v.key === "kanban") { setShowTimeGrid(false); saveSetting("showTimeGrid", false); } }} style={{ flex: 1, padding: "5px 0", borderRadius: "6px", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: profile.viewStyle === v.key ? 700 : 400, background: profile.viewStyle === v.key ? "var(--accent)" : (darkMode ? "#1f2937" : "#e5e7eb"), color: profile.viewStyle === v.key ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{v.icon}</button>))}</div></div>
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Spalten" : "Days"}</span><div style={{ display: "flex", gap: "4px" }}>{[1, 2, 3, 5, 7].map((num) => (<button key={num} onClick={() => { setViewDays(num); savedViewDaysRef.current = num; saveSetting("viewDays", num); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: viewDays === num ? 700 : 400, background: viewDays === num ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: viewDays === num ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{num}</button>))}</div></div> <div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Spalten" : "Days"}</span><div style={{ display: "flex", gap: "4px" }}>{[1, 2, 3, 5, 7].map((num) => (<button key={num} onClick={() => { setViewDays(num); savedViewDaysRef.current = num; saveSetting("viewDays", num); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: viewDays === num ? 700 : 400, background: viewDays === num ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: viewDays === num ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{num}</button>))}</div></div>
{profile.showTimeGrid && (<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Zeitfenster" : "Slot"}</span><div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div></div>)} {profile.showTimeGrid && (<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Zeitfenster" : "Slot"}</span><div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div></div>)}
{profile.showTimeGrid && (<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { const v = !effectiveShowSubHourSlots; setShowSubHourSlots(v); saveSetting("showSubHourSlots", v); }} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>)} {profile.showTimeGrid && (<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { saveViewSetting("showSubHourSlots", !effectiveShowSubHourSlots, true); }} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>)}
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{profile.language === "de" ? "Textgröße" : "Text size"}</span><div style={{ display: "flex", gap: "4px" }}>{(["S", "M", "L"] as const).map((size) => (<button key={size} onClick={() => { setFontSize(size); saveSetting("fontSize", size); }} style={{ padding: "4px 10px", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: profile.fontSize === size ? 700 : 400, background: profile.fontSize === size ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: profile.fontSize === size ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>{size}</button>))}</div></div> <div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{profile.language === "de" ? "Textgröße" : "Text size"}</span><div style={{ display: "flex", gap: "4px" }}>{(["S", "M", "L"] as const).map((size) => (<button key={size} onClick={() => { setFontSize(size); saveSetting("fontSize", size); }} style={{ padding: "4px 10px", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: profile.fontSize === size ? 700 : 400, background: profile.fontSize === size ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: profile.fontSize === size ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>{size}</button>))}</div></div>
<div style={{ borderTop: `1px solid ${darkMode ? "#333" : "#e5e7eb"}`, paddingTop: "4px" }} /> <div style={{ borderTop: `1px solid ${darkMode ? "#333" : "#e5e7eb"}`, paddingTop: "4px" }} />
{[{ label: profile.language === "de" ? "Irgendwann" : "Someday", value: effectiveShowSomeday, toggle: () => saveViewSetting("showSomeday", !effectiveShowSomeday, true) }, { label: profile.language === "de" ? "Ganztägig" : "All-day", value: effectiveShowAllDay, toggle: () => saveViewSetting("showAllDayEvents", !effectiveShowAllDay, true) }, { label: profile.language === "de" ? "Checkboxen" : "Checkboxes", value: effectiveShowTaskCheckboxes, toggle: () => saveViewSetting("showTaskCheckboxes", !effectiveShowTaskCheckboxes, true) }, { label: profile.language === "de" ? "Projekt-Icons" : "Project Icons", value: effectiveShowProjectIcons, toggle: () => saveViewSetting("showProjectIcons", !effectiveShowProjectIcons, true) }, { label: profile.language === "de" ? "Prioritäts-Icons" : "Priority Icons", value: effectiveShowPriorityIcons, toggle: () => saveViewSetting("showPriorityIcons", !effectiveShowPriorityIcons, true) }, ...((profile.weatherEnabled || profile.weatherLat || profile.weatherLon) ? [{ label: profile.language === "de" ? "Wetter" : "Weather", value: effectiveWeatherEnabled, toggle: () => { const v = !effectiveWeatherEnabled; setProfile((p: any) => ({ ...p, weatherEnabled: v })); saveViewSetting("weatherEnabled", v, true); } }] : []) ].map(({ label, value, toggle }) => (<div key={label} style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{label}</span><button onClick={toggle} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{value ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>))} {[{ label: profile.language === "de" ? "Irgendwann" : "Someday", value: effectiveShowSomeday, toggle: () => saveViewSetting("showSomeday", !effectiveShowSomeday, true) }, { label: profile.language === "de" ? "Ganztägig" : "All-day", value: effectiveShowAllDay, toggle: () => saveViewSetting("showAllDayEvents", !effectiveShowAllDay, true) }, { label: profile.language === "de" ? "Checkboxen" : "Checkboxes", value: effectiveShowTaskCheckboxes, toggle: () => saveViewSetting("showTaskCheckboxes", !effectiveShowTaskCheckboxes, true) }, { label: profile.language === "de" ? "Projekt-Icons" : "Project Icons", value: effectiveShowProjectIcons, toggle: () => saveViewSetting("showProjectIcons", !effectiveShowProjectIcons, true) }, { label: profile.language === "de" ? "Prioritäts-Icons" : "Priority Icons", value: effectiveShowPriorityIcons, toggle: () => saveViewSetting("showPriorityIcons", !effectiveShowPriorityIcons, true) }, ...((profile.weatherEnabled || profile.weatherLat || profile.weatherLon) ? [{ label: profile.language === "de" ? "Wetter" : "Weather", value: effectiveWeatherEnabled, toggle: () => { const v = !effectiveWeatherEnabled; setProfile((p: any) => ({ ...p, weatherEnabled: v })); saveViewSetting("weatherEnabled", v, true); } }] : []) ].map(({ label, value, toggle }) => (<div key={label} style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{label}</span><button onClick={toggle} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{value ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>))}
@ -5880,7 +5880,7 @@ export default function WeeklyView() {
</div> </div>
{/* Slot Duration */} {/* Slot Duration */}
{profile.showTimeGrid && (<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Zeitfenster" : "Slot"}</span><div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div></div>)} {profile.showTimeGrid && (<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Zeitfenster" : "Slot"}</span><div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div></div>)}
{profile.showTimeGrid && (<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { const v = !effectiveShowSubHourSlots; setShowSubHourSlots(v); saveSetting("showSubHourSlots", v); }} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>)} {profile.showTimeGrid && (<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { saveViewSetting("showSubHourSlots", !effectiveShowSubHourSlots, true); }} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={16} /> : <EyeOff size={16} />}</button></div>)}
{/* Text size */} {/* Text size */}
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{profile.language === "de" ? "Textgröße" : "Text size"}</span><div style={{ display: "flex", gap: "4px" }}>{(["S", "M", "L"] as const).map((size) => (<button key={size} onClick={() => { setFontSize(size); saveSetting("fontSize", size); }} style={{ padding: "4px 10px", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: profile.fontSize === size ? 700 : 400, background: profile.fontSize === size ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: profile.fontSize === size ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>{size}</button>))}</div></div> <div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{profile.language === "de" ? "Textgröße" : "Text size"}</span><div style={{ display: "flex", gap: "4px" }}>{(["S", "M", "L"] as const).map((size) => (<button key={size} onClick={() => { setFontSize(size); saveSetting("fontSize", size); }} style={{ padding: "4px 10px", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: profile.fontSize === size ? 700 : 400, background: profile.fontSize === size ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: profile.fontSize === size ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>{size}</button>))}</div></div>
<div style={{ borderTop: `1px solid ${darkMode ? "#333" : "#e5e7eb"}`, paddingTop: "4px" }} /> <div style={{ borderTop: `1px solid ${darkMode ? "#333" : "#e5e7eb"}`, paddingTop: "4px" }} />
@ -5996,7 +5996,7 @@ export default function WeeklyView() {
<> <>
<div style={flyoutLabelStyle}>{profile.language === "de" ? "Zeitfenster" : "Slot Duration"}</div> <div style={flyoutLabelStyle}>{profile.language === "de" ? "Zeitfenster" : "Slot Duration"}</div>
<div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div> <div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { const v = !effectiveShowSubHourSlots; setShowSubHourSlots(v); saveSetting("showSubHourSlots", v); }} style={{ background: "none", border: "none", cursor: "pointer", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={15} /> : <EyeOff size={15} />}</button></div> <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { saveViewSetting("showSubHourSlots", !effectiveShowSubHourSlots, true); }} style={{ background: "none", border: "none", cursor: "pointer", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={15} /> : <EyeOff size={15} />}</button></div>
</> </>
)} )}
{flyoutSection === "visibility" && ( {flyoutSection === "visibility" && (
@ -6190,7 +6190,7 @@ export default function WeeklyView() {
<> <>
<div style={flyoutLabelStyle}>{profile.language === "de" ? "Zeitfenster" : "Slot Duration"}</div> <div style={flyoutLabelStyle}>{profile.language === "de" ? "Zeitfenster" : "Slot Duration"}</div>
<div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div> <div style={{ display: "flex", gap: "4px" }}>{(([15, 20, 30, 60] as CellDuration[])).map((d) => (<button key={d} onClick={() => { setCellDuration(d); saveSetting("cellDuration", d); saveViewSetting("cellDuration", d, true); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "var(--ink)") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}>{d}m</button>))}</div>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { const v = !effectiveShowSubHourSlots; setShowSubHourSlots(v); saveSetting("showSubHourSlots", v); }} style={{ background: "none", border: "none", cursor: "pointer", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={15} /> : <EyeOff size={15} />}</button></div> <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}><span style={{ fontSize: "0.75rem", color: darkMode ? "#9ca3af" : "#6b7280" }}>:15/:30/:45</span><button onClick={() => { saveViewSetting("showSubHourSlots", !effectiveShowSubHourSlots, true); }} style={{ background: "none", border: "none", cursor: "pointer", color: darkMode ? "#9ca3af" : "#6b7280" }}>{effectiveShowSubHourSlots ? <Eye size={15} /> : <EyeOff size={15} />}</button></div>
</> </>
)} )}
{flyoutSection === "visibility" && ( {flyoutSection === "visibility" && (