@chakra-ui/react#TabList JavaScript Examples
The following examples show how to use
@chakra-ui/react#TabList.
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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: Details.js From web-client with Apache License 2.0 | 4 votes |
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> </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 #9
Source File: Details.js From web-client with Apache License 2.0 | 4 votes |
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 #10
Source File: ChallengeDetailView.jsx From scaffold-directory with MIT License | 4 votes |
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 #11
Source File: Details.js From web-client with Apache License 2.0 | 4 votes |
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 #12
Source File: ChallengeReviewRow.jsx From scaffold-directory with MIT License | 4 votes |
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 #13
Source File: wallets.js From idena-web with MIT License | 4 votes |
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 #14
Source File: get-invitation.js From idena-web with MIT License | 4 votes |
export default function GetInvitation() {
const router = useRouter()
const {t} = useTranslation()
const [nickname, setNickname] = useState('')
const failToast = useFailToast()
const successToast = useSuccessToast()
const [code, setCode] = useState()
const [isWaiting, setIsWaiting] = useState(false)
const size = useBreakpointValue(['lg', 'md'])
const invitationCodeRef = useRef()
const {scrollTo: scrollToCode} = useScroll(invitationCodeRef)
const getCode = async () => {
setIsWaiting(true)
const name = nickname.startsWith('@') ? nickname.substring(1) : nickname
try {
const {invitation} = await getInvitationCode(name, cookie.get('refId'))
setCode(invitation)
successToast(t('Your invitation code has been generated successfully!'))
scrollToCode()
} catch (e) {
failToast(e.message)
} finally {
setIsWaiting(false)
}
}
return (
<Layout showHamburger={false}>
<Page>
<Flex
align="center"
alignSelf="stretch"
justify={['center', 'space-between']}
mb={[8, 2]}
w={['100%', null]}
>
<PageTitle
fontSize={['base', 'xl']}
fontWeight={['bold', 500]}
mb={0}
>
{t('How to get an invitation')}
</PageTitle>
<CloseButton
color={['blue.500', 'inherit']}
size="lg"
position={['absolute', 'inherit']}
right={2}
onClick={() => router.push('/home')}
/>
</Flex>
<Flex
direction="column"
maxW="480px"
w={['100%', null]}
fontSize={['mdx', 'md']}
>
<Text>
{t(
'To minimize the probability of a Sybil attack, the pace of network growth is restricted: Idena network participation is invitation-based. New invitations can be sent out only by validated users. The number of invitations is limited and increases as the network grows.',
{nsSeparator: '|'}
)}
</Text>
<Text mt={2}>
{t(
'Please choose the platform where you have the most active account:',
{nsSeparator: '|'}
)}
</Text>
<Tabs variant="unstyled" mt={8}>
<TabList bg={['gray.50', 'white']} p={[1, 0]} borderRadius="md">
<GetInvitationTab
iconSelected={<TelegramInvertedIcon />}
icon={<TelegramIcon />}
title="Telegram"
/>
<GetInvitationTab
iconSelected={<DiscordInvertedIcon />}
icon={<DiscordIcon />}
title="Discord"
/>
<GetInvitationTab
iconSelected={<TwitterIcon />}
icon={<TwitterIcon />}
title="Twitter"
/>
<GetInvitationTab
iconSelected={<RedditInvertedIcon />}
icon={<RedditIcon />}
title="Reddit"
/>
</TabList>
<TabPanels>
<GetInvitationTabPanel>
<GetInvitationTabTitle>Telegram</GetInvitationTabTitle>
<Text>
<Trans t={t} i18nKey="joinIdenaTelegram">
Join the official{' '}
<Link
href="https://t.me/IdenaNetworkPublic"
target="_blank"
color="blue.500"
>
Idena Telegram group
</Link>{' '}
and request an invitation code from the community.
</Trans>
</Text>
</GetInvitationTabPanel>
<GetInvitationTabPanel>
<GetInvitationTabTitle>Discord</GetInvitationTabTitle>
<Text>
<Trans t={t} i18nKey="joinIdenaDiscord">
Join{' '}
<Link
href="https://discord.gg/8BusRj7"
target="_blank"
color="blue.500"
>
Idena Community Discord
</Link>{' '}
and request an invitation code from the community in
#invite-requests channel.
</Trans>
</Text>
</GetInvitationTabPanel>
<GetInvitationTabPanel>
<GetInvitationTabTitle>Twitter</GetInvitationTabTitle>
<OrderedList spacing={2}>
<ListItem>
{t('Follow')}{' '}
<Link
href="https://twitter.com/IdenaNetwork"
target="_blank"
color="blue.500"
>
@IdenaNetwork
</Link>{' '}
</ListItem>
<ListItem>
<Stack spacing={4}>
<Text>
<Trans t={t} i18nKey="joinIdenaTwitterSendTweet">
<Link
target="_blank"
color="blue.500"
rel="noreferrer"
href="https://twitter.com/intent/tweet?text=I%20want%20to%20join%20%40IdenaNetwork%20to%20become%20a%20validator%20of%20the%20first%20Proof-of-Person%20blockchain%20%23IdenaInvite%0A%0Ahttps://www.idena.io"
>
Send a tweet
</Link>{' '}
with a hashtag #IdenaInvite from your account. To get
an invite, your account should be older than 1 year or
older than two months and have at least 50 followers.
The tweet should say:
</Trans>
</Text>
<Flex mt={4} p={[7, 10]} borderRadius="md" bg="gray.50">
<Flex direction={['column', 'row']}>
<Stack>
<Text color="gray.500">
I want to join @IdenaNetwork to become a validator
of the first Proof-of-Person blockchain
#IdenaInvite
</Text>
<Text>
<Link
href="https://www.idena.io"
target="_blank"
color="blue.500"
>
https://www.idena.io
</Link>
</Text>
</Stack>
<GetInvitationCopyButton
ml={[0, 10]}
value={
'I want to join @IdenaNetwork to become a validator of the first Proof-of-Person blockchain #IdenaInvite\n' +
'\n' +
'https://www.idena.io'
}
/>
</Flex>
</Flex>
</Stack>
</ListItem>
<ListItem>
<Stack spacing={4} pt={2}>
<Text>
<Trans t={t} i18nKey="joinIdenaTwitterGetCode">
Enter your twitter name and click{' '}
<i>Get an invitation code</i> button. The code will be
shown automatically.
</Trans>
</Text>
<Stack>
<Text color="gray.500" fontWeight="500">
{t('Your nickname')}
</Text>
<GetInvitationTwitterInput
value={nickname}
onChange={value => setNickname(value)}
/>
</Stack>
{code ? (
<Flex
boxShadow="0 3px 12px 0 rgba(83, 86, 92, 0.1), 0 2px 3px 0 rgba(83, 86, 92, 0.2)"
px={10}
py={8}
borderRadius="lg"
position="relative"
>
<Flex
direction={['column', 'row']}
justifyContent="space-between"
w="100%"
>
<Stack spacing={0}>
<Text color="muted">{t('Invitation code')}</Text>
<Text
color="gray.500"
fontWeight={500}
wordBreak="break-all"
>
{code}
</Text>
</Stack>
<GetInvitationCopyButton
value={code}
ml={[0, 10]}
/>
</Flex>
</Flex>
) : (
<Flex>
<PrimaryButton
ml="auto"
onClick={getCode}
isLoading={isWaiting}
loadingText=""
w={['100%', 'auto']}
size={size}
>
{t('Get an invitation code')}
</PrimaryButton>
</Flex>
)}
<Box ref={invitationCodeRef}></Box>
</Stack>
</ListItem>
</OrderedList>
</GetInvitationTabPanel>
<GetInvitationTabPanel>
<GetInvitationTabTitle>Reddit</GetInvitationTabTitle>
<Text color="gray.500">
<Trans t={t} i18nKey="joinIdenaReddit">
Join{' '}
<Link
href="https://www.reddit.com/r/Idena/"
target="_blank"
color="blue.500"
>
Idena subreddit
</Link>{' '}
and request an invitation code from the community.
</Trans>
</Text>
</GetInvitationTabPanel>
</TabPanels>
</Tabs>
</Flex>
</Page>
</Layout>
)
}
Example #15
Source File: Details.js From web-client with Apache License 2.0 | 4 votes |
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
<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 |
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 |
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
<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> {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 |
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>
);
}