@material-ui/core#ListItemSecondaryAction JavaScript Examples

The following examples show how to use @material-ui/core#ListItemSecondaryAction. 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: TagList.js    From ra-data-django-rest-framework with MIT License 6 votes vote down vote up
SubTree = ({ level, root, getChildNodes, openChildren, toggleNode }) => {
    const childNodes = getChildNodes(root);
    const hasChildren = childNodes.length > 0;
    const open = openChildren.includes(root.id);
    return (
        <Fragment>
            <ListItem
                button={hasChildren}
                onClick={() => hasChildren && toggleNode(root)}
                style={{ paddingLeft: level * 16 }}
            >
                {hasChildren && open && <ExpandLess />}
                {hasChildren && !open && <ExpandMore />}
                {!hasChildren && <div style={{ width: 24 }}>&nbsp;</div>}
                <ListItemText primary={root.name} />

                <ListItemSecondaryAction>
                    <EditButton record={root} basePath="/tags" />
                </ListItemSecondaryAction>
            </ListItem>
            <Collapse in={open} timeout="auto" unmountOnExit>
                <MuiList component="div" disablePadding>
                    {childNodes.map(node => (
                        <SubTree
                            key={node.id}
                            root={node}
                            getChildNodes={getChildNodes}
                            openChildren={openChildren}
                            toggleNode={toggleNode}
                            level={level + 1}
                        />
                    ))}
                </MuiList>
            </Collapse>
        </Fragment>
    );
}
Example #2
Source File: OwnerOrganizers.js    From Quizzie with MIT License 5 votes vote down vote up
function OwnerUsers() {
	const [organizers, setOrganizers] = useState([]);

	const getUsers = async () => {
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/owner/allAdmins`;

		try {
			await axios.get(url, {
				headers: {
					"auth-token": token
				}
			}).then(res => {
				setOrganizers(res.data.result);
			})
		} catch(error) {
			console.log(error);
		}
	}

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

	return (
		<div className="owner-quizzes">
			<List aria-label="users-display" className="owner-quiz-list">
				{organizers.map((user) => (
					<ListItem button key={user._id}>
						<ListItemText primary={user.email} secondary={user.name} />
						<ListItemSecondaryAction>
							<IconButton edge="end" aria-label="details">
								<ArrowForwardIos />
							</IconButton>
					</ListItemSecondaryAction>
					</ListItem>
				))}
			</List>
		</div>
	)

}
Example #3
Source File: OwnerQuizzes.js    From Quizzie with MIT License 5 votes vote down vote up
function OwnerQuizzes(props) {
	const [loading, setLoading] = useState(true);
	const [quizzes, setQuizzes] = useState([]);

	const getAllQuizzes = async () => {
		let token = localStorage.getItem("authToken");
		let url = "https://quizzie-api.herokuapp.com/owner/allQuizzes";

		try {
			await axios.get(url, {
				headers: {
					"auth-token": token
				}
			}).then(res => {
				setQuizzes(res.data.result);
			})
		} catch(error) {
			console.log(error);
		}
		setLoading(false);
	}

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

	if(loading) {
		return <QuizLoading />
	}

	return (
		<div className="owner-quizzes">
			{quizzes.length === 0? <p>No quizzes available now!</p>:
				<List aria-label="quiz display" className="owner-quiz-list">
				{quizzes.map(quiz => (
					<ListItem button className="owner-quiz-item" component={Link} to={`/ownerQuizDetails/${quiz._id}`} key={quiz._id}>
						<ListItemText primary={quiz.quizName} secondary={`By: ${quiz.adminId.name}`} />
						<ListItemSecondaryAction>
							<IconButton edge="end" aria-label="details" component={Link} to={`/ownerQuizDetails/${quiz._id}`}>
								<ArrowForwardIos />
							</IconButton>
						</ListItemSecondaryAction>
					</ListItem>
				))}
				</List> }
		</div>
	)
}
Example #4
Source File: OwnerUsers.js    From Quizzie with MIT License 5 votes vote down vote up
function OwnerUsers() {
	const [users, setUsers] = useState([]);

	const getUsers = async () => {
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/owner/allUsers`;

		try {
			await axios.get(url, {
				headers: {
					"auth-token": token
				}
			}).then(res => {
				setUsers(res.data.result);
			})
		} catch(error) {
			console.log(error);
		}
	}

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

	return (
		<div className="owner-quizzes">
			<List aria-label="users-display" className="owner-quiz-list">
				{users.map((user) => (
					<ListItem button key={user._id}>
						<ListItemText primary={user.email} secondary={user.name} />
						<ListItemSecondaryAction>
							<IconButton edge="end" aria-label="details">
								<ArrowForwardIos />
							</IconButton>
					</ListItemSecondaryAction>
					</ListItem>
				))}
			</List>
		</div>
	)

}
Example #5
Source File: ToolbarExtension.js    From eSim-Cloud with GNU General Public License v3.0 5 votes vote down vote up
function LibraryRow ({ library }) {
  const dispatch = useDispatch()
  const [open, setopen] = React.useState(false)
  const classes = useStyles()
  const components = useSelector(state => state.schematicEditorReducer.components)

  const handleAppply = (lib) => {
    dispatch(fetchLibrary(lib.id))
  }

  const handleUnapply = (lib) => {
    dispatch(removeLibrary(lib.id))
  }

  const handleOpen = () => {
    if (components[library.id].length === 0) { dispatch(fetchComponents(library.id)) }
    setopen(!open)
  }

  return (
    <Paper style={{ marginBottom: '.5rem' }}>
      <ListSubheader>
        <ListItem onClick={handleOpen} >
          {open ? <ExpandLess /> : <ExpandMore />}
          <ListItemText primary={library.library_name.slice(0, -4)} />
          <ListItemSecondaryAction>
            {(!library.default && !library.additional) &&
              <Button variant="contained" size="small"
                style={{ backgroundColor: '#ff1744', color: '#ffffff', margin: '.5rem' }}
                onClick={() => { dispatch(deleteLibrary(library.id)) }} hidden={library.default || library.additional} >
                Delete
              </Button>
            }
            {library.active
              ? <Button variant="contained" size="small" color="secondary"
                onClick={() => { handleUnapply(library) }} style={{ margin: '.5rem' }}>
                Remove
              </Button>
              : <Button variant="contained" size="small" color="primary"
                onClick={() => { handleAppply(library) }} style={{ margin: '.5rem' }}>
                Use
              </Button>
            }
          </ListItemSecondaryAction>
        </ListItem>
      </ListSubheader>

      {(components[library.id]) &&
        <Collapse in={open} timeout="auto" unmountOnExit>
          <List component="div" style={{ paddingLeft: '1rem', paddingRight: '1rem' }}>
            {components[library.id].map(component => {
              return (
                <ListItem alignItems='center' key={component.id} dense className={classes.nested}>
                  <ListItemText primary={component.name} secondary={component.description} />
                </ListItem>
              )
            })}
          </List>
        </Collapse>
      }
    </Paper>
  )
}
Example #6
Source File: Comment.js    From yasn with MIT License 5 votes vote down vote up
export default function Comment(props) {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <Grid item xs={12}>
        <div className={classes.demo}>
          <List>
            {/* {generate( */}
            <ListItem>
              <ListItemAvatar>
                {props.username ? (
                  <Link to={`/user/${props.username}`}>
                    <Avatar className={classes.avatar}>
                      {props.name
                        ? props.name[0]
                        : // + props.name.split(" ")[1][0]
                          "X"}
                    </Avatar>
                  </Link>
                ) : (
                  <Avatar className={classes.avatar}>
                    {props.name
                      ? props.name[0]
                      : // + props.name.split(" ")[1][0]
                        "X"}
                  </Avatar>
                )}
              </ListItemAvatar>
              <ListItemText
                primary={props.comment}
                secondary={
                  <Moment format="MMM D" withTitle>
                    {props.date}
                  </Moment>
                }
              />
              <ListItemSecondaryAction>
                {/* <IconButton edge="end" aria-label="delete">
                  <DeleteIcon fontSize="small" />
                </IconButton> */}
              </ListItemSecondaryAction>
            </ListItem>
          </List>
        </div>
      </Grid>
    </div>
  );
}
Example #7
Source File: TemplateList.js    From akashlytics-deploy with GNU General Public License v3.0 4 votes vote down vote up
export function TemplateList(props) {
  const classes = useStyles();
  const history = useHistory();
  const { setSelectedTemplate } = props;

  function handleGithubOpen(value) {
    window.electron.openUrl(value.githubUrl);
  }

  function selectTemplate(template) {
    setSelectedTemplate(template);
    history.push("/createDeployment/editManifest");
  }

  async function fromFile() {
    const fileDef = await window.electron.openTemplateFromFile();

    if (fileDef) {
      setSelectedTemplate({
        title: "From file",
        code: "from-file",
        category: "General",
        description: fileDef.path,
        content: fileDef.content
      });
      history.push("/createDeployment/editManifest");
    }
  }

  function fromGallery() {
    history.push(UrlService.templates());
  }

  return (
    <>
      <Helmet title="Create Deployment - Template List" />

      <Box padding="1rem">
        <Typography variant="h5"><strong>What do you want to deploy?</strong></Typography>
      </Box>

      <List className={classes.root}>
        <ListItem dense button onClick={() => selectTemplate(emptyTemplate)}>
          <ListItemAvatar>
            <div className={classes.logoItem}>
              <InsertDriveFileIcon />
            </div>
          </ListItemAvatar>
          <ListItemText primary={emptyTemplate.title} secondary={emptyTemplate.description} />
          {emptyTemplate.githubUrl && (
            <ListItemSecondaryAction>
              <IconButton edge="end" aria-label="github" onClick={() => handleGithubOpen(emptyTemplate)}>
                <GitHubIcon />
              </IconButton>
            </ListItemSecondaryAction>
          )}
        </ListItem>
        <ListItem dense button onClick={() => selectTemplate(helloWorldTemplate)}>
          <ListItemAvatar>
            <div className={classes.logoItem}>
              <CloudIcon />
            </div>
          </ListItemAvatar>
          <ListItemText primary={helloWorldTemplate.title} secondary={helloWorldTemplate.description} />
          {helloWorldTemplate.githubUrl && (
            <ListItemSecondaryAction>
              <IconButton edge="end" aria-label="github" onClick={() => handleGithubOpen(helloWorldTemplate)}>
                <GitHubIcon />
              </IconButton>
            </ListItemSecondaryAction>
          )}
        </ListItem>
        <ListItem dense button onClick={() => fromFile()}>
          <ListItemAvatar>
            <div className={classes.logoItem}>
              <DescriptionIcon />
            </div>
          </ListItemAvatar>
          <ListItemText primary="From a file" secondary="Load a deploy.yml file from the computer." />
        </ListItem>
        <ListItem dense button onClick={() => fromGallery()}>
          <ListItemAvatar>
            <div className={classes.logoItem}>
              <CollectionsIcon />
            </div>
          </ListItemAvatar>
          <ListItemText primary="Browse template gallery" secondary="Explore the template gallery for a great variety of pre-made template by the community." />
        </ListItem>
      </List>
    </>
  );
}
Example #8
Source File: LeaseRow.js    From akashlytics-deploy with GNU General Public License v3.0 4 votes vote down vote up
LeaseRow = React.forwardRef(({ lease, setActiveTab, deploymentManifest, dseq, providers, loadDeploymentDetail }, ref) => {
  const { enqueueSnackbar } = useSnackbar();
  const providerInfo = providers?.find((p) => p.owner === lease?.provider);
  const { localCert } = useCertificate();
  const isLeaseActive = lease.state === "active";
  const [isServicesAvailable, setIsServicesAvailable] = useState(false);
  const { favoriteProviders, updateFavoriteProviders } = useLocalNotes();
  const [isViewingProviderDetail, setIsViewingProviderDetail] = useState(false);
  const isFavorite = favoriteProviders.some((x) => lease?.provider === x);
  const {
    data: leaseStatus,
    error,
    refetch: getLeaseStatus,
    isLoading: isLoadingLeaseStatus
  } = useLeaseStatus(providerInfo?.host_uri, lease, {
    enabled: isLeaseActive && !isServicesAvailable && !!providerInfo?.host_uri && !!localCert,
    refetchInterval: 10_000,
    onSuccess: (leaseStatus) => {
      if (leaseStatus) {
        checkIfServicesAreAvailable(leaseStatus);
      }
    }
  });
  const {
    data: providerStatus,
    isLoading: isLoadingProviderStatus,
    refetch: getProviderStatus
  } = useProviderStatus(providerInfo?.host_uri, {
    enabled: false,
    retry: false
  });
  const isLeaseNotFound = error && error.includes && error.includes("lease not found") && isLeaseActive;
  const servicesNames = leaseStatus ? Object.keys(leaseStatus.services) : [];
  const classes = useStyles();
  const [isSendingManifest, setIsSendingManifest] = useState(false);

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

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

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

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

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

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

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

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

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

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

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

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

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

    updateFavoriteProviders(newFavorites);
  };

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

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

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

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

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

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

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

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

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

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

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

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

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

                  {service.uris?.length > 0 && (
                    <>
                      <Box marginTop=".5rem">
                        <LabelValue label="Uris:" />
                        <List dense>
                          {service.uris.map((uri) => {
                            return (
                              <ListItem key={uri} className={classes.listItem}>
                                <ListItemText
                                  primary={
                                    <LinkTo className={classes.link} onClick={(ev) => handleExternalUrlClick(ev, uri)}>
                                      {uri} <LaunchIcon fontSize="small" />
                                    </LinkTo>
                                  }
                                />
                                <ListItemSecondaryAction>
                                  <IconButton
                                    edge="end"
                                    aria-label="uri"
                                    size="small"
                                    onClick={(ev) => {
                                      copyTextToClipboard(uri);
                                      enqueueSnackbar(<Snackbar title="Uri copied to clipboard!" iconVariant="success" />, {
                                        variant: "success",
                                        autoHideDuration: 2000
                                      });
                                    }}
                                  >
                                    <FileCopyIcon fontSize="small" />
                                  </IconButton>
                                </ListItemSecondaryAction>
                              </ListItem>
                            );
                          })}
                        </List>
                      </Box>
                    </>
                  )}
                </Box>
              ))}
        </CardContent>
      </Card>
    </>
  );
})
Example #9
Source File: HistorySection.js    From Quizzie with MIT License 4 votes vote down vote up
function HistorySection(props) {
	const [userType, setUserType] = useState(props.type);
	const [profile, setProfile] = useState(props.profile);
	const [quizzes, setQuizzes] = useState([]);

	const [loading, setLoading] = useState(true);

	const getCols = () => {
		if (isWidthUp('md', props.width)) {
			return 3;
		}

		return 2;
	}

	const getQuizzes = async () => {

		let token = localStorage.getItem("authToken");
		let url = null;

		if(userType === "admin") url = "https://quizzie-api.herokuapp.com/admin/created";
		else url = "https://quizzie-api.herokuapp.com/user/quizzesGiven";

		try {
			await axios.get(url, {
				headers: {
					"auth-token": token
				}
			}).then(res => {
				let quizL = res.data.result.sort(function(a,b) {return a.scheduledFor - b.scheduledFor});
				setQuizzes(quizL);
				setLoading(false);
			})
		} catch (error) {
			console.log(error);
			setLoading(false);
		}
	}

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

	if (loading) {
		return (
			<QuizLoading />
		)
	}
	else if (userType === "admin") {
		return (
			<div className="history-section">
				{quizzes.length === 0 ?
					<p style={{ textAlign: 'center' }}>You have not created any quizzes yet!</p>
					:
					<GridList cols={getCols()} className="grid-list">
						{quizzes.map((quiz) => (
							<GridListTile key={quiz._id} className="quiz-tile">
								<img src="../CC LOGO-01.svg" />
								<GridListTileBar
									title={quiz.quizName}
									subtitle={`By: You`}
									actionIcon={
										<Tooltip title="Settings">
											<IconButton aria-label={`edit ${quiz.quizName}`}
												component={Link} to={`/editQuiz/${quiz._id}`}>
												<Settings className="enroll-icon" />
											</IconButton>
										</Tooltip>
									}
								/>
							</GridListTile>
						))}
					</GridList>
				}
			</div>
		)
	}
	else {
		return (
			<div className="history-section">
				{profile.quizzesGiven.length === 0 ?
					<p style={{ textAlign: 'center' }}>You have not given any quizzes yet!</p>
					: <List aria-label="quiz display" className="owner-quiz-list">
						{quizzes.map(quiz => (
							quiz.quizId !== null?
								(<ListItem button className="owner-quiz-item" component={Link} key={quiz._id} to={`/results/${quiz.quizId._id}`}>
									<ListItemText primary={quiz.quizId.quizName} secondary={`Scored: ${quiz.marks}`} />
									<ListItemSecondaryAction>
										<IconButton edge="end" aria-label="details" component={Link} to={`/results/${quiz.quizId._id}`}>
											<ArrowForwardIos />
										</IconButton>
									</ListItemSecondaryAction>
								</ListItem>): null
						))}
					</List>}
			</div>
		)
	}
}
Example #10
Source File: AlertSelect.jsx    From archeage-tools with The Unlicense 4 votes vote down vote up
render() {
    const { id, alerts, mobile, setAlert, speak, setSpeak, nextTime } = this.props;
    const { menu } = this.state;
    const menuOpen = Boolean(menu);
    const eventAlerts = pathOr([], [id])(alerts);
    const isSpeak = pathOr(false, [id])(speak);

    return (
      <>
        <Tooltip title="Configure alerts">
          <IconButton
            size="small"
            onClick={this.handleOpenMenu}
            className="super-btn"
          >
            <NotificationsIcon
              fontSize="small"
              className={cn({ 'notif-fade': eventAlerts.length === 0 })}
              color={eventAlerts.length > 0 ? 'primary' : 'inherit'}
            />
            {eventAlerts.length > 0 &&
            <div className="super-text color-white">{eventAlerts.length}</div>}
          </IconButton>
        </Tooltip>
        <Menu
          id="alert-menu"
          anchorEl={menu}
          anchorOrigin={{
            vertical: 'top',
            horizontal: 'center',
          }}
          transformOrigin={{
            vertical: 'top',
            horizontal: 'center',
          }}
          getContentAnchorEl={null}
          open={menuOpen}
          onClose={this.handleCloseMenu}
          className="alert-menu"
          autoFocus={false}
        >
          <ListItem tabIndex={null} dense={!mobile}>
            <ListItemText>Alert Types:</ListItemText>
          </ListItem>
          <MenuItem disabled dense={!mobile}>
            <ListItemIcon>
              <CheckBoxIcon fontSize="small" />
            </ListItemIcon>
            <ListItemText>Audio Cue</ListItemText>
          </MenuItem>
          <MenuItem
            onClick={setSpeak(id, !isSpeak)}
            dense={!mobile}
            disabled={!CAN_SPEAK}
            divider
          >
            <ListItemIcon>
              {isSpeak
                ? <CheckBoxIcon fontSize="small" color="primary" />
                : <CheckBoxOutlineBlankIcon fontSize="small" />}
            </ListItemIcon>
            <ListItemText>Audio Message</ListItemText>
          </MenuItem>
          <ListItem tabIndex={null} dense={!mobile}>
            <ListItemText>Alert Times:</ListItemText>
            <ListItemSecondaryAction>
              <Tooltip title="Clear all">
                <span>
                  <IconButton size="small" onClick={setAlert(id, '')} disabled={eventAlerts.length === 0}>
                    <CloseIcon fontSize="small" />
                  </IconButton>
                </span>
              </Tooltip>
            </ListItemSecondaryAction>
          </ListItem>
          {Object.entries(ALERT_OPTIONS).map(([key, option]) => (
            <MenuItem
              dense={!mobile}
              onClick={setAlert(id, key)}
              key={`alert-opt-${randomString(16)}-${key}`}
            >
              <ListItemIcon>
                {eventAlerts.includes(key)
                  ? <CheckBoxIcon fontSize="small" color="primary" />
                  : <CheckBoxOutlineBlankIcon fontSize="small" />}
              </ListItemIcon>
              <ListItemText>{substitute(option.name, { time: getReminderTime(nextTime, option) / 60 })}</ListItemText>
            </MenuItem>
          ))}
        </Menu>
      </>
    );
  }
