Skip to content

Commit

Permalink
Refactor: extract common code into score-board component
Browse files Browse the repository at this point in the history
  • Loading branch information
ThulinaWickramasinghe committed Aug 19, 2024
1 parent 18826db commit e15278a
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 190 deletions.
4 changes: 2 additions & 2 deletions lefthook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ pre-commit:
commands:
format:
glob: "*.{js,ts,jsx}"
run: npm run format {staged_files}
run: npm run format {staged_files} && git add {staged_files}
lint:
glob: "*.{js,ts,jsx}"
run: npm run lint {staged_files}
run: npm run lint {staged_files} && git add {staged_files}

commit-msg:
commands:
Expand Down
101 changes: 101 additions & 0 deletions src/components/home/score-board/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { useEffect, useState } from "react";
import { twMerge } from "tailwind-merge";
import { ScoreCardSkeleton } from "@/components";
import { ScoreCard } from "@/components/home";
import { filters as filterData, sorts as sortData } from "@/filters";
import { useTitle } from "@/hooks";
import {
AnimatedSwitcher,
Filters,
NoRecords,
Pagination,
Sorts,
TwinSwitch
} from "@sliit-foss/bashaway-ui/components";
import { useGhostLegion, useRound } from "@sliit-foss/bashaway-ui/hooks";
import { Ghost } from "@sliit-foss/bashaway-ui/icons";
import { Footnote, Title } from "@sliit-foss/bashaway-ui/typography";
import { computeFilterQuery, computeSortQuery } from "@sliit-foss/bashaway-ui/utils";

const ScoreBoard = ({ pageTitle, title, subTitle, useFetchData }) => {
const [page, setPage] = useState(1);
const [filters, setFilters] = useState(computeFilterQuery(filterData));
const [sorts, setSorts] = useState(computeSortQuery(sortData));

const { rounds, round, roundKey, onRoundChange } = useRound();
const { ghostLegion, toggleGhostLegion } = useGhostLegion();
const { data: scores, isFetching } = useFetchData({ page, filters, sorts, round, ghostLegion });

useEffect(() => {
if (page !== 1) setPage(1);
}, [filters, sorts, round, ghostLegion]);

useTitle(pageTitle);

return (
<>
<div className="w-full flex flex-col justify-center items-center gap-6 mb-8 max-w-4xl">
<div className="flex flex-col items-center gap-2 md:gap-1 mb-2">
<Title className="tracking-normal pointer-events-none">{title}</Title>
<Footnote className="text-black/40 max-w-[500px] text-xl lg:text-center leading-6 pointer-events-none">
{subTitle}
</Footnote>
<TwinSwitch values={rounds} className="mt-5" onChange={onRoundChange} selectedValue={roundKey} />
</div>
<div className="w-full flex flex-col md:flex-row justify-between items-center gap-6 mb-8">
<Filters filters={filterData} setFilterQuery={setFilters} styles={{ root: "w-auto", filter: "md:w-full" }} />
<div className="flex flex-wrap justify-center items-center gap-y-3 gap-x-8" onClick={toggleGhostLegion}>
<div
className={twMerge(
"group flex justify-center items-center gap-3.5 transform translate-y-[1.5px] cursor-pointer transition-all duration-medium",
round == 2 ? "opacity-100 h-10 md:h-auto" : "opacity-0 h-0 md:h-auto"
)}
>
<span className="text-md text-black/70 group-hover:text-black/90 font-semibold transition-all duration-medium">
Ghost Legion
</span>
<Ghost
className={twMerge(
"w-[1.4rem] h-[1.4rem] fill-current transition-all duration-medium",
ghostLegion ? "text-[#f00]" : "text-black/60 group-hover:text-[#f00]"
)}
/>
</div>
<Sorts
styles={{ root: "w-auto justify-end gap-8", sort: "justify-center md:justify-start w-full md:w-full" }}
sorts={sortData}
setSortQuery={setSorts}
/>
</div>
</div>
<AnimatedSwitcher
show={isFetching}
className={`w-full flex flex-col gap-5 min-h-[150px] xl:min-h-[250px] 2xl:min-h-[350px]`}
component={<ScoreCardSkeleton />}
alternateComponent={
scores?.data?.docs?.length ? (
<>
{scores.data.docs.map((item, index) => (
<ScoreCard item={item} round={round} key={`score-card-${index}`} />
))}
</>
) : (
<div className="h-full flex flex-1 items-center">
<NoRecords text="No leaders at the moment" />
</div>
)
}
/>
<div className="w-full flex justify-center items-center mt-6 mb-2">
<Pagination
currentPage={page}
onPageChange={(newPage) => setPage(newPage)}
totalPages={scores?.data?.totalPages}
/>
</div>
</div>
</>
);
};

