Unhandled Runtime Error
TypeError: article.content.substring is not a function

Source
component\FootballDashboard.tsx (171:81) @ substring

  169 |                         <CardContent className="p-4">
  170 |                           <h3 className="font-semibold text-lg mb-2">{article.title}</h3>
> 171 |                           <p className="text-sm text-gray-600">{article.content.substring(0, 100)}...</p>
      |                                                                                 ^
  172 |                         </CardContent>
  173 |                       </Card>
  174 |                     ))}
Call Stack
Show collapsed frames

// component/FootballDashboard.tsx
'use client'

import { useState, useEffect } from 'react'
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Button } from "@/components/ui/button"
import { RefreshCw, Play, LogIn, LogOut } from 'lucide-react'
import Image from 'next/image'
import Link from 'next/link'
import LiveScore from './LiveScore'
import LeagueSelector from './LeagueSelector'
import NewsArticles from './NewsArticles'
import PlayerSearch from './PlayerSearch'
import TeamHistory from './TeamHistory'
import FantasySports from './FantasySports'
import VideoContent from './VideoContent'
import AdminDashboard from './AdminDashboard'

const API_BASE_URL = 'http://localhost:5000'

export default function HomePage() {
  const [liveScores, setLiveScores] = useState<{ [key: string]: any[] } | null>(null)
  const [articles, setArticles] = useState<any[]>([])
  const [videos, setVideos] = useState<any[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [isAdmin, setIsAdmin] = useState(false)

  useEffect(() => {
    const token = localStorage.getItem('adminToken')
    setIsAdmin(!!token)

    const fetchData = async () => {
      setIsLoading(true)
      try {
        const [scoresRes, articlesRes, videosRes] = await Promise.all([
          fetch(`${API_BASE_URL}/api/scores`),
          fetch(`${API_BASE_URL}/api/articles`),
          fetch(`${API_BASE_URL}/api/videos/recent`)
        ])

        const scoresData = await scoresRes.json()
        const articlesData = await articlesRes.json()
        const videosData = await videosRes.json()

        setLiveScores(scoresData.data || {})
        setArticles(articlesData.slice(0, 5)) // Limit to 5 articles
        setVideos(videosData.response.slice(0, 3)) // Limit to 3 videos
        setError(null)
      } catch (error) {
        console.error("Fetching error:", error)
        setError("Failed to load data. Please try again later.")
      } finally {
        setIsLoading(false)
      }
    }

    fetchData()
    const intervalId = setInterval(fetchData, 60000) // Refresh every minute
    return () => clearInterval(intervalId)
  }, [])

  const handleLogout = () => {
    localStorage.removeItem('adminToken')
    setIsAdmin(false)
  }

  const MatchRow = ({ match }: { match: any }) => (
    <div className="flex items-center justify-between py-2 px-4 border-b last:border-b-0">
      <div className="flex items-center space-x-2 w-5/12">
        <Image src={match.homeTeam.crest} alt={match.homeTeam.name} width={24} height={24} className="rounded-full" />
        <span className="font-medium text-sm">{match.homeTeam.shortName}</span>
      </div>
      <div className="flex flex-col items-center w-2/12">
        <div className="text-sm font-bold">
         {match.score.fullTime.home != null ? match.score.fullTime.home : '-'} - 
          {match.score.fullTime.away != null ? match.score.fullTime.away : '-'}
        </div>
        <div className="text-xs text-gray-500">
          {match.status === 'FINISHED' ? 'FT' : match.status === 'IN_PLAY' ? "LIVE" : ""}
        </div>
      </div>
      <div className="flex items-center justify-end space-x-2 w-5/12">
        <span className="font-medium text-sm">{match.awayTeam.shortName}</span>
        <Image src={match.awayTeam.crest} alt={match.awayTeam.name} width={24} height={24} className="rounded-full" />
      </div>
    </div>
  )

  return (
    <div className="container mx-auto px-4 py-8">
      <div className="flex justify-between items-center mb-8">
        <h1 className="text-4xl font-bold">FootballBuzz</h1>
        {isAdmin ? (
          <Button onClick={handleLogout} variant="outline">
            <LogOut className="mr-2 h-4 w-4" /> Logout
          </Button>
        ) : (
          <Link href="/admin/login">
            <Button variant="outline">
              <LogIn className="mr-2 h-4 w-4" /> Admin Login
            </Button>
          </Link>
        )}
      </div>

      <Tabs defaultValue="home">
        <TabsList className="mb-6">
          <TabsTrigger value="home">Home</TabsTrigger>
          <TabsTrigger value="liveScore">Live Score</TabsTrigger>
          <TabsTrigger value="leagues">Leagues</TabsTrigger>
          <TabsTrigger value="news">News</TabsTrigger>
          <TabsTrigger value="players">Players</TabsTrigger>
          <TabsTrigger value="teams">Teams</TabsTrigger>
          <TabsTrigger value="fantasy">Fantasy</TabsTrigger>
          <TabsTrigger value="videos">Videos</TabsTrigger>
          {isAdmin && <TabsTrigger value="admin">Admin</TabsTrigger>}
        </TabsList>

        <TabsContent value="home">
          <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
            {/* Live Scores Section */}
            <div className="lg:col-span-2">
              <Card className="mb-8">
                <CardHeader className="flex flex-row items-center justify-between pb-2">
                  <CardTitle className="text-2xl font-bold">Live Scores</CardTitle>
                  <Button variant="ghost" size="sm" onClick={() => window.location.reload()}>
                    <RefreshCw size={16} />
                  </Button>
                </CardHeader>
                <CardContent>
                  <ScrollArea className="h-[400px] pr-4">
                    {isLoading ? (
                      <p>Loading live scores...</p>
                    ) : error ? (
                      <p className="text-red-500">{error}</p>
                    ) : liveScores && Object.keys(liveScores).length > 0 ? (
                      Object.entries(liveScores).map(([league, matches]) => (
                        <div key={league} className="mb-4">
                          <h3 className="font-semibold text-lg mb-2">{league}</h3>
                          {Array.isArray(matches) ? (
                            matches.map((match: any) => (
                              <MatchRow key={match.id} match={match} />
                            ))
                          ) : (
                            <p className="text-red-500">Invalid data format for league: {league}</p>
                          )}
                        </div>
                      ))
                    ) : (
                      <p>No live scores available at the moment.</p>
                    )}
                  </ScrollArea>
                </CardContent>
              </Card>

              {/* News Articles Section */}
              <Card>
                <CardHeader>
                  <CardTitle className="text-2xl font-bold">Latest News</CardTitle>
                </CardHeader>
                <CardContent>
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    {articles.map(article => (
                      <Card key={article.id} className="overflow-hidden">
                        <Image src={article.headingImage} alt={article.title} width={300} height={200} className="w-full h-40 object-cover" />
                        <CardContent className="p-4">
                          <h3 className="font-semibold text-lg mb-2">{article.title}</h3>
                          <p className="text-sm text-gray-600">{article.content.substring(0, 100)}...</p>
                        </CardContent>
                      </Card>
                    ))}
                  </div>
                </CardContent>
              </Card>
            </div>

            {/* Videos Section */}
            <div>
              <Card>
                <CardHeader>
                  <CardTitle className="text-2xl font-bold">Featured Videos</CardTitle>
                </CardHeader>
                <CardContent>
                  <div className="space-y-4">
                    {videos.map(video => (
                      <div key={video.id} className="relative">
                        <Image src={video.thumbnail} alt={video.title} width={300} height={200} className="w-full rounded-lg" />
                        <div className="absolute inset-0 flex items-center justify-center">
                          <Play className="h-12 w-12 text-white bg-black bg-opacity-50 rounded-full p-3" />
                        </div>
                        <h4 className="mt-2 font-semibold">{video.title}</h4>
                      </div>
                    ))}
                  </div>
                </CardContent>
              </Card>
            </div>
          </div>
        </TabsContent>

        <TabsContent value="liveScore">
          <LiveScore />
        </TabsContent>
        <TabsContent value="leagues">
          <LeagueSelector />
        </TabsContent>
        <TabsContent value="news">
          <NewsArticles />
        </TabsContent>
        <TabsContent value="players">
          <PlayerSearch />
        </TabsContent>
        <TabsContent value="teams">
          <TeamHistory />
        </TabsContent>
        <TabsContent value="fantasy">
          <FantasySports />
        </TabsContent>
        <TabsContent value="videos">
          <VideoContent />
        </TabsContent>
        {isAdmin && (
          <TabsContent value="admin">
            <AdminDashboard />
          </TabsContent>
        )}
      </Tabs>
    </div>
  )
}
Can you remove this error and make it work like