react-bootstrap#Badge JavaScript Examples

The following examples show how to use react-bootstrap#Badge. 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: RemainingStockBadge.js    From covid-19-mask-map with MIT License 6 votes vote down vote up
function RemainingStockBadge({ remainingStockStr }) {
    const { t } = useTranslation();
    let variant;
    let text;

    switch (remainingStockStr) {
        case "plenty":
            variant = "success";
            text = t("badge.plenty");
            break;
        case "some":
            variant = "warning";
            text = t("badge.some");
            break;
        case "few":
            variant = "danger";
            text = t("badge.few");
            break;
        case "empty":
            variant = "light";
            text = t("badge.empty");
            break;
        case "break":
            variant = "secondary";
            text = t("badge.break");
            break;
        default:
            variant = "light";
            text = "?";
    }
    return <Badge variant={variant}>{text}</Badge>;
}
Example #2
Source File: Navbar.js    From orca-ui with Apache License 2.0 6 votes vote down vote up
render() {
    return (
      <Navbar bg="dark" variant="dark" expand="lg">
        <Navbar.Brand href="/">
          <img src={logo} className="navbar-logo" alt="logo" />
          OpenRCA
        </Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="mr-auto">
            <Nav.Link href="/graph">Graph</Nav.Link>
            <Nav.Link href="/alerts">
                Alerts
              <Badge className="alertBadge" variant="danger" pill>{this.state.alertCount ? this.state.alertCount : null}</Badge>
            </Nav.Link>
          </Nav>
        </Navbar.Collapse>
      </Navbar>
    );
  }
Example #3
Source File: Room.js    From talk4free with MIT License 6 votes vote down vote up
render() {
    if (this.state.showModal) {
      return (
        <JoinRoomModal
          show={this.state.showModal}
          handleClose={this.showJoinRoomModal}
          lang={this.props.room.lang}
          level={this.props.room.lvl}
          sessionId={this.props.room.session_id}
          email={this.props.email}
          username={this.props.username}
          img={this.props.img}
          onUpdate={this.props.onUpdate}
        />
      );
    } else {
      return (
        <Col className="text-center room-box">
          <Row className="room-box-header">
            <p>
              <Badge variant="warning">{this.props.room.lang}</Badge>
              {this.props.room.lvl}
            </p>
          </Row>
          <Row className="room-box-body">
            <ParticipantsList participants={this.props.users} />
          </Row>
          <Row className="room-box-footer">
            <Button variant="primary" onClick={this.showJoinRoomModal}>
              <i className="material-icons">perm_phone_msg</i>Join now!
            </Button>
          </Row>
        </Col>
      );
    }
  }
Example #4
Source File: connectMeta.js    From RC4Community with Apache License 2.0 6 votes vote down vote up
ShowBalance = ({ balance, account }) => {
  return (
    <div>
      <div className={styles.account}>
        {WeiToEth(parseInt(balance, 16))} ETH
        <OverlayTrigger
          overlay={
            <Tooltip placement="right" id="tooltip-disabled">
              Account Id!
            </Tooltip>
          }
        >
          <Badge className={styles.pill} pill>
            {`${account.substr(0, 4)}...${account.substr(
              account.length - 4,
              account.length
            )}`}
          </Badge>
        </OverlayTrigger>
      </div>
    </div>
  );
}
Example #5
Source File: ShareRouteGroup.js    From viade_en1b with MIT License 5 votes vote down vote up
export function ShareRouteGroup(props) {
  const { userWebId, selectedRoute, shareRoute } = props;
  const [state, setState] = useState({ groups: [] });
  const groups = useGroups(userWebId);
  useEffect(() => {
    const checkedGroups = groups.map((group) => ({
      ...group,
      checked: false,
    }));
    setState({ ...state, groups: checkedGroups });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [groups]);

  const friendsForlist = () => state.groups;
  const handleClose = () => {};
  const handleOnSave = () => {
    let friendsToShare = [];
    state.groups.forEach((group) => {
      group.friends.forEach((friend) => {
        let f = { uri: friend, name: friend.split("//")[1].split("/")[0] };
        friendsToShare.push(f);
      });
    });
    shareRoute(selectedRoute, friendsToShare);
  };

  const handleOnClick = (key) => {
    let groups = deepClone(state.groups);
    let checked = [];
    checked = filterUnsharedFriends(groups, checked);
    let group = groups[key];
    group.checked = !group.checked;
    setState({ ...state, groups: checked });
  };
  const activeSelectedGroups = state.groups.filter((group) => group.checked)
    .length;
  const shareButtonText =
    activeSelectedGroups > 0 ? (
      <span data-testid="share-route-share-button-numbers">
        <FormattedMessage id="Share" />
        <Badge className={style.badge} color="secondary">
          <span data-testid="share-route-share-button-number">
            {activeSelectedGroups}
          </span>
        </Badge>
      </span>
    ) : (
      <span data-testid="share-route-share-button-plain">Share</span>
    );
  return (
    <div className={style.groupsContainer}>
      <ViadeModal
        data-testid="share-group-modal"
        onOpen={() => {}}
        disabled={groups.length === 0}
        saveDisabled={false}
        toggleText={<FormattedMessage id="ShareGroup" />}
        handleClose={handleClose}
        onSave={handleOnSave}
        title={
          <FormattedMessage
            data-testid="share-group-modal-title"
            id="ShareGroupModalTitle"
          />
        }
        closeText={<FormattedMessage id="Close" />}
        saveText={shareButtonText}
      >
        <FriendList
          data-testid="share-group-friend-list"
          onClick={handleOnClick}
          friends={friendsForlist()}
          style={{ container: style.friendsExpanded, card: style.cardExpanded }}
          checked
        ></FriendList>
      </ViadeModal>
    </div>
  );
}
Example #6
Source File: ProjectList.js    From portfolio-react with MIT License 5 votes vote down vote up
function ProjectList({ProjectListVal}) {
	return (
		<div>
			{ProjectListVal &&
				ProjectListVal.sort((a, b) => {
					if (a.title > b.title) return 1
					if (a.title < b.title) return -1
					return 0
				}).map((Obj, index) => {
					return (
						<a
							href={Obj.projectRoute}
							key={`project-list-item-${index}`}
							className='project_list_item_link'>
							<div
								style={{
									background:
										`linear-gradient(120deg,` +
										Obj.initialColor +
										`,` +
										Obj.finalColor +
										`)`,
								}}
								className='project_list_item'>
								<h3>
									{Obj.title}
									{Obj.githubUrl && (
										<a href={Obj.githubUrl}>
											<AiFillGithub className='projectGithubIcon' />
										</a>
									)}
								</h3>
								{Object.keys(Obj.badgeTitle).map((item, index) => {
									return (
										<Badge pill variant='primary' className='chip' key={index}>
											{Obj.badgeTitle[item]}
										</Badge>
									)
								})}
								<p>{Obj.description}</p>
							</div>
						</a>
					)
				})}
		</div>
	)
}
Example #7
Source File: bottom-nav.js    From tclone with MIT License 5 votes vote down vote up
function Nav() {
    let notifsCount = useSelector(selectUnread).length
    let { user: { screen_name } } = useSelector(state => state.auth)
    let list = [
        {
            name: "Home",
            href: "/home",
            icon: faHome
        },
        {
            name: "Explore",
            href: "/explore",
            icon: faSearch
        },
        {
            name: "Notifications",
            href: "/notifications",
            icon: faBell,
            count: notifsCount
        },
        {
            name: "Profile",
            href: `/user/${screen_name}`,
            icon: faUser,
        }
    ]
    let compose = {
        name: "Tweet",
        icon: faPlusCircle,
        href: '/compose/post',
        style: {
            right: '.5em',
            bottom: '4em',
            fontSize: '1.1em'
        }
    }
    return (
        <div className="fixed-bottom bg-white d-flex justify-content-around border">
            <Link style={compose.style} to={compose.href} className="btn btn-primary rounded-circle position-absolute">
                <FontAwesomeIcon className="" size="2x" icon={compose.icon} />
            </Link>
            {list.map(item => {
                let vis = item.disabled ? 'disabled' : ''
                let badge = item.count ? <><Badge className="position-absolute" variant="primary" style={{ top: 6, right: 6, left: 'unset' }}>{item.count}</Badge><span className="sr-only">new items</span></> : null
                return (<div key={item.name} className="d-flex align-items-top position-relative">
                    <NavLink
                        key={item.name}
                        to={item.href}
                        activeClassName="active"
                        className={`${vis} btn btn-naked-primary rounded-pill p-3`}
                    >
                        <FontAwesomeIcon
                            icon={item.icon}
                            size='lg'
                        />
                    </NavLink>
                    {badge}
                </div>)
            })}
        </div>
    )
}
Example #8
Source File: JoinRoomModal.js    From talk4free with MIT License 5 votes vote down vote up
render() {
    if (!this.state.joined) {
      return (
        <Modal show={this.props.show} onHide={this.handleClose}>
          <Modal.Header closeButton>
            <Modal.Title>
              {" "}
              <p>
                <Badge variant="warning">{this.props.lang}</Badge>
                {this.props.level}
              </p>
            </Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <p>Woohoo, you're aboout to join this call!</p>
          </Modal.Body>
          <Modal.Footer>
            <Button variant="secondary" onClick={this.props.handleClose}>
              Cancel
            </Button>
            <Button variant="primary" onClick={this.onSubmit}>
              Join Call
            </Button>
          </Modal.Footer>
        </Modal>
      );
    } else {
      return (
        <ModalVideo
          show={true}
          sessionId={this.props.sessionId}
          token={this.state.userToken}
          roomId={this.state.roomId}
          userId={this.state.userId}
          onUpdate={this.props.onUpdate}
          handleClose={this.handleClose}
          email={this.props.email}
          username2={this.props.username}
          img={this.props.img}
        />
      );
    }
  }
Example #9
Source File: index.js    From bootstrap-dsp with MIT License 5 votes vote down vote up
function HomePage() {
  return (
    <>
      <h1>React Bootstrap DSP for Adobe XD VSCode Extension</h1>
      <h4>Example heading <Badge variant="secondary">New</Badge></h4>
      <Button variant="primary">Primary Button</Button>
      <Card style={{ width: '18rem' }}>
        <Card.Img variant="top" src="holder.js/100px180" />
        <Card.Body>
          <Card.Title>Card Title</Card.Title>
          <Card.Text>
            Some quick example text to build on the card title and make up the bulk of
            the card's content.
          </Card.Text>
          <Button variant="primary">Go somewhere</Button>
        </Card.Body>
      </Card>
      <Form>
        <Form.Group controlId="exampleForm.ControlInput1">
          <Form.Label>Email address</Form.Label>
          <Form.Control type="email" placeholder="[email protected]" />
        </Form.Group>
      </Form>
      <Table striped bordered hover>
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Username</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>1</td>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
          </tr>
          <tr>
            <td>2</td>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
          </tr>
          <tr>
            <td>3</td>
            <td colSpan="2">Larry the Bird</td>
            <td>@twitter</td>
          </tr>
        </tbody>
      </Table>
    </>
  );
}
Example #10
Source File: tagSearchPage.js    From community-forum-frontend with GNU General Public License v3.0 5 votes vote down vote up
function TagSearchPage(props) {
  const {
    match: { params },
  } = props;
  const tagTopics = useSelector((state) => state.tag.search);
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(tagSearch({ _id: params.id}));
  }, params.id);

  if (tagTopics.isCompleted) {
    return (
      <Container fluid>
        <NavBar history={props.history} />
        <Container className="primary-container">
          <Row className="center-row">
            <Col>
              <h2 className="dashboard-category-name">
                Topics (Tag: {" "}
                <Badge
                  pill
                  variant=""
                  className="primary-big-tag"
                  style={{ backgroundColor: tagTopics.tag.hexColorCode }}
                >
                  {tagTopics.tag.name}
                </Badge>)
              </h2>
            </Col>
          </Row>
          <Row className="tag-page-topics-container">
            {tagTopics.topics.map((topic) => (
              <Col key={topic._id} md="6">
                <CategoryTopicCard
                  entityType="topic"
                  category={{ _id: topic.parentCategory }}
                  topic={topic}
                />
              </Col>
            ))}
          </Row>
        </Container>
      </Container>
    );
  } else {
    return null;
  }
}
Example #11
Source File: githubrepo.js    From RC4Community with Apache License 2.0 5 votes vote down vote up
GithubRepo = ({data}) => {
  return (

    <div
    className={`${styles.container} d-flex flex-wrap justify-content-center`}
    >
      <Col className={`${styles.column} py-2 px-3 m-2 rounded`}>
        <Row className={`${styles.item_container}`}>
          <NavLink href={data.html_url}>{data.full_name}</NavLink>
        </Row>
        <Row className="d-flex align-items-center">
          <Col xs="auto" className={`${styles.numbers}`}>
            <span className="me-2">
              <IssueIcon />
            </span>
            {data.open_issues_count}
          </Col>
          <Col xs="auto" className={`me-1 ${styles.numbers}`}>
            <span className="me-2">
              <StarIcon />
            </span>
            {data.stargazers_count}
          </Col>
          <Col xs="auto" className={`me-2 ${styles.numbers}`}>
            <span className="me-2">
              <ForkIcon />
            </span>
            {data.forks_count}
          </Col>
        </Row>
        {
          (Array.isArray(data.topics) && (data.topics.length > 0 )) && 
          (
            <Row className={`${styles.md_container} p-1 d-flex align-items-center justify-content-start`}>
              {data.topics.map((topic) => {
                return (<Col xs="auto" className={`m-0 px-1`}>
                <Badge pill bg="light" text="dark">
                  {topic}
                </Badge>
              </Col>)
              })}
            </Row>
          )
        }
        <Row className={`${styles.md_container} p-1`}>
          <span>
              {data.description}
          </span>
        </Row>
      </Col>
    </div>
  );
}
Example #12
Source File: MyProfile.js    From viade_en1b with MIT License 5 votes vote down vote up
/**
 * Component to show the user's profile
 * @param {*} props 
 */
