kaiqiu-rank-list/src/components/GroupingPrediction.tsx

66 lines
2.4 KiB
TypeScript

import React, { useMemo, useState } from "react";
import { Flex, Form, InputNumber, Space, Switch } from "antd";
import { chunk } from 'lodash';
import type { Player } from "../types";
import { GroupMember } from "./GroupMember";
import { sneckGroup } from "../utils";
interface Props {
players?: Player[];
sneckMode: boolean;
}
type CustomPlayer = (Player & { index: number; id: string; });
export const GroupingPrediction: React.FC<Props> = props => {
const [maxPlayerSize, setMaxPlayerSize] = useState(48);
const players: CustomPlayer[] = useMemo(() => {
return props.players?.slice(0, maxPlayerSize)?.map((e, i) => ({ ...e, index: i + 1, id: `${i}-${e.name}-${e.score}` })) ?? [];
}, [props.players, maxPlayerSize]);
const [groupLen, setGroupLen] = useState(6);
const [sneckMode, setSneckMode] = useState(props.sneckMode);
const chunkSize = useMemo(() => Math.floor((players.length ?? 0) / groupLen) || 1, [players, groupLen]);
const grouped = useMemo(() => {
return chunk(players, chunkSize);
}, [chunkSize]);
const sneckedGroups = useMemo(() => {
const sneckIndexGroups = sneckGroup(players.length, groupLen);
return sneckIndexGroups.map(g => {
const subGroup = g.map(i => ({
...players[i],
})).filter(Boolean) as CustomPlayer[];
return subGroup;
});
}, [grouped, groupLen, maxPlayerSize]);
return (
<>
<Form layout='horizontal'>
<Form.Item label={'取人数'}>
<InputNumber
value={maxPlayerSize}
onChange={e => setMaxPlayerSize(e || props.players?.length || 0)}
max={props.players?.length}
/>
</Form.Item>
<Form.Item label="分组数">
<InputNumber
value={groupLen}
onChange={e => setGroupLen(e ?? 1)}
min={1}
max={26}
/>
</Form.Item>
<Form.Item label="蛇形分组">
<Switch checked={sneckMode} onChange={setSneckMode} />
</Form.Item>
</Form>
<Flex gap='middle' wrap align="center" justify="center">
<React.Fragment key={'normal'}>
{ !sneckMode && grouped.map((p, i) => <GroupMember key={i} players={p} index={i} />)}
</React.Fragment>
<React.Fragment key={'sneck'}>
{ sneckMode && sneckedGroups.map((p, i) => <GroupMember key={i} players={p} index={i} />)}
</React.Fragment>
</Flex>
</>
);
}