diff --git a/src/components/GridTaskBlock.tsx b/src/components/GridTaskBlock.tsx index 9a1401a..9085e2b 100644 --- a/src/components/GridTaskBlock.tsx +++ b/src/components/GridTaskBlock.tsx @@ -180,7 +180,7 @@ export function GridTaskBlock({ boxShadow: (isNotesOpen || isSubTasksOpen || isResizing) ? "0 1px 3px rgba(0,0,0,0.05)" : "none", display: "flex", flexDirection: "column", - overflow: isNotesOpen || isSubTasksOpen ? "visible" : "hidden", + overflow: "visible", }} draggable={!editingTaskId && !isResizing} onDragStart={(e) => handleDragStart(e, task)} diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index 2ba0463..2c83184 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -539,6 +539,7 @@ export default function WeeklyView() { todayHighlightColor?: string; pastDayColor?: string; goalFallbackType?: "quote" | "next_todo" | "default"; + quoteSourceUrl?: string; goalDefaultSentence?: string; goalFontFamily?: string; goalFontSize?: string; @@ -607,7 +608,9 @@ export default function WeeklyView() { weekendColorSat: "#666666", weekendColorSun: "#dc2626", pastDayColor: "#a6a6a7", + quoteSourceUrl: "https://recite.vercel.app/api/random", }); + const [motivationalQuote, setMotivationalQuote] = useState(""); const [showSummary, setShowSummary] = useState(false); const [isAddingSomedayList, setIsAddingSomedayList] = useState(false); @@ -940,14 +943,43 @@ export default function WeeklyView() { } }; + const fetchMotivationalQuote = useCallback(async () => { + if (profile.goalFallbackType !== "quote") return; + try { + const url = profile.quoteSourceUrl || "https://recite.vercel.app/api/random"; + const res = await fetch(url); + if (!res.ok) throw new Error("Failed to fetch quote"); + const data = await res.json(); + + // Handle different JSON formats (array or object) + let quoteText = ""; + if (Array.isArray(data) && data.length > 0) { + const item = data[0]; + quoteText = item.quote || item.text || item.content || (typeof item === 'string' ? item : ""); + if (item.author) quoteText += ` - ${item.author}`; + } else if (data && typeof data === 'object') { + quoteText = data.quote || data.text || data.content || ""; + if (data.author) quoteText += ` - ${data.author}`; + } else if (typeof data === 'string') { + quoteText = data; + } + + if (quoteText) setMotivationalQuote(quoteText); + } catch (error) { + console.error("Error fetching motivational quote:", error); + setMotivationalQuote("Stay focused and productive."); + } + }, [profile.goalFallbackType, profile.quoteSourceUrl]); + // Fetch tasks on mount useEffect(() => { if (session) { fetchTasks(); fetchConnections(); fetchCalendarEvents(); + fetchMotivationalQuote(); } - }, [session]); + }, [session, fetchMotivationalQuote]); // Periodic pull-sync from Google Tasks (every 2 minutes) useEffect(() => { @@ -1104,18 +1136,21 @@ export default function WeeklyView() { setGoal(newGoal); try { await fetch("/api/goal", { - method: "PUT", + method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ weekStart: goalDateKey, - text: newGoal, + goal: newGoal, + scope: profile.goalScope || "week", }), }); - } catch (err) { - console.error("Failed to save goal:", err); + } catch (error) { + console.error("Error saving goal:", error); } }; + + const handleSomedayWheel = (e: React.WheelEvent) => { if (e.currentTarget) { e.currentTarget.scrollLeft += e.deltaY; @@ -3277,10 +3312,10 @@ export default function WeeklyView() { {/* Week & Year */}
+ URL that returns a JSON list or object of quotes (e.g. {'[{"quote":"...","author":"..."}]'} or {'{"quote":"..."}'}). +
+