react-icons/bs#BsChevronCompactDown TypeScript Examples
The following examples show how to use
react-icons/bs#BsChevronCompactDown.
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: ArrowToggle.tsx From majsoul-api with MIT License | 6 votes |
ArrowToggle: React.FC<{
pointUp?: boolean
}> = ({pointUp}) => {
return <Container className={styles.arrow}>
{pointUp
? <BsChevronCompactUp color="white" size="30px" />
: <BsChevronCompactDown color="white" size="30px" />
}
</Container>
}
Example #2
Source File: Session.tsx From majsoul-api with MIT License | 4 votes |
export function Session(props: {
session: Rest.Session<string>;
forceDetails?: boolean;
}): JSX.Element {
const [viewDetails, setViewDetails] = React.useState(false);
const [gamesFetchedStatus, setGamesFetched] = React.useState(GamesFetchStatus.None);
const [sessionName, setSessionName] = React.useState(props?.session?.name);
const teams = useSelector((state: IState) => state.contestsById[props.session.contestId].teams);
const detailsOpen = viewDetails || props.forceDetails;
const { t } = useTranslation();
React.useEffect(() => {
setSessionName(props.session?.name);
}, [props.session?.name]);
const token = useSelector((state: IState) => state.user?.token);
const games = useSelector((state: IState) =>
Object.values(state.games ?? {})
.filter(game =>
game.sessionId === props.session?._id
&& game.contestId === props.session?.contestId
)
);
const orderedGames = React.useMemo(() => {
const numberOfMatches = props.session.plannedMatches.length;
const matchMap: Record<number, number> = {};
const indexedGames = games
.filter(game => token || !game.hidden)
.sort((a, b) => a.start_time - b.start_time)
.map((game) => {
const playerInfo = game.players.map(player => findPlayerInformation(player._id, teams));
const matchIndex = props.session.plannedMatches.map((match, index) => ({
index,
strength: match.teams.filter(team => playerInfo.find(player => player?.team?._id === team._id) != null).length,
})).sort((a, b) => b.strength - a.strength)[0]?.index ?? 0;
matchMap[matchIndex] ??= 0;
return {
...game,
matchIndex,
index: matchMap[matchIndex]++
}
});
const mostGames = Object.entries(matchMap)
.filter(([key]) => key !== "-1")
.reduce((prev, [, value]) => Math.max(prev, value), 0);
return indexedGames.reduce((total, next) => {
const index = next.matchIndex < 0
? mostGames * numberOfMatches + next.index
: next.index * numberOfMatches + next.matchIndex;
total[index] = next;
return total;
}
, new Array<Rest.GameResult<string>>(mostGames * numberOfMatches + (matchMap[-1] ?? 0)).fill(null))
}, [teams, games, token]);
const dispatch = useDispatch();
React.useEffect(() => {
setGamesFetched(GamesFetchStatus.None);
}, [props.session?._id]);
React.useEffect(() => {
if (!detailsOpen || gamesFetchedStatus !== GamesFetchStatus.None) {
return;
}
if (props.session?._id == null) {
return;
}
setGamesFetched(GamesFetchStatus.Fetching);
fetchGames({
sessionIds: [props.session._id],
contestIds: [props.session?.contestId],
}).then(games => {
setGamesFetched(GamesFetchStatus.Fetched);
dispatchGamesRetrievedAction(dispatch, games);
});
}, [props.session?._id, detailsOpen, gamesFetchedStatus]);
const onAccordionSelect = React.useCallback((accordionKey: string) => {
setViewDetails(accordionKey === "0");
}, [setViewDetails]);
const utcScheduledTime = React.useMemo(() => {
if (props.session?.scheduledTime == null) {
return dayjs().tz("UTC");
}
return dayjs(props.session.scheduledTime).tz("UTC");
}, [props.session?.scheduledTime]);
const utcStartMomentText = React.useMemo(() => utcScheduledTime.format("LT l z"), [utcScheduledTime]);
const hasStarted = React.useMemo(() => utcScheduledTime.isBefore(dayjs().tz("UTC")), [utcScheduledTime]);
const [editName, setEditName] = React.useState<string>();
const [utcMoment, setUtcMoment] = React.useState<string>();
const [timeIsInvalid, setTimeIsValid] = React.useState(!utcScheduledTime.isValid());
const [editTime, setEditTime] = React.useState(false);
if (props.session == null) {
return null;
}
const sessionState =
hasStarted
? gamesFetchedStatus === GamesFetchStatus.Fetched && games.length === 0
? SessionState.Current
: SessionState.Completed
: SessionState.Future
return <Container
fluid
className={clsx(
"rounded text-light",
sessionState === SessionState.Future
? styles.nextSession
: sessionState === SessionState.Completed
? styles.previousSession
: styles.currentSession
)}
>
<Row className="py-3 px-2">
<Col md="auto">
<Container>
<Row>
<Form.Control
plaintext={!token || !editTime}
readOnly={!token || !editTime}
isInvalid={timeIsInvalid}
className={`py-0${(!token || !editTime) ? " text-light" : ""}`}
value={`${utcMoment ?? utcStartMomentText}`}
onChange={event => {
setUtcMoment(event.target.value)
setTimeIsValid(!dayjs(event.target.value).isValid())
}}
onFocus={(event: any) => setEditTime(true)}
onBlur={(event: any) => {
if (timeIsInvalid) {
setUtcMoment(null)
} else {
setUtcMoment(dayjs(event.target.value).tz("UTC").format("LT l z"))
}
setEditTime(false);
}}
/>
</Row>
<Row>
{t("session.timeInZone", { time: dayjs(props.session.scheduledTime).calendar(), zone: dayjs.tz.guess() })}
</Row>
</Container>
</Col>
<Col className="text-right align-self-center">
<CountdownTimer targetTime={props.session.scheduledTime} prefix={sessionName}></CountdownTimer>
</Col>
</Row>
<Row>
<Col>
<Accordion
as={Container}
className="p-0"
onSelect={onAccordionSelect}
activeKey={detailsOpen ? "0" : null}
>
<Accordion.Collapse eventKey="0">
<Container className="p-0 pb-2">
{detailsOpen && <>
{props.session.plannedMatches?.length > 0 && <>
<Row className="no-gutters">
<Col className="px-2">
<div className="h5"><u>{t("session.matches")}</u></div>
</Col>
</Row>
<Row className="no-gutters">
{props.session.plannedMatches.map((match, index) => <Col key={index}>
<Match match={match} contestId={props.session.contestId} totals={hasStarted ? props.session.totals : null} aggregateTotals={props.session.aggregateTotals} />
</Col>)}
</Row>
</>}
{hasStarted && <>
<Row className="no-gutters">
<Col className="px-2">
<div className="h5"><u>{t("session.games")}</u></div>
</Col>
</Row>
<Row className="no-gutters">
{gamesFetchedStatus === GamesFetchStatus.Fetched
? games.length === 0
? <Col className="text-center">
<div className={clsx("h4 font-weight-bold m-0", props.forceDetails ? "pb-4" : "pb-1")}>未だ無し</div>
</Col>
: orderedGames.map((game, index) => <React.Fragment key={index}>
{game == null
? <Col style={{ minWidth: "auto" }} className="d-flex align-items-stretch">
<div
className={clsx(
"mt-5 mx-2 mb-3 rounded d-flex align-items-center justify-content-center",
sessionState === SessionState.Completed
? "bg-secondary"
: "bg-dark"
)}
style={{ flex: 1 }}
>
<div className="h4 font-weight-bold m-0">
試合未決
</div>
</div>
</Col>
: <Col style={{ minWidth: "auto" }}>
<GameResultSummary game={game} />
</Col>
}
{(index % 2 == 1) && <div className="w-100" />}
</React.Fragment>)
: <Col className="text-center pb-2">
<LoadingSpinner />
</Col>
}
</Row>
</>}
</>}
</Container>
</Accordion.Collapse>
{props.forceDetails || <Accordion.Toggle
disabled as={Row}
eventKey="0"
>
<Col className="text-center pb-1">
{
viewDetails
? <BsChevronCompactUp color="white" size="30px" />
: <BsChevronCompactDown color="white" size="30px" />
}
</Col>
</Accordion.Toggle>}
</Accordion>
</Col>
</Row>
{token &&
<Row className="pb-3 px-3 justify-content-end">
<Col>
<TextField
id={`${props.session._id}-name-editor`}
fallbackValue={editName ?? sessionName}
placeholder="Session Name"
onChange={(oldValue, newValue) => {
setEditName(newValue);
}}
/>
</Col>
<Col md="auto">
<Button
disabled={
(utcMoment == null || timeIsInvalid)
&& (editName === sessionName || editName === undefined)
}
variant="secondary"
onClick={() => patchSession(token, {
_id: props.session._id,
name: editName
}).then(session => {
if (session.name) {
setSessionName(session.name);
}
})}
>Save</Button>
</Col>
</Row>
}
</Container>;
}
Example #3
Source File: Teams.tsx From majsoul-api with MIT License | 4 votes |
export function Teams(props: {
isLoading?: boolean;
teamScores: Record<string, number>;
teamLimit?: number;
}): JSX.Element {
const { teamLimit = 8 } = props;
const token = useSelector((state: IState) => state.user?.token);
const dispatch = useDispatch();
const { contestId } = React.useContext(ContestContext);
const teams = useSelector((state: IState) => state.contestsById[contestId]?.teams ?? {});
const addTeamOnClick = React.useCallback(() => {
const id = contestId;
if (id == null) {
return;
}
createTeam(token, id).then(team => dispatchTeamCreatedAction(dispatch, id, team));
}, []);
const [viewDetails, setViewDetails] = React.useState(false);
const onAccordionSelect = React.useCallback((accordionKey: string) => {
setViewDetails(accordionKey === "0");
}, [setViewDetails]);
const {
teamScores = {},
} = props;
const teamsArray: TeamData[] =
Object.values(teams)
.filter(team => team._id in teamScores)
.map(team => ({ ...team, total: teamScores[team._id] }))
.sort((a, b) => b.total - a.total)
.map((team, placing) => ({ ...team, placing }));
const maxPlaceLength = jpNumeral(teamsArray.length).length;
if (props.isLoading) {
return <Container className="rounded bg-dark text-light px-3 py-4">
<Row>
<Col className="text-center">
<LoadingSpinner />
</Col>
</Row>
</Container>
}
return <Container className="rounded bg-dark text-light px-3 py-4">
<TeamList
maxPlaceLength={maxPlaceLength}
teams={teamsArray.slice(0, teamLimit)}
/>
{teamsArray.length > teamLimit && <Accordion
as={Container}
className="p-0"
onSelect={onAccordionSelect}
activeKey={viewDetails ? "0" : null}
>
<Accordion.Collapse eventKey="0">
<TeamList
maxPlaceLength={maxPlaceLength}
teams={teamsArray.slice(teamLimit)}
/>
</Accordion.Collapse>
<Accordion.Toggle
disabled as={Row}
eventKey="0"
>
<Col className="text-center pb-1">
{
viewDetails
? <BsChevronCompactUp color="white" size="30px" />
: <BsChevronCompactDown color="white" size="30px" />
}
</Col>
</Accordion.Toggle>
</Accordion>}
{token && <TeamRow>
<Button onClick={addTeamOnClick}>Add Team</Button>
</TeamRow>}
</Container>;
}