feat(club): add club type filtering and optimize event list display
- Add 'Club' vs 'Points Club' filter in `ClubSearchTable` using Radio buttons. - Update `searchClub` request to accept and pass `clubType` parameter to the backend API. - Refactor logic in `ClubEventList` to determine "Show All" button visibility based on whether all items are finished or not finished, rather than just a fixed count. - Add custom CSS (styled-components) to limit the height of the game selector drawer for better UX. - Update backend service `KaiqiuService` to handle the new query parameters for filtering clubs by type.
This commit is contained in:
parent
99fd5778df
commit
aef89d2341
@ -42,8 +42,9 @@ export const ClubEvenList = (props: Props) => {
|
|||||||
const id = setTimeout(async () => {
|
const id = setTimeout(async () => {
|
||||||
const data = await requestEvents.runAsync(props.clubId, 1).then(res => res.data);
|
const data = await requestEvents.runAsync(props.clubId, 1).then(res => res.data);
|
||||||
setPage(1);
|
setPage(1);
|
||||||
if (data.length === 10) {
|
if (data.length) {
|
||||||
setShowAll(data.every(e => !e.isFinished));
|
const isAllFinishedOrAllNotFinished = data.every(e => e.isFinished) || data.every(e => !e.isFinished);
|
||||||
|
setShowAll(isAllFinishedOrAllNotFinished);
|
||||||
setShowAllDiable(data.every(e => !e.isFinished));
|
setShowAllDiable(data.every(e => !e.isFinished));
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useRequest } from "ahooks";
|
import { useRequest } from "ahooks";
|
||||||
import { Avatar, Button, Flex, Input, Space, Table } from "antd";
|
import { Avatar, Button, Flex, Input, Radio, Space, Table } from "antd";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import type { ClubInfo } from "../types";
|
import type { ClubInfo } from "../types";
|
||||||
import { EyeOutlined, StarFilled, StarOutlined } from "@ant-design/icons";
|
import { EyeOutlined, StarFilled, StarOutlined } from "@ant-design/icons";
|
||||||
@ -14,23 +14,44 @@ interface Props {
|
|||||||
|
|
||||||
export const ClubSearchTable = (props: Props) => {
|
export const ClubSearchTable = (props: Props) => {
|
||||||
const [searchKey, setSearchKey] = useState('');
|
const [searchKey, setSearchKey] = useState('');
|
||||||
const searchClub = useRequest<{ clubs: ClubInfo[], total: number }, [string, number]>(async (searchKey: string, page = 1) => {
|
const searchClub = useRequest<{ clubs: ClubInfo[], total: number }, [string, number, number]>(async (
|
||||||
const resp: { clubs: ClubInfo[], total: number } = await fetch(`/api/club/find?key=${searchKey}&page=${page}`).then(e => e.json());
|
searchKey: string,
|
||||||
|
page = 1,
|
||||||
|
clubType = 0,
|
||||||
|
) => {
|
||||||
|
const resp: { clubs: ClubInfo[], total: number } = await fetch(
|
||||||
|
`/api/club/find?key=${searchKey}&page=${page}${clubType ? '&normalClub=1' : ''}`
|
||||||
|
).then(e => e.json());
|
||||||
return resp;
|
return resp;
|
||||||
}, { manual: true });
|
}, { manual: true });
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const handleSearch = useCallback((searchKey: string) => {
|
const [clubType, setClubType] = useState(0);
|
||||||
searchClub.runAsync(searchKey, 1);
|
const handleSearch = useCallback((searchKey: string, clubType: number) => {
|
||||||
}, [searchKey]);
|
setPage(1);
|
||||||
|
searchClub.runAsync(searchKey, 1, clubType);
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<Flex vertical gap={12} justify="center" align="center">
|
<Flex vertical gap={12} justify="center" align="center">
|
||||||
|
<Radio.Group
|
||||||
|
optionType="button"
|
||||||
|
value={clubType}
|
||||||
|
onChange={e => {
|
||||||
|
setClubType(e.target.value);
|
||||||
|
if (!searchKey) return;
|
||||||
|
handleSearch(searchKey, e.target.value);
|
||||||
|
}}
|
||||||
|
options={[
|
||||||
|
{ label: '积分俱乐部', value: 0 },
|
||||||
|
{ label: '俱乐部', value: 1 },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<Input.Search
|
<Input.Search
|
||||||
allowClear
|
allowClear
|
||||||
onSearch={e => {
|
onSearch={e => {
|
||||||
setSearchKey(e);
|
setSearchKey(e);
|
||||||
handleSearch(e);
|
handleSearch(e, clubType);
|
||||||
}}
|
}}
|
||||||
onPressEnter={() => handleSearch(searchKey)}
|
onPressEnter={() => handleSearch(searchKey, clubType)}
|
||||||
value={searchKey}
|
value={searchKey}
|
||||||
onChange={e => setSearchKey(e.target.value)}
|
onChange={e => setSearchKey(e.target.value)}
|
||||||
/>
|
/>
|
||||||
@ -46,7 +67,8 @@ export const ClubSearchTable = (props: Props) => {
|
|||||||
total: searchClub.data?.total,
|
total: searchClub.data?.total,
|
||||||
onChange: (page) => {
|
onChange: (page) => {
|
||||||
setPage(page);
|
setPage(page);
|
||||||
searchClub.runAsync(searchKey, page);
|
searchClub.runAsync(searchKey, page, clubType);
|
||||||
|
console.debug('onPageChange', { searchKey, page, clubType });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -3,9 +3,10 @@ import type React from 'react';
|
|||||||
import { clubs } from './clubList';
|
import { clubs } from './clubList';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { ClubEvenList } from '../ClubEventList';
|
import { ClubEvenList } from '../ClubEventList';
|
||||||
import { DeleteOutlined, PlusOutlined, SearchOutlined } from '@ant-design/icons';
|
import { DeleteOutlined, SearchOutlined } from '@ant-design/icons';
|
||||||
import { useClubStore } from '../../store/useClubStore';
|
import { useClubStore } from '../../store/useClubStore';
|
||||||
import { ClubSearchTable } from '../ClubSearchTable';
|
import { ClubSearchTable } from '../ClubSearchTable';
|
||||||
|
import { createGlobalStyle } from 'styled-components';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
}
|
}
|
||||||
@ -14,6 +15,12 @@ const defaultOptions = clubs.map(e => ({
|
|||||||
value: e.clubId,
|
value: e.clubId,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const ChangeDrawerHeight = createGlobalStyle`
|
||||||
|
.ant-drawer-content-wrapper:has(div.search-table) {
|
||||||
|
max-height: 720px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const GameSelector: React.FC<Props> = () => {
|
export const GameSelector: React.FC<Props> = () => {
|
||||||
const [options, setOptions] = useState<{ label: React.ReactNode, value: string }[]>(defaultOptions);
|
const [options, setOptions] = useState<{ label: React.ReactNode, value: string }[]>(defaultOptions);
|
||||||
const [clubId, setClubId] = useState<string>(clubs[0]?.clubId ?? '');
|
const [clubId, setClubId] = useState<string>(clubs[0]?.clubId ?? '');
|
||||||
@ -43,6 +50,7 @@ export const GameSelector: React.FC<Props> = () => {
|
|||||||
}, [clubStore]);
|
}, [clubStore]);
|
||||||
return (
|
return (
|
||||||
<Space orientation='vertical' style={{ width: '100%' }}>
|
<Space orientation='vertical' style={{ width: '100%' }}>
|
||||||
|
<ChangeDrawerHeight />
|
||||||
<Flex gap={12} justify='center' align='center'>
|
<Flex gap={12} justify='center' align='center'>
|
||||||
<Select
|
<Select
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
@ -60,6 +68,7 @@ export const GameSelector: React.FC<Props> = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<ClubEvenList clubId={clubId} />
|
<ClubEvenList clubId={clubId} />
|
||||||
<Drawer
|
<Drawer
|
||||||
|
className='search-table'
|
||||||
open={searchOpen}
|
open={searchOpen}
|
||||||
placement='bottom'
|
placement='bottom'
|
||||||
size={"80vh"}
|
size={"80vh"}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export class KaiqiuService {
|
|||||||
|
|
||||||
public static async findClub(name: string, page = 1, normalClub?: boolean) {
|
public static async findClub(name: string, page = 1, normalClub?: boolean) {
|
||||||
const searchKey = encodeURIComponent(name);
|
const searchKey = encodeURIComponent(name);
|
||||||
const url = `${this.#baseURL}/home/space.php?province=&city=&searchkey=${searchKey}&searchsubmit=%E6%90%9C%E7%B4%A2&searchmode=1&do=mtag&view=hot&page=${page}`;
|
const url = `${this.#baseURL}/home/space.php?province=&city=&searchkey=${searchKey}&searchsubmit=%E6%90%9C%E7%B4%A2&searchmode=1&do=mtag&view=hot&${normalClub ? 'page2': 'page'}=${page}`;
|
||||||
const html = await fetch(url, {
|
const html = await fetch(url, {
|
||||||
headers: htmlRequestHeaders,
|
headers: htmlRequestHeaders,
|
||||||
}).then(res => res.text());
|
}).then(res => res.text());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user