+ {/* Calendar */}
+
+
+
+
+ {monthNames[currentMonth]} {currentYear}
+
+
+
+
+
+ {["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((d) => (
+
+ {d}
+
+ ))}
+
+
+
+ {calendarDays}
+
+
+
+ {/* Today's Brief Preview */}
+ {todayBrief && (
+
+
+
Today's Brief
+ {todayBrief.generatedAt}
+
+
+
+ {/* Weather */}
+
+
Weather
+
+
🌤️
+
+
{todayBrief.weather?.temperature}
+
{todayBrief.weather?.condition}
+
+
+
+
+ {/* Market */}
+
+
Market
+
+
{todayBrief.market.usIndex}
+
{todayBrief.market.crypto}
+
+
+
+ {/* Tasks */}
+
+
My Tasks Today
+
+ {todayBrief.myTasks.pending.slice(0, 3).map((task, i) => (
+ - • {task}
+ ))}
+
+
+
+
+ )}
+
+ {/* Brief Detail Modal */}
+ {viewingBrief && (
+
+
setViewingBrief(null)}
+ />
+
+
+
+
Brief Date
+
{viewingBrief.date}
+
+
+
+
+
+ {/* Weather */}
+
+ 🌤️ Weather
+ {viewingBrief.weather?.temperature} — {viewingBrief.weather?.condition}
+ {viewingBrief.weather?.location}
+
+
+ {/* AI News */}
+
+ 🤖 AI News
+
+ {viewingBrief.aiNews.items.map((item, i) => (
+ - • {item}
+ ))}
+
+
+
+ {/* Tasks */}
+
+ ✓ My Tasks
+ {viewingBrief.myTasks.pending.length > 0 && (
+
+
Pending
+ {viewingBrief.myTasks.pending.map((t, i) => (
+
• {t}
+ ))}
+
+ )}
+ {viewingBrief.myTasks.inProgress.length > 0 && (
+
+
In Progress
+ {viewingBrief.myTasks.inProgress.map((t, i) => (
+
• {t}
+ ))}
+
+ )}
+
+
+ {/* Market */}
+
+ 📈 Market
+ {viewingBrief.market.usIndex}
+ {viewingBrief.market.crypto}
+
+ Sentiment: {viewingBrief.market.sentiment.toUpperCase()}
+
+
+
+
+
+ )}
+
+ {/* Generate Button */}
+
+
+ );
+}
diff --git a/lib/morning-brief/store.tsx b/lib/morning-brief/store.tsx
new file mode 100644
index 0000000..2d6f0dd
--- /dev/null
+++ b/lib/morning-brief/store.tsx
@@ -0,0 +1,138 @@
+"use client";
+
+import { createContext, useContext, useState, useEffect, ReactNode } from "react";
+import { MorningBrief, defaultBrief } from "./types";
+
+interface MorningBriefStore {
+ briefs: MorningBrief[];
+ todayBrief: MorningBrief | null;
+ generateBrief: () => Promise
;
+ getBriefByDate: (date: string) => MorningBrief | undefined;
+}
+
+const MorningBriefContext = createContext(null);
+
+const STORAGE_KEY = "sitemente:morning-briefs";
+
+export function MorningBriefProvider({ children }: { children: ReactNode }) {
+ const [briefs, setBriefs] = useState([]);
+ const [todayBrief, setTodayBrief] = useState(null);
+
+ // Load from localStorage on mount
+ useEffect(() => {
+ if (typeof window === "undefined") return;
+ const saved = localStorage.getItem(STORAGE_KEY);
+ if (saved) {
+ try {
+ const parsed = JSON.parse(saved);
+ if (Array.isArray(parsed)) {
+ setBriefs(parsed);
+ // Find today's brief
+ const today = new Date().toISOString().split("T")[0];
+ const todayBrief = parsed.find((b: MorningBrief) => b.date === today);
+ if (todayBrief) setTodayBrief(todayBrief);
+ }
+ } catch {
+ // Use default
+ }
+ }
+ }, []);
+
+ // Save to localStorage on change
+ useEffect(() => {
+ if (typeof window === "undefined") return;
+ if (briefs.length > 0) {
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(briefs));
+ }
+ }, [briefs]);
+
+ const generateBrief = async () => {
+ const today = new Date().toISOString().split("T")[0];
+ const now = new Date().toISOString();
+
+ // Get Mission Control tasks from localStorage
+ let myTasks = { pending: [], inProgress: [], dueToday: [] };
+ try {
+ const mcTasks = localStorage.getItem("sitemente:mission-control");
+ if (mcTasks) {
+ const tasks = JSON.parse(mcTasks);
+ myTasks = {
+ pending: tasks.filter((t: any) => t.status === "todo").map((t: any) => t.title).slice(0, 5),
+ inProgress: tasks.filter((t: any) => t.status === "in_progress").map((t: any) => t.title).slice(0, 3),
+ dueToday: tasks.filter((t: any) => t.dueDate === today).map((t: any) => t.title),
+ };
+ }
+ } catch (e) {
+ console.error("Failed to load Mission Control tasks", e);
+ }
+
+ // Mock data - in production, these would be API calls
+ const newBrief: MorningBrief = {
+ id: `brief-${today}`,
+ date: today,
+ generatedAt: now,
+ weather: {
+ location: "Benalmádena, Málaga",
+ temperature: "18°C",
+ condition: "Partly Cloudy",
+ humidity: "65%",
+ wind: "12 km/h NW",
+ },
+ aiNews: {
+ items: [
+ "OpenAI announces GPT-5 roadmap with enhanced reasoning",
+ "Google DeepMind achieves breakthrough in protein folding",
+ "European AI Act enters enforcement phase",
+ "Nvidia reports record AI chip demand",
+ ],
+ },
+ things3Tasks: {
+ today: [
+ "Review SiteMente pricing page",
+ "Call with potential restaurant client",
+ "Update HolaCompi roadmap",
+ ],
+ overdue: [],
+ },
+ myTasks,
+ market: {
+ usIndex: "S&P 500: +0.3%",
+ crypto: "BTC: $67,500 (+1.2%)",
+ sentiment: "bullish",
+ topNews: [
+ "Fed signals potential rate cut in March",
+ "Bitcoin ETF inflows hit record high",
+ "Tech earnings exceed expectations",
+ ],
+ events: [
+ "US Jobs Report (8:30 AM ET)",
+ "Crypto Treasury Meeting (2:00 PM ET)",
+ ],
+ },
+ };
+
+ setBriefs((prev) => {
+ const filtered = prev.filter((b) => b.date !== today);
+ return [...filtered, newBrief];
+ });
+ setTodayBrief(newBrief);
+ };
+
+ const getBriefByDate = (date: string) => {
+ return briefs.find((b) => b.date === date);
+ };
+
+ return (
+
+ {children}
+
+ );
+}
+
+export function useMorningBrief() {
+ const ctx = useContext(MorningBriefContext);
+ if (!ctx) {
+ throw new Error("useMorningBrief must be used within MorningBriefProvider");
+ }
+ return ctx;
+}
diff --git a/lib/morning-brief/types.ts b/lib/morning-brief/types.ts
new file mode 100644
index 0000000..a8e9fb1
--- /dev/null
+++ b/lib/morning-brief/types.ts
@@ -0,0 +1,59 @@
+// Morning Brief Types
+
+export interface MorningBrief {
+ id: string;
+ date: string; // YYYY-MM-DD
+ generatedAt: string; // ISO timestamp
+
+ // Weather
+ weather?: {
+ location: string;
+ temperature: string;
+ condition: string;
+ humidity: string;
+ wind: string;
+ };
+
+ // AI News
+ aiNews: {
+ items: string[];
+ };
+
+ // Things 3 Tasks (placeholder - needs integration)
+ things3Tasks?: {
+ today: string[];
+ overdue: string[];
+ };
+
+ // My actionable tasks (from Mission Control)
+ myTasks: {
+ pending: string[];
+ inProgress: string[];
+ dueToday: string[];
+ };
+
+ // Market sentiment
+ market: {
+ usIndex: string;
+ crypto: string;
+ sentiment: 'bullish' | 'bearish' | 'neutral';
+ topNews: string[];
+ events: string[];
+ };
+}
+
+export const defaultBrief: MorningBrief = {
+ id: '',
+ date: '',
+ generatedAt: '',
+ aiNews: { items: [] },
+ things3Tasks: { today: [], overdue: [] },
+ myTasks: { pending: [], inProgress: [], dueToday: [] },
+ market: {
+ usIndex: '',
+ crypto: '',
+ sentiment: 'neutral',
+ topNews: [],
+ events: [],
+ }
+};