@chakra-ui/react#useDisclosure JavaScript Examples
The following examples show how to use
@chakra-ui/react#useDisclosure.
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: layout.js From idena-web with MIT License | 6 votes |
export default function Layout({
showHamburger = true,
didConnectIdenaBot,
...props
}) {
const {auth} = useAuthState()
const sidebarDisclosure = useDisclosure()
const ads = useRotatingAds()
const hasRotatingAds = ads?.length > 0
const hamburgerTop = useHamburgerTop({didConnectIdenaBot})
return (
<LayoutContainer>
{auth ? (
<>
{showHamburger && (
<Hamburger onClick={sidebarDisclosure.onOpen} top={hamburgerTop} />
)}
<Sidebar {...sidebarDisclosure} />
<NormalApp hasRotatingAds={hasRotatingAds} {...props} />
</>
) : (
<Auth />
)}
</LayoutContainer>
)
}
Example #2
Source File: Modal.js From interspace.chat with GNU General Public License v3.0 | 6 votes |
MFModal = (children) => {
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<>
<Button onClick={onOpen} colorScheme="pink">Delegate application</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalCloseButton />
<ModalBody>{children}</ModalBody>
</ModalContent>
</Modal>
</>
);
}
Example #3
Source File: NotesTab.js From web-client with Apache License 2.0 | 6 votes |
ProjectNotesTab = ({ project }) => {
const [notes, reloadNotes] = useFetch(`/notes?parentType=project&parentId=${project.id}`)
const deleteNoteById = useDelete('/notes/', reloadNotes)
const { isOpen, onOpen, onClose } = useDisclosure();
const onDeleteButtonClick = (ev, note) => {
ev.preventDefault();
deleteNoteById(note.id);
}
const onNoteFormSaved = () => {
reloadNotes();
onClose();
}
if (!notes) {
return <Loading />
}
return (
<section>
<h4>
<IconDocument />Project notes
<RestrictedComponent roles={['administrator', 'superuser', 'user']}>
<NoteModalDialog parentType="project" parent={project} isOpen={isOpen} onClose={onNoteFormSaved} onCancel={onClose} />
<CreateButton onClick={onOpen}>Add note...</CreateButton>
</RestrictedComponent>
</h4>
<NotesTable notes={notes} onDeleteButtonClick={onDeleteButtonClick} />
</section>
)
}
Example #4
Source File: offers.js From idena-web with MIT License | 5 votes |
export default function AdOfferList() {
const {t} = useTranslation()
const queryClient = useQueryClient()
const {data: burntCoins, status: burntCoinsStatus} = useApprovedBurntCoins()
const isFetched = burntCoinsStatus === 'success'
const isEmpty = isFetched && burntCoins.length === 0
const [selectedAd, setSelectedAd] = React.useState({})
const burnDisclosure = useDisclosure()
const {
onOpen: onOpenBurnDisclosure,
onClose: onCloseBurnDisclosure,
} = burnDisclosure
const handlePreviewBurn = React.useCallback(
ad => {
setSelectedAd(ad)
onOpenBurnDisclosure()
},
[onOpenBurnDisclosure]
)
const handleBurn = React.useCallback(() => {
onCloseBurnDisclosure()
queryClient.invalidateQueries(['bcn_burntCoins', []])
}, [onCloseBurnDisclosure, queryClient])
return (
<Layout skipBanner>
<Page>
<PageHeader>
<PageTitle mb={4}>{t('All offers')}</PageTitle>
<PageCloseButton href="/adn/list" />
</PageHeader>
<Table>
<Thead>
<Tr>
<RoundedTh isLeft>{t('Banner/author')}</RoundedTh>
<RoundedTh>{t('Website')}</RoundedTh>
<RoundedTh>{t('Target')}</RoundedTh>
<RoundedTh>{t('Burn')}</RoundedTh>
<RoundedTh isRight />
</Tr>
</Thead>
<Tbody>
{isFetched &&
burntCoins.map(burn => (
<AdOfferListItem
key={burn.key}
burn={burn}
onBurn={handlePreviewBurn}
/>
))}
</Tbody>
</Table>
{isEmpty && (
<Center color="muted" mt="4" w="full">
{t('No active offers')}
</Center>
)}
<BurnDrawer ad={selectedAd} onBurn={handleBurn} {...burnDisclosure} />
</Page>
</Layout>
)
}
Example #5
Source File: Modal.js From blobs.app with MIT License | 5 votes |
Modal = ({ title, src, children, actions, size = '2xl' }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<>
<Box onClick={onOpen}>{src}</Box>
<ChakModal
isOpen={isOpen}
onClose={onClose}
isCentered
motionPreset="scale"
size={size}
autoFocus={false}
returnFocusOnClose={false}
>
<ModalOverlay background="rgba(78,86,107,0.71)" />
<ModalContent>
<ModalHeader px={{ base: '2', lg: '10' }}>
<Flex align="center">
<Flex
direction={{ base: 'column', lg: 'row' }}
align="center"
justify={{ base: 'center', lg: 'space-between' }}
flex="1"
>
<Heading fontSize="xl" variant="main">
{title}
</Heading>
<Box>{actions}</Box>
</Flex>
<Button
onClick={onClose}
variant="subtle"
pos="relative"
right={{ base: '0', lg: '-20px' }}
>
<CloseIcon />
</Button>
</Flex>
</ModalHeader>
<Divider />
<ModalBody py="5" px="10">
{typeof children === 'function' ? children() : children}
</ModalBody>
</ModalContent>
</ChakModal>
</>
);
}
Example #6
Source File: components.js From idena-web with MIT License | 5 votes |
export function ValidationReportCategoryLabel({
isFirst,
label,
description,
info,
...props
}) {
const disclosure = useDisclosure()
const {t} = useTranslation()
return (
<Box fontWeight={500} {...props}>
<Text
fontSize={['base', 'md']}
fontWeight={500}
textAlign={[isFirst ? 'left' : 'right', 'left']}
>
{label}
{info && (
<>
<InfoIcon
color="blue.500"
boxSize={4}
ml={2}
onClick={() => disclosure.onOpen()}
display={['initial', 'none']}
/>
<Dialog title={label} {...disclosure}>
<DialogBody fontSize="mobile">{info}</DialogBody>
<DialogFooter mb={2}>
<Flex justifyContent="center" w="full">
<Button
variant="link"
fontSize="mobile"
color="blue.500"
onClick={() => disclosure.onClose()}
>
{t('Close')}
</Button>
</Flex>
</DialogFooter>
</Dialog>
</>
)}
</Text>
<SmallText textAlign={[isFirst ? 'left' : 'right', 'left']}>
{description}
</SmallText>
</Box>
)
}
Example #7
Source File: ChallengeStatusTag.jsx From scaffold-directory with MIT License | 5 votes |
ChallengeStatusTag = ({ status, comment, autograding }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
let colorScheme;
let label;
switch (status) {
case CHALLENGE_SUBMISSION_STATUS.ACCEPTED: {
colorScheme = "green";
label = "Accepted";
break;
}
case CHALLENGE_SUBMISSION_STATUS.REJECTED: {
colorScheme = "red";
label = "Rejected";
break;
}
case CHALLENGE_SUBMISSION_STATUS.SUBMITTED: {
label = "Submitted";
break;
}
default:
// do nothing
}
return (
<>
<Flex align="center">
<Box>
<Badge borderRadius="xl" colorScheme={colorScheme} textTransform="none" py={0.5} px={2.5}>
{label}
</Badge>
</Box>
<Spacer />
{status !== CHALLENGE_SUBMISSION_STATUS.SUBMITTED && comment && (
<Tooltip label="See comment">
<Button variant="ghost" onClick={onOpen} p={0} ml={1}>
<QuestionOutlineIcon ml="2px" />
</Button>
</Tooltip>
)}
</Flex>
<Modal isOpen={isOpen} onClose={onClose} size="xl">
<ModalOverlay />
<ModalContent maxW="56rem">
<ModalHeader>Review feedback</ModalHeader>
<ModalCloseButton />
<ModalBody p={6} overflowX="auto">
{autograding ? (
<Box className="autograding-feedback">
<style>
{`
.autograding-feedback a { text-decoration: underline; color: var(--chakra-colors-teal-500) }
`}
</style>
<chakra.pre fontSize={14} whiteSpace="pre-wrap" dangerouslySetInnerHTML={{ __html: comment }} />
</Box>
) : (
<ReactMarkdown components={ChakraUIRenderer(chakraMarkdownComponents)} remarkPlugins={[remarkBreaks]}>
{comment}
</ReactMarkdown>
)}
</ModalBody>
</ModalContent>
</Modal>
</>
);
}
Example #8
Source File: new.js From idena-web with MIT License | 5 votes |
export default function NewAdPage() {
const {t} = useTranslation()
const router = useRouter()
const coinbase = useCoinbase()
const adFormRef = React.useRef()
const previewAdRef = React.useRef()
const previewDisclosure = useDisclosure()
return (
<Layout>
<Page px={0} py={0} overflow="hidden">
<Box flex={1} w="full" px={20} py={6} overflowY="auto">
<PageHeader>
<PageTitle mb={0}>{t('New ad')}</PageTitle>
<PageCloseButton href="/adn/list" />
</PageHeader>
<AdForm
ref={adFormRef}
id="adForm"
onSubmit={async ad => {
await db.table('ads').add({
...ad,
id: nanoid(),
status: AdStatus.Draft,
author: coinbase,
})
router.push('/adn/list?from=new&save=true')
}}
/>
</Box>
<PageFooter>
<SecondaryButton
onClick={() => {
const ad = Object.fromEntries(
new FormData(adFormRef.current).entries()
)
previewAdRef.current = {
...ad,
author: coinbase,
thumb: ad.thumb && URL.createObjectURL(ad.thumb),
media: ad.media && URL.createObjectURL(ad.media),
}
previewDisclosure.onOpen()
}}
>
<HStack>
<TriangleUpIcon boxSize="3" transform="rotate(90deg)" />
<Text>{t('Show preview')}</Text>
</HStack>
</SecondaryButton>
<PrimaryButton form="adForm" type="submit">
{t('Save')}
</PrimaryButton>
</PageFooter>
</Page>
<AdPreview ad={previewAdRef.current} {...previewDisclosure} />
</Layout>
)
}
Example #9
Source File: List.js From web-client with Apache License 2.0 | 5 votes |
VulnerabilityCategoriesPage = () => {
const [categories, fetchParentCategories] = useFetch('/vulnerabilities/categories?parentsOnly=0')
const destroy = useDelete('/vulnerabilities/categories/', fetchParentCategories);
const [editCategory, setEditCategory] = useState({});
const { isOpen: isAddCategoryDialogOpen, onOpen: openAddCategoryDialog, onClose: closeAddCategoryDialog } = useDisclosure();
const { isOpen: isEditCategoryDialogOpen, onOpen: openEditCategoryDialog, onClose: closeEditCategoryDialog } = useDisclosure();
const onCategoryDialogClosed = () => {
fetchParentCategories();
closeAddCategoryDialog();
closeEditCategoryDialog();
}
const onAddClick = ev => {
ev.preventDefault();
openAddCategoryDialog();
}
const onEditClick = (ev, ccategory) => {
ev.preventDefault();
setEditCategory(ccategory);
openEditCategoryDialog();
}
const onDeleteClick = (ev, templateId) => {
ev.stopPropagation();
destroy(templateId);
}
return <>
<PageTitle value="Vulnerability categories" />
<div className='heading'>
<Breadcrumb>
<Link to="/vulnerabilities">Vulnerabilities</Link>
</Breadcrumb>
<VulnerabilityCategoryAddModalDialog isOpen={isAddCategoryDialogOpen} onClose={onCategoryDialogClosed} onCancel={closeAddCategoryDialog} />
{isEditCategoryDialogOpen && <VulnerabilityCategoryEditModalDialog category={editCategory} isOpen={isEditCategoryDialogOpen} onClose={onCategoryDialogClosed} onCancel={closeEditCategoryDialog} />}
<CreateButton onClick={onAddClick}>Add vulnerability category...</CreateButton>
</div>
<Title title='Vulnerability categories' icon={<IconDocumentDuplicate />} />
{!categories ? <Loading /> :
<Table>
<Thead>
<Tr>
<Th style={{ width: '190px' }}>Name</Th>
<Th>Parent category</Th>
<Th colSpan={2}>Description</Th>
</Tr>
</Thead>
<Tbody>
{categories.length === 0 ?
<Tr><Td colSpan={3}><NoResults /></Td></Tr>
:
categories.map(category =>
<Tr key={category.id}>
<Td><strong>{category.name}</strong></Td>
<Td>{category.parent_name ?? '-'}</Td>
<Td>{category.description}</Td>
<Td textAlign="right">
<LinkButton href="#" onClick={ev => onEditClick(ev, category)}>Edit</LinkButton>
<DeleteIconButton onClick={ev => onDeleteClick(ev, category.id)} />
</Td>
</Tr>
)
}
</Tbody>
</Table>
}
</>
}
Example #10
Source File: edit.js From idena-web with MIT License | 5 votes |
export default function EditAdPage() {
const {t} = useTranslation()
const router = useRouter()
const {data: ad} = usePersistedAd(router.query.id)
const coinbase = useCoinbase()
const adFormRef = React.useRef()
const previewAdRef = React.useRef()
const previewDisclosure = useDisclosure()
return (
<Layout showHamburger={false}>
<Page px={0} py={0} overflow="hidden">
<Box flex={1} w="full" px={20} py={6} overflowY="auto">
<PageHeader>
<PageTitle mb={0}>{t('Edit ad')}</PageTitle>
<PageCloseButton href="/adn/list" />
</PageHeader>
<AdForm
ref={adFormRef}
id="adForm"
ad={ad}
onSubmit={async nextAd => {
await db.table('ads').update(ad.id, nextAd)
router.push('/adn/list')
}}
/>
</Box>
<PageFooter>
<SecondaryButton
onClick={async () => {
const currentAd = Object.fromEntries(
new FormData(adFormRef.current).entries()
)
previewAdRef.current = {
...ad,
...currentAd,
author: ad.author ?? coinbase,
thumb: isValidImage(currentAd.thumb)
? URL.createObjectURL(currentAd.thumb)
: ad.thumb,
media: isValidImage(currentAd.media)
? URL.createObjectURL(currentAd.media)
: ad.media,
}
previewDisclosure.onOpen()
}}
>
<HStack>
<TriangleUpIcon boxSize="3" transform="rotate(90deg)" />
<Text>{t('Show preview')}</Text>
</HStack>
</SecondaryButton>
<PrimaryButton form="adForm" type="submit">
{t('Save')}
</PrimaryButton>
</PageFooter>
</Page>
<AdPreview ad={previewAdRef.current} {...previewDisclosure} />
</Layout>
)
}
Example #11
Source File: Toolbar.js From sided.news.web with MIT License | 5 votes |
export default function Toolbar() {
const { isOpen, onOpen, onClose } = useDisclosure();
const install = usePWAInstall();
return (
<div className={styles.title}>
<>
<Modal size="3xl" isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader style={{ textAlign: "center" }}>
Media Bias in Sri Lanka
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<p className={styles.para}>
Presenting data analysed by the Ministry of Mass Media on the
news reporting of eight television stations, during presidention
election 2019, Sri Lanka
</p>
<img src="/election.jpg" />
</ModalBody>
<ModalFooter>
<Button
mr={3}
variant="outline"
onClick={(e) => {
e.preventDefault();
window.location.href =
"https://economynext.com/worst-media-behaviour-in-election-history-election-commissioner-47087/";
}}
>
Source
</Button>
<Button colorScheme="blue" onClick={onClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
<div className={styles.wrapper}>
<div className={styles.hide_button}>
<Button colorScheme="teal">Media Bias in Sri Lanka</Button>
{/* <Button ml={3} onClick={onOpen} colorScheme="teal">
Download
</Button> */}
</div>
<span>
<span className={styles.fliph}>s</span>ided.
<span className={styles.news_span}>news</span>
</span>
<div>
<Button onClick={onOpen} colorScheme="teal" leftIcon={<InfoIcon />}>
Media Bias in Sri Lanka
</Button>
{/* <Button
ml={3}
onClick={install}
colorScheme="gray"
leftIcon={<GetAppIcon />}
>
App
</Button> */}
</div>
</div>
</div>
);
}
Example #12
Source File: about.js From handsign-tensorflow with BSD 2-Clause "Simplified" License | 5 votes |
export default function About() {
const { isOpen, onOpen, onClose } = useDisclosure()
return (
<div>
<Button onClick={onOpen} colorScheme="orange">
Learn More
</Button>
<Modal onClose={onClose} isOpen={isOpen} isCentered>
<ModalOverlay />
<ModalContent>
<ModalHeader>American Sign Language (ASL)</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text fontSize="sm">
American Sign Language (ASL) is a visual language that serves as
the predominant sign language of Deaf communities in the United
States and most of Canada.<br></br>
Here's the list of ASL hand gestures for alphabet.
</Text>
<Image src={handImages} />
<Text fontSize="sm">
This sign language illustration is created by{" "}
<Link
href="https://thenounproject.com/pelodrome/"
isExternal
color="orange.300"
>
Pelin Kahraman
</Link>
</Text>
</ModalBody>
<ModalFooter>
<Button onClick={onClose}>Close</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
)
}
Example #13
Source File: Todos.jsx From fastapi-react with MIT License | 5 votes |
function UpdateTodo({item, id}) {
const {isOpen, onOpen, onClose} = useDisclosure()
const [todo, setTodo] = useState(item)
const {fetchTodos} = React.useContext(TodosContext)
const updateTodo = async () => {
await fetch(`http://localhost:8000/todo/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ item: todo })
})
onClose()
await fetchTodos()
}
return (
<>
<Button h="1.5rem" size="sm" onClick={onOpen}>Update Todo</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay/>
<ModalContent>
<ModalHeader>Update Todo</ModalHeader>
<ModalCloseButton/>
<ModalBody>
<InputGroup size="md">
<Input
pr="4.5rem"
type="text"
placeholder="Add a todo item"
aria-label="Add a todo item"
value={todo}
onChange={e => setTodo(e.target.value)}
/>
</InputGroup>
</ModalBody>
<ModalFooter>
<Button h="1.5rem" size="sm" onClick={updateTodo}>Update Todo</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
)
}
Example #14
Source File: index.js From idena-web with MIT License | 5 votes |
function ValidationSession({
privateKey,
coinbase,
epoch,
validationStart,
shortSessionDuration,
longSessionDuration,
}) {
const router = useRouter()
const {i18n} = useTranslation()
const {
isOpen: isExceededTooltipOpen,
onOpen: onOpenExceededTooltip,
onClose: onCloseExceededTooltip,
} = useDisclosure()
const validationMachine = useMemo(
() =>
createValidationMachine({
privateKey,
coinbase,
epoch,
validationStart,
shortSessionDuration,
longSessionDuration,
locale: i18n.language || 'en',
}),
[
coinbase,
epoch,
i18n.language,
longSessionDuration,
privateKey,
shortSessionDuration,
validationStart,
]
)
const [state, send] = useMachine(validationMachine, {
actions: {
onExceededReports: () => {
onOpenExceededTooltip()
setTimeout(onCloseExceededTooltip, 3000)
},
onValidationSucceeded: () => {
router.push('/home')
},
},
state: loadValidationState(),
logger: async data => writeValidationLog(epoch, transformLog(data)),
})
useEffect(() => {
persistValidationState(state)
}, [state])
return (
<ValidationScreen
state={state}
send={send}
validationStart={validationStart}
shortSessionDuration={shortSessionDuration}
longSessionDuration={longSessionDuration}
isExceededTooltipOpen={isExceededTooltipOpen}
/>
)
}
Example #15
Source File: Header.js From DAOInsure with MIT License | 5 votes |
function Header(props) {
const { isOpen, onOpen, onClose } = useDisclosure();
const web3Context = useContext(Web3Context);
const { connectWallet, signerAddress, checkIfMemberExists } = web3Context;
function connect() {
connectWallet().then(async (data) => {
console.log(data.provider.networkVersion);
if (data.provider.networkVersion == "80001") {
checkIfMemberExists(data).then((value) => {
if (value === true) {
props.setIsMember(true);
}
});
} else {
onOpen();
}
});
}
return (
<HStack
backgroundColor='white'
zIndex='1'
position='fixed'
width='100vw'
boxShadow='base'
px='250px'
py={3}>
<Modal
isOpen={isOpen}
onClose={onClose}
closeOnOverlayClick={false}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Invalid Network</ModalHeader>
<ModalBody>Please connect to Mumbai Testnet.</ModalBody>
</ModalContent>
</Modal>
<Link to='/'>
<Image height='35px' src='../assets/DAOInsure.png' />
</Link>
<Spacer />
<Link to='/profile'>
<Button colorScheme='whatsapp'>Profile</Button>
</Link>
<Link to='/activity'>
<Button colorScheme='whatsapp'>Activity</Button>
</Link>
{signerAddress !== "" && signerAddress !== undefined ? (
<Button colorScheme='whatsapp' variant='solid'>
{`${signerAddress.substr(0, 6)}...${signerAddress.substr(
-6
)}`}
</Button>
) : (
<Button
onClick={connect}
colorScheme='whatsapp'
variant='solid'>
Connect Wallet
</Button>
)}
</HStack>
);
}
Example #16
Source File: layout.js From codeursenseine.com with MIT License | 5 votes |
Layout = ({ children, theme = "ces" }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<ChakraProvider theme={themes[theme]}>
<Flex
minH="100vh"
maxW="100vw"
background="white"
color="brand.900"
style={{
minHeight: "calc(var(--vh, 1vh) * 100)",
}}
>
<Nav
isOpen={isOpen}
maxW="100vw"
w={{ base: "100%", [navBreakpoint]: navDesktopWidth }}
breakpoint={navBreakpoint}
onNavClose={onClose}
/>
<NavTopbar maxW="100vw" h={navTopbarHeight} onNavOpen={onOpen} />
<Box
as="main"
ml={{ [navBreakpoint]: navDesktopWidth }}
mt={{ base: navTopbarHeight, [navBreakpoint]: "0" }}
width="100%"
position="relative"
zIndex="1"
>
<Box
maxWidth="60rem"
width="100%"
overflow="auto"
marginX="auto"
p={6}
pb={16}
>
<PageHeader />
<Mdx>{children}</Mdx>
</Box>
</Box>
</Flex>
</ChakraProvider>
);
}
Example #17
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 #18
Source File: components.js From idena-web with MIT License | 4 votes |
export function CertificateCard({
title,
description,
type,
trustLevel,
scheduleText,
certificateColor,
...props
}) {
const {t} = useTranslation()
const [waiting, setWaiting] = useState(false)
const size = useBreakpointValue(['lg', 'md'])
const {isOpen, onOpen, onClose} = useDisclosure()
const cancelRef = useRef()
const failToast = useFailToast()
const testValidationState = useTestValidationState()
const {scheduleValidation, cancelValidation} = useTestValidationDispatch()
const epochState = useEpoch()
const {
isOpen: isOpenReSchedule,
onOpen: onOpenReSchedule,
onClose: onCloseReSchedule,
} = useDisclosure()
const {
validations: {[type]: cardValue},
current,
} = testValidationState
const isStarted = type === current?.type
const schedule = async () => {
try {
setWaiting(true)
if (current) {
return failToast(
t(
'Can not schedule the training validation. Another validation is already requested.'
)
)
}
if (!canScheduleValidation(type, epochState?.nextValidation)) {
return failToast(
t(
'Can not schedule the training validation because it overlaps with the real validation ceremony.'
)
)
}
await scheduleValidation(type)
} catch (e) {
console.error(e)
} finally {
setWaiting(false)
}
}
const onScheduleClick = () => {
if (cardValue.actionType === CertificateActionType.Passed) {
onOpenReSchedule()
} else {
schedule()
}
}
return (
<Flex
alignSelf="stretch"
direction="column"
shadow="0 3px 12px 0 rgba(83, 86, 92, 0.1), 0 2px 3px 0 rgba(83, 86, 92, 0.2)"
p={['28px', 10]}
borderRadius="lg"
borderTop="4px solid"
borderTopColor={certificateColor}
{...props}
>
<Flex
justify={['space-between', 'flex-start']}
alignItems="center"
mb={2}
>
<CertificateStarIcon
order={[2, 1]}
boxSize={[6, 4]}
color={certificateColor}
/>
<Heading
order={[1, 2]}
as="h2"
fontSize="lg"
fontWeight={500}
verticalAlign="center"
ml={[0, 1]}
>
{title}
</Heading>
</Flex>
<Flex>
<Text color="muted">{description}</Text>
</Flex>
<Flex
direction={['column', 'row']}
bg="gray.50"
px={6}
py={['30px', 5]}
mt={6}
rounded="lg"
>
<CertificateCardPanelItem title={t('Schedule')} mb={[5, 0]}>
{isStarted
? dayjs(current.startTime).format('D MMM HH:mm')
: scheduleText}
</CertificateCardPanelItem>
{isStarted && (
<CertificateCardPanelItem title={t('Time left')}>
<Countdown validationTime={current.startTime} />
</CertificateCardPanelItem>
)}
<CertificateCardPanelItem title={t('Trust level')}>
{trustLevel}
</CertificateCardPanelItem>
</Flex>
{cardValue.actionType === CertificateActionType.Passed && (
<AlertBox>
<Flex align="center">
<RightIcon boxSize={[5, 4]} color="green.500" mr={2} />
<Text fontWeight={500}>{t('Passed successfully')}</Text>
</Flex>
<Box>
<TextLink
href="/try/details/[id]"
as={`/try/details/${cardValue.id}`}
color="green.500"
>
{t('Details')}
</TextLink>
</Box>
</AlertBox>
)}
{cardValue.actionType === CertificateActionType.Failed && (
<AlertBox borderColor="red.050" bg="red.010">
<Flex align="center">
<WarningIcon boxSize={[5, 4]} color="red.500" mr={2} />
<Text fontWeight={500}>{t('Failed. Please try again')}</Text>
</Flex>
<Box>
<TextLink
href="/try/details/[id]"
as={`/try/details/${cardValue.id}`}
color="red.500"
>
{t('Details')}
</TextLink>
</Box>
</AlertBox>
)}
{cardValue.actionType === CertificateActionType.Requested && (
<AlertBox borderColor="gray.200" bg="gray.50">
<Flex align="center">
<TimerIcon boxSize={4} color="blue.500" mr={2} />
<Text fontWeight={500}>{t('Test was requested...')}</Text>
</Flex>
<TextLink
href="#"
onClick={e => {
e.preventDefault()
onOpen()
}}
>
{t('Cancel')}
</TextLink>
</AlertBox>
)}
<Flex mt={6}>
<Flex
direction={['column', 'row']}
ml={[0, 'auto']}
w={['100%', 'auto']}
alignItems="center"
>
{cardValue.actionType === CertificateActionType.Passed && (
<>
<TextLink
display={['none', 'block']}
href="/certificate/[id]"
as={`/certificate/${cardValue.id}`}
fontWeight={500}
mr={4}
target="_blank"
>
<CertificateIcon boxSize={5} mr={1} />
{t('Show certificate')}
</TextLink>
<Divider
display={['none', 'block']}
borderColor="gray.100"
orientation="vertical"
mr={4}
/>
</>
)}
<PrimaryButton
size={size}
w={['100%', 'auto']}
isDisabled={isStarted || !epochState}
onClick={() => onScheduleClick()}
isLoading={waiting}
loadingText={t('Scheduling...')}
>
{t('Schedule')}
</PrimaryButton>
{cardValue.actionType === CertificateActionType.Passed && (
<TextLink
display={['block', 'none']}
href="/certificate/[id]"
as={`/certificate/${cardValue.id}`}
fontSize="mobile"
fontWeight={500}
mt={5}
target="_blank"
>
{t('Show certificate')}
</TextLink>
)}
</Flex>
</Flex>
<AlertDialog
motionPreset="slideInBottom"
leastDestructiveRef={cancelRef}
onClose={onClose}
isOpen={isOpen}
isCentered
>
<AlertDialogOverlay />
<AlertDialogContent>
<AlertDialogHeader fontSize="lg">
{t('Cancel validation?')}
</AlertDialogHeader>
<AlertDialogCloseButton />
<AlertDialogBody fontSize="md">
{t('Are you sure you want to cancel the scheduled validation?')}
</AlertDialogBody>
<AlertDialogFooter>
<SecondaryButton
onClick={() => {
cancelValidation(type)
onClose()
}}
>
{t('Yes')}
</SecondaryButton>
<PrimaryButton ref={cancelRef} onClick={onClose} ml={2}>
{t('No')}
</PrimaryButton>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ReScheduleAlert
isOpen={isOpenReSchedule}
onConfirm={schedule}
onClose={onCloseReSchedule}
/>
</Flex>
)
}
Example #19
Source File: BuilderProfileCard.jsx From scaffold-directory with MIT License | 4 votes |
BuilderProfileCard = ({ builder, mainnetProvider, isMyProfile, userProvider, fetchBuilder, userRole }) => {
const address = useUserAddress(userProvider);
const ens = useDisplayAddress(mainnetProvider, builder?.id);
const [updatedSocials, setUpdatedSocials] = useState({});
const [isUpdatingReachedOutFlag, setIsUpdatingReachedOutFlag] = useState(false);
const [isUpdatingSocials, setIsUpdatingSocials] = useState(false);
const { isOpen, onOpen, onClose } = useDisclosure();
const { hasCopied, onCopy } = useClipboard(builder?.id);
const { borderColor, secondaryFontColor } = useCustomColorModes();
const shortAddress = ellipsizedAddress(builder?.id);
const hasEns = ens !== shortAddress;
const toast = useToast({ position: "top", isClosable: true });
const toastVariant = useColorModeValue("subtle", "solid");
const joinedDate = new Date(builder?.creationTimestamp);
const joinedDateDisplay = joinedDate.toLocaleString("default", { month: "long" }) + " " + joinedDate.getFullYear();
// INFO: conditional chaining and coalescing didn't work when also checking the length
const hasProfileLinks = builder?.socialLinks ? Object.keys(builder.socialLinks).length !== 0 : false;
const isAdmin = userRole === USER_ROLES.admin;
useEffect(() => {
if (builder) {
setUpdatedSocials(builder.socialLinks ?? {});
}
}, [builder]);
const handleUpdateSocials = async () => {
setIsUpdatingSocials(true);
// Avoid sending socials with empty strings.
const socialLinkCleaned = Object.fromEntries(Object.entries(updatedSocials).filter(([_, value]) => !!value));
const invalidSocials = validateSocials(socialLinkCleaned);
if (invalidSocials.length !== 0) {
toast({
description: `The usernames for the following socials are not correct: ${invalidSocials
.map(([social]) => social)
.join(", ")}`,
status: "error",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
let signMessage;
try {
signMessage = await getUpdateSocialsSignMessage(address);
} catch (error) {
toast({
description: " Sorry, the server is overloaded. ???",
status: "error",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
let signature;
try {
signature = await userProvider.send("personal_sign", [signMessage, address]);
} catch (error) {
toast({
description: "Couldn't get a signature from the Wallet",
status: "error",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
try {
await postUpdateSocials(address, signature, socialLinkCleaned);
} catch (error) {
if (error.status === 401) {
toast({
status: "error",
description: "Access error",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
toast({
status: "error",
description: "Can't update your socials. Please try again.",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
toast({
description: "Your social links have been updated",
status: "success",
variant: toastVariant,
});
fetchBuilder();
setIsUpdatingSocials(false);
onClose();
};
const handleUpdateReachedOutFlag = async reachedOut => {
setIsUpdatingReachedOutFlag(true);
let signMessage;
try {
signMessage = await getUpdateReachedOutFlagSignMessage(builder.id, reachedOut);
} catch (error) {
toast({
description: " Sorry, the server is overloaded. ???",
status: "error",
variant: toastVariant,
});
setIsUpdatingReachedOutFlag(false);
return;
}
let signature;
try {
signature = await userProvider.send("personal_sign", [signMessage, address]);
} catch (error) {
toast({
description: "Couldn't get a signature from the Wallet",
status: "error",
variant: toastVariant,
});
setIsUpdatingReachedOutFlag(false);
return;
}
try {
await postUpdateReachedOutFlag(address, builder.id, reachedOut, signature);
} catch (error) {
if (error.status === 401) {
toast({
status: "error",
description: "Access error",
variant: toastVariant,
});
setIsUpdatingReachedOutFlag(false);
return;
}
toast({
status: "error",
description: "Can't update the reached out flag. Please try again.",
variant: toastVariant,
});
setIsUpdatingReachedOutFlag(false);
return;
}
toast({
description: 'Updated "reached out" flag successfully',
status: "success",
variant: toastVariant,
});
fetchBuilder();
setIsUpdatingReachedOutFlag(false);
};
return (
<>
<BuilderProfileCardSkeleton isLoaded={!!builder}>
{() => (
/* delay execution */
<Flex
borderRadius="lg"
borderColor={borderColor}
borderWidth={1}
justify={{ base: "space-around", xl: "center" }}
direction={{ base: "row", xl: "column" }}
p={4}
pb={6}
maxW={{ base: "full", lg: "50%", xl: 60 }}
margin="auto"
>
<Link as={RouteLink} to={`/builders/${builder.id}`}>
<QRPunkBlockie
withQr={false}
address={builder.id?.toLowerCase()}
w={52}
borderRadius="lg"
margin="auto"
/>
</Link>
<Flex alignContent="center" direction="column" mt={4}>
{hasEns ? (
<>
<Text fontSize="2xl" fontWeight="bold" textAlign="center">
{ens}
</Text>
<Text textAlign="center" mb={4} color={secondaryFontColor}>
{shortAddress}{" "}
<Tooltip label={hasCopied ? "Copied!" : "Copy"} closeOnClick={false}>
<CopyIcon cursor="pointer" onClick={onCopy} />
</Tooltip>
</Text>
</>
) : (
<Text fontSize="2xl" fontWeight="bold" textAlign="center" mb={8}>
{shortAddress}{" "}
<Tooltip label={hasCopied ? "Copied!" : "Copy"} closeOnClick={false}>
<CopyIcon cursor="pointer" onClick={onCopy} />
</Tooltip>
</Text>
)}
{isAdmin && (
<Center mb={4}>
{builder.reachedOut ? (
<Badge variant="outline" colorScheme="green" alignSelf="center">
Reached Out
</Badge>
) : (
<Button
colorScheme="green"
size="xs"
onClick={() => handleUpdateReachedOutFlag(true)}
isLoading={isUpdatingReachedOutFlag}
alignSelf="center"
>
Mark as reached out
</Button>
)}
</Center>
)}
<Divider mb={6} />
{hasProfileLinks ? (
<Flex mb={4} justifyContent="space-evenly" alignItems="center">
{Object.entries(builder.socialLinks)
.sort(bySocialWeight)
.map(([socialId, socialValue]) => (
<SocialLink id={socialId} value={socialValue} />
))}
</Flex>
) : (
isMyProfile && (
<Alert mb={3} status="warning">
<Text style={{ fontSize: 11 }}>
You haven't set your socials{" "}
<Tooltip label="It's our way of reaching out to you. We could sponsor you an ENS, offer to be part of a build or set up an ETH stream for you.">
<QuestionOutlineIcon />
</Tooltip>
</Text>
</Alert>
)
)}
{isMyProfile && (
<Button mb={3} size="xs" variant="outline" onClick={onOpen}>
Update socials
</Button>
)}
<Text textAlign="center" color={secondaryFontColor}>
Joined {joinedDateDisplay}
</Text>
</Flex>
</Flex>
)}
</BuilderProfileCardSkeleton>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Update your socials</ModalHeader>
<ModalCloseButton />
<ModalBody p={6}>
{Object.entries(socials).map(([socialId, socialData]) => (
<FormControl id="socialId" key={socialId} mb={3}>
<FormLabel htmlFor={socialId} mb={0}>
<strong>{socialData.label}:</strong>
</FormLabel>
<Input
type="text"
name={socialId}
value={updatedSocials[socialId] ?? ""}
placeholder={socialData.placeholder}
onChange={e => {
const value = e.target.value;
setUpdatedSocials(prevSocials => ({
...prevSocials,
[socialId]: value,
}));
}}
/>
</FormControl>
))}
<Button colorScheme="blue" onClick={handleUpdateSocials} isLoading={isUpdatingSocials} isFullWidth mt={4}>
Update
</Button>
</ModalBody>
</ModalContent>
</Modal>
</>
);
}
Example #20
Source File: index.js From idena-web with MIT License | 4 votes |
function Settings() {
const router = useRouter()
const {t} = useTranslation()
const {lng, isoLng} = useLanguage()
const [password, setPassword] = useState()
const [showQR, setShowQR] = useState()
const {
isOpen: isOpenExportPKDialog,
onOpen: onOpenExportPKDialog,
onClose: onCloseExportPKDialog,
} = useDisclosure()
const changeLanguageDisclosure = useDisclosure()
const [pk, setPk] = useState('')
const {onCopy, hasCopied} = useClipboard(pk)
const {exportKey} = useAuthDispatch()
const size = useBreakpointValue(['lg', 'md'])
const variantSecondary = useBreakpointValue(['secondaryFlat', 'secondary'])
const variantPrimary = useBreakpointValue(['primaryFlat', 'primary'])
const buttonWidth = useBreakpointValue(['100%', 'auto'])
const successToast = useSuccessToast()
const epochData = useEpoch()
const {coinbase} = useAuthState()
const {addError} = useNotificationDispatch()
const getLogs = async () => {
try {
const epoch = epochData.epoch - 1
const logs = await readValidationLogs(epoch)
const blob = new Blob(
[logs.map(x => `${x.timestamp} - ${JSON.stringify(x.log)}`).join('\n')],
{
type: 'text/plain;charset=utf-8',
}
)
saveAs(blob, `validation-${epoch}-${coinbase}.txt`)
} catch (e) {
addError({title: 'Cannot export logs', body: e.message})
}
}
return (
<SettingsLayout title={t('Settings')}>
<Language display={['none', 'block']} />
<ExportPK
display={['none', 'block']}
onDialogOpen={onOpenExportPKDialog}
/>
<ExportLogs display={['none', 'block']} getLogs={getLogs} />
<Flex display={['flex', 'none']} direction="column" mt={6}>
<MobileSettingsItem
title={t('Node')}
onClick={() => router.push('/settings/node')}
/>
<MobileSettingsItem
title={t('Affiliate program')}
onClick={() => router.push('/settings/affiliate')}
/>
<MobileSettingsItem
title={t('Language')}
description={`${isoLng} (${lng.toUpperCase()})`}
mb={6}
onClick={() => changeLanguageDisclosure.onOpen()}
/>
<WideLink
label={t('Export my private key')}
onClick={onOpenExportPKDialog}
>
<Box boxSize={8} backgroundColor="brandBlue.10" borderRadius="10px">
<PrivateKeyIcon fill="#578FFF" boxSize={5} mt="6px" ml="6px" />
</Box>
</WideLink>
<WideLink label={t('Export validation logs')} onClick={getLogs}>
<Box boxSize={8} backgroundColor="brandBlue.10" borderRadius="10px">
<OpenExplorerIcon boxSize={5} mt="6px" ml="6px" />
</Box>
</WideLink>
</Flex>
<Dialog
size="mdx"
isOpen={isOpenExportPKDialog}
onClose={onCloseExportPKDialog}
>
<DialogHeader>{t('Encrypted private key')}</DialogHeader>
<DialogBody mb={0}>
{!showQR ? (
<form
onSubmit={e => {
e.preventDefault()
const key = exportKey(password)
setPk(key)
setShowQR(true)
}}
>
<Flex direction="column" align="flex-start">
<Text fontSize="mdx" color="gray.300">
{t('Create a new password to export your private key')}
</Text>
<FormLabel
fontSize={['base', 'md']}
mt={5}
mb={3}
w={['auto', '100px']}
htmlFor="url"
>
{t('New password')}
</FormLabel>
<PasswordInput
size={size}
value={password}
mr={[0, '15px']}
width="100%"
disabled={showQR}
onChange={e => setPassword(e.target.value)}
/>
</Flex>
<Flex mt={6} justify="flex-end">
<Button
variant={variantSecondary}
size={size}
w={buttonWidth}
onClick={onCloseExportPKDialog}
>
{t('Close')}
</Button>
<Button
variant={variantPrimary}
size={size}
ml={[0, 2]}
w={buttonWidth}
type="submit"
disabled={!password}
>
{t('Export')}
</Button>
</Flex>
</form>
) : (
<Box>
<Text>
{t(
'Scan QR by your mobile phone or copy code below for export privatekey.'
)}
</Text>
<Flex justify="center" mx="auto" my={8}>
<QRCode value={pk} />
</Flex>
<Flex display={['none', 'flex']} justify="space-between">
<FormLabel style={{fontSize: rem(13)}}>
{t('Your encrypted private key')}
</FormLabel>
{hasCopied ? (
<FormLabel style={{fontSize: rem(13)}}>
{t('Copied!')}
</FormLabel>
) : (
<FlatButton onClick={onCopy} marginBottom={rem(10)}>
{t('Copy')}
</FlatButton>
)}
</Flex>
<Flex
width="100%"
style={{marginBottom: rem(20), position: 'relative'}}
>
<Input
size={size}
value={pk}
width="100%"
pr={[10, 0]}
disabled
/>
<Box
display={['initial', 'none']}
position="absolute"
top={3}
right={3}
>
<CopyIcon
boxSize={6}
fill="muted"
opacity="0.4"
onClick={() => {
onCopy()
successToast({
title: t('Private key copied!'),
duration: '5000',
})
}}
/>
</Box>
</Flex>
<Flex justify="flex-end">
<Button
variant={variantSecondary}
size={size}
w={buttonWidth}
onClick={() => {
setPassword('')
setShowQR(false)
onCloseExportPKDialog()
}}
>
{t('Close')}
</Button>
</Flex>
</Box>
)}
</DialogBody>
</Dialog>
<ChangeLanguageDrawer
changeLanguageDisclosure={changeLanguageDisclosure}
/>
</SettingsLayout>
)
}
Example #21
Source File: Targets.js From web-client with Apache License 2.0 | 4 votes |
ProjectTargets = ({ project }) => {
const query = useQuery();
const urlPageNumber = query.get('page') !== null ? parseInt(query.get('page')) : 1;
const [pageNumber, setPageNumber] = useState(urlPageNumber);
const [numberPages, setNumberPages] = useState(1);
const [targets, setTargets] = useState([]);
const { isOpen: isAddTargetDialogOpen, onOpen: openAddTargetDialog, onClose: closeAddTargetDialog } = useDisclosure();
const onDeleteButtonClick = (ev, targetId) => {
ev.preventDefault();
secureApiFetch(`/targets/${targetId}`, { method: 'DELETE' })
.then(() => {
reloadTargets();
})
}
const onTargetFormSaved = () => {
reloadTargets();
closeAddTargetDialog();
}
const reloadTargets = useCallback(() => {
setTargets([]);
secureApiFetch(`/targets?projectId=${project.id}&page=${pageNumber - 1}`, { method: 'GET' })
.then(resp => {
if (resp.headers.has('X-Page-Count')) {
setNumberPages(resp.headers.get('X-Page-Count'))
}
return resp.json()
})
.then(data => {
setTargets(data);
});
}, [pageNumber, project]);
const onPrevPageClick = () => {
setPageNumber(pageNumber - 1);
}
const onNextPageClick = () => {
setPageNumber(pageNumber + 1);
}
useEffect(() => {
reloadTargets()
}, [reloadTargets])
return <section>
<h4>
<IconServer />Targets
<RestrictedComponent roles={['administrator', 'superuser', 'user']}>
<ButtonGroup>
<TargetModalDialog project={project} isOpen={isAddTargetDialogOpen} onSubmit={onTargetFormSaved} onCancel={closeAddTargetDialog} />
<CreateButton onClick={openAddTargetDialog}>Add target...</CreateButton>
</ButtonGroup>
</RestrictedComponent>
</h4>
{!targets ? <Loading /> :
<>
{numberPages > 1 && <Center>
<Pagination page={pageNumber - 1} total={numberPages} handlePrev={onPrevPageClick} handleNext={onNextPageClick} />
</Center>}
<Table>
<Thead>
<Tr>
<Th>Name</Th>
<Th>Sub-target</Th>
<Th>Kind</Th>
<Th>Vulnerable?</Th>
<Th> </Th>
</Tr>
</Thead>
<Tbody>
{targets.length === 0 && <NoResultsTableRow numColumns={4} />}
{targets.map((target, index) =>
<Tr key={index}>
<Td>
{target.parent_id === null &&
<HStack>
<Link to={`/targets/${target.id}`}><TargetBadge name={target.name} /></Link>
</HStack>
}
{target.parent_id !== null &&
<>{target.parent_name ?? '-'}</>
}
</Td>
<Td>{target.parent_id !== null ?
<>
<Link to={`/targets/${target.id}`}><TargetBadge name={target.name} /></Link>
</> : '-'}</Td>
<Td>{target.kind} <Tags values={target.tags} /></Td>
<Td>{target.num_vulnerabilities > 0 ? `Yes (${target.num_vulnerabilities} vulnerabilities found)` : "No"}</Td>
<Td>
<RestrictedComponent roles={['administrator', 'superuser', 'user']}>
<DeleteIconButton onClick={ev => onDeleteButtonClick(ev, target.id)} />
</RestrictedComponent>
</Td>
</Tr>
)}
</Tbody>
</Table>
</>
}
</section>
}
Example #22
Source File: FormCard.js From MeowForm with MIT License | 4 votes |
function FormCard({formName , responses ,formData ,redirectUrl ,email }) {
const formBackground = useColorModeValue("gray.100","gray.700");
const [check] = useMediaQuery("(min-width: 1025px)")
const { isOpen, onOpen, onClose } = useDisclosure()
const [size, setSize] = React.useState("md")
const [url, setUrl] = React.useState();
const [edit , setEdit] = React.useState(false);
let apiKey = process.env.REACT_APP_APIKEY ;
let apiUrl = process.env.REACT_APP_HOSTURL ;
function isValidURL(string) {
var res = string.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
return (res !== null)
};
const sendResponse = async(serverUrl)=> {
let meow = await axios({
method: 'post',
url: serverUrl,
data: {
url: url,
formName: formName
}
});
}
const checkUrl = () => {
if(url === "" || url === undefined){
toast.error(' Url not saved');
setEdit(!edit)
}else if(isValidURL(url)){
let serverUrl = apiUrl + 'url/' + email + '&' + apiKey;
sendResponse(serverUrl);
toast.success('Url is saved, it will some time to reflect');
setEdit(!edit)
}else{
toast.error('The url is not valid :( ');
}
}
return (
<Box id={formName}mt="1%" borderRadius={25} padding="2%" display="flex" flexDirection={check ? "row" : "column"} backgroundColor ="#fff" background={formBackground} >
<Box width="100%" ml="5%" >
<Flex justifyContent="space-between" >
<Text> {formName}</Text>
<Text> {responses} Responses</Text>
<Button colorScheme="orange" onClick={onOpen}> View</Button>
</Flex>
{/* {console.log(formData)} */}
</Box>
<Drawer onClose={onClose} isOpen={isOpen} size={check ? "xl" :"xs"}>
<DrawerOverlay />
<DrawerContent>
<DrawerHeader align="center">
<Text
margin="1%"
fontWeight="extraBold"
fontSize="3xl"
bgGradient="linear(to-l, #ec9f05 ,#ff4e00)"
bgClip="text"
>
{formName}
</Text>
<Text
>
{responses} Responses
</Text>
</DrawerHeader>
<DrawerBody>
<Box>
{formData.length > 0 &&
<>
<FormHeading obj={formData[0]}></FormHeading>
{
formData.map(x=>
<FormData obj={x}></FormData>
)
}
</>
}
{/* <Flex>
<Text margin="5%">Redirect Url </Text>
<Text margin="5%"> { redirectUrl } </Text>
</Flex> */}
{/* { edit && */}
{/* <Flex>
<Input placeholder={redirectUrl} isDisabled={!edit} value={url} onChange={ (e)=>(setUrl(e.target.value))}
/>
{edit === false ?
<Button onClick={()=>{setEdit(!edit)}}>
edit
</Button>
:
<Button onClick={()=>(checkUrl())}> Save</Button>
}
</Flex> */}
{/* } */}
{/* <Text> * you one need Redirect url if you are just using html css , check docs here </Text> */}
</Box>
<Box>
</Box>
</DrawerBody>
</DrawerContent>
</Drawer>
</Box>
);
}
Example #23
Source File: list.js From idena-web with MIT License | 4 votes |
export default function FlipListPage() {
const {t} = useTranslation()
const toast = useToast()
const epochState = useEpoch()
const {privateKey} = useAuthState()
const {
isOpen: isOpenDeleteForm,
onOpen: openDeleteForm,
onClose: onCloseDeleteForm,
} = useDisclosure()
const [
{
flips: knownFlips,
requiredFlips: requiredFlipsNumber,
availableFlips: availableFlipsNumber,
state: status,
},
] = useIdentity()
const [selectedFlip, setSelectedFlip] = React.useState()
const canSubmitFlips = [
IdentityStatus.Verified,
IdentityStatus.Human,
IdentityStatus.Newbie,
].includes(status)
const [current, send] = useMachine(flipsMachine, {
context: {
knownFlips: knownFlips || [],
filter: loadPersistentState('flipFilter') || FlipFilterType.Active,
},
actions: {
onError: (_, {error}) =>
toast({
title: error,
status: 'error',
duration: 5000,
isClosable: true,
// eslint-disable-next-line react/display-name
render: () => (
<Box fontSize="md">
<Notification title={error} type={NotificationType.Error} />
</Box>
),
}),
},
logger: msg => console.log(redact(msg)),
})
useEffect(() => {
if (epochState && privateKey && status) {
send('INITIALIZE', {epoch: epochState.epoch, privateKey, canSubmitFlips})
}
}, [canSubmitFlips, epochState, privateKey, send, status])
const {flips, missingFlips, filter} = current.context
const filterFlips = () => {
switch (filter) {
case FlipFilterType.Active:
return flips.filter(({type}) =>
[
FlipType.Publishing,
FlipType.Published,
FlipType.Deleting,
FlipType.Invalid,
].includes(type)
)
case FlipType.Draft:
return flips.filter(({type}) => type === FlipType.Draft)
case FlipType.Archived:
return flips.filter(({type}) =>
[FlipType.Archived, FlipType.Deleted].includes(type)
)
default:
return []
}
}
const madeFlipsNumber = (knownFlips || []).length
const remainingRequiredFlips = requiredFlipsNumber - madeFlipsNumber
const remainingOptionalFlips =
availableFlipsNumber - Math.max(requiredFlipsNumber, madeFlipsNumber)
const [currentOnboarding, {dismissCurrentTask}] = useOnboarding()
const eitherOnboardingState = (...states) =>
eitherState(currentOnboarding, ...states)
return (
<Layout>
<Page pt={[4, 6]}>
<MobileApiStatus display={['initial', 'none']} left={4} />
<PageTitleNew>{t('My Flips')}</PageTitleNew>
<Flex justify="space-between" align="center" alignSelf="stretch" mb={8}>
<Stack spacing={2} isInline>
<Button
variant="tab"
onClick={() => send('FILTER', {filter: FlipFilterType.Active})}
isActive={filter === FlipFilterType.Active}
>
{t('Active')}
</Button>
<Button
variant="tab"
onClick={() => send('FILTER', {filter: FlipFilterType.Draft})}
isActive={filter === FlipFilterType.Draft}
>
{t('Drafts')}
</Button>
<Button
variant="tab"
onClick={() => send('FILTER', {filter: FlipFilterType.Archived})}
isActive={filter === FlipFilterType.Archived}
>
{t('Archived')}
</Button>
</Stack>
<Box alignSelf="end">
<OnboardingPopover
isOpen={eitherOnboardingState(
onboardingShowingStep(OnboardingStep.CreateFlips)
)}
>
<PopoverTrigger>
<Box onClick={dismissCurrentTask}>
<IconLink
icon={<PlusSolidIcon boxSize={5} mt={1} />}
href="/flips/new"
bg="white"
position={
eitherOnboardingState(
onboardingShowingStep(OnboardingStep.CreateFlips)
)
? 'relative'
: 'initial'
}
zIndex={2}
>
{t('New flip')}
</IconLink>
</Box>
</PopoverTrigger>
<OnboardingPopoverContent
title={t('Create required flips')}
onDismiss={dismissCurrentTask}
>
<Stack>
<Text>
{t(`You need to create at least 3 flips per epoch to participate
in the next validation ceremony. Follow step-by-step
instructions.`)}
</Text>
<OnboardingPopoverContentIconRow
icon={<RewardIcon boxSize={5} />}
>
{t(
`You'll get rewarded for every successfully qualified flip.`
)}
</OnboardingPopoverContentIconRow>
<OnboardingPopoverContentIconRow
icon={<PenaltyIcon boxSize={5} />}
>
{t(`Read carefully "What is a bad flip" rules to avoid
penalty.`)}
</OnboardingPopoverContentIconRow>
</Stack>
</OnboardingPopoverContent>
</OnboardingPopover>
</Box>
</Flex>
{current.matches('ready.dirty.active') &&
canSubmitFlips &&
(remainingRequiredFlips > 0 || remainingOptionalFlips > 0) && (
<Box alignSelf="stretch" mb={8}>
<Alert
status="success"
bg="green.010"
borderWidth="1px"
borderColor="green.050"
fontWeight={500}
rounded="md"
px={3}
py={2}
>
<AlertIcon name="info" color="green.500" size={5} mr={3} />
{remainingRequiredFlips > 0
? t(
`Please submit {{remainingRequiredFlips}} required flips.`,
{remainingRequiredFlips}
)
: null}{' '}
{remainingOptionalFlips > 0
? t(
`You can also submit {{remainingOptionalFlips}} optional flips if you want.`,
{
remainingOptionalFlips,
}
)
: null}
</Alert>
</Box>
)}
{status && !canSubmitFlips && (
<Box alignSelf="stretch" mb={8}>
<Alert
status="error"
bg="red.010"
borderWidth="1px"
borderColor="red.050"
fontWeight={500}
rounded="md"
px={3}
py={2}
>
<AlertIcon
name="info"
color="red.500"
size={5}
mr={3}
></AlertIcon>
{t('You can not submit flips. Please get validated first. ')}
</Alert>
</Box>
)}
{current.matches('ready.pristine') && (
<Flex
flex={1}
alignItems="center"
justifyContent="center"
alignSelf="stretch"
>
<Image src="/static/flips-cant-icn.svg" />
</Flex>
)}
{current.matches('ready.dirty') && (
<FlipCardList>
{filterFlips().map(flip => (
<FlipCard
key={flip.id}
flipService={flip.ref}
onDelete={() => {
if (
flip.type === FlipType.Published &&
(knownFlips || []).includes(flip.hash)
) {
setSelectedFlip(flip)
openDeleteForm()
} else flip.ref.send('ARCHIVE')
}}
/>
))}
{current.matches('ready.dirty.active') && (
<>
{missingFlips.map(({keywords}, idx) => (
<Box key={idx}>
<EmptyFlipBox>
<Image src="/static/flips-cant-icn.svg" />
</EmptyFlipBox>
<Box mt={4}>
<FlipCardTitle>
{keywords
? formatKeywords(keywords.words)
: t('Missing keywords')}
</FlipCardTitle>
<FlipCardSubtitle>
{t('Missing on client')}
</FlipCardSubtitle>
</Box>
</Box>
))}
{Array.from({length: remainingRequiredFlips}, (flip, idx) => (
<RequiredFlipPlaceholder
key={idx}
title={`Flip #${madeFlipsNumber + idx + 1}`}
{...flip}
/>
))}
{Array.from({length: remainingOptionalFlips}, (flip, idx) => (
<OptionalFlipPlaceholder
key={idx}
title={`Flip #${availableFlipsNumber -
(remainingOptionalFlips - idx - 1)}`}
{...flip}
isDisabled={remainingRequiredFlips > 0}
/>
))}
</>
)}
</FlipCardList>
)}
<DeleteFlipDrawer
hash={selectedFlip?.hash}
cover={selectedFlip?.images[selectedFlip.originalOrder[0]]}
isOpen={isOpenDeleteForm}
onClose={onCloseDeleteForm}
onDelete={() => {
selectedFlip.ref.send('DELETE')
onCloseDeleteForm()
}}
/>
</Page>
</Layout>
)
}
Example #24
Source File: SponsorCard.js From codeursenseine.com with MIT License | 4 votes |
SponsorCard = ({ logoSrc, link, name, excerpt, children }) => {
const containerRef = React.useRef();
const contentRef = React.useRef();
const [isExpandable, setIsExpandable] = React.useState(false);
const { isOpen, onOpen, onClose } = useDisclosure();
React.useEffect(() => {
if (containerRef.current && contentRef.current) {
setIsExpandable(
contentRef.current.offsetHeight - containerRef.current.offsetHeight > 0
);
}
}, [setIsExpandable]);
return (
<>
<Card
ref={containerRef}
as="article"
maxH="22rem"
position="relative"
p={0}
>
<Box ref={contentRef} p={6}>
{logoSrc && (
<>
<Link
d="block"
href={link}
title={name}
target="_blank"
rel="noopener noreferrer"
>
<AspectRatio ratio={320 / 190}>
<Image src={logoSrc} alt={name} objectFit="fit" />
</AspectRatio>
</Link>
<Divider />
</>
)}
<Box d="flex" alignItems="baseline">
<A href={link} title={name} target="_blank">
{name}
</A>
</Box>
<Text fontSize="sm">{excerpt}</Text>
</Box>
{isExpandable && (
<Box
position="absolute"
bottom={0}
left={0}
right={0}
pt={16}
textAlign="center"
background="linear-gradient(0deg, rgba(255,255,255,1) 50%, rgba(255,255,255,0) 100%)"
>
<Button
onClick={onOpen}
variant="unstyled"
d="inline-block"
fontSize="sm"
h="auto"
m={4}
p={4}
py={2}
_hover={{ color: "brand.600" }}
>
Lire la suite
</Button>
</Box>
)}
</Card>
<Modal motionPreset="scale" isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader fontSize="xl">
<Box>
<Text>{name}</Text>
</Box>
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<MDXRenderer>{children}</MDXRenderer>
</ModalBody>
</ModalContent>
</Modal>
</>
);
}
Example #25
Source File: BecomeMember.js From DAOInsure with MIT License | 4 votes |
function BecomeMember() {
const { signerAddress, provider, signer } = useContext(Web3Context);
const { isOpen, onOpen, onClose } = useDisclosure();
const [latitude, setLatitude] = useState();
const [longitude, setLongitude] = useState();
const handleChange = (e, setter) => {
setter(e.target.value);
};
const web3 = new Web3(provider);
console.log(web3);
const joinDao = async () => {
let contract = new ethers.Contract(
SUPERAPP_CONTRACT_ADDRESS,
SUPERAPP_CONTRACT_ABI,
signer
);
const walletAddress = await window.ethereum.request({
method: "eth_requestAccounts",
params: [
{
eth_accounts: {},
},
],
});
// this sdk has a lot of changes (breaking changes) from the version we used.
const sf = new SuperfluidSDK.Framework({
ethers: provider,
});
await sf.initialize();
// creating user from unlocked address. token is super token.
const carol = sf.user({
address: walletAddress[0],
token: "0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f",
});
// creating a flow, user data can contain arbitary data.
await carol.flow({
recipient: SUPERAPP_CONTRACT_ADDRESS,
flowRate: "3858024691358",
userData: web3.eth.abi.encodeParameters(
["string", "string"],
[latitude, longitude]
),
});
// details of the user like incoming and outgoing flow rates, and the various active flows along with types.
const details = await carol.details();
console.log(details);
// // Call the host with the batch call parameters
// await sf.host.batchCall(createPlayBatchCall(100));
function createPlayBatchCall(upgradeAmount = 0) {
return [
[
202, // upgrade 100 daix to play the game
"0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f",
// adding latitude and longitude to the encoded data.
contract.interface.encodeFunctionData("setCoordinates", [
parseInt(latitude),
parseInt(longitude),
]),
],
[
1, // approve the ticket fee
{
token: "0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f", // Super Tokens only
amount: "1000000000000000000",
spender: SUPERAPP_CONTRACT_ADDRESS,
},
],
];
}
// Call the host with the batch call parameters
await sf.host.batchCall(createPlayBatchCall(100));
};
return (
<VStack spacing={5} mt='20px'>
<Modal
isOpen={isOpen}
onClose={onClose}
closeOnOverlayClick={false}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Enter the following Details</ModalHeader>
<ModalCloseButton />
<ModalBody>
<HStack>
<Input
onChange={(e) => handleChange(e, setLatitude)}
placeholder='Latitude'
/>
<Input
onChange={(e) => handleChange(e, setLongitude)}
placeholder='Longitude'
/>
</HStack>
</ModalBody>
<ModalFooter>
<Button onClick={joinDao} colorScheme='whatsapp'>
Join DAO (10 DAIx / Month)
</Button>
</ModalFooter>
</ModalContent>
</Modal>
<Heading fontSize='32px'>Become A Member</Heading>
<Heading fontSize='24px'>How it works?</Heading>
<UnorderedList>
<ListItem>
DAOInsure provides insurances to its members based on DAO
voting
</ListItem>
<ListItem>
DAO members stream insurance premium to the treasury.
</ListItem>
<ListItem>
In exchange for premium paid the members get voting power.
</ListItem>
<ListItem>
Use voting power to approve other fellow member's claim.
</ListItem>
</UnorderedList>
<Heading fontSize='24px'>
Become A Member just 10 DAIx / Month
</Heading>
{signerAddress ? (
<Button colorScheme='whatsapp' onClick={onOpen}>
Join the DAO
</Button>
) : (
<GreenTag>Please connect wallet first</GreenTag>
)}
</VStack>
);
}
Example #26
Source File: Header.js From interspace.chat with GNU General Public License v3.0 | 4 votes |
export function SiteHeader() {
const { isOpen, onOpen, onClose } = useDisclosure();
const ref = useRef(null);
const linkRef = useRef(null);
const onScreen = useOnScreen(ref);
const linkOnScreen = useOnScreen(linkRef)
const disabledGenNotify = useDisabledGeneralNotify();
const handleToggle = () => (isOpen ? onClose() : onOpen());
const screenSize = useBreakpoint()
console.log('s',screenSize);
const NavLink = ({ href, children, offset }) => (
<Link
ref={linkRef}
fontWeight={{ base: 500, lg: 700 }}
px={2}
py={1}
rounded={"md"}
textShadow="0 0 10px rgba(0, 0, 0, 0.8)"
opacity={!linkOnScreen ? 1 : 0}
transform={`translate3d(${!linkOnScreen ? 0 : -200}, 0, 0)`}
transition={`all 0.2s ${0.6 + offset}s ease`}
_hover={{
textDecoration: "none",
background: "linear-gradient(-90deg, #FF61E6 -29.22%, #7C56FF 107.53%)",
backgroundClip: "text",
WebkitTextFillColor: "transparent",
}}
href={href}
onClick={handleToggle}
color="white"
>
{children}
</Link>
);
return (
<>
<Box
ref={ref}
as="header"
bg="transparent"
position="fixed"
top={0}
px={4}
w="100%"
maxW="100vw"
h={{base: '75px', md: "100px"}}
// transform={`translate3d(0, ${onScreen ? 0 : "-70px"}, 0)`}
opacity={onScreen ? 1 : 0}
transition="transform 0.3s 1s ease-in-out, opacity 0.6s 0.8s ease-in"
zIndex={2000}
sx={{
a: {
color: "white",
},
}}
>
<Flex
h={{base: '75px', md: "100px"}}
alignItems={"center"}
justifyContent={"space-between"}
>
<Box width={{ base: "25%" }} h="2.5rem" overflow="visible" sx={{
d: {base: 'inline-flex', md: 'none'},
}}>
<Button
onClick={handleToggle}
sx={{
alignSelf: "center",
justifySelf: "right",
position: "relative",
flexDirection: "column",
justifyContent: "space-around",
overflow: 'visible',
w: { base: "2.25rem" },
h: { base: "2.25rem" },
background: "transparent",
border: "none",
cursor: "pointer",
padding: 0,
mx: 0,
zIndex: 2003,
"&:hover, &:focus, &[data-hover]": {
outline: "none",
background: "transparent",
boxShadow: "none",
},
div: {
w: "100%",
h: "100%",
p: 0,
transition: "all 0.3s linear",
position: "relative",
transformOrigin: "1px",
},
"path, circle": {
fill: isOpen ? "transparent" : "transparent",
transition: "all 0.2s 0.2s ease",
stroke: isOpen ? "#7C56FF" : "#927CFF",
},
".top-line": {
transition: "all 0.6s ease",
transform: isOpen
? "rotate(-405deg) translate3d(1px, 3px, 0)"
: "rotate(0)",
transformOrigin: "center",
},
".bottom-line": {
transition: "all 0.6s ease",
transform: isOpen
? "rotate(405deg) translate3d(0px, -4px, 0)"
: "rotate(0)",
transformOrigin: "center",
},
}}
>
<MenuIcon2SVG toggle={isOpen} />
</Button>
</Box>
<HStack spacing={8} alignItems={"center"}>
<Link href="#home" flex={{base: 1}}>
<Image
src={MF2Logo}
alt="MetaGame Logo"
boxSize={{ base: "65px", md: "95px" }}
objectFit="cover"
transform={{ md: "translateY(15px) translateX(10px)" }}
sx={{
transition: 'all 0.2s 0.1s ease',
filter: "drop-shadow(0 0 15px rgba(0,0,0,0.6))",
_hover: {
filter: "drop-shadow(0 0 15px #FF61E696)",
}
}}
/>
</Link>
<HStack
as={"nav"}
spacing={4}
display={{ base: "none", md: "flex" }}
>
{Links.map((link, i) => (
<NavLink key={`desktop-${link.name}`} href={link.href}>
{link.name}
</NavLink>
))}
</HStack>
</HStack>
<Flex alignItems="center" justifyContent="end" width={{ base: "25%", md: 'auto' }}>
{screenSize !== 'base' ? (
<Button
variant={"solid"}
colorScheme={"purple"}
bg="#927CFF"
boxShadow="0 0 10px rgba(0, 0, 0, 0.6)"
size="sm"
mr={0}
onClick={disabledGenNotify}
>
Connect
</Button>
) : (
<IconButton
icon={<BiWalletAlt />}
aria-label="Connect Web3 wallet"
flex={0}
fontSize={{base: '12vmin', lg: "2vmax"}}
colorScheme="ghost"
color="#927CFF"
onClick={disabledGenNotify}
alignSelf="center"
// filter="drop-shadow(0 0 15px #FF61E6)"
/>
)}
</Flex>
</Flex>
{/* {isOpen ? ( */}
<Box
display={{ base: "flex", md: "none" }}
position="fixed"
top={0}
left={0}
w="100%"
minW="100%"
minH="100vh"
alignItems="center"
justifyContent="center"
p={5}
pt="100px"
bg="linear-gradient(0deg, rgba(41,2,80,0.1) 0%, rgba(25,0,50,0.5) 40%)"
backdropFilter="blur(7px)"
transition="transform 0.3s 0.1s ease, opacity 0.3s 0.2s"
boxShadow="0 0 15px #00000070"
opacity={isOpen ? 1 : 0}
transform={`translate3d(0, ${isOpen ? 0 : '-100vh'}, 0)`}
zIndex={-1}
>
<Stack as={"nav"} spacing={4} height="auto">
{Links.map((link) => (
<NavLink key={`mobile-${link.name}`} href={link.href}>
{link.name}
</NavLink>
))}
</Stack>
</Box>
{/* ) : null} */}
</Box>
</>
);
}
Example #27
Source File: Player.jsx From bottle-radio with MIT License | 4 votes |
Player = () => {
const variables = window._env_ ? window._env_ : { REACT_ICECAST_URL: "" };
const [playing, setPlaying] = useState(false);
const [loading, setLoading] = useState(false);
const [muted, setMuted] = useState(false);
const [firstLoad, setFirstLoad] = useState(true);
const [nowPlaying, setNowPlaying] = useState(["No data", "No data"]);
const [listeners, setListeners] = useState([0, 0]);
const { colorMode } = useColorMode();
const colorHover = { light: "white", dark: "black" };
const { isOpen, onOpen, onClose } = useDisclosure();
const trackLinks = useSaveTrack(
nowPlaying[0],
nowPlaying[1]
);
const audioRef = useRef(null);
const { setPlayer } = useContext(VisualiserContext);
useEffect(() => {
const audio = document.getElementById("player");
if (audio) {
setPlayer(audioRef);
}
}, [setPlayer]);
useEffect(() => {
const updateStats = async () => {
let url = variables.REACT_ICECAST_URL + "status-json.xsl";
let response = await fetch(url);
let json = await response.json();
let track = json.icestats.source.title;
if (track && track !== "") {
let artist = track.split(" - ")[0];
track = track.split(" - ").slice(1).join(" - ");
setNowPlaying([track, artist]);
}
let listeners = json.icestats.source.listeners;
let peakListeners = json.icestats.source.listener_peak;
if (listeners && listeners) {
setListeners([listeners, peakListeners]);
}
};
updateStats();
setInterval(() => {
updateStats();
}, 10000);
}, [variables.REACT_ICECAST_URL]);
const togglePlay = () => {
let player = document.getElementById("player");
if (firstLoad) {
setFirstLoad(false);
}
if (player.paused) {
setPlaying(true);
player.load();
player.play();
} else {
setPlaying(false);
player.pause();
}
};
const changeVolume = (value) => {
let player = document.getElementById("player");
value <= 0 ? setMuted(true) : setMuted(false);
player.volume = value / 100;
};
const TrackModal = (props) => {
const { modal, setModal } = useContext(ModalContext);
useEffect(() => {
if (!modal) {
setModal(trackLinks);
}
}, [modal, setModal]);
return (
<div>
<Modal
isOpen={isOpen}
onClose={() => {
onClose();
setModal();
}}
size="sm"
isCentered
>
<ModalOverlay>
<ModalContent>
<ModalCloseButton />
<ModalBody>
<Grid templateColumns="1fr 1fr" justifyItems="center" gap={0}>
{modal && modal.length > 0 ? (
modal.map((link) => (
<Link key={link.url} href={link.url} isExternal>
<Button variant="ghost">{link.displayName}</Button>
</Link>
))
) : (
<div>
<Spinner size="sm" /> Loading...
</div>
)}
</Grid>
</ModalBody>
</ModalContent>
</ModalOverlay>
</Modal>
</div>
);
};
return (
<div>
<Flex
direction="column"
justify="center"
align="center"
width="100%"
height="100%"
>
<Box>
<Grid
m={2}
p={2}
templateColumns="auto 1fr auto"
alignItems="center"
gap={1}
>
<Box
gridRow="1/4"
w="80px"
h="80px"
aria-label="Play toggle"
as={loading ? FaSpinner : playing ? FaPauseCircle : FaPlayCircle}
onClick={togglePlay}
_hover={{ color: colorHover[colorMode] }}
mr={1}
className={loading ? "icon-spin" : ""}
/>
<Text m={0} align="center">
<strong>{nowPlaying[0]}</strong>
</Text>
<Text m={0} align="center">
{nowPlaying[1]}
</Text>
<Flex direction="row" justify="center" maxWidth={400} p={2}>
<Slider
defaultValue={100}
min={0}
max={100}
step={10}
onChange={changeVolume}
width="80px"
>
<SliderTrack>
<SliderFilledTrack bg="tomato" />
</SliderTrack>
<SliderThumb size={2} />
</Slider>
<Box
w="20px"
h="20px"
as={muted ? FaVolumeMute : FaVolumeUp}
ml={3}
/>
<audio
id="player"
crossOrigin="anonymous"
autoPlay
preload="none"
ref={audioRef}
onPlay={() => setPlaying(true)}
onPause={() => setPlaying(false)}
onLoadStart={() => {
if (!firstLoad) {
setLoading(true);
}
}}
onCanPlay={() => setLoading(false)}
>
<source
src={variables.REACT_ICECAST_URL + "radio.mp3"}
type="audio/mp3"
/>
Your browser does not support the audio element.
</audio>
</Flex>
<Text gridColumn="1/4">
<strong>Listeners: </strong>
{listeners[0]} <strong>Peak: </strong>
{listeners[1]}
</Text>
<Box gridColumn="3" gridRow="1/4" alignItems="center">
<Box
w="25px"
h="25px"
as={FaHeart}
mx={1}
onClick={onOpen}
_hover={{ color: "tomato" }}
/>
{isOpen ? <TrackModal /> : null}
</Box>
</Grid>
</Box>
</Flex>
</div>
);
}
Example #28
Source File: Todo.js From benjamincarlson.io with MIT License | 4 votes |
Todo = () => {
const toast = useToast()
const { colorMode } = useColorMode()
const { isOpen, onOpen, onClose } = useDisclosure()
const colorSecondary = {
light: 'gray.600',
dark: 'gray.400',
}
const borderColor = {
light: 'gray.200',
dark: 'gray.600',
}
const colorSmall = {
light: 'gray.400',
dark: 'gray.600',
}
const myTodos = [
{
completed: false,
title: 'Improve Final Cut Pro skills ?',
},
{
completed: false,
title: 'Finish my degree ?',
},
{
completed: false,
title: 'Grow my YouTube channel ?',
},
{
completed: false,
title: 'Grow coffeeclass.io ☕',
},
]
const [todos, setTodos] = useState(myTodos)
const [input, setInput] = useState('')
const removeTodo = todo => {
setTodos(todos.filter(t => t !== todo))
}
const toggleCompleted = todo => {
todo.completed = !todo.completed
setTodos([...todos])
}
const addTodo = () => {
setTodos(todos.concat({
completed: false,
title: input,
}))
setInput('')
}
return (
<>
<Box as="section" w="100%" mt={10} mb={20}>
<Stack spacing={4} w="100%">
<Heading letterSpacing="tight" size="lg" fontWeight={700} as="h2">Todo List ?</Heading>
<Text color={colorSecondary[colorMode]}>Here is a list of things I plan to accomplish over the next year. Try it out yourself!</Text>
<InputGroup size="md" mt={4} borderColor="gray.500" borderColor={borderColor[colorMode]}>
<InputLeftElement
pointerEvents="none"
children={<Search2Icon color={useColorModeValue("gray.500", "gray.600")} />}
/>
<Input
aria-label="Enter a Todo!"
placeholder="Improve Python skills ?"
value={input}
onChange={e => setInput(e.target.value)}
/>
<InputRightElement width="6.75rem">
<Button
aria-label="Add a TODO!"
fontWeight="bold"
h="1.75rem"
size="md"
colorScheme="gray"
mr={2}
variant="outline"
px={10}
onClick={() => {
if (input == '')
toast({
title: 'Whoops! There\'s an error!',
description: "Input can't be empty!",
status: "error",
duration: 2000,
isClosable: true,
})
else {
addTodo(input)
}
}}
>
Add Todo!
</Button>
</InputRightElement>
</InputGroup>
<Flex flexDir="column">
{todos.map((todo, index) => (
<Flex
key={index}
justify="space-between"
align="center"
my={1}
>
<Flex align="center">
<Icon fontSize="xl" mr={2} as={ChevronRightIcon} color={colorSecondary[colorMode]} />
<Tooltip label={`Click "${todo.title}" to mark as completed.`} placement="top" hasArrow>
<Text color={colorSecondary[colorMode]} textDecor={todo.completed && "line-through"} _hover={{ cursor: 'pointer' }} onClick={() => toggleCompleted(todo)}>{todo.title}</Text>
</Tooltip>
</Flex>
<Tooltip label={`Delete "${todo.title}"`} placement="top" hasArrow>
<IconButton aria-label={`Delete "${todo.title}" from Todo list.`} icon={<DeleteIcon color="red.400" />} onClick={() => removeTodo(todo)} />
</Tooltip>
</Flex>
))}
</Flex>
<Flex align="center">
<Text onClick={() => setTodos(myTodos)} _hover={{ cursor: 'pointer' }} color={colorSmall[colorMode]}>Reset</Text>
<Divider orientation="vertical" mx={2} h={4} />
<Text onClick={onOpen} _hover={{ cursor: 'pointer' }} color={colorSmall[colorMode]}>Help</Text>
</Flex>
</Stack>
</Box>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Todo List Help</ModalHeader>
<ModalCloseButton />
<ModalBody>
<OrderedList>
<ListItem>
<Text fontWeight="bold">Add a Todo</Text>
<Text>Input your Todo and click the "Add Todo!" button to add a new Todo.</Text>
</ListItem>
<ListItem>
<Text fontWeight="bold">Reset</Text>
<Text>Click the "Reset" button to reset the list.</Text>
</ListItem>
<ListItem>
<Text fontWeight="bold">Delete</Text>
<Text>Click the "Delete" button to delete a Todo.</Text>
</ListItem>
<ListItem>
<Text fontWeight="bold">Completed</Text>
<Text>Click a Todo to mark it as completed.</Text>
</ListItem>
<ListItem>
<Text fontWeight="bold">View Code</Text>
<Text>Click the "View Code" button to view the code on GitHub for this simple TODO list.</Text>
</ListItem>
</OrderedList>
<Divider my={6} />
<Text><strong>Current state of Todo List:</strong> [{todos.map(t => { return `{"${t.title}",${t.completed}},` })}]</Text>
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
<Link
href="https://github.com/bjcarlson42/benjamincarlson.io/blob/master/components/Todo.js"
_hover={{ textDecor: 'none' }}
isExternal
>
<Button variant="ghost">View Code</Button>
</Link>
</ModalFooter>
</ModalContent>
</Modal>
</>
)
}
Example #29
Source File: list.js From idena-web with MIT License | 4 votes |
export default function AdListPage() {
const {t} = useTranslation()
const formatDna = useFormatDna()
const reviewDisclosure = useDisclosure()
const publishDisclosure = useDisclosure()
const burnDisclosure = useDisclosure()
const coinbase = useCoinbase()
const balance = useBalance(coinbase)
const [filter, setFilter] = React.useState(() =>
typeof window === 'undefined'
? AdStatus.Approved
: localStorage?.getItem('adListFilter') ?? AdStatus.Approved
)
React.useEffect(() => {
localStorage.setItem('adListFilter', filter)
}, [filter])
const {
data: profileAds,
refetch: refetchProfileAds,
status: profileAdsStatus,
} = useProfileAds()
const {
data: persistedAds,
refetch: refetchPersistedAds,
status: persistedAdsStatus,
} = usePersistedAds()
const loadingStatus =
profileAdsStatus === 'loading' || persistedAdsStatus === 'loading'
? 'loading'
: 'done'
const ads = [
...profileAds,
...(persistedAds?.filter(
a => profileAds.findIndex(b => a?.cid === b?.cid) < 0
) ?? []),
].filter(ad => ad?.status === filter)
const [selectedAd, setSelectedAd] = React.useState({})
const refetchAds = React.useCallback(() => {
refetchProfileAds()
refetchPersistedAds()
}, [refetchPersistedAds, refetchProfileAds])
const {toast, close: closeToast} = useClosableToast()
const failToast = useFailToast()
const {onClose: onClosePublishDisclosure} = publishDisclosure
const handlePublish = React.useCallback(async () => {
try {
await db.table('ads').update(selectedAd.id, {
status: AdStatus.Published,
})
refetchAds()
toast({
title: t('Ad campaign is successfully created'),
actionContent: t(`View 'Campaigns'`),
onAction: () => {
setFilter(AdStatus.Published)
closeToast()
},
})
} catch {
console.error('Error updating persisted ads', {id: selectedAd?.id})
} finally {
onClosePublishDisclosure()
}
}, [closeToast, onClosePublishDisclosure, refetchAds, selectedAd, t, toast])
const {onClose: onCloseReviewDisclosure} = reviewDisclosure
const handleStartVoting = React.useCallback(
async ({cid, contract}) => {
try {
await db.table('ads').update(selectedAd.id, {
status: AdStatus.Reviewing,
cid,
contract,
})
refetchAds()
toast({
title: t('Ad has been sent to oracles review'),
actionContent: t(`View 'On review'`),
onAction: () => {
setFilter(AdStatus.Reviewing)
closeToast()
},
})
} catch {
console.error('Error updating persisted ads', {id: selectedAd?.id})
} finally {
onCloseReviewDisclosure()
}
},
[closeToast, onCloseReviewDisclosure, refetchAds, selectedAd, t, toast]
)
const queryClient = useQueryClient()
const {onClose: onCloseBurnDisclosure} = burnDisclosure
const handleBurn = React.useCallback(() => {
onCloseBurnDisclosure()
queryClient.invalidateQueries(['bcn_burntCoins', []])
}, [onCloseBurnDisclosure, queryClient])
const {query, replace} = useRouter()
React.useEffect(() => {
if (query.from === 'new' && query.save) {
toast({
title: t('Ad has been saved to drafts'),
actionContent: t(`View 'Drafts'`),
onAction: () => {
setFilter(AdStatus.Draft)
closeToast()
replace('/adn/list')
},
})
}
}, [closeToast, query, replace, t, toast])
const handleDeployContract = React.useCallback(
({cid, contract}) => {
db.table('ads').update(selectedAd?.id, {
cid,
contract,
author: coinbase,
status: AdStatus.Reviewing,
})
refetchPersistedAds()
},
[coinbase, refetchPersistedAds, selectedAd]
)
const handleRemoveAd = React.useCallback(
async ad => {
try {
if (ad.id) {
await db.table('ads').delete(ad.id)
} else {
await db
.table('ads')
.where({cid: ad.cid})
.delete()
}
} catch {
console.error({ad}, 'failed to delete ad')
failToast('Failed to delete ad')
} finally {
refetchPersistedAds()
}
},
[failToast, refetchPersistedAds]
)
const previewAdDisclosure = useDisclosure()
const devToolsDisclosure = useDisclosure()
return (
<Layout>
<Page pt={[4, 6]}>
<MobileApiStatus left={4} />
<PageTitleNew>{t('My Ads')}</PageTitleNew>
<HStack spacing={20} pb="2" pt="1">
<BlockAdStat label="My balance" w="2xs">
<Skeleton isLoaded={Boolean(balance)}>
<AdStatNumber fontSize="lg" lineHeight="5" isTruncated>
{formatDna(balance)}
</AdStatNumber>
</Skeleton>
</BlockAdStat>
</HStack>
<FilterButtonList value={filter} onChange={setFilter} w="full" mt={4}>
<Flex align="center" justify="space-between" w="full">
<HStack>
<FilterButton value={AdStatus.Published}>
{t('Campaigns')}
</FilterButton>
<VDivider />
<FilterButton value={AdStatus.Draft}>{t('Drafts')}</FilterButton>
<FilterButton value={AdStatus.Reviewing}>
{t('On review')}
</FilterButton>
<FilterButton value={AdStatus.Approved}>
{t('Approved')}
</FilterButton>
<FilterButton value={AdStatus.Rejected}>
{t('Rejected')}
</FilterButton>
</HStack>
<HStack spacing={1} align="center">
<IconButton
icon={<RefreshIcon boxSize={5} />}
onClick={refetchAds}
>
{t('Refresh')}
</IconButton>
<VDivider />
<IconLink icon={<PlusSolidIcon boxSize={5} />} href="/adn/new">
{t('New ad')}
</IconLink>
</HStack>
</Flex>
</FilterButtonList>
{loadingStatus === 'done' && (
<AdList spacing={4} w="full" my="8">
{ads.map(ad => (
<AdListItem
key={`${ad.cid}!!${ad.id}`}
ad={ad}
onReview={() => {
setSelectedAd(ad)
reviewDisclosure.onOpen()
}}
onPublish={() => {
setSelectedAd(ad)
publishDisclosure.onOpen()
}}
onBurn={() => {
setSelectedAd(ad)
burnDisclosure.onOpen()
}}
onRemove={handleRemoveAd}
onPreview={() => {
setSelectedAd(ad)
previewAdDisclosure.onOpen()
}}
/>
))}
</AdList>
)}
{loadingStatus === 'loading' && <LoadingAdList />}
{loadingStatus === 'done' && ads.length === 0 && (
<EmptyAdList>
{filter === AdStatus.Published
? t(`You haven't created any campaigns yet`)
: t('No corresponding ads')}
</EmptyAdList>
)}
<ReviewAdDrawer
ad={selectedAd}
onDeployContract={handleDeployContract}
onStartVoting={handleStartVoting}
{...reviewDisclosure}
/>
<PublishAdDrawer
ad={selectedAd}
onPublish={handlePublish}
{...publishDisclosure}
/>
<BurnDrawer ad={selectedAd} onBurn={handleBurn} {...burnDisclosure} />
<AdPreview ad={selectedAd} {...previewAdDisclosure} />
{typeof window !== 'undefined' &&
window.location.hostname.includes('localhost') && (
<>
<Box position="fixed" bottom="8" right="8">
<SecondaryButton onClick={devToolsDisclosure.onOpen}>
Debug ads
</SecondaryButton>
</Box>
<Drawer title="Debug ads" size="xl" {...devToolsDisclosure}>
<DrawerBody>
<Stack spacing="10">
<Box>
<h4>Current ads</h4>
<Debug>{ads}</Debug>
</Box>
<Box>
<h4>Decoders</h4>
<AdDebug />
</Box>
</Stack>
</DrawerBody>
</Drawer>
<ReactQueryDevtools />
</>
)}
</Page>
</Layout>
)
}