diff --git a/frontend/app/users/[userId]/page.tsx b/frontend/app/users/[userId]/page.tsx index afa28a7..735a687 100644 --- a/frontend/app/users/[userId]/page.tsx +++ b/frontend/app/users/[userId]/page.tsx @@ -4,32 +4,46 @@ import React, { useEffect, useState } from "react"; -export default function PublicUserProfilePage({ params }: { params: { userId: string } }) { - const { userId } = params; +// --- FIX: Define specific types for the data --- +interface Solve { + id: number; + name: string; + points: number; +} + +interface User { + id: number; + name: string; + team_name?: string; + points: number; + team_id?: number; + solves: Solve[]; +} + +interface Team { + id: number; + name: string; + points: number; +} +export default function PublicUserProfilePage({ params }: { params: { userId: string } }) { + const { userId } = params; - const [user, setUser] = useState(null); - const [team, setTeam] = useState(null); + // --- FIX: Use the new types instead of 'any' --- + const [user, setUser] = useState(null); + const [team, setTeam] = useState(null); const [teamRank, setTeamRank] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const API_BASE = "http://127.0.0.1:8000"; - // ✅ UPDATED FUNCTION function getAuthHeaders(): Record { - const headers: Record = { - "Content-Type": "application/json", - }; - + const headers: Record = { "Content-Type": "application/json" }; const token = localStorage.getItem("token"); - if (token) { headers["Authorization"] = `Bearer ${token}`; - } else { - console.warn("No auth token found. Continuing without authentication."); } - return headers; } @@ -40,36 +54,36 @@ export default function PublicUserProfilePage({ params }: { params: { userId: st try { setLoading(true); - const userRes = await fetch(`${API_BASE}/users/${userId}`, { - headers: getAuthHeaders(), - }); - if (!userRes.ok) { - throw new Error("User not found or failed to fetch data"); - } - const userData = await userRes.json(); + const userRes = await fetch(`${API_BASE}/users/${userId}`, { headers: getAuthHeaders() }); + if (!userRes.ok) throw new Error("User not found or failed to fetch data"); + + // --- FIX: Tell TypeScript the shape of the incoming data --- + const userData: User = await userRes.json(); setUser(userData); if (userData.team_id) { - const teamRes = await fetch(`${API_BASE}/teams/${userData.team_id}`, { - headers: getAuthHeaders(), - }); + const teamRes = await fetch(`${API_BASE}/teams/${userData.team_id}`, { headers: getAuthHeaders() }); if (teamRes.ok) { setTeam(await teamRes.json()); } - const allTeamsRes = await fetch(`${API_BASE}/teams`, { - headers: getAuthHeaders(), - }); + const allTeamsRes = await fetch(`${API_BASE}/teams`, { headers: getAuthHeaders() }); if (allTeamsRes.ok) { const allTeamsData = await allTeamsRes.json(); - const teamsList = allTeamsData.teams || []; - const sortedTeams = teamsList.sort((a: any, b: any) => b.points - a.points); - const rank = sortedTeams.findIndex((t: any) => t.id === userData.team_id) + 1; + // --- FIX: Type the list of teams --- + const teamsList: Team[] = allTeamsData.teams || []; + const sortedTeams = teamsList.sort((a, b) => b.points - a.points); + const rank = sortedTeams.findIndex((t) => t.id === userData.team_id) + 1; setTeamRank(rank > 0 ? rank : null); } } - } catch (err: any) { - setError(err.message); + } catch (err) { + // --- FIX: Type the error properly --- + if (err instanceof Error) { + setError(err.message); + } else { + setError("An unknown error occurred"); + } } finally { setLoading(false); } @@ -85,14 +99,13 @@ export default function PublicUserProfilePage({ params }: { params: { userId: st if (error) { return
Error: {error}
; } - + if (!user) { return
User not found.
; } return ( -
- {/* Header */} +

{user.team_name || "No Team"} @@ -105,7 +118,6 @@ export default function PublicUserProfilePage({ params }: { params: { userId: st )}

- {/* User Info */}

Username: {user.name} @@ -113,7 +125,6 @@ export default function PublicUserProfilePage({ params }: { params: { userId: st

Individual Points: {user.points}

- {/* Solves Table */}

Solves @@ -128,7 +139,8 @@ export default function PublicUserProfilePage({ params }: { params: { userId: st {user.solves && user.solves.length > 0 ? ( - user.solves.map((solve: any) => ( + // --- FIX: Use the 'Solve' type for each item in the map function --- + user.solves.map((solve: Solve) => (

); -} +} \ No newline at end of file diff --git a/frontend/app/users/page.tsx b/frontend/app/users/page.tsx index 9a66909..623134b 100644 --- a/frontend/app/users/page.tsx +++ b/frontend/app/users/page.tsx @@ -1,11 +1,13 @@ +// File: app/users/page.tsx + "use client"; import React, { useEffect, useState } from "react"; -import { useRouter } from 'next/navigation'; // ✅ 1. Import the useRouter hook -import { Jersey_10, Jaini_Purva, Outfit } from "next/font/google"; +import { useRouter } from 'next/navigation'; +// --- FIX: Removed 'Jaini_Purva' as it was unused --- +import { Jersey_10, Outfit } from "next/font/google"; const jersey = Jersey_10({ subsets: ["latin"], weight: "400", variable: "--font-jersey-10" }); -const jainiPurva = Jaini_Purva({ subsets: ["latin"], weight: "400", variable: "--font-jaini-purva" }); const outfit = Outfit({ subsets: ["latin"], variable: "--font-outfit" }); interface User { @@ -18,25 +20,29 @@ interface User { } export default function UsersPage() { - const router = useRouter(); // ✅ 2. Initialize the router + const router = useRouter(); const [users, setUsers] = useState([]); const [searchTerm, setSearchTerm] = useState(""); const [filterBy, setFilterBy] = useState<"name" | "affiliation" | "country">("name"); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); - + const API_BASE = "http://127.0.0.1:8000"; useEffect(() => { const fetchUsers = async () => { try { - // Using your backend endpoint to get the list of all users const res = await fetch(`${API_BASE}/users`); if (!res.ok) throw new Error("Failed to fetch users"); const data = await res.json(); setUsers(data.users || []); - } catch (err: any) { - setError(err.message || "Error fetching users"); + } catch (err) { + // --- FIX: Typed the error properly instead of using 'any' --- + if (err instanceof Error) { + setError(err.message); + } else { + setError("An unknown error occurred while fetching users"); + } } finally { setLoading(false); } @@ -48,12 +54,11 @@ export default function UsersPage() { const filteredUsers = users.filter((user) => { const field = filterBy === "name" ? user.name : - filterBy === "affiliation" ? user?.affiliation ?? "" : - user?.country ?? ""; + filterBy === "affiliation" ? user?.affiliation ?? "" : + user?.country ?? ""; return field.toLowerCase().includes(searchTerm.toLowerCase()); }); - // Function to handle navigation when a row is clicked const handleRowClick = (userId: number) => { router.push(`/users/${userId}`); }; @@ -66,7 +71,6 @@ export default function UsersPage() {
- {/* Search and Filter */}