diff --git a/app/src/@shared/components/Pagination/index.tsx b/app/src/@shared/components/Pagination/index.tsx
index 739d072f..29c9bfaf 100644
--- a/app/src/@shared/components/Pagination/index.tsx
+++ b/app/src/@shared/components/Pagination/index.tsx
@@ -7,7 +7,7 @@ import { ARIA_LABEL } from '@shared/constants/accessibility';
import { Clickable, HStack } from '@shared/ui-kit';
import { PageButton } from './PageButton';
-type PaginationProps = {
+export type PaginationProps = {
currPageNumber: number;
onPageNumberChange: (pageNumber: number) => void;
totalPageNumber: number;
diff --git a/app/src/Leaderboard/components/Leaderboard/LeaderboardHeader.tsx b/app/src/Leaderboard/components/Leaderboard/LeaderboardHeader.tsx
deleted file mode 100644
index 8a6902b2..00000000
--- a/app/src/Leaderboard/components/Leaderboard/LeaderboardHeader.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import styled from '@emotion/styled';
-import { useAtomValue } from 'jotai';
-
-import { leaderboardPromoListAtom } from '@/Leaderboard/atoms/leaderboardPromoListAtom';
-import { LeaderboardDateDescriptor } from '@/Leaderboard/components/Leaderboard/LeaderboardDateDescriptor';
-import { PromoSelectList } from '@/Leaderboard/components/PromoSelect/PromoSelectList';
-import { Select, SelectContent, SelectTrigger } from '@shared/ui-kit';
-import { mq } from '@shared/utils/facepaint/mq';
-import { numberWithUnitFormatter } from '@shared/utils/formatters/numberWithUnitFormatter';
-
-type LeaderboardHeaderProps = {
- currSegmentedControlIndex?: number;
- currPromo: number | null;
- onPromoChange: (promo: string | null) => void;
- start: Date;
- end: Date;
-};
-
-export function LeaderboardHeader({
- currSegmentedControlIndex,
- currPromo,
- onPromoChange,
- start,
- end,
-}: LeaderboardHeaderProps) {
- const promoList = useAtomValue(leaderboardPromoListAtom);
-
- if (promoList === null) {
- throw new Error('promoList is null');
- }
-
- const unit = '기';
-
- return (
-
-
-
-
- );
-}
-
-const Layout = styled.div`
- width: 100%;
- display: flex;
- align-items: center;
-
- ${mq({
- flexDirection: ['column', 'row'],
- justifyContent: ['center', 'space-between'],
- gap: ['2rem', 0],
- })}
-`;
diff --git a/app/src/Leaderboard/components/LeaderboardPagination.tsx b/app/src/Leaderboard/components/LeaderboardPagination.tsx
new file mode 100644
index 00000000..b8c83fa3
--- /dev/null
+++ b/app/src/Leaderboard/components/LeaderboardPagination.tsx
@@ -0,0 +1,14 @@
+import {
+ Pagination,
+ type PaginationProps,
+} from '@shared/components/Pagination';
+import { useDeviceType } from '@shared/utils/react-responsive/useDeviceType';
+
+type LeaderboardPaginationProps = Omit;
+
+export function LeaderboardPagination(props: LeaderboardPaginationProps) {
+ const device = useDeviceType();
+ const pagePerRow = device === 'mobile' ? 5 : 10;
+
+ return ;
+}
diff --git a/app/src/Leaderboard/components/PromoSelect/index.tsx b/app/src/Leaderboard/components/PromoSelect/index.tsx
new file mode 100644
index 00000000..7a4ba413
--- /dev/null
+++ b/app/src/Leaderboard/components/PromoSelect/index.tsx
@@ -0,0 +1,31 @@
+import { Promo } from '@shared/__generated__/graphql';
+import { Select, SelectContent, SelectTrigger } from '@shared/ui-kit';
+import { numberWithUnitFormatter } from '@shared/utils/formatters/numberWithUnitFormatter';
+
+import { PromoSelectList } from './PromoSelectList';
+
+type PromoSelectProps = {
+ curr: number | null;
+ list: Promo[];
+ onChange: (promo: string | null) => void;
+};
+
+export function PromoSelect({ curr, list, onChange }: PromoSelectProps) {
+ const unit = '기';
+
+ return (
+
+ );
+}
diff --git a/app/src/Leaderboard/components/skeletons/LeaderboardResultSkeleton.tsx b/app/src/Leaderboard/components/skeletons/LeaderboardResultSkeleton.tsx
index de9a8b71..0830cd6f 100644
--- a/app/src/Leaderboard/components/skeletons/LeaderboardResultSkeleton.tsx
+++ b/app/src/Leaderboard/components/skeletons/LeaderboardResultSkeleton.tsx
@@ -3,7 +3,7 @@ import { LeaderboardListItemSkeleteon } from './LeaderboardListItemSkeleton';
export const LeaderboardResultSkeleton = () => {
return (
-
+
{Array.from({ length: 50 }, (x) => x).map((_, idx) => (
diff --git a/app/src/Leaderboard/pages/Comment/components/LeaderboardCommentResult.tsx b/app/src/Leaderboard/pages/Comment/components/LeaderboardCommentResult.tsx
new file mode 100644
index 00000000..b40f9be8
--- /dev/null
+++ b/app/src/Leaderboard/pages/Comment/components/LeaderboardCommentResult.tsx
@@ -0,0 +1,96 @@
+import { QueryResult } from '@apollo/client';
+import { useAtomValue } from 'jotai';
+import { useSearchParams } from 'react-router-dom';
+
+import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
+import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
+import { LeaderboardDateDescriptor } from '@/Leaderboard/components/Leaderboard/LeaderboardDateDescriptor';
+import { LeaderboardPagination } from '@/Leaderboard/components/LeaderboardPagination';
+import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
+import { SIZE_PER_PAGE } from '@/Leaderboard/constants/defaultOptions';
+import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
+import {
+ DateTemplate,
+ GetLeaderboardCommentQuery,
+} from '@shared/__generated__/graphql';
+import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
+import { HStack, Spacer, VStack } from '@shared/ui-kit';
+
+type LeaderboardCommentResultProps = {
+ result: QueryResult<
+ GetLeaderboardCommentQuery,
+ {
+ dateTemplate: DateTemplate;
+ pageNumber: number;
+ promo: number | null;
+ pageSize: number;
+ }
+ >;
+};
+
+export function LeaderboardCommentResult({
+ result: { loading, error, data },
+}: LeaderboardCommentResultProps) {
+ const [_, setSearchParams] = useSearchParams();
+ const params = new URLSearchParams();
+
+ const { PROMO, PAGE } = LEADERBOARD_PARAM_KEYS;
+
+ const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
+
+ if (leaderboardArgs === null) {
+ throw new Error('leaderboardArgs is null');
+ }
+
+ const { promo, pageNumber } = leaderboardArgs;
+
+ function handlePageNumberChange(pageNumber: number) {
+ if (promo) {
+ params.set(PROMO, promo.toString());
+ }
+ params.set(PAGE, pageNumber.toString());
+
+ setSearchParams(params);
+ }
+
+ if (loading) {
+ return ;
+ }
+ if (error) {
+ return ;
+ }
+ if (!data) {
+ return ;
+ }
+
+ const {
+ data: {
+ me,
+ totalRanking: { nodes, totalCount },
+ },
+ start,
+ end,
+ } = data.getLeaderboardComment.byDateTemplate;
+
+ const unit = '자';
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/src/Leaderboard/pages/Comment/index.tsx b/app/src/Leaderboard/pages/Comment/index.tsx
index 6152ba31..2f22d6e0 100644
--- a/app/src/Leaderboard/pages/Comment/index.tsx
+++ b/app/src/Leaderboard/pages/Comment/index.tsx
@@ -3,28 +3,21 @@ import { useAtomValue } from 'jotai';
import { useSearchParams } from 'react-router-dom';
import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
-import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
-import { LeaderboardHeader } from '@/Leaderboard/components/Leaderboard/LeaderboardHeader';
-import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
-import {
- LEADERBOARD_DEFAULT_OPTIONS,
- SIZE_PER_PAGE,
-} from '@/Leaderboard/constants/defaultOptions';
+import { leaderboardPromoListAtom } from '@/Leaderboard/atoms/leaderboardPromoListAtom';
+import { PromoSelect } from '@/Leaderboard/components/PromoSelect';
+import { LEADERBOARD_DEFAULT_OPTIONS } from '@/Leaderboard/constants/defaultOptions';
import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
import { Footer } from '@core/components/Footer';
import { DateTemplate } from '@shared/__generated__/graphql';
-import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
-import { Pagination } from '@shared/components/Pagination';
import { Seo } from '@shared/components/Seo';
-import { DeferredComponent, VStack } from '@shared/ui-kit';
-import { useDeviceType } from '@shared/utils/react-responsive/useDeviceType';
+import { HStack, VStack } from '@shared/ui-kit';
+import { LeaderboardCommentResult } from './components/LeaderboardCommentResult';
import { GET_LEADERBOARD_COMMENT } from './queries/getLeaderboardComment';
export default function LeaderboardCommentPage() {
- const device = useDeviceType();
const [_, setSearchParams] = useSearchParams();
- const { PAGE, PROMO } = LEADERBOARD_PARAM_KEYS;
+ const { PROMO } = LEADERBOARD_PARAM_KEYS;
const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
@@ -32,7 +25,13 @@ export default function LeaderboardCommentPage() {
throw new Error('leaderboardArgs is null');
}
- const { loading, error, data } = useQuery(GET_LEADERBOARD_COMMENT, {
+ const promoList = useAtomValue(leaderboardPromoListAtom);
+
+ if (promoList === null) {
+ throw new Error('promoList is null');
+ }
+
+ const result = useQuery(GET_LEADERBOARD_COMMENT, {
variables: {
...LEADERBOARD_DEFAULT_OPTIONS,
...leaderboardArgs,
@@ -40,7 +39,7 @@ export default function LeaderboardCommentPage() {
},
});
- const { promo, pageNumber } = leaderboardArgs;
+ const { promo } = leaderboardArgs;
function handlePromoChange(promo: string | null) {
const params = new URLSearchParams();
@@ -52,69 +51,18 @@ export default function LeaderboardCommentPage() {
setSearchParams(params);
}
- function handlePageNumberChange(pageNumber: number) {
- const params = new URLSearchParams();
-
- if (promo) {
- params.set(PROMO, promo.toString());
- }
- params.set(PAGE, pageNumber.toString());
-
- setSearchParams(params);
- }
-
- if (loading) {
- return (
-
-
-
- );
- }
- if (error) {
- return (
-
-
-
- );
- }
- if (!data) {
- return (
-
-
-
- );
- }
-
- const {
- data: {
- me,
- totalRanking: { nodes, totalCount },
- },
- start,
- end,
- } = data.getLeaderboardComment.byDateTemplate;
-
- const unit = '자';
-
return (
<>
-
-
-
+
+
-
-
-
+
+
>
diff --git a/app/src/Leaderboard/pages/EvalCount/components/LeaderboardEvalCountResult.tsx b/app/src/Leaderboard/pages/EvalCount/components/LeaderboardEvalCountResult.tsx
new file mode 100644
index 00000000..f3e73300
--- /dev/null
+++ b/app/src/Leaderboard/pages/EvalCount/components/LeaderboardEvalCountResult.tsx
@@ -0,0 +1,99 @@
+import { QueryResult } from '@apollo/client';
+import { useAtomValue } from 'jotai';
+import { useSearchParams } from 'react-router-dom';
+
+import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
+import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
+import { LeaderboardDateDescriptor } from '@/Leaderboard/components/Leaderboard/LeaderboardDateDescriptor';
+import { LeaderboardPagination } from '@/Leaderboard/components/LeaderboardPagination';
+import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
+import { SIZE_PER_PAGE } from '@/Leaderboard/constants/defaultOptions';
+import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
+import {
+ DateTemplate,
+ Exact,
+ GetLeaderboardEvalCountQuery,
+ InputMaybe,
+} from '@shared/__generated__/graphql';
+import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
+import { HStack, Spacer, VStack } from '@shared/ui-kit';
+
+type LeaderboardEvalCountResultProps = {
+ result: QueryResult<
+ GetLeaderboardEvalCountQuery,
+ Exact<{
+ pageSize: number;
+ pageNumber: number;
+ dateTemplate: DateTemplate;
+ promo?: InputMaybe | undefined;
+ }>
+ >;
+};
+
+export function LeaderboardEvalCountResult({
+ result: { loading, error, data },
+}: LeaderboardEvalCountResultProps) {
+ const [_, setSearchParams] = useSearchParams();
+ const params = new URLSearchParams();
+
+ const { PROMO, PAGE, DATE } = LEADERBOARD_PARAM_KEYS;
+
+ const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
+
+ if (leaderboardArgs === null) {
+ throw new Error('leaderboardArgs is null');
+ }
+
+ const { promo, dateTemplate, pageNumber } = leaderboardArgs;
+
+ function handlePageNumberChange(pageNumber: number) {
+ params.set(DATE, dateTemplate);
+ if (promo) {
+ params.set(PROMO, promo.toString());
+ }
+ params.set(PAGE, pageNumber.toString());
+
+ setSearchParams(params);
+ }
+
+ if (loading) {
+ return ;
+ }
+ if (error) {
+ return ;
+ }
+ if (!data) {
+ return ;
+ }
+
+ const {
+ data: {
+ me,
+ totalRanking: { nodes, totalCount },
+ },
+ start,
+ end,
+ } = data.getLeaderboardEvalCount.byDateTemplate;
+
+ const unit = '회';
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/src/Leaderboard/pages/EvalCount/index.tsx b/app/src/Leaderboard/pages/EvalCount/index.tsx
index 0068e826..3bab184c 100644
--- a/app/src/Leaderboard/pages/EvalCount/index.tsx
+++ b/app/src/Leaderboard/pages/EvalCount/index.tsx
@@ -3,28 +3,21 @@ import { useAtomValue } from 'jotai';
import { useSearchParams } from 'react-router-dom';
import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
-import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
-import { LeaderboardHeader } from '@/Leaderboard/components/Leaderboard/LeaderboardHeader';
-import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
-import {
- LEADERBOARD_DEFAULT_OPTIONS,
- SIZE_PER_PAGE,
-} from '@/Leaderboard/constants/defaultOptions';
+import { leaderboardPromoListAtom } from '@/Leaderboard/atoms/leaderboardPromoListAtom';
+import { PromoSelect } from '@/Leaderboard/components/PromoSelect';
+import { LEADERBOARD_DEFAULT_OPTIONS } from '@/Leaderboard/constants/defaultOptions';
import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
import { Footer } from '@core/components/Footer';
-import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
-import { Pagination } from '@shared/components/Pagination';
import { Seo } from '@shared/components/Seo';
-import { DeferredComponent, SegmentedControl, VStack } from '@shared/ui-kit';
-import { useDeviceType } from '@shared/utils/react-responsive/useDeviceType';
+import { HStack, SegmentedControl, VStack } from '@shared/ui-kit';
+import { LeaderboardEvalCountResult } from './components/LeaderboardEvalCountResult';
import { useLeaderboardEvalCountSegmentedControl } from './hooks/useLeaderboardEvalCountSegmentedControl';
import { GET_LEADERBOARD_EVAL_COUNT } from './queries/getLeaderboardEvalCount';
export default function LeaderboardEvalCountPage() {
- const device = useDeviceType();
const [_, setSearchParams] = useSearchParams();
- const { DATE, PAGE, PROMO } = LEADERBOARD_PARAM_KEYS;
+ const { DATE, PROMO } = LEADERBOARD_PARAM_KEYS;
const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
@@ -32,14 +25,20 @@ export default function LeaderboardEvalCountPage() {
throw new Error('leaderboardArgs is null');
}
- const { loading, error, data } = useQuery(GET_LEADERBOARD_EVAL_COUNT, {
+ const promoList = useAtomValue(leaderboardPromoListAtom);
+
+ if (promoList === null) {
+ throw new Error('promoList is null');
+ }
+
+ const result = useQuery(GET_LEADERBOARD_EVAL_COUNT, {
variables: {
...LEADERBOARD_DEFAULT_OPTIONS,
...leaderboardArgs,
},
});
- const { promo, pageNumber, dateTemplate } = leaderboardArgs;
+ const { promo, dateTemplate } = leaderboardArgs;
const { options, controlRef, segments } =
useLeaderboardEvalCountSegmentedControl();
@@ -66,77 +65,26 @@ export default function LeaderboardEvalCountPage() {
setSearchParams(params);
}
- function handlePageNumberChange(pageNumber: number) {
- const params = new URLSearchParams();
-
- params.set(DATE, dateTemplate);
- if (promo) {
- params.set(PROMO, promo.toString());
- }
- params.set(PAGE, pageNumber.toString());
-
- setSearchParams(params);
- }
-
- if (loading) {
- return (
-
-
-
- );
- }
- if (error) {
- return (
-
-
-
- );
- }
- if (!data) {
- return (
-
-
-
- );
- }
-
- const {
- data: {
- me,
- totalRanking: { nodes, totalCount },
- },
- start,
- end,
- } = data.getLeaderboardEvalCount.byDateTemplate;
-
- const unit = '회';
-
return (
<>
-
-
-
-
-
-
+
+
+
+
+
+
>
diff --git a/app/src/Leaderboard/pages/ExpIncrement/components/LeaderboardExpIncrementResult.tsx b/app/src/Leaderboard/pages/ExpIncrement/components/LeaderboardExpIncrementResult.tsx
new file mode 100644
index 00000000..22f7089f
--- /dev/null
+++ b/app/src/Leaderboard/pages/ExpIncrement/components/LeaderboardExpIncrementResult.tsx
@@ -0,0 +1,99 @@
+import { QueryResult } from '@apollo/client';
+import { useAtomValue } from 'jotai';
+import { useSearchParams } from 'react-router-dom';
+
+import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
+import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
+import { LeaderboardDateDescriptor } from '@/Leaderboard/components/Leaderboard/LeaderboardDateDescriptor';
+import { LeaderboardPagination } from '@/Leaderboard/components/LeaderboardPagination';
+import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
+import { SIZE_PER_PAGE } from '@/Leaderboard/constants/defaultOptions';
+import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
+import {
+ DateTemplate,
+ Exact,
+ GetLeaderboardExpIncrementQuery,
+ InputMaybe,
+} from '@shared/__generated__/graphql';
+import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
+import { HStack, Spacer, VStack } from '@shared/ui-kit';
+
+type LeaderboardExpIncrementResultProps = {
+ result: QueryResult<
+ GetLeaderboardExpIncrementQuery,
+ Exact<{
+ pageSize: number;
+ pageNumber: number;
+ dateTemplate: DateTemplate;
+ promo?: InputMaybe | undefined;
+ }>
+ >;
+};
+
+export function LeaderboardExpIncrementResult({
+ result: { loading, error, data },
+}: LeaderboardExpIncrementResultProps) {
+ const [_, setSearchParams] = useSearchParams();
+ const params = new URLSearchParams();
+
+ const { PROMO, PAGE, DATE } = LEADERBOARD_PARAM_KEYS;
+
+ const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
+
+ if (leaderboardArgs === null) {
+ throw new Error('leaderboardArgs is null');
+ }
+
+ const { promo, dateTemplate, pageNumber } = leaderboardArgs;
+
+ function handlePageNumberChange(pageNumber: number) {
+ params.set(DATE, dateTemplate);
+ if (promo) {
+ params.set(PROMO, promo.toString());
+ }
+ params.set(PAGE, pageNumber.toString());
+
+ setSearchParams(params);
+ }
+
+ if (loading) {
+ return ;
+ }
+ if (error) {
+ return ;
+ }
+ if (!data) {
+ return ;
+ }
+
+ const {
+ data: {
+ me,
+ totalRanking: { nodes, totalCount },
+ },
+ start,
+ end,
+ } = data.getLeaderboardExpIncrement.byDateTemplate;
+
+ const unit = '회';
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/src/Leaderboard/pages/ExpIncrement/index.tsx b/app/src/Leaderboard/pages/ExpIncrement/index.tsx
index 7ecfd2ab..bd1da5a2 100644
--- a/app/src/Leaderboard/pages/ExpIncrement/index.tsx
+++ b/app/src/Leaderboard/pages/ExpIncrement/index.tsx
@@ -3,28 +3,21 @@ import { useAtomValue } from 'jotai';
import { useSearchParams } from 'react-router-dom';
import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
-import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
-import { LeaderboardHeader } from '@/Leaderboard/components/Leaderboard/LeaderboardHeader';
-import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
-import {
- LEADERBOARD_DEFAULT_OPTIONS,
- SIZE_PER_PAGE,
-} from '@/Leaderboard/constants/defaultOptions';
+import { leaderboardPromoListAtom } from '@/Leaderboard/atoms/leaderboardPromoListAtom';
+import { PromoSelect } from '@/Leaderboard/components/PromoSelect';
+import { LEADERBOARD_DEFAULT_OPTIONS } from '@/Leaderboard/constants/defaultOptions';
import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
import { Footer } from '@core/components/Footer';
-import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
-import { Pagination } from '@shared/components/Pagination';
import { Seo } from '@shared/components/Seo';
-import { DeferredComponent, SegmentedControl, VStack } from '@shared/ui-kit';
-import { useDeviceType } from '@shared/utils/react-responsive/useDeviceType';
+import { HStack, SegmentedControl, VStack } from '@shared/ui-kit';
+import { LeaderboardExpIncrementResult } from './components/LeaderboardExpIncrementResult';
import { useLeaderboardExpIncrementSegmentedControl } from './hooks/useLeaderboardExpIncrementSegmentedControl';
import { GET_LEADERBOARD_EXP_INCREMENT } from './queries/getLeaderboardExpIncrement';
export default function LeaderboardExpIncrementPage() {
- const device = useDeviceType();
const [_, setSearchParams] = useSearchParams();
- const { DATE, PAGE, PROMO } = LEADERBOARD_PARAM_KEYS;
+ const { DATE, PROMO } = LEADERBOARD_PARAM_KEYS;
const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
@@ -32,14 +25,20 @@ export default function LeaderboardExpIncrementPage() {
throw new Error('leaderboardArgs is null');
}
- const { loading, error, data } = useQuery(GET_LEADERBOARD_EXP_INCREMENT, {
+ const promoList = useAtomValue(leaderboardPromoListAtom);
+
+ if (promoList === null) {
+ throw new Error('promoList is null');
+ }
+
+ const result = useQuery(GET_LEADERBOARD_EXP_INCREMENT, {
variables: {
...LEADERBOARD_DEFAULT_OPTIONS,
...leaderboardArgs,
},
});
- const { promo, pageNumber, dateTemplate } = leaderboardArgs;
+ const { promo, dateTemplate } = leaderboardArgs;
const { options, controlRef, segments } =
useLeaderboardExpIncrementSegmentedControl();
@@ -66,77 +65,26 @@ export default function LeaderboardExpIncrementPage() {
setSearchParams(params);
}
- function handlePageNumberChange(pageNumber: number) {
- const params = new URLSearchParams();
-
- params.set(DATE, dateTemplate);
- if (promo) {
- params.set(PROMO, promo.toString());
- }
- params.set(PAGE, pageNumber.toString());
-
- setSearchParams(params);
- }
-
- if (loading) {
- return (
-
-
-
- );
- }
- if (error) {
- return (
-
-
-
- );
- }
- if (!data) {
- return (
-
-
-
- );
- }
-
- const {
- data: {
- me,
- totalRanking: { nodes, totalCount },
- },
- start,
- end,
- } = data.getLeaderboardExpIncrement.byDateTemplate;
-
- const unit = 'XP';
-
return (
<>
-
-
-
-
-
-
+
+
+
+
+
+
>
diff --git a/app/src/Leaderboard/pages/Level/components/LeaderboardLevelResult.tsx b/app/src/Leaderboard/pages/Level/components/LeaderboardLevelResult.tsx
new file mode 100644
index 00000000..8d04014b
--- /dev/null
+++ b/app/src/Leaderboard/pages/Level/components/LeaderboardLevelResult.tsx
@@ -0,0 +1,94 @@
+import { QueryResult } from '@apollo/client';
+import { useAtomValue } from 'jotai';
+import { useSearchParams } from 'react-router-dom';
+
+import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
+import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
+import { LeaderboardDateDescriptor } from '@/Leaderboard/components/Leaderboard/LeaderboardDateDescriptor';
+import { LeaderboardPagination } from '@/Leaderboard/components/LeaderboardPagination';
+import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
+import { SIZE_PER_PAGE } from '@/Leaderboard/constants/defaultOptions';
+import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
+import {
+ DateTemplate,
+ GetLeaderboardLevelQuery,
+} from '@shared/__generated__/graphql';
+import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
+import { HStack, Spacer, VStack } from '@shared/ui-kit';
+
+type LeaderboardLevelResultProps = {
+ result: QueryResult<
+ GetLeaderboardLevelQuery,
+ {
+ dateTemplate: DateTemplate;
+ pageNumber: number;
+ promo: number | null;
+ pageSize: number;
+ }
+ >;
+};
+
+export function LeaderboardLevelResult({
+ result: { loading, error, data },
+}: LeaderboardLevelResultProps) {
+ const [_, setSearchParams] = useSearchParams();
+ const params = new URLSearchParams();
+
+ const { PROMO, PAGE } = LEADERBOARD_PARAM_KEYS;
+
+ const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
+
+ if (leaderboardArgs === null) {
+ throw new Error('leaderboardArgs is null');
+ }
+
+ const { promo, pageNumber } = leaderboardArgs;
+
+ function handlePageNumberChange(pageNumber: number) {
+ if (promo) {
+ params.set(PROMO, promo.toString());
+ }
+ params.set(PAGE, pageNumber.toString());
+
+ setSearchParams(params);
+ }
+
+ if (loading) {
+ return ;
+ }
+ if (error) {
+ return ;
+ }
+ if (!data) {
+ return ;
+ }
+
+ const {
+ data: {
+ me,
+ totalRanking: { nodes, totalCount },
+ },
+ start,
+ end,
+ } = data.getLeaderboardLevel.byDateTemplate;
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/src/Leaderboard/pages/Level/index.tsx b/app/src/Leaderboard/pages/Level/index.tsx
index 7dfa04fa..804daaa0 100644
--- a/app/src/Leaderboard/pages/Level/index.tsx
+++ b/app/src/Leaderboard/pages/Level/index.tsx
@@ -3,28 +3,21 @@ import { useAtomValue } from 'jotai';
import { useSearchParams } from 'react-router-dom';
import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
-import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
-import { LeaderboardHeader } from '@/Leaderboard/components/Leaderboard/LeaderboardHeader';
-import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
-import {
- LEADERBOARD_DEFAULT_OPTIONS,
- SIZE_PER_PAGE,
-} from '@/Leaderboard/constants/defaultOptions';
+import { leaderboardPromoListAtom } from '@/Leaderboard/atoms/leaderboardPromoListAtom';
+import { PromoSelect } from '@/Leaderboard/components/PromoSelect';
+import { LEADERBOARD_DEFAULT_OPTIONS } from '@/Leaderboard/constants/defaultOptions';
import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
import { Footer } from '@core/components/Footer';
import { DateTemplate } from '@shared/__generated__/graphql';
-import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
-import { Pagination } from '@shared/components/Pagination';
import { Seo } from '@shared/components/Seo';
-import { DeferredComponent, VStack } from '@shared/ui-kit';
-import { useDeviceType } from '@shared/utils/react-responsive/useDeviceType';
+import { HStack, VStack } from '@shared/ui-kit';
+import { LeaderboardLevelResult } from './components/LeaderboardLevelResult';
import { GET_LEADERBOARD_LEVEL } from './queries/getLeaderboardLevel';
export default function LeaderboardLevelPage() {
- const device = useDeviceType();
const [_, setSearchParams] = useSearchParams();
- const { PAGE, PROMO } = LEADERBOARD_PARAM_KEYS;
+ const { PROMO } = LEADERBOARD_PARAM_KEYS;
const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
@@ -32,7 +25,13 @@ export default function LeaderboardLevelPage() {
throw new Error('leaderboardArgs is null');
}
- const { loading, error, data } = useQuery(GET_LEADERBOARD_LEVEL, {
+ const promoList = useAtomValue(leaderboardPromoListAtom);
+
+ if (promoList === null) {
+ throw new Error('promoList is null');
+ }
+
+ const result = useQuery(GET_LEADERBOARD_LEVEL, {
variables: {
...LEADERBOARD_DEFAULT_OPTIONS,
...leaderboardArgs,
@@ -40,7 +39,7 @@ export default function LeaderboardLevelPage() {
},
});
- const { promo, pageNumber } = leaderboardArgs;
+ const { promo } = leaderboardArgs;
function handlePromoChange(promo: string | null) {
const params = new URLSearchParams();
@@ -52,67 +51,18 @@ export default function LeaderboardLevelPage() {
setSearchParams(params);
}
- function handlePageNumberChange(pageNumber: number) {
- const params = new URLSearchParams();
-
- if (promo) {
- params.set(PROMO, promo.toString());
- }
- params.set(PAGE, pageNumber.toString());
-
- setSearchParams(params);
- }
-
- if (loading) {
- return (
-
-
-
- );
- }
- if (error) {
- return (
-
-
-
- );
- }
- if (!data) {
- return (
-
-
-
- );
- }
-
- const {
- data: {
- me,
- totalRanking: { nodes, totalCount },
- },
- start,
- end,
- } = data.getLeaderboardLevel.byDateTemplate;
-
return (
<>
-
-
-
+
+
-
-
-
+
+
>
diff --git a/app/src/Leaderboard/pages/Score/components/LeaderboardScoreResult.tsx b/app/src/Leaderboard/pages/Score/components/LeaderboardScoreResult.tsx
new file mode 100644
index 00000000..18e7f3c3
--- /dev/null
+++ b/app/src/Leaderboard/pages/Score/components/LeaderboardScoreResult.tsx
@@ -0,0 +1,99 @@
+import { QueryResult } from '@apollo/client';
+import { useAtomValue } from 'jotai';
+import { useSearchParams } from 'react-router-dom';
+
+import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
+import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
+import { LeaderboardDateDescriptor } from '@/Leaderboard/components/Leaderboard/LeaderboardDateDescriptor';
+import { LeaderboardPagination } from '@/Leaderboard/components/LeaderboardPagination';
+import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
+import { SIZE_PER_PAGE } from '@/Leaderboard/constants/defaultOptions';
+import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
+import {
+ DateTemplate,
+ Exact,
+ GetLeaderboardScoreQuery,
+ InputMaybe,
+} from '@shared/__generated__/graphql';
+import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
+import { HStack, Spacer, VStack } from '@shared/ui-kit';
+
+type LeaderboardScoreResultProps = {
+ result: QueryResult<
+ GetLeaderboardScoreQuery,
+ Exact<{
+ pageSize: number;
+ pageNumber: number;
+ dateTemplate: DateTemplate;
+ promo?: InputMaybe | undefined;
+ }>
+ >;
+};
+
+export function LeaderboardScoreResult({
+ result: { loading, error, data },
+}: LeaderboardScoreResultProps) {
+ const [_, setSearchParams] = useSearchParams();
+ const params = new URLSearchParams();
+
+ const { PROMO, PAGE, DATE } = LEADERBOARD_PARAM_KEYS;
+
+ const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
+
+ if (leaderboardArgs === null) {
+ throw new Error('leaderboardArgs is null');
+ }
+
+ const { promo, dateTemplate, pageNumber } = leaderboardArgs;
+
+ function handlePageNumberChange(pageNumber: number) {
+ params.set(DATE, dateTemplate);
+ if (promo) {
+ params.set(PROMO, promo.toString());
+ }
+ params.set(PAGE, pageNumber.toString());
+
+ setSearchParams(params);
+ }
+
+ if (loading) {
+ return ;
+ }
+ if (error) {
+ return ;
+ }
+ if (!data) {
+ return ;
+ }
+
+ const {
+ data: {
+ me,
+ totalRanking: { nodes, totalCount },
+ },
+ start,
+ end,
+ } = data.getLeaderboardScore.byDateTemplate;
+
+ const unit = 'P';
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/src/Leaderboard/pages/Score/index.tsx b/app/src/Leaderboard/pages/Score/index.tsx
index 5bf23416..e0f7bcf9 100644
--- a/app/src/Leaderboard/pages/Score/index.tsx
+++ b/app/src/Leaderboard/pages/Score/index.tsx
@@ -3,27 +3,21 @@ import { useAtomValue } from 'jotai';
import { useSearchParams } from 'react-router-dom';
import { leaderboardArgsAtom } from '@/Leaderboard/atoms/leaderboardArgsAtom';
-import { Leaderboard } from '@/Leaderboard/components/Leaderboard';
-import { LeaderboardHeader } from '@/Leaderboard/components/Leaderboard/LeaderboardHeader';
-import { LeaderboardResultSkeleton } from '@/Leaderboard/components/skeletons/LeaderboardResultSkeleton';
-import {
- LEADERBOARD_DEFAULT_OPTIONS,
- SIZE_PER_PAGE,
-} from '@/Leaderboard/constants/defaultOptions';
+import { leaderboardPromoListAtom } from '@/Leaderboard/atoms/leaderboardPromoListAtom';
+import { PromoSelect } from '@/Leaderboard/components/PromoSelect';
+import { LEADERBOARD_DEFAULT_OPTIONS } from '@/Leaderboard/constants/defaultOptions';
import { LEADERBOARD_PARAM_KEYS } from '@/Leaderboard/constants/paramKeys';
import { Footer } from '@core/components/Footer';
-import { FullPageApolloErrorView } from '@shared/components/ApolloError/FullPageApolloErrorView';
-import { Pagination } from '@shared/components/Pagination';
-import { DeferredComponent, SegmentedControl, VStack } from '@shared/ui-kit';
-import { useDeviceType } from '@shared/utils/react-responsive/useDeviceType';
+import { HStack, SegmentedControl, VStack } from '@shared/ui-kit';
+import { Seo } from '@shared/components/Seo';
+import { LeaderboardScoreResult } from './components/LeaderboardScoreResult';
import { useLeaderboardScoreSegmentedControl } from './hooks/useLeaderboardScoreSegmentedControl';
import { GET_LEADERBOARD_SCORE } from './queries/getLeaderboardScore';
export default function LeaderboardScorePage() {
- const device = useDeviceType();
const [_, setSearchParams] = useSearchParams();
- const { DATE, PAGE, PROMO } = LEADERBOARD_PARAM_KEYS;
+ const { DATE, PROMO } = LEADERBOARD_PARAM_KEYS;
const leaderboardArgs = useAtomValue(leaderboardArgsAtom);
@@ -31,14 +25,20 @@ export default function LeaderboardScorePage() {
throw new Error('leaderboardArgs is null');
}
- const { loading, error, data } = useQuery(GET_LEADERBOARD_SCORE, {
+ const promoList = useAtomValue(leaderboardPromoListAtom);
+
+ if (promoList === null) {
+ throw new Error('promoList is null');
+ }
+
+ const result = useQuery(GET_LEADERBOARD_SCORE, {
variables: {
...LEADERBOARD_DEFAULT_OPTIONS,
...leaderboardArgs,
},
});
- const { promo, pageNumber, dateTemplate } = leaderboardArgs;
+ const { promo, dateTemplate } = leaderboardArgs;
const { options, controlRef, segments } =
useLeaderboardScoreSegmentedControl();
@@ -65,76 +65,26 @@ export default function LeaderboardScorePage() {
setSearchParams(params);
}
- function handlePageNumberChange(pageNumber: number) {
- const params = new URLSearchParams();
-
- params.set(DATE, dateTemplate);
- if (promo) {
- params.set(PROMO, promo.toString());
- }
- params.set(PAGE, pageNumber.toString());
-
- setSearchParams(params);
- }
-
- if (loading) {
- return (
-
-
-
- );
- }
- if (error) {
- return (
-
-
-
- );
- }
- if (!data) {
- return (
-
-
-
- );
- }
-
- const {
- data: {
- me,
- totalRanking: { nodes, totalCount },
- },
- start,
- end,
- } = data.getLeaderboardScore.byDateTemplate;
-
- const unit = 'P';
-
return (
<>
+
-
-
-
-
-
-
+
+
+
+
+
+
>