From 4152abe49c49843b42868d81549b34c312c56a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1rio=20Guimar=C3=A3es?= <49988070+Darguima@users.noreply.github.com> Date: Thu, 7 Dec 2023 17:45:26 +0000 Subject: [PATCH] refactor: change from pagination to scroll on badgedex (#578) --- components/Badge/index.tsx | 45 ++++++++++++- components/GoToTop/index.tsx | 35 +++++++++++ layout/Attendee/Badgedex/Badgedex.tsx | 80 ++++++++++++------------ public/images/badges/badge-not-found.svg | 1 + 4 files changed, 117 insertions(+), 44 deletions(-) create mode 100644 components/GoToTop/index.tsx create mode 100644 public/images/badges/badge-not-found.svg diff --git a/components/Badge/index.tsx b/components/Badge/index.tsx index f8ad5730..de649bd9 100644 --- a/components/Badge/index.tsx +++ b/components/Badge/index.tsx @@ -1,14 +1,47 @@ import Link from "next/link"; +import { ReactEventHandler, useState } from "react"; + +interface BadgeProps { + name: string; + id: string | number; + avatar: string; + tokens: string | number; + owned: boolean; +} + +export default function Badge({ name, id, avatar, tokens, owned }: BadgeProps) { + const [badgeLoaded, setBadgeLoaded] = useState(false); + const [fallbackRan, setFallbackRan] = useState(false) + + const imageOnError: ReactEventHandler = (e) => { + // prevent infinite loop fallback + if (fallbackRan) { + setBadgeLoaded(true); + return + } + + setBadgeLoaded(false); + e.currentTarget.src = "/images/badges/badge-not-found.svg"; + setFallbackRan(true) + }; -export default function Badge({ name, id, avatar, tokens, owned }) { return ( -
- {name} +
+ + {!badgeLoaded && } + + {name} setBadgeLoaded(true)} + onError={imageOnError} + />
+
{name}
{tokens} 💰
@@ -16,3 +49,9 @@ export default function Badge({ name, id, avatar, tokens, owned }) { ); } + +const BadgeSkeleton = () => { + return ( +
+ ); +}; diff --git a/components/GoToTop/index.tsx b/components/GoToTop/index.tsx new file mode 100644 index 00000000..d5da7b24 --- /dev/null +++ b/components/GoToTop/index.tsx @@ -0,0 +1,35 @@ +import { faArrowUp } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { useEffect, useState } from "react"; + +export default function GoToTop() { + const [showButton, setShowButton] = useState(false); + + useEffect(() => { + window.addEventListener("scroll", () => { + if (window.scrollY > 400) { + setShowButton(true); + } else { + setShowButton(false); + } + }); + }, []); + + const goToTop = () => { + window.scrollTo({ + top: 0, + behavior: "smooth", + }); + }; + + return ( + + ); +} diff --git a/layout/Attendee/Badgedex/Badgedex.tsx b/layout/Attendee/Badgedex/Badgedex.tsx index 1b658f8b..84c29ef3 100644 --- a/layout/Attendee/Badgedex/Badgedex.tsx +++ b/layout/Attendee/Badgedex/Badgedex.tsx @@ -5,38 +5,35 @@ import { getAllBadges } from "@lib/api"; import Layout from "@components/Layout"; -import Pagination from "./components/Pagination"; import ErrorMessage from "@components/ErrorMessage"; import Badge from "@components/Badge"; import BadgeFilter from "@components/BadgeFilter"; +import GoToTop from "@components/GoToTop"; -interface Badges { - id: string; - type: string; - name: string; +export interface Badges { + avatar: string; + begin: string; description: string; + end: string; + id: number; + name: string; + tokens: number; + type: number; +} + +interface UserWithBadges { + user: { + badges: Badges[]; + }; } function Badgedex() { - const { user } = useAuth(); + const { user }: UserWithBadges = useAuth(); const [allBadges, updateAllBadges] = useState([]); const [all, updateAll] = useState(true); const [filter, updateFilter] = useState(null); const [error, setError] = useState(); - const [currentPage, setCurrentPage] = useState(1); - const [badgesPerPage] = useState(10); - - const indexOfLastVisitor = currentPage * badgesPerPage; - const indexOfFirstVisitor = indexOfLastVisitor - badgesPerPage; - const currentBadges: any = allBadges.slice( - indexOfFirstVisitor, - indexOfLastVisitor - ); - - const paginate = (pageNumber) => setCurrentPage(pageNumber); - if (currentBadges.length === 0 && currentPage !== 1) { - paginate(0); - } + const [currentBadges, setCurrentBadges] = useState(allBadges); useEffect(() => { getAllBadges() @@ -46,6 +43,13 @@ function Badgedex() { }); }, []); + useEffect(() => { + const badges = all ? allBadges : user.badges; + setCurrentBadges( + badges.filter((badge) => badge.type == filter || filter == null) + ); + }, [user, allBadges, filter, all]); + return (
@@ -80,31 +84,25 @@ function Badgedex() {
- {all - ? currentBadges - .filter((badge) => badge.type == filter || filter == null) - .map((badge) => ( - b.id).includes(badge.id)} - {...badge} - /> - )) - : user.badges - .filter((badge) => badge.type == filter || filter == null) - .map((badge) => )} -
- {all && ( -
- ( + b.id).includes(badge.id)} + {...badge} /> + ))} +
+ + {currentBadges.length == 0 && ( +
+

+ No Badges to show! +

)} + {error && } + ); } diff --git a/public/images/badges/badge-not-found.svg b/public/images/badges/badge-not-found.svg new file mode 100644 index 00000000..6c3c3b79 --- /dev/null +++ b/public/images/badges/badge-not-found.svg @@ -0,0 +1 @@ + \ No newline at end of file