Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved team backend and filter logic #132

Merged
merged 2 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions app/api/teams/create-team/route.jsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
import dbConnect from "../../../../lib/dbConnect";
import { teamSchema } from "../../../../model/Schema/teamSchema";
import { TeamModel } from "../../../../model/Team";

export async function POST(request) {
await dbConnect();

try {
const { teamname, game, role, rank, server, language, players, requests } = await request.json();
// Parse JSON body from the request
const { teamname, game, role, rank, server, language, players, participantCount} = await request.json();

await TeamModel.create({
teamname,
game,
role,
rank,
server,
language,
players,
requests
});
// Zod validation
const parsedData = teamSchema.parse({
teamname,
game,
role,
rank,
server,
language,
players,
participantCount,
// requests,
});

// Ensure 'requests' is always an array
const formattedData = {
...parsedData,
requests: Array.isArray(parsedData.requests) ? parsedData.requests : [parsedData.requests],
};

// Create a new team document in the database
const team = await TeamModel.create(formattedData);

console.log("Team created successfully:", team);

return Response.json({
success: true,
message: 'Team created successfully.'
message: "Team created successfully.",
team,
}, { status: 201 });

} catch (error) {
console.error('Error creating team:', error);
console.error("Error creating team:", error);
return Response.json({
success: false,
message: 'Error creating team'
message: "Error creating team",
error: error.message,
}, { status: 500 });
}
}
18 changes: 8 additions & 10 deletions app/create/team/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function CreateTeamForm() {
const [server, setServer] = useState("");
const [language, setLanguage] = useState("");
const [players, setPlayers] = useState("");
const [requests, setRequests] = useState("");
// const [requests, setRequests] = useState("");
const [participantCount, setParticipantCount] = useState("");

const { toast } = useToast();
Expand All @@ -40,7 +40,7 @@ export default function CreateTeamForm() {
server: "",
language: "",
players: "",
requests: "",
// requests: "",
participantCount: "",
},
shouldFocusError: false,
Expand All @@ -58,14 +58,12 @@ export default function CreateTeamForm() {
server !== "" &&
language !== "" &&
players !== "" &&
requests !== "" &&
// requests !== "" &&
participantCount !== ""
) {
const playersArray = players.split(",").map((player) => player.trim());
// const playersArray = players.split(",").map((player) => player.trim());
const dataWithPlayersArray = {
...data,
players: playersArray,
participantCount: parseInt(participantCount, 10),
...data
};

const response = await axios.post(
Expand All @@ -86,7 +84,7 @@ export default function CreateTeamForm() {
setServer("");
setLanguage("");
setPlayers("");
setRequests("");
// setRequests("");
setParticipantCount("");
}
} catch (error) {
Expand Down Expand Up @@ -274,7 +272,7 @@ export default function CreateTeamForm() {
</FormItem>
)}
/>
<FormField
{/* <FormField
control={form.control}
name="requests"
render={({ field }) => (
Expand All @@ -294,7 +292,7 @@ export default function CreateTeamForm() {
<FormMessage className="text-red-500" />
</FormItem>
)}
/>
/> */}
<FormField
control={form.control}
name="participantCount"
Expand Down
100 changes: 65 additions & 35 deletions app/teams/page.jsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,82 @@
"use client";

import React from "react";
import FiltersSidebar from "../../components/FiltersSidebar";
import TeamCard from "../../components/TeamCard";
import React, { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useState, useEffect } from "react";
import axios from "axios";
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "../../@/components/ui/card";
import FiltersSidebar from "../../components/FiltersSidebar";
import TeamCard from "../../components/TeamCard";
import { Card, CardContent, CardHeader, CardTitle } from "../../@/components/ui/card";
import { Button } from "../../@/components/ui/button";

const TeamFinder = () => {
const router = useRouter();
const [teams, setTeams] = useState([]);
const [filteredTeams, setFilteredTeams] = useState([]); // For filtered display
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [filters, setFilters] = useState({ game: "", role: "", language: "" }); // Filters state

// Fetch teams from the backend
useEffect(() => {
const fetchTeams = async () => {
try {
const response = await axios.get("/api/teams/get-teams");
if (response.data.success) {
setTeams(response.data.teams);
setFilteredTeams(response.data.teams); // Initialize filtered teams
} else if (response.status === 401) {
router.push("/auth/login");
} else {
console.error("Failed to fetch teams:", response.data.message);
throw new Error(response.data.message || "Failed to fetch teams.");
}
} catch (error) {
console.error("Error fetching teams:", error);
setError("Unable to fetch teams. Please try again later.");
} finally {
setLoading(false);
}
};

fetchTeams();
}, []);
}, [router]);

// Apply filters to the team list
useEffect(() => {
const applyFilters = () => {
const filtered = teams.filter((team) => {
return (
(!filters.game || team.game === filters.game) &&
(!filters.role || team.role === filters.role) &&
(!filters.language || team.language === filters.language)
);
});
setFilteredTeams(filtered);
};

applyFilters();
}, [filters, teams]);

const NavigateToCreateTeam = () => {
router.push("/create/team");
// Reset filters
const handleResetFilters = () => {
setFilters({ game: "", role: "", language: "" });
};

if (loading) {
return (
<div className="flex items-center justify-center min-h-screen">
<p>Loading teams...</p>
</div>
);
}

if (error) {
return (
<div className="flex items-center justify-center min-h-screen">
<p className="text-red-500">{error}</p>
</div>
);
}

return (
<div className="mt-20 px-5 md:px-10 xl:px-[12%] min-h-[70vh] transition-all">
<h1 className="text-3xl ml-4 mb-14 font-semibold tracking-tight">
Expand All @@ -50,36 +88,28 @@ const TeamFinder = () => {
<CardHeader className="flex flex-col gap-5">
<CardTitle className="flex items-center justify-between">
<h2 className="text-2xl">Find Team</h2>
<Button
// variant="outline"
className=""
onClick={NavigateToCreateTeam}
>
<Button onClick={() => router.push("/create/team")}>
Create Team
</Button>
</CardTitle>

<div className="mb-4 flex flex-wrap gap-2 justify-between">
<Button variant="outline" className="px-4 py-2 rounded text-sm">
Request Raised
</Button>
<Button variant="outline" className="px-4 py-2 rounded text-sm">
Request Sent
</Button>
<Button variant="outline" className="px-4 py-2 rounded text-sm">
+ New Request
</Button>
</div>
</CardHeader>

<CardContent className="min-h-80 lg:h-full border-t pt-5 transition-all">
{teams.map((team, index) => (
<TeamCard key={index} team={team} />
))}
{filteredTeams.length > 0 ? (
filteredTeams.map((team, index) => (
<TeamCard key={index} team={team} />
))
) : (
<p>No teams found. Try creating one!</p>
)}
</CardContent>
</Card>

<FiltersSidebar className="" />
<FiltersSidebar
filters={filters}
setFilters={setFilters}
onReset={handleResetFilters}
/>
</div>
</div>
);
Expand Down
101 changes: 64 additions & 37 deletions components/FiltersSidebar.jsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,86 @@
import React from "react";
import { Button } from "../@/components/ui/button";

const FiltersSidebar = () => {
const FiltersSidebar = ({ filters, setFilters, onReset }) => {
const handleChange = (e) => {
setFilters((prev) => ({ ...prev, [e.target.name]: e.target.value }));
};

return (
<div class="p-4 rounded-lg col-span-1 lg:col-span-3 h-fit border shadow transition-all">
<div className="p-4 rounded-lg col-span-1 lg:col-span-3 h-fit border shadow transition-all">
<form>
<div class="flex justify-between items-center mb-4">
<div className="flex justify-between items-center w-full">
<div class="text-xl font-semibold">Filters</div>
<Button variant="outline" className="transition-all">
<input type="reset" value="Reset" className="cursor-pointer" />
</Button>
</div>
<div className="flex justify-between items-center mb-4">
<div className="text-xl font-semibold">Filters</div>
<Button
variant="outline"
type="button"
className="transition-all"
onClick={onReset}
>
Reset
</Button>
</div>

{/* Game Filter */}
<div className="mb-4">
<label className="block mb-2">Game</label>
<select className="w-full p-2 rounded-md bg-background border">
<option selected>Select Game</option>
<option className="text-sm">BGMI</option>
<option className="text-sm">Free Fire Max</option>
<option className="text-sm">Valorant</option>
<option className="text-sm">COD Mobile</option>
<option className="text-sm">Pokemon Unite</option>
<option className="text-sm">Clash of Clans</option>
<option className="text-sm">Cricket</option>
<option className="text-sm">NEW STATE Mobile</option>
<option className="text-sm">GTA V</option>
<option className="text-sm">League of Legends PC</option>
<option className="text-sm">FIFA 22</option>
<option className="text-sm">Brawl Stars</option>
<option className="text-sm">Apex Legends Mobile</option>
<option className="text-sm">Clash Royale</option>
<option className="text-sm">Mobile Legends Bang Bang</option>
<select
name="game"
value={filters.game}
onChange={handleChange}
className="w-full p-2 rounded-md bg-background border"
>
<option className="text-black" value="" disabled>
Select Game
</option>
<option className="text-black">BGMI</option>
<option className="text-black">Free Fire Max</option>
<option className="text-black">Valorant</option>
<option className="text-black">COD Mobile</option>
<option className="text-black">Pokemon Unite</option>
<option className="text-black">Clash of Clans</option>
<option className="text-black">Cricket</option>
</select>
</div>

{/* Role Filter */}
<div className="mb-4">
<label className="block mb-2">Role</label>
<select className="w-full p-2 rounded-md bg-background border">
<option>Select role</option>
<option>Select role</option>
<option>Select role</option>
<option>Select role</option>
<option>Select role</option>
<select
name="role"
value={filters.role}
onChange={handleChange}
className="w-full p-2 rounded-md bg-background border"
>
<option value="" disabled>
Select Role
</option>
<option className="text-black">Leader</option>
<option className="text-black">Member</option>
<option className="text-black">Support</option>
</select>
</div>

{/* Language Filter */}
<div className="mb-4">
<label className="block mb-2">Language</label>
<select className="w-full p-2 rounded-md bg-background border">
<option selected>Select Language</option>
<option>English</option>
<option>Hindi</option>
<select
name="language"
value={filters.language}
onChange={handleChange}
className="w-full p-2 rounded-md bg-background border"
>
<option className="text-black" value="" disabled>
Select Language
</option>
<option className="text-black">English</option>
<option className="text-black">Hindi</option>
</select>
</div>

<Button className="w-full mt-5">Apply</Button>
<Button type="button" className="w-full mt-5">
Apply
</Button>
</form>
</div>
);
Expand Down
Loading
Loading