Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 'use client';
import { UserOutlined } from '@ant-design/icons';
import { useGetTotalFestivalRankingQuery, useGetTotalFestivalsQuery } from '@lib/api/queries';
import {
HeaderContainer,
UserImage,
UserImageContainer,
UserInfoContainer
} from '@lib/components/styledComponents';
import { FestivalRankingDto } from '@uniquegood/realworld-adventure-interface';
import { Select, Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import React from 'react';
import { UserIdCell } from '../UserIdCell';
const rankingStyle = {
backgroundColor: '#f9f0ff',
color: '#c869ff'
};
function Row({ children, ...props }: { children: React.ReactElement }) {
const ranking = (
React.Children.toArray(children)[0] as { props: { record: { ranking: number } } }
)?.props?.record?.ranking;
return (
<tr {...props} style={ranking < 4 ? rankingStyle : { border: '2px solid red' }}>
{React.Children.map(children, (child) => {
return child;
})}
</tr>
);
}
export default function FestivalRankingPage() {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const [currentFestivalId, setCurrentFestivalId] = React.useState(
searchParams.get('festivalId') || ''
);
const createQueryString = React.useCallback(
(name: string, value: string) => {
const params = new URLSearchParams(searchParams);
params.set(name, value);
return params.toString();
},
[searchParams]
);
const { data: festivals } = useGetTotalFestivalsQuery();
const { data: festivalRanking } = useGetTotalFestivalRankingQuery(currentFestivalId);
const columns: ColumnsType<FestivalRankingDto> = [
{
key: 'ranking',
dataIndex: 'ranking',
title: '순위'
},
{
key: 'findCount',
dataIndex: 'findCount',
title: '찾은 개수'
},
{
key: 'userName',
dataIndex: 'userName',
title: '이름',
render: (value, record) => (
<UserInfoContainer>
<UserImageContainer>
{record.userImageUrl ? (
<UserImage src={record.userImageUrl} alt="프로필 이미지" />
) : (
<div>
<UserOutlined />
</div>
)}
</UserImageContainer>
{value}
</UserInfoContainer>
)
},
{
key: 'userId',
dataIndex: 'userId',
title: '유저 ID',
render: (value) => <UserIdCell>{value}</UserIdCell>
}
];
return (
<div>
<HeaderContainer>
<h1>축제 랭킹 조회</h1>
</HeaderContainer>
<Select
value={currentFestivalId || undefined}
placeholder="축제를 선택해주세요."
options={festivals?.data?.content.map((festival) => ({
label: festival.title,
value: festival.id
}))}
onChange={(value) => {
setCurrentFestivalId(value);
router.push(`${pathname}?${createQueryString('festivalId', value)}`);
}}
showSearch
filterOption={(input, option) => {
return option?.label?.includes(input) || false;
}}
style={{ width: '300px', marginBottom: '16px' }}
/>
<Table
dataSource={festivalRanking?.data?.content}
columns={columns}
components={{ body: { row: Row } }}
pagination={false}
rowKey="userId"
/>
</div>
);
}
|