@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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
/**
* @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 |
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 |
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 |
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: </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:
</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:
</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 |
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 |
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 |
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 |
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 |
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 |
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>
);
}