-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from cesaregarza/bugfix/weapon-leaderboards
Bugfix/weapon leaderboards
- Loading branch information
Showing
11 changed files
with
282 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
src/react_app/src/components/leaderboards_components/season_selector.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import React, { useState, useEffect, useRef } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import { calculateSeasonNow, getSeasonName } from "../utils/season_utils"; | ||
import { FaTimes } from "react-icons/fa"; | ||
|
||
const SeasonSelector = ({ selectedSeason, setSelectedSeason }) => { | ||
const { t } = useTranslation("weapon_leaderboard"); | ||
const { t: gameT } = useTranslation("game"); | ||
const [isOpen, setIsOpen] = useState(false); | ||
const dropdownRef = useRef(null); | ||
|
||
const currentSeason = calculateSeasonNow(); | ||
const seasons = Array.from({ length: currentSeason }, (_, i) => i + 1).sort( | ||
(a, b) => a - b | ||
); | ||
|
||
const handleSeasonSelect = (season) => { | ||
setSelectedSeason(season); | ||
setIsOpen(false); | ||
}; | ||
|
||
const handleClearSeason = (e) => { | ||
e.stopPropagation(); | ||
setSelectedSeason(null); | ||
}; | ||
|
||
useEffect(() => { | ||
const handleClickOutside = (event) => { | ||
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { | ||
setIsOpen(false); | ||
} | ||
}; | ||
|
||
document.addEventListener("mousedown", handleClickOutside); | ||
return () => { | ||
document.removeEventListener("mousedown", handleClickOutside); | ||
}; | ||
}, []); | ||
|
||
const toggleDropdown = () => { | ||
setIsOpen(!isOpen); | ||
}; | ||
|
||
return ( | ||
<div className="relative inline-block w-64" ref={dropdownRef}> | ||
<div | ||
className="flex items-center justify-between w-full bg-gray-800 border border-gray-700 text-white py-2 px-3 rounded leading-tight cursor-pointer" | ||
onClick={toggleDropdown} | ||
> | ||
{selectedSeason !== null ? ( | ||
<div className="flex items-center flex-grow"> | ||
<span>{`${selectedSeason} ${getSeasonName( | ||
selectedSeason, | ||
gameT | ||
)}`}</span> | ||
<button | ||
onClick={handleClearSeason} | ||
className="ml-auto p-1 hover:bg-gray-700 rounded" | ||
aria-label="Clear season selection" | ||
> | ||
<FaTimes size={14} /> | ||
</button> | ||
</div> | ||
) : ( | ||
<span>{t("all_seasons")}</span> | ||
)} | ||
<svg | ||
className={`fill-current h-4 w-4 ml-2 ${ | ||
isOpen ? "transform rotate-180" : "" | ||
}`} | ||
xmlns="http://www.w3.org/2000/svg" | ||
viewBox="0 0 20 20" | ||
> | ||
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" /> | ||
</svg> | ||
</div> | ||
{isOpen && ( | ||
<div className="absolute z-10 w-full mt-1 bg-gray-800 border border-gray-700 rounded shadow-lg max-h-60 overflow-y-auto"> | ||
{seasons.map((season) => ( | ||
<div | ||
key={season} | ||
className="flex items-center px-3 py-2 cursor-pointer hover:bg-gray-700" | ||
onClick={() => handleSeasonSelect(season)} | ||
> | ||
<span>{`${season} ${getSeasonName(season, gameT)}`}</span> | ||
</div> | ||
))} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default SeasonSelector; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
src/react_app/src/components/player_components/season_results.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
src/react_app/src/components/player_components/season_selector.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
const getSeasonStartDate = (season) => { | ||
const yearOffset = Math.floor((season - 1) / 4); | ||
const monthIndex = (season - 1) % 4; | ||
const monthMap = [11, 2, 5, 8]; // December, March, June, September | ||
const year = monthIndex === 0 ? 2023 + yearOffset - 1 : 2023 + yearOffset; | ||
return new Date(Date.UTC(year, monthMap[monthIndex], 1)); | ||
}; | ||
|
||
const getSeasonEndDate = (season) => { | ||
const nextSeasonStart = getSeasonStartDate(season + 1); | ||
return new Date( | ||
Date.UTC( | ||
nextSeasonStart.getUTCFullYear(), | ||
nextSeasonStart.getUTCMonth(), | ||
nextSeasonStart.getUTCDate(), | ||
0, | ||
0, | ||
0, | ||
nextSeasonStart.getUTCMilliseconds() - 1000 | ||
) | ||
); | ||
}; | ||
|
||
const getPercentageInSeason = (timestamp, season) => { | ||
const seasonStart = getSeasonStartDate(season); | ||
const seasonEnd = getSeasonEndDate(season); | ||
const totalDuration = seasonEnd - seasonStart; | ||
const elapsedDuration = new Date(timestamp) - seasonStart; | ||
return (elapsedDuration / totalDuration) * 100; | ||
}; | ||
|
||
const calculateSeasonNow = () => { | ||
const now_utc = new Date(); | ||
return calculateSeasonByTimestamp(now_utc); | ||
}; | ||
|
||
const calculateSeasonByTimestamp = (timestamp) => { | ||
const timestamp_utc = new Date(timestamp); | ||
const timestamp_utc_month = (timestamp_utc.getUTCMonth() + 1) % 12; | ||
const timestamp_utc_year = | ||
timestamp_utc.getUTCFullYear() + (timestamp_utc_month === 0 ? 1 : 0); | ||
return ( | ||
4 * (timestamp_utc_year - 2022) + Math.floor(timestamp_utc_month / 3) - 3 | ||
); | ||
}; | ||
|
||
const getSeasonName = (season_number, t) => { | ||
const season_offset = season_number + 2; | ||
const season_index = season_offset % 4; | ||
const year = 2022 + Math.floor(season_offset / 4); | ||
const season_names = [t("spring"), t("summer"), t("autumn"), t("winter")]; | ||
return t("format_short") | ||
.replace("%SEASON%", season_names[season_index]) | ||
.replace("%YEAR%", year); | ||
}; | ||
|
||
export { | ||
getSeasonStartDate, | ||
getSeasonEndDate, | ||
getPercentageInSeason, | ||
calculateSeasonNow, | ||
calculateSeasonByTimestamp, | ||
getSeasonName, | ||
}; |
Oops, something went wrong.