export function MyProfile(props) {
  let email = props.userEmail ? <p>{props.userEmail}</p> : null;
  let emailLoading = props.loading === true ? <p>Loading...</p> : null;
  const { routes } = props;
  const {userWebId} = props;
  let own = getOwnRoutesNumber(routes, userWebId);
  let shared = getSharedRoutesNumber(routes, userWebId);

  return (
    <div id="generalComponent">
      <LoggedIn>
        <div id="card">
          <div id="image-cropper">
            <Image
              src="user.vcard_hasPhoto"
              defaultSrc="profile.svg"
              id="profilePicture"
            />
          </div>

          <div id="allData">
            <div id="profileData">
              <h1>
                <FormattedMessage id="Greetings" />,{" "}
                <b>
                  <Value src="user.name" />
                </b>
              </h1>

              {email}
              {emailLoading}
              <p>
                <Badge variant="dark">
                  {<Value src="user.vcard_role" /> ? (
                    <Value src="user.vcard_role" />
                  ) : (
                    <FormattedMessage id="CEO" />
                  )}
                </Badge>
              </p>
              <a href={useWebId()}>
                <FormattedMessage id="SolidProfile" />{" "}
                <BsBoxArrowUpRight></BsBoxArrowUpRight>
              </a>
            </div>
            <div id="profileData">
              <Button variant="primary">
                <FormattedMessage id="Routes" />
                <Badge variant="light">
                  {own}
                </Badge>
              </Button>
              <Button variant="primary">
                <FormattedMessage id="SharedRoutes" />{" "}
                <Badge variant="light">
                  {shared}
                </Badge>
              </Button>
            </div>
          </div>
          <FriendList friends={props.friends} id="friendList" />
        </div>
      </LoggedIn>
      <LoggedOut>
        <Redirect to="/"></Redirect>
      </LoggedOut>
    </div>
  );
}
Example #13
Source File: discussionPage.js    From community-forum-frontend with GNU General Public License v3.0 4 votes vote down vote up
render() {
    const {
      match: { params },
    } = this.props;
    return (
      <React.Fragment>
        <Container fluid>
          <NavBar history={this.props.history} />
          <Container className="primary-container discussion-container">
            <Row>
              <Col xs={12}>
                {Object.keys(this.props.topic).length !== 0 && (
                  <React.Fragment>
                    <h2 className="dashboard-category-name">
                      {(this.props.topic.isSelfArchived ||
                        this.props.topic.isArchived) && (
                        <ArchiveIcon
                          className="archive-icon"
                          data-tip="This topic had been archived"
                        />
                      )}
                      {this.props.topic.name}
                    </h2>
                    {(this.props.topic.createdBy._id ===
                      this.props.currentUser._id ||
                      this.props.currentUser.isModerator) && (
                      <React.Fragment>
                        <Link
                          className="anchor-text dashboard-anchor-text"
                          onClick={() => {
                            this.setState(handleModal("updateTopic", "open"));
                          }}
                        >
                          Edit
                        </Link>
                        <UpdateTopicModal
                          showModal={this.state.showUpdateTopicModal}
                          handleClose={() => {
                            this.setState(handleModal("updateTopic", "close"));
                          }}
                          handleShow={() => {
                            this.setState(handleModal("updateTopic", "open"));
                          }}
                          categoryId={params.categoryId}
                          topic={this.props.topic}
                          history={this.props.history}
                        />
                      </React.Fragment>
                    )}
                    <AnnouncementsModal
                      showModal={this.state.showAnnouncementsModal}
                      handleClose={() => {
                        this.setState(handleModal("announcements", "close"));
                      }}
                      announcements={this.props.topic.announcements}
                      removeAnnouncement={this.props.removeAnnouncement}
                      isLoggedIn={this.props.isLoggedIn}
                      currentUser={this.props.currentUser}
                      isTopicArchived={
                        this.props.topic.isArchived ||
                        this.props.topic.isSelfArchived
                      }
                    />
                    <h6 className="dashboard-category-creator">
                      <ReplyAllIcon />
                      Created By:{" "}
                      {this.props.topic.createdBy.isRemoved ||
                      this.props.topic.createdBy.isBlocked ? (
                        "Removed User"
                      ) : (
                        <Link
                          className="anchor-text"
                          to={`/profile/${this.props.topic.createdBy._id}`}
                        >
                          {this.props.topic.createdBy.name.firstName}
                        </Link>
                      )}
                    </h6>
                    {this.props.topic.tags.length !== 0 &&
                      this.props.topic.tags.map((tag) => (
                        <Badge
                          key={tag._id}
                          pill
                          variant=""
                          className="primary-tag"
                          style={{ backgroundColor: tag.hexColorCode }}
                        >
                          <Link to={`/tag/${tag._id}`}>{tag.name}</Link>
                        </Badge>
                      ))}
                    <h6 className="discussion-topic-description">
                      {this.props.topic.description}
                    </h6>
                    <h6 className="dashboard-category-date">
                      <TodayIcon />
                      Last Activity: {this.props.topic.updatedAt.slice(0, 10)}
                      &nbsp;
                      {this.props.topic.updatedAt.slice(11, 16)}
                    </h6>
                    <hr className="dashboard-main-separator" />
                  </React.Fragment>
                )}
              </Col>
            </Row>
            <Row className="center-row">
              {this.props.chats !== undefined &&
                this.props.chats.map((message) => (
                  <MessageCard
                    messageData={message}
                    isLoggedIn={this.props.isLoggedIn}
                    currentUser={this.props.currentUser}
                    turnAnnouncement={this.props.turnAnnouncement}
                    removeAnnouncement={this.props.removeAnnouncement}
                    deleteMessage={this.props.deleteMessage}
                    isTopicArchived={
                      this.props.topic.isArchived ||
                      this.props.topic.isSelfArchived
                    }
                  />
                ))}
            </Row>
          </Container>
        </Container>
        {this.props.isLoggedIn &&
        !this.props.topic.isArchived &&
        !this.props.topic.isSelfArchived ? (
          <div
            className="discussion-bottom-scroll"
            ref={(el) => {
              this.el = el;
            }}
          />
        ) : (
          <div
            ref={(el) => {
              this.el = el;
            }}
          />
        )}
        {this.props.isLoggedIn &&
          !this.props.topic.isArchived &&
          !this.props.topic.isSelfArchived && (
            <Container fluid className="discussion-message-input-container">
              <Container>
                <Row className="center-row discussion-message-input-row">
                  <Col>
                    <Form onSubmit={this.onMessageSubmit}>
                      <Form.Group controlId="addMessageBasicText1">
                        <Form.Control
                          onChange={this.onFieldChange}
                          type="text"
                          as="textarea"
                          rows={1}
                          placeholder={`Message in ${this.props.topic.name} discussion`}
                          name={fieldNames.MESSAGE_DESCRIPTION}
                          value={this.state.messageDescription}
                        />
                      </Form.Group>
                      <Row className="discussion-message-submit-button-container">
                        <Col>
                          <Button
                            variant=""
                            className="primary-button discussion-message-submit-button"
                            type="submit"
                            disabled={this.state.isFormInvalid}
                          >
                            Send
                          </Button>
                        </Col>
                      </Row>
                    </Form>
                  </Col>
                </Row>
              </Container>
            </Container>
          )}
      </React.Fragment>
    );
  }
