react-icons/bs#BsX TypeScript Examples
The following examples show how to use
react-icons/bs#BsX.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Teams.tsx From majsoul-api with MIT License | 4 votes |
function Team(props: {
team: Store.ContestTeam,
score?: number,
placing: number,
maxPlaceLength: number,
}): JSX.Element {
const { contestId } = React.useContext(ContestContext);
const showTeamLogo = useSelector((state: IState) => state.contestsById[contestId]?.subtype !== TourneyContestPhaseSubtype.TeamQualifier);
const token = useSelector((state: IState) => state.user?.token);
const [name, setName] = React.useState<string>();
const [image, setImage] = React.useState<string>();
const [anthem, setAnthem] = React.useState<string>();
const [playAnthem, setPlayAnthem] = React.useState(false);
const [viewDetails, setViewDetails] = React.useState(false);
const [apiPlayers, setApiPlayers] = React.useState<Rest.ContestPlayer<string>[]>(null);
const [editedPlayers, setEditedPlayers] = React.useState<Partial<Rest.ContestPlayer<string>>[]>(null);
const [color, setColor] = React.useState<string>();
const [statsRequest, setStatsRequest] = React.useState<StatsRequest>(null);
const [selectedPlayerName, setSelectedPlayerName] = React.useState<string>();
const onColorChange = React.useCallback((oldValue: string, newValue: string) => {
const isValid = colorRegex.test(newValue);
const value = isValid ? newValue : oldValue;
setColor(value);
return {
value,
isValid,
};
}, [setColor]);
const teamAnthem = anthem ?? props.team.anthem ?? "";
React.useEffect(() => {
if (!viewDetails) {
return;
}
fetchContestPlayers({
contestId: contestId,
teamId: props.team._id,
}).then(players => {
setApiPlayers(players);
});
setStatsRequest({
team: props.team._id
});
}, [props.team._id, contestId, viewDetails]);
const onAccordionSelect = React.useCallback((selectedKey: string) => {
setViewDetails(selectedKey === "0");
}, [setViewDetails])
const dispatch = useDispatch();
const players = editedPlayers ?? apiPlayers;
return <Accordion
as={Container}
className="p-0"
onSelect={onAccordionSelect}
activeKey={viewDetails ? "0" : null}
>
<Accordion.Toggle
disabled as={Row}
eventKey="0"
className={clsx("no-gutters align-items-center flex-nowrap", globalStyles.linkDark)}
>
{props.placing != null
&& <Col
md="auto"
className="mr-3 text-right"
style={{ minWidth: `${(props.maxPlaceLength + 1) * 1.25}rem` }}>
<h3>
<Badge variant={props.placing === 1 ? "danger" : props.placing > 4 ? "secondary" : "success"}>
<b>
{jpNumeral(props.placing)}位
</b>
</Badge>
</h3>
</Col>
}
{ showTeamLogo &&
<Col md="auto" className="mr-3">
<label>
<input
disabled={token == null}
style={{ display: "none" }}
type="file"
onChange={function (event) {
const reader = new FileReader();
const input = event.target as HTMLInputElement;
if (input.files && input.files[0]) {
reader.onload = function (e) {
setImage(e.target.result.toString());
}
reader.readAsDataURL(input.files[0]);
}
}}
/>
<TeamImage className={clsx(styles.teamImage, "rounded")} team={props.team} />
</label>
</Col>
}
<Col md="auto" className="text-nowrap" style={{ flexShrink: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis" }}>
<Container className="p-0">
<Row className="no-gutters">
<Col md="auto" className="font-weight-bold text-capitalize h5 text-truncate" style={{ borderBottom: `3px solid #${props.team.color}` }}>
{props.team.name ?? `#${props.team._id}`}
</Col>
</Row>
</Container>
</Col>
<Col></Col>
{isNaN(props.score) || <Col md="auto" className="ml-3"> <h5><b>{props.score / 1000}</b></h5></Col>}
</Accordion.Toggle>
<Accordion.Collapse as={Row} eventKey="0">
<>
<Container className={clsx("p-0")}>
<Row>
{players && <Col className="text-center">
<span
className={clsx("h5 font-weight-bold", globalStyles.linkDark)}
onClick={() => {
setSelectedPlayerName(null);
setStatsRequest({ team: props.team._id });
}}
>{props.team.name}</span>
<span className="h5">{selectedPlayerName}</span>
</Col>}
</Row>
<Row>
<Stats
request={statsRequest}
hideResults={players == null}
/>
</Row>
</Container>
{players == null
? <LoadingSpinner />
: <Container className="p-0">
{[...players].sort((a, b) => (b.tourneyScore ?? 0) - (a.tourneyScore ?? 0)).map(player =>
<Row key={player._id} className="no-gutters py-1">
<Col md="auto" style={{ minWidth: `${(props.maxPlaceLength + 1) * 1.25}rem` }} className="mr-3" />
<Col md="auto" style={{ minWidth: 64 }} className="mr-3">
{token && <BsX
className={globalStyles.linkDark}
onClick={() => setEditedPlayers(players.filter(p => p._id !== player._id))}
/>}
</Col>
<Col
className={clsx("text-left", globalStyles.linkDark)}
onClick={() => {
setStatsRequest({ player: player._id });
setSelectedPlayerName(player.displayName ?? player.nickname);
}}
>
{player.displayName ?? player.nickname}
</Col>
<Col className="text-right">
{(player.tourneyScore ?? 0) / 1000}
</Col>
</Row>
)}
</Container>
}
{token &&
<Container>
{(teamAnthem?.length > 0) && <SongPlayer videoId={teamAnthem} play={playAnthem} />}
<Row>
<Col>
<TextField
inline
label="Name"
id={`${props.team._id}-name-editor`}
placeholder={`#${props.team._id}`}
fallbackValue={props.team.name}
onChange={(_, newValue) => {
setName(newValue);
return {
value: newValue,
isValid: true,
}
}}
/>
</Col>
<Col md="auto">
<Button
onClick={() =>
deleteTeam(token, contestId, props.team._id)
.then(() => dispatchTeamDeletedAction(dispatch, contestId, props.team._id))
}
>
Delete
</Button>
</Col>
<Col md="auto">
<Button
variant="secondary"
disabled={
(name === props.team.name || name === undefined)
&& (image === props.team.image || image === undefined)
&& (color === props.team.anthem || color === undefined)
&& (anthem === props.team.anthem || anthem === undefined)
&& (editedPlayers == null)
}
onClick={(event: any) => {
patchTeam(
token,
contestId,
{
_id: props.team._id,
name: name,
anthem: anthem,
image: image,
players: players,
color
} as Store.ContestTeam
).then(team => dispatchTeamPatchedAction(dispatch, contestId, team))
}}
>Save</Button>
</Col>
</Row>
<Row>
<Col>
<TextField
inline
label="Anthem"
id={`${props.team._id}-anthem-editor`}
fallbackValue={props.team.anthem}
onChange={(_, newValue) => {
setPlayAnthem(false);
setAnthem(newValue);
return {
value: newValue,
isValid: true,
}
}}
/>
</Col>
<Col md="auto">
<Button onClick={() => teamAnthem?.length > 0 && setPlayAnthem(!playAnthem)}>
{playAnthem ? "Stop" : "Play"}
</Button>
</Col>
</Row>
<Row>
<Col>
<TextField
id={`team-${props.team._id}-color-editor`}
label="Color"
fallbackValue={color ?? props.team.color}
onChange={onColorChange}
inline
/>
</Col>
</Row>
<Row>
<PlayerSearch
excludedPlayerIds={(players ?? []).map(player => player._id)}
onSelect={(player) => setEditedPlayers([...(players ?? []), player])}
/>
</Row>
</Container>
}
</>
</Accordion.Collapse>
</Accordion>;
}