Skip to content

Commit

Permalink
feat: 更优雅的省份搜索
Browse files Browse the repository at this point in the history
  • Loading branch information
renbaoshuo committed Nov 23, 2024
1 parent aea47a0 commit 7a9724d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 58 deletions.
42 changes: 31 additions & 11 deletions src/components/Search.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState, useTransition } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useEffect, useMemo, useState, useTransition } from 'react';
import { Link, useSearchParams } from 'react-router-dom';
import {
Header,
Input,
Expand All @@ -14,10 +14,10 @@ import PersonCard from '@/components/PersonCard';
import getGrade, { currentYear } from '@/utils/getGrade';
import compareGrades from '@/utils/compareGrades';
import {
provinces,
type OIer,
genders,
searchableGenderKeys,
provincesWithId,
} from '@/libs/OIerDb';
import styles from './Search.module.less';

Expand Down Expand Up @@ -49,6 +49,18 @@ const Search: React.FC = () => {
school: '',
});

const provinces = useMemo(
() =>
Object.entries(provincesWithId).map(([id, province]) => ({
key: id,
value: province,
text: `${province} (${id})`,
content: province,
label: { content: id, basic: true, size: 'mini' },
})),
[]
);

const province = searchParams.get('province') || '';
const setProvince = (province: string) => setSearchParams({ province });

Expand All @@ -70,14 +82,15 @@ const Search: React.FC = () => {

startTransition(() => {
let result: OIer[] = [];

if (!advanced) {
result = OIerDb.oiers.filter(
(oier) => oier.lowered_name === input || oier.initials === input
);
} else if (!input && !grade && !school) {
result = [];
} else {
result = OIerDb.oiers.filter((oier) => {
if (!(input || province || grade || school)) return false;

let res = Boolean(input || province || grade || school || gender);

if (input) {
Expand Down Expand Up @@ -156,11 +169,7 @@ const Search: React.FC = () => {
search
selection
clearable
options={provinces.map((province) => ({
key: province,
value: province,
text: province,
}))}
options={provinces}
defaultValue={province}
onChange={(_, { value }) => setProvince(value as string)}
/>
Expand Down Expand Up @@ -231,7 +240,18 @@ const Search: React.FC = () => {
<>
{input || province || grade || school || gender ? (
<div style={{ paddingTop: '1rem' }}>
{gender ? '暂时不支持仅按照性别搜索选手。' : '未找到结果。'}
{gender || province ? (
gender ? (
'暂时不支持仅按照性别搜索选手。'
) : (
<>
请访问「
<Link to="/oiers">选手</Link>」页面查询某省的所有选手。
</>
)
) : (
'未找到结果。'
)}
</div>
) : (
<></>
Expand Down
76 changes: 40 additions & 36 deletions src/libs/OIerDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,42 +442,46 @@ export const initDb = async (setProgressPercent?: (p: number) => void) => {
};

// 省份列表
export const provinces = [
'安徽',
'北京',
'福建',
'甘肃',
'广东',
'广西',
'贵州',
'海南',
'河北',
'河南',
'黑龙江',
'湖北',
'湖南',
'吉林',
'江苏',
'江西',
'辽宁',
'内蒙古',
'山东',
'山西',
'陕西',
'上海',
'四川',
'天津',
'新疆',
'浙江',
'重庆',
'宁夏',
'云南',
'澳门',
'香港',
'青海',
'西藏',
'台湾',
] as const;
export const provincesWithId = {
AH: '安徽',
BJ: '北京',
FJ: '福建',
GS: '甘肃',
GD: '广东',
GX: '广西',
GZ: '贵州',
HI: '海南',
HE: '河北',
HA: '河南',
HL: '黑龙江',
HB: '湖北',
HN: '湖南',
JL: '吉林',
JS: '江苏',
JX: '江西',
LN: '辽宁',
NM: '内蒙古',
SD: '山东',
SX: '山西',
SN: '陕西',
SH: '上海',
SC: '四川',
TJ: '天津',
XJ: '新疆',
ZJ: '浙江',
CQ: '重庆',
NX: '宁夏',
YN: '云南',
MO: '澳门',
HK: '香港',
QH: '青海',
XC: '西藏',
TW: '台湾',
} as const;

export const provinces = Object.values(
provincesWithId
) as (typeof provincesWithId)[keyof typeof provincesWithId][];

// 奖项列表及颜色
export const awardColors = {
Expand Down
29 changes: 18 additions & 11 deletions src/pages/contest/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import getProgress from '@/utils/getProgress';
import fixContestName from '@/utils/fixContestName';
import Pagination from '@/components/Pagination';
import styles from './[id].module.less';
import { awardColors, awardLevels } from '@/libs/OIerDb';
import { awardColors, awardLevels, provincesWithId } from '@/libs/OIerDb';
import compareGrades from '@/utils/compareGrades';

const NotFound = lazy(() => import('@/pages/404'));
Expand Down Expand Up @@ -52,12 +52,23 @@ const Contest: React.FC = () => {
setSearchParams({ grade: String(grade), page: '1' });
};

const provinces = useMemo(
() => [
const provinces = useMemo(() => {
const withId2 = Object.fromEntries(
Object.entries(provincesWithId).map(([id, province]) => [province, id])
);

return [
...new Set(contest.contestants.map((contestant) => contestant.province)),
],
[id]
);
]
.map((province) => ({
key: withId2[province],
value: province,
text: `${province} (${withId2[province]})`,
content: province,
label: { content: withId2[province], basic: true, size: 'mini' },
}))
.sort((a, b) => a.key.localeCompare(b.key));
}, [id]);

const grades = useMemo(
() => [
Expand Down Expand Up @@ -172,11 +183,7 @@ const Contest: React.FC = () => {
clearable
placeholder="省份"
value={province}
options={provinces.map((province) => ({
key: province,
value: province,
text: province,
}))}
options={provinces}
onChange={(_, { value }) => setProvince(value as string)}
/>
</Form.Group>
Expand Down

0 comments on commit 7a9724d

Please sign in to comment.