Example #14
Source File: projects.js    From community-forum-frontend with GNU General Public License v3.0 4 votes vote down vote up
render() {
    return (
      <div>
        <Modal show={this.state.showModal} onHide={this.handleClose} centered>
          <div className="modalbody">
            <Modal.Body>
              <TopicForm
                projectID={this.state.projectID}
                handleTopicSubmission={this.handleTopicSubmission}
              />
            </Modal.Body>
          </div>
        </Modal>
        <DragDropContext onDragEnd={this.onDragEnd}>
          <div className="projectCards">
            {this.state.categoriesArray.map((categoryID) => {
              const category = this.state.categories[categoryID._id];
              return (
                <Card
                  className="projectCard"
                  bg="light"
                  style={{ width: "21rem" }}
                  key={category._id}
                >
                  <Card.Header color="#366FF0" className="projectcardheader">
                    {category.categoryName}
                  </Card.Header>
                  <Droppable droppableId={category._id}>
                    {(provided) => (
                      <div
                        className="cardcontent"
                        ref={provided.innerRef}
                        {...provided.droppableProps}
                      >
                        {category.topicIds.map((topicid, index) => {
                          const topic = this.state.Topics[topicid];
                          if (topic) {
                            return (
                              <Draggable draggableId={topic._id} index={index}>
                                {(provided) => (
                                  <Card
                                    onClick={() =>
                                      this.props.handleDiscussionTrue(topic)
                                    }
                                    key={topic._id}
                                    className="topicscard"
                                    {...provided.draggableProps}
                                    {...provided.dragHandleProps}
                                    ref={provided.innerRef}
                                  >
                                    <Card.Title className="topicsheading">
                                      {topic.topicName}
                                    </Card.Title>
                                    <Card.Text className="topicdescription">
                                      {topic.topicDescription}
                                    </Card.Text>
                                    <div>
                                      {topic.topicTags ? (
                                        topic.topicTags.map((k) => {
                                          return (
                                            <Badge
                                              variant="primary"
                                              className="tags"
                                            >
                                              {k}
                                            </Badge>
                                          );
                                        })
                                      ) : (
                                        <Badge variant="primary"></Badge>
                                      )}
                                    </div>
                                  </Card>
                                )}
                              </Draggable>
                            );
                          }
                        })}
                        {provided.placeholder}
                      </div>
                    )}
                  </Droppable>
                  <div
                    className="addnewcard"
                    onClick={() => this.handleShow(category._id)}
                  >
                    <IconContext.Provider
                      value={{
                        style: { verticalAlign: "middle" },
                        className: "reacticon",
                      }}
                    >
                      <FiPlus />
                    </IconContext.Provider>{" "}
                    Add another discussion
                  </div>
                </Card>
              );
            })}
          </div>
        </DragDropContext>
      </div>
    );
  }
