@chakra-ui/react#TabPanel JavaScript Examples

The following examples show how to use @chakra-ui/react#TabPanel. 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: ouput.js    From GitMarkonics with MIT License 6 votes vote down vote up
Output = (file) => {

  // const getMarkdownText = () => {
  //   var rawMarkup = marked("_Nothing_ to show ");
  //   if (file.file) {
  //     rawMarkup = marked(file.file);
  //     // console.log("file is", file);
  //   } else {
  //     rawMarkup = marked("_Nothing_ to show ");
  //   }
  //   return { __html: rawMarkup };
  // };

  return (
    <Box flex="1" bg="white" border="1px" borderColor="gray.10" p={5}>
      <Tabs>
        <TabList>
          <Tab>Output</Tab>

          {/* <Tab>Preview</Tab> */}
        </TabList>

        <TabPanels>
          <TabPanel>
            <Text whiteSpace="pre-line">{file.file}</Text>
          </TabPanel>

          {/* <TabPanel>
            <div dangerouslySetInnerHTML={getMarkdownText()} />
          </TabPanel> */}
          
        </TabPanels>
      </Tabs>
    </Box>
  );
}
Example #2
Source File: DashboardPanels.js    From web-client with Apache License 2.0 5 votes vote down vote up
DashboardPanels = () => {
    const user = Auth.getLoggedInUser();
    user.preferences = initialiseUserPreferences(user);
    const [dashboardConfig, setDashboardConfig] = useState(user?.preferences?.['web-client.widgets'] || InitialiseWidgetConfig());
    const [visibleWidgets, setVisibleWidgets] = useState(filterWidgets(user));

    const onWidgetChange = ev => {
        setDashboardConfig(prev => ({ ...prev, [ev.target.name]: { ...prev[ev.target.name], visible: ev.target.checked } }));
    }

    const onSave = () => {
        const user = Auth.getLoggedInUser();
        user.preferences = initialiseUserPreferences(user);

        user.preferences['web-client.widgets'] = dashboardConfig;

        secureApiFetch(`/users/${user.id}`, {
            method: 'PATCH',
            body: JSON.stringify({ preferences: user.preferences })
        })
            .then(() => {
                localStorage.setItem('user', JSON.stringify(user));

                setVisibleWidgets(filterWidgets(user));

                actionCompletedToast("Your preferences have been saved.");
            })
            .catch(err => console.error(err));
    }

    if (dashboardConfig === null) return <Loading />

    return <section>
        <Title type="Home" title="Dashboard" icon={<IconChartBar />} />
        <PageTitle value="Dashboard" />
        <Tabs>
            <TabList>
                <Tab>View</Tab>
                <Tab>Configure</Tab>
            </TabList>
            <TabPanels>
                <TabPanel>
                    <SimpleGrid gap="3" columns={{ base: "1", md: "2", xl: "3" }}>
                        {visibleWidgets.length === 0 ? <WelcomeWidget /> : visibleWidgets}
                    </SimpleGrid>
                </TabPanel>
                <TabPanel>
                    <h4>Select which widgets to present in your dashboard</h4>
                    <br />
                    <Stack>
                        {Object.keys(Widgets).map(widgetKey => {
                            const widget = Widgets[widgetKey];
                            if (!widget.hasOwnProperty("permissions") || PermissionsService.isAllowed(widget.permissions, user.permissions)) {
                                return <Checkbox key={widgetKey} name={widgetKey} isChecked={dashboardConfig.hasOwnProperty(widgetKey) && dashboardConfig[widgetKey].visible} onChange={onWidgetChange}>{Widgets[widgetKey].title}. <em>{Widgets[widgetKey].description}</em></Checkbox>
                            } else {
                                return <></>
                            }
                        })}
                    </Stack>

                    <Button onClick={onSave}>Save</Button>
                </TabPanel>
            </TabPanels>
        </Tabs>
    </section>
}
Example #3
Source File: Details.js    From web-client with Apache License 2.0 5 votes vote down vote up
VulnerabilityTemplateDetails = () => {
    const navigate = useNavigate();
    const { templateId } = useParams();
    const [vulnerability] = useFetch(`/vulnerabilities/${templateId}`)

    const cloneProject = async (templateId) => {
        secureApiFetch(`/vulnerabilities/${templateId}/clone`, { method: 'POST' })
            .then(resp => resp.json())
            .then(data => {
                navigate(`/vulnerabilities/${data.vulnerabilityId}/edit`);
            });
    }

    const destroy = useDelete('/vulnerabilities/', () => {
        navigate('/vulnerabilities/templates');
    });

    if (!vulnerability) return <Loading />

    if (vulnerability && !vulnerability.is_template) {
        return <Navigate to={`/vulnerabilities/${vulnerability.id}`} />
    }

    return (
        <>
            <div>
                <div className='heading'>
                    <Breadcrumb>
                        <Link to="/vulnerabilities">Vulnerabilities</Link>
                        <Link to="/vulnerabilities/templates">Templates</Link>
                    </Breadcrumb>
                    <ButtonGroup>
                        <PrimaryButton onClick={() => cloneProject(vulnerability.id)} leftIcon={<IconPlusCircle />}>Clone and edit</PrimaryButton>

                        <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                            <LinkButton href={`/vulnerabilities/${vulnerability.id}/edit`}>Edit</LinkButton>
                            <DeleteButton onClick={() => destroy(vulnerability.id)} />
                        </RestrictedComponent>
                    </ButtonGroup>
                </div>
                <article>
                    <PageTitle value={`${vulnerability.summary} vulnerability template`} />

                    <Title type='Vulnerability template' title={vulnerability.summary} icon={<IconFlag />} />

                    <Tabs>
                        <TabList>
                            <Tab>Description</Tab>
                            <Tab>Remediation</Tab>
                        </TabList>
                        <TabPanels>
                            <TabPanel>
                                <VulnerabilityDescriptionPanel vulnerability={vulnerability} />
                            </TabPanel>
                            <TabPanel>
                                <VulnerabilityRemediationPanel vulnerability={vulnerability} />
                            </TabPanel>
                        </TabPanels>
                    </Tabs>
                </article>
            </div>
        </>
    )
}
Example #4
Source File: Profile.js    From web-client with Apache License 2.0 5 votes vote down vote up
UserProfile = () => {
    const navigate = useNavigate();

    const { userId } = useParams();
    const [user] = useFetch(`/users/${userId}`)
    const [auditLog] = useFetch(`/users/${userId}/activity`)
    const deleteUser = useDelete('/users/');

    const onDeleteButtonClick = ev => {
        ev.preventDefault();

        deleteUser(userId).then(() => {
            navigate('/users');
        })
    }

    if (!user) return <Loading />

    return <>
        <div className='heading'>
            <Breadcrumb>
                <Link to="/users">Users</Link>
            </Breadcrumb>
            <ButtonGroup>
                <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                    <LinkButton href={`/users/${user.id}/edit`}>Edit</LinkButton>
                    <DeleteButton onClick={onDeleteButtonClick} />
                </RestrictedComponent>
            </ButtonGroup>
        </div>
        <div>
            <PageTitle value={`${user.full_name} user`} />

            <Title type='User profile' title={user.full_name}
                icon={<UserAvatar email={user.email} />} />
            <Tabs isLazy>
                <TabList>
                    <Tab>Details</Tab>
                    <Tab>Activity</Tab>
                </TabList>
                <TabPanels>
                    <TabPanel>
                        <div className="grid grid-two">
                            <div>
                                <h4>Properties</h4>
                                <dl>
                                    <dt>Short bio</dt>
                                    <dd>{user.short_bio ? user.short_bio : <EmptyField />}</dd>

                                    <dt>Role</dt>
                                    <dd><UserRoleBadge role={user.role} /><br /></dd>

                                    <dt>Timezone</dt>
                                    <dd>{user.timezone}</dd>

                                    <dt>Active?</dt>
                                    <dd><BooleanText value={user.active} /></dd>

                                    <dt>2FA enabled?</dt>
                                    <dd><BooleanText value={user.mfa_enabled} /></dd>
                                </dl>
                            </div>

                            <div>
                                <TimestampsSection entity={user} />

                            </div>
                        </div>
                    </TabPanel>
                    <TabPanel>
                        <h4>Activity (<Link to="/auditlog">view full audit log</Link>)</h4>
                        {auditLog ? <AuditLogsTable auditLog={auditLog} hideUserColumns="true" /> : <Loading />}
                    </TabPanel>
                </TabPanels>
            </Tabs>
        </div>
    </>
}
Example #5
Source File: Details.js    From web-client with Apache License 2.0 5 votes vote down vote up
ReportTemplateDetails = () => {
    const navigate = useNavigate();
    const { templateId } = useParams();
    const [vulnerability] = useFetch(`/vulnerabilities/${templateId}`)

    const cloneProject = async (templateId) => {
        secureApiFetch(`/vulnerabilities/${templateId}/clone`, { method: 'POST' })
            .then(resp => resp.json())
            .then(data => {
                navigate(`/vulnerabilities/${data.vulnerabilityId}/edit`);
            });
    }

    const destroy = useDelete('/vulnerabilities/', () => {
        navigate('/vulnerabilities/templates');
    });

    if (!vulnerability) return <Loading />

    if (vulnerability && !vulnerability.is_template) {
        return <Navigate to={`/vulnerabilities/${vulnerability.id}`} />
    }

    return (
        <>
            <div>
                <div className='heading'>
                    <Breadcrumb>
                        <Link to="/vulnerabilities">Vulnerabilities</Link>
                        <Link to="/vulnerabilities/templates">Templates</Link>
                    </Breadcrumb>
                    <ButtonGroup>
                        <PrimaryButton onClick={() => cloneProject(vulnerability.id)} leftIcon={<IconPlusCircle />}>Clone and edit</PrimaryButton>

                        <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                            <LinkButton href={`/vulnerabilities/${vulnerability.id}/edit`}>Edit</LinkButton>
                            <DeleteButton onClick={() => destroy(vulnerability.id)} />
                        </RestrictedComponent>
                    </ButtonGroup>
                </div>
                <article>
                    <PageTitle value={`${vulnerability.summary} vulnerability template`} />

                    <Title type='Vulnerability template' title={vulnerability.summary} icon={<IconFlag />} />

                    <Tabs>
                        <TabList>
                            <Tab>Description</Tab>
                            <Tab>Remediation</Tab>
                        </TabList>
                        <TabPanels>
                            <TabPanel>
                            </TabPanel>
                            <TabPanel>
                            </TabPanel>
                        </TabPanels>
                    </Tabs>
                </article>
            </div>
        </>
    )
}
Example #6
Source File: Details.js    From web-client with Apache License 2.0 5 votes vote down vote up
TemplateDetails = () => {
    const navigate = useNavigate();
    const { templateId } = useParams();
    const [template] = useFetch(`/projects/${templateId}`)

    const cloneProject = async (templateId) => {
        secureApiFetch(`/projects/${templateId}/clone`, { method: 'POST' })
            .then(resp => resp.json())
            .then(data => {
                navigate(`/projects/${data.projectId}/edit`);
            });
    }

    const destroy = useDelete('/projects/', () => {
        navigate('/projects/templates');
    });

    if (template && !template.is_template) {
        return <Navigate to={`/projects/${template.id}`} />
    }

    return <>
        <div className='heading'>
            <Breadcrumb>
                <Link to="/projects">Projects</Link>
                <Link to="/projects/templates">Templates</Link>
            </Breadcrumb>
            {template &&
                <ButtonGroup>
                    <PrimaryButton onClick={() => cloneProject(template.id)} leftIcon={<IconPlusCircle />}>Create project from template</PrimaryButton>
                    <LinkButton href={`/projects/${template.id}/edit`}>Edit</LinkButton>
                    <DeleteButton onClick={() => destroy(template.id)} />
                </ButtonGroup>
            }
        </div>
        {!template ?
            <Loading /> :
            <article>
                <PageTitle value={`${template.name} project template`} />
                <Title title={template.name} type='Project template' icon={<IconFolder />} />

                <Tabs>
                    <TabList>
                        <Tab>Details</Tab>
                        <Tab>Tasks</Tab>
                    </TabList>
                    <TabPanels>
                        <TabPanel><ProjectDetailsTab project={template} /></TabPanel>
                        <TabPanel><ProjectTasks project={template} /></TabPanel>
                    </TabPanels>
                </Tabs>
            </article>}
    </>
}
Example #7
Source File: Report.js    From web-client with Apache License 2.0 5 votes vote down vote up
ProjectReport = () => {
    const { projectId } = useParams();
    const [project, setProject] = useState(null);

    useEffect(() => {
        secureApiFetch(`/projects/${projectId}`, {
            method: 'GET',
        })
            .then(resp => resp.json())
            .then(json => {
                setProject(json);
            });
    }, [projectId, setProject]);

    if (!project) {
        return <Loading />
    }

    return (
        <>
            <PageTitle value={`Report ${project.name}`} />
            <div className='heading'>
                <Breadcrumb>
                    <Link to="/projects">Projects</Link>
                    <Link to={`/projects/${project.id}`}>{project.name}</Link>
                </Breadcrumb>
            </div>
            <Title type="Project reporting" title="Project report"
                icon={<IconReport />} />

            <Tabs>
                <TabList>
                    <Tab>Preview</Tab>
                    <Tab>Revisions</Tab>
                    {false && <Tab>Configuration</Tab>}
                </TabList>
                <TabPanels>
                    <TabPanel>
                        <ReportPreview projectId={projectId} />
                    </TabPanel>

                    <TabPanel>
                        <ReportRevisions projectId={projectId} />
                    </TabPanel>

                    {false &&
                        <TabPanel>
                            <ReportConfigurationForm projectId={projectId} />
                        </TabPanel>
                    }
                </TabPanels>
            </Tabs>

        </>
    )
}
Example #8
Source File: components.js    From idena-web with MIT License 5 votes vote down vote up
export function GetInvitationTabPanel(props) {
  return (
    <TabPanel p={0} pt={[6, 8]} color={['gray.300', 'initial']} {...props} />
  )
}
Example #9
Source File: Details.js    From web-client with Apache License 2.0 4 votes vote down vote up
ClientDetails = () => {
    const { clientId } = useParams();
    const navigate = useNavigate();

    const [client] = useFetch(`/clients/${clientId}`);
    const [contacts, fetchContacts] = useFetch(`/clients/${clientId}/contacts`);

    const [contact, setContact] = useState(new Contact());

    const onContactFormChange = ev => {
        setContact({ ...contact, [ev.target.name]: ev.target.value });
    }


    const deleteClient = useDelete(`/clients/`)
    const [logo, setLogo] = useState(null);
    const [smallLogo, setSmallLogo] = useState(null);

    const handleDelete = async () => {
        const confirmed = await deleteClient(clientId);
        if (confirmed)
            navigate('/clients');
    }

    const onFormSubmit = ev => {
        ev.preventDefault();

        secureApiFetch(`/clients/${clientId}/contacts`, { method: 'POST', body: JSON.stringify(contact) })
            .then(resp => {
                if (resp.status === 201) {
                    setContact(new Contact());
                    fetchContacts();
                    actionCompletedToast(`The contact has been added.`);
                } else {
                    errorToast("The contact could not be saved. Review the form data or check the application logs.")
                }
            })
    }

    const onContactDelete = contactId => {
        secureApiFetch(`/contacts/${contactId}`, { method: 'DELETE' })
            .then(() => {
                fetchContacts();
                actionCompletedToast("The contact has been deleted.");
            })
            .catch(err => console.error(err))
    }

    useEffect(() => {
        if (client) {
            if (client.small_logo_attachment_id) {
                downloadAndDisplayLogo(client.small_logo_attachment_id, 'small_logo');
            }

            if (client.logo_attachment_id) {
                downloadAndDisplayLogo(client.logo_attachment_id, 'logo');
            }
        }
    }, [client]);

    const downloadAndDisplayLogo = (logoId, type) => {
        secureApiFetch(`/attachments/${logoId}`, { method: 'GET' })
            .then(resp => {
                const contentDispositionHeader = resp.headers.get('Content-Disposition');
                const filenameRe = new RegExp(/filename="(.*)";/)
                const filename = filenameRe.exec(contentDispositionHeader)[1]
                return Promise.all([resp.blob(), filename]);
            })
            .then((values) => {
                const blob = values[0];
                const url = URL.createObjectURL(blob);
                if (type === 'small_logo') {
                    setSmallLogo(url);
                } else {
                    setLogo(url);
                }
            })
    }

    if (!client) {
        return <Loading />
    }

    return <div>
        <div className='heading'>
            <Breadcrumb>
                <Link to="/clients">Clients</Link>
            </Breadcrumb>
            <ButtonGroup>
                <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                    <EditButton onClick={(ev) => {
                        ev.preventDefault();
                        navigate(`/clients/${client.id}/edit`)
                    }}>Edit</EditButton>
                    <DeleteButton onClick={handleDelete} />
                </RestrictedComponent>
            </ButtonGroup>
        </div>
        <article>
            <div>
                <PageTitle value={`${client.name} client`} />
                <Title type='Client' title={client.name} icon={<IconBriefcase />} />
            </div>

            <Tabs isLazy>
                <TabList>
                    <Tab>Details</Tab>
                    <Tab>Contacts</Tab>
                    <Tab>Projects</Tab>
                </TabList>
                <TabPanels>
                    <TabPanel>
                        <div className="grid grid-two">
                            <div>
                                <h4>Properties</h4>

                                <dl>
                                    <dt>Address</dt>
                                    <dd>{client.address ?? '-'}</dd>

                                    <dt>URL</dt>
                                    <dd><ExternalLink href={client.url}>{client.url}</ExternalLink></dd>
                                </dl>

                                <h4>Branding</h4>

                                <dl>
                                    <dt>Main logo</dt>
                                    <dd>{logo ? <img src={logo} alt="The main logo" /> : <EmptyField />}</dd>

                                    <dt>Small logo</dt>
                                    <dd>{smallLogo ? <img src={smallLogo} alt="The smaller version of the logo" /> : <EmptyField />}</dd>
                                </dl>
                            </div>

                            <div>
                                <h4>Relations</h4>
                                <dl>
                                    <dt>Created by</dt>
                                    <dd><UserLink userId={client.creator_uid}>{client.creator_full_name}</UserLink></dd>
                                </dl>

                                <TimestampsSection entity={client} />
                            </div>
                        </div>
                    </TabPanel>

                    <TabPanel>
                        <h4>Contacts</h4>

                        {contacts && <>
                            <form onSubmit={onFormSubmit}>
                                <Table>
                                    <Thead>
                                        <Tr>
                                            <Th>Kind</Th>
                                            <Th>Name</Th>
                                            <Th>Role</Th>
                                            <Th>Email</Th>
                                            <Th>Phone</Th>
                                            <Th>&nbsp;</Th>
                                        </Tr>
                                    </Thead>
                                    <Tbody>
                                        <Tr>
                                            <Td>
                                                <Select name="kind" onChange={onContactFormChange} value={contact.kind || ""} isRequired>
                                                    <option value="general">General</option>
                                                    <option value="technical">Technical</option>
                                                    <option value="billing">Billing</option>
                                                </Select>
                                            </Td>
                                            <Td>
                                                <Input type="text" name="name" onChange={onContactFormChange} value={contact.name || ""} isRequired />
                                            </Td>
                                            <Td>
                                                <Input type="text" name="role" onChange={onContactFormChange} value={contact.role || ""} />
                                            </Td>
                                            <Td>
                                                <Input type="email" name="email" onChange={onContactFormChange} value={contact.email || ""} isRequired />
                                            </Td>
                                            <Td>
                                                <Input type="tel" name="phone" onChange={onContactFormChange} value={contact.phone || ""} />
                                            </Td>
                                            <Td>
                                                <Button type="submit">Add</Button>
                                            </Td>
                                        </Tr>
                                        {0 === contacts.length && <NoResultsTableRow numColumns={6} />}
                                        {contacts.map(contact => <>
                                            <Tr key={contact.id}>
                                                <Td>{contact.kind}</Td>
                                                <Td>{contact.name}</Td>
                                                <Td>{contact.role}</Td>
                                                <Td><MailLink email={contact.email} /></Td>
                                                <Td><TelephoneLink number={contact.phone} /></Td>
                                                <Td><DeleteIconButton onClick={onContactDelete.bind(this, contact.id)} /></Td>
                                            </Tr>
                                        </>)}
                                    </Tbody>
                                </Table>
                            </form>
                        </>}
                    </TabPanel>
                    <TabPanel>
                        <ClientProjectsTab clientId={clientId} />
                    </TabPanel>
                </TabPanels>
            </Tabs>

        </article>
    </div>
}
Example #10
Source File: Details.js    From web-client with Apache License 2.0 4 votes vote down vote up
CommandDetails = () => {
    const { commandId } = useParams();
    const navigate = useNavigate();

    const [command] = useFetch(`/commands/${commandId}`)
    const deleteClient = useDelete(`/commands/`)

    const handleDelete = async () => {
        const confirmed = await deleteClient(commandId);
        if (confirmed)
            navigate('/commands');
    }

    if (!command) {
        return <Loading />
    }

    return <div>
        <div className='heading'>
            <Breadcrumb>
                <Link to="/commands">Commands</Link>
            </Breadcrumb>
            <ButtonGroup>
                <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                    <EditButton onClick={(ev) => {
                        ev.preventDefault();
                        navigate(`/commands/${command.id}/edit`)
                    }}>Edit</EditButton>
                    <DeleteButton onClick={handleDelete} />
                </RestrictedComponent>
            </ButtonGroup>
        </div>
        <article>
            <div>
                <PageTitle value={`${command.name} command`} />

                <Title type='Command' title={command.name} icon={<IconBriefcase />} />
                <Tags values={command.tags} />
            </div>

            <Tabs>
                <TabList>
                    <Tab>Details</Tab>
                    <Tab>Run instructions</Tab>
                    <Tab>Command outputs</Tab>
                    <Tab>Terminal</Tab>
                </TabList>
                <TabPanels>
                    <TabPanel>
                        <div className="grid grid-two">
                            <div>
                                <dl>
                                    <dt>Description</dt>
                                    <dd>{command.description ? <ReactMarkdown>{command.description}</ReactMarkdown> : <EmptyField />}</dd>

                                    {command.output_parser && <>
                                        <dt>Output parser support</dt>
                                        <dl>Yes ({command.output_parser})</dl>
                                    </>}
                                    {command.more_info_url && <>
                                        <dt>More information URL</dt>
                                        <dl>{command.more_info_url ? <ExternalLink href={command.more_info_url}>{command.more_info_url}</ExternalLink> : <EmptyField />}</dl>
                                    </>}

                                    {CommandService.hasCommand(command) && <>
                                        {CommandService.isHost(command) && <>
                                            <dt>Command line example</dt>
                                            <dd>
                                                <ShellCommand>{HostCommandLineGenerator.generateEntryPoint(command)} {HostCommandLineGenerator.renderArguments(command)}</ShellCommand>
                                            </dd>
                                        </>}
                                        <dt>Command line example using rmap CLI</dt>
                                        <dd>
                                            <ShellCommand>{CommandService.generateEntryPoint(command)} {CommandService.renderArguments(command)}</ShellCommand>
                                        </dd>
                                    </>}
                                </dl>
                            </div>

                            <div>
                                <h4>Relations</h4>
                                <dl>
                                    <dt>Created by</dt>
                                    <dd><UserLink userId={command.creator_uid}>{command.creator_full_name}</UserLink></dd>
                                </dl>

                                <TimestampsSection entity={command} />
                            </div>
                        </div>
                    </TabPanel>
                    <TabPanel>
                        <CommandInstructions command={command} />
                    </TabPanel>
                    <TabPanel>
                        <CommandOutputs command={command} />
                    </TabPanel>
                    <TabPanel>
                        <CommandTerminal commands={[]} />
                    </TabPanel>
                </TabPanels>
            </Tabs>
        </article>
    </div >
}
Example #11
Source File: ChallengeDetailView.jsx    From scaffold-directory with MIT License 4 votes vote down vote up
export default function ChallengeDetailView({ serverUrl, address, userProvider, userRole, loadWeb3Modal }) {
  const [descriptionJs, setDescriptionJs] = useState(null);
  const [descriptionTs, setDescriptionTs] = useState(null);
  const { challengeId } = useParams();
  const history = useHistory();
  const { isOpen, onOpen, onClose } = useDisclosure();
  const [openModalOnLoad, setOpenModalOnLoad] = useState(false);

  const challenge = challengeInfo[challengeId];
  const isWalletConnected = !!userRole;
  const isAnonymous = userRole && USER_ROLES.anonymous === userRole;

  // Fetch challenge description from local files.
  // In the future, this might be a fetch to the repos/branchs README
  // (Ideally fetched at build time)
  useEffect(() => {
    getChallengeReadme(challengeId, "js")
      .then(text => setDescriptionJs(parseGithubReadme(text)))
      .catch(() => setDescriptionJs(challenge.description));

    getChallengeReadme(challengeId, "ts")
      .then(text => setDescriptionTs(parseGithubReadme(text)))
      .catch(() => setDescriptionTs(challenge.description));
  }, [challengeId, challenge]);

  useEffect(() => {
    if (!isWalletConnected || isAnonymous) return;

    if (openModalOnLoad) {
      onOpen();
      setOpenModalOnLoad(false);
    }
  }, [isAnonymous, isWalletConnected, onOpen, userRole, openModalOnLoad, setOpenModalOnLoad]);

  if (!challenge) {
    // TODO implement a 404 page
    // this looks good: https://ant.design/components/result/#components-result-demo-404
    history.push("/404");
  }

  const handleSubmitChallengeModal = async () => {
    if (isWalletConnected && !isAnonymous) {
      return onOpen();
    }

    if (!isWalletConnected) {
      await loadWeb3Modal();
      setOpenModalOnLoad(true);
    }
  };

  const challengeActionButtons = (type = "JS") => {
    const repo = type === "JS" ? JS_CHALLENGE_REPO : TS_CHALLENGE_REPO;
    return (
      <Box>
        <Button
          as="a"
          colorScheme="gray"
          variant="outline"
          href={`${repo}/tree/${challenge.branchName}`}
          target="_blank"
          rel="noopener noreferrer"
        >
          View it on Github <ExternalLinkIcon ml={1} />
        </Button>
        <Box pos="fixed" bottom={0} p={6} left={0} right={0}>
          <Tooltip label={isAnonymous ? "You need to register as a builder" : "Submit Challenge"} shouldWrapChildren>
            <Button colorScheme="blue" boxShadow="dark-lg" onClick={handleSubmitChallengeModal} disabled={isAnonymous}>
              Submit challenge
            </Button>
          </Tooltip>
        </Box>
      </Box>
    );
  };

  return (
    // Magic number for maxW to match GitHub
    <Container maxW="894px" mb="60px">
      <Box textAlign="center" mb={6}>
        <Heading as="h1" mb={4}>
          {challenge.label}
        </Heading>
      </Box>
      <Tabs variant="enclosed-colored" align="center">
        <TabList>
          <Tab>Javascript</Tab>
          <Tab>Typescript</Tab>
        </TabList>
        <TabPanels align="left">
          <TabPanel>
            <SkeletonText mt="4" noOfLines={4} spacing="4" isLoaded={descriptionJs} />
            <ReactMarkdown components={ChakraUIRenderer(chakraMarkdownComponents)}>{descriptionJs}</ReactMarkdown>
            <Box textAlign="center" my={6}>
              {challengeActionButtons("JS")}
            </Box>
          </TabPanel>
          <TabPanel>
            <SkeletonText mt="4" noOfLines={4} spacing="4" isLoaded={descriptionTs} />
            <ReactMarkdown components={ChakraUIRenderer(chakraMarkdownComponents)}>{descriptionTs}</ReactMarkdown>
            <Box textAlign="center" my={6}>
              {challengeActionButtons("TS")}
            </Box>
          </TabPanel>
        </TabPanels>
      </Tabs>
      <Modal isOpen={isOpen} onClose={onClose}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Submit Challenge</ModalHeader>
          <ModalCloseButton />
          <ModalBody px={6} pb={8}>
            <ChallengeSubmission
              challenge={challenge}
              serverUrl={serverUrl}
              address={address}
              userProvider={userProvider}
              loadWeb3Modal={loadWeb3Modal}
            />
          </ModalBody>
        </ModalContent>
      </Modal>
    </Container>
  );
}
Example #12
Source File: Details.js    From web-client with Apache License 2.0 4 votes vote down vote up
ProjectDetails = () => {
    const navigate = useNavigate();
    const { projectId } = useParams();
    const { colorMode } = useColorMode()

    const [project, updateProject] = useFetch(`/projects/${projectId}`)
    const [users] = useFetch(`/projects/${projectId}/users`)
    const destroy = useDelete(`/projects/`, updateProject);

    const handleGenerateReport = () => {
        navigate(`/projects/${project.id}/report`)
    }

    const handleManageTeam = () => {
        navigate(`/projects/${project.id}/membership`)
    }

    const onArchiveButtonClick = (project) => {
        secureApiFetch(`/projects/${project.id}`, {
            method: 'PATCH',
            body: JSON.stringify({ archived: !project.archived })
        })
            .then(() => {
                updateProject();
                actionCompletedToast('The project has been updated.');
            })
            .catch(err => console.error(err))
    }

    if (project && project.is_template) {
        return <Navigate to={`/projects/templates/${project.id}`} />
    }

    return <>
        <div className='heading'>
            <Breadcrumb>
                <Link to="/projects">Projects</Link>
            </Breadcrumb>
            {project && <>
                <PageTitle value={`${project.name} project`} />
                <ProjectTeam project={project} users={users} />

                <ButtonGroup isAttached>
                    <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                        {!project.archived && <>
                            <LinkButton href={`/projects/${project.id}/edit`}>Edit</LinkButton>
                            <SecondaryButton onClick={handleGenerateReport} leftIcon={<IconClipboardCheck />}>Report</SecondaryButton>
                            <SecondaryButton onClick={handleManageTeam} leftIcon={<IconUserGroup />}>Membership</SecondaryButton>
                        </>}

                        <Menu>
                            <MenuButton as={IconButton} aria-label='Options' icon={<FontAwesomeIcon icon={faEllipsis} />} variant='outline' />
                            <MenuList>
                                <MenuItem onClick={() => onArchiveButtonClick(project)}>{project.archived ? 'Unarchive' : 'Archive'}</MenuItem>
                                <MenuItem icon={<FontAwesomeIcon icon={faTrash} />} color={colorMode === "light" ? "red.500" : "red.400"} onClick={() => destroy(project.id)}>Delete</MenuItem>
                            </MenuList>
                        </Menu>
                    </RestrictedComponent>
                </ButtonGroup>
            </>}
        </div>
        {!project ? <Loading /> :
            <>
                <Title title={project.name} type="Project" icon={<IconFolder />} />

                <Tabs>
                    <TabList>
                        <Tab>Details</Tab>
                        <Tab>Targets</Tab>
                        <Tab>Tasks</Tab>
                        <Tab>Vulnerabilities</Tab>
                        <Tab>Notes</Tab>
                        <Tab>Attachments</Tab>
                        <Tab>Vault</Tab>
                    </TabList>
                    <TabPanels>
                        <TabPanel><ProjectDetailsTab project={project} /></TabPanel>
                        <TabPanel><ProjectTargets project={project} /></TabPanel>
                        <TabPanel><ProjectTasks project={project} /></TabPanel>
                        <TabPanel><ProjectVulnerabilities project={project} /></TabPanel>
                        <TabPanel><ProjectNotesTab project={project} /></TabPanel>
                        <TabPanel><ProjectAttachmentsTab project={project} /></TabPanel>
                        <TabPanel><ProjectVaultTab project={project} /></TabPanel>
                    </TabPanels>
                </Tabs>
            </>
        }
    </>
}
Example #13
Source File: ChallengeReviewRow.jsx    From scaffold-directory with MIT License 4 votes vote down vote up
export default function ChallengeReviewRow({ challenge, isLoading, approveClick, rejectClick, userProvider }) {
  const [comment, setComment] = useState(challenge.reviewComment ?? "");
  const [testPassed, setTestPassed] = useState(null);
  const [isRunningTests, setIsRunningTests] = useState(false);
  const { isOpen, onOpen, onClose } = useDisclosure();
  const address = useUserAddress(userProvider);

  if (!challengeInfo[challenge.id]) {
    return null;
  }

  // We asume that rejected challenges will always have review Comments.
  const isAutograded = challenge.autograding;
  // ToDo. Use the stored events.
  const isResubmitted = !isAutograded && !!challenge.reviewComment;

  const runTests = async () => {
    try {
      console.log("Testing challenge with the auto-grader");

      setIsRunningTests(true);
      setTestPassed(null);

      const result = await runAutograderTest(challenge.id, challenge.contractUrl, address);
      const resultData = result.data;

      console.log("Testing results", resultData);
      setTestPassed(resultData.success);
      setComment(resultData.feedback ?? resultData.error);
    } catch (e) {
      console.log("Error calling the auto-grader", e);
    } finally {
      setIsRunningTests(false);
    }
  };

  const challengeReviewDisplay = (
    <Link as={RouteLink} to={`/challenge/${challenge.id}`}>
      {challengeInfo[challenge.id].label}
      {isResubmitted && (
        <>
          <br />
          <Text fontSize="xs">(Resubmitted)</Text>
        </>
      )}
      {isAutograded && (
        <>
          <br />
          <Text fontSize="xs" color="orange.500">
            (Autograded)
          </Text>
        </>
      )}
    </Link>
  );

  const submittedMoment = moment(challenge.submittedTimestamp);

  const reviewRow = (
    <>
      <Td>
        <Link as={RouteLink} to={`/builders/${challenge.userAddress}`} pos="relative">
          <Address address={challenge.userAddress} w="12.5" fontSize="16" />
        </Link>
      </Td>
      <Td>{challengeReviewDisplay}</Td>
      <Td>
        <DateWithTooltip timestamp={challenge.submittedTimestamp} />
      </Td>
    </>
  );

  return (
    <Tr>
      {reviewRow}
      <Td>
        <Button type="button" colorScheme="blue" disabled={isLoading} className="danger" onClick={onOpen} size="xs">
          Review
        </Button>
      </Td>
      <Modal isOpen={isOpen} onClose={onClose} size="xl">
        <ModalOverlay />
        <ModalContent maxW="56rem">
          <ModalHeader>Review Challenge</ModalHeader>
          <ModalCloseButton />
          <Table mb={4}>
            <Thead>
              <Tr>
                <Th>Builder</Th>
                <Th>Challenge & Links</Th>
              </Tr>
            </Thead>
            <Tbody>
              <Tr>
                <Td>
                  <Link as={RouteLink} to={`/builders/${challenge.userAddress}`} pos="relative">
                    <Address address={challenge.userAddress} w="12.5" fontSize="16" />
                  </Link>
                </Td>
                <Td>
                  {challengeReviewDisplay}
                  <UnorderedList>
                    <ListItem>
                      <Link
                        // Legacy branchUrl
                        href={challenge.contractUrl || challenge.branchUrl}
                        color="teal.500"
                        target="_blank"
                        rel="noopener noreferrer"
                      >
                        Contract
                      </Link>
                    </ListItem>
                    <ListItem>
                      <Link href={challenge.deployedUrl} color="teal.500" target="_blank" rel="noopener noreferrer">
                        Demo
                      </Link>
                    </ListItem>
                    <ListItem>
                      Submitted{" "}
                      <Tooltip label={submittedMoment.format("YYYY-MM-DD, HH:mm")}>
                        <chakra.span cursor="pointer">{submittedMoment.fromNow()}</chakra.span>
                      </Tooltip>
                    </ListItem>
                    <ListItem listStyleType="none" mt={2}>
                      <Flex align="center">
                        <Button onClick={runTests} isLoading={isRunningTests} mr={2}>
                          Run tests
                        </Button>
                        {isBoolean(testPassed) && (
                          <Badge colorScheme={testPassed ? "green" : "red"}>
                            {testPassed ? "Accepted" : "Rejected"}
                          </Badge>
                        )}
                      </Flex>
                    </ListItem>
                  </UnorderedList>
                </Td>
              </Tr>
            </Tbody>
          </Table>
          <ModalBody px={6} pb={0}>
            <Tabs variant="enclosed-colored">
              <TabList>
                <Tab>Write</Tab>
                <Tab>Preview</Tab>
              </TabList>
              <TabPanels align="left">
                <TabPanel p={0}>
                  <Textarea
                    onChange={e => {
                      const value = e.target.value;
                      setComment(value);
                    }}
                    placeholder="Comment"
                    style={{ marginBottom: 10 }}
                    rows={10}
                    value={comment}
                    borderTopRadius={0}
                  />
                </TabPanel>
                <TabPanel>
                  <ReactMarkdown components={ChakraUIRenderer(chakraMarkdownComponents)}>{comment}</ReactMarkdown>
                </TabPanel>
              </TabPanels>
            </Tabs>
          </ModalBody>
          <ModalFooter>
            <Button
              type="button"
              colorScheme="red"
              disabled={isLoading}
              className="danger"
              onClick={() => rejectClick(challenge.userAddress, challenge.id, comment)}
              size="sm"
              isFullWidth
            >
              Reject
            </Button>
            <Button
              type="button"
              colorScheme="green"
              disabled={isLoading}
              ml={3}
              onClick={() => approveClick(challenge.userAddress, challenge.id, comment)}
              size="sm"
              isFullWidth
            >
              Approve
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </Tr>
  );
}
Example #14
Source File: wallets.js    From idena-web with MIT License 4 votes vote down vote up
export default function Index() {
  const {t} = useTranslation()

  const {coinbase} = useAuthState()

  const [{all}] = useDeferredVotes()

  const {
    data: {balance, stake},
    isLoading,
  } = useBalance()

  const receiveDrawerDisclosure = useDisclosure()

  const sendDrawerDisclosure = useDisclosure()

  return (
    <Layout>
      <Page pt={[4, 6]}>
        <MobileApiStatus left={4} />
        <PageTitleNew>{t('Wallets')}</PageTitleNew>
        <Flex w="100%" flexFlow="row wrap">
          <Flex flexBasis={['100%', '50%']} order={1}>
            <Avatar
              display={['block', 'none']}
              size="80px"
              mr={6}
              address={coinbase}
            />
            <TotalAmount
              amount={parseFloat(balance) + parseFloat(stake)}
              isLoading={isLoading}
              mt={[2, 0]}
            />
          </Flex>
          <Flex flexBasis={['100%', '50%']} order={[4, 2]} mt={1}>
            <HStack
              justifyContent={['space-around', 'flex-end']}
              h={6}
              alignItems="center"
              flexBasis="100%"
            >
              <VDivider display={['none', 'initial']} />
              <IconButton
                mx={[3, 0]}
                fontSize={['mobile', 'md']}
                color={['red.500', 'blue.500']}
                icon={
                  <SendOutIcon boxSize={5} color={['red.500', 'blue.500']} />
                }
                onClick={sendDrawerDisclosure.onOpen}
              >
                {t('Send')}
              </IconButton>
              <VDivider />
              <IconButton
                mx={[3, 0]}
                fontSize={['mobile', 'md']}
                icon={<ReceiveIcon boxSize={5} color="blue.500" />}
                onClick={receiveDrawerDisclosure.onOpen}
              >
                {t('Receive')}
              </IconButton>
            </HStack>
          </Flex>
          <Flex flexBasis="100%" order={[2, 3]} mt={[8, 2]}>
            <Link
              target="_blank"
              href={`https://scan.idena.io/address/${coinbase}`}
              color="blue.500"
              fontWeight={500}
              w={['100%', 'auto']}
            >
              <Flex
                fontSize={['base', 'md']}
                alignItems="center"
                w={['100%', 'auto']}
              >
                <Box
                  boxSize={8}
                  backgroundColor="brandBlue.10"
                  borderRadius="10px"
                  display={['inline-block', 'none']}
                >
                  <OpenExplorerIcon boxSize={5} mt={1} ml={3 / 2} />
                </Box>
                <Box
                  as="span"
                  ml={[3, 0]}
                  borderBottomWidth={['1px', 0]}
                  flex={[1, 'auto']}
                  pb={[1, 0]}
                >
                  {t('More details in explorer')}{' '}
                  <Icon display={['none', 'inline']} as={FiChevronRight} />
                </Box>
              </Flex>
            </Link>
          </Flex>
          <Flex
            flexBasis="100%"
            order={[3, 4]}
            overflowX={['auto', 'initial']}
            sx={{
              '&::-webkit-scrollbar': {
                display: 'none',
              },
            }}
            mt={8}
            mb={[6, 0]}
          >
            <WalletCard
              address={coinbase}
              wallet={{name: 'Main', balance, isStake: false}}
              isSelected
              onSend={sendDrawerDisclosure.onOpen}
              onReceive={receiveDrawerDisclosure.onOpen}
              isLoading={isLoading}
            />
            <WalletCard
              wallet={{name: 'Stake', balance: stake, isStake: true}}
              isLoading={isLoading}
            />
          </Flex>
        </Flex>

        <Heading
          fontSize="lg"
          color="brandGray.500"
          fontWeight={500}
          mb={0}
          mt={8}
          display={['none', 'block']}
        >
          {t('Transactions')}
        </Heading>

        {all.length > 0 ? (
          <Tabs variant="unstyled" w={['100%', 'auto']} mt={[8, 6]}>
            <TabList bg={['gray.50', 'white']} borderRadius="md" p={[1, 0]}>
              <TransactionsTab>
                {t('Scheduled')}
                {all.length > 0 && (
                  <>
                    <Badge ml={2} display={['none', 'inline-block']}>
                      {all.length}
                    </Badge>
                    <Box as="span" ml={1} display={['inline', 'none']}>
                      {all.length}
                    </Box>
                  </>
                )}
              </TransactionsTab>
              <TransactionsTab> {t('Recent')}</TransactionsTab>
            </TabList>
            <TabPanels mt={4}>
              <TabPanel p={0}>
                <WalletPendingTransactions />
              </TabPanel>
              <TabPanel p={0}>
                <WalletTransactions address={coinbase} />
              </TabPanel>
            </TabPanels>
          </Tabs>
        ) : (
          <Flex mt={4}>
            <WalletTransactions address={coinbase} />
          </Flex>
        )}

        <SendDrawer {...sendDrawerDisclosure} />

        <ReceiveDrawer address={coinbase} {...receiveDrawerDisclosure} />
      </Page>
    </Layout>
  )
}
Example #15
Source File: Details.js    From web-client with Apache License 2.0 4 votes vote down vote up
TaskDetails = () => {
    const loggedInUser = Auth.getLoggedInUser();
    const navigate = useNavigate();
    const { taskId } = useParams();
    const [task, fetchTask] = useFetch(`/tasks/${taskId}`)
    const [users] = useFetch(`/users`)
    const [project, setProject] = useState(null);
    const [command, setCommand] = useState(null);

    const parentType = 'task';
    const parentId = taskId;
    const [attachments, reloadAttachments] = useFetch(`/attachments?parentType=${parentType}&parentId=${parentId}`)

    const destroy = useDelete('/tasks/', fetchTask);

    const handleDelete = () => {
        destroy(task.id);
        navigate('/tasks');
    }

    const onAssigneeChange = ev => {
        const assigneeUid = ev.target.value;
        secureApiFetch(`/tasks/${task.id}`, {
            method: 'PATCH',
            body: JSON.stringify({ assignee_uid: '' === assigneeUid ? null : assigneeUid })
        })
            .then(() => {
                actionCompletedToast("The assignee has been updated.");
                fetchTask()
            })
            .catch(err => console.error(err))
    }

    const onStatusChange = ev => {
        const status = ev.target.value;
        secureApiFetch(`/tasks/${task.id}`, {
            method: 'PATCH',
            body: JSON.stringify({ status: status })
        })
            .then(() => {
                actionCompletedToast("The status has been transitioned.");
                fetchTask()
            })
            .catch(err => console.error(err))
    }

    useEffect(() => {
        if (task) {
            if (task.command_id) {
                secureApiFetch(`/commands/${task.command_id}`, { method: 'GET' })
                    .then(resp => resp.json())
                    .then(command => setCommand(command))
                    .catch(err => console.error(err))
            }

            secureApiFetch(`/projects/${task.project_id}`, { method: 'GET' })
                .then(resp => resp.json())
                .then(project => setProject(project))
                .catch(err => console.error(err))
        }
    }, [task])

    return <div>
        <div className="heading">
            <Breadcrumb>
                <Link to="/tasks">Tasks</Link>
                {project && <Link to={`/projects/${project.id}`}>{project.name}</Link>}
            </Breadcrumb>
            {task && users &&
                <HStack alignItems='flex-end'>
                    <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                        <Link to={`/tasks/${task.id}/edit`}>Edit</Link>
                        <label>Transition to&nbsp;
                            <Select onChange={onStatusChange} value={task.status}>
                                {TaskStatuses.map((status, index) =>
                                    <option key={index} value={status.id}>{status.name}</option>
                                )}
                            </Select>
                        </label>
                        <DeleteButton onClick={() => handleDelete(task.id)} />
                    </RestrictedComponent>
                </HStack>
            }
        </div>
        {!task ? <Loading /> :
            <article>
                <PageTitle value={`${task.summary} task`} />

                <Title title={task.summary} type='Task' icon={<IconClipboard />} />

                <Tabs>
                    <TabList>
                        <Tab>Details</Tab>
                        {null !== command && <Tab>Command instructions</Tab>}
                        <Tab>Attachments</Tab>
                    </TabList>
                    <TabPanels>
                        <TabPanel>
                            <div className="grid grid-two">
                                <div>
                                    <h4>Description</h4>
                                    {task.description ? <ReactMarkdown>{task.description}</ReactMarkdown> : <EmptyField />}
                                    <h4>Priority</h4>
                                    <p>{task.priority}</p>
                                    <h4>Status</h4>
                                    <p style={{ display: 'flex', alignItems: 'center', columnGap: 'var(--margin)' }}>
                                        <TaskStatusFormatter task={task} />
                                    </p>
                                    {task.command_id && <>
                                        <h4>Command</h4>
                                        <CommandBadge command={{ id: task.command_id, name: task.command_name }} />
                                    </>}
                                </div>

                                <div>
                                    <h4>People</h4>
                                    <dl>
                                        <dt>Created by</dt>
                                        <dd><UserLink userId={task.creator_uid}>{task.creator_full_name}</UserLink></dd>

                                        <dt>Assigned to</dt>
                                        <dd>
                                            {users &&
                                                <Select onChange={onAssigneeChange} defaultValue={task.assignee_uid}>
                                                    <option value="">(nobody)</option>
                                                    {users.map((user, index) =>
                                                        <option key={index} value={user.id}>{user.full_name}{user.id === loggedInUser.id ? " (You)" : ""}</option>
                                                    )}
                                                </Select>}
                                        </dd>
                                    </dl>

                                    <TimestampsSection entity={task} />
                                    {task.due_date &&
                                        <dl>
                                            <dt>Due date</dt>
                                            <dd><RelativeDateFormatter date={task.due_date} /></dd>
                                        </dl>
                                    }
                                </div>
                            </div>
                        </TabPanel>
                        {null !== command && <TabPanel>
                            <CommandInstructions command={command} task={task} />
                        </TabPanel>}
                        <TabPanel>
                            <AttachmentsDropzone parentType={parentType} parentId={parentId} onUploadFinished={reloadAttachments} />

                            <h4><IconDocument />Attachment list</h4>
                            <AttachmentsTable attachments={attachments} reloadAttachments={reloadAttachments} />
                        </TabPanel>
                    </TabPanels>
                </Tabs>
            </article>
        }
    </div>
}
Example #16
Source File: Profile.js    From DAOInsure with MIT License 4 votes vote down vote up
function Profile() {
	const web3Context = useContext(Web3Context);
	const {
		signerAddress,
		userDaoTokenBalance,
		fetchProposals,
		fetchVotedProposals,
		proposalsArray,
		votedProposalsArray,
	} = web3Context;

	const [daoTokenBalance, setDaoTokenBalance] = useState(0);
	const [stable, setStable] = useState(false);

	useEffect(() => {
		setInterval(async () => {
			setDaoTokenBalance(await userDaoTokenBalance());
		}, 10000);
	}, []);

	useEffect(() => {
		fetchProposals();
		fetchVotedProposals();
	}, [stable]);

	function con() {
		console.log(proposalsArray);
	}

	return (
		<VStack
			alignItems='flex-start'
			height='calc(100vh - 64px)'
			px='250px'
			py='20px'
			width='100%'>
			<HStack width='100%' alignItems='flex-start'>
				<Box
					borderWidth='2px'
					borderRadius='full'
					borderColor='whatsapp.500'
					padding='2px'>
					<Avatar
						size='md'
						icon={
							<Jazzicon
								diameter='48'
								address={`${signerAddress}`}
							/>
						}
					/>
				</Box>
				<VStack alignItems='flex-start'>
					<Heading fontSize='20px'>{signerAddress}</Heading>
					<Tag>10DAIx / month</Tag>
				</VStack>
				<Spacer />
				<VStack>
					<Tag>INSURE Tokens : {daoTokenBalance}</Tag>
				</VStack>
			</HStack>
			<Grid
				width='100%'
				mt='30px !important'
				templateColumns='3fr 2fr'
				gridGap={5}
				alignItems='flex-start'>
				<Tabs
					colorScheme='whatsapp'
					variant='soft-rounded'
					width='100%'>
					<TabList>
						<Tab onClick={con}>
							Claims{" "}
							<Tag ml={2} borderRadius='20px'>
								{proposalsArray.length}
							</Tag>
						</Tab>
						<Tab>
							Voted For
							<Tag ml={2} borderRadius='20px'>
								{votedProposalsArray.length}
							</Tag>
						</Tab>
					</TabList>
					<TabPanels>
						<TabPanel mt={3} padding={0}>
							<Card cardTitle='Claims'>
								<Table>
									<Tbody>
										{proposalsArray.map(function (
											element,
											id
										) {
											return (
												<Tr key={id}>
													<Th>
														{" "}
														{element[0].toNumber()}{" "}
													</Th>
													<Th>{element[2]}</Th>
													<Th>
														{element[7] ? (
															<span>
																{" "}
																Passed{" "}
															</span>
														) : (
															<span>
																{" "}
																Failed{" "}
															</span>
														)}
													</Th>
												</Tr>
											);
										})}
									</Tbody>
								</Table>
							</Card>
						</TabPanel>
						<TabPanel mt={3} padding={0}>
							<Card cardTitle='Claims'>
								<Table>
									<Tbody>
										{votedProposalsArray.map(function (
											element,
											id
										) {
											return (
												<Tr key={id}>
													<Th>
														{" "}
														{element[0].toNumber()}{" "}
													</Th>
													<Th>{element[2]}</Th>
													<Th>
														{element[7] ? (
															<span>
																{" "}
																Passed{" "}
															</span>
														) : (
															<span>
																{" "}
																Failed{" "}
															</span>
														)}
													</Th>
												</Tr>
											);
										})}
									</Tbody>
								</Table>
							</Card>
						</TabPanel>
					</TabPanels>
				</Tabs>
			</Grid>
		</VStack>
	);
}
Example #17
Source File: Details.js    From web-client with Apache License 2.0 4 votes vote down vote up
VulnerabilityDetails = () => {
    const navigate = useNavigate();
    const { vulnerabilityId } = useParams();
    const [vulnerability, updateVulnerability] = useFetch(`/vulnerabilities/${vulnerabilityId}`)
    const deleteVulnerability = useDelete(`/vulnerabilities/`)

    const parentType = 'vulnerability';
    const parentId = vulnerabilityId;
    const [attachments, reloadAttachments] = useFetch(`/attachments?parentType=${parentType}&parentId=${parentId}`)

    const handleDelete = async () => {
        const confirmed = await deleteVulnerability(vulnerabilityId);
        if (confirmed)
            navigate('/vulnerabilities')
    }

    const onStatusChange = ev => {
        const [status, substatus] = ev.target.value.split('-');
        secureApiFetch(`/vulnerabilities/${vulnerability.id}`, {
            method: 'PATCH',
            body: JSON.stringify({ status, substatus })
        })
            .then(() => {
                actionCompletedToast("The status has been transitioned.");
                updateVulnerability()
            })
            .catch(err => console.error(err))
    }

    if (!vulnerability) return <Loading />

    if (vulnerability && vulnerability.is_template) {
        return <Navigate to={`/vulnerabilities/templates/${vulnerability.id}`} />
    }

    return <div>
        <div className='heading'>
            <Breadcrumb>
                <Link to="/vulnerabilities">Vulnerabilities</Link>
            </Breadcrumb>
            <HStack alignItems='flex-end'>
                <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                    <EditButton onClick={(ev) => {
                        ev.preventDefault();
                        navigate(`/vulnerabilities/${vulnerability.id}/edit`)
                    }}>Edit</EditButton>

                    <label>Transition to&nbsp;
                        <Select onChange={onStatusChange} value={vulnerability.status + '-' + vulnerability.substatus}>
                            {VulnerabilityStatuses.map(status =>
                                <option key={`vulnstatus_${status.id}`} value={status.id}>{status.name}</option>
                            )}
                        </Select>
                    </label>

                    <DeleteButton onClick={handleDelete} />
                </RestrictedComponent>
            </HStack>
        </div>
        <article>
            <PageTitle value={`${vulnerability.summary} vulnerability`} />

            <Title type='Vulnerability' title={vulnerability.external_id ? <><strong>{vulnerability.external_id.toUpperCase()}</strong>&nbsp;{vulnerability.summary}</> : vulnerability.summary} icon={<IconFlag />} />
            <Tag size="sm" colorScheme="blue">{vulnerability.visibility}</Tag> <Tags values={vulnerability.tags} />

            <Tabs>
                <TabList>
                    <Tab>Description</Tab>
                    <Tab>Remediation</Tab>
                    <Tab>Notes</Tab>
                    <Tab>Attachments</Tab>
                </TabList>
                <TabPanels>
                    <TabPanel>
                        <VulnerabilityDescriptionPanel vulnerability={vulnerability} />
                    </TabPanel>
                    <TabPanel>
                        <VulnerabilityRemediationPanel vulnerability={vulnerability} />
                    </TabPanel>
                    <TabPanel>
                        <VulnerabilitiesNotesTab vulnerability={vulnerability} />
                    </TabPanel>
                    <TabPanel>
                        <AttachmentsDropzone parentType={parentType} parentId={parentId} onUploadFinished={reloadAttachments} />

                        <h4><IconDocument />Attachment list</h4>
                        <AttachmentsTable attachments={attachments} reloadAttachments={reloadAttachments} />
                    </TabPanel>
                </TabPanels>
            </Tabs>
        </article>

    </div >
}
Example #18
Source File: ClaimsPage.js    From DAOInsure with MIT License 4 votes vote down vote up
function ClaimsPage() {
	const { textileClient } = useContext(AppContext);
	const [openClaims, setOpenClaims] = useState();
	const [isLoadingOpenClaims, setIsLoadingOpenClaims] = useState(true);

	const web3Context = useContext(Web3Context);
	const {
		fetchAllProposals,
		allProposalsArray,
		openProposalsArray,
		acceptedProposalsArray,
		rejectedProposalsArray,
		daoMemberCount,
		setDaoMemberCount,
	} = web3Context;

	useEffect(() => {
		async function init() {
			console.log(textileClient);
			if (textileClient) {
				// textile database querying the thread using threadId and collection where claims are present.
				let openClaims = await queryThread(
					textileClient,
					"bafkyspsyykcninhqn4ht6d6jeqmzq4cepy344akmkhjk75dmw36wq4q",
					"claimsData",
					{}
				);
				console.log(openClaims);
				setOpenClaims(openClaims);
				setIsLoadingOpenClaims(false);
			}
		}
		init();
	}, [textileClient]);

	useEffect(() => {
		fetchAllProposals();
		console.log(openProposalsArray);
	}, []);

	return (
		<Grid
			height='calc(100vh - 64px)'
			px='250px'
			py='20px'
			width='100%'
			templateColumns='3fr 1fr'
			gridGap={5}
			alignItems='flex-start'>
			<Tabs variant='soft-rounded' colorScheme='whatsapp'>
				<TabList justifyContent='space-between'>
					<HStack>
						<Tab>
							Open Claims{" "}
							<GreenTag>{openProposalsArray.length}</GreenTag>
						</Tab>
						<Tab variant='solid'>
							Accepted Claims{" "}
							<GreenTag>{acceptedProposalsArray.length}</GreenTag>
						</Tab>
						<Tab variant='solid'>
							Rejected Claims{" "}
							<GreenTag>{rejectedProposalsArray.length}</GreenTag>
						</Tab>
					</HStack>
					<Link to='/makeClaim'>
						<Button colorScheme='whatsapp'>+ Make a Claim</Button>
					</Link>
				</TabList>
				<TabPanels>
					<TabPanel py={4} px={0}>
						<ClaimsList claims={openProposalsArray} />
					</TabPanel>
					<TabPanel py={4} px={0}>
						<ClaimsList claims={acceptedProposalsArray} />
					</TabPanel>
					<TabPanel py={4} px={0}>
						<ClaimsList claims={rejectedProposalsArray} />
					</TabPanel>
				</TabPanels>
			</Tabs>
			<Stats
				claims={
					acceptedProposalsArray.length +
					rejectedProposalsArray.length
				}
				daoMemberCount={daoMemberCount}
			/>
		</Grid>
	);
}