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 vote down vote up
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>&nbsp;
							<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>;
}