the first character is being ommitted, can you help me resolve this? 

code:

import React, { useState, useEffect, useContext, useRef } from 'react';
import { useParams } from 'react-router-dom';
import axios from 'axios';
import {
Typography,
Paper,
Grid,
CircularProgress, // For loading indicator
} from '@mui/material';
import { styled } from '@mui/system';
import { PieChart, Pie, Cell, ResponsiveContainer } from 'recharts';
import { AuthContext } from '../AuthContext'; // Import AuthContext for authentication
import { signOut } from 'firebase/auth';
import { auth } from '../firebase'; // Import your Firebase auth instance

// Optional: Import an icon for the diagram placeholder (e.g., InsertChartIcon)
import InsertChartIcon from '@mui/icons-material/InsertChart';

const Container = styled(Paper)(({ theme }) => ({
padding: theme.spacing(4),
margin: theme.spacing(4),
}));

function UserPage() {
const { id } = useParams(); // Get the user ID from the route parameters
const [userData, setUserData] = useState(null);
const { currentUser } = useContext(AuthContext); // Access currentUser from context
const [error, setError] = useState(null); // Error state
const [isLoading, setIsLoading] = useState(true); // Loading state
const [generatingSummary, setGeneratingSummary] = useState(false); // State for AI summary generation
const [displayedSummary, setDisplayedSummary] = useState(''); // State for typing animation
const [typing, setTyping] = useState(false); // Typing animation state

// useRef to persist the current character index and timeout ID across renders
const indexRef = useRef(0);
const timeoutRef = useRef(null);

useEffect(() => {
// Function to fetch user data
const fetchUserData = async () => {
if (!currentUser) {
setError('User is not authenticated.');
setIsLoading(false);
return;
}


  try {
    const token = await currentUser.getIdToken(true); // Force token refresh
    const response = await axios.get(
      `https://us-central1-mind-gardener.cloudfunctions.net/api/users/${id}`,
      {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      }
    );
    setUserData(response.data);
  } catch (err) {
    if (err.response) {
      if (err.response.status === 403) {
        setError('Access denied. You do not have permission to view this user.');
      } else if (err.response.status === 401) {
        setError('Unauthorized. Please log in again.');
      } else if (err.response.status === 404) {
        setError('User not found.');
      } else {
        setError('An error occurred while fetching user data.');
      }
    } else {
      setError('Failed to fetch user data.');
    }
  } finally {
    setIsLoading(false);
  }
};

fetchUserData();
}, [id, currentUser]);

useEffect(() => {
// Automatically generate summary when userData is available and summary is not present
const generateSummary = async () => {
if (!userData || userData.summary) return; // Avoid regenerating if summary already exists or userData not loaded


  setGeneratingSummary(true);
  setError(null);
  setTyping(true);
  setDisplayedSummary(''); // Reset displayed summary
  indexRef.current = 0; // Reset index

  try {
    const token = await currentUser.getIdToken(true); // Get fresh token
    const response = await axios.post(
      `https://us-central1-mind-gardener.cloudfunctions.net/api/generate-summary`,
      { userId: id },
      {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      }
    );
    setUserData((prevState) => ({
      ...prevState,
      summary: response.data.summary, // Update the summary field
    }));
  } catch (err) {
    console.error('Error generating summary:', err);
    if (err.response && err.response.data && err.response.data.error) {
      setError(err.response.data.error);
    } else {
      setError('Error generating AI summary.');
    }
  } finally {
    setGeneratingSummary(false);
  }
};

generateSummary();
}, [userData, currentUser, id]);

useEffect(() => {
// Typing animation for the summary (character-by-character)
if (userData && userData.summary && typing) {
const summary = userData.summary;
const typingSpeed = 30; // Milliseconds per character


  const typeCharacter = () => {
    // Append the next character
    setDisplayedSummary((prev) => prev + summary.charAt(indexRef.current));
    indexRef.current += 1;

    // Check if all characters have been displayed
    if (indexRef.current < summary.length) {
      timeoutRef.current = setTimeout(typeCharacter, typingSpeed);
    } else {
      setTyping(false); // Animation complete
    }
  };

  typeCharacter(); // Start the typing animation

  // Cleanup function to clear the timeout if the component unmounts or dependencies change
  return () => {
    clearTimeout(timeoutRef.current);
  };
}
}, [userData, typing]);

const handleLogout = () => {
signOut(auth)
.then(() => {
console.log('User signed out successfully.');
})
.catch((err) => {
console.error('Error during sign out:', err);
});
};

if (isLoading) {
return (
<Typography variant="h6" align="center" sx={{ mt: 4 }}>


);
}

if (error) {
return (
<Typography variant="h6" align="center" color="error" sx={{ mt: 4 }}>
{error}

);
}

if (!userData) {
return (
<Typography variant="h6" align="center" sx={{ mt: 4 }}>
No user data available.

);
}

const data = [
{ name: 'Positive', value: userData.sentimentScore },
{ name: 'Negative', value: 100 - userData.sentimentScore },
];

const COLORS = ['#0088FE', '#FF8042'];

return (


User ID: {userData.id}
<Typography
variant="button"
onClick={handleLogout}
sx={{ cursor: 'pointer', color: 'primary.main' }}
>
Logout



  <Typography variant="h6" gutterBottom sx={{ mt: 2 }}>
    Detailed User Information
  </Typography>

  <Grid container spacing={4}>
    <Grid item xs={12} md={8}>
      <Typography variant="subtitle1" gutterBottom>
        AI-Generated Summary:
      </Typography>

      {/* Display generated summary with typing animation and justified text */}
      {userData.summary ? (
        <Typography variant="body1" sx={{ mt: 2, textAlign: 'justify', whiteSpace: 'pre-wrap' }}>
          {displayedSummary}
          {typing && <span className="cursor">|</span>}
        </Typography>
      ) : (
        <Typography variant="body1" sx={{ mt: 2, textAlign: 'justify' }}>
          Summary will be generated automatically.
        </Typography>
      )}

      {/* Placeholder for Diagram/Chart */}
      <Typography variant="subtitle1" gutterBottom mt={4}>
        User Diagram:
      </Typography>
      <div
        style={{
          height: 300,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          border: '2px dashed #ccc',
          borderRadius: '8px',
          backgroundColor: '#f9f9f9',
        }}
      >
        <InsertChartIcon color="action" sx={{ fontSize: 50, mr: 2 }} />
        <Typography variant="body2" color="textSecondary">
          Diagram or chart will be displayed here.
        </Typography>
      </div>
    </Grid>
    <Grid item xs={12} md={4}>
      <ResponsiveContainer width="100%" height={200}>
        <PieChart>
          <Pie
            data={data}
            dataKey="value"
            innerRadius={60}
            outerRadius={80}
            fill="#8884d8"
            paddingAngle={5}
            startAngle={90}
            endAngle={-270}
          >
            {data.map((entry, index) => (
              <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
            ))}
          </Pie>
        </PieChart>
      </ResponsiveContainer>
      <Typography variant="body1" align="center">
        Sentiment Score: {userData.sentimentScore}%
      </Typography>
    </Grid>
  </Grid>

  {/* Optional: Add some global styling for the blinking cursor */}
  <style jsx="true">{`
    .cursor {
      display: inline-block;
      width: 10px;
      background-color: black;
      margin-left: 2px;
      animation: blink 1s step-start infinite;
    }

    @keyframes blink {
      50% {
        opacity: 0;
      }
    }
  `}</style>
</Container>
);
}

export default UserPage;