66 lines
2.4 KiB
TypeScript
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>
|
|
</>
|
|
);
|
|
} |