Example #11
Source File: CargoShip.jsx    From archeage-tools with The Unlicense 4 votes vote down vote up
render() {
    const { alerts, setAlert, speak, setSpeak, servers, server: serverId, mobile, openDialog } = this.props;
    const { open, setup, stepIndex, endTime, shipPosition, menu, updated } = this.state;
    const now = moment();
    let eventStepTime = moment(endTime);
    const step = CARGO_SCHEDULE[stepIndex];

    const server = servers[serverId];
    const serverName = pathOr('???', ['name'])(server);

    return [
      <Paper className="cargo-ship event-list" key="cargo-timer">
        <AppBar position="static">
          <Toolbar variant="dense">
            <Icon><img src={'/images/event_type/exploration.png'} alt="Cargo Ship" /></Icon>
            <Typography variant="subtitle1" className="title-text">[{serverName}] Cargo Ship</Typography>
            <IfPerm permission={`cargo.${serverName.toLowerCase()}`}>
              <Tooltip title={`Edit ${serverName} Timer`}>
                <IconButton onClick={this.toggleDialog} color="inherit">
                  <EditIcon />
                </IconButton>
              </Tooltip>
            </IfPerm>
            <Tooltip title="Change Server">
              <IconButton onClick={() => openDialog(DIALOG_MY_GAME, SERVER)} color="inherit">
                <HomeIcon />
              </IconButton>
            </Tooltip>
            <Tooltip title="Configure alerts">
              <IconButton
                onClick={this.handleOpenMenu}
                className="super-btn"
              >
                <NotificationsIcon
                  className={cn({ 'notif-fade': alerts.length === 0 })}
                  color="inherit"
                />
                {alerts.length > 0 &&
                <Typography className="super-text" color="primary">{alerts.length}</Typography>}
              </IconButton>
            </Tooltip>
          </Toolbar>
        </AppBar>
        <div className="cargo-slider">
          <div className="cargo-rail" />
          <Tooltip title="Solis Headlands Trade Outlet">
            <div className="cargo-icon austera" />
          </Tooltip>
          <Tooltip title="Two Crowns Trade Outlet">
            <div className="cargo-icon two-crowns" />
          </Tooltip>
          <div
            className={cn('cargo-icon ship', { moving: !step.port, reverse: step.reverse })}
            style={{ [step.reverse ? 'left' : 'right']: `${(shipPosition / step.duration) * 100}%` }}
          />
        </div>
        <div className="cargo-text">
          {!server &&
          <Typography>Select a server to see the cargo ship location.</Typography>}
          {server && !updated &&
          <Typography>The cargo ship has not been updated since the last maintenance.</Typography>}
          {server && updated &&
          <>
            <Typography>Cargo ship is {step.text}.</Typography>
            <br />
            <Table size="small" stickyHeader className="timer-table">
              <TableHead>
                <TableRow>
                  <TableCell>
                    Event
                  </TableCell>
                  <TableCell>
                    Time
                  </TableCell>
                  <TableCell align="right">
                    Countdown
                  </TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {Array.from(Array(CARGO_SCHEDULE.length).keys()).map((_, i) => {
                  const index = getNextIndex(stepIndex + i - 1);
                  const step = CARGO_SCHEDULE[index];
                  if (i > 0) {
                    eventStepTime.add(step.duration, 'seconds');
                  }
                  return (
                    <TableRow key={`cargo-${i}`}>
                      <TableCell>{step.next}</TableCell>
                      <TableCell>{eventStepTime.format('h:mm A')}</TableCell>
                      <TableCell align="right">{hhmmssFromDate(eventStepTime.diff(now))}</TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </>}
        </div>
      </Paper>,
      <Dialog
        open={open}
        key="cargo-settings"
        onClose={this.toggleDialog}
        maxWidth="sm"
      >
        <AppBar position="static">
          <Toolbar variant="dense">
            <Typography variant="subtitle1" className="title-text">Cargo Ship Setup</Typography>
            <Tooltip title="Close">
              <IconButton onClick={this.toggleDialog}>
                <CloseIcon />
              </IconButton>
            </Tooltip>
          </Toolbar>
        </AppBar>
        <DialogContent>
          <Typography>To setup the timer, the ship must currently be docked at a port.</Typography>
          <br />
          <FormControl component="fieldset">
            <FormLabel component="legend">What port is the ship at?</FormLabel>
            <RadioGroup name="port" value={Number.parseInt(setup.port)} onChange={this.handleSetupChange('port')} row>
              <FormControlLabel
                control={<Radio color="primary" />}
                label="Solis Headlands"
                value={ZONE.SOLIS_HEADLANDS}
              />
              <FormControlLabel
                control={<Radio color="primary" />}
                label="Two Crowns"
                value={ZONE.TWO_CROWNS}
              />
            </RadioGroup>
          </FormControl>
          <FormControl component="fieldset">
            <FormLabel component="legend">What is the remaining time on the &quot;Cargo Ship
              Anchored&quot; buff?</FormLabel>
            <div className="duration-pick">
              <Input
                id="mm"
                placeholder="20"
                endAdornment="m"
                inputProps={{
                  maxLength: 2,
                  ref: this.mm,
                }}
                value={setup.mm}
                onChange={this.handleTimeChange('mm')}
                onKeyPress={this.handleEnter}
              />
              <Input
                id="ss"
                placeholder="00"
                endAdornment="s"
                inputProps={{
                  maxLength: 2,
                  ref: this.ss,
                }}
                value={setup.ss}
                onChange={this.handleTimeChange('ss')}
                onKeyPress={this.handleEnter}
              />
            </div>
          </FormControl>
          <FormControl component="fieldset">
            <FormControlLabel
              control={<Checkbox color="primary" />}
              label="Don't Update Sibling Realms"
              checked={setup.noLinkedUpdate}
              onChange={this.handleNoLink}
            />
          </FormControl>
        </DialogContent>
        <DialogActions>
          <Button
            onClick={this.submitSetup}
            color="primary"
            disabled={!setup.port || (String(setup.mm).length === 0 && String(setup.ss).length === 0)}
          >
            Update
          </Button>
        </DialogActions>
      </Dialog>,
      <Menu
        id="alert-menu"
        anchorEl={menu}
        anchorOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
        getContentAnchorEl={null}
        open={Boolean(menu)}
        onClose={this.handleCloseMenu}
        className="alert-menu"
        autoFocus={false}
        key="alert-menu"
        variant="menu"
      >
        <ListItem tabIndex={null} dense={!mobile}>
          <ListItemText>Alert Types:</ListItemText>
        </ListItem>
        <MenuItem disabled dense={!mobile}>
          <ListItemIcon>
            <CheckBoxIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText>Audio Cue</ListItemText>
        </MenuItem>
        <MenuItem
          onClick={setSpeak(CARGO_ID, !speak)}
          dense={!mobile}
          disabled={!CAN_SPEAK}
          divider
        >
          <ListItemIcon>
            {speak
              ? <CheckBoxIcon fontSize="small" color="primary" />
              : <CheckBoxOutlineBlankIcon fontSize="small" />}
          </ListItemIcon>
          <ListItemText>Audio Message</ListItemText>
        </MenuItem>
        <ListItem tabIndex={null} dense={!mobile}>
          <ListItemText>Alert Times:</ListItemText>
          <ListItemSecondaryAction>
            <Tooltip title="Clear all">
                <span>
                  <IconButton size="small" onClick={setAlert(CARGO_ID, '')} disabled={alerts.length === 0}>
                    <CloseIcon fontSize="small" />
                  </IconButton>
                </span>
            </Tooltip>
          </ListItemSecondaryAction>
        </ListItem>
        {Object.entries(CARGO_ALERTS).map(([key, option]) => (
          <MenuItem
            dense={!mobile}
            onClick={setAlert(CARGO_ID, key)}
            key={`alert-opt-${randomString(16)}-${key}`}
          >
            <ListItemIcon>
              {alerts.includes(key)
                ? <CheckBoxIcon fontSize="small" color="primary" />
                : <CheckBoxOutlineBlankIcon fontSize="small" />}
            </ListItemIcon>
            <ListItemText>{option.name}</ListItemText>
          </MenuItem>
        ))}
      </Menu>,
    ];
  }
Example #12
Source File: PortOfEntryForm.js    From surveillance-forms with MIT License 4 votes vote down vote up
PortOfEntryForm = ({ onSubmit, lang, langCode }) => {
  const [formValues, setFormValues] = useState({
    ...PortOfEntryInitialState,
  });

  const [open, setOpen] = useState(false);
  const [isLoaded, setIsLoaded] = useState(false);
  const [captchaText, setCaptchaText] = useState("");
  const [isCaptchaExpired, setIsCaptchaExpired] = useState(false);
  const [clear, setClear] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setIsLoaded(true);
    }, DELAY);
  });

  const handleChange = (value) => {
    setCaptchaText(value);
    if (value === null) {
      setIsCaptchaExpired(true);
    }
  };

  const asyncScriptOnLoad = () => {
    console.log("scriptLoad - reCaptcha Ref-", React.createRef());
  };

  const handleFieldChange = (field) => (value) => {
    if (UNDERLYING.includes(field)) {
      setFormValues({
        ...formValues,
        underlyingConditions: {
          ...formValues.underlyingConditions,
          [field]: value,
        },
      });
    } else if (BIOGRAPHICALDATA.includes(field)) {
      setFormValues({
        ...formValues,
        biographicalData: {
          ...formValues.biographicalData,
          [field]: value,
        },
      });
    } else if (CONTACTINFO.includes(field)) {
      setFormValues({
        ...formValues,
        biographicalData: {
          ...formValues.biographicalData,
          contactInformation: {
            ...formValues.biographicalData.contactInformation,
            [field]: value,
          },
        },
      });
    } else if (ADDRESS.includes(field)) {
      setFormValues({
        ...formValues,
        biographicalData: {
          ...formValues.biographicalData,
          contactInformation: {
            ...formValues.biographicalData.contactInformation,
            address: {
              ...formValues.biographicalData.contactInformation.address,
              [field]: value,
            },
          },
        },
      });
    } else if (SYMPTOMS.includes(field)) {
      setFormValues({
        ...formValues,
        symptoms: {
          ...formValues.symptoms,
          [field]: value,
        },
      });
    } else if (RISKS.includes(field)) {
      setFormValues({
        ...formValues,
        riskFromContact: {
          ...formValues.riskFromContact,
          [field]: value,
        },
      });
    } else {
      setFormValues({
        ...formValues,
        [field]: value,
      });
    }
  };

  const fields = PORT_OF_ENTRY_FIELDS(lang, handleFieldChange, langCode);

  const renderFormField = (property) => {
    const field = fields.find((f) => f.property === property);
    if (!field) {
      return null;
    }
    return renderField(field, clear);
  };

  const renderSectionHeader = (label) => {
    return (
      <Typography className="sectionheader" variant="h2">
        {label}
      </Typography>
    );
  };

  const renderSubsectionheader = (label) => {
    return (
      <Typography className="subsectionheader" variant="h5">
        {label}
      </Typography>
    );
  };

  const handleSubmit = () => {
    onSubmit(formValues).then(() => {
      // clear form values
      setFormValues({});
      setClear(clear + 1);
    });
  };

  const handleModal = () => {
    setOpen(true);
  };

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

  const isFormValid = () => {
    let isValid = true;
    if (!isEmpty(captchaText) && !isCaptchaExpired) {
      fields.forEach((f) => {
        if (f.onValidate) {
          if (f.property === "email") {
            isValid =
              isValid &&
              f.onValidate(
                get(
                  formValues,
                  `biographicalData.contactInformation.${f.property}`
                )
              );
          } else {
            isValid =
              isValid &&
              f.onValidate(get(formValues, `biographicalData.${f.property}`));
          }
        }
      });
    } else {
      isValid = false;
    }
    return isValid;
  };

  const handleDependentsAdd = (dependent) => {
    setOpen(false);
    const dependents = formValues.dependents || [];
    dependents.push(dependent);
    setFormValues({
      ...formValues,
      dependents,
    });
  };

  const renderForm = () => {
    return (
      <form autoComplete="off">
        {renderSectionHeader(lang.t("passengerDependentsRegistrationForm"))}
        {renderSubsectionheader(lang.t("basicInformation"))}
        <Grid container spacing={4}>
          <Grid item xs={12} md={4}>
            {renderFormField("firstName")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("middleName")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("lastName")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("age")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("dateOfBirth")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("gender")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("preferredLanguage")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("occupation")}
          </Grid>
          {formValues.biographicalData.occupation === "other" && (
            <Grid item xs={12} md={4}>
              {renderFormField("occupationOther")}
            </Grid>
          )}
          <Grid item xs={12} md={4}>
            {renderFormField("nationality")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("passportNumber")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("governmentIssuedId")}
          </Grid>
        </Grid>

        {renderSubsectionheader(lang.t("contactInformation"))}
        <Grid container spacing={4}>
          <Grid item xs={12} md={4}>
            {renderFormField("country")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("region")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("city")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("customField1")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("customField2")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("postalCode")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("street")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("building")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("email")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderFormField("phoneNumber")}
          </Grid>
        </Grid>

        <Grid container spacing={4}>
          <Grid item xs={12} sm={4}>
            {renderSubsectionheader(lang.t("symptoms"))}
            {renderFormField("fever")}
            {renderFormField("cough")}
            {renderFormField("shortnessOfBreath")}
            {renderFormField("fatigue")}
            {renderFormField("headache")}
            {renderFormField("runnyNose")}
            {renderFormField("feelingUnwell")}
          </Grid>
          <Grid item xs={12} sm={4}>
            {renderSubsectionheader(lang.t("underlyingConditions"))}
            {renderFormField("chronicLungDisease")}
            {renderFormField("heartDisease")}
            {renderFormField("liverDisease")}
            {renderFormField("renalDisease")}
            {renderFormField("autoimmuneDisease")}
            {renderFormField("cancer")}
            {renderFormField("diabetes")}
            {renderFormField("hiv")}
            {renderFormField("pregnancy")}
          </Grid>
          <Grid item xs={12} md={4}>
            {renderSubsectionheader(lang.t("riskFromContact"))}
            {renderFormField("hasRecentlyTraveled")}
            {renderFormField("contactWithSuspected")}
            {renderFormField("contactWithConfirmed")}
            {renderFormField("worksAtOrVisitedHealthFacility")}
          </Grid>
        </Grid>
        {renderSubsectionheader(lang.t("travelInfo"))}
        <Grid container spacing={4}>
          <Grid item xs={12} md={3}>
            {renderFormField("travelFromCountry")}
          </Grid>
          <Grid item xs={12} md={3}>
            {renderFormField("finalTransitCountry")}
          </Grid>
          <Grid item xs={12} md={3}>
            {renderFormField("flightNumber")}
          </Grid>
          <Grid item xs={12} md={3}>
            {renderFormField("seatNumber")}
          </Grid>
          <Grid item xs={12} md={3}>
            {renderFormField("stayingAtHotel")}
          </Grid>
          {formValues.stayingAtHotel === "other" ? (
            <Grid item xs={12} md={4}>
              {renderFormField("hotelOther")}
            </Grid>
          ) : (
            ""
          )}
        </Grid>
        <Box mt={4} textAlign="left">
          {renderSubsectionheader(lang.t("dependents"))}
          <Button onClick={handleModal} variant="outlined" size="large">
            {lang.t("addDependent")}
          </Button>
          {!isEmpty(formValues.dependents) && (
            <Grid container item xs={12} md={4}>
              <List style={{ width: "100%" }}>
                {formValues.dependents.map((d, index) => {
                  const onRemoveDependent = () => {
                    const dependents = formValues.dependents.filter(
                      (d, i) => i !== index
                    );
                    setFormValues({
                      ...formValues,
                      dependents,
                    });
                  };

                  return (
                    <ListItem>
                      <Typography>{`${index + 1}. ${d.firstName} ${
                        d.lastName
                      }`}</Typography>
                      <ListItemSecondaryAction>
                        <Button onClick={onRemoveDependent}>Remove</Button>
                      </ListItemSecondaryAction>
                    </ListItem>
                  );
                })}
              </List>
            </Grid>
          )}

          <Dialog
            fullScreen
            open={open}
            onClose={handleClose}
            TransitionComponent={Transition}
          >
            <AppBar style={{ background: "blue" }}>
              <Toolbar>
                <IconButton
                  edge="start"
                  color="inherit"
                  onClick={handleClose}
                  aria-label="close"
                >
                  <CloseIcon />
                </IconButton>
                <Typography>
                  {lang.t("passengerDependentsRegistrationForm")}
                </Typography>
              </Toolbar>
            </AppBar>
            <Paper style={{ margin: 30, padding: 30 }}>
              <DependantsForm
                onSubmit={handleDependentsAdd}
                lang={lang}
                langCode={langCode}
              />
            </Paper>
          </Dialog>
        </Box>
        {isLoaded && (
          <ReCAPTCHA
            style={{ paddingTop: 20 }}
            ref={React.createRef()}
            sitekey={TEST_SITE_KEY}
            onChange={handleChange}
            asyncScriptOnLoad={asyncScriptOnLoad}
          />
        )}
        <Box mt={4} textAlign="right">
          <Button
            onClick={handleSubmit}
            variant="contained"
            size="large"
            disabled={!isFormValid()}
          >
            {lang.t("submit")}
          </Button>
        </Box>
      </form>
    );
  };

  return <Box>{renderForm()}</Box>;
}
Example #13
Source File: ConfirmStep.jsx    From resilience-app with GNU General Public License v3.0 4 votes vote down vote up
function ConfirmStep({ dispatch, state }) {
  const history = useHistory();
  const classes = useStyles();

  // convert cart object to an array of items and filter out any items with a quantity of 0
  const cart = Object.keys(state.cart).reduce((items, key) => {
    state.cart[key].quantity > 0 && items.push(state.cart[key]);
    return items;
  }, []);

  const [isDonationRequest, setIsDonationRequest] = useState(false);

  const total = cart.reduce((total, item) => item.resource.cost * item.quantity + total, 0);

  async function confirmRequest() {
    const { details, recipient } = state;
    let mission = {
      type: MissionType.resource,
      status: MissionStatus.unassigned,
      recipientUid: recipient.uid,
      recipientDisplayName: recipient.displayName,
      recipientPhoneNumber: recipient.phoneNumber,
      recipientEmailAddress: recipient.recipientEmailAddress,
      deliveryLocation: details.location,
      deliveryNotes: details.instructions,
      deliveryType: details.curbsidePickup ? DeliveryType.curbside : DeliveryType.delivery,
      details: cart.map((item) => ({
        resourceUid: item.resource.uid,
        quantity: item.quantity,
        displayName: item.resource.displayName,
      })),
    };

    if (isDonationRequest) {
      mission = { ...mission, fundedStatus: MissionFundedStatus.notfunded };
    } else {
      mission = {
        ...mission,
        status: MissionStatus.tentative,
        fundedStatus: MissionFundedStatus.fundedbyrecipient,
        fundedDate: new Date().toISOString(),
      };
    }
    try {
      const createdMission = await Mission.create(mission);
      const redirect = isDonationRequest
        ? routes.request.success.donation
        : routes.request.success.payment;
      history.push(redirect);
    } catch (error) {
      dispatch({
        type: "ERROR",
        payload: "There was an error creating your mission. Please contact the organization.",
      });
    }
  }

  const paypalCart = transformForPaypal(cart);

  if (isDonationRequest) {
    return (
      <>
        <H3 className={classes.yMargin} align="left" color="textPrimary">
          Find Me a Donation
        </H3>
        <TypographyWrapper align="left">
          As an organization of volunteers, we will try our best to fulfill your request but please
          understand that wait times for this option may be uncertain.
        </TypographyWrapper>
        <NavigationButtons
          nextText="Confirm"
          onBack={() => setIsDonationRequest(false)}
          onNext={() => confirmRequest()}
        />
      </>
    );
  }

  return (
    <>
      <Box display="flex" justifyContent="space-between" marginBottom="1rem">
        <H3 align="left" color="textPrimary">
          Request Summary
        </H3>
        <Button onClick={() => dispatch({ type: "UPDATE_STEP", payload: 0 })}>
          <Create fontSize="small" color="primary" />
          <H4 color="primary">Edit</H4>
        </Button>
      </Box>

      <Grid container direction="row" justify="space-between" alignItems="center">
        <Body1 color="textSecondary">QTY</Body1>
        <Body1 color="textSecondary">SUBTOTAL</Body1>
      </Grid>
      <List dense={true}>
        {Object.keys(cart).map((key) => {
          const { quantity, resource } = cart[key];
          return (
            <CheckoutItem
              key={resource.uid}
              quantity={quantity}
              cost={quantity * resource.cost}
              description={resource.description}
              name={resource.displayName}
            />
          );
        })}
        <Divider />
        <ListItem>
          <ListItemText>
            <H5 color="textSecondary">TOTAL (BEFORE TAX)</H5>
          </ListItemText>
          <ListItemSecondaryAction>
            <H5 color="textPrimary">${parseFloat(total).toFixed(2)}</H5>
          </ListItemSecondaryAction>
        </ListItem>
      </List>
      <PaypalCheckout
        cart={paypalCart}
        onApprove={() => confirmRequest()}
        onError={(e) =>
          dispatch({ type: "ERROR", payload: "There was an error processing your payment" })
        }
      />

      <TypographyWrapper elementType="subtitle2">
        <i>Pay securly online with your credit card</i>
      </TypographyWrapper>

      <Body1 className={classes.yMargin} color="textSecondary">
        At the moment, we are not accepting cash due to potential health risks.
      </Body1>

      <Paper className={classes.paper} variant="outlined">
        <span role="img" aria-label="heart" className={classes.heart}>
          ❤️
        </span>
        <Body1 align="left" gutterBottom={true}>
          We want to make sure everyone has access to food. If you're unable to pay, we'll try to
          find a donation for your request.
        </Body1>
        <H5
          color="primary"
          align="left"
          className={classes.donation}
          onClick={() => setIsDonationRequest(true)}
        >
          Find me a donation
        </H5>
      </Paper>
      <Button
        style={{ marginBottom: "1rem" }}
        fullWidth
        variant="contained"
        color="primary"
        onClick={() => dispatch({ type: "BACK" })}
      >
        Back
      </Button>
    </>
  );
}
Example #14
Source File: CSPSummaryReport.js    From SESTA-FMS with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes } = this.props;
    const columns = [
      {
        id: "Name",
        displayName: "Name",
      },
      {
        id: "Count",
        displayName: "Count",
      },
    ];
    const datas = [
      {
        Name: "Amount of principal collected",
        Count: "₹" + this.state.principalCollected,
      },
      {
        Name: "Amount of interest collected",
        Count: "₹" + this.state.interestCollected,
      },
      {
        Name: "No of livelihood activities",
        Count: this.state.completedActivities.length,
      },
      {
        Name: "No of loans sanctioned",
        Count: this.state.sanctionedLoans.length,
      },
      {
        Name: "No of loan defaulters",
        Count: this.state.loanDefaulters.length,
      },
      {
        Name: "",
        Count: "",
      },
      {
        Name: "Types of activities",
        Count: "",
      },
    ];

    /** csv file name & report header name */
    let fileName = "";
    let reportFilterName = "";
    let filterCsp = "All";
    if (this.state.filterCspName) {
      fileName += "_for_" + this.state.filterCspName.name.split(" ").join("_");
      filterCsp = this.state.filterCspName.name;
    }

    if (filterCsp === "All") {
      reportFilterName += "Report of " + filterCsp + " CSPs";
    } else {
      reportFilterName += "Report for CSP: " + filterCsp;
    }

    if (this.state.filterStartDate) {
      let filterStDate = this.state.filterStartDate
        ? Moment(this.state.filterStartDate).format("DD MMM YYYY")
        : null;
      fileName +=
        "_from_" + Moment(this.state.filterStartDate).format("DDMMMYYYY");
      reportFilterName += " for the duration: " + filterStDate;
    }

    if (this.state.filterEndDate) {
      let filterEnDate = this.state.filterEndDate
        ? Moment(this.state.filterEndDate).format("DD MMM YYYY")
        : null;
      fileName += "_to_" + Moment(this.state.filterEndDate).format("DDMMMYYYY");
      reportFilterName += " - " + filterEnDate;
    }
    fileName = "csp_summary_report" + fileName + ".csv";

    if (this.state.activityTypesWithCount.length <= 0) {
      datas.push({
        Name: "No records found",
        Count: "",
      });
    }
    /** display list of activity types with their count */
    var elements = [];
    this.state.activityTypesWithCount.map((key, value) => {
      datas.push(key);
      elements.push(
        <ListItem>
          <ListItemText primary={key.Name} />
          <ListItemSecondaryAction style={{ paddingRight: "100px" }}>
            {key.Count}
          </ListItemSecondaryAction>
        </ListItem>
      );
    });

    return (
      <Layout breadcrumbs={CSP_SUMMARY_REPORT_BREADCRUMBS}>
        <Grid>
          <Grid>
            <div className="App">
              <h3>CSP Summary Report</h3>
              <div
                className={classes.row}
                style={{ flexWrap: "wrap", height: "auto" }}
              >
                <div className={classes.searchInput}>
                  <div className={classes.Districts}>
                    <Grid item md={12} xs={12}>
                      <Autocomplete
                        id="combo-box-demo"
                        options={this.state.userContacts}
                        getOptionLabel={(option) => option.name}
                        onChange={(event, value) => {
                          this.handleCSPChange(event, value);
                        }}
                        value={
                          this.state.filterCspName
                            ? this.state.isCancel === true
                              ? null
                              : this.state.filterCspName
                            : null
                        }
                        renderInput={(params) => (
                          <Input
                            {...params}
                            fullWidth
                            label="CSP"
                            name="cspName"
                            variant="outlined"
                          />
                        )}
                      />
                    </Grid>
                  </div>
                </div>
                <div className={classes.searchInput}>
                  <Grid item md={12} xs={12}>
                    <Datepicker
                      label="Start Date"
                      name="startDate"
                      value={this.state.filterStartDate || ""}
                      format={"dd MMM yyyy"}
                      onChange={(event, value) =>
                        this.handleStartDateChange(event, value)
                      }
                    />
                  </Grid>
                </div>
                <div className={classes.searchInput}>
                  <Grid item md={12} xs={12}>
                    <Datepicker
                      label="End Date"
                      name="endDate"
                      value={this.state.filterEndDate || ""}
                      format={"dd MMM yyyy"}
                      onChange={(event, value) =>
                        this.handleEndDateChange(event, value)
                      }
                    />
                  </Grid>
                </div>
                <Button
                  style={{ marginRight: "5px", marginBottom: "8px" }}
                  onClick={this.handleSearch.bind(this)}
                >
                  Search
                </Button>
                &nbsp;&nbsp;&nbsp;
                <Button
                  style={{ marginBottom: "8px" }}
                  color="secondary"
                  clicked={this.cancelForm}
                >
                  reset
                </Button>
              </div>

              <h5>{reportFilterName}</h5>

              <Card style={{ maxHeight: "max-content" }}>
                <List>
                  <ListItem>
                    <ListItemText
                      primary={
                        <Typography style={{ fontWeight: "500" }}>
                          No of livelihood activites
                        </Typography>
                      }
                    />
                    <ListItemSecondaryAction style={{ paddingRight: "100px" }}>
                      {this.state.completedActivities.length}
                    </ListItemSecondaryAction>
                  </ListItem>
                </List>
                <Divider />

                <div style={{ paddingTop: "15px" }}>
                  <Typography
                    style={{
                      paddingLeft: "15px",
                      fontWeight: "500",
                    }}
                  >
                    Type of activities
                  </Typography>
                  <div style={{ paddingLeft: "15px" }}>
                    {elements.length > 0 ? (
                      <List>{elements}</List>
                    ) : (
                      <h5 style={{ paddingTop: "15px", paddingLeft: "13px" }}>
                        No records found
                      </h5>
                    )}
                  </div>
                </div>
                <Divider />

                <List>
                  <ListItem>
                    <ListItemText
                      primary={
                        <Typography style={{ fontWeight: "500" }}>
                          No of loans sanctioned
                        </Typography>
                      }
                    />
                    <ListItemSecondaryAction style={{ paddingRight: "100px" }}>
                      {this.state.sanctionedLoans.length}
                    </ListItemSecondaryAction>
                  </ListItem>
                </List>
                <Divider />

                <List>
                  <ListItem>
                    <ListItemText
                      primary={
                        <Typography style={{ fontWeight: "500" }}>
                          No of loan defaulters
                        </Typography>
                      }
                    />
                    <ListItemSecondaryAction style={{ paddingRight: "100px" }}>
                      {this.state.loanDefaulters.length}
                    </ListItemSecondaryAction>
                  </ListItem>
                </List>
                <Divider />

                <List>
                  <ListItem>
                    <ListItemText
                      primary={
                        <Typography style={{ fontWeight: "500" }}>
                          Amount of principal collected
                        </Typography>
                      }
                    />
                    <ListItemSecondaryAction style={{ paddingRight: "100px" }}>
                      ₹{this.state.principalCollected.toLocaleString()}
                    </ListItemSecondaryAction>
                  </ListItem>
                </List>
                <Divider />

                <List>
                  <ListItem>
                    <ListItemText
                      primary={
                        <Typography style={{ fontWeight: "500" }}>
                          Amount of interest collected
                        </Typography>
                      }
                    />
                    <ListItemSecondaryAction style={{ paddingRight: "100px" }}>
                      ₹{this.state.interestCollected.toLocaleString()}
                    </ListItemSecondaryAction>
                  </ListItem>
                </List>
                <Divider />
              </Card>

              <div style={{ paddingTop: "15px" }}>
                <Button>
                  <CSVLink
                    data={datas}
                    filename={fileName}
                    className={classes.csvData}
                  >
                    Download
                  </CSVLink>
                </Button>
              </div>
            </div>
          </Grid>
        </Grid>
      </Layout>
    );
  }