Dashboard UI code:

"use client";

import React, { useEffect, useState } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart";
import {
  Bar,
  BarChart,
  ResponsiveContainer,
  XAxis,
  YAxis,
} from "recharts";
import { db } from "@/firebase"; // Ensure the correct path to your firebase config file
import {
  collection,
  query,
  orderBy,
  where,
  limit,
  getDocs,
} from "firebase/firestore";
import { OpenAI } from "openai";
import ReactMarkdown from "react-markdown";

// Configure OpenAI SDK
const openai = new OpenAI({
  apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY, // <-- Add your openAI API key here
  dangerouslyAllowBrowser: true,
});

interface HealthScore {
  type: string;
  score: number;
  state: string;
  factors: any[];
  createdAtUtc: string;
  externalId: string;
  timeOfDay?: string;
}

export default function UserEngagementDashboard() {
  const [healthScores, setHealthScores] = useState<HealthScore[]>([]);
  const [summary, setSummary] = useState<string>("");
  const [loading, setLoading] = useState<boolean>(false); // Loading state

  // Fetch data from Firestore
  useEffect(() => {
    async function fetchData() {
      try {
        const healthScoresQuery = query(
          collection(db, "score"),
          where("externalId", "==", "EXTERNALID HERE"), // <-- Add your Sahha Profile ExternalID here
          orderBy("createdAtUtc", "desc"),
          limit(14)
        );
        const healthScoresSnapshot = await getDocs(healthScoresQuery);
        const healthScoresList = healthScoresSnapshot.docs.map((doc) => {
          const data = doc.data() as HealthScore;
          return {
            ...data,
            timeOfDay: new Date(data.createdAtUtc).toLocaleString("en-US", {
              hour: "2-digit",
              minute: "2-digit",
              hour12: true,
            }), // Format the time of the day
          };
        });
        setHealthScores(healthScoresList);

      } catch (error) {
        console.error("Error fetching data: ", error);
      }
    }
    fetchData();
  }, []);

  // Function to summarize health scores using the OpenAI SDK directly
  async function summarizeScores() {
    setLoading(true); // Set loading to true when the button is clicked
    const scoresText = healthScores
      .map(
        (score) => {
          // Format each factor with details
          const formattedFactors = score.factors && score.factors.length > 0
          ? score.factors.map((factor) =>
              `${factor.name}: ${factor.value} ${factor.unit} (Goal: ${factor.goal}, State: ${factor.state})`
            ).join("\\n  - ")
          : "No additional factors.";

          return `${score.type}: ${score.score}% (Trend: ${score.state}) on ${new Date(
            score.createdAtUtc).toLocaleString()}. The important factors for this score to consider in your recommendations for this score are: ${formattedFactors}`
        }
      ).join("\\n");
      console.log(scoresText)

    try {
      // Call OpenAI SDK for summarization
      const response = await openai.chat.completions.create({
        model: "gpt-4o",
        messages: [
          {
            role: "system",
            content: `You are a marketing strategist focused on leveraging user behavior and mental states for engagement. Your role is to analyze health scores in terms of how they influence behavior, mood, and cognitive patterns. You must never provide health advice. Instead, focus on psychological or behavioral patterns, like distraction, curiosity, or positive reinforcement, based on how the user might be thinking or feeling. 
            Your goal is to create opportunities for engagement by predicting how the user is likely to behave or respond, based on their current state of mind. Use the time of day and the user's health scores to inform your suggestions without mentioning or recommending actions that directly target health improvements.
            
            Important: 
            1. Do not make recommendations that involve health advice or suggestions for improving health directly.
            2. Use the user's current emotional, physical or cognitive state to craft attention-grabbing notifications.
            3. Recommendations should focus on timing, mood engagement, and curiosity-driven interactions, avoiding health-specific language.
        
            Scores contain their type (e.g., sleep, mood, activity), a score percentage, and their state (low, medium, or high). Low indicates negative states, and high indicates positive states. Use this to infer their cognitive/behavioral tendencies and create engaging, non-health recommendations accordingly.`,
          },
          {
            role: "user",
            content: `Analyze the following health scores and provide me with some ways to engage the user based on their mindset, physical health, behavior or emotional state, without providing health recommendations:
            
            ${scoresText}. 
            
            The output strictly must be a single engagement strategy that takes into account all of the information from each of the health scores.
            You must follow it up with the reasons why you created the strategy and what data informed it.
            
            `,
          },
        ],
        max_tokens: 1000,
        temperature: 0.7,
      });

      // Update the summary state with the response
      setSummary(
        response.choices[0]?.message?.content.trim() || "No summary generated."
      );
    } catch (error) {
      console.error("Error calling OpenAI:", error);
      setSummary("Failed to generate summary.");
    } finally {
      setLoading(false); // Set loading to false after the summary is generated
    }
  }

  return (
    <div className="container mx-auto p-4 space-y-6">
      <h1 className="text-3xl font-bold mb-6">User Engagement Dashboard</h1>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        {/* Health Scores */}
        <Card>
          <CardHeader>
            <CardTitle>Health Scores (Last 14 Scores)</CardTitle>
          </CardHeader>
          <CardContent>
            <ul className="space-y-2">
              {healthScores.map((score, index) => (
                <li key={index} className="flex justify-between items-center">
                  <span className="font-medium">{score.type}:</span>
                  <div className="flex items-center gap-2">
                    <span>{score.score * 100}%</span>
                    <span className="text-sm text-gray-500">
                      {/* Format the date to show day, month, year, and time */}
                      {new Date(score.createdAtUtc).toLocaleString("en-US", {
                        weekday: "short", // Show abbreviated day name
                        year: "numeric", // Show year
                        month: "short", // Show abbreviated month name
                        day: "numeric", // Show day number
                        hour: "2-digit", // Show hour in 2 digits
                        minute: "2-digit", // Show minutes in 2 digits
                      })}
                    </span>
                    <Badge
                      variant={score.state === "high"  ? "default" : score.state === "low" ? "moderate" : "secondary"
                      }
                    >
                      {score.state}
                    </Badge>
                  </div>
                </li>
              ))}
            </ul>
            <Button className="mt-4" onClick={summarizeScores} disabled={loading}>
              {loading ? (
                <span className="flex items-center">
                  <svg
                    className="animate-spin h-5 w-5 mr-3 text-white"
                    xmlns="<http://www.w3.org/2000/svg>"
                    fill="none"
                    viewBox="0 0 24 24"
                  >
                    <circle
                      className="opacity-25"
                      cx="12"
                      cy="12"
                      r="10"
                      stroke="currentColor"
                      strokeWidth="4"
                    ></circle>
                    <path
                      className="opacity-75"
                      fill="currentColor"
                      d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
                    ></path>
                  </svg>
                  Processing...
                </span>
              ) : (
                "Create Engagements"
              )}
            </Button>
          </CardContent>
        </Card>

        {/*chart*/}
        <Card>
          <CardHeader>
            <CardTitle>Health Scores Visualization</CardTitle>
          </CardHeader>
          <CardContent>
            <ChartContainer
              config={{
                score: {
                  label: "Score",
                  color: "hsl(var(--chart-1))",
                },
              }}
              className="h-[300px]"
            >
              <ResponsiveContainer width="100%" height="100%">
                <BarChart data={healthScores}>
                  <XAxis dataKey="timeOfDay" />
                  <YAxis dataKey="score" />
                  <ChartTooltip content={<ChartTooltipContent />} />
                  <Bar
                    dataKey="type"
                    fill="var(--color-score)"
                    radius={[4, 4, 0, 0]}
                  />
                  <Bar
                    dataKey="score"
                    fill="var(--color-score)"
                    radius={[4, 4, 0, 0]}
                  />
                </BarChart>
              </ResponsiveContainer>
            </ChartContainer>
          </CardContent>
        </Card>
      </div>

      {/* Summary Output */}
      <Card>
        <CardHeader>
          <CardTitle>Engagement Opportunities</CardTitle>
        </CardHeader>
        <CardContent>
          <ReactMarkdown>{summary}</ReactMarkdown>
        </CardContent>
      </Card>
    </div>
  );
}