> ## Documentation Index
> Fetch the complete documentation index at: https://academy.pathfindr.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Gemini Pulse

> Latest AI updates from Google.

export const AIPulseDataProvider = ({endpoint, children, max = 10}) => {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  useEffect(() => {
    let cancelled = false;
    const fetchPulse = async () => {
      const CACHE_KEY = `ai-pulse-cache-${endpoint}`;
      const CACHE_DURATION = 12 * 60 * 60 * 1000;
      try {
        const cached = localStorage.getItem(CACHE_KEY);
        if (cached) {
          const {data, timestamp} = JSON.parse(cached);
          const age = Date.now() - timestamp;
          if (age < CACHE_DURATION) {
            console.log("Using cached data");
            if (!cancelled) setItems(data);
            setLoading(false);
            return;
          }
        }
        console.log("Fetching fresh data from API");
        const res = await fetch(endpoint);
        if (!res.ok) {
          throw new Error(`API request failed: ${res.status}`);
        }
        const response = await res.json();
        if (!cancelled && response.success) {
          const fetchedItems = response.items || [];
          setItems(fetchedItems);
          localStorage.setItem(CACHE_KEY, JSON.stringify({
            data: fetchedItems,
            timestamp: Date.now()
          }));
        }
      } catch (e) {
        console.error("Error fetching AI pulse:", e);
        if (!cancelled) setError(e.message);
      } finally {
        if (!cancelled) setLoading(false);
      }
    };
    fetchPulse();
    return () => {
      cancelled = true;
    };
  }, [endpoint]);
  const formatDate = dateString => {
    if (!dateString) return "";
    const date = new Date(dateString);
    return date.toLocaleDateString("en-US", {
      year: "numeric",
      month: "long",
      day: "numeric"
    });
  };
  const itemsWithFormattedDate = items.slice(0, max).map(item => ({
    ...item,
    formattedDate: formatDate(item.pubDate)
  }));
  if (loading) {
    return <div style={{
      padding: "40px",
      textAlign: "center",
      color: "#64748b"
    }}>
        <div style={{
      display: "inline-block",
      width: "40px",
      height: "40px",
      border: "4px solid #e2e8f0",
      borderTopColor: "#3b82f6",
      borderRadius: "50%",
      animation: "spin 1s linear infinite"
    }} />
        <p style={{
      marginTop: "16px"
    }}>Loading AI updates...</p>
        <style>{`
          @keyframes spin {
            to { transform: rotate(360deg); }
          }
        `}</style>
      </div>;
  }
  if (error) {
    return <div style={{
      padding: "24px",
      backgroundColor: "#fef2f2",
      border: "1px solid #fecaca",
      borderRadius: "8px",
      color: "#991b1b"
    }}>
        <strong>Error loading the latest AI updates:</strong> {error}
      </div>;
  }
  if (itemsWithFormattedDate.length === 0) {
    return <div style={{
      padding: "24px",
      backgroundColor: "#f8fafc",
      border: "1px solid #e2e8f0",
      borderRadius: "8px",
      color: "#64748b",
      textAlign: "center"
    }}>
        No updates available at this time.
      </div>;
  }
  return <>{children(itemsWithFormattedDate)}</>;
};

<AIPulseDataProvider endpoint="https://mintlify-ai-pulse-api.vercel.app/api/ai-pulse?company=google" max={20}>
  {(items) => items.map((item) => (
      <Update label={item.formattedDate} tags={[item.company]}>
        <h3>{item.title}</h3>
        <p>{item.summary}</p>
        <a href={item.link} target="_blank" rel="noopener noreferrer">Read full article →</a>
      </Update>
    ))}
</AIPulseDataProvider>

<Info>
  Updates are fetched from official RSS feeds and cached for 12 hours for optimal performance.
</Info>
