feat: task edit alignment + settings tabs + mobile sidebar
- Someday task edit: add icon/checkbox column spacers before the textarea so the edit field aligns exactly with the task text column - Settings tabs: remove outer padding, use space-around + nowrap so all 9 icons fit in a single row without wrapping - Mobile: left sidebar rail (PanelLeftOpen button) — slides in from left with nav controls (prev/next day/week, today), actions (search, calendar jump, projects, focus, quick settings), and bottom controls (dark mode, settings, sign out). CSS class .mobile-left-sidebar and .mobile-rail-btn added for easy customization. v1.110.0
This commit is contained in:
parent
94098fdac2
commit
81f3a42620
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "my-weekly-todo-list",
|
||||
"version": "1.109.2",
|
||||
"version": "1.110.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": {
|
||||
|
||||
@ -4791,6 +4791,42 @@ h3 {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* --- Mobile Left Sidebar Rail --- */
|
||||
.mobile-left-sidebar {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.mobile-left-sidebar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-rail-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
color: var(--weekly-text-light, #888);
|
||||
transition: background 0.15s, color 0.15s;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.mobile-rail-btn:hover,
|
||||
.mobile-rail-btn:active {
|
||||
background: var(--weekly-hover-bg, rgba(0, 0, 0, 0.07));
|
||||
color: var(--weekly-text, #333);
|
||||
}
|
||||
.dark-mode .mobile-rail-btn:hover,
|
||||
.dark-mode .mobile-rail-btn:active {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: #e5e7eb;
|
||||
}
|
||||
.mobile-rail-backdrop {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
/* --- Mobile Quick Actions in Sidebar --- */
|
||||
.mobile-quick-nav-btn {
|
||||
min-width: 44px;
|
||||
|
||||
@ -951,11 +951,11 @@ function SettingsSidebar({
|
||||
className="weekly-settings-tabs"
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
flexWrap: "wrap",
|
||||
gap: "4px",
|
||||
justifyContent: "space-around",
|
||||
flexWrap: "nowrap",
|
||||
gap: "0",
|
||||
borderBottom: "1px solid var(--weekly-border, #eee)",
|
||||
padding: "0 24px",
|
||||
padding: "0",
|
||||
}}
|
||||
>
|
||||
{([
|
||||
@ -975,7 +975,7 @@ function SettingsSidebar({
|
||||
title={tab.label}
|
||||
className="settings-tab-btn"
|
||||
style={{
|
||||
padding: "10px 14px",
|
||||
padding: "10px 8px",
|
||||
borderBottom:
|
||||
activeTab === tab.key
|
||||
? "2px solid var(--weekly-text, black)"
|
||||
|
||||
@ -94,6 +94,7 @@ import {
|
||||
Star,
|
||||
LogOut,
|
||||
Briefcase,
|
||||
SlidersHorizontal,
|
||||
} from "lucide-react";
|
||||
|
||||
const stripHtml = (html: string) => html.replace(/<[^>]*>/g, '').trim();
|
||||
@ -922,6 +923,7 @@ export default function WeeklyView() {
|
||||
const [selectedDay, setSelectedDay] = useState<Date | null>(null);
|
||||
|
||||
const [showMobileFabSheet, setShowMobileFabSheet] = useState(false);
|
||||
const [showMobileRail, setShowMobileRail] = useState(false);
|
||||
const [showMobileFabMenu, setShowMobileFabMenu] = useState(false);
|
||||
const [mobileStickyDay, setMobileStickyDay] = useState<string | null>(null);
|
||||
const [mobileStickyDayVisible, setMobileStickyDayVisible] = useState(false);
|
||||
@ -6061,8 +6063,8 @@ export default function WeeklyView() {
|
||||
{/* Mobile Header */}
|
||||
{isMobile && (
|
||||
<header className="mobile-header" style={{ background: darkMode ? "#111827" : "#ffffff", borderBottom: `1px solid ${darkMode ? "#374151" : "#e5e7eb"}` }}>
|
||||
{/* Left: Quick settings */}
|
||||
<button className="mobile-header-btn" onClick={() => setShowQuickSettings(true)} title="Quick Settings" style={{ color: darkMode ? "#e5e7eb" : "#6b7280" }}>
|
||||
{/* Left: Mobile sidebar */}
|
||||
<button className="mobile-header-btn" onClick={() => setShowMobileRail(true)} title="Menu" style={{ color: darkMode ? "#e5e7eb" : "#6b7280" }}>
|
||||
<PanelLeftOpen size={22} />
|
||||
</button>
|
||||
|
||||
@ -6110,6 +6112,47 @@ export default function WeeklyView() {
|
||||
</header>
|
||||
)}
|
||||
|
||||
{/* Mobile left sidebar */}
|
||||
{isMobile && showMobileRail && (
|
||||
<>
|
||||
<div
|
||||
className="mobile-rail-backdrop"
|
||||
onClick={() => setShowMobileRail(false)}
|
||||
style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.35)", zIndex: 200 }}
|
||||
/>
|
||||
<div className="mobile-left-sidebar" style={{
|
||||
position: "fixed", left: 0, top: 0, bottom: 0, width: "60px",
|
||||
background: darkMode ? "#1a1a2e" : "var(--paper)",
|
||||
borderRight: `1px solid var(--line)`,
|
||||
zIndex: 201, display: "flex", flexDirection: "column",
|
||||
alignItems: "center", paddingTop: "8px", paddingBottom: "8px", gap: "4px",
|
||||
overflowY: "auto",
|
||||
}}>
|
||||
{/* Close */}
|
||||
<button className="mobile-rail-btn" onClick={() => setShowMobileRail(false)} title="Close" style={{ ...railIconBtnStyle }}><PanelLeftOpen size={16} /></button>
|
||||
<div className="mobile-rail-sep" style={{ width: "32px", height: "1px", background: "var(--line)", margin: "4px 0" }} />
|
||||
{/* Navigation */}
|
||||
<button className="mobile-rail-btn" onClick={() => { goToPrevWeek(); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title={profile.language === "de" ? "Vorherige Woche" : "Prev week"}><ChevronsLeft size={15} /></button>
|
||||
<button className="mobile-rail-btn" onClick={() => { goToPrevDay(); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title={profile.language === "de" ? "Vorheriger Tag" : "Prev day"}><ChevronLeft size={15} /></button>
|
||||
<button className="mobile-rail-btn" onClick={() => { goToToday(); setShowMobileRail(false); }} style={{ ...railIconBtnStyle, fontSize: "0.5rem", fontWeight: 800, letterSpacing: "0.05em" }} title="Today">{profile.language === "de" ? "HEUTE" : "TODAY"}</button>
|
||||
<button className="mobile-rail-btn" onClick={() => { goToNextDay(); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title={profile.language === "de" ? "Nächster Tag" : "Next day"}><ChevronRight size={15} /></button>
|
||||
<button className="mobile-rail-btn" onClick={() => { goToNextWeek(); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title={profile.language === "de" ? "Nächste Woche" : "Next week"}><ChevronsRight size={15} /></button>
|
||||
<div className="mobile-rail-sep" style={{ width: "32px", height: "1px", background: "var(--line)", margin: "4px 0" }} />
|
||||
{/* Actions */}
|
||||
<button className="mobile-rail-btn" onClick={() => { setIsSearchOpen(true); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title={profile.language === "de" ? "Suche" : "Search"}><Search size={15} /></button>
|
||||
<button className="mobile-rail-btn" onClick={() => { setShowDatePicker(true); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title={profile.language === "de" ? "Datum" : "Jump to date"}><CalendarDays size={15} /></button>
|
||||
<button className="mobile-rail-btn" onClick={() => { setShowProjectsSidebar(true); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title={profile.language === "de" ? "Projekte" : "Projects"}><FolderOpen size={15} /></button>
|
||||
<button className="mobile-rail-btn" onClick={() => { setShowFocusMode(true); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title={profile.language === "de" ? "Fokus" : "Focus"}><Zap size={15} /></button>
|
||||
<button className="mobile-rail-btn" onClick={() => { setShowQuickSettings(true); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title="Quick settings"><SlidersHorizontal size={15} /></button>
|
||||
<div style={{ flex: 1 }} />
|
||||
<div className="mobile-rail-sep" style={{ width: "32px", height: "1px", background: "var(--line)", margin: "4px 0" }} />
|
||||
<button className="mobile-rail-btn" onClick={() => setDarkMode(!darkMode)} style={{ ...railIconBtnStyle }} title={darkMode ? "Light" : "Dark"}>{darkMode ? <Sun size={15} /> : <Moon size={15} />}</button>
|
||||
<button className="mobile-rail-btn" onClick={() => { setShowSettings(true); setShowMobileRail(false); }} style={{ ...railIconBtnStyle }} title={profile.language === "de" ? "Einstellungen" : "Settings"}><Settings size={15} /></button>
|
||||
<button className="mobile-rail-btn" onClick={() => signOut()} style={{ ...railIconBtnStyle, color: "#ef4444" }} title={profile.language === "de" ? "Abmelden" : "Sign out"}><LogOut size={15} /></button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 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)', minHeight: useLeftRail ? "44px" : undefined }}>
|
||||
{/* LEFT SECTION: View Switcher, Days, Hours, Slot Duration — only shown in top-toolbar mode */}
|
||||
@ -10268,6 +10311,10 @@ function TaskItem({
|
||||
}}
|
||||
>
|
||||
{isEditing ? (
|
||||
<>
|
||||
{/* Someday: match icon + checkbox column widths so textarea aligns with task text */}
|
||||
{isSomeday && showProjectIcons && <span style={{ width: "18px", minWidth: "18px", flexShrink: 0 }} />}
|
||||
{isSomeday && showTaskCheckboxes && <span style={{ width: "16px", minWidth: "16px", flexShrink: 0 }} />}
|
||||
<form onSubmit={handleSubmit} style={{ flex: 1, display: "flex" }}>
|
||||
{variant === "minimal" ? (
|
||||
<textarea
|
||||
@ -10310,6 +10357,7 @@ function TaskItem({
|
||||
/>
|
||||
)}
|
||||
</form>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{/* Someday: fixed-width icon column — project icon, priority badge, delegation, or empty placeholder */}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user