diff --git a/app/(auth)/login/page.js b/app/(auth)/login/page.js index 9d3a2ed..8dfb23a 100644 --- a/app/(auth)/login/page.js +++ b/app/(auth)/login/page.js @@ -32,8 +32,15 @@ export default function Login() { throw new Error(result.error); } - // Success case - redirect - router.push("/team-selection"); + // If the user has a team, redirect directly to the team page + if (result?.url) { + // Extract the teamId from the URL or session data if available + // This part depends on how your auth system returns the result + router.push(`/${session?.user?.teamId || ""}`); + } else { + // Otherwise go to team selection + router.push("/team-selection"); + } return; } catch (signInError) { console.error("Error with signIn method:", signInError); diff --git a/app/(main)/create-team/page.js b/app/(main)/create-team/page.js index 0695a78..df50595 100644 --- a/app/(main)/create-team/page.js +++ b/app/(main)/create-team/page.js @@ -46,7 +46,7 @@ export default function CreateTeam() { headers: { "Content-Type": "application/json", }, - credentials: "include", // Important for cookies + credentials: "include", body: JSON.stringify({ name: teamName }), }); @@ -56,24 +56,11 @@ export default function CreateTeam() { throw new Error(data.error || "Failed to create team"); } - // Force a session update to get the new teamId - try { - // Update the client-side session data with the new teamId - if (session && session.user) { - session.user.teamId = data.teamId; - } - - console.log("Team created successfully, redirecting to:", `/team/${data.teamId}`); - - // Add a small delay to allow session update - setTimeout(() => { - router.push(`/team/${data.teamId}`); - }, 100); - } catch (navError) { - console.error("Navigation error:", navError); - // Fallback to direct navigation - window.location.href = `/team/${data.teamId}`; - } + // Navigate with the correct URL pattern for the page component + console.log("Team created successfully with ID:", data.teamId); + + // Hard navigation to make sure we're going to the page component not the API route + window.location.href = `/${data.teamId}`; } catch (err) { setError(err.message); setIsLoading(false); diff --git a/app/(main)/team-selection/page.js b/app/(main)/team-selection/page.js index ef704e1..2ae3eab 100644 --- a/app/(main)/team-selection/page.js +++ b/app/(main)/team-selection/page.js @@ -14,7 +14,7 @@ export default function TeamSelection() { useEffect(() => { if (status === "authenticated") { if (session.user.teamId) { - router.push(`/team/${session.user.teamId}`); + window.location.href = `/${session.user.teamId}`; } else { setIsLoading(false); } @@ -41,7 +41,7 @@ export default function TeamSelection() { throw new Error(data.error || "Failed to join team"); } - router.push(`/team/${data.teamId}`); + window.location.href = `/${data.teamId}`; } catch (err) { setError(err.message); setIsLoading(false); diff --git a/app/(main)/team/[teamId]/page.js b/app/(main)/team/[teamId]/page.js index 10cb789..346a516 100644 --- a/app/(main)/team/[teamId]/page.js +++ b/app/(main)/team/[teamId]/page.js @@ -20,7 +20,7 @@ export default function TeamPage({ params }) { } console.log("Fetching team data for team ID:", teamId); - + const response = await fetch(`/api/teams/${teamId}`, { method: "GET", headers: { @@ -44,11 +44,12 @@ export default function TeamPage({ params }) { } const data = await response.json(); + console.log("Team data received:", data); + if (!data.team) { throw new Error("Team not found"); } - console.log("Team data fetched successfully:", data); setTeam(data.team); setTeamMembers(data.members || []); setError(""); @@ -69,145 +70,163 @@ export default function TeamPage({ params }) { if (status === "authenticated" && teamId) { console.log("Session authenticated, fetching team data"); fetchTeamData(); - const interval = setInterval(fetchTeamData, 5000); // Refresh every 5 seconds - return () => clearInterval(interval); } else if (status === "unauthenticated") { console.log("User not authenticated, redirecting to login"); router.push("/login"); - } else { - console.log("Waiting for session...", status); } }, [teamId, status, fetchTeamData, router]); - const handleLeaveTeam = async () => { - try { - setLoading(true); - const response = await fetch(`/api/teams/${teamId}/leave`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - credentials: "include", - }); - - if (!response.ok) { - const errorData = await response.json(); - throw new Error(errorData.error || "Failed to leave team"); - } - - // Redirect to team selection after leaving - router.push("/team-selection"); - } catch (err) { - console.error("Leave team error:", err); - setError(err.message); - } finally { - setLoading(false); - } - }; - - const handleStartHunt = async () => { - try { - if (session?.user?.role !== "admin") { - setError("Only admins can start a hunt"); - return; - } - - setLoading(true); - const response = await fetch(`/api/teams/${teamId}/start-hunt`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - credentials: "include", - }); - - if (!response.ok) { - const errorData = await response.json(); - throw new Error(errorData.error || "Failed to start hunt"); - } - - // You could redirect to a hunt page or refresh the current page - // For now, just refresh the team data - await fetchTeamData(); - } catch (err) { - console.error("Start hunt error:", err); - setError(err.message); - } finally { - setLoading(false); - } - }; - - const handleAddUser = () => { - // Navigate to add user page or open a modal - router.push(`/team/${teamId}/add-user`); - }; - if (status === "loading" || loading) { - return
Loading...
; + return ( +
+
+
Loading team data...
+
+ ); } if (error) { - return
Error: {error}
; + return ( +
+
⚠️
+
Error: {error}
+ + + +
+ ); } if (!team) { - return
Team not found
; + return ( +
+
🔍
+
Team not found
+ + + +
+ ); } return (
-
+
← -
{team.name}
-
{team.code}
-
00:00
+
+

{team.name}

+
Team Code: {team.code}
+
-
-
- Add Users -
+
+

Team Members

-
- {teamMembers.map((member) => ( -
- {member.username} {member.id === session?.user?.id && "(You)"} -
- ))} - -
-
+
+ {teamMembers.length > 0 ? ( +
+ {teamMembers.map((member) => ( +
+
👤
+
+
+ {member.username} + {member.id === session?.user?.id && " (You)"} +
+
+
+ ))}
-
+ ) : ( +
No team members found
+ )} + +
-
- - + + {session?.user?.role === "admin" && ( + + )}
-
+
🏠
+
Home
📊
+
Stats
- -
🏆
+ +
👥
+
Team
👤
+
Profile
@@ -215,134 +234,193 @@ export default function TeamPage({ params }) { .team-page { display: flex; flex-direction: column; - height: 100vh; - overflow: hidden; + min-height: 100vh; + background-color: #f4f4f4; font-family: Arial, sans-serif; } - .header { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - padding: 15px 10px; - background-color: #c8b6a6; + .team-banner { + background-color: #68543c; color: white; - font-weight: bold; + padding: 20px; position: relative; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + display: flex; + align-items: center; } .back-button { - font-size: 24px; - color: black; text-decoration: none; + color: white; + font-size: 24px; + margin-right: 15px; display: flex; align-items: center; } - .team-name, - .team-code { - text-align: center; - font-weight: 600; - color: black; - } - - .timer { - text-align: right; - color: black; - } - - .content-container { + .team-info { flex: 1; - background-color: #8ecae6; - display: flex; - flex-direction: column; - padding: 10px; - overflow-y: auto; } - .add-users-button { - background-color: #e9c46a; - color: black; - text-align: center; - padding: 15px; - margin: 10px 0; - border-radius: 15px; + .team-name { + margin: 0; + font-size: 24px; font-weight: bold; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } - .users-container { + .team-code { + margin-top: 5px; + font-size: 14px; + opacity: 0.8; + } + + .members-container { + padding: 20px; flex: 1; - background-color: #f6bd60; - border-radius: 10px; - padding: 10px; + } + + .members-title { + font-size: 18px; + margin-bottom: 15px; + color: #333; + } + + .members-list { display: flex; flex-direction: column; gap: 10px; - overflow-y: auto; } - .user-card { - background-color: #c8b6a6; - color: black; - padding: 15px; + .member-card { + background-color: white; border-radius: 8px; - text-align: center; - font-weight: bold; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - } - - .add-user-icon { - display: flex; - justify-content: center; - margin-top: 10px; - } - - .plus-icon { - width: 30px; - height: 30px; - background-color: #c8b6a6; - border-radius: 50%; + padding: 15px; display: flex; align-items: center; - justify-content: center; - font-size: 20px; - color: black; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } - .team-footer { - display: flex; - justify-content: space-around; - padding: 15px 0; - background-color: #c8b6a6; + .member-avatar { + font-size: 24px; + margin-right: 15px; } - .leave-button, - .start-hunt-button { - background-color: #e9c46a; - color: black; - padding: 10px 20px; + .member-name { + font-weight: 600; + } + + .empty-state { + text-align: center; + padding: 30px; + color: #888; + } + + .add-member-button { + background-color: #68543c; + color: white; border: none; - border-radius: 5px; + border-radius: 8px; + padding: 15px; + margin-top: 20px; + width: 100%; + font-size: 16px; font-weight: bold; cursor: pointer; } - .leave-button:disabled, - .start-hunt-button:disabled { - background-color: #ccc; - cursor: not-allowed; + .team-actions { + display: flex; + gap: 10px; + padding: 20px; } - .navbar { + .action-button { + flex: 1; + padding: 15px; + border: none; + border-radius: 8px; + font-weight: bold; + cursor: pointer; + } + + .leave-button { + background-color: #f6bd60; + color: #333; + } + + .start-button { + background-color: #588157; + color: white; + } + + .nav-bar { display: flex; justify-content: space-around; - padding: 15px 0; - background-color: #c8b6a6; + background-color: white; + border-top: 1px solid #ddd; + padding: 10px 0; + } + + .nav-item { + display: flex; + flex-direction: column; + align-items: center; + text-decoration: none; + color: #666; + flex: 1; + padding: 10px 0; + } + + .nav-item.active { + color: #68543c; } .nav-icon { font-size: 24px; + margin-bottom: 5px; + } + + .nav-label { + font-size: 12px; + } + + .loading-container, + .error-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + padding: 20px; + text-align: center; + } + + .loading-spinner { + border: 4px solid #f3f3f3; + border-top: 4px solid #68543c; + border-radius: 50%; + width: 40px; + height: 40px; + animation: spin 1s linear infinite; + margin-bottom: 20px; + } + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + + .error-icon { + font-size: 48px; + margin-bottom: 20px; + } + + .error-message { + margin-bottom: 20px; + color: #d32f2f; } `}
diff --git a/app/(main)/team/[teamId]/route.js b/app/(main)/team/[teamId]/route.js index bf759fa..5da57e0 100644 --- a/app/(main)/team/[teamId]/route.js +++ b/app/(main)/team/[teamId]/route.js @@ -1,5 +1,4 @@ import { redirect } from "next/navigation"; -import { query, queryOne } from "@/lib/db"; import { cookies } from "next/headers"; import { verifyToken } from "@/app/api/auth/[...nextauth]/route"; @@ -18,31 +17,10 @@ export async function GET(_, context) { return redirect("/login"); } - const params = await context.params; - const teamId = params.teamId; - - const team = await queryOne("SELECT * FROM teams WHERE id = ?", [teamId]); - - if (!team) { - return new Response( - JSON.stringify({ success: false, error: "Team not found" }), - { status: 404 } - ); - } - - const members = await query( - "SELECT id, username FROM users WHERE team_id = ?", - [teamId] - ); - - return new Response(JSON.stringify({ success: true, team, members }), { - status: 200, - }); + // Instead of returning JSON, redirect to the page component + return redirect(`/${context.params.teamId}`); } catch (error) { - console.error("Team fetch error:", error); - return new Response( - JSON.stringify({ success: false, error: "Failed to fetch team" }), - { status: 500 } - ); + console.error("Team route error:", error); + return redirect("/team-selection"); } }