export default ScoreBoard;
101 changes: 7 additions & 94 deletions src/pages/hall-of-fame.jsx
Original file line number Diff line number Diff line change
@@ -1,101 +1,14 @@
import { useEffect, useState } from "react";
import { twMerge } from "tailwind-merge";
import { ScoreCardSkeleton } from "@/components";
import { ScoreCard } from "@/components/home";
import { filters as filterData, sorts as sortData } from "@/filters";
import { useTitle } from "@/hooks";
import ScoreBoard from "@/components/home/score-board";
import { useFetchPastLeaderboardsQuery } from "@/store/api";
import {
AnimatedSwitcher,
Filters,
NoRecords,
Pagination,
Sorts,
TwinSwitch
} from "@sliit-foss/bashaway-ui/components";
import { useGhostLegion, useRound } from "@sliit-foss/bashaway-ui/hooks";
import { Ghost } from "@sliit-foss/bashaway-ui/icons";
import { Footnote, Title } from "@sliit-foss/bashaway-ui/typography";
import { computeFilterQuery, computeSortQuery } from "@sliit-foss/bashaway-ui/utils";

const HallOfFame = () => {
const [page, setPage] = useState(1);
const [filters, setFilters] = useState(computeFilterQuery(filterData));
const [sorts, setSorts] = useState(computeSortQuery(sortData));

const { rounds, round, roundKey, onRoundChange } = useRound();
const { ghostLegion, toggleGhostLegion } = useGhostLegion();
const { data: scores, isFetching } = useFetchPastLeaderboardsQuery({ page, filters, sorts, round, ghostLegion });

useEffect(() => {
if (page !== 1) setPage(1);
}, [filters, sorts, round, ghostLegion]);

useTitle("Hall of Fame | Bashaway");

return (
<>
<div className="w-full flex flex-col justify-center items-center gap-6 mb-8 max-w-4xl">
<div className="flex flex-col items-center gap-2 md:gap-1 mb-2">
<Title className="tracking-normal pointer-events-none">Hall of Fame 2023</Title>
<Footnote className="text-black/40 max-w-[500px] text-xl lg:text-center leading-6 pointer-events-none">
A tribute to legendary warriors who once marched amongst us with unwavering valour
</Footnote>
<TwinSwitch values={rounds} className="mt-5" onChange={onRoundChange} selectedValue={roundKey} />
</div>
<div className="w-full flex flex-col md:flex-row justify-between items-center gap-6 mb-8">
<Filters filters={filterData} setFilterQuery={setFilters} styles={{ root: "w-auto", filter: "md:w-full" }} />
<div className="flex flex-wrap justify-center items-center gap-y-3 gap-x-8" onClick={toggleGhostLegion}>
<div
className={twMerge(
"group flex justify-center items-center gap-3.5 transform translate-y-[1.5px] cursor-pointer transition-all duration-medium",
round == 2 ? "opacity-100 h-10 md:h-auto" : "opacity-0 h-0 md:h-auto"
)}
>
<span className="text-md text-black/70 group-hover:text-black/90 font-semibold transition-all duration-medium">
Ghost Legion
</span>
<Ghost
className={twMerge(
"w-[1.4rem] h-[1.4rem] fill-current transition-all duration-medium",
ghostLegion ? "text-[#f00]" : "text-black/60 group-hover:text-[#f00]"
)}
/>
</div>
<Sorts
styles={{ root: "w-auto justify-end gap-8", sort: "justify-center md:justify-start w-full md:w-full" }}
sorts={sortData}
setSortQuery={setSorts}
/>
</div>
</div>
<AnimatedSwitcher
show={isFetching}
className={`w-full flex flex-col gap-5 min-h-[150px] xl:min-h-[250px] 2xl:min-h-[350px]`}
component={<ScoreCardSkeleton />}
alternateComponent={
scores?.data?.docs?.length ? (
<>
{scores.data.docs.map((item, index) => (
<ScoreCard item={item} round={round} key={`score-card-${index}`} />
))}
</>
) : (
<div className="h-full flex flex-1 items-center">
<NoRecords text="No leaders at the moment" />
</div>
)
}
/>
<div className="w-full flex justify-center items-center mt-6 mb-2">
<Pagination
currentPage={page}
onPageChange={(newPage) => setPage(newPage)}
totalPages={scores?.data?.totalPages}
/>
</div>
</div>
</>
<ScoreBoard
pageTitle={"Hall of Fame | Bashaway"}
title={"Hall of Fame 2023"}
subTitle={" A tribute to legendary warriors who once marched amongst us with unwavering valour"}
useFetchData={useFetchPastLeaderboardsQuery}
/>
);
};

