Scopri come utilizzare lo strumento IA v0 per creare un'interfaccia moderna di classifica dei votanti con la nostra API Top-Games.
Ecco il prompt che è stato utilizzato con v0 per generare questa interfaccia:
Un elenco dei migliori votanti da un server di gioco. L'elenco può essere ottenuto da questa API: https://api.top-serveurs.net/v1/servers/:token/players-ranking
L'IA v0 ha generato automaticamente un'interfaccia React completa con gestione dello stato, chiamate API e design moderno:
"use client"
import { useEffect, useState } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Users, TrendingUp } from "lucide-react"
interface Player {
id: string
playername: string
votes: number
position: number
}
export default function Component() {
const [players, setPlayers] = useState<Player[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [totalVotes, setTotalVotes] = useState(0)
useEffect(() => {
const fetchVoterRankings = async () => {
try {
setLoading(true)
const response = await fetch("https://api.top-games.net/v1/servers/TOKEN/players-ranking")
if (!response.ok) {
throw new Error("Impossibile recuperare le classifiche dei votanti")
}
const data = await response.json()
console.log("API Response:", data) // Log di debug
// Gestire diverse possibili strutture di risposta
let playersData: Player[] = []
if (data.players && Array.isArray(data.players)) {
playersData = data.players
} else if (Array.isArray(data)) {
playersData = data
} else if (data.data && Array.isArray(data.data)) {
playersData = data.data
} else {
console.error("Formato di risposta inaspettato:", data)
throw new Error("Formato di risposta inaspettato")
}
// Assicurarsi che ogni giocatore abbia i campi richiesti
const processedPlayers = playersData.map((player: Player, index: number) => ({
id: `player-${index}`,
playername: player.playername || `Giocatore ${index + 1}`,
votes: player.votes || 0,
position: index + 1,
}))
setPlayers(processedPlayers)
setTotalVotes(processedPlayers.reduce((sum, player) => sum + player.votes, 0))
} catch (err) {
setError(err instanceof Error ? err.message : "Si è verificato un errore")
} finally {
setLoading(false)
}
}
fetchVoterRankings()
}, [])
const getRankBadgeVariant = (position: number) => {
switch (position) {
case 1:
return "default"
case 2:
return "secondary"
case 3:
return "outline"
default:
return "outline"
}
}
if (loading) {
return (
<div className="w-full max-w-4xl mx-auto p-6">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Users className="w-6 h-6" />
Migliori Votanti
</CardTitle>
<CardDescription>Caricamento classifiche votanti...</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
{[...Array(5)].map((_, i) => (
<div key={i} className="flex items-center gap-4 p-4 border rounded-lg animate-pulse">
<div className="w-12 h-12 bg-muted rounded-full" />
<div className="flex-1 space-y-2">
<div className="h-4 bg-muted rounded w-1/3" />
<div className="h-3 bg-muted rounded w-1/4" />
</div>
<div className="h-6 bg-muted rounded w-16" />
</div>
))}
</div>
</CardContent>
</Card>
</div>
)
}
if (error) {
return (
<div className="w-full max-w-4xl mx-auto p-6">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-destructive">
<Users className="w-6 h-6" />
Errore nel caricamento delle classifiche votanti
</CardTitle>
<CardDescription>{error}</CardDescription>
</CardHeader>
</Card>
</div>
)
}
return (
<div className="w-full max-w-4xl mx-auto p-6 space-y-6">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Users className="w-6 h-6" />
Classifica dei Migliori Votanti
</CardTitle>
<CardDescription className="flex items-center gap-4">
<span>Classifiche di voto del server</span>
<Badge variant="outline" className="flex items-center gap-1">
<TrendingUp className="w-3 h-3" />
{totalVotes} voti totali
</Badge>
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-3">
{players.length === 0 ? (
<div className="text-center py-8 text-muted-foreground">Nessun dato sui votanti disponibile</div>
) : (
players.map((player, index) => {
const position = index + 1
return (
<div
key={player.id || player.playername}
className={`flex items-center gap-4 p-4 border rounded-lg transition-colors hover:bg-muted/50 ${
position <= 3 ? "bg-muted/30" : ""
}`}
>
<div className="flex-1">
<div className="flex items-center gap-2">
<h3 className="font-semibold">{player.playername}</h3>
{position <= 3 && (
<Badge variant={getRankBadgeVariant(position)} className="text-xs">
{position === 1 ? "Campione" : position === 2 ? "Secondo classificato" : "Terzo posto"}
</Badge>
)}
</div>
<p className="text-sm text-muted-foreground">Rango #{position}</p>
</div>
<div className="text-right">
<div className="text-lg font-bold">{player.votes}</div>
<div className="text-xs text-muted-foreground">{player.votes === 1 ? "voto" : "voti"}</div>
</div>
</div>
)
})
)}
</div>
</CardContent>
</Card>
</div>
)
}
Link utili per riprodurre questo esempio: