Skip to content

Commit

Permalink
Merge pull request #132 from SanyamMadaan/team-backend
Browse files Browse the repository at this point in the history
Improved team backend and filter logic
  • Loading branch information
dinxsh authored Dec 16, 2024
2 parents 8e527c7 + db036d6 commit b966b55
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 108 deletions.
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

0 comments on commit b966b55

Please sign in to comment.