Expand Down
101 changes: 7 additions & 94 deletions src/pages/home.jsx
Original file line number Diff line number Diff line change
@@ -1,101 +1,14 @@
import { useEffect, useState } from "react";
import { twMerge } from "tailwind-merge";
import { ScoreCardSkeleton } from "@/components";
import { ScoreCard } from "@/components/home";
import { filters as filterData, sorts as sortData } from "@/filters";
import { useTitle } from "@/hooks";
import ScoreBoard from "@/components/home/score-board";
import { useFetchLeaderboardQuery } from "@/store/api";
import {
AnimatedSwitcher,
Filters,
NoRecords,
Pagination,
Sorts,
TwinSwitch
} from "@sliit-foss/bashaway-ui/components";
import { useGhostLegion, useRound } from "@sliit-foss/bashaway-ui/hooks";
import { Ghost } from "@sliit-foss/bashaway-ui/icons";
import { Footnote, Title } from "@sliit-foss/bashaway-ui/typography";
import { computeFilterQuery, computeSortQuery } from "@sliit-foss/bashaway-ui/utils";

const Home = () => {
const [page, setPage] = useState(1);
const [filters, setFilters] = useState(computeFilterQuery(filterData));
const [sorts, setSorts] = useState(computeSortQuery(sortData));

const { rounds, round, roundKey, onRoundChange } = useRound();
const { ghostLegion, toggleGhostLegion } = useGhostLegion();
const { data: scores, isFetching } = useFetchLeaderboardQuery({ page, filters, sorts, round, ghostLegion });

useEffect(() => {
if (page !== 1) setPage(1);
}, [filters, sorts, round, ghostLegion]);

useTitle("Leaderboard | Bashaway");

return (
<>
<div className="w-full flex flex-col justify-center items-center gap-6 mb-8 max-w-4xl">
<div className="flex flex-col items-center gap-2 md:gap-1 mb-2">
<Title className="tracking-normal pointer-events-none">The Leaderboard</Title>
<Footnote className="text-black/40 max-w-[500px] text-xl lg:text-center leading-6 pointer-events-none">
A place where your true colors show off despite all the differences
</Footnote>
<TwinSwitch values={rounds} className="mt-5" onChange={onRoundChange} selectedValue={roundKey} />
</div>
<div className="w-full flex flex-col md:flex-row justify-between items-center gap-6 mb-8">
<Filters filters={filterData} setFilterQuery={setFilters} styles={{ root: "w-auto", filter: "md:w-full" }} />
<div className="flex flex-wrap justify-center items-center gap-y-3 gap-x-8" onClick={toggleGhostLegion}>
<div
className={twMerge(
"group flex justify-center items-center gap-3.5 transform translate-y-[1.5px] cursor-pointer transition-all duration-medium",
round == 2 ? "opacity-100 h-10 md:h-auto" : "opacity-0 h-0 md:h-auto"
)}
>
<span className="text-md text-black/70 group-hover:text-black/90 font-semibold transition-all duration-medium">
Ghost Legion
</span>
<Ghost
className={twMerge(
"w-[1.4rem] h-[1.4rem] fill-current transition-all duration-medium",
ghostLegion ? "text-[#f00]" : "text-black/60 group-hover:text-[#f00]"
)}
/>
</div>
<Sorts
styles={{ root: "w-auto justify-end gap-8", sort: "justify-center md:justify-start w-full md:w-full" }}
sorts={sortData}
setSortQuery={setSorts}
/>
</div>
</div>
<AnimatedSwitcher
show={isFetching}
className={`w-full flex flex-col gap-5 min-h-[150px] xl:min-h-[250px] 2xl:min-h-[350px]`}
component={<ScoreCardSkeleton />}
alternateComponent={
scores?.data?.docs?.length ? (
<>
{scores.data.docs.map((item, index) => (
<ScoreCard item={item} round={round} key={`score-card-${index}`} />
))}
</>
) : (
<div className="h-full flex flex-1 items-center">
<NoRecords text="No leaders at the moment" />
</div>
)
}
/>
<div className="w-full flex justify-center items-center mt-6 mb-2">
<Pagination
currentPage={page}
onPageChange={(newPage) => setPage(newPage)}
totalPages={scores?.data?.totalPages}
/>
</div>
</div>
</>
<ScoreBoard
pageTitle={"Leaderboard | Bashaway"}
title={"The Leaderboard"}
subTitle={"A place where your true colors show off despite all the differences"}
useFetchData={useFetchLeaderboardQuery}
/>
);
};

Expand Down

0 comments on commit e15278a

Please sign in to comment.