139 lines
4.2 KiB
TypeScript
139 lines
4.2 KiB
TypeScript
"use client";
|
|
|
|
import { createContext, useContext, useState, useEffect, ReactNode } from "react";
|
|
import { MorningBrief, defaultBrief } from "./types";
|
|
|
|
interface MorningBriefStore {
|
|
briefs: MorningBrief[];
|
|
todayBrief: MorningBrief | null;
|
|
generateBrief: () => Promise<void>;
|
|
getBriefByDate: (date: string) => MorningBrief | undefined;
|
|
}
|
|
|
|
const MorningBriefContext = createContext<MorningBriefStore | null>(null);
|
|
|
|
const STORAGE_KEY = "sitemente:morning-briefs";
|
|
|
|
export function MorningBriefProvider({ children }: { children: ReactNode }) {
|
|
const [briefs, setBriefs] = useState<MorningBrief[]>([]);
|
|
const [todayBrief, setTodayBrief] = useState<MorningBrief | null>(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 (
|
|
<MorningBriefContext.Provider value={{ briefs, todayBrief, generateBrief, getBriefByDate }}>
|
|
{children}
|
|
</MorningBriefContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useMorningBrief() {
|
|
const ctx = useContext(MorningBriefContext);
|
|
if (!ctx) {
|
|
throw new Error("useMorningBrief must be used within MorningBriefProvider");
|
|
}
|
|
return ctx;
|
|
}
|