feat: menu position setting — left rail or top toolbar, not both
Add a "Menüposition / Menu position" segmented toggle (Left / Top) in
the expanded left-rail preferences panel and in the top-mode overlay.
- "Left" (default): persistent left rail; header toolbar controls are
de-emphasised (fade in on hover only since they are duplicated).
- "Top": left rail hidden entirely; header controls always visible;
PanelLeftOpen button in header opens the full settings overlay.
Persisted via saveSetting("menuPosition", …) so the choice survives
page reloads.
v1.106.1
This commit is contained in:
parent
c3dd70a438
commit
0e09711432
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "my-weekly-todo-list",
|
"name": "my-weekly-todo-list",
|
||||||
"version": "1.106.0",
|
"version": "1.106.1",
|
||||||
"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": {
|
||||||
|
|||||||
@ -33,6 +33,8 @@ import {
|
|||||||
import FocusModeOverlay from "./FocusModeOverlay";
|
import FocusModeOverlay from "./FocusModeOverlay";
|
||||||
import {
|
import {
|
||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
|
LayoutPanelLeft,
|
||||||
|
LayoutPanelTop,
|
||||||
Calendar,
|
Calendar,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
ChevronLeft,
|
ChevronLeft,
|
||||||
@ -5372,6 +5374,7 @@ export default function WeeklyView() {
|
|||||||
return `${(num * fontSizeScale * mobileScale).toFixed(3)}rem`;
|
return `${(num * fontSizeScale * mobileScale).toFixed(3)}rem`;
|
||||||
};
|
};
|
||||||
const activeTheme = (darkMode ? profile.darkTheme : profile.lightTheme) as Record<string, string> | null;
|
const activeTheme = (darkMode ? profile.darkTheme : profile.lightTheme) as Record<string, string> | null;
|
||||||
|
const useLeftRail = !isMobile && profile.menuPosition !== "top";
|
||||||
|
|
||||||
const containerStyle = {
|
const containerStyle = {
|
||||||
...(activeTheme ? {
|
...(activeTheme ? {
|
||||||
@ -5450,7 +5453,7 @@ export default function WeeklyView() {
|
|||||||
"--weekly-past-color": activeTheme?.color8 || (darkMode
|
"--weekly-past-color": activeTheme?.color8 || (darkMode
|
||||||
? invertColor(profile.pastDayColor || "#a6a6a7")
|
? invertColor(profile.pastDayColor || "#a6a6a7")
|
||||||
: profile.pastDayColor || "#a6a6a7"),
|
: profile.pastDayColor || "#a6a6a7"),
|
||||||
...(!isMobile ? { paddingLeft: leftRailExpanded ? "240px" : "44px", transition: "padding-left 0.2s ease" } : {}),
|
...(useLeftRail ? { paddingLeft: leftRailExpanded ? "240px" : "44px", transition: "padding-left 0.2s ease" } : {}),
|
||||||
} as React.CSSProperties;
|
} as React.CSSProperties;
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
@ -5757,8 +5760,63 @@ export default function WeeklyView() {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Desktop Top-mode overlay — opens like the mobile overlay, triggered by header button */}
|
||||||
|
{!isMobile && !useLeftRail && showQuickSettings && (
|
||||||
|
<>
|
||||||
|
<div onClick={() => setShowQuickSettings(false)} style={{ position: "fixed", inset: 0, zIndex: 999 }} />
|
||||||
|
<div style={{ position: "fixed", left: 0, top: 0, bottom: 0, width: "240px", background: darkMode ? "#1a1a2e" : "var(--paper)", borderRight: "1px solid var(--line)", zIndex: 1000, display: "flex", flexDirection: "column", padding: "16px 14px", gap: "10px", overflowY: "auto", boxShadow: "2px 0 8px rgba(0,0,0,0.04)" }}>
|
||||||
|
<div style={{ fontSize: "0.85rem", fontWeight: 700, color: darkMode ? "#e5e7eb" : "#333" }}>{profile.language === "de" ? "Einstellungen" : "Preferences"}</div>
|
||||||
|
{/* Menu position toggle */}
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}>
|
||||||
|
<span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Menüposition" : "Menu position"}</span>
|
||||||
|
<div style={{ display: "flex", gap: "4px" }}>
|
||||||
|
<button onClick={() => { setProfile((p: any) => ({ ...p, menuPosition: "left" })); saveSetting("menuPosition", "left"); setShowQuickSettings(false); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.75rem", borderRadius: "6px", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", gap: "5px", fontWeight: (profile.menuPosition || "left") === "left" ? 700 : 400, background: (profile.menuPosition || "left") === "left" ? "var(--accent)" : (darkMode ? "#1f2937" : "#e5e7eb"), color: (profile.menuPosition || "left") === "left" ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}><LayoutPanelLeft size={13} />{profile.language === "de" ? "Links" : "Left"}</button>
|
||||||
|
<button onClick={() => { setProfile((p: any) => ({ ...p, menuPosition: "top" })); saveSetting("menuPosition", "top"); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.75rem", borderRadius: "6px", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", gap: "5px", fontWeight: (profile.menuPosition || "left") === "top" ? 700 : 400, background: (profile.menuPosition || "left") === "top" ? "var(--accent)" : (darkMode ? "#1f2937" : "#e5e7eb"), color: (profile.menuPosition || "left") === "top" ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}><LayoutPanelTop size={13} />{profile.language === "de" ? "Oben" : "Top"}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ borderTop: "1px solid var(--line)", paddingTop: "8px" }} />
|
||||||
|
<div style={{ display: "flex", justifyContent: "center", gap: "4px", borderBottom: "1px solid var(--line)", paddingBottom: "10px" }}>
|
||||||
|
<button onClick={() => { goToPrevWeek(); setShowQuickSettings(false); }} style={{ ...qsBtnStyle(darkMode), minWidth: "36px" }} title="Previous Week"><ChevronsLeft size={16} /></button>
|
||||||
|
<button onClick={() => { goToPrevDay(); setShowQuickSettings(false); }} style={{ ...qsBtnStyle(darkMode), minWidth: "36px" }} title="Previous Day"><ChevronLeft size={16} /></button>
|
||||||
|
<button onClick={() => { goToToday(); setShowQuickSettings(false); }} style={{ ...qsBtnStyle(darkMode), minWidth: "56px", fontWeight: 700, fontSize: "0.7rem" }}>{profile.language === "de" ? "Heute" : "Today"}</button>
|
||||||
|
<button onClick={() => { goToNextDay(); setShowQuickSettings(false); }} style={{ ...qsBtnStyle(darkMode), minWidth: "36px" }} title="Next Day"><ChevronRight size={16} /></button>
|
||||||
|
<button onClick={() => { goToNextWeek(); setShowQuickSettings(false); }} style={{ ...qsBtnStyle(darkMode), minWidth: "36px" }} title="Next Week"><ChevronsRight size={16} /></button>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: "1px" }}>
|
||||||
|
<button onClick={() => { setIsSearchOpen(true); setShowQuickSettings(false); }} style={qsActionStyle(darkMode)}><Search size={16} /> <span>{profile.language === "de" ? "Suche" : "Search"}</span></button>
|
||||||
|
<button onClick={() => { setShowDatePicker(true); setShowQuickSettings(false); }} style={qsActionStyle(darkMode)}><Calendar size={16} /> <span>{profile.language === "de" ? "Datum wählen" : "Jump to date"}</span></button>
|
||||||
|
<button onClick={() => { const now = new Date(); setCalendarEventModal({ isOpen: true, event: undefined, initialDate: now, initialStartTime: `${String(now.getHours()).padStart(2, "0")}:00` }); setShowQuickSettings(false); }} style={qsActionStyle(darkMode)}><Plus size={16} /> <span>{profile.language === "de" ? "Kalendereintrag" : "Calendar Event"}</span></button>
|
||||||
|
<button onClick={() => { setShowProjectsSidebar(true); setShowQuickSettings(false); }} style={qsActionStyle(darkMode)}><FolderPlus size={16} /> <span>{profile.language === "de" ? "Projekte" : "Projects"}</span></button>
|
||||||
|
<button onClick={() => { setIsRecurringTasksOpen(true); setShowQuickSettings(false); }} style={qsActionStyle(darkMode)}><Repeat size={16} /> <span>{profile.language === "de" ? "Wiederkehrend" : "Recurring Tasks"}</span></button>
|
||||||
|
<button onClick={() => { const nv = !profile.showNextTask; setShowNextTask(nv); saveSetting("showNextTask", nv); }} style={qsActionStyle(darkMode)}>{profile.showNextTask ? <Play size={16} /> : <Target size={16} />}<span>{profile.showNextTask ? (profile.language === "de" ? "Nächste Aufgabe" : "Next Task") : (profile.language === "de" ? "Ziel" : "Goal")}</span></button>
|
||||||
|
<button onClick={() => { setShowFocusMode(true); setShowQuickSettings(false); }} style={qsActionStyle(darkMode)}><Zap size={16} /> <span>{profile.language === "de" ? "Fokus" : "Focus"}</span></button>
|
||||||
|
</div>
|
||||||
|
<div style={{ borderTop: "1px solid var(--line)", paddingTop: "8px" }} />
|
||||||
|
<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>
|
||||||
|
{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>)}
|
||||||
|
<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" }} />
|
||||||
|
{[{ 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>))}
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}><span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "#6b7280" }}>{profile.language === "de" ? "Starten mit" : "Start on"}</span><div style={{ display: "flex", gap: "4px" }}><button onClick={() => { setProfile({ ...profile, startDayOffset: 0 }); saveSetting("startDayOffset", 0); const d = new Date(); d.setHours(0, 0, 0, 0); setCurrentWeekStart(d); }} style={{ padding: "4px 10px", fontSize: "0.75rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: (profile.startDayOffset || 0) === 0 ? 700 : 400, background: (profile.startDayOffset || 0) === 0 ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: (profile.startDayOffset || 0) === 0 ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>{profile.language === "de" ? "Heute" : "Today"}</button><button onClick={() => { setProfile({ ...profile, startDayOffset: -1 }); saveSetting("startDayOffset", -1); const d = new Date(); d.setHours(0, 0, 0, 0); d.setDate(d.getDate() - 1); setCurrentWeekStart(d); }} style={{ padding: "4px 10px", fontSize: "0.75rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: profile.startDayOffset === -1 ? 700 : 400, background: profile.startDayOffset === -1 ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: profile.startDayOffset === -1 ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>{profile.language === "de" ? "Gestern" : "Yesterday"}</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" ? "Anzeige" : "Display"}</span><div style={{ display: "flex", gap: "4px" }}><button onClick={() => setDarkMode(false)} style={{ padding: "4px 10px", fontSize: "0.75rem", borderRadius: "6px", border: "none", cursor: "pointer", display: "flex", alignItems: "center", gap: "4px", fontWeight: !darkMode ? 700 : 400, background: !darkMode ? "#333" : (darkMode ? "#1f2937" : "#e5e7eb"), color: !darkMode ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}><Sun size={12} /> {profile.language === "de" ? "Hell" : "Light"}</button><button onClick={() => setDarkMode(true)} style={{ padding: "4px 10px", fontSize: "0.75rem", borderRadius: "6px", border: "none", cursor: "pointer", display: "flex", alignItems: "center", gap: "4px", fontWeight: darkMode ? 700 : 400, background: darkMode ? "#374151" : "#e5e7eb", color: darkMode ? "#fff" : "#6b7280" }}><Moon size={12} /> {profile.language === "de" ? "Dunkel" : "Dark"}</button></div></div>
|
||||||
|
<div style={{ borderTop: `1px solid ${darkMode ? "#333" : "#e5e7eb"}`, paddingTop: "4px" }} />
|
||||||
|
<div style={{ display: "flex", justifyContent: "center", gap: "8px", padding: "2px 0" }}>
|
||||||
|
<button onClick={handleUndo} disabled={undoCount === 0} style={{ ...qsBtnStyle(darkMode), opacity: undoCount === 0 ? 0.3 : 1 }} title="Undo"><Undo2 size={15} /></button>
|
||||||
|
<button onClick={handleRedo} disabled={redoCount === 0} style={{ ...qsBtnStyle(darkMode), opacity: redoCount === 0 ? 0.3 : 1 }} title="Redo"><Redo2 size={15} /></button>
|
||||||
|
<button onClick={() => { fetchCalendarEvents(true); fetchTasks(); setShowQuickSettings(false); }} style={qsBtnStyle(darkMode)} title="Refresh"><RefreshCcw size={15} /></button>
|
||||||
|
</div>
|
||||||
|
<div style={{ flex: 1 }} />
|
||||||
|
<button onClick={() => setShowQuickSettings(false)} style={{ display: "flex", alignItems: "center", gap: "6px", background: "none", border: "none", cursor: "pointer", fontSize: "0.75rem", color: darkMode ? "#6b7280" : "#9ca3af", padding: "4px 0" }}>
|
||||||
|
<PanelLeftClose size={16} />{profile.language === "de" ? "Ausblenden" : "Hide"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Desktop Left Rail — persistent, collapses to icon strip */}
|
{/* Desktop Left Rail — persistent, collapses to icon strip */}
|
||||||
{!isMobile && (
|
{useLeftRail && (
|
||||||
<>
|
<>
|
||||||
{/* The rail panel */}
|
{/* The rail panel */}
|
||||||
<div style={{ position: "fixed", left: 0, top: 0, bottom: 0, width: leftRailExpanded ? "240px" : "44px", transition: "width 0.2s ease", background: darkMode ? "#1a1a2e" : "var(--paper)", borderRight: "1px solid var(--line)", zIndex: 100, display: "flex", flexDirection: "column", overflow: "hidden" }}>
|
<div style={{ position: "fixed", left: 0, top: 0, bottom: 0, width: leftRailExpanded ? "240px" : "44px", transition: "width 0.2s ease", background: darkMode ? "#1a1a2e" : "var(--paper)", borderRight: "1px solid var(--line)", zIndex: 100, display: "flex", flexDirection: "column", overflow: "hidden" }}>
|
||||||
@ -5771,6 +5829,15 @@ export default function WeeklyView() {
|
|||||||
<PanelLeftClose size={16} />
|
<PanelLeftClose size={16} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
{/* Menu position toggle */}
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}>
|
||||||
|
<span style={{ fontSize: "0.7rem", fontWeight: 600, color: darkMode ? "#9ca3af" : "var(--ink-3)" }}>{profile.language === "de" ? "Menüposition" : "Menu position"}</span>
|
||||||
|
<div style={{ display: "flex", gap: "4px" }}>
|
||||||
|
<button onClick={() => { setProfile((p: any) => ({ ...p, menuPosition: "left" })); saveSetting("menuPosition", "left"); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.75rem", borderRadius: "6px", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", gap: "5px", fontWeight: (profile.menuPosition || "left") === "left" ? 700 : 400, background: (profile.menuPosition || "left") === "left" ? "var(--accent)" : (darkMode ? "#1f2937" : "#e5e7eb"), color: (profile.menuPosition || "left") === "left" ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}><LayoutPanelLeft size={13} />{profile.language === "de" ? "Links" : "Left"}</button>
|
||||||
|
<button onClick={() => { setProfile((p: any) => ({ ...p, menuPosition: "top" })); saveSetting("menuPosition", "top"); setLeftRailExpanded(false); }} style={{ flex: 1, padding: "5px 0", fontSize: "0.75rem", borderRadius: "6px", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", gap: "5px", fontWeight: (profile.menuPosition || "left") === "top" ? 700 : 400, background: (profile.menuPosition || "left") === "top" ? "var(--accent)" : (darkMode ? "#1f2937" : "#e5e7eb"), color: (profile.menuPosition || "left") === "top" ? "#fff" : (darkMode ? "#9ca3af" : "var(--ink-3)") }}><LayoutPanelTop size={13} />{profile.language === "de" ? "Oben" : "Top"}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ borderTop: "1px solid var(--line)" }} />
|
||||||
{/* Navigation */}
|
{/* Navigation */}
|
||||||
<div style={{ display: "flex", justifyContent: "center", gap: "4px", padding: "4px 0", borderBottom: "1px solid var(--line)", paddingBottom: "10px" }}>
|
<div style={{ display: "flex", justifyContent: "center", gap: "4px", padding: "4px 0", borderBottom: "1px solid var(--line)", paddingBottom: "10px" }}>
|
||||||
<button onClick={goToPrevWeek} style={{ ...qsBtnStyle(darkMode), minWidth: "36px" }} title="Previous Week"><ChevronsLeft size={16} /></button>
|
<button onClick={goToPrevWeek} style={{ ...qsBtnStyle(darkMode), minWidth: "36px" }} title="Previous Week"><ChevronsLeft size={16} /></button>
|
||||||
@ -6012,8 +6079,18 @@ export default function WeeklyView() {
|
|||||||
|
|
||||||
{/* Desktop Header: Left, Center, Right */}
|
{/* Desktop Header: Left, Center, Right */}
|
||||||
<header className="group relative flex items-center justify-between w-full px-4 py-1.5 border-b bg-white dark:bg-gray-900 dark:text-white transition-colors duration-200" style={isMobile ? { display: "none" } : { borderBottomColor: 'var(--line)' }}>
|
<header className="group relative flex items-center justify-between w-full px-4 py-1.5 border-b bg-white dark:bg-gray-900 dark:text-white transition-colors duration-200" style={isMobile ? { display: "none" } : { borderBottomColor: 'var(--line)' }}>
|
||||||
{/* LEFT SECTION: View Switcher, Days, Hours, Slot Duration */}
|
{/* LEFT SECTION: View Switcher, Days, Hours, Slot Duration — only shown in top-toolbar mode */}
|
||||||
<div className="weekly-header-controls flex items-center gap-4 transition-opacity duration-700 opacity-0 group-hover:opacity-100" style={{ zIndex: 1, ...(showIntroHints ? { opacity: 1 } : {}) }}>
|
<div className={`weekly-header-controls flex items-center gap-4 ${useLeftRail ? "transition-opacity duration-700 opacity-0 group-hover:opacity-100" : ""}`} style={{ zIndex: 1, ...(showIntroHints ? { opacity: 1 } : {}) }}>
|
||||||
|
{/* Quick-settings button (top mode only) */}
|
||||||
|
{!useLeftRail && (
|
||||||
|
<button
|
||||||
|
onClick={() => setShowQuickSettings(true)}
|
||||||
|
className="p-1.5 rounded text-gray-400 hover:text-gray-700 hover:bg-gray-100 dark:hover:text-white dark:hover:bg-gray-700 transition-colors"
|
||||||
|
title={profile.language === "de" ? "Einstellungen" : "Settings"}
|
||||||
|
>
|
||||||
|
<PanelLeftOpen size={16} />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
{/* View Switcher */}
|
{/* View Switcher */}
|
||||||
<div className="flex items-center gap-0.5 bg-gray-100 dark:bg-gray-800 rounded p-0.5" title={t.viewStyle}>
|
<div className="flex items-center gap-0.5 bg-gray-100 dark:bg-gray-800 rounded p-0.5" title={t.viewStyle}>
|
||||||
<button
|
<button
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user