@material-ui/core#Chip JavaScript Examples

The following examples show how to use @material-ui/core#Chip. 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: DataPreview.js    From Otto with MIT License 6 votes vote down vote up
export default function DataPreview() {
  const { state } = useState();
  const classes = useStyles();

  if (state.sample_dataset == null) {
    return null;
  }
  const metadata = datasetMetadata[state.sample_dataset];
  function getFormatted(label, index) {
    if (metadata.units) {
      return label + " (" + metadata.units[index] + ")";
    }
    return label;
  }

  return (
    <Grid direction="column" container className={classes.noPadding}>
      {/* Data Attributes */}
      <Grid item>
        <div className={classes.root}>
          {chipData(state).map((data, index) => {
            return (
              <li key={index}>
                <Chip label={data} color="primary" className={classes.chip} />
              </li>
            );
          })}
        </div>
      </Grid>
      {/* Table */}
      <Grid item className={classes.fullWidth}>
        <TableContainer component={Paper} className={classes.table}>
          <Table size="small" aria-label="a dense table">
            <TableHead>
              <TableRow>
                {metadata.columns.map((column, index) => (
                  <TableCell key={index}>
                    {getFormatted(
                      metadata.columnsMap
                        ? metadata.columnsMap[column]
                        : column,
                      index
                    )}
                  </TableCell>
                ))}
              </TableRow>
            </TableHead>
            <TableBody>
              {metadata.data.slice(0, 5).map((row, index) => (
                <TableRow key={index}>
                  {metadata.columns.map((column, index) => (
                    <TableCell key={index} component="th" scope="row">
                      {row[column]}
                    </TableCell>
                  ))}
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      </Grid>
    </Grid>
  );
}
Example #2
Source File: card.js    From dscbppimt-official-website with MIT License 6 votes vote down vote up
AboutCard = ({ image, title, body, hashtag }) => {
    const classes = useStyles()
    return(
        <Card elevation={2} className={classes.aboutCard}>
            <CardContent className={classes.aboutCardContent}>
                {image}
                <Typography variant="subtitle1" component="h5" className={classes.aboutCardTitle}>{title}</Typography>
                <Typography variant="body2" component="p" className={classes.aboutCardBody}>{body}</Typography>
                <Chip label={hashtag}/>
            </CardContent>
        </Card>
        )
}
Example #3
Source File: index.js    From yi-note with GNU General Public License v3.0 6 votes vote down vote up
Tags = () => {
  const { tags } = useStoreState(state => state.page.data);

  const handleTagClick = tag => {
    browser.runtime.sendMessage({
      action: 'open-options',
      data: { action: 'filter-by-tags', data: [tag] }
    });
  };

  return (
    <Grid container spacing={1}>
      {tags.map(tag => (
        <Grid item key={tag}>
          <Chip
            label={tag}
            color="default"
            clickable
            onClick={handleTagClick.bind(null, tag)}
          />
        </Grid>
      ))}
    </Grid>
  );
}
Example #4
Source File: BetaBanner.js    From akashlytics-deploy with GNU General Public License v3.0 6 votes vote down vote up
BetaBanner = () => {
  const [isBetaBarVisible, setIsBetaBarVisible] = useState(true);
  const classes = useStyles();

  const onCloseClick = () => {
    localStorage.setItem("isBetaBannerSeen", true);

    setIsBetaBarVisible(false);
  };

  return (
    <>
      {isBetaBarVisible && (
        <Dialog open={true} maxWidth="xs" fullWidth>
          <DialogContent className={classes.dialogContent}>
            <Typography variant="h3">
              <strong>Welcome!</strong>
            </Typography>
            <Box padding="1rem 0">
              <Chip label="BETA" color="secondary" className={classes.betaChip} size="small" />
            </Box>
            <div className={classes.betaText}>
              <Typography variant="body1">
                <strong>Akashlytics Deploy</strong> is currently in <strong>BETA</strong>. We strongly suggest you start with a new wallet and a small amount of
                AKT until we further stabilize the product. Enjoy!
              </Typography>
            </div>
          </DialogContent>
          <DialogActions>
            <Button variant="contained" onClick={onCloseClick} type="button" color="primary">
              Got it!
            </Button>
          </DialogActions>
        </Dialog>
      )}
    </>
  );
}
Example #5
Source File: Table.js    From react-code-splitting-2021-04-26 with MIT License 6 votes vote down vote up
export default function TableComponent({ data }) {
  const classes = useStyles();
  var keys = Object.keys(data[0]).map(i => i.toUpperCase());
  keys.shift(); // delete "id" key

  return (
    <Table className="mb-0">
      <TableHead>
        <TableRow>
          {keys.map(key => (
            <TableCell key={key}>{key}</TableCell>
          ))}
        </TableRow>
      </TableHead>
      <TableBody>
        {data.map(({ id, name, email, product, price, date, city, status }) => (
          <TableRow key={id}>
            <TableCell className="pl-3 fw-normal">{name}</TableCell>
            <TableCell>{email}</TableCell>
            <TableCell>{product}</TableCell>
            <TableCell>{price}</TableCell>
            <TableCell>{date}</TableCell>
            <TableCell>{city}</TableCell>
            <TableCell>
              <Chip label={status} classes={{root: classes[states[status.toLowerCase()]]}}/>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  );
}
Example #6
Source File: TagsManager.js    From Edlib with GNU General Public License v3.0 6 votes vote down vote up
renderTags() {
        return this.props.tags.map((tag) => {
            return (
                <Chip
                    onDelete={() => this.handleRemove(tag)}
                    key={'tag-' + tag}
                    className={this.props.classes.chip}
                    label={tag}
                />
            );
        });
    }
Example #7
Source File: Highlightable.js    From dataqa with GNU General Public License v3.0 5 votes vote down vote up
getRanges() {
    const newText = [];
    let lastRange;

    // For all the characters on the text
    for(let textCharIndex = 0;textCharIndex < this.props.text.length;textCharIndex++) {
      const range = this.getRange((this.props.startChar || 0) + textCharIndex);
      if(range){
        console.log("char index ", textCharIndex, "startChar ", this.props.startChar , range);
      }
      const url = getUrl(textCharIndex, this.props.text);
      const isEmoji = emojiRegex().test(this.props.text[textCharIndex] + this.props.text[textCharIndex + 1]);
      // Get the current character node
      const node = this.getNode(textCharIndex, range, this.props.text, url, isEmoji);

      // If the next node is an url one, we fast forward to the end of it
      if(url.length) {
        textCharIndex += url.length - 1;
      } else if(isEmoji) {
        // Because an emoji is composed of 2 chars
        textCharIndex++;
      }

      if(!range) {
        newText.push(node);
        continue;
      }

      // If the char is in range
      lastRange = range;
      // We put the first range node on the array
      const letterGroup = [node];

      // For all the characters in the highlighted range
      let rangeCharIndex = textCharIndex + 1;

      for(;rangeCharIndex < parseInt(range.end - (this.props.startChar || 0)) + 1;rangeCharIndex++) {
        const isEmoji = emojiRegex().test(`${this.props.text[rangeCharIndex]}${this.props.text[rangeCharIndex + 1]}`);

        if(isEmoji) {
          letterGroup.push(this.getEmojiNode(rangeCharIndex, range));
          // Because an emoji is composed of 2 chars
          rangeCharIndex++;
        } else {
          letterGroup.push(this.getLetterNode(rangeCharIndex, range));
        }

        textCharIndex = rangeCharIndex;
      }
      // const RangeText = letterGroup.map((node) => node.props.children).join('');

      // if range does not have entityId (ED), then assign default color
      let color, variant;
      if((typeof range.entityId) === "undefined"){
        color = colors["grey"][100];
        variant='outlined';
      }else{
        color = colors[this.props.entityColourMap[range.entityId]][200];
      }

      newText.push(<Chip 
                      key={`chip-${textCharIndex}`} 
                      style={{backgroundColor: color}}
                      label={letterGroup} 
                      onDelete={this.props.onDeleteRange? () => this.props.onDeleteRange(range) : undefined}
                      variant={variant}
                    />);
    }

    return newText;
  }
Example #8
Source File: RightSidePanel.js    From stack-underflow with MIT License 5 votes vote down vote up
RightSidePanel = () => {
  const classes = useRightSidePanelStyles();
  const { notify } = useStateContext();
  const theme = useTheme();
  const isNotDesktop = useMediaQuery(theme.breakpoints.down('sm'));
  const { data, loading } = useQuery(GET_ALL_TAGS, {
    onError: (err) => {
      notify(getErrorMsg(err), 'error');
    },
  });

  if (isNotDesktop) return null;

  return (
    <Grid item>
      <div className={classes.rootPanel}>
        <div className={classes.content}>
          <div className={classes.tagsColumn}>
            <Typography variant="h6" color="secondary">
              Top Tags
            </Typography>
            {!loading && data ? (
              <div className={classes.tagsWrapper}>
                {data.getAllTags.slice(0, 26).map((t) => (
                  <div key={t.tagName}>
                    <Chip
                      label={
                        t.tagName.length > 13
                          ? t.tagName.slice(0, 13) + '...'
                          : t.tagName
                      }
                      variant="outlined"
                      color="primary"
                      size="small"
                      component={RouterLink}
                      to={`/tags/${t.tagName}`}
                      className={classes.tag}
                      clickable
                    />
                    <Typography
                      color="secondary"
                      variant="caption"
                    >{` × ${t.count}`}</Typography>
                  </div>
                ))}
              </div>
            ) : (
              <div style={{ minWidth: '200px' }}>
                <LoadingSpinner size={40} />
              </div>
            )}
          </div>
        </div>
      </div>
    </Grid>
  );
}
Example #9
Source File: ProductOptions.js    From beluga with GNU General Public License v3.0 5 votes vote down vote up
function ProductOptions(props) {
  const { variant, handleNameChange, onSave, inEditMode } = props;

  const [variantOptionText, setVariantOptionText] = useState("");

  return (
    <div>
      <div style={{ display: "flex", alignItems: "center" }}>
        {(onSave && !inEditMode) ? (
          <div style={{ fontWeight: "bold", margin: "0 40px 10px 0" }}>
            {variant.name}
          </div>
        ) : (
          <TextField
            label="Option Name (i.e. Size, Color)"
            style={{ width: "350px" }}
            value={variant.name}
            onChange={(e) => handleNameChange(e.target.value)}
            margin="normal"
          />
        )}
        { onSave && inEditMode && (
          <Button
            onClick={onSave}
            variant="outlined" color="secondary" size="small"
            style={{ verticalAlign: "bottom", margin: "0 40px" }}
          >
            Save
          </Button>
        )}
        <div style={{ margin: "0 0 10px 40px", verticalAlign: "bottom", display: "inline-block" }}>
          { variant.options.map((v,i) => (
            <Chip key={`variant${i}`}
              label={v.label}
              onDelete={() => props.deleteVariantOption(i)}
              color="secondary"
              variant="outlined"
              style={{ marginRight: "10px" }}
            />
          ))}
        </div>
      </div>
      <Step disabled={onSave && inEditMode}>
        <TextField
          label="Option Value (i.e. Medium, Blue)"
          value={variantOptionText}
          onChange={(e) => setVariantOptionText(e.target.value)}
          margin="normal"
          size="small"
          style={{ width: "350px" }}
        />
        <Button
          onClick={() => {
            props.addVariantOption(variantOptionText);
            setVariantOptionText("");
          }}
          variant="outlined" color="secondary" size="small"
          style={{ verticalAlign: "bottom", margin: "0 0 10px 40px" }}
        >
          Add
        </Button>
      </Step>
    </div>
  );
}
Example #10
Source File: Header.js    From spells-fyi with MIT License 5 votes vote down vote up
Header = () => {
    const classes = useStyles();
    return (
      <Grid className={classes.topBar}
          container 
          direction="row" 
          alignItems="center" 
          justify="space-between"
      >
      <Grid item>
        <Grid
          container
          direction="row"
          justify="flex-start"
          alignItems="center"
          wrap="nowrap"
        >
          <img src={ Blocky } className={classes.logo} alt="Blocklytics" />
          <Typography className={classes.logoText}>Spells</Typography>
          <Chip label=".fyi" className={classes.fyiTag} />
        </Grid>
      </Grid>
      <Grid item>
        <Grid container direction="row" alignItems="center" justify="flex-end" spacing={2}>
          <Grid item>
            <Button color="primary" href="https://github.com/blocklytics/spells-fyi" target="_blank">Code</Button>
          </Grid>
          <Grid item>
            <Button color="primary" href="https://thegraph.com/explorer/subgraph/blocklytics/spells" target="_blank">Data</Button>
          </Grid>
          {/* <Grid item>
            <Button color="primary">Bounties</Link>
          </Grid> */}
          <Grid item>
            <Button color="primary" href="https://twitter.com/spellsfyi" target="_blank">Twitter</Button>
          </Grid>
          <Grid item>
            <Button color="primary" href="https://discordapp.com/invite/GFxFN3K" target="_blank">Discord</Button>
          </Grid>
          <Grid item>
            <Button color="primary" href="https://gitcoin.co/grants/601/spellsfyi-see-the-future" target="_blank">GitCoin</Button>
          </Grid>
        </Grid>
      </Grid>
      </Grid>
    )
}
Example #11
Source File: MentorCard.js    From mentors-website with MIT License 5 votes vote down vote up
MentorCard = (props) => {
  const classes = useStyles();
  const {
    mentor,
    choseCountry,
    choseSkill,
    heartedMentor,
    toggleHeartedMentor,
  } = props;

  const handleFlagClick = () => {
    choseCountry(mentor.countryAlpha2Code)
  }

  const handleSkillChipClick = (e) => {
    choseSkill(e.target.textContent)
  }
  return (
    <Card className={classes.root}>
      <CardHeader
        avatar={
          <Avatar
            src={`https://unavatar.now.sh/twitter/${mentor.twitter}`}
            aria-label="mentor"
            className={classes.avatar}
          >
            {mentor.name[0]}
          </Avatar>
        }
        action={
          <IconButton onClick={handleFlagClick}>
            <img
              src={`https://www.countryflags.io/${mentor.countryAlpha2Code}/flat/32.png`}
              alt={mentor.country}
            />
          </IconButton>
        }
        title={mentor.name}
        subheader={mentor.title}
      />
      <CardContent className={classes.MessageCardContent}>
        <Typography variant="body2">"{mentor.message}"</Typography>
      </CardContent>
      <CardContent className={classes.SkillsCardContent}>
        <Grid container justify="center" spacing={1}>
          {mentor.skills.map((skill, index) => (
            <Grid key={index} item>
              <Chip label={skill} variant="outlined" onClick={handleSkillChipClick} />
            </Grid>
          ))}
        </Grid>
      </CardContent>
      <Divider variant="fullWidth" />
      <CardActions className={classes.cardAction} disableSpacing>
        <Button href="#connect-mentor" color="primary">
          Connect
        </Button>
        <IconButton onClick={() => toggleHeartedMentor(mentor.id)}>
          {heartedMentor ? (
            <FavoriteOutlinedIcon color="secondary" />
          ) : (
            <FavoriteBorderOutlinedIcon />
          )}
        </IconButton>
      </CardActions>
    </Card>
  );
}
Example #12
Source File: QuesCard.js    From stack-underflow with MIT License 5 votes vote down vote up
QuesCard = ({ question }) => {
  const classes = useQuesCardStyles();

  const {
    id,
    title,
    author,
    body,
    tags,
    points,
    views,
    answerCount,
    createdAt,
  } = question;

  return (
    <Paper elevation={0} className={classes.root}>
      <div className={classes.infoWrapper}>
        <div className={classes.innerInfo}>
          <Typography variant="body2" className={classes.mainText}>
            {points}
          </Typography>
          <Typography variant="caption">votes</Typography>
        </div>
        <div className={classes.innerInfo}>
          <Typography variant="body2" className={classes.mainText}>
            {answerCount}
          </Typography>
          <Typography variant="caption">answers</Typography>
        </div>
        <Typography variant="caption" noWrap>
          {views} views
        </Typography>
      </div>
      <div className={classes.quesDetails}>
        <Typography
          variant="body2"
          color="secondary"
          className={classes.title}
          component={RouterLink}
          to={`/questions/${id}`}
        >
          {title}
        </Typography>
        <Typography variant="body2" style={{ wordWrap: 'anywhere' }}>
          {body.length > 150 ? body.slice(0, 150) + '...' : body}
        </Typography>
        <div className={classes.bottomWrapper}>
          <div className={classes.tagsWrapper}>
            {tags.map((t) => (
              <Chip
                key={t}
                label={t}
                variant="outlined"
                color="primary"
                size="small"
                component={RouterLink}
                to={`/tags/${t}`}
                className={classes.tag}
                clickable
              />
            ))}
          </div>
          <PostedByUser
            username={author.username}
            userId={author.id}
            createdAt={createdAt}
          />
        </div>
      </div>
    </Paper>
  );
}
Example #13
Source File: Facets.js    From azure-search-react-template with MIT License 5 votes vote down vote up
export default function Facets(props) {

    function mapFacetName(facetName) {
        const capitalizeFirstLetter = (string) =>
            string[0] ? `${string[0].toUpperCase()}${string.substring(1)}` : '';
        facetName = facetName.trim();
        facetName = capitalizeFirstLetter(facetName);

        facetName = facetName.replace('_', ' ');
        return facetName;
    }

    function addFilter(name, value) {
        const newFilters = props.filters.concat({ field: name, value: value });
        props.setFilters(newFilters);
    }

    function removeFilter(filter) {      
        const newFilters = props.filters.filter((item) => item.value !== filter.value);
        props.setFilters(newFilters);
    }

    var facets;
    try{
        facets = Object.keys(props.facets).map(key => {
            return <CheckboxFacet 
                key={key}
                name={key} 
                values={props.facets[key]}
                addFilter={addFilter}
                removeFilter={removeFilter}
                mapFacetName={mapFacetName}
                selectedFacets={props.filters.filter( f => f.field === key)}
              />;
          });
    } catch (error) {
        console.log(error);
    }

    const filters = props.filters.map((filter, index) => {
            return (
            <li key={index}>
                <Chip 
                    label={`${mapFacetName(filter.field)}: ${filter.value}`} 
                    onDelete={() => removeFilter(filter)}
                    className="chip"
              />
            </li>);
          });


    return (
        <div id="facetPanel" className="box">
            <div className="facetbox">
                <div id="clearFilters">
                <ul className="filterlist">
                    {filters}
                </ul>
                </div>
                <FacetList component="nav" className="listitem" >
                    {facets}
                </FacetList>    
            </div>
        </div>
    );
}
Example #14
Source File: BmcDialog.js    From budgie-stream with MIT License 5 votes vote down vote up
export default function BmcDialog(props) {
  const { close } = props;
  const classes = useStyles();
  const [supporters, setSupporters] = useState({});

  const loadSupporters = async () => {
    const response = await fetch(
      "https://filahf.github.io/budgie-stream-supporters/supporters.json"
    );
    const data = await response.json();
    setSupporters(data.supporters);
  };

  useEffect(() => {
    loadSupporters();
  }, []);

  return (
    <div>
      <Dialog
        onClose={close}
        aria-labelledby="customized-dialog-title"
        open={props.open}
        scroll="paper"
        maxWidth="xs"
      >
        <DialogTitle
          id="customized-dialog-title"
          style={{ textAlign: "center", marginBottom: 0, paddingBottom: 0 }}
        >
          Sponsors & Supporters
        </DialogTitle>
        <DialogContent>
          <Typography>
            This project is open source and free to use. If you would like to
            support the development of Budgie Stream, consider buying me a
            coffee.
          </Typography>
          <div className={classes.action}>
            <Typography style={{ marginTop: "1.5rem" }} variant="subtitle2">
              Supporters
            </Typography>
          </div>
          <div className={classes.root}>
            {Object.entries(supporters).length === 0 ? (
              <Chip variant="outlined" label="No supporters yet" />
            ) : (
              supporters.sort(compare).map((supporter, id) => (
                <Tooltip
                  key={id}
                  title={"Bought " + supporter.value + " coffee(s)!"}
                  placement="top"
                  arrow
                >
                  <Chip
                    icon={<FavoriteIcon style={{ color: "#bf616a" }} />}
                    variant="outlined"
                    label={supporter.name}
                  />
                </Tooltip>
              ))
            )}
          </div>
        </DialogContent>
        <MuiDialogActions className={classes.action}>
          <Button
            variant="contained"
            color="secondary"
            style={{ textTransform: "none" }}
            onClick={handleClick}
          >
            Buy me a coffee
          </Button>
        </MuiDialogActions>
      </Dialog>
    </div>
  );
}
Example #15
Source File: positions.jsx    From GraphVega with MIT License 5 votes vote down vote up
Positions = props => {
  return (
    <Row>
      <Col sm={{span:12}}>
        <Card>
          <CardContent>
          <Typography variant="h6" display="block" gutterBottom>
            Positions
          </Typography>
            <Table>
              <TableHead>
                <TableRow>
                  <TableCell>TYPE</TableCell>
                  <TableCell>QTY</TableCell>
                  <TableCell>MARK</TableCell>
                  <TableCell>STRIKE</TableCell>
                  <TableCell>EXPIRY</TableCell>
                  <TableCell>IMP VOL</TableCell>
                  <TableCell>VEGA</TableCell>
                  <TableCell>THETA</TableCell>
                  <TableCell>DELTA</TableCell>
                  <TableCell>GAMMA</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {props.positions.map((option) => (
                  <TableRow>
                    <TableCell>
                      <Chip label={option.option_type} color={chipStyle(option.option_type)}/>
                    </TableCell>
                    <TableCell>{option.quantity}</TableCell>
                    <TableCell>{(option.bid + option.ask)/2}</TableCell>
                    <TableCell>{option.strike}</TableCell>
                    <TableCell>{expiry(option.expiration_date)}</TableCell>
                    <TableCell>{roundOne(option.greeks.smv_vol*100)}%</TableCell>
                    <TableCell>{option.greeks.vega}</TableCell>
                    <TableCell>{option.greeks.theta}</TableCell>
                    <TableCell>{option.greeks.delta}</TableCell>
                    <TableCell>{option.greeks.gamma}</TableCell>
                  </TableRow>
                ))}
                {(props.quantity && props.quantity !== 0) ? 
                  <TableRow>
                    <TableCell>
                      <Chip label={"shares"} />
                    </TableCell>
                    <TableCell>{props.quantity}</TableCell>
                    <TableCell>{(props.quote.ask + props.quote.bid)/2}</TableCell>
                    <TableCell>--</TableCell>
                    <TableCell>--</TableCell>
                    <TableCell>--</TableCell>
                    <TableCell>--</TableCell>
                    <TableCell>--</TableCell>
                    <TableCell>{props.quantity}</TableCell>
                    <TableCell>--</TableCell>
                  </TableRow>
                : ""
                }
              </TableBody>
            </Table>
          </CardContent>
        </Card>
      </Col>
    </Row>
  )
}
Example #16
Source File: index.js    From yi-note with GNU General Public License v3.0 5 votes vote down vote up
TagDialog = ({ tags, onAddTag, onRemoveTag }) => {
  const { t } = useTranslation('tagdialog');
  const {
    tagDialog: { open }
  } = useStoreState(state => state);
  const {
    tagDialog: { setOpen }
  } = useStoreActions(actions => actions);
  const [input, setInput] = useState('');
  const containerRef = useRef(null);

  useEffect(() => {
    containerRef.current = document.getElementById(APP_ID);
  }, []);

  const handleClose = () => {
    setOpen(false);
  };

  const handleInputChange = e => {
    setInput(e.target.value);
  };

  const handleKeyPress = e => {
    if (e.key === 'Enter') {
      onAddTag(input);
      setInput('');
    }
  };

  const handleDelete = tag => {
    onRemoveTag(tag);
  };

  return (
    <Dialog onClose={handleClose} open={open} container={containerRef.current}>
      <DialogContent>
        <Grid container direction="column" spacing={3}>
          <Grid item>
            <TextField
              autoFocus
              label={t('input.label')}
              value={input}
              onChange={handleInputChange}
              onKeyPress={handleKeyPress}
            />
          </Grid>
          <Grid item container spacing={1}>
            {tags.map(tag => (
              <Grid item key={tag}>
                <Chip
                  label={tag}
                  color="default"
                  onDelete={handleDelete.bind(null, tag)}
                />
              </Grid>
            ))}
          </Grid>
        </Grid>
      </DialogContent>
    </Dialog>
  );
}
Example #17
Source File: Disruption.js    From warsinhk with MIT License 5 votes vote down vote up
Disruption = props => {
  const { node, onCategoryClick } = props
  const { i18n, t } = useTranslation()
  const [expanded, setExpanded] = React.useState(false)

  const handleExpandClick = () => {
    setExpanded(!expanded)
  }

  const sourceUrl = withLanguage(i18n, node, "source_url")
  const hasDescription = props.children && props.children.length > 0
  const ExpandIcon = expanded ? InvertedExpandMoreIcon : ExpandMoreIcon

  return (
    <DisruptionCard>
      <DisruptionCardHeader title={withLanguage(i18n, node, "name")} />
      <DisruptionCardContent>
        <Box alignItems="flex-start">
          <Row>
            <Chip
              label={withLanguage(i18n, node, "category")}
              size="small"
              variant="outlined"
              onClick={() =>
                onCategoryClick(withLanguage(i18n, node, "category"))
              }
            />
          </Row>
          <Row>
            <DisruptionDetail variant="body1">
              {withLanguage(i18n, node, "detail")}
            </DisruptionDetail>
          </Row>
          <Row>
            {t("disruption.status")}:{" "}
            {withLanguage(i18n, node, "status") || "-"}
          </Row>
          <Row>
            {t("disruption.to")}: {withLanguage(i18n, node, "to") || "-"}
          </Row>
        </Box>
      </DisruptionCardContent>
      <>
        <DisruptionCardActions disableSpacing>
          <DisruptionAction>
            {sourceUrl && (
              <Row>
                <Typography variant="caption">
                  <Link component={Link} href={sourceUrl} target="_blank">
                    {t("disruption.source")}
                  </Link>
                </Typography>
              </Row>
            )}
            <Row>
              <Typography variant="caption">
                {t("disruption.last_updated", { date: node.last_update })}
              </Typography>
            </Row>
          </DisruptionAction>
          {hasDescription && (
            <IconButton onClick={handleExpandClick} aria-expanded={expanded}>
              <ExpandIcon />
            </IconButton>
          )}
        </DisruptionCardActions>
        {hasDescription && (
          <Collapse in={expanded} timeout="auto" unmountOnExit>
            <DisruptionCardContent>
              {hasDescription && (
                <Box alignItems="flex-start">{props.children}</Box>
              )}
            </DisruptionCardContent>
          </Collapse>
        )}
      </>
    </DisruptionCard>
  )
}
Example #18
Source File: PageRegion.js    From covid-19 with MIT License 5 votes vote down vote up
Graphs = (props) => {
  const classes = useGraphStyles();
  const world = useContext(WorldContext);
  const name = world.get(props.path, NameComponent);
  const basic = world.get(props.path, BasicDataComponent);
  const population = world.get(props.path, PopulationComponent);

  const [comparingWith, setComparingWith] = React.useState(() => []);
  const addComparison = (path) => {
    const name = world.get(path, NameComponent);
    const basic = world.get(path, BasicDataComponent);
    const population = world.get(path, PopulationComponent);
    setComparingWith(comparingWith.concat([{
      path,
      name,
      basic,
      population
    }]));
  };
  const removeComparison = (i) => {
    const copied = [...comparingWith];
    copied.splice(i, 1);
    setComparingWith(copied);
  };

  return (
    <div className={props.className}>
      <div className={classes.comparisons}>
        <Typography>Compare with: </Typography>
        <SearchInput
          className={classes.comparisonSearch}
          onChoice={addComparison}
        />
        {comparingWith.map(({ path, name }, i) => {
          return (
            <Chip
              key={path.string()}
              className={classes.chip}
              onDelete={() => removeComparison(i)}
              label={name.english()}
            />
          );
        })}
      </div>

      {[DailyChangeGraph, DailyTotalGraph, DoublingGraph].map((Graph, i) => (
        <Graph
          key={i}
          name={name}
          basic={basic}
          population={population}
          comparingWith={comparingWith}
          className={classes.graph}
        />
      ))}
    </div>
  );
}
Example #19
Source File: Footer.js    From akashlytics-deploy with GNU General Public License v3.0 5 votes vote down vote up
Footer = () => {
  const classes = useStyles();
  const { appVersion } = useAppVersion();

  return (
    <AppBar position="fixed" color="default" elevation={0} component="footer" className={classes.root} id="footer">
      <Toolbar variant="dense" className={classes.toolbar}>
        <Box display="flex" alignItems="center">
          {appVersion && (
            <>
              <Typography variant="caption" className={classes.caption}>
                <strong>v{appVersion}</strong>
              </Typography>

              <Chip label="beta" color="secondary" size="small" className={classes.betaChip} />
            </>
          )}

          <LinkTo onClick={() => window.electron.openUrl("https://akash.network")} className={classes.akashLink}>
            <img src="./images/powered-by-akash.svg" alt="Akashlytics Logo" className={classes.akashImage} />
          </LinkTo>
        </Box>

        <Box display="flex" alignItems="center">
          <Box marginRight="1rem">
            <Button
              onClick={() => window.electron.openUrl("https://www.mintscan.io/akash/validators/akashvaloper14mt78hz73d9tdwpdvkd59ne9509kxw8yj7qy8f")}
              size="small"
            >
              <Typography variant="caption" className={classes.caption}>
                Validator
              </Typography>
            </Button>
          </Box>

          <ul className={classes.socialLinks}>
            <li>
              <LinkTo onClick={() => window.electron.openUrl("https://discord.gg/rXDFNYnFwv")} className={classes.socialLink}>
                <DiscordIcon className={classes.socialIcon} />
              </LinkTo>
            </li>
            <li>
              <LinkTo
                onClick={() => window.electron.openUrl("https://www.youtube.com/channel/UC1rgl1y8mtcQoa9R_RWO0UA?sub_confirmation=1")}
                className={classes.socialLink}
              >
                <YouTubeIcon className={classes.socialIcon} />
              </LinkTo>
            </li>
            <li>
              <LinkTo onClick={() => window.electron.openUrl("https://twitter.com/akashlytics")} className={classes.socialLink}>
                <TwitterIcon className={classes.socialIcon} />
              </LinkTo>
            </li>
            <li>
              <LinkTo onClick={() => window.electron.openUrl("https://github.com/Akashlytics/akashlytics-deploy")} className={classes.socialLink}>
                <GitHubIcon className={classes.socialIcon} />
              </LinkTo>
            </li>
          </ul>
        </Box>
      </Toolbar>
    </AppBar>
  );
}
Example #20
Source File: CreateProject.jsx    From zubhub with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * @function CreateProject View
 * @author Raymond Ndibe <[email protected]>
 *
 * @todo - describe function's signature
 */
function CreateProject(props) {
  const [category, setCategory] = React.useState([]);

  const classes = useStyles();
  const common_classes = useCommonStyles();

  const refs = {
    title_el: React.useRef(null),
    desc_el: React.useRef(null),
    image_el: React.useRef(null),
    image_upload_button_el: React.useRef(null),
    video_upload_button_el: React.useRef(null),
    image_count_el: React.useRef(null),
    video_el: React.useRef(null),
    video_file_el: React.useRef(null),
    video_selection_feedback_el: React.useRef(null),
    add_materials_used_el: React.useRef(null),
    add_tags_el: React.useRef(null),
    publish_type_el: React.useRef(null),
    publish_visible_to_el: React.useRef(null),
  };

  const [state, setState] = React.useState({
    ...JSON.parse(JSON.stringify(vars.default_state)),
  });

  React.useEffect(() => {
    if (props.match.params.id) {
      Promise.all([getProject(refs, props, state), getCategories(props)]).then(
        result => handleSetState({ ...result[0], ...result[1] }),
      );
    } else {
      handleSetState(getCategories(props));
    }
    handleSetState(buildPublishTypes(props));
  }, []);

  React.useEffect(() => {
    checkMediaFilesErrorState(refs, props);
  }, [
    props.errors['project_images'],
    props.touched['project_images'],
    props.errors['video'],
    props.touched['video'],
  ]);

  const handleSetState = obj => {
    if (obj) {
      Promise.resolve(obj).then(obj => {
        setState(state => ({ ...state, ...obj }));
      });
    }
  };

  const {
    desc_input_is_focused,
    video_upload_dialog_open,
    media_upload,
    categories,
    tag_suggestion,
    tag_suggestion_open,
    select_video_file,
    publish_types,
    publish_visible_to_suggestion_open,
    publish_visible_to_suggestion,
  } = state;
  const { t } = props;
  const id = props.match.params.id;
  if (!props.auth.token) {
    return <ErrorPage error={t('createProject.errors.notLoggedIn')} />;
  } else {
    return (
      <Box className={classes.root}>
        <Container className={classes.containerStyle}>
          <Card className={classes.cardStyle}>
            <CardActionArea>
              <CardContent>
                <form
                  className="project-create-form"
                  name="create_project"
                  noValidate="noValidate"
                  onSubmit={e =>
                    !vars.upload_in_progress
                      ? initUpload(e, state, props, handleSetState)
                      : e.preventDefault()
                  }
                >
                  <Typography
                    className={classes.titleStyle}
                    gutterBottom
                    variant="h5"
                    component="h2"
                    color="textPrimary"
                  >
                    {!id
                      ? t('createProject.welcomeMsg.primary')
                      : t('createProject.inputs.edit')}
                  </Typography>
                  <Typography
                    variant="body2"
                    color="textSecondary"
                    component="p"
                    className={classes.descStyle}
                  >
                    {t('createProject.welcomeMsg.secondary')}
                  </Typography>

                  <Grid container spacing={3}>
                    <Grid item xs={12}>
                      <Box
                        component="p"
                        className={
                          props.status &&
                          props.status['non_field_errors'] &&
                          classes.errorBox
                        }
                      >
                        {props.status && props.status['non_field_errors'] && (
                          <Box component="span" className={classes.error}>
                            {props.status['non_field_errors']}
                          </Box>
                        )}
                      </Box>
                    </Grid>

                    <Grid item xs={12} className={common_classes.marginTop1em}>
                      <FormControl
                        className={clsx(classes.margin, classes.textField)}
                        variant="outlined"
                        size="small"
                        fullWidth
                        margin="small"
                        error={
                          (props.status && props.status['title']) ||
                          (props.touched['title'] && props.errors['title'])
                        }
                      >
                        <label htmlFor="title">
                          <Typography
                            color="textSecondary"
                            className={clsx(
                              classes.customLabelStyle,
                              common_classes.marginBottom1em,
                            )}
                          >
                            <Box className={classes.fieldNumberStyle}>1</Box>
                            {t('createProject.inputs.title.label')}
                          </Typography>
                        </label>
                        <OutlinedInput
                          ref={refs.title_el}
                          className={classes.customInputStyle}
                          id="title"
                          name="title"
                          type="text"
                          onChange={e => handleTextFieldChange(e, props)}
                          onBlur={e => handleTextFieldBlur(e, props)}
                        />
                        <FormHelperText
                          error
                          className={classes.fieldHelperTextStyle}
                        >
                          {(props.status && props.status['title']) ||
                            (props.touched['title'] &&
                              props.errors['title'] &&
                              t(
                                `createProject.inputs.title.errors.${props.errors['title']}`,
                              ))}
                        </FormHelperText>
                      </FormControl>
                    </Grid>

                    <Grid item xs={12} className={common_classes.marginTop1em}>
                      <FormControl
                        className={clsx(classes.margin, classes.textField)}
                        variant="outlined"
                        size="small"
                        fullWidth
                        margin="small"
                      >
                        <label htmlFor="description">
                          <Typography
                            color="textSecondary"
                            className={clsx(
                              classes.customLabelStyle,
                              common_classes.marginBottom1em,
                            )}
                          >
                            <Box className={classes.fieldNumberStyle}>2</Box>
                            {t('createProject.inputs.description.label')}
                          </Typography>
                        </label>
                        <Typography
                          color="textSecondary"
                          variant="caption"
                          component="span"
                          className={clsx(
                            classes.fieldHelperTextStyle,
                            common_classes.marginBottom1em,
                          )}
                        >
                          {t('createProject.inputs.description.helperText')}
                        </Typography>
                        <ClickAwayListener
                          onClickAway={() =>
                            handleSetState({ desc_input_is_focused: false })
                          }
                        >
                          <ReactQuill
                            ref={refs.desc_el}
                            className={clsx(
                              classes.descInputStyle,
                              {
                                [classes.descInputFocusStyle]:
                                  desc_input_is_focused,
                              },
                              {
                                [classes.descInputErrorStyle]:
                                  (props.status &&
                                    props.status['description']) ||
                                  (props.touched['description'] &&
                                    props.errors['description']),
                              },
                            )}
                            modules={vars.quill.modules}
                            formats={vars.quill.formats}
                            defaultValue={''}
                            placeholder={t(
                              'createProject.inputs.description.placeholder',
                            )}
                            onChange={value =>
                              handleDescFieldChange(
                                value,
                                props,
                                handleSetState,
                              )
                            }
                            onFocus={() =>
                              handleDescFieldFocusChange(
                                null,
                                props,
                                handleSetState,
                              )
                            }
                          />
                        </ClickAwayListener>
                        <FormHelperText
                          error
                          className={classes.fieldHelperTextStyle}
                        >
                          {(props.status && props.status['description']) ||
                            (props.touched['description'] &&
                              props.errors['description'] &&
                              t(
                                `createProject.inputs.description.errors.${props.errors['description']}`,
                              ))}
                        </FormHelperText>
                      </FormControl>
                    </Grid>

                    <Grid item xs={12} className={common_classes.marginTop1em}>
                      <FormControl
                        fullWidth
                        error={
                          (props.status && props.status['project_images']) ||
                          (props.touched['project_images'] &&
                            props.errors['project_images'])
                        }
                      >
                        <label htmlFor="project_images">
                          <Typography
                            color="textSecondary"
                            className={classes.customLabelStyle}
                          >
                            <Box className={classes.fieldNumberStyle}>3</Box>
                            {t('createProject.inputs.projectImages.label')}
                          </Typography>
                        </label>

                        <Typography
                          color="textSecondary"
                          variant="caption"
                          component="span"
                          className={clsx(
                            classes.fieldHelperTextStyle,
                            common_classes.marginBottom1em,
                          )}
                        >
                          {t(
                            'createProject.inputs.projectImages.topHelperText',
                          )}
                        </Typography>
                        <Grid container spacing={1}>
                          <Grid item xs={12} sm={6} md={6}>
                            <CustomButton
                              ref={refs.image_upload_button_el}
                              variant="outlined"
                              size="large"
                              margin="normal"
                              id="image_upload_button"
                              startIcon={<ImageIcon />}
                              onClick={e =>
                                handleImageButtonClick(e, props, refs)
                              }
                              secondaryButtonStyle
                              mediaUploadButtonStyle
                              customButtonStyle
                              fullWidth
                            >
                              {t('createProject.inputs.projectImages.label2')}
                            </CustomButton>
                            <Typography
                              color="textSecondary"
                              variant="caption"
                              component="span"
                              ref={refs.image_count_el}
                            ></Typography>
                          </Grid>
                        </Grid>
                        <input
                          ref={refs.image_el}
                          className={classes.displayNone}
                          aria-hidden="true"
                          type="file"
                          accept="image/*"
                          id="project_images"
                          name="project_images"
                          multiple
                          onChange={_ =>
                            handleImageFieldChange(
                              refs,
                              props,
                              state,
                              handleSetState,
                            )
                          }
                          onBlur={props.handleBlur}
                        />
                        <FormHelperText
                          error
                          className={classes.fieldHelperTextStyle}
                        >
                          {(props.status && props.status['images']) ||
                            (props.errors['project_images'] &&
                              t(
                                `createProject.inputs.projectImages.errors.${props.errors['project_images']}`,
                              ))}
                        </FormHelperText>
                      </FormControl>
                    </Grid>

                    <Grid item xs={12} className={common_classes.marginTop1em}>
                      <FormControl
                        fullWidth
                        error={
                          (props.status && props.status['video']) ||
                          (props.touched['video'] && props.errors['video'])
                        }
                      >
                        <label htmlFor="video">
                          <Typography
                            color="textSecondary"
                            className={classes.customLabelStyle}
                          >
                            <Box className={classes.fieldNumberStyle}>4</Box>
                            {t('createProject.inputs.video.label')}
                          </Typography>
                        </label>

                        <Typography
                          color="textSecondary"
                          variant="caption"
                          component="span"
                          className={clsx(
                            classes.fieldHelperTextStyle,
                            common_classes.marginBottom1em,
                          )}
                        >
                          {t('createProject.inputs.video.topHelperText')}
                        </Typography>
                        <Grid container spacing={1}>
                          <Grid item xs={12} sm={6} md={6}>
                            <CustomButton
                              ref={refs.video_upload_button_el}
                              variant="outlined"
                              size="large"
                              margin="normal"
                              id="video_upload_button"
                              startIcon={<VideoIcon />}
                              onClick={e =>
                                handleSetState(
                                  handleVideoButtonClick(
                                    e,
                                    props,
                                    video_upload_dialog_open,
                                  ),
                                )
                              }
                              secondaryButtonStyle
                              mediaUploadButtonStyle
                              customButtonStyle
                              fullWidth
                            >
                              {t('createProject.inputs.video.label2')}
                            </CustomButton>
                            <Typography
                              color="textSecondary"
                              variant="caption"
                              component="span"
                              ref={refs.video_selection_feedback_el}
                            ></Typography>
                          </Grid>
                        </Grid>
                        <FormHelperText
                          error
                          className={classes.fieldHelperTextStyle}
                        >
                          {(props.status && props.status['video']) ||
                            (props.errors['video'] &&
                              t(
                                `createProject.inputs.video.errors.${props.errors['video']}`,
                              ))}
                        </FormHelperText>
                        <Typography
                          color="textSecondary"
                          variant="caption"
                          component="span"
                          className={classes.fieldHelperTextStyle}
                        >
                          {t('createProject.inputs.video.bottomHelperText')}
                        </Typography>
                      </FormControl>
                    </Grid>

                    <Grid item xs={12} className={common_classes.marginTop1em}>
                      <FormControl
                        className={clsx(classes.margin, classes.textField)}
                        variant="outlined"
                        size="small"
                        fullWidth
                        margin="small"
                        error={
                          (props.status && props.status['materials_used']) ||
                          (props.touched['materials_used'] &&
                            props.errors['materials_used'])
                        }
                      >
                        <label htmlFor="add_materials_used">
                          <Typography
                            color="textSecondary"
                            className={clsx(
                              classes.customLabelStyle,
                              common_classes.marginBottom1em,
                            )}
                          >
                            <Box className={classes.fieldNumberStyle}>5</Box>
                            {t('createProject.inputs.materialsUsed.label')}
                          </Typography>
                        </label>

                        <Grid container spacing={1} alignItems="flex-end">
                          <Grid item xs={12} sm={8}>
                            <Box ref={refs.add_materials_used_el}>
                              {buildMaterialUsedNodes({
                                props,
                                refs,
                                classes,
                                common_classes,
                              })}
                            </Box>
                          </Grid>
                          <Grid item xs={12} sm={4} md={4}>
                            <CustomButton
                              variant="outlined"
                              size="large"
                              onClick={e => addMaterialsUsedNode(e, props)}
                              secondaryButtonStyle
                              customButtonStyle
                              fullWidth
                            >
                              <AddIcon />{' '}
                              {t('createProject.inputs.materialsUsed.addMore')}
                            </CustomButton>
                          </Grid>
                          <FormHelperText
                            error
                            className={classes.fieldHelperTextStyle}
                          >
                            {(props.status && props.status['materials_used']) ||
                              (props.touched['materials_used'] &&
                                props.errors['materials_used'] &&
                                t(
                                  `createProject.inputs.materialsUsed.errors.${props.errors['materials_used']}`,
                                ))}
                          </FormHelperText>
                        </Grid>
                      </FormControl>
                    </Grid>

                    <Grid item xs={12} className={common_classes.marginTop1em}>
                      <FormControl
                        className={clsx(classes.margin, classes.textField)}
                        variant="outlined"
                        size="small"
                        fullWidth
                        margin="small"
                        error={
                          (props.status && props.status['category']) ||
                          (props.touched['category'] &&
                            props.errors['category'])
                        }
                      >
                        <label htmlFor="category">
                          <Typography
                            color="textSecondary"
                            className={classes.customLabelStyle}
                          >
                            <Box className={classes.fieldNumberStyle}>6</Box>
                            {t('createProject.inputs.category.label')}
                          </Typography>
                        </label>
                        <Typography
                          color="textSecondary"
                          variant="caption"
                          component="span"
                          className={clsx(
                            classes.fieldHelperTextStyle,
                            common_classes.marginBottom1em,
                          )}
                        >
                          {t('createProject.inputs.category.topHelperText')}
                        </Typography>
                        <Select
                          labelId="category"
                          id="category"
                          name="category"
                          className={classes.customInputStyle}
                          value={
                            props.values.category ? props.values.category : ''
                          }
                          onChange={props.handleChange}
                          onBlur={props.handleBlur}
                        >
                          <MenuItem value="">
                            <em>None</em>
                          </MenuItem>
                          {Array.isArray(categories) &&
                            categories.map(category => (
                              <MenuItem key={category.id} value={category.name}>
                                {category.name}
                              </MenuItem>
                            ))}
                        </Select>
                        <FormHelperText
                          error
                          className={classes.fieldHelperTextStyle}
                        >
                          {(props.status && props.status['category']) ||
                            (props.touched['category'] &&
                              props.errors['category'] &&
                              t(
                                `createProject.inputs.category.errors.${props.errors['category']}`,
                              ))}
                        </FormHelperText>
                      </FormControl>
                    </Grid>

                    <Grid item xs={12} className={common_classes.marginTop1em}>
                      <FormControl
                        className={clsx(classes.margin, classes.textField)}
                        variant="outlined"
                        size="small"
                        fullWidth
                        margin="small"
                        error={
                          (props.status && props.status['tags']) ||
                          (props.touched['tags'] && props.errors['tags'])
                        }
                      >
                        <label htmlFor="add_tags">
                          <Typography
                            color="textSecondary"
                            className={classes.customLabelStyle}
                          >
                            <Box className={classes.fieldNumberStyle}>7</Box>
                            {t('createProject.inputs.tags.label')}
                          </Typography>
                        </label>

                        <Typography
                          color="textSecondary"
                          variant="caption"
                          component="span"
                          className={clsx(
                            classes.fieldHelperTextStyle,
                            common_classes.marginBottom1em,
                          )}
                        >
                          {t('createProject.inputs.tags.topHelperText')}
                        </Typography>
                        <Box className={classes.tagsViewStyle}>
                          {props.values['tags'] &&
                            JSON.parse(props.values['tags']).map((tag, num) =>
                              tag && tag.name ? (
                                <Chip
                                  className={classes.customChipStyle}
                                  key={num}
                                  label={tag.name}
                                  onDelete={e => removeTag(e, props, tag.name)}
                                  color="secondary"
                                  variant="outlined"
                                />
                              ) : null,
                            )}
                          <input
                            ref={refs.add_tags_el}
                            className={classes.tagsInputStyle}
                            name="tags"
                            type="text"
                            autocomplete="off"
                            placeholder={
                              props.values['tags'] &&
                              JSON.parse(props.values['tags']).length >= 5
                                ? t(
                                    'createProject.inputs.tags.errors.limitReached',
                                  )
                                : `${t('createProject.inputs.tags.addTag')}...`
                            }
                            onChange={e => {
                              handleSuggestTags(
                                e,
                                props,
                                state,
                                handleSetState,
                              );
                              handleSetState(handleAddTags(e, props));
                            }}
                            onBlur={e => {
                              handleAddTags(e, props);
                            }}
                          />
                          <ClickAwayListener
                            onClickAway={() =>
                              handleSetState({
                                tag_suggestion_open: false,
                                tag_suggestion: [],
                              })
                            }
                          >
                            <Box
                              className={clsx(
                                classes.tagSuggestionStyle,
                                !tag_suggestion_open
                                  ? common_classes.displayNone
                                  : null,
                              )}
                            >
                              {tag_suggestion && tag_suggestion.length > 0 ? (
                                tag_suggestion.map((tag, index) => (
                                  <Typography
                                    key={index}
                                    color="textPrimary"
                                    className={classes.tagSuggestionTextStyle}
                                    onClick={() => {
                                      clearTimeout(vars.timer.id);
                                      handleSetState(
                                        handleAddTags(
                                          {
                                            currentTarget: {
                                              value: `${tag.name},`,
                                            },
                                          },
                                          props,
                                          refs.add_tags_el,
                                        ),
                                      );
                                    }}
                                  >
                                    {tag.name}
                                  </Typography>
                                ))
                              ) : (
                                <CircularProgress size={30} thickness={3} />
                              )}
                            </Box>
                          </ClickAwayListener>
                        </Box>
                        <FormHelperText
                          error
                          className={classes.fieldHelperTextStyle}
                        >
                          {(props.status && props.status['tags']) ||
                            (props.touched['tags'] &&
                              props.errors['tags'] &&
                              t(
                                `createProject.inputs.tags.errors.${props.errors['tags']}`,
                              ))}
                        </FormHelperText>
                      </FormControl>
                    </Grid>

                    <Grid item xs={12} className={common_classes.marginTop1em}>
                      <FormControl
                        className={clsx(classes.margin, classes.textField)}
                        variant="outlined"
                        size="small"
                        fullWidth
                        margin="small"
                        error={
                          (props.status && props.status['publish']) ||
                          (props.touched['publish'] && props.errors['publish'])
                        }
                      >
                        <label htmlFor="publish">
                          <Typography
                            color="textSecondary"
                            className={classes.customLabelStyle}
                          >
                            <Box className={classes.fieldNumberStyle}>8</Box>
                            {t('createProject.inputs.publish.label')}
                          </Typography>
                        </label>

                        <Typography
                          color="textSecondary"
                          variant="caption"
                          component="span"
                          className={clsx(
                            classes.fieldHelperTextStyle,
                            common_classes.marginBottom1em,
                          )}
                        >
                          {t('createProject.inputs.publish.topHelperText')}
                        </Typography>

                        <Select
                          ref={refs.publish_type_el}
                          labelId="publish"
                          id="publish"
                          name="publish"
                          className={classes.customInputStyle}
                          value={
                            props.values.publish
                              ? props.values.publish.type
                              : publish_types[0]
                              ? publish_types[0].value
                              : ''
                          }
                          onChange={e => handlePublishFieldChange(e, props)}
                          onBlur={e => handlePublishFieldBlur(e, props)}
                        >
                          {publish_types.map(type => (
                            <MenuItem key={type.name} value={type.value}>
                              {t(`createProject.inputs.publish.publishTypes.${type.name}`)}
                            </MenuItem>
                          ))}
                        </Select>

                        <Box
                          className={clsx(
                            classes.tagsViewStyle,
                            common_classes.marginTop1em,
                            {
                              [common_classes.displayNone]:
                                props.values.publish?.type !==
                                publish_type['Preview'],
                            },
                          )}
                        >
                          {props.values.publish?.visible_to &&
                            props.values['publish']['visible_to'].map(
                              (username, num) =>
                                username ? (
                                  <Chip
                                    className={classes.customChipStyle}
                                    key={num}
                                    label={username}
                                    onDelete={e =>
                                      handleRemovePublishVisibleTo(
                                        e,
                                        props,
                                        username,
                                      )
                                    }
                                    color="secondary"
                                    variant="outlined"
                                  />
                                ) : null,
                            )}
                          <input
                            ref={refs.publish_visible_to_el}
                            className={classes.tagsInputStyle}
                            name="publish_visible_to"
                            type="text"
                            autocomplete="off"
                            placeholder={`${t(
                              'createProject.inputs.publish.addUsernames',
                            )}...`}
                            onChange={e => {
                              handleSuggestPublishVisibleTo(
                                e,
                                props,
                                state,
                                handleSetState,
                              );
                              handleSetState(
                                handleAddPublishVisibleTo(e, props),
                              );
                            }}
                            onBlur={e => {
                              handleAddPublishVisibleTo(e, props);
                            }}
                          />
                          <ClickAwayListener
                            onClickAway={() =>
                              handleSetState({
                                publish_visible_to_suggestion_open: false,
                                publish_visible_to_suggestion: [],
                              })
                            }
                          >
                            <Box
                              className={clsx(
                                classes.tagSuggestionStyle,
                                !publish_visible_to_suggestion_open
                                  ? common_classes.displayNone
                                  : null,
                              )}
                            >
                              {publish_visible_to_suggestion &&
                              publish_visible_to_suggestion.length > 0 ? (
                                publish_visible_to_suggestion.map(
                                  (username, index) => (
                                    <Typography
                                      key={index}
                                      color="textPrimary"
                                      className={classes.tagSuggestionTextStyle}
                                      onClick={() => {
                                        clearTimeout(vars.timer.id);
                                        handleSetState(
                                          handleAddPublishVisibleTo(
                                            {
                                              currentTarget: {
                                                value: `${username},`,
                                              },
                                            },
                                            props,
                                            refs.publish_visible_to_el,
                                          ),
                                        );
                                      }}
                                    >
                                      {username}
                                    </Typography>
                                  ),
                                )
                              ) : (
                                <CircularProgress size={30} thickness={3} />
                              )}
                            </Box>
                          </ClickAwayListener>
                        </Box>
                        <FormHelperText
                          error
                          className={classes.fieldHelperTextStyle}
                        >
                          {(props.status && props.status['publish']) ||
                            (props.touched['publish'] &&
                              props.errors['publish'] &&
                              t(
                                `createProject.inputs.publish.errors.${props.errors['publish']}`,
                              ))}
                        </FormHelperText>
                      </FormControl>
                    </Grid>

                    <Grid item xs={12}>
                      <CustomButton
                        variant="contained"
                        size="large"
                        type="submit"
                        primaryButtonStyle
                        customButtonStyle
                        fullWidth
                      >
                        {!id
                          ? t('createProject.inputs.submit')
                          : t('createProject.inputs.edit')}
                      </CustomButton>
                    </Grid>
                  </Grid>

                  <Dialog
                    PaperProps={{
                      style: {
                        backgroundColor: 'transparent',
                        boxShadow: 'none',
                      },
                    }}
                    open={video_upload_dialog_open}
                    onClose={async () =>
                      handleSetState({
                        ...(await handleVideoFieldCancel(refs, props, state)),
                        video_upload_dialog_open: false,
                      })
                    }
                    aria-labelledby="video upload dialog"
                  >
                    <Container
                      className={clsx(
                        classes.containerStyle,
                        classes.videoInputDialogContainerStyle,
                      )}
                    >
                      <Card
                        className={clsx(
                          classes.cardStyle,
                          classes.videoInputDialogCardStyle,
                        )}
                      >
                        <CardActionArea>
                          <CardContent>
                            <div
                              className={
                                classes.videoInputDialogControlSectionStyle
                              }
                            >
                              <CustomButton
                                className={
                                  classes.videoInputDialogControlButtonStyle
                                }
                                primaryButtonStyle={!select_video_file}
                                secondaryButtonStyle={select_video_file}
                                size="medium"
                                onClick={_ =>
                                  handleSetState({ select_video_file: false })
                                }
                              >
                                <div
                                  className={
                                    classes.videoInputDialogControlButtonUseTextDescStyle
                                  }
                                >
                                  {t(
                                    'createProject.inputs.video.dialogURLToggle',
                                  )}
                                </div>
                                <InsertLinkIcon
                                  className={
                                    classes.videoInputDialogControlButtonUseIconDescStyle
                                  }
                                />
                              </CustomButton>
                              <CustomButton
                                className={
                                  classes.videoInputDialogControlButtonStyle
                                }
                                primaryButtonStyle={select_video_file}
                                secondaryButtonStyle={!select_video_file}
                                size="medium"
                                onClick={_ =>
                                  handleSetState(
                                    handleSelectVideoFileChecked(
                                      refs.video_file_el.current,
                                    ),
                                  )
                                }
                              >
                                <div
                                  className={
                                    classes.videoInputDialogControlButtonUseTextDescStyle
                                  }
                                >
                                  {t(
                                    'createProject.inputs.video.dialogFileToggle',
                                  )}
                                </div>
                                <MovieIcon
                                  className={
                                    classes.videoInputDialogControlButtonUseIconDescStyle
                                  }
                                />
                              </CustomButton>
                            </div>
                            <Grid container spacing={1} alignItems="flex-end">
                              <Grid
                                item
                                xs={12}
                                sm={12}
                                className={clsx(
                                  common_classes.marginTop1em,
                                  classes.videoInputDialogBodyGridStyle,
                                )}
                              >
                                {!select_video_file ? (
                                  <FormControl
                                    className={clsx(
                                      classes.margin,
                                      classes.textField,
                                      classes.videoInputDialogURLFormControlStyle,
                                    )}
                                    variant="outlined"
                                    size="small"
                                  >
                                    <InputLabel
                                      className={classes.customLabelStyle}
                                      htmlFor="url-input"
                                    >
                                      {t(
                                        'createProject.inputs.video.dialogURLFieldLabel',
                                      )}
                                    </InputLabel>
                                    <OutlinedInput
                                      ref={refs.video_el}
                                      className={classes.customInputStyle}
                                      type="text"
                                      name="url-input"
                                      labelWidth={calculateLabelWidth(
                                        t(
                                          'createProject.inputs.video.dialogURLFieldLabel',
                                        ),
                                        document,
                                      )}
                                      placeholder="https://youtube.com/..."
                                      onChange={async e =>
                                        handleSetState(
                                          await handleVideoFieldChange(
                                            e,
                                            refs,
                                            props,
                                            state,
                                            handleSetState,
                                          ),
                                        )
                                      }
                                    />
                                  </FormControl>
                                ) : null}
                                {select_video_file ? (
                                  <p className={classes.videoFileName}>
                                    {refs.video_file_el.current?.files?.[0]
                                      ? refs.video_file_el.current?.files?.[0]
                                          ?.name
                                      : t(
                                          'createProject.inputs.video.dialogFileToggle',
                                        )}
                                  </p>
                                ) : null}
                                <CustomButton
                                  className={
                                    classes.videoInputDialogActionButtonStyle
                                  }
                                  secondaryButtonStyle
                                  variant="outlined"
                                  size="medium"
                                  onClick={async () =>
                                    handleSetState({
                                      ...(await handleVideoFieldCancel(
                                        refs,
                                        props,
                                        state,
                                      )),
                                      video_upload_dialog_open: false,
                                    })
                                  }
                                >
                                  <CloseIcon />
                                </CustomButton>

                                <CustomButton
                                  className={
                                    classes.videoInputDialogActionButtonStyle
                                  }
                                  primaryButtonStyle
                                  size="medium"
                                  onClick={async () =>
                                    handleSetState({
                                      ...(await handleVideoSelectDone(
                                        refs,
                                        props,
                                        state,
                                      )),
                                      video_upload_dialog_open: false,
                                    })
                                  }
                                >
                                  <CheckIcon />
                                </CustomButton>

                                <input
                                  className={common_classes.displayNone}
                                  ref={refs.video_file_el}
                                  type="file"
                                  accept="video/*"
                                  id="video"
                                  name="video"
                                  onChange={async e => {
                                    handleSetState(
                                      await handleVideoFieldChange(
                                        e,
                                        refs,
                                        props,
                                        state,
                                        handleSetState,
                                      ),
                                    );
                                  }}
                                  onBlur={props.handleBlur}
                                />
                              </Grid>
                            </Grid>
                          </CardContent>
                        </CardActionArea>
                      </Card>
                    </Container>
                  </Dialog>
                </form>
                <Dialog
                  PaperProps={{
                    style: {
                      backgroundColor: 'transparent',
                      boxShadow: 'none',
                    },
                  }}
                  className={classes.uploadProgressDialogStyle}
                  open={media_upload.upload_dialog}
                  aria-labelledby="upload progress dialog"
                >
                  <Box
                    className={classes.uploadProgressIndicatorContainerStyle}
                  >
                    <CircularProgress
                      className={classes.uploadProgressStyle}
                      variant="determinate"
                      size={70}
                      thickness={6}
                      value={media_upload.upload_percent}
                    />
                    <Box
                      top={0}
                      left={0}
                      bottom={0}
                      right={0}
                      position="absolute"
                      display="flex"
                      alignItems="center"
                      justifyContent="center"
                    >
                      <Typography
                        className={classes.uploadProgressLabelStyle}
                        variant="caption"
                        component="div"
                      >{`${Math.round(
                        media_upload.upload_percent,
                      )}%`}</Typography>
                    </Box>
                  </Box>
                </Dialog>
              </CardContent>
            </CardActionArea>
          </Card>
        </Container>
      </Box>
    );
  }
}
Example #21
Source File: SendModal.js    From akashlytics-deploy with GNU General Public License v3.0 4 votes vote down vote up
SendModal = ({ onClose, onSendTransaction }) => {
  const classes = useStyles();
  const formRef = useRef();
  const [isBalanceClicked, setIsBalanceClicked] = useState(false);
  const [error, setError] = useState("");
  const { balance } = useWallet();
  const {
    handleSubmit,
    control,
    formState: { errors },
    watch,
    setValue,
    clearErrors
  } = useForm({
    defaultValues: {
      recipient: "",
      sendAmount: 0
    }
  });
  const { recipient } = watch();

  const onBalanceClick = () => {
    setIsBalanceClicked((prev) => !prev);
    setError("");
    clearErrors();
    setValue("sendAmount", uaktToAKT(balance - txFeeBuffer, 6));
  };

  const onSubmit = ({ sendAmount }) => {
    clearErrors();
    const amount = aktToUakt(sendAmount);

    if (!recipient) {
      setError(`You must set a recipient.`);
      return;
    }

    if (amount > balance) {
      setError(`You can't send more than you currently have in your balance. Current balance is: ${uaktToAKT(amount, 6)}AKT.`);
      return;
    }

    onSendTransaction(recipient.trim(), amount);
  };

  const onContinueClick = (event) => {
    event.preventDefault();
    formRef.current.dispatchEvent(new Event("submit", { cancelable: true, bubbles: true }));
  };

  return (
    <Dialog maxWidth="xs" fullWidth aria-labelledby="send-transaction-dialog-title" open={true} onClose={onClose}>
      <DialogTitle id="send-transaction-dialog-title">Send tokens</DialogTitle>
      <DialogContent dividers className={classes.dialogContent}>
        <form onSubmit={handleSubmit(onSubmit)} ref={formRef}>
          <FormControl error={!errors.recipient} className={classes.formControl} fullWidth>
            <Controller
              control={control}
              name="recipient"
              rules={{
                required: true
              }}
              render={({ fieldState, field }) => {
                const helperText = "Recipient is required.";

                return (
                  <TextField
                    {...field}
                    type="text"
                    variant="outlined"
                    label="Recipient"
                    error={!!fieldState.invalid}
                    helperText={fieldState.invalid && helperText}
                    className={classes.formValue}
                  />
                );
              }}
            />
          </FormControl>

          <Box marginBottom=".5rem" marginTop=".5rem" textAlign="right">
            <LinkTo onClick={() => onBalanceClick()}>Balance: {uaktToAKT(balance, 6)} AKT</LinkTo>
          </Box>

          <FormControl error={!errors.sendAmount} className={classes.formControl} fullWidth>
            <Controller
              control={control}
              name="sendAmount"
              rules={{
                required: true,
                validate: (value) => value > 0 && value < balance
              }}
              render={({ fieldState, field }) => {
                const helperText = fieldState.error?.type === "validate" ? "Invalid amount." : "Amount is required.";

                return (
                  <TextField
                    {...field}
                    type="number"
                    variant="outlined"
                    label="Amount"
                    autoFocus
                    error={!!fieldState.invalid}
                    helperText={fieldState.invalid && helperText}
                    className={classes.formValue}
                    inputProps={{ min: 0, step: 0.000001, max: uaktToAKT(balance - txFeeBuffer, 6) }}
                    InputProps={{
                      startAdornment: <InputAdornment position="start">AKT</InputAdornment>,
                      endAdornment: isBalanceClicked && (
                        <InputAdornment position="end">
                          <Chip label="MAX" size="small" color="primary" />
                        </InputAdornment>
                      )
                    }}
                    disabled={isBalanceClicked}
                  />
                );
              }}
            />
          </FormControl>
          {error && (
            <Alert severity="warning" className={classes.alert}>
              {error}
            </Alert>
          )}
        </form>
      </DialogContent>
      <DialogActions className={classes.dialogActions}>
        <Button onClick={onClose}>Cancel</Button>
        <Button onClick={onContinueClick} disabled={!!errors.sendAmount || !!errors.recipient} variant="contained" color="primary">
          Continue
        </Button>
      </DialogActions>
    </Dialog>
  );
}
Example #22
Source File: index.js    From yi-note with GNU General Public License v3.0 4 votes vote down vote up
Bookmarks = () => {
  const { t } = useTranslation('options');
  const { search } = useLocation();
  const {
    bookmarks: {
      bookmarks,
      tags,
      toolbar: { filtering, exporting, exportFormat }
    }
  } = useStoreState(state => state);
  const {
    fetchBookmarks,
    fetchTags,
    selectTag,
    toolbar: { setExportFormat }
  } = useStoreActions(actions => actions.bookmarks);

  useEffect(() => {
    let tagsFromUrl = [];
    const tagsStr = new URLSearchParams(search).get('tags');
    if (tagsStr) {
      tagsFromUrl = tagsStr.split(',');
    }
    fetchBookmarks();
    fetchTags(tagsFromUrl);
  }, [fetchBookmarks, fetchTags, search]);

  const handleSelectTag = tag => {
    selectTag(tag);
  };

  const handleExportFormatChange = e => setExportFormat(e.target.value);

  return (
    <StyledContainer>
      {bookmarks.length === 0 && !filtering ? (
        <NoBookmark />
      ) : (
        <Grid container>
          {exporting && (
            <Grid
              item
              container
              direction="row"
              alignItems="center"
              spacing={1}
            >
              <Grid item>
                <FormLabel>{t('bookmarks.export.format.label')}</FormLabel>
              </Grid>
              <Grid item>
                <RadioGroup
                  row
                  value={exportFormat}
                  onChange={handleExportFormatChange}
                >
                  <FormControlLabel
                    value="json"
                    control={<Radio size="small" />}
                    label="JSON"
                  />
                  <FormControlLabel
                    value="markdown"
                    control={<Radio size="small" />}
                    label="Markdown (no image)"
                  />
                </RadioGroup>
              </Grid>
            </Grid>
          )}
          {filtering && (
            <Grid item container spacing={1}>
              {tags.map(({ tag, selected }) => (
                <Grid item key={tag}>
                  <Chip
                    label={tag}
                    color={selected ? 'primary' : 'default'}
                    clickable
                    onClick={handleSelectTag.bind(null, tag)}
                  />
                </Grid>
              ))}
            </Grid>
          )}
          <Grid item>
            <List>
              {bookmarks.map(
                ({ id, title, description, url, image, selected }) => {
                  return (
                    <ListItem key={id}>
                      <BookmarkItem
                        id={id}
                        title={title}
                        description={description}
                        url={url}
                        image={image}
                        selected={selected}
                      />
                    </ListItem>
                  );
                }
              )}
            </List>
          </Grid>
        </Grid>
      )}
    </StyledContainer>
  );
}
Example #23
Source File: LeaseRow.js    From akashlytics-deploy with GNU General Public License v3.0 4 votes vote down vote up
LeaseRow = React.forwardRef(({ lease, setActiveTab, deploymentManifest, dseq, providers, loadDeploymentDetail }, ref) => {
  const { enqueueSnackbar } = useSnackbar();
  const providerInfo = providers?.find((p) => p.owner === lease?.provider);
  const { localCert } = useCertificate();
  const isLeaseActive = lease.state === "active";
  const [isServicesAvailable, setIsServicesAvailable] = useState(false);
  const { favoriteProviders, updateFavoriteProviders } = useLocalNotes();
  const [isViewingProviderDetail, setIsViewingProviderDetail] = useState(false);
  const isFavorite = favoriteProviders.some((x) => lease?.provider === x);
  const {
    data: leaseStatus,
    error,
    refetch: getLeaseStatus,
    isLoading: isLoadingLeaseStatus
  } = useLeaseStatus(providerInfo?.host_uri, lease, {
    enabled: isLeaseActive && !isServicesAvailable && !!providerInfo?.host_uri && !!localCert,
    refetchInterval: 10_000,
    onSuccess: (leaseStatus) => {
      if (leaseStatus) {
        checkIfServicesAreAvailable(leaseStatus);
      }
    }
  });
  const {
    data: providerStatus,
    isLoading: isLoadingProviderStatus,
    refetch: getProviderStatus
  } = useProviderStatus(providerInfo?.host_uri, {
    enabled: false,
    retry: false
  });
  const isLeaseNotFound = error && error.includes && error.includes("lease not found") && isLeaseActive;
  const servicesNames = leaseStatus ? Object.keys(leaseStatus.services) : [];
  const classes = useStyles();
  const [isSendingManifest, setIsSendingManifest] = useState(false);

  React.useImperativeHandle(ref, () => ({
    getLeaseStatus: loadLeaseStatus
  }));

  const loadLeaseStatus = useCallback(() => {
    if (isLeaseActive && providerInfo && localCert) {
      getLeaseStatus();
      getProviderStatus();
    }
  }, [isLeaseActive, providerInfo, localCert, getLeaseStatus, getProviderStatus]);

  const checkIfServicesAreAvailable = (leaseStatus) => {
    const servicesNames = leaseStatus ? Object.keys(leaseStatus.services) : [];
    const isServicesAvailable =
      servicesNames.length > 0
        ? servicesNames
            .map((n) => leaseStatus.services[n])
            .every((service, i) => {
              return service.available > 0;
            })
        : false;
    setIsServicesAvailable(isServicesAvailable);
  };

  useEffect(() => {
    loadLeaseStatus();
  }, [lease, providerInfo, localCert, loadLeaseStatus]);

  function handleExternalUrlClick(ev, externalUrl) {
    ev.preventDefault();

    window.electron.openUrl("http://" + externalUrl);
  }

  function handleEditManifestClick(ev) {
    ev.preventDefault();
    setActiveTab("EDIT");
  }

  async function sendManifest() {
    setIsSendingManifest(true);
    try {
      const doc = yaml.load(deploymentManifest);
      const manifest = deploymentData.Manifest(doc);

      await sendManifestToProvider(providerInfo, manifest, dseq, localCert);

      enqueueSnackbar(<Snackbar title="Manifest sent!" iconVariant="success" />, { variant: "success", autoHideDuration: 10_000 });

      loadDeploymentDetail();
    } catch (err) {
      enqueueSnackbar(<ManifestErrorSnackbar err={err} iconVariant="error" />, { variant: "error", autoHideDuration: null });
    }
    setIsSendingManifest(false);
  }

  const onStarClick = (event) => {
    event.preventDefault();
    event.stopPropagation();

    const newFavorites = isFavorite ? favoriteProviders.filter((x) => x !== lease.provider) : favoriteProviders.concat([lease.provider]);

    updateFavoriteProviders(newFavorites);
  };

  return (
    <>
      {isViewingProviderDetail && (
        <ProviderDetailModal provider={{ ...providerStatus, ...providerInfo }} onClose={() => setIsViewingProviderDetail(false)} address={lease.provider} />
      )}

      <Card className={classes.root} elevation={4}>
        <CardHeader
          classes={{ title: classes.cardHeaderTitle, root: classes.cardHeader }}
          title={
            <Box display="flex">
              <LabelValue
                label="Status:"
                value={
                  <>
                    <div>{lease.state}</div>
                    <StatusPill state={lease.state} size="small" />
                  </>
                }
              />
              <LabelValue label="GSEQ:" value={lease.gseq} marginLeft="1rem" fontSize="1rem" />
              <LabelValue label="OSEQ:" value={lease.oseq} marginLeft="1rem" fontSize="1rem" />

              {isLeaseActive && (
                <Box marginLeft="1rem" display="inline-flex">
                  <LinkTo onClick={() => setActiveTab("LOGS")}>View logs</LinkTo>
                </Box>
              )}
            </Box>
          }
        />
        <CardContent>
          <Box display="flex">
            <Box>
              <Box paddingBottom="1rem">
                <SpecDetail
                  cpuAmount={lease.cpuAmount}
                  memoryAmount={lease.memoryAmount}
                  storageAmount={lease.storageAmount}
                  color={isLeaseActive ? "primary" : "default"}
                />
              </Box>
              <LabelValue
                label="Price:"
                value={
                  <>
                    <PricePerMonth perBlockValue={uaktToAKT(lease.price.amount, 6)} />
                    <PriceEstimateTooltip value={uaktToAKT(lease.price.amount, 6)} />
                    <Box component="span" marginLeft=".5rem">
                      <FormattedNumber value={lease.price.amount} maximumSignificantDigits={18} />
                      uakt ({`~${getAvgCostPerMonth(lease.price.amount)}akt/month`})
                    </Box>
                  </>
                }
              />

              {isLeaseActive && (
                <LabelValue
                  label="Provider:"
                  value={
                    <>
                      {isLoadingProviderStatus && <CircularProgress size="1rem" />}
                      {providerStatus && (
                        <>
                          <Link to={UrlService.providerDetail(lease.provider)}>{providerStatus.name}</Link>

                          <Box display="flex" alignItems="center" marginLeft={1}>
                            <FavoriteButton isFavorite={isFavorite} onClick={onStarClick} />

                            {providerInfo.isAudited && (
                              <Box marginLeft=".5rem">
                                <AuditorButton provider={providerInfo} />
                              </Box>
                            )}

                            <Box marginLeft=".5rem" display="flex">
                              <LinkTo onClick={() => setIsViewingProviderDetail(true)}>View details</LinkTo>
                            </Box>
                          </Box>
                        </>
                      )}
                    </>
                  }
                  marginTop="5px"
                  marginBottom=".5rem"
                />
              )}
            </Box>

            {providerInfo && (
              <Box paddingLeft="1rem" flexGrow={1}>
                <ProviderAttributes provider={providerInfo} />
              </Box>
            )}
          </Box>

          {isLeaseNotFound && (
            <Alert severity="warning">
              The lease was not found on this provider. This can happen if no manifest was sent to the provider. To send one you can update your deployment in
              the <LinkTo onClick={handleEditManifestClick}>VIEW / EDIT MANIFEST</LinkTo> tab.
              {deploymentManifest && (
                <>
                  <Box margin="1rem 0">
                    <strong>OR</strong>
                  </Box>
                  <Button variant="contained" color="primary" disabled={isSendingManifest} onClick={sendManifest} size="small">
                    {isSendingManifest ? <CircularProgress size="1.5rem" /> : <span>Send manifest manually</span>}
                  </Button>
                </>
              )}
            </Alert>
          )}

          {!leaseStatus && isLoadingLeaseStatus && <CircularProgress size="1rem" />}

          {isLeaseActive &&
            leaseStatus &&
            leaseStatus.services &&
            servicesNames
              .map((n) => leaseStatus.services[n])
              .map((service, i) => (
                <Box mb={1} key={`${service.name}_${i}`}>
                  <Box display="flex" alignItems="center">
                    <LabelValue label="Group:" value={service.name} fontSize="1rem" />
                    {isLoadingLeaseStatus || !isServicesAvailable ? (
                      <Box display="inline-flex" marginLeft="1rem">
                        <CircularProgress size="1rem" />
                      </Box>
                    ) : (
                      <Box display="inline-flex" marginLeft=".5rem">
                        <Tooltip
                          classes={{ tooltip: classes.tooltip }}
                          arrow
                          interactive
                          title={
                            <>
                              Workloads can take some time to spin up. If you see an error when browsing the uri, it is recommended to refresh and wait a bit.
                              Check the{" "}
                              <LinkTo onClick={() => setActiveTab("LOGS")} className={classes.whiteLink}>
                                logs
                              </LinkTo>{" "}
                              for more information.
                            </>
                          }
                        >
                          <InfoIcon className={classes.tooltipIcon} fontSize="small" />
                        </Tooltip>
                      </Box>
                    )}
                  </Box>

                  <Box display="flex" alignItems="center" marginTop="2px">
                    <Box display="flex" alignItems="center">
                      <Typography variant="caption">Available:&nbsp;</Typography>
                      <Chip label={service.available} size="small" color={service.available > 0 ? "primary" : "default"} className={classes.serviceChip} />
                    </Box>
                    <Box display="flex" alignItems="center">
                      <Typography variant="caption" className={classes.marginLeft}>
                        Ready Replicas:&nbsp;
                      </Typography>
                      <Chip
                        label={service.ready_replicas}
                        size="small"
                        color={service.ready_replicas > 0 ? "primary" : "default"}
                        className={classes.serviceChip}
                      />
                    </Box>
                    <Box display="flex" alignItems="center">
                      <Typography variant="caption" className={classes.marginLeft}>
                        Total:&nbsp;
                      </Typography>
                      <Chip label={service.total} size="small" color="primary" className={classes.serviceChip} />
                    </Box>
                  </Box>

                  {leaseStatus.forwarded_ports && leaseStatus.forwarded_ports[service.name]?.length > 0 && (
                    <Box marginTop="4px">
                      <LabelValue
                        label="Forwarded Ports:"
                        value={leaseStatus.forwarded_ports[service.name].map((p) => (
                          <Box key={"port_" + p.externalPort} display="inline" mr={0.5}>
                            <LinkTo label={``} disabled={p.available < 1} onClick={(ev) => handleExternalUrlClick(ev, `${p.host}:${p.externalPort}`)}>
                              {p.externalPort}:{p.port}
                            </LinkTo>
                          </Box>
                        ))}
                      />
                    </Box>
                  )}

                  {service.uris?.length > 0 && (
                    <>
                      <Box marginTop=".5rem">
                        <LabelValue label="Uris:" />
                        <List dense>
                          {service.uris.map((uri) => {
                            return (
                              <ListItem key={uri} className={classes.listItem}>
                                <ListItemText
                                  primary={
                                    <LinkTo className={classes.link} onClick={(ev) => handleExternalUrlClick(ev, uri)}>
                                      {uri} <LaunchIcon fontSize="small" />
                                    </LinkTo>
                                  }
                                />
                                <ListItemSecondaryAction>
                                  <IconButton
                                    edge="end"
                                    aria-label="uri"
                                    size="small"
                                    onClick={(ev) => {
                                      copyTextToClipboard(uri);
                                      enqueueSnackbar(<Snackbar title="Uri copied to clipboard!" iconVariant="success" />, {
                                        variant: "success",
                                        autoHideDuration: 2000
                                      });
                                    }}
                                  >
                                    <FileCopyIcon fontSize="small" />
                                  </IconButton>
                                </ListItemSecondaryAction>
                              </ListItem>
                            );
                          })}
                        </List>
                      </Box>
                    </>
                  )}
                </Box>
              ))}
        </CardContent>
      </Card>
    </>
  );
})
Example #24
Source File: Dashboard.js    From medha-STPC with GNU Affero General Public License v3.0 4 votes vote down vote up
Dashboard = props => {
  const { container, className, ...rest } = props;
  const history = useHistory();
  const classes = useStyles();
  const inputLabel = React.useRef(null);
  const [zones, setZones] = useState([]);
  const [rpcs, setRpcs] = useState([]);
  const [monthData, setMonthData] = useState([]);
  const [yearData, setYearData] = useState([]);
  const [colleges, setColleges] = useState([]);
  const [status, setStatus] = useState({
    time: "",
    status: ""
  });
  const { setIndex } = useContext(SetIndexContext);
  const { setLoaderStatus } = useContext(LoaderContext);

  const [formState, setFormState] = useState({
    state: 1,
    values: {},
    zonerows: [],
    indrows: [],
    placementrows: [],
    flag: true,
    errors: {},
    greenButtonChecker: true
  });
  const setData = () => {
    setLoaderStatus(true);
    setFormState(formState => ({
      ...formState,
      zonerows: [
        createDataWorkshop("Overall Workshops", finalData.Workshops),
        createDataWorkshop("1st Year", finalData.FirstYear),
        createDataWorkshop("2nd Year", finalData.SecondYear),
        createDataWorkshop("Final Year", finalData.FinalYear),
        createDataWorkshop("Entrepreneurship", finalData.Entrepreneurship),
        createDataWorkshop(
          "1st Year Attendance",
          finalData.FirstYearAttendance
        ),
        createDataWorkshop(
          "2nd Year Attendance",
          finalData.SecondYearAttendance
        ),
        createDataWorkshop(
          "Final Year Attendance",
          finalData.FinalYearAttendance
        ),
        createDataWorkshop("Planned", finalData.PlannedWorkshops),
        createDataWorkshop("Achieved", finalData.AchievedWorkshops),
        createDataWorkshop("Unique Students", finalData.UniqueStudents),
        createDataWorkshop(
          "Instittions touched",
          finalData.Institutionstouched
        ),
        createDataWorkshop("Student Feedback", finalData.StudentFeedback),
        createDataWorkshop("TPO Feedback", finalData.TPOFeedback)
      ],
      indrows: [
        createDataind("Industrial Visit", finalData.IndustrialVisits),
        createDataind("Attendance", finalData.IndustrialVisitAttendance),
        createDataind("Planned", finalData.PlannedIndustrialVisit),
        createDataind("Achieved", finalData.AchievedIndustrialVisit),
        createDataind(
          "Student Feedback",
          finalData.IndustrialVisitStudentFeedback
        ),
        createDataind("TPO Feedback", finalData.IndustrialVisitTPOFeedback)
      ],
      placementrows: [
        createDataplacement("Placement", finalData.Placement),
        createDataplacement("Attended", finalData.PlacementAttended),
        createDataplacement("Hired", finalData.PlacementSelected),
        createDataplacement(
          "Student Feedback",
          finalData.PlacementStudentFeedback
        ),
        createDataplacement("TPO Feedback", finalData.PlacementTPOFeedback),
        createDataplacement(
          "College Feedback",
          finalData.PlacementCollegeFeedback
        )
      ]
    }));

    setLoaderStatus(false);
  };

  /** Initial data bringing for all the filters role wise */
  useEffect(() => {
    if (auth.getUserInfo().role.name === roleConstants.STUDENT) {
      history.push({
        pathname: routeConstants.NOT_FOUND_URL
      });
    } else {
      setLoaderStatus(true);
      getStatusOfDashboard();
      prefillInitialDataRoleWise();
      setData();
      getInitialData();
    }
  }, []);

  const getStatusOfDashboard = async () => {
    let STATUS_URL = strapiApiConstants.STRAPI_DB_URL + "dashboard-histories";

    await serviceProvider
      .serviceProviderForGetRequest(STATUS_URL)
      .then(res => {
        if (res.data.length) {
          let today = new Date();
          let updatedDate = new Date(res.data[0].created_at);
          let days = parseInt((today - updatedDate) / (1000 * 60 * 60 * 24));
          let hours = parseInt(
            (Math.abs(today - updatedDate) / (1000 * 60 * 60)) % 24
          );
          let minutes = parseInt(
            (Math.abs(today.getTime() - updatedDate.getTime()) / (1000 * 60)) %
              60
          );
          let seconds = parseInt(
            (Math.abs(today.getTime() - updatedDate.getTime()) / 1000) % 60
          );

          let updatedTime = "";
          if (days !== 0) {
            updatedTime =
              days +
              " days, " +
              hours +
              " hours, " +
              minutes +
              " minutes, " +
              seconds +
              " seconds ago";
          } else if (hours !== 0) {
            updatedTime =
              hours +
              " hours, " +
              minutes +
              " minutes, " +
              seconds +
              " seconds ago";
          } else if (minutes !== 0) {
            updatedTime = minutes + " minutes, " + seconds + " seconds ago";
          } else {
            updatedTime = seconds + " seconds ago";
          }

          setStatus(status => ({
            ...status,
            time: updatedTime,
            status: res.data[0].status
          }));
        } else {
          setStatus(status => ({
            ...status,
            time: null,
            status: null
          }));
        }
      })
      .catch(error => {
        console.log("error", error);
      });
  };

  const prefillInitialDataRoleWise = () => {
    if (
      auth.getUserInfo().role.name === roleConstants.MEDHAADMIN ||
      auth.getUserInfo().role.name === roleConstants.DEPARTMENTADMIN
    ) {
      formState.values = {};
    } else if (auth.getUserInfo().role.name === roleConstants.ZONALADMIN) {
      formState.values = {
        zone: auth.getUserInfo().zone.id
      };
    } else if (
      auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
      auth.getUserInfo().studentInfo.organization.contact.id ===
        auth.getUserInfo().rpc.main_college
    ) {
      formState.values = {
        rpc: auth.getUserInfo().rpc.id
      };
    } else if (
      auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
      auth.getUserInfo().rpc.main_college !== null &&
      auth.getUserInfo().studentInfo.organization.contact.id !==
        auth.getUserInfo().rpc.main_college
    ) {
      formState.values = {
        zone: auth.getUserInfo().zone.id,
        rpc: auth.getUserInfo().rpc.id,
        contact: auth.getUserInfo().studentInfo.organization.contact.id
      };
    }
  };

  const getInitialData = () => {
    setLoaderStatus(true);
    setYears(true);
    if (
      auth.getUserInfo().role.name === roleConstants.MEDHAADMIN ||
      auth.getUserInfo().role.name === roleConstants.DEPARTMENTADMIN
    ) {
      fetchZoneRpcDistrictData();
    } else if (auth.getUserInfo().role.name === roleConstants.ZONALADMIN) {
      fetchAllRpc();
    } else if (
      auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
      auth.getUserInfo().studentInfo.organization.contact.id ===
        auth.getUserInfo().rpc.main_college
    ) {
      fetchCollegesToRPC();
    }
    setLoaderStatus(false);
  };

  const fetchCollegesToRPC = async () => {
    let COLLEGE_URL =
      strapiApiConstants.STRAPI_DB_URL +
      strapiApiConstants.STRAPI_RPCS +
      "/" +
      auth.getUserInfo().rpc.id +
      "/colleges";

    await serviceProvider
      .serviceProviderForGetRequest(COLLEGE_URL)
      .then(res => {
        setColleges(res.data.result);
      })
      .catch(error => {
        console.log("error", error);
      });
  };

  /** Get Data */
  function createDataWorkshop(workshop, zoneresult) {
    return { workshop, zoneresult };
  }

  function createDataind(industry, industryresult) {
    return { industry, industryresult };
  }

  function createDataplacement(placement, placementresult) {
    return { placement, placementresult };
  }

  const generateEntityDataForDownload = (name, result) => {
    return [
      { value: name, style: { font: { sz: "12" } } },
      {
        value: "" + result + "",
        style: { font: { sz: "12" } }
      }
    ];
  };

  const generateHeaders = name => {
    return [{ value: name, style: { font: { sz: "12", bold: true } } }];
  };

  /** Fetch all rpc */
  const fetchAllRpc = async () => {
    await serviceProvider
      .serviceProviderForGetRequest(RPCS, { pageSize: -1 })
      .then(res => {
        setRpcs(res.data.result);
      })
      .catch(error => {
        console.log("error", error);
      });
  };

  /** Sets Years */
  const setYears = isInitialized => {
    let startingYear = 1990;
    let currentYear = new Date().getFullYear();
    let diff = currentYear - startingYear;
    let yearArray = [startingYear];
    for (let i = 1; i <= diff; i++) {
      yearArray.push(startingYear + i);
    }
    if (isInitialized) {
      formState.values[year] = currentYear;
      formState.values[month] = new Date().getMonth() + 1;
      generateData();
    }
    setYearData(yearArray);
  };

  /** Set month on year */
  useEffect(() => {
    if (formState.values[year]) {
      getMonthsOnYears();
    }
  }, [formState.values[year]]);

  const getMonthsOnYears = () => {
    let currentYear = new Date().getFullYear();
    let currentMonth = new Date().getMonth() + 1;
    let monthArray = [];
    if (formState.values[year] == currentYear) {
      tempMonthArray.forEach(data => {
        if (data["id"] <= currentMonth) {
          monthArray.push(data);
        }
      });
      setMonthData(monthArray);
    } else {
      setMonthData(tempMonthArray);
    }
  };

  useEffect(() => {
    if (formState.values[zone] && formState.values[rpc]) {
      fetchCollegeData();
    }
  }, [formState.values[zone], formState.values[rpc]]);

  /** Function to get college data after selcting zones and rpc's */
  async function fetchCollegeData() {
    let params = {
      "zone.id": formState.values[zone],
      "rpc.id": formState.values[rpc],
      pageSize: -1
    };

    await serviceProvider
      .serviceProviderForGetRequest(COLLEGE_URL, params)
      .then(res => {
        setColleges(res.data.result);
      })
      .catch(error => {
        console.log("error", error);
      });
  }

  const generateData = async () => {
    if (Object.keys(formState.values) !== 0) {
      if (
        auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
        auth.getUserInfo().studentInfo.organization.contact.id ===
          auth.getUserInfo().rpc.main_college
      ) {
        _.assign(formState.values, { isRpc: true });
      }
      setLoaderStatus(true);
      await serviceProvider
        .serviceProviderForGetRequest(DASHBOARD_URL, formState.values)
        .then(res => {
          Object.keys(finalData).map(data => {
            finalData[data] = res.data[data];
          });
          setDataForDownload();
          setData();
        })
        .catch(error => {
          setLoaderStatus(false);
          console.log("error", error);
        });
    }
  };

  const setDataForDownload = async () => {
    let month = "-";
    let zone = "-";
    let rpc = "-";
    let college = "-";
    if (formState.values.hasOwnProperty("zone")) {
      for (let i in zones) {
        if (zones[i]["id"] === formState.values.zone) {
          zone = zones[i]["name"];
          break;
        }
      }
    }
    if (formState.values.hasOwnProperty("rpc")) {
      for (let i in rpcs) {
        if (rpcs[i]["id"] === formState.values.rpc) {
          rpc = rpcs[i]["name"];
          break;
        }
      }
    }
    if (formState.values.hasOwnProperty("contact")) {
      for (let i in colleges) {
        if (colleges[i]["id"] === formState.values.contact) {
          college = colleges[i]["name"];
          break;
        }
      }
    }
    for (let i in tempMonthArray) {
      if (tempMonthArray[i]["id"] === formState.values.Month) {
        month = tempMonthArray[i]["name"];
        break;
      }
    }
    let roleName = auth.getUserInfo().role.name;
    multiDataSet = [
      {
        columns: ["", ""],
        data: [
          [
            { value: "Login Name", style: { font: { sz: "12", bold: true } } },
            {
              value: roleName,
              style: { font: { sz: "12" } }
            }
          ],
          [
            { value: "Year", style: { font: { sz: "12", bold: true } } },
            {
              value: "" + formState.values.Year + "",
              style: { font: { sz: "12" } }
            }
          ],
          [
            { value: "Month", style: { font: { sz: "12", bold: true } } },
            { value: month, style: { font: { sz: "12" } } }
          ],
          [
            { value: "Zone", style: { font: { sz: "12", bold: true } } },
            { value: zone, style: { font: { sz: "12" } } }
          ],
          [
            { value: "RPC", style: { font: { sz: "12", bold: true } } },
            { value: rpc, style: { font: { sz: "12" } } }
          ],
          [
            { value: "College", style: { font: { sz: "12", bold: true } } },
            { value: college, style: { font: { sz: "12" } } }
          ],

          [{ value: "" }, { value: "" }],
          generateHeaders("Headers"),
          [{ value: "" }, { value: "" }],
          generateEntityDataForDownload("Workshops", finalData.Workshops),
          generateEntityDataForDownload(
            "TPO Feedback",
            finalData.TPOFeedback +
              finalData.IndustrialVisitTPOFeedback +
              finalData.PlacementTPOFeedback
          ),
          generateEntityDataForDownload(
            "Student Feedback",
            finalData.StudentFeedback +
              finalData.IndustrialVisitStudentFeedback +
              finalData.PlacementStudentFeedback
          ),
          generateEntityDataForDownload(
            "Industrial Visits",
            finalData.IndustrialVisits
          ),
          generateEntityDataForDownload("Hired", finalData.PlacementSelected),
          [{ value: "" }, { value: "" }],
          generateHeaders("Workshop"),
          [{ value: "" }, { value: "" }],
          generateEntityDataForDownload(
            "Overall Workshops",
            finalData.Workshops
          ),
          generateEntityDataForDownload("1st Year", finalData.FirstYear),
          generateEntityDataForDownload("2nd Year", finalData.SecondYear),
          generateEntityDataForDownload("Final Year", finalData.FinalYear),
          generateEntityDataForDownload(
            "Entrepreneurship",
            finalData.Entrepreneurship
          ),
          generateEntityDataForDownload(
            "1st Year Attendance",
            finalData.FirstYearAttendance
          ),
          generateEntityDataForDownload(
            "2nd Year Attendance",
            finalData.SecondYearAttendance
          ),
          generateEntityDataForDownload(
            "Final Year Attendance",
            finalData.FinalYearAttendance
          ),
          generateEntityDataForDownload("Planned", finalData.PlannedWorkshops),
          generateEntityDataForDownload(
            "Achieved",
            finalData.AchievedWorkshops
          ),
          generateEntityDataForDownload(
            "Unique Students",
            finalData.UniqueStudents
          ),
          generateEntityDataForDownload(
            "Instittions touched",
            finalData.Institutionstouched
          ),
          generateEntityDataForDownload(
            "Student Feedback",
            finalData.StudentFeedback
          ),
          generateEntityDataForDownload("TPO Feedback", finalData.TPOFeedback),
          [{ value: "" }, { value: "" }],
          generateHeaders("Industrial Visit"),
          [{ value: "" }, { value: "" }],
          generateEntityDataForDownload(
            "Industrial Visit",
            finalData.IndustrialVisits
          ),
          generateEntityDataForDownload(
            "Attendance",
            finalData.IndustrialVisitAttendance
          ),
          generateEntityDataForDownload(
            "Planned",
            finalData.PlannedIndustrialVisit
          ),
          generateEntityDataForDownload(
            "Achieved",
            finalData.AchievedIndustrialVisit
          ),
          generateEntityDataForDownload(
            "Student Feedback",
            finalData.IndustrialVisitStudentFeedback
          ),
          generateEntityDataForDownload(
            "TPO Feedback",
            finalData.IndustrialVisitTPOFeedback
          ),
          [{ value: "" }, { value: "" }],
          generateHeaders("Placement"),
          [{ value: "" }, { value: "" }],
          generateEntityDataForDownload("Placement", finalData.Placement),
          generateEntityDataForDownload(
            "Attended",
            finalData.PlacementAttended
          ),
          generateEntityDataForDownload("Hired", finalData.PlacementSelected),
          generateEntityDataForDownload(
            "Student Feedback",
            finalData.PlacementStudentFeedback
          ),
          generateEntityDataForDownload(
            "TPO Feedback",
            finalData.PlacementTPOFeedback
          ),
          generateEntityDataForDownload(
            "College Feedback",
            finalData.PlacementCollegeFeedback
          )
        ]
      }
    ];
  };

  async function fetchZoneRpcDistrictData() {
    if (
      formState.state &&
      formState.state !== null &&
      formState.state !== undefined &&
      formState.state !== ""
    ) {
      let zones_url =
        STATES_URL +
        "/" +
        formState.state +
        "/" +
        strapiApiConstants.STRAPI_ZONES;

      await serviceProvider
        .serviceProviderForGetRequest(zones_url)
        .then(res => {
          setZones(res.data.result);
        })
        .catch(error => {
          console.log("error", error);
        });

      let rpcs_url =
        STATES_URL +
        "/" +
        formState.state +
        "/" +
        strapiApiConstants.STRAPI_RPCS;

      await serviceProvider
        .serviceProviderForGetRequest(rpcs_url)
        .then(res => {
          if (Array.isArray(res.data)) {
            setRpcs(res.data[0].result);
          } else {
            setRpcs(res.data.result);
          }
        })
        .catch(error => {
          console.log("error", error);
        });
    }
  }

  /** Handle change for autocomplete fields */
  const handleChangeAutoComplete = (eventName, event, value) => {
    /**TO SET VALUES OF AUTOCOMPLETE */
    if (value !== null) {
      if (eventName !== year && eventName !== college) {
        setFormState(formState => ({
          ...formState,
          values: {
            ...formState.values,
            [eventName]: value.id
          }
        }));
      } else if (eventName === college) {
        setFormState(formState => ({
          ...formState,
          values: {
            ...formState.values,
            [eventName]: value.contact.id
          }
        }));
      } else {
        setFormState(formState => ({
          ...formState,
          values: {
            ...formState.values,
            [eventName]: value
          }
        }));
      }

      if (eventName === state) {
        fetchZoneRpcDistrictData();
      }
      if (formState.errors.hasOwnProperty(eventName)) {
        delete formState.errors[eventName];
      }
    } else {
      if (eventName === zone || eventName === rpc) {
        setColleges([]);
        delete formState.values[college];
      } else if (eventName === year) {
        setMonthData([]);
        delete formState.values[month];
      }
      /** This is used to remove clear out data form auto complete when we click cross icon of auto complete */
      setFormState(formState => ({
        ...formState,
        flag: !formState.flag
      }));
      delete formState.values[eventName];
    }
  };

  const handleSubmit = event => {
    setLoaderStatus(true);
    let isValid = false;
    formState.values = _.omit(formState.values, ["isRpc"]);
    /** Checkif all fields are present in the submitted form */
    let checkAllFieldsValid = formUtilities.checkAllKeysPresent(
      formState.values,
      DashboardSchema
    );
    if (checkAllFieldsValid) {
      /** Evaluated only if all keys are valid inside formstate */
      formState.errors = formUtilities.setErrors(
        formState.values,
        DashboardSchema
      );
      /** Checks if the form is empty */
      if (formUtilities.checkEmpty(formState.errors)) {
        isValid = true;
      }
    } else {
      /** This is used to find out which all required fields are not filled */
      formState.values = formUtilities.getListOfKeysNotPresent(
        formState.values,
        DashboardSchema
      );
      /** This sets errors by comparing it with the json schema provided */
      formState.errors = formUtilities.setErrors(
        formState.values,
        DashboardSchema
      );
    }
    if (isValid) {
      /** CALL POST FUNCTION */
      generateData();
    } else {
      setFormState(formState => ({
        ...formState,
        flag: !formState.flag
      }));
      setLoaderStatus(false);
    }
    event.preventDefault();
  };

  const StyledTableCell = withStyles(theme =>
    createStyles({
      head: {
        backgroundColor: "#000000",
        color: "#ffffff",
        padding: "10px",
        fontSize: "14px",
        fontWeight: 700
      },
      body: {
        fontSize: "14px",
        padding: "8px"
      }
    })
  )(TableCell);

  const StyledTableRow = withStyles(theme =>
    createStyles({
      root: {
        "&:nth-of-type(odd)": {
          backgroundColor: theme.palette.background.default
        }
      }
    })
  )(TableRow);

  const clearFilter = () => {
    prefillInitialDataRoleWise();
    setYears(true);
    if (
      auth.getUserInfo().role.name === roleConstants.MEDHAADMIN ||
      auth.getUserInfo().role.name === roleConstants.ZONALADMIN ||
      auth.getUserInfo().role.name === roleConstants.DEPARTMENTADMIN
    ) {
      setColleges([]);
    }
    setFormState(formState => ({
      ...formState,
      errors: {}
    }));
  };

  const hasError = field => (formState.errors[field] ? true : false);
  return (
    <div className={classes.root}>
      <Grid container spacing={2}>
        <Grid item lg sm={6} xl={3} xs={12}>
          <Card {...rest} className={clsx(classes.root, className)}>
            <CardHeader
              classes={{
                title: classes.title,
                root: classes.titleRoot
              }}
              title="Workshops"
              color="textSecondary"
              align="center"
            />
            <CardContent>
              <Typography variant="h1" align="center">
                {finalData.Workshops}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
        <Grid item lg sm={6} xl={3} xs={12}>
          <Card {...rest} className={clsx(classes.root, className)}>
            <CardHeader
              classes={{
                title: classes.title,
                root: classes.titleRoot
              }}
              title="TPO Feedback"
              color="textSecondary"
              align="center"
            />
            <CardContent>
              <Typography variant="h1" align="center">
                {finalData.TPOFeedback +
                  finalData.IndustrialVisitTPOFeedback +
                  finalData.PlacementTPOFeedback}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
        <Grid item lg sm={6} xl={3} xs={12}>
          <Card {...rest} className={clsx(classes.root, className)}>
            <CardHeader
              classes={{
                title: classes.title,
                root: classes.titleRoot
              }}
              title="Student Feedback"
              color="textSecondary"
              align="center"
            />
            <CardContent>
              <Typography variant="h1" align="center">
                {finalData.StudentFeedback +
                  finalData.IndustrialVisitStudentFeedback +
                  finalData.PlacementStudentFeedback}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
        <Grid item lg sm={6} xl={3} xs={12}>
          <Card {...rest} className={clsx(classes.root, className)}>
            <CardHeader
              classes={{
                title: classes.title,
                root: classes.titleRoot
              }}
              title="Industrial Visits"
              color="textSecondary"
              align="center"
            />
            <CardContent>
              <Typography variant="h1" align="center">
                {finalData.IndustrialVisits}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
        <Grid item lg md={6} xl={3} xs={12}>
          <Card {...rest} className={clsx(classes.root, className)}>
            <CardHeader
              classes={{
                title: classes.title,
                root: classes.titleRoot
              }}
              title="Hired"
              color="textSecondary"
              align="center"
            />
            <CardContent>
              <Typography variant="h1" align="center">
                {finalData.PlacementSelected}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
        <Grid item lg={12} md={6} xl={9} xs={12}>
          <Card className={classes.root} variant="outlined">
            <CardContent>
              <Grid container spacing={3} className={classes.formgrid}>
                {auth.getUserInfo().role.name === roleConstants.MEDHAADMIN ||
                auth.getUserInfo().role.name ===
                  roleConstants.DEPARTMENTADMIN ? (
                  <Grid item md={2} xs={12}>
                    <FormControl
                      variant="outlined"
                      fullWidth
                      className={classes.formControl}
                    >
                      <Autocomplete
                        id={"zoneDemo"}
                        options={zones}
                        getOptionLabel={option => option.name}
                        /* This is used to set the default value to the auto complete */
                        name={"demo-id"}
                        onChange={(event, value) => {
                          handleChangeAutoComplete(zone, event, value);
                        }}
                        value={
                          zones[
                            zones.findIndex(function (item, i) {
                              return item.id === formState.values[zone];
                            })
                          ] || null /** Please give a default " " blank value */
                        }
                        renderInput={params => (
                          <TextField
                            {...params}
                            label={"Select Zone"}
                            placeholder={"Select Zone"}
                            variant="outlined"
                          />
                        )}
                      />
                    </FormControl>
                  </Grid>
                ) : null}

                {auth.getUserInfo().role.name === roleConstants.MEDHAADMIN ||
                auth.getUserInfo().role.name === roleConstants.ZONALADMIN ||
                auth.getUserInfo().role.name ===
                  roleConstants.DEPARTMENTADMIN ? (
                  <Grid item md={2} xs={12}>
                    <FormControl
                      variant="outlined"
                      fullWidth
                      className={classes.formControl}
                    >
                      <Autocomplete
                        id={"regionDemo"}
                        options={rpcs}
                        getOptionLabel={option => option.name}
                        /* This is used to set the default value to the auto complete */
                        name={"demo-id"}
                        onChange={(event, value) => {
                          handleChangeAutoComplete(rpc, event, value);
                        }}
                        value={
                          rpcs[
                            rpcs.findIndex(function (item, i) {
                              return item.id === formState.values[rpc];
                            })
                          ] || null /** Please give a default " " blank value */
                        }
                        renderInput={params => (
                          <TextField
                            {...params}
                            placeholder={"Select Region"}
                            label={"Select Region"}
                            variant="outlined"
                          />
                        )}
                      />
                    </FormControl>
                  </Grid>
                ) : null}

                {auth.getUserInfo().role.name === roleConstants.MEDHAADMIN ||
                auth.getUserInfo().role.name ===
                  roleConstants.DEPARTMENTADMIN ||
                auth.getUserInfo().role.name === roleConstants.ZONALADMIN ||
                (auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
                  auth.getUserInfo().studentInfo.organization.contact.id ===
                    auth.getUserInfo().rpc.main_college) ? (
                  <Grid item md={2} xs={12}>
                    <FormControl
                      variant="outlined"
                      fullWidth
                      className={classes.formControl}
                    >
                      <Autocomplete
                        id={"collegeDemo"}
                        options={colleges}
                        getOptionLabel={option => option.name}
                        /* This is used to set the default value to the auto complete */
                        name={"demo-id"}
                        onChange={(event, value) => {
                          handleChangeAutoComplete(college, event, value);
                        }}
                        value={
                          colleges[
                            colleges.findIndex(function (item, i) {
                              return (
                                item.contact.id === formState.values[college]
                              );
                            })
                          ] || null /** Please give a default " " blank value */
                        }
                        renderInput={params => (
                          <TextField
                            {...params}
                            placeholder={"Select College"}
                            label={"Select College"}
                            variant="outlined"
                          />
                        )}
                      />
                    </FormControl>
                  </Grid>
                ) : null}

                <Grid item md={2} xs={12}>
                  <FormControl
                    variant="outlined"
                    fullWidth
                    className={classes.formControl}
                  >
                    <Autocomplete
                      id={DashboardSchema[year]["id"]}
                      options={yearData}
                      getOptionLabel={option => "" + option + ""}
                      /* This is used to set the default value to the auto complete */
                      name={DashboardSchema[year]["name"]}
                      onChange={(event, value) => {
                        handleChangeAutoComplete(year, event, value);
                      }}
                      value={
                        yearData[
                          yearData.findIndex(function (item, i) {
                            return item === formState.values[year];
                          })
                        ] || null /** Please give a default " " blank value */
                      }
                      renderInput={params => (
                        <TextField
                          {...params}
                          placeholder={DashboardSchema[year]["placeholder"]}
                          label={DashboardSchema[year]["label"]}
                          variant="outlined"
                          error={hasError(year)}
                          helperText={
                            hasError(year)
                              ? formState.errors[year].map(error => {
                                  return error + " ";
                                })
                              : null
                          }
                        />
                      )}
                    />
                  </FormControl>
                </Grid>
                <Grid item md={2} xs={12}>
                  <FormControl
                    variant="outlined"
                    fullWidth
                    className={classes.formControl}
                  >
                    <Autocomplete
                      id={DashboardSchema[month]["id"]}
                      options={monthData}
                      getOptionLabel={option => option.name}
                      /* This is used to set the default value to the auto complete */
                      name={DashboardSchema[month]["name"]}
                      onChange={(event, value) => {
                        handleChangeAutoComplete(month, event, value);
                      }}
                      value={
                        monthData[
                          monthData.findIndex(function (item, i) {
                            return item.id === formState.values[month];
                          })
                        ] || null /** Please give a default " " blank value */
                      }
                      renderInput={params => (
                        <TextField
                          {...params}
                          placeholder={DashboardSchema[month]["placeholder"]}
                          label={DashboardSchema[month]["label"]}
                          variant="outlined"
                          error={hasError(month)}
                          helperText={
                            hasError(month)
                              ? formState.errors[month].map(error => {
                                  return error + " ";
                                })
                              : null
                          }
                        />
                      )}
                    />
                  </FormControl>
                </Grid>
                {/** <Grid item md={2} xs={12}>
                  <FormControl
                    variant="outlined"
                    fullWidth
                    className={classes.formControl}
                  >
                    <InputLabel ref={inputLabel} id="select-trainer">
                      Select Trainer
                    </InputLabel>
                    <Autocomplete
                      id={"trainerDemo"}
                      options={[]}
                      getOptionLabel={option => option.name}
                      name={"demo-id"}
                      renderInput={params => (
                        <TextField
                          {...params}
                          placeholder={"Select Trainer"}
                          value={option => option.id}
                          name={"demo"}
                          key={option => option.id}
                          variant="outlined"
                        />
                      )}
                    />
                  </FormControl>
                </Grid>*/}
                <Grid item md={2} xs={12} className={classes.dash_search_btn}>
                  <Grid item className={classes.filterButtonsMargin}>
                    <YellowButton
                      id="handle_submit"
                      variant="contained"
                      color="primary"
                      disableElevation
                      onClick={handleSubmit}
                    >
                      {genericConstants.SEARCH_BUTTON_TEXT}
                    </YellowButton>
                  </Grid>
                  <Grid item className={classes.filterButtonsMargin}>
                    <GrayButton
                      variant="contained"
                      color="primary"
                      disableElevation
                      onClick={clearFilter}
                    >
                      {genericConstants.RESET_BUTTON_TEXT}
                    </GrayButton>
                  </Grid>
                </Grid>
              </Grid>
            </CardContent>
          </Card>
          <Card className={classes.marginCard} variant="outlined">
            <CardContent>
              <Grid item md={4} xs={12}>
                <TableContainer component={Paper}>
                  <Table
                    className={classes.table}
                    aria-label="customized table"
                  >
                    <TableHead>
                      <TableRow>
                        <StyledTableCell>Workshop</StyledTableCell>
                        <StyledTableCell></StyledTableCell>
                      </TableRow>
                    </TableHead>

                    <TableBody>
                      {formState.zonerows.map(zonerow => (
                        <StyledTableRow key={zonerow.workshop}>
                          <StyledTableCell component="th" scope="zonerow">
                            {zonerow.workshop}
                          </StyledTableCell>
                          <StyledTableCell align="right">
                            {zonerow.zoneresult}
                          </StyledTableCell>
                        </StyledTableRow>
                      ))}
                    </TableBody>
                  </Table>
                </TableContainer>
                <TableContainer
                  component={Paper}
                  className={classes.marginCard}
                >
                  <Table
                    className={classes.table}
                    aria-label="customized table"
                  >
                    <TableHead>
                      <TableRow>
                        <StyledTableCell>Industrial Visit</StyledTableCell>
                        <StyledTableCell></StyledTableCell>
                      </TableRow>
                    </TableHead>

                    <TableBody>
                      {formState.indrows.map(industry => (
                        <StyledTableRow key={industry.industry}>
                          <StyledTableCell component="th" scope="zonerow">
                            {industry.industry}
                          </StyledTableCell>
                          <StyledTableCell align="right">
                            {industry.industryresult}
                          </StyledTableCell>
                        </StyledTableRow>
                      ))}
                    </TableBody>
                  </Table>
                </TableContainer>
                <TableContainer
                  component={Paper}
                  className={classes.marginCard}
                >
                  <Table
                    className={classes.table}
                    aria-label="customized table"
                  >
                    <TableHead>
                      <TableRow>
                        <StyledTableCell>Placement</StyledTableCell>
                        <StyledTableCell></StyledTableCell>
                      </TableRow>
                    </TableHead>

                    <TableBody>
                      {formState.placementrows.map(placement => (
                        <StyledTableRow key={placement.placement}>
                          <StyledTableCell component="th" scope="zonerow">
                            {placement.placement}
                          </StyledTableCell>
                          <StyledTableCell align="right">
                            {placement.placementresult}
                          </StyledTableCell>
                        </StyledTableRow>
                      ))}
                    </TableBody>
                  </Table>
                </TableContainer>
              </Grid>
              <Grid item className={classes.move_right}>
                <ExcelFile
                  element={
                    <GreenButton
                      variant="contained"
                      color="secondary"
                      className={classes.greenButton}
                      startIcon={<GetAppIcon />}
                      onClick={() => {}}
                      greenButtonChecker={formState.greenButtonChecker}
                    >
                      Download
                    </GreenButton>
                  }
                >
                  <ExcelSheet dataSet={multiDataSet} name="Dashboard" />
                </ExcelFile>
              </Grid>
            </CardContent>
          </Card>
        </Grid>
        <Grid container spacing={2}>
          <Grid item lg={12} sm={12} xl={12} xs={12}>
            <div className={classes.move_right}>
              {status.status === "pending" ? (
                <>
                  <Chip
                    label={"Updating dashboard data"}
                    disabled
                    variant="outlined"
                    size="medium"
                  />
                  <CircularProgress size={18} />
                </>
              ) : status.status === "error" ? (
                <Chip
                  label={
                    "Updating dashboard data failed last updated " + status.time
                  }
                  disabled
                  variant="outlined"
                  size="medium"
                />
              ) : status.status === "completed" ? (
                <Chip
                  label={"Updated " + status.time}
                  disabled
                  variant="outlined"
                  size="medium"
                />
              ) : null}
            </div>
          </Grid>
        </Grid>
      </Grid>
    </div>
  );
}
Example #25
Source File: GeneralSkills.js    From resumeker-fe with MIT License 4 votes vote down vote up
function GeneralSkills(props) {
  const { data } = useQuery(DRAFT_ID);
  const [info, setInfo] = useState({
    draftID: "",
    skill: "",
    id: Date.now(),
  });
  const [activeStep, setActiveStep] = useState(6);
  //Instantiate useMutation Hook / Creates tuple with 1st var being actual
  //call function, and 2nd destructured variable being return data and tracking
  const [addSkill, { loading, error }] = useMutation(ADD_SKILL_MUTATION, {
    onCompleted(data) {
      console.log(data, "\n Add General Skill Response");
    },
  });
  const classes = useStyles();

  const addingData = () => {
    if (info.skill.length > 0) {
      props.addGeneralSkill(info);
      //Apollo useMutation API call to send data to backend
      addSkill({
        variables: {
          input: {
            draftID: localStorage.getItem("draftID"),
            skillType: "Qualitative",
            name: info.skill,
          },
        },
      });
    }
  };

  const nextPage = (event) => {
    event.preventDefault();
    addingData();
    props.setActiveStep((prevActiveStep) => prevActiveStep + 1);
    props.history.push("/form/languages");
  };
  const anotherSkill = (event) => {
    event.preventDefault();
    addingData();
    setInfo({
      ...info,
      skill: "",
      id: Date.now(),
    });
  };
  const onChange = (event) => {
    event.preventDefault();
    setInfo({ ...info, [event.target.name]: event.target.value });
  };
  const handleDelete = (skillToDelete) => (event) => {
    event.preventDefault();
    props.removeGeneralSkill(skillToDelete);
    setInfo({ ...info });
  };
  return (
    <div>
      <Grid container componet="main" className={classes.root}>
        <CssBaseline />
        <TipsLayout tips={Tip()} />
        <Grid item xs={12} sm={8} md={9} component={Paper} elevation={6} square>
          <MobileStepper
            variant="progress"
            steps={8}
            position="static"
            activeStep={props.activeStep}
            className={classes.progress}
          />
          <div className={classes.paper}>
            <Typography component="h1" variant="h5">
              Tell us about some of your other skills that didn't quite make it
              into the technical section!
            </Typography>
            <Typography
              color="textSecondary"
              component="h5"
              variant="subtitle2"
            >
              (Time Management, Critical Thinking, Teamwork, Problem Solving,
              Comunication, etc)
            </Typography>
            <form
              className={classes.form}
              onSubmit={anotherSkill}
              id="generalSkillsForm"
            >
              <SingleFieldFormTemplate
                onChange={onChange}
                info={info.skill}
                anotherOne={(e) => anotherSkill(e)}
                name="skill"
                label="General Skill"
              />
              <Grid className={classes.skillContainer}>
                <Paper
                  component="ul"
                  square="true"
                  className={classes.chipContainer}
                >
                  <Chip
                    label="Your Skills:"
                    className={classes.chip}
                    color="primary"
                  />
                  {props.resumeData.generalSkills.map((data) => {
                    return (
                      <li key={data.id} className="listOfGeneralSkills">
                        <Chip
                          label={data.skill}
                          onDelete={handleDelete(data)}
                          className={classes.chip}
                        />
                      </li>
                    );
                  })}
                </Paper>
              </Grid>
              <Grid className={classes.buttonContainer}>
                <Button
                  type="button"
                  fullWidth
                  variant="outlined"
                  color="primary"
                  id="previous_techSkills"
                  className={`${classes.previousButton} singlePageButton`}
                  onClick={() => {
                    props.setActiveStep((prevActiveStep) => prevActiveStep - 1);
                    props.history.push("/form/techskills");
                  }}
                >
                  Previous Form
                </Button>
                <Button
                  type="button"
                  fullWidth
                  variant="contained"
                  color="primary"
                  id="next_languages"
                  className={`${classes.nextButton} singlePageButton`}
                  onClick={(e) => nextPage(e)}
                >
                  Next Form
                </Button>
              </Grid>
            </form>
          </div>
        </Grid>
      </Grid>
      <button onClick={() => nextPage()}>Next Page</button>
    </div>
  );
}
Example #26
Source File: Form.js    From linked-in-clone with MIT License 4 votes vote down vote up
Form = () => {
  const classes = Styles();
  const theme = useTheme();
  const { displayName, photoURL } = useSelector((state) => state.user);

  const [uploadData, setUploadData] = useState({
    description: "",
    file: {
      type: "",
      name: "",
      data: "",
    },
  });

  const [progress, setProgress] = useState("");
  const [openURL, setOpenURL] = useState(false);
  const [URL, setURL] = useState("");

  const uploadToFirebaseDB = (fileData) => {
    // uploading to collection called posts
    db.collection("posts")
      .add({
        profile: photoURL,
        username: displayName,
        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
        description: uploadData.description,
        fileType: fileData === URL ? "image" : uploadData.file.type,
        fileName: uploadData.file.name,
        fileData: fileData,
      })
      .then(() => resetState());
  };

  const handleSubmitButton = async (e) => {
    e.preventDefault();

    // verify atleast one of the input fields are not empyt
    if (uploadData.description || uploadData.file.data || URL) {
      // if file input is true...upload the file to Fire-Store
      if (uploadData.file.data) {
        const id = uuid();
        const uploadTask = storage.ref(`posts/${id}`).putString(uploadData.file.data, "data_url");
        uploadTask.on(
          "state_changed",
          (snapshot) => {
            const value = Math.floor((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
            setProgress(value);
          },

          (error) => {
            alert(error);
          },

          () => {
            storage
              .ref("posts")
              .child(id)
              .getDownloadURL()
              .then((url) => uploadToFirebaseDB(url));
          }
        );

        // do not go further..
        return;
      }
      if (URL !== "") {
        if (URL.startsWith("data")) {
          swal("Invalid Image URL", "DATA-URL format is not allowed","warning");
          setURL("");
        } else if (URL.includes("youtu.be") || URL.includes("youtube")) {
          swal("Invalid Image URL","Youtube videos are not allowed","warning");
          setURL("");
        } else if (!URL.startsWith("http")) {
          swal("Invalid Image URL","Please enter valid image url","warning");
          setURL("");
        } else {
          uploadToFirebaseDB(URL);
        }
      } else {
        // if not file input provided
        uploadToFirebaseDB(uploadData.file.data);
      }
    } else {
      swal("Empty Post", "Please enter something","warning");
    }
  };

  const resetState = () => {
    setUploadData({
      description: "",
      file: {
        type: "",
        name: "",
        data: "",
      },
    });
    setProgress("");
    setOpenURL(false);
    setURL("");
  };

  const toggleURL_Tab = () => {
    if (uploadData.file.data !== "") {
      setOpenURL(false);
    } else if (URL === "") {
      setOpenURL(!openURL);
    } else {
      setOpenURL(true);
    }
  };

  const closeURL_Tab = () => {
    if (URL === "") {
      setOpenURL(false);
    } else {
      setOpenURL(true);
    }
  };

  return (
    <Paper className={classes.upload}>
      <div className={classes.upload__header}>
        <form className={classes.header__form} onSubmit={handleSubmitButton}>
          <CreateIcon />
          <input
            placeholder="Start a post"
            value={uploadData.description}
            onChange={(e) => setUploadData({ ...uploadData, description: e.target.value })}
          />
          <input
            id="upload-image"
            type="file"
            accept="image/*"
            hidden
            onChange={(e) => {
              imageUploadHandler(e, "image", uploadData, setUploadData);
              setOpenURL(false);
            }}
          />
          <input
            id="upload-video"
            type="file"
            accept="video/*"
            hidden
            onChange={(e) => {
              imageUploadHandler(e, "video", uploadData, setUploadData);
              setOpenURL(false);
            }}
          />
          <button type="submit">Post</button>
        </form>
      </div>
      {!openURL && !progress && uploadData.file.name && (
        <div className={classes.selectedFile}>
          <Chip
            color="primary"
            size="small"
            onDelete={resetState}
            icon={
              uploadData.file.type === "image" ? (
                <PhotoSizeSelectActualIcon />
              ) : (
                <VideocamRoundedIcon />
              )
            }
            label={uploadData.file.name}
          />
        </div>
      )}
      {!openURL && progress ? (
        <div className={classes.uploading}>
          <LinearProgress variant="determinate" value={progress} className={classes.progress} />
          <p>{progress} %</p>
        </div>
      ) : (
        ""
      )}
      {openURL && (
        <div className={classes.pasteURL_Input}>
          <InsertLinkIcon />
          <input
            placeholder="Paste an image URL"
            value={URL}
            onChange={(e) => setURL(e.target.value)}
          />
          {URL !== "" && (
            <HighlightOffIcon
              style={{ color: "orange", fontSize: 16 }}
              onClick={() => setURL("")}
            />
          )}
        </div>
      )}

      <div className={classes.upload__media}>
        <label
          htmlFor={URL === "" ? "upload-image" : ""}
          onClick={closeURL_Tab}
          className={classes.media__options}
        >
          <PhotoSizeSelectActualIcon
            style={{ color: theme.palette.type === "dark" ? LinkedInLightBlue : LinkedInBlue }}
          />
          <h4>Photo</h4>
        </label>
        <label
          htmlFor={URL === "" ? "upload-video" : ""}
          onClick={closeURL_Tab}
          className={classes.media__options}
        >
          <YouTubeIcon style={{ color: "orange" }} />
          <h4>Video</h4>
        </label>
        <div className={classes.media__options} onClick={toggleURL_Tab}>
          <InsertLinkIcon style={{ color: "#e88ee4", fontSize: 30 }} />
          <h4>URL</h4>
        </div>
        <div className={classes.media__options}>
          <CalendarViewDayIcon style={{ color: "#f5987e" }} />
          <h4>Write article</h4>
        </div>
      </div>
    </Paper>
  );
}
Example #27
Source File: Form.js    From facebook-clone with MIT License 4 votes vote down vote up
Form = () => {
  const classes = Styles();
  const { displayName, photoURL } = useSelector((state) => state.user);

  const [uploadData, setUploadData] = useState({
    description: "",
    file: {
      type: "",
      name: "",
      data: "",
    },
  });

  const [progress, setProgress] = useState("");

  const uploadToFirebaseDB = (fileData) => {
    // uploading to collection called posts
    db.collection("posts")
      .add({
        profile: photoURL,
        username: displayName,
        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
        description: uploadData.description,
        fileType: uploadData.file.type,
        fileName: uploadData.file.name,
        fileData: fileData,
      })
      .then(() => resetState());
  };

  const handleSubmitButton = (e) => {
    e.preventDefault();

    // verify atleast one of the input fields are not empyt
    if (uploadData.description || uploadData.file.data) {
      // if file input is true...upload the file to Fire-Store
      if (uploadData.file.data) {
        const id = uuid();
        const uploadTask = storage.ref(`posts/${id}`).putString(uploadData.file.data, "data_url");
        uploadTask.on(
          "state_changed",
          (snapshot) => {
            const value = Math.floor((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
            setProgress(value);
          },

          (error) => {
            alert(error);
          },

          () => {
            storage
              .ref("posts")
              .child(id)
              .getDownloadURL()
              .then((url) => uploadToFirebaseDB(url));
          }
        );

        // do not go further..
        return;
      }
      // if not file input provided
      uploadToFirebaseDB(uploadData.file.data);
    } else {
      swal("? Input field can not be empty");
    }
  };

  // if file name is too long.. compress it
  const fileNameCompressor = (str, limit) => {
    let fileName = str;
    const arr = str.split(".");
    const name = arr[0];
    const ext = arr[arr.length - 1];

    if (name.length > limit) {
      fileName = name.substring(0, limit).trim() + "... ." + ext;
    }
    return fileName;
  };

  const imageUploadHandler = async (e, type) => {
    const inputFile = e.target.files[0];
    const _inputFile = inputFile.type.split("/");
    const inputFileType = _inputFile[0];
    const inputFileExec = _inputFile[1];
    const inputFileName = fileNameCompressor(inputFile.name, 20);

    const fileSize = inputFile.size / (1024 * 1024);

    const acceptedImageFormats = ["png", "jpg", "jpeg", "gif"];
    const acceptedVideoFormats = ["mp4", "mkv", "3gp", "avi", "webm"];

    switch (type) {
      case "video":
        if (!acceptedVideoFormats.some((format) => format.includes(inputFileExec))) {
          swal("? Please select video format of mp4 , mkv , av ");
          e.target.value = "";
          return;
        }
        if (fileSize > 10) {
          swal("? Please select a video less than 10MB file size");
          e.target.value = "";
          return;
        }
        break;
      case "image":
        if (!acceptedImageFormats.some((format) => format.includes(inputFileExec))) {
          swal("? Please select image format of png , jpg , jpeg , gif ");
          e.target.value = "";
          return;
        }
        if (fileSize > 2) {
          swal("? Please select an image less than 2MB file size");
          e.target.value = "";
          return;
        }
        break;
      default:
        swal("? OOPS...!!! Invalid file format");
        e.target.value = "";
        return;
    }

    let compressedInputFile = inputFile;
    if (inputFileType === "image") {
      //compression algorithm
      const compressionOptions = {
        maxSizeMB: 1,
        maxWidthOrHeight: 1920,
        useWebWorker: true,
      };

      try {
        compressedInputFile = await imageCompression(inputFile, compressionOptions);
      } catch (error) {
        alert(error);
      }
    }

    let inputFileDataBase64;
    const file = new FileReader();
    if (compressedInputFile) {
      file.onloadend = (fileLoadedEvent) => {
        inputFileDataBase64 = fileLoadedEvent.target.result;
        setUploadData({
          ...uploadData,
          file: {
            type: inputFileType,
            name: inputFileName,
            data: inputFileDataBase64,
          },
        });
      };
      file.readAsDataURL(compressedInputFile);
    }

    // clear the file input event value
    e.target.value = "";
  };

  const resetState = () => {
    setUploadData({
      description: "",
      file: {
        type: "",
        name: "",
        data: "",
      },
    });
    setProgress("");
  };

  return (
    <Paper className={classes.upload}>
      <div className={classes.upload__header}>
        <Avatar src={photoURL} />
        <form className={classes.header__form} onSubmit={handleSubmitButton}>
          <input
            placeholder={`What's on your mind, ${displayName}?`}
            value={uploadData.description}
            onChange={(e) => setUploadData({ ...uploadData, description: e.target.value })}
          />
          <input
            id="upload-image"
            type="file"
            accept="image/*"
            hidden
            onChange={(e) => imageUploadHandler(e, "image")}
          />
          <input
            id="upload-video"
            type="file"
            accept="video/*"
            hidden
            onChange={(e) => imageUploadHandler(e, "video")}
          />
          <button type="submit">Post</button>
        </form>
      </div>
      {uploadData.file.name && !progress && (
        <div className={classes.selectedFile}>
          <Chip
            color="primary"
            size="small"
            onDelete={resetState}
            icon={uploadData.file.type === "image" ? <PhotoRoundedIcon /> : <VideocamRoundedIcon />}
            label={uploadData.file.name}
          />
        </div>
      )}
      {progress ? (
        <div className={classes.uploading}>
          <LinearProgress variant="determinate" value={progress} className={classes.progress} />
          <p>{progress} %</p>
        </div>
      ) : (
        ""
      )}
      <Divider />

      <div className={classes.upload__media}>
        <label htmlFor="upload-video" className={classes.media__options}>
          <VideocamRoundedIcon style={{ color: "red" }} />
          <h4>Video</h4>
        </label>
        <label htmlFor="upload-image" className={classes.media__options}>
          <PhotoRoundedIcon style={{ color: "green" }} />
          <h4>Photo</h4>
        </label>
        <div className={classes.media__options}>
          <EmojiEmotionsOutlinedIcon style={{ color: "orange" }} />
          <h4>Feeling/Activity</h4>
        </div>
      </div>
    </Paper>
  );
}
Example #28
Source File: Projects.js    From Portfolio with MIT License 4 votes vote down vote up
export default function Projects({ data }) {

    const classes = useStyles()

    const animRef = useRef(null)
    const animate = useAnimate(animRef)

    return (
        <Grid direction="row-reverse" container justify="center" alignItems="center" spacing={10} className={classes.cont}>
            <Grid item xs={12} lg={6}>
                <Typography variant="h2" gutterBottom align="center" innerRef={animRef}>
                    Projects
                </Typography>
                <Hidden mdDown>
                    <Fade in={animate} style={{ transitionDelay: '250ms' }}>
                        <div>
                            <Image
                                alt="Projects"
                                src="/projects.svg"
                                width="1144"
                                height="617.32"
                            />
                        </div>
                    </Fade>
                </Hidden>
            </Grid>
            <Grid container item xs={12} lg={6} direction="row" spacing={1}>
                {
                    !!data && data.map((v, i) =>
                        <Grid item sm={6} xs={12} key={i}>
                            <Fade in={animate} style={{ transitionDelay: `${200 * i}ms` }}>
                                <Card key={i} className={classes.card}>
                                    <CardActionArea
                                        className={classes.cardActionArea}
                                        href={v.value.html_url}
                                        target="_blank"
                                        rel="noopener noreferrer"
                                    >
                                        <CardHeader
                                            title={<><RepoIcon verticalAlign='middle' /> {v.value.name}</>}
                                            subheader={
                                                <>
                                                    {
                                                        !!v.value.stargazers_count &&
                                                        <>
                                                            <StarIcon verticalAlign='middle' />
                                                            {v.value.stargazers_count}
                                                        </>
                                                    }
                                                    {
                                                        !!v.value.forks &&
                                                        <>
                                                            <RepoForkedIcon verticalAlign='middle' />
                                                            {v.value.forks}
                                                        </>
                                                    }
                                                </>
                                            }
                                        />
                                        <CardContent>
                                            <Typography variant="body2" color="textSecondary" component="p">
                                                {v.value.description}
                                            </Typography>
                                        </CardContent>
                                        <CardActions>
                                            <Grid container direction="row" spacing={1}>
                                                {
                                                    !!v.value.languages &&
                                                    v.value.languages.map((lang, i) =>
                                                        <Grid item key={i}>
                                                            <Chip
                                                                key={i}
                                                                label={lang}
                                                                size="small"
                                                            />
                                                        </Grid>
                                                    )
                                                }
                                            </Grid>
                                        </CardActions>
                                    </CardActionArea>
                                </Card>
                            </Fade>
                        </Grid>
                    )
                }
            </Grid>
        </Grid>
    )
}
Example #29
Source File: Projects.js    From gitlab-lint-react with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
Projects = () => {
  const classes = useStyles();

  const [page, setPage] = useState(1);
  const [searchInput, setSearchInput] = useState("");
  const handleChange = (event, value) => {
    setPage(value);
    fetchData({ query: { page: value, q: searchInput } });
  };
  const debouncedSearch = useCallback(
    () => debounce((value) => fetchData({ query: { page, q: value } }), 500),
    [page]
  );
  const handleChangeSearch = (value) => {
    setSearchInput(value);
    debouncedSearch(value);
  };
  const [rows, setData] = useState({});
  const [meta, setMeta] = useState({});
  const fetchData = ({ query }) => {
    GitlabLintHttpClient("GET_ALL", { entity: "projects", query: query })
      .then((data) => {
        setData(data.data);
        setMeta(data.meta);
      })
      .catch((err) => console.error(err));
  };

  useEffect(() => {
    fetchData({ query: { page: 1 } });
  }, []);

  if (Object.keys(rows).length === 0 && rows.constructor === Object) {
    return <Loading />;
  }

  return (
    <React.Fragment>
      <div className={classes.header}>
        <Typography variant="h4" paragraph>
          Projects
        </Typography>
        <form noValidate autoComplete="off">
          <Input
            placeholder="Find a project..."
            value={searchInput}
            onChange={(e) => handleChangeSearch(e.target.value)}
          />
        </form>
      </div>
      <List>
        {rows.map((row) => {
          return (
            <ListItem
              button
              component={Link}
              to={`/projects/${row.id}`}
              key={row.id}
            >
              <ListItemText primary={row.path_with_namespace} />
              <div className={classes.levels}>
                {Object.keys(row.rules).map((key, index) => {
                  return (
                    <Tooltip key={key} title={key} placement="top-start">
                      <Chip
                        className={`${classes.level} ${classes[key]}`}
                        label={row.rules[key]}
                        size="small"
                      />
                    </Tooltip>
                  );
                })}
              </div>
            </ListItem>
          );
        })}
      </List>
      <div className={classes.pagination}>
        <Pagination
          boundaryCount={2}
          color="primary"
          count={meta.totalOfPages}
          onChange={handleChange}
          page={page}
          siblingCount={2}
        />
      </div>
    </React.Fragment>
  );
}