Example #15
Source File: group-details.js    From what-front with MIT License 4 votes vote down vote up
GroupDetails = ({
  studentGroupData, studentsData, mentorsData, coursesData,
}) => {
  const {
    data: group,
    isLoading: isGroupLoading,
    isLoaded: isGroupLoaded,
  } = studentGroupData;
  const {
    data: students,
    isLoading: areStudentsLoading,
    isLoaded: areStudentsLoaded,
  } = studentsData;
  const {
    data: mentors,
    isLoading: areMentorsLoading,
    isLoaded: areMentorsLoaded,
  } = mentorsData;
  const {
    data: courses,
    isLoading: areCoursesLoading,
    loaded: areCoursesLoaded,
  } = coursesData;

  const history = useHistory();

  return (
    <div className="container pt-5">
      <div className="row justify-content-center">
        <div className="w-100 card shadow p-4">
          <WithLoading
            isLoading={isGroupLoading || !isGroupLoaded || areMentorsLoading || !areMentorsLoaded
            || areCoursesLoading || !areCoursesLoaded}
            className={styles['loader-centered']}
          >
            <div className="d-flex flex-row text-left justify-content-between">
              <div className="d-flex flex-column">
                <h2>
                  Group: {group.name}
                </h2>
                <p className="m-0">
                  { commonHelpers.transformDateTime({ isDayTime:false, dateTime: group.startDate }).date}
                  &nbsp;-&nbsp;
                  { commonHelpers.transformDateTime({ isDayTime:false, dateTime: group.finishDate }).date}
                </p>
              </div>
              <div className="pt-3">
                <Link to={`${paths.SCHEDULE_BY_GROUP_ID}/${group.id}`}>
                  <span className={styles['schedule-link']}>View schedule</span>
                </Link>
              </div>
            </div>
            <hr className="p-0" />
            <div className="d-flex mb-2">
              <h4 className="pr-2 mb-2">
                Mentors:
              </h4>
              <div className="d-flex flex-wrap">
                { mentors
                  .filter((mentor) => group.mentorIds?.includes(mentor.id))
                  .map((mentor) => (
                    <div className="pr-2 lead" key={mentor.id}>
                      <Badge pill variant="info">
                        <Link
                          to={`${paths.MENTORS_DETAILS}/${mentor.id}`}
                          className="text-decoration-none text-light"
                        >
                          {mentor.firstName} {mentor.lastName}
                        </Link>
                      </Badge>
                    </div>
                  )) }
              </div>
            </div>
            <div className="d-flex align-items-center mb-2 lead">
              <h4 className="mb-2 pr-4">Course:</h4>
              <Badge pill variant="info">
                <Link
                  to={`${paths.COURSE_DETAILS}/${group.courseId}`}
                  className="text-decoration-none text-white"
                >
                  {courses.find((course) => course.id === group.courseId)?.name }
                </Link>
              </Badge>
            </div>
            <h4 className="h4 my-2">
              Students:
            </h4>
            <WithLoading isLoading={areStudentsLoading || !areStudentsLoaded}>
              <Table bordered hover responsive>
                <thead>
                  <tr>
                    <th>â„–</th>
                    <th>Name</th>
                    <th>Email</th>
                  </tr>
                </thead>
                <tbody>
                  { students
                    .filter((student) => group.studentIds?.includes(student.id))
                    .map((student, index) => (
                      <tr
                        key={student.id}
                        onClick={() => history.push(`${paths.STUDENTS_DETAILS}/${student.id}`)}
                        className={styles['table-row']}
                      >
                        <td>{index + 1}</td>
                        <td>{student.firstName} {student.lastName}</td>
                        <td>{student.email}</td>
                      </tr>
                    )) }
                </tbody>
              </Table>
            </WithLoading>
          </WithLoading>
        </div>
      </div>
    </div>
  );
}
Example #16
Source File: lesson-details.js    From what-front with MIT License 4 votes vote down vote up
LessonDetails = () => {
  const history = useHistory();

  const { id } = useParams();

  const [studentsGroup, setStudentsGroup] = useState({});
  const [lesson, setLesson] = useState({});
  const [formData, setFormData] = useState([]);
  const [mentor, setMentor] = useState({});

  const [
    loadLessons,
    loadMentors,
    loadGroups,
    fetchStudents,
  ] = useActions([fetchLessons, fetchMentors, globalLoadStudentGroups, loadStudents]);

  const {
    data: lessons,
    isLoading: lessonsIsLoading,
    isLoaded: lessonsIsLoaded,
  } = useSelector(lessonsSelector, shallowEqual);

  const {
    data: mentors,
    isLoading: mentorsIsLoading,
    isLoaded: mentorsIsLoaded,
  } = useSelector(mentorsSelector, shallowEqual);

  const {
    data: groups,
    isLoading: groupsIsLoading,
    isLoaded: groupsIsLoaded,
  } = useSelector(loadStudentGroupsSelector, shallowEqual);

  const {
    data: students,
    isLoading: studentsIsLoading,
    isLoaded: studentsIsLoaded,
  } = useSelector(studentsSelector, shallowEqual);

  useEffect(() => {
    if(!lessonsIsLoaded) loadLessons();
    if(!studentsIsLoaded) fetchStudents();
    if(!groupsIsLoaded) loadGroups();
    if(!mentorsIsLoaded) loadMentors();
  }, [loadLessons, fetchStudents, loadGroups, loadMentors]);

  useEffect(() => {
    if (lessonsIsLoaded) {
      const lesson = lessons.find((lesson) => lesson.id === Number(id));
      if (!lesson) {
        history.push(paths.NOT_FOUND);
      } else {
        const {date, time} = commonHelpers.transformDateTime({ dateTime: lesson.lessonDate });
        const lessonsData = {
            lessonShortDate: date,
            lessonTime: time,
            ...lesson,
          };
        setLesson(lessonsData);
      }
    }
  }, [lessons]);

  const getFormData = () => {
    const uniqueIds = [...new Set(studentsGroup.studentIds)];
    const studentD = uniqueIds.map((id) => students.find((student) => student.id === id));

    const studentsData = studentD.map((student) => (
      {
        studentId: student.id,
        studentName: `${student.firstName} ${student.lastName}`,
      }
    ));

    const resultLessonVisits = studentsData.sort((a, b) => {
      if (a.studentName < b.studentName) {
        return -1;
      }
      if (a.studentName > b.studentName) {
        return 1;
      }
    })
      .map((student, index) => ({
        ...lesson.lessonVisits[index],
        ...student,
      }));

    setFormData(resultLessonVisits);
  };

  useEffect(() => {
    if (lesson && groups.length) {
      const group = groups?.find((group) => group.id === lesson.studentGroupId);

      if (group && studentsIsLoaded && !studentsIsLoading) {
        setStudentsGroup(group);
        if (studentsGroup && students) {
          getFormData();
        }
      }
    }
  }, [groups, students, studentsIsLoaded, studentsIsLoading, lesson, studentsGroup]);

  useEffect(() => {
    if (lesson && mentorsIsLoaded && !mentorsIsLoading) {
      const mentor = mentors?.find((mentor) => mentor.id === lesson.mentorId);
      if (mentor) {
        setMentor(mentor);
      }
    }
  }, [lesson, mentorsIsLoaded, !mentorsIsLoading]);

  useEffect(() => {
    if (!lessons && lessonsIsLoaded) {
      history.push(paths.NOT_FOUND);
    }
  }, [lessons, history, lessonsIsLoaded]);

  const openStudentDetails = useCallback((studentId) => {
    history.push(`${paths.STUDENTS_DETAILS}/${studentId}`);
  }, [history]);

  const handleCancel = useCallback(() => {
    history.push(paths.LESSONS);
  }, [history]);

  return (
    <div className="container pt-5">
      <div className={classNames(styles.page, 'mx-auto', 'col-12')}>
        <div className="d-flex flex-row">
          <WithLoading
            isLoading={lessonsIsLoading || mentorsIsLoading || groupsIsLoading
                || studentsIsLoading || !lesson || !formData.length}
            className={styles['loader-centered']}
          >
            <div className="col-6">
              <h3>Lesson details</h3>
              <hr />
              <div className="d-flex flex-row w-100">
                <div className="col-12">
                  <div className="mt-3 mb-4 row">
                    <div className="col-sm-6 font-weight-bolder"><span>Lesson Theme: </span></div>
                    <div className="col-sm-6"><span>{lesson?.themeName}</span></div>
                  </div>
                  <div className="row mb-4">
                    <div className="col-sm-6 font-weight-bolder d-flex align-items-center">
                      <span>Mentor name: </span>
                    </div>
                    <div className="col-sm-6 lead">
                      <Badge pill className={styles.bg_colour}>
                        <Link
                          to={`${paths.MENTORS_DETAILS}/${mentor.id}`}
                          className="text-decoration-none text-white"
                        >{`${mentor.firstName} ${mentor.lastName}`}
                        </Link>
                      </Badge>
                    </div>
                  </div>
                  <div className="row mb-4">
                    <div className="col-sm-6 font-weight-bolder d-flex align-items-center">
                      <span>Group name: </span>
                    </div>
                    <div className="col-sm-6 lead">
                      <Badge pill className={styles.bg_colour}>
                        <Link
                          to={`${paths.GROUPS_DETAILS}/${studentsGroup?.id}`}
                          className="text-decoration-none text-white"
                        >{studentsGroup?.name}
                        </Link>
                      </Badge>
                    </div>
                  </div>
                  <div className="row mb-4">
                    <div className="col-sm-6 font-weight-bolder">
                      <span>Lesson Date: </span>
                    </div>
                    <div className="col-sm-6">
                      {lesson?.lessonShortDate}
                    </div>
                  </div>
                  <div className="row">
                    <div className="col-sm-6 font-weight-bolder">
                      <span>Lesson Time: </span>
                    </div>
                    <div className="col-sm-6">
                      {lesson?.lessonTime}
                    </div>
                  </div>
                </div>
                <div className="col-lg-12">
                  <table className="table table-bordered table-hover">
                    <thead>
                      <tr>
                        <th scope="col" aria-label="first_col" />
                        <th scope="col">Full Student`s Name</th>
                        <th scope="col" className="text-center">Mark</th>
                        <th scope="col" className="text-center">Presence</th>
                      </tr>
                    </thead>
                    <tbody>
                      {formData.map((lessonVisit, index) => (
                        <tr key={lessonVisit.studentId}>
                          <th scope="row">{ index + 1 }</th>
                          <td>
                            <p
                            className={classNames(styles.link)}
                            onClick={() => openStudentDetails(lessonVisit.studentId)}
                          >
                            { lessonVisit.studentName }
                          </p>
                          </td>
                          <td className="text-center align-content-center">
                            <div>{lessonVisit.presence && lessonVisit.studentMark}</div>
                          </td>
                          <td className="text-center font-weight-bolder">
                            <span>{lessonVisit.presence ? <Icon icon="Present" /> : <Icon icon="Absent" />}</span>
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>
            </div>
          </WithLoading>
        </div>
        <div className="col-12 mt-3">
          <button
            form="form"
            type="button"
            className="btn btn-secondary btn-lg"
            onClick={handleCancel}
          >Cancel
          </button>
        </div>
      </div>
    </div>
  );
}
Example #17
Source File: mentor-details.js    From what-front with MIT License 4 votes vote down vote up
MentorDetails = ({ id }) => {
  const history = useHistory();
  const {
    data: mentor,
    isLoading: mentorIsLoading,
    isLoaded: mentorIsLoaded,
    error: mentorError
  } = useSelector(mentorIdSelector, shallowEqual);

  const {
    data: mentorGroups,
    isLoading: mentorGroupsAreLoading,
    isLoaded: mentorGroupsAreLoaded,
    error: mentorGroupsError
  } = useSelector(mentorGroupsSelector, shallowEqual);

  const {
    data: mentorCourses,
    isLoading:mentorCoursesAreLoading ,
    isLoaded: mentorCoursesAreLoaded,
    error: mentorCoursesError
  } = useSelector(mentorCoursesSelector, shallowEqual);

  const [
    dispatchLoadMentors,
  ] = useActions([fetchMentorById, fetchActiveMentors]); 

  useEffect(() => {
    if (mentorError && mentorCoursesError && mentorGroupsError) {
      history.push(paths.NOT_FOUND);
    }
  }, [mentorError, mentorCoursesError, mentorGroupsError, history]);

  useEffect(() => {
    dispatchLoadMentors(id);
  }, [dispatchLoadMentors, id]);

  return (
    <div className="container" data-testid='mentorDetails'>
      <div className="row justify-content-center">
        <div className="col-sm-12 card shadow">
          <div className="px-2 py-4">
            <h3>Mentor Details</h3>
            <hr />
            {/* test */}
            <WithLoading isLoading={mentorIsLoading || !mentorIsLoaded}
              className="d-block mx-auto m-0"
            >
              <div className="row">
                <span className="col-12 col-md-6 font-weight-bolder">First Name:</span>
                <span className="col-12 col-md-6" data-testid='firstName'>{mentor?.firstName}</span>
              </div>
              <hr />
              <div className="row">
                <span className="col-12 col-md-6 font-weight-bolder">Last Name:</span>
                <span className="col-12 col-md-6" data-testid='lastName'>{mentor?.lastName}</span>
              </div>
              <hr />
              <div className="row">
                <span className="col-12 col-md-6 font-weight-bolder">Email:</span>
                <span className="col-12 col-md-6" data-testid='email'>{mentor?.email}</span>
              </div>
              <hr />
            <div className="row">
              <div className="col-12 col-md-6 font-weight-bolder"><span>Group('s): </span></div>
              {/* test */}
              <WithLoading
                isLoading={mentorGroupsAreLoading || !mentorGroupsAreLoaded}
                className="d-block mx-auto m-0"
              >
                <div className="col-12 col-md-6 d-flex flex-wrap lead">
                  {mentorGroups
                    .map(({ id, name }) => (
                      <div className="pr-2" key={id}>
                        <Badge pill variant="info">
                          <Link
                            to={`${paths.GROUPS_DETAILS}/${id}`}
                            className="text-decoration-none text-light group-link"
                            data-testid='groupLink'
                            data-testgroupidparam={id}
                          >{name}
                          </Link>
                        </Badge>
                      </div>
                    ))}
                </div>
              </WithLoading>
            </div>
            <hr/>
            <div className="row">
              <div className="col-12 col-md-6 font-weight-bolder"><span>Course('s): </span></div>
              {/* test */}
              <WithLoading
                isLoading={mentorCoursesAreLoading || !mentorCoursesAreLoaded}
                className="d-block mx-auto m-0"
              >
                <div className="col-12 col-md-6 d-flex flex-wrap lead">
                  {mentorCourses
                    .map(({ id, name }) => (
                      <div className="pr-2" key={id}>
                        <Badge pill variant="info">
                          <Link
                            to={`${paths.COURSE_DETAILS}/${id}`}
                            className="text-decoration-none text-light course-link"
                            data-testid='courseLink'
                            data-testcourseidparam={id}
                          >{name}</Link>
                        </Badge>
                      </div>
                    ))}
                </div>
                </WithLoading>
              </div>
            </WithLoading>
          </div>
        </div>
      </div>
    </div>
  );
}
Example #18
Source File: schedule.js    From what-front with MIT License 4 votes vote down vote up
Schedule = ({ groupsData, schedulesData }) => {
  const { currentUser } = useSelector(currentUserSelector, shallowEqual);

  const {
    data: schedules,
    isLoading: areSchedulesLoading,
    isLoaded: areSchedulesLoaded,
  } = schedulesData;
  const {
    data: groups,
    isLoading: areGroupsLoading,
    isLoaded: areGroupsLoaded,
  } = groupsData;

  const [currentWeek, setCurrentWeek] = useState([]);
  const [chosenDate, setChosenDate] = useState(new Date());
  const [inputDateValue, setInputDateValue] = useState('');

  const history = useHistory();

  const DAY_IN_MILLIS = 86400000;
  const WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;

  useEffect(() => {
    const addZero = (num) => (num < 10 ? `0${num}` : num);

    if (areSchedulesLoaded && areGroupsLoaded) {
      const weekDayNames = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
      const firstDayOfWeek = new Date(chosenDate.getTime()
        - (chosenDate.getDay() - 1) * DAY_IN_MILLIS);

      const weekDays = weekDayNames.map((day, index) => {
        const currentDay = new Date(firstDayOfWeek.getTime() + index * DAY_IN_MILLIS);

        const lessons = schedules
          .filter((schedule) => schedule.dayNumber === index || schedule.repeatRate === 1)
          .sort((lesson, nextLesson) => (nextLesson.lessonStart < lesson.lessonStart ? 1 : -1));

        return {
          id: index,
          day,
          lessons,
          date: `${addZero(currentDay.getDate())}.${addZero(currentDay.getMonth() + 1)}`,
          isToday: new Date().toDateString() === currentDay.toDateString(),
          isPast: new Date(new Date().toDateString()).getTime() > currentDay.getTime(),
        };
      });

      setCurrentWeek(weekDays);
    }
  }, [areGroupsLoaded, areSchedulesLoaded, chosenDate, schedules, setCurrentWeek]);

  const handleNextWeek = () => {
    setChosenDate(new Date(chosenDate.getTime() + WEEK_IN_MILLIS));
  };

  const handlePreviousWeek = () => {
    setChosenDate(new Date(chosenDate.getTime() - WEEK_IN_MILLIS));
  };

  const handleInputDate = (event) => {
    setChosenDate(new Date(event.target.value));
    setInputDateValue(event.target.value);
  };

  const handleAddSchedule = () => {
    history.push(paths.SCHEDULE_ADD);
  };

  const handleSetToday = () => {
    const today = commonHelpers.transformDateTime({ isDayTime: false }).reverseDate;
    setChosenDate(new Date(today));
    setInputDateValue(today);
  };

  const handleEditSchedule = (id) => {
    console.log(id);
    history.push(`${paths.SCHEDULE_EDIT}/${id}`);
  };

  const handleGroupSchedule = useCallback((event) => {
    const { groupId } = event.target.dataset;
    history.push(`${paths.SCHEDULE_BY_GROUP_ID}/${groupId}`);
  }, [history]);

  return (
    <div className="container pt-5">
      <WithLoading isLoading={areGroupsLoading || areSchedulesLoading} className="d-block mx-auto">
        <div className="row ml-2 mr-2 mb-5">
          <div className="col-3 d-flex justify-content-start pl-0">
            <input
              type="date"
              min={`${new Date().getFullYear() - 1}-${new Date().getMonth() + 1}-${new Date().getDate()}`}
              max={`${new Date().getFullYear() + 1}-${new Date().getMonth() + 1}-${new Date().getDate()}`}
              onChange={handleInputDate}
              value={inputDateValue}
              className={styles['date-input']}
            />
            <Button
              className="ml-2"
              variant="info"
              onClick={handleSetToday}
            >
              Today
            </Button>
          </div>
          <div className="col-6 d-flex justify-content-center">
            <button
              type="button"
              className={styles['change-week-btn']}
              onClick={handlePreviousWeek}
            >
              <Icon icon="Arrow" className={classNames(styles.arrow, styles['arrow-left'])} />
            </button>
            <h4 className="mb-0">{currentWeek[0]?.date} - {currentWeek[currentWeek.length - 1]?.date}</h4>
            <button
              type="button"
              className={styles['change-week-btn']}
              onClick={handleNextWeek}
            >
              <Icon icon="Arrow" className={styles.arrow} />
            </button>
          </div>
          {[8, 4].includes(currentUser.role) ? (
            <div className="col-3 d-flex justify-content-end pr-0">
              <Button variant="info" onClick={handleAddSchedule}>
                Add schedule
              </Button>
            </div>
          ) : null}
        </div>
        <section className={classNames('row', 'justify-content-center')}>
          { currentWeek.map(({ id, isToday, day, date, lessons, isPast }) => (
            <div key={id} className={classNames('col', 'px-0', { [styles['current-day']]: isToday }, styles['day-column'])}>
              <hgroup className={styles['day-column-header']}>
                <h5 className="text-center">{day}</h5>
                <h5 className="text-center">{date}</h5>
              </hgroup>
              <ul className={styles['lessons-list']}>
                { lessons.map(({ id: lessonId, studentGroupId, eventStart, eventFinish, lessonEnd, lessonStart }) => (
                  <li key={lessonId} className={styles['lessons-list__item']}>
                    <p
                      className={styles['lessons-list__group-name']}
                      onClick={handleGroupSchedule}
                      data-group-id={studentGroupId}
                    >
                      { Array.isArray(groups)
                        ? groups.find((group) => studentGroupId === group.id).name
                        : groups.name }
                    </p>
                    <div className={styles['lessons-list__details']}>
                      <Badge
                        variant={classNames(
                          { info: isToday },
                          { secondary: isPast && !isToday },
                        )}
                        className={classNames({ [styles['future-lesson']]: !isToday && !isPast })}
                      >
                        {/* {lessonStart.substring(0, 5)} - {lessonEnd.substring(0, 5)} */}
                        {new Date(eventStart).toLocaleTimeString()} - {new Date(eventFinish).toLocaleTimeString()}
                      </Badge>
                      {[8, 4].includes(currentUser.role) ? (
                        <button
                          type="button"
                          className={styles['edit-button']}
                          onClick={() => handleEditSchedule(lessonId)}
                        >
                          <Icon icon="Edit" size={24} />
                        </button>
                      ) : null}
                    </div>
                  </li>
                )) }
              </ul>
            </div>
          )) }
        </section>
      </WithLoading>
    </div>
  );
}
Example #19
Source File: schedule.js    From what-front with MIT License 4 votes vote down vote up
Schedule = () => {
  const [
    dispatchFetchSchedules,
    dispatchFetchGroups,
  ] = useActions([fetchSchedules, globalLoadStudentGroups]);

  const { currentUser } = useSelector(currentUserSelector, shallowEqual);

  const {
    data: schedules,
    isLoading: areSchedulesLoading,
    isLoaded: areSchedulesLoaded,
  } = useSelector(schedulesSelector, shallowEqual);
  const {
    data: groups,
    isLoading: areGroupsLoading,
    isLoaded: areGroupsLoaded,
  } = useSelector(loadStudentGroupsSelector, shallowEqual);

  const [currentWeek, setCurrentWeek] = useState([]);
  const [chosenDate, setChosenDate] = useState(new Date());

  const history = useHistory();

  const DAY_IN_MILLIS = 86400000;
  const WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;

  useEffect(() => {
    dispatchFetchSchedules();
    dispatchFetchGroups();
  }, [dispatchFetchSchedules, dispatchFetchGroups]);

  useEffect(() => {
    const addZero = (num) => (num < 10 ? `0${num}` : num);

    if (areSchedulesLoaded && areGroupsLoaded) {
      const weekDayNames = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
      const firstDayOfWeek = new Date(chosenDate.getTime()
        - (chosenDate.getDay() - 1) * DAY_IN_MILLIS);

      const weekDays = weekDayNames.map((day, index) => {
        const currentDay = new Date(firstDayOfWeek.getTime() + index * DAY_IN_MILLIS);

        const lessons = schedules
          .filter((schedule) => schedule.dayNumber === index || schedule.repeatRate === 1)
          .sort((lesson, nextLesson) => (nextLesson.lessonStart < lesson.lessonStart ? 1 : -1));

        return {
          id: index,
          day,
          lessons,
          date: `${addZero(currentDay.getDate())}.${addZero(currentDay.getMonth() + 1)}`,
          isToday: new Date().toDateString() === currentDay.toDateString(),
          isPast: new Date(new Date().toDateString()).getTime() > currentDay.getTime(),
        };
      });

      setCurrentWeek(weekDays);
    }
  }, [areGroupsLoaded, areSchedulesLoaded, chosenDate, schedules, setCurrentWeek]);

  const handleNextWeek = () => {
    setChosenDate(new Date(chosenDate.getTime() + WEEK_IN_MILLIS));
  };

  const handlePreviousWeek = () => {
    setChosenDate(new Date(chosenDate.getTime() - WEEK_IN_MILLIS));
  };

  const handleInputDate = (event) => {
    setChosenDate(new Date(event.target.value));
  };

  const handleEditSchedule = (id) => {
    history.push(`${paths.SCHEDULE_EDIT}/${id}`);
  };

  const handleAddSchedule = () => {
    history.push(paths.SCHEDULE_ADD);
  };

  return (
    <div className="container">
      <WithLoading isLoading={areGroupsLoading || areSchedulesLoading} className="d-block mx-auto">
        <div className="row mb-4">
          <div className="col-3 d-flex justify-content-start pl-0">
            <input
              type="date"
              min={`${new Date().getFullYear() - 1}-${new Date().getMonth() + 1}-${new Date().getDate()}`}
              max={`${new Date().getFullYear() + 1}-${new Date().getMonth() + 1}-${new Date().getDate()}`}
              onChange={handleInputDate}
              className={styles['date-input']}
            />
            <Button
              className="ml-2"
              variant="warning"
              onClick={() => setChosenDate(new Date())}
            >
              Today
            </Button>
          </div>
          <div className="col-6 d-flex justify-content-center">
            <button
              type="button"
              className={styles['change-week-btn']}
              onClick={handlePreviousWeek}
            >
              <Icon icon="Arrow" className={classNames(styles.arrow, styles['arrow-left'])} />
            </button>
            <h4 className="mb-0">{currentWeek[0]?.date} - {currentWeek[currentWeek.length - 1]?.date}</h4>
            <button
              type="button"
              className={styles['change-week-btn']}
              onClick={handleNextWeek}
            >
              <Icon icon="Arrow" className={styles.arrow} />
            </button>
          </div>
          {[3, 4].includes(currentUser.role) ? (
            <div className="col-3 d-flex justify-content-end pr-0">
              <Button variant="warning" onClick={handleAddSchedule}>
                <Icon icon="Plus" className="icon" />
                Add schedule
              </Button>
            </div>
          ) : null}
        </div>
        <section className={classNames('row', 'justify-content-center')}>
          { currentWeek.map(({ id, isToday, day, date, lessons, isPast }) => (
            <div key={id} className={classNames('col', 'px-0', { [styles['current-day']]: isToday }, styles['day-column'])}>
              <hgroup className={styles['day-column-header']}>
                <h5 className="text-center">{day}</h5>
                <h5 className="text-center">{date}</h5>
              </hgroup>
              <ul className={styles['lessons-list']}>
                { lessons.map(({ id: lessonId, studentGroupId, lessonEnd, lessonStart }) => (
                  <li key={lessonId} className={styles['lessons-list__item']}>
                    <p className={styles['lessons-list__group-name']}>
                      {groups.find((group) => studentGroupId === group.id).name}
                    </p>
                    <div className={styles['lessons-list__details']}>
                      <Badge
                        variant={classNames(
                          { primary: isToday },
                          { secondary: isPast && !isToday },
                          { warning: !isToday && !isPast },
                        )}
                      >
                        {lessonStart.substring(0, 5)} - {lessonEnd.substring(0, 5)}
                      </Badge>
                      {[3, 4].includes(currentUser.role) ? (
                        <button
                          type="button"
                          className={styles['edit-button']}
                          onClick={() => handleEditSchedule(lessonId)}
                        >
                          <Icon icon="Edit" viewBox="0 0 45 45" size={20} />
                        </button>
                      ) : null}
                    </div>
                  </li>
                )) }
              </ul>
            </div>
          )) }
        </section>
      </WithLoading>
    </div>
  );
}
Example #20
Source File: student-details.js    From what-front with MIT License 4 votes vote down vote up
StudentDetails = () => {
  const history = useHistory();
  const {
    data: student,
    isLoading: isStudentLoading,
    isLoaded: isStudentLoaded,
    error: studentError,
  } = useSelector(currentStudentSelector, shallowEqual);
  
  const {
      data: studentGroups,
      isLoading: areStudentGroupsLoading,
    } = useSelector(currentStudentGroupsSelector, shallowEqual);
    
    const {
      data: studentLessons,
      isLoading: studentLessonsIsLoading,
      isLoaded: studentLessonsIsLoaded,
    } = useSelector(studentLessonsSelector, shallowEqual);

  useEffect(() => {
    if (studentError && !isStudentLoading) {
      history.push(paths.NOT_FOUND);
    }
  }, [history, isStudentLoading, studentError]);

  return (
    <div className="container">
      <div className="row justify-content-center">
        <div className="col-md-12 col-sm-12 card shadow">
          <div className="px-2 py-4">
            <h3>Student Details</h3>
            <hr />
            <WithLoading
              isLoading={isStudentLoading || !isStudentLoaded}
              className={styles['loader-centered']}
            >
              <div className="row">
                <div className="col-12 col-md-6 font-weight-bolder"><span>First name: </span></div>
                <div className="col-12 col-md-6"><span data-testid='firstName'>{student?.firstName}</span></div>
              </div>
              <hr />
              <div className="row">
                <div className="col-12 col-md-6 font-weight-bolder"><span>Last name: </span></div>
                <div className="col-12 col-md-6 "><span data-testid='lastName'>{student?.lastName}</span></div>
              </div>
              <hr />
              <div className="row">
                <div className="col-12 col-md-6 font-weight-bolder"><span>Email: </span></div>
                <div className="col-12 col-md-6 "><span data-testid='email'>{student?.email}</span></div>
              </div>
              <hr />
              <div className="row">
                <div className="col-12 col-md-6 font-weight-bolder"><span>Group(s): </span></div>
                <WithLoading
                  isLoading={areStudentGroupsLoading}
                  className={styles['loader-centered']}
                >
                  <div className="col-12 col-md-6 d-flex flex-wrap lead">
                    {studentGroups
                      .map(({ id, name }) => (
                        <div className="pr-2" key={id}>
                          <Badge pill variant="info">
                            <Link
                              to={`${paths.GROUPS_DETAILS}/${id}`}
                              className="text-decoration-none text-white"
                              data-testid='groupLink'
                              data-testgroupidparam={id}
                            >{name}
                            </Link>
                          </Badge>
                        </div>
                      ))}
                  </div>
                </WithLoading>
              </div>
              <hr />
              <div className="row">
                <div className="col-12 col-md-6 font-weight-bolder"><span>Lesson(s): </span></div>
                <WithLoading
                  isLoading={studentLessonsIsLoading || !studentLessonsIsLoaded}
                  className={styles['loader-centered']}
                >
                  <div className="col-12 col-md-6 d-flex flex-wrap lead">
                    {studentLessons
                      .map(({ id, themeName }) => (
                        <div className="pr-2" key={id}>
                          <Badge pill variant="info">
                            <Link
                              to={`${paths.LESSON_DETAILS}/${id}`}
                              className="text-decoration-none text-white"
                              data-testid='lessonLink'
                              data-testlessonidparam={id}
                            >{themeName}
                            </Link>
                          </Badge>
                        </div>
                      ))}
                  </div>
                </WithLoading>
              </div>
            </WithLoading>
          </div>
        </div>
      </div>
    </div>
  );
}
Example #21
Source File: categoryTopicCard.js    From community-forum-frontend with GNU General Public License v3.0 4 votes vote down vote up
function CategoryTopicCard(props) {
  const {
    entityType,
    category,
    topic
  } = props;
  let linkValue, entity;
  switch (entityType) {
    case "category": {
      linkValue = `/category/${category._id}`
      entity = category;
      break;
    }
    case "topic": {
      linkValue = `/category/${category._id}/topic/${topic._id}`;
      entity = topic;
      break;
    }
    default: {
      console.log(`Invalid entity type: ${entityType}`)
      break;
    }
  }
  return (
    <React.Fragment>
      <Link className="common-card-link" to={linkValue}>
        <div className="common-card-container">
          <Row>
            <Col md={10}>
              <Row>
                {entity.isArchived && (
                  <ArchiveIcon className="common-card-icon" />
                )}
                {!entity.isArchived &&
                  (entityType === "category" ? (
                    <ForumRoundedIcon className="common-card-icon" />
                  ) : (
                    <NotesRoundedIcon className="common-card-icon" />
                  ))}
                <h3 className="common-card-heading">{entity.name}</h3>
              </Row>
              {entityType === "topic" && (
                <Row>
                  {entity.tags.length !== 0 &&
                    entity.tags.map((tag) => (
                      <Badge
                        key={tag._id}
                        pill
                        variant=""
                        className="primary-tag"
                        style={{ backgroundColor: tag.hexColorCode }}
                      >
                        <Link to={`/tag/${tag._id}`}>{tag.name}</Link>
                      </Badge>
                    ))}
                </Row>
              )}
              <Row>
                <h6 className="common-card-description">
                  {entity.description}
                </h6>
              </Row>
            </Col>
            <Col md={2}>
              <div className="common-card-count-container">
                {entityType === "category" ? (
                  <React.Fragment>
                    <BubbleChartRoundedIcon />
                    <h6>{entity.topics.length}</h6>
                  </React.Fragment>
                ) : (
                  <React.Fragment>
                    <ChatBubbleOutlineRoundedIcon />
                    <h6>{entity.chats.length}</h6>
                  </React.Fragment>
                )}
              </div>
            </Col>
          </Row>
        </div>
      </Link>
    </React.Fragment>
  );
}
Example #22
Source File: PlayerStats.jsx    From ashteki with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
        let t = this.props.t;
        let userStyle = {};
        if (this.props.user?.faveColor) {
            userStyle.color = this.props.user.faveColor;
        }
        let userClass = 'username' + (this.props.user.role ? ` ${this.props.user.role.toLowerCase()}-role` : '');

        let playerAvatar = (
            <div className='state'>
                <Avatar imgPath={this.props.user?.avatar} />
                <b className={userClass} style={userStyle}>{this.props.user?.username || t('Noone')}</b>
            </div>
        );

        let statsClass = classNames('panel player-stats', {
            'active-player': this.props.activePlayer
        });

        let firstPlayerToken = this.props.firstPlayer ? (
            <div className='state'>
                <img src={FirstPlayerImage} title='First Player' />
            </div>
        ) : (
            ''
        );

        return (
            <div className={statsClass}>
                {playerAvatar}
                {this.renderLifeRemaining()}
                {this.renderActions()}
                {firstPlayerToken}
                {this.props.activePlayer && (
                    <div className='state first-player-state'>
                        <Trans>Active Player</Trans>
                    </div>
                )}

                {this.props.showMessages && (
                    <div className='state chat-status'>
                        <div className='state'>
                            <a href='#' className='pr-1 pl-1' title='Show dice/card history'>
                                <FontAwesomeIcon
                                    icon={faHistory}
                                    onClick={this.props.onDiceHistoryClick}
                                ></FontAwesomeIcon>
                            </a>
                        </div>
                        <div className='state'>
                            <a href='#' className='pr-1 pl-1' title='Mute spectators'>
                                <FontAwesomeIcon
                                    icon={this.props.muteSpectators ? faEyeSlash : faEye}
                                    onClick={this.props.onMuteClick}
                                ></FontAwesomeIcon>
                            </a>
                        </div>
                        {this.props.showManualMode && (
                            <div className='state'>
                                <a
                                    href='#'
                                    className={this.props.manualModeEnabled ? 'text-danger' : ''}
                                    onClick={this.props.onManualModeClick}
                                >
                                    <FontAwesomeIcon icon={faWrench}></FontAwesomeIcon>
                                    <span className='ml-1'>
                                        <Trans>Manual Mode</Trans>
                                    </span>
                                </a>&nbsp;
                                <a href='#' className='pr-1 pl-1' title='Show manual command list'>
                                    <FontAwesomeIcon
                                        icon={faList}
                                        onClick={this.props.onManualCommandsClick}
                                    />
                                </a>
                            </div>
                        )}
                        <div className='state'>
                            <a
                                href='#'
                                onClick={this.onSettingsClick.bind(this)}
                                className='pr-1 pl-1'
                            >
                                <FontAwesomeIcon icon={faCogs}></FontAwesomeIcon>
                                <span className='ml-1'>
                                    <Trans>Settings</Trans>
                                </span>
                            </a>
                        </div>
                        <div className='state'>
                            <a href='#' className='pr-1 pl-1' title='Copy chat to clipboard'>
                                <FontAwesomeIcon
                                    icon={faCopy}
                                    onClick={this.writeChatToClipboard.bind(this)}
                                ></FontAwesomeIcon>
                            </a>
                        </div>
                        <div>
                            <a
                                href='#'
                                onClick={this.props.onMessagesClick}
                                className='pl-1'
                                title='Toggle chat'
                            >
                                <FontAwesomeIcon icon={faComment}></FontAwesomeIcon>
                                {this.props.numMessages > 0 && (
                                    <Badge variant='danger'>{this.props.numMessages}</Badge>
                                )}
                            </a>
                        </div>
                    </div>
                )}
            </div>
        );
    }
Example #23
Source File: index.js    From tclone with MIT License 4 votes vote down vote up
function Header(props) {
    let notifsCount = useSelector(selectUnread).length
    let { user: { screen_name } } = useSelector(state => state.auth)
    let logo = {
        href: "/home",
    }
    let compose = {
        name: "Post",
        icon: faPlusCircle
    }
    let list = [
        {
            name: "Home",
            href: "/home",
            icon: faHome
        },
        {
            name: "Explore",
            href: "/explore",
            icon: faHashtag
        },
        {
            name: "Profile",
            href: `/user/${screen_name}`,
            icon: faUser,
        },
        {
            name: "Notifications",
            href: "/notifications",
            icon: faBell,
            count: notifsCount
        },
        // {
        //     name: "Chat Room",
        //     href: "/chats",
        //     icon: faComments
        // },
        {
            name: "Settings",
            href: "/settings",
            icon: faEllipsisH
        },
        {
            name: "Messages",
            href: "/messages",
            icon: faEnvelope,
            disabled: true
        },

    ]
    return (
        <Col className="d-flex flex-column align-items-end vh-100 overflow-y-auto mr-sm-n3 mr-md-0 mr-xl-3 hide-scroll">
            <div className="my-2 mr-xl-auto ml-xl-4">
                <Link
                    className='btn text-primary btn-naked-primary rounded-circle p-2'
                    to={logo.href}>
                    {/* <FontAwesomeIcon size="2x" icon={logo.icon} /> */}
                    <img className="rounded-circle" height="45" width="45" src="/android-chrome-192x192.png" alt="logo" />
                </Link>
            </div>
            <div className="ml-0 d-flex flex-column mb-2 align-items-start">
                {list.map(itm => {
                    let vis = itm.disabled ? "disabled" : ""
                    let badge = itm.count ? <><Badge className="position-absolute" variant="primary" style={{ top: 5, right: 5, left: 'unset' }}>{itm.count}</Badge><span className="sr-only">new items</span></> : null
                    return (<div key={itm.name} className="d-flex align-items-top position-relative">
                        <NavLink
                            to={itm.href}
                            className={`${vis} px-xl-2 py-xl-1 p-1 mb-2 mx-lg-0 mx-auto btn btn-naked-primary rounded-pill font-weight-bold btn-lg d-flex align-items-center`}
                            activeClassName="active"
                        >
                            <FontAwesomeIcon className="m-2" size="lg" icon={itm.icon} />
                            <span className="d-none d-xl-block mr-2">{itm.name}</span>
                        </NavLink>
                        {badge}
                    </div>)
                })}
            </div>

            <Link className="d-flex btn btn-primary font-weight-bold p-xl-3 rounded-pill" id="compose" to="/compose/post">
                <span className="d-none d-xl-block mx-auto px-5">{compose.name}</span>
                <FontAwesomeIcon className="d-xl-none mx-auto" size="2x" icon={compose.icon} />
            </Link>
        </Col >
    )
}
Example #24
Source File: Groups.js    From viade_en1b with MIT License 4 votes vote down vote up
export function Groups(props) {
  const [state, setState] = useState({ friends: [], groupName: "" });
  useEffect(() => {
    const checkedFriends = props.friends.map((friend) => ({
      ...friend,
      checked: false,
    }));

    setState({ ...state, friends: checkedFriends });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [props.friends]);
  const friendsForlist = () => state.friends;
  const handleClose = () => {};
  const handleOnSave = () => {
    let groupFriends = state.friends
      .filter((friend) => friend.checked)
      .map((friend) => friend.uri);
    createGroup(props.userWebId, state.groupName, groupFriends);
  };
  const handleOnClick = (key) => {
    let friends = deepClone(state.friends);
    let checked = [];
    checked = filterUnsharedFriends(friends, checked);
    let friend = friends[key];
    friend.checked = !friend.checked;
    setState({ ...state, friends: checked });
  };
  const activeSelectedFriends = state.friends.filter((friend) => friend.checked)
    .length;
  const shareButtonText =
    activeSelectedFriends > 0 ? (
      <span data-testid="share-route-share-button-numbers">
        <FormattedMessage id="CreateGroup" />
        <Badge className={style.badge} color="secondary">
          <span data-testid="share-route-share-button-number">
            {activeSelectedFriends}
          </span>
        </Badge>
      </span>
    ) : (
      <span data-testid="share-route-share-button-plain">
        <FormattedMessage id="CreateGroup" />
      </span>
    );
  const changeHandlerGroupName = (e) => {
    setState({ ...state, groupName: e.target.value });
  };

  return (
    <div className={style.groupsContainer}>
      <GroupList userWebId={props.userWebId}></GroupList>
      <ViadeModal
        data-testid="create-group-modal"
        onOpen={() => {}}
        disabled={false}
        saveDisabled={false}
        toggleText={<FormattedMessage id="CreateGroup" />}
        handleClose={handleClose}
        onSave={handleOnSave}
        title={
          <FormattedMessage
            data-testid="create-group-modal-title"
            id="CreateGroupModalTitle"
          />
        }
        closeText={<FormattedMessage id="Close" />}
        saveText={shareButtonText}
      >
        <Form className={style.form}>
          <Form.Group>
            <FormattedMessage id="CreateGroupFormPlaceholder">
              {(placeholder) => (
                <Form.Control
                  value={state.groupName}
                  onChange={changeHandlerGroupName}
                  type="text"
                  placeholder={placeholder}
                />
              )}
            </FormattedMessage>
          </Form.Group>
        </Form>
        <FriendList
          data-testid="create-group-friend-list"
          onClick={handleOnClick}
          friends={friendsForlist()}
          style={{ container: style.friendsExpanded, card: style.cardExpanded }}
          checked
        ></FriendList>
      </ViadeModal>
    </div>
  );
}
Example #25
Source File: ShareRoute.js    From viade_en1b with MIT License 4 votes vote down vote up
/**
 * Component to share routes with your solid friends
 * @param {*} props 
 */
export function ShareRoute(props) {
  const { selectedRoute, shareRoute, userWebId } = props;
  const friendsToShow = (sharedWith) =>
    filterUnsharedFriends(props.friends, sharedWith).map((friend) => ({
      ...friend,
      checked: false,
    }));
  const alreadySharedWith = deepClone(props.sharedWith);

  const [state, setState] = useState({
    friends: filterUnsharedFriends(
      props.friends,
      props.sharedWith
    ).map((friend) => ({ ...friend, checked: false })),
    friendsToShareWith: alreadySharedWith.map((friend) => ({
      ...friend,
      checked: false,
    })),
    shared: false,
  });

  useEffect(() => {
    setState({
      ...state,
      friends: friendsToShow(props.sharedWith),
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [props.sharedWith]);

  const friendsForList = () => {
    return state.friends;
  };
  const handleOnSave = async () => {
    shareRoute(selectedRoute, state.friendsToShareWith || []);
    setTimeout(async () => {
      props.clearRoute();
      props.loadRoutes();
    }, 1000);
  };

  const handleClose = () => {
    if (!state.shared) {
      let uncheckedFriends = state.friends.map((friend) => ({
        ...friend,
        checked: false,
      }));
      setState({ ...state, friends: uncheckedFriends, friendsToShareWith: [] });
    }
  };

  const checkAuthority = () => {
    let username = userWebId.split("//")[1].split("/")[0];
    return selectedRoute.author === username;
  };

  const handleOnClick = (key) => {
    state.friends[key].checked = !state.friends[key].checked;
    let shared = deepClone(state.friendsToShareWith);
    let friends = deepClone(state.friends);
    if (friends[key].checked) {
      let f = friends[key];
      shared.push(f);
    } else {
      shared.pop(key);
    }
    setState({ ...state, friendsToShareWith: shared, friends: friends });
  };
  let activeSelectedFriends = state.friendsToShareWith.filter(
    (friend) => friend.checked
  ).length;
  const shareButtonText =
    activeSelectedFriends > 0 ? (
      <span data-testid="share-route-share-button-numbers">
        <FormattedMessage id="Share" />
        <Badge className={style.badge} color="secondary">
          <span data-testid="share-route-share-button-number">
            {activeSelectedFriends}
          </span>
        </Badge>
      </span>
    ) : (
        <span data-testid="share-route-share-button-plain">Share</span>
      );

  return (
    <ViadeModal
      data-testid="share-route-modal"
      onOpen={() => { }}
      disabled={!checkAuthority()}
      saveDisabled={activeSelectedFriends === 0}
      toggleText={<FormattedMessage id="Share" />}
      handleClose={handleClose}
      onSave={handleOnSave}
      title={<FormattedMessage data-testid="share-modal-title" id="ShareModalTitle" />}
      closeText={<FormattedMessage id="Close" />}
      saveText={shareButtonText}
    >
      <FriendList
        data-testid="share-route-friend-list"
        onClick={handleOnClick}
        friends={friendsForList()}
        style={{ container: style.friendsExpanded, card: style.cardExpanded }}
        checked
      ></FriendList>
    </ViadeModal>
  );
}