@chakra-ui/react#Spacer JavaScript Examples

The following examples show how to use @chakra-ui/react#Spacer. 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: Navbar.js    From GitMarkonics with MIT License 6 votes vote down vote up
function NavHeader() {
  return (
    <Box className="nav_header" p={1}>
      <Flex direction="row " >
        <img src={logo} alt="heading" width="100px"  className="logo"/>
        <Spacer />
        <Stack direction="row" spacing={2}>
          <Link to="/">
            <Button leftIcon={<GrHome />} colorScheme="pink" variant="solid" className="home">
              Home
            </Button>
          </Link>
        </Stack>
      </Flex>
    </Box>
  );
}
Example #2
Source File: BuildCard.jsx    From scaffold-directory with MIT License 6 votes vote down vote up
BuildCard = ({ build }) => {
  const { borderColor, secondaryFontColor } = useCustomColorModes();
  return (
    <Box borderWidth="1px" borderRadius="lg" borderColor={borderColor} overflow="hidden">
      <Box bgColor={borderColor} borderBottom="1px" borderColor={borderColor}>
        <Image src={`${ASSETS_BASE_URL}/${build.image}`} h="200px" mx="auto" />
      </Box>
      <Flex pt={9} pb={4} px={4} direction="column" minH="240px">
        <Text fontWeight="bold">{build.name}</Text>
        <Text color={secondaryFontColor}>{build.desc}</Text>
        <Spacer />
        <ButtonGroup variant="outline" size="sm" spacing="2">
          <Button disabled variant="outline" isFullWidth>
            Fund
          </Button>
          <Button isFullWidth as="a" href={build.branch} target="_blank" rel="noopener noreferrer">
            Fork
          </Button>
        </ButtonGroup>
      </Flex>
    </Box>
  );
}
Example #3
Source File: nav-head.js    From GitMarkonics with MIT License 5 votes vote down vote up
function NavHeader() {
    return ( <
        Box className = "nav_header"
        p = { 1 } >
        <
        Flex direction = "row " >
        <
        img src = { logo }
        alt = "heading"
        width = "80px" / >
        <
        Spacer / >
        <
        Stack direction = "row"
        spacing = { 2 } >
        <
        Link to = "/login" >
        <
        Button leftIcon = { < GrLogin / > }
        colorScheme = "pink"
        variant = "solid" >
        Login <
        /Button> < /
        Link > <
        Link to = "/register" >
        <
        Button colorScheme = "white"
        variant = "outline" >
        Register <
        /Button> < /
        Link > <
        Link to = "/contactus" >
        <
        Button leftIcon = { < GrLogin / > }
        colorScheme = "blue"
        variant = "solid" >
        ContactUs <
        /Button> < /
        Link > <
        /Stack> < /
        Flex > <
        /Box>
    );
}

export default NavHeader;
Example #4
Source File: Header.js    From DAOInsure with MIT License 5 votes vote down vote up
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 #5
Source File: ChallengeStatusTag.jsx    From scaffold-directory with MIT License 5 votes vote down vote up
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 #6
Source File: Vulnerabilities.js    From web-client with Apache License 2.0 5 votes vote down vote up
ProjectVulnerabilities = ({ project }) => {
    const [tableModel, setTableModel] = useState(new VulnerabilityTableModel())

    const navigate = useNavigate();

    const fetchVulnerabilities = useCallback(() => {
        const queryParams = new URLSearchParams();
        queryParams.set('projectId', project.id);
        queryParams.set('isTemplate', false);
        queryParams.set('orderColumn', tableModel.sortBy.column);
        queryParams.set('orderDirection', tableModel.sortBy.order);
        Object.keys(tableModel.filters)
            .forEach(key => tableModel.filters[key] !== null && tableModel.filters[key].length !== 0 && queryParams.append(key, tableModel.filters[key]));
        const url = `/vulnerabilities?${queryParams.toString()}`;
        secureApiFetch(url, { method: 'GET' })
            .then(resp => resp.json())
            .then(data => {
                setTableModel(tableModel => ({ ...tableModel, vulnerabilities: data }));
            })
    }, [tableModel.filters, tableModel.sortBy, project])

    const handleCreateVulnerability = () => {
        navigate(`/vulnerabilities/create?projectId=${project.id}`)
    }

    useEffect(() => {
        fetchVulnerabilities();
    }, [fetchVulnerabilities, tableModel.filters]);

    return <section>
        <Flex>
            <VulnerabilityFilters tableModel={tableModel} tableModelSetter={setTableModel} showProjectFilter={false} />
            <Spacer />
            <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                <CreateButton onClick={handleCreateVulnerability}>Add new vulnerability</CreateButton>
            </RestrictedComponent>
        </Flex>
        <VulnerabilitiesTable tableModel={tableModel} tableModelSetter={setTableModel} reloadCallback={fetchVulnerabilities} showProjectColumn={false} showSelection={false} />
    </section >
}
Example #7
Source File: ClaimsList.js    From DAOInsure with MIT License 4 votes vote down vote up
function ClaimsList({ claims }) {
	let history = useHistory();

	return (
		<VStack alignItems='flex-start' width='100%' spacing={4}>
			{claims.map((claim) => {
				return (
					<VStack
						key={claim[0].toNumber()}
						alignItems='flex-start'
						borderStyle='solid'
						borderWidth='1px'
						borderRadius='10px'
						borderColor='whatsapp.500'
						px={6}
						py={4}
						width='100%'>
						<HStack
							justifyItems='flex-start'
							alignItems='flex-start'
							width='100%'>
							<Box>
								<HStack>
									<Box
										borderStyle='solid'
										borderWidth='2px'
										borderRadius='full'
										borderColor='whatsapp.500'
										padding='2px'>
										<Avatar
											size='sm'
											icon={
												<Jazzicon
													diameter='32'
													address={claim[1]}
												/>
											}
										/>
									</Box>
									<Text>{claim[1]}</Text>
									<Tag
										colorScheme='whatsapp'
										fontWeight='600'>
										? : {claim[4].toNumber()}
									</Tag>
									<Tag
										colorScheme='whatsapp'
										fontWeight='600'>
										? : {claim[5].toNumber()}
									</Tag>
								</HStack>
							</Box>
							<Spacer />
						</HStack>
						<Link
							cursor='pointer'
							to={`/voting/${claim[0].toNumber()}`}>
							<Heading fontSize='20px' textColor='whatsapp.500'>
								{claim[2]}
							</Heading>
						</Link>
						<Text>{claim.claimSummary}</Text>
						<Text fontWeight='600'>{claim.startTime}</Text>
					</VStack>
				);
			})}
		</VStack>
	);
}
Example #8
Source File: InformationCards.js    From DAOInsure with MIT License 4 votes vote down vote up
function InformationCards({
	author,
	loadingClaim,
	dateOfIncident,
	ipfsHash,
	yesVotes,
	noVotes,
	rainData,
	memberData,
}) {
	const voters = [""];

	const [openWeatherStats, setOpenWeatherStats] = useState();

	useEffect(() => {
		async function init() {
			let response = await axios.get(
				"https://api.openweathermap.org/data/2.5/onecall/timemachine?lat=32.21&lon=76.32&exclude=minutely,hourly&appid=162ac7d2a16586444f5b2e968f020e4c&dt=1628319601"
			);
			setOpenWeatherStats(response.data.hourly);
		}
		init();
	}, []);

	return (
		<VStack spacing={5}>
			<Card cardTitle='Information'>
				<HStack width='100%'>
					<Text fontWeight='600'>Author</Text>
					<Spacer />
					{loadingClaim ? (
						<Skeleton isLoaded={!loadingClaim}>Author</Skeleton>
					) : (
						<Text>{`${author.substr(0, 7)}...${author.substr(
							-7
						)}`}</Text>
					)}
				</HStack>
				<HStack width='100%'>
					<Text fontWeight='600'>IPFS</Text>
					<Spacer />
					{loadingClaim ? (
						<Skeleton isLoaded={!loadingClaim}>IPFS hash</Skeleton>
					) : (
						<HStack>
							<a
								href={`https://ipfs.io/ipfs/` + ipfsHash}
								target='_blank'>
								<Text>
									{" "}
									{`${ipfsHash.substr(
										0,
										7
									)}...${ipfsHash.substr(-7)}`}{" "}
								</Text>

								<FaExternalLinkAlt size='10px' />
							</a>
						</HStack>
					)}
				</HStack>
				<HStack width='100%'>
					<Text fontWeight='600'>Member location</Text>
					<Spacer />
					{loadingClaim ? (
						<Skeleton isLoaded={!loadingClaim}>Author</Skeleton>
					) : (
						<a
							target='_blank'
							href={
								`https://www.google.co.in/maps/@` +
								memberData.lat +
								`,` +
								memberData.long
							}>
							Map
						</a>
					)}
				</HStack>
			</Card>
			<Card cardTitle='Time'>
				<VStack width='100%'>
					<HStack width='100%'>
						<Text fontWeight='600'>Date Of Incident</Text>
						<Spacer />
						{loadingClaim ? (
							<Skeleton isLoaded={!loadingClaim}>
								Date Of Incident
							</Skeleton>
						) : (
							<HStack>
								<Text>{dateOfIncident}</Text>
							</HStack>
						)}
					</HStack>
				</VStack>
			</Card>
			<ChainlinkCard cardTitle=''>
				<VStack width='100%'>
					<HStack width='100%'>
						<Text fontWeight='600'>Rain data : </Text>
						<Text fontWeight='600'>{rainData} mm</Text>

						<Spacer />
					</HStack>
				</VStack>
			</ChainlinkCard>
			<Card cardTitle='Current Results'>
				<VStack width='100%'>
					<HStack width='100%'>
						<Text fontWeight='600'>Yes</Text>
						<Spacer />
						{loadingClaim ? (
							<Skeleton>vote percent</Skeleton>
						) : (
							<Text fontWeight='600'>
								{(yesVotes / (yesVotes + noVotes)) * 100
									? (yesVotes / (yesVotes + noVotes)) * 100
									: "0"}
								%
							</Text>
						)}
					</HStack>
					<Progress
						width='100%'
						borderRadius='20px'
						background='gray.300'
						height='10px'
						value={
							loadingClaim
								? 0
								: (yesVotes / (yesVotes + noVotes)) * 100
						}
						colorScheme='green'
						size='lg'
					/>
					<HStack width='100%'>
						<Text fontWeight='600'>No</Text>
						<Spacer />
						{loadingClaim ? (
							<Skeleton>vote percent</Skeleton>
						) : (
							<Text fontWeight='600'>
								{(noVotes / (yesVotes + noVotes)) * 100
									? (noVotes / (yesVotes + noVotes)) * 100
									: "0"}
								%
							</Text>
						)}
					</HStack>
					<Progress
						width='100%'
						borderRadius='20px'
						background='gray.300'
						height='10px'
						value={
							loadingClaim ? 0 : noVotes / (yesVotes + noVotes)
						}
						colorScheme='green'
						size='lg'
					/>
				</VStack>
			</Card>
			<Card cardTitle='OpenWeather Analysis'>
				{openWeatherStats ? (
					<>
						{openWeatherStats.map((stat) => {
							return (
								<HStack width='100%'>
									<Text>
										{new Date(parseInt(stat.dt) * 1000)
											.toTimeString()
											.substr(0, 5)}
									</Text>
									<Text>
										{stat.weather[0].description[0].toUpperCase() +
											stat.weather[0].description.substr(
												1
											)}
									</Text>
									<Spacer />
									<Image
										src={`http://openweathermap.org/img/wn/${stat.weather[0].icon}.png`}
									/>
								</HStack>
							);
						})}
					</>
				) : (
					<Spinner margin='auto' />
				)}
			</Card>

			<Card cardTitle='Votes'>
				<VStack width='100%' alignItems='flex-start'>
					{loadingClaim ? (
						<HStack justifyContent='space-between' width='100%'>
							<HStack>
								<SkeletonCircle />
								<Skeleton>Address that voted</Skeleton>
							</HStack>
							<Skeleton>Vote</Skeleton>
							<Skeleton>Voting Power</Skeleton>
						</HStack>
					) : (
						<>
							{voters.map((voter) => {
								return (
									<HStack
										justifyContent='space-between'
										width='100%'
										key={0}>
										<HStack>
											<Avatar
												size='xs'
												icon={
													<Jazzicon
														diameter='24'
														address='0x8Cf24E66d1DC40345B1bf97219856C8140Ce6c69'
													/>
												}
											/>
											<Tag>{`${"0x8Cf24E66d1DC40345B1bf97219856C8140Ce6c69".substr(
												0,
												6
											)}...${"0x8Cf24E66d1DC40345B1bf97219856C8140Ce6c69".substr(
												-5
											)}`}</Tag>
										</HStack>
										<Tag colorScheme='whatsapp'>Yes</Tag>
										<Text>300 DIx</Text>
									</HStack>
								);
							})}
						</>
					)}
				</VStack>
			</Card>
		</VStack>
	);
}
Example #9
Source File: Profile.js    From DAOInsure with MIT License 4 votes vote down vote up
function Profile() {
	const web3Context = useContext(Web3Context);
	const {
		signerAddress,
		userDaoTokenBalance,
		fetchProposals,
		fetchVotedProposals,
		proposalsArray,
		votedProposalsArray,
	} = web3Context;

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

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

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

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

	return (
		<VStack
			alignItems='flex-start'
			height='calc(100vh - 64px)'
			px='250px'
			py='20px'
			width='100%'>
			<HStack width='100%' alignItems='flex-start'>
				<Box
					borderWidth='2px'
					borderRadius='full'
					borderColor='whatsapp.500'
					padding='2px'>
					<Avatar
						size='md'
						icon={
							<Jazzicon
								diameter='48'
								address={`${signerAddress}`}
							/>
						}
					/>
				</Box>
				<VStack alignItems='flex-start'>
					<Heading fontSize='20px'>{signerAddress}</Heading>
					<Tag>10DAIx / month</Tag>
				</VStack>
				<Spacer />
				<VStack>
					<Tag>INSURE Tokens : {daoTokenBalance}</Tag>
				</VStack>
			</HStack>
			<Grid
				width='100%'
				mt='30px !important'
				templateColumns='3fr 2fr'
				gridGap={5}
				alignItems='flex-start'>
				<Tabs
					colorScheme='whatsapp'
					variant='soft-rounded'
					width='100%'>
					<TabList>
						<Tab onClick={con}>
							Claims{" "}
							<Tag ml={2} borderRadius='20px'>
								{proposalsArray.length}
							</Tag>
						</Tab>
						<Tab>
							Voted For
							<Tag ml={2} borderRadius='20px'>
								{votedProposalsArray.length}
							</Tag>
						</Tab>
					</TabList>
					<TabPanels>
						<TabPanel mt={3} padding={0}>
							<Card cardTitle='Claims'>
								<Table>
									<Tbody>
										{proposalsArray.map(function (
											element,
											id
										) {
											return (
												<Tr key={id}>
													<Th>
														{" "}
														{element[0].toNumber()}{" "}
													</Th>
													<Th>{element[2]}</Th>
													<Th>
														{element[7] ? (
															<span>
																{" "}
																Passed{" "}
															</span>
														) : (
															<span>
																{" "}
																Failed{" "}
															</span>
														)}
													</Th>
												</Tr>
											);
										})}
									</Tbody>
								</Table>
							</Card>
						</TabPanel>
						<TabPanel mt={3} padding={0}>
							<Card cardTitle='Claims'>
								<Table>
									<Tbody>
										{votedProposalsArray.map(function (
											element,
											id
										) {
											return (
												<Tr key={id}>
													<Th>
														{" "}
														{element[0].toNumber()}{" "}
													</Th>
													<Th>{element[2]}</Th>
													<Th>
														{element[7] ? (
															<span>
																{" "}
																Passed{" "}
															</span>
														) : (
															<span>
																{" "}
																Failed{" "}
															</span>
														)}
													</Th>
												</Tr>
											);
										})}
									</Tbody>
								</Table>
							</Card>
						</TabPanel>
					</TabPanels>
				</Tabs>
			</Grid>
		</VStack>
	);
}
Example #10
Source File: index.js    From UpStats with MIT License 4 votes vote down vote up
export default function Home({ status, systems, config }) {
  console.log(status);
  console.log(systems);
  const [email, setEmail] = useState("");
  const toast = useToast();
  const handleSubmit = async (email) => {
    try {
      await http.post("/subs", { email: email });
      toast({
        title: "Success",
        description: "Successfully Subscribed ",
        status: "success",
        duration: 9000,
        isClosable: true,
      });
    } catch (ex) {
      toast({
        title: "Error",
        description: "Submit Unsuccessful",
        status: "error",
        duration: 9000,
        isClosable: true,
      });
    }
  };
  return (
    <>
      <Head>
        <meta charSet="UTF-8" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1, viewport-fit=cover"
        />
        <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
        <link rel="icon" href="/favicon.ico" type="image/x-icon" />
        <title>UP Stats</title>
        <link rel="stylesheet" href="/main.css" />
      </Head>
      <main className="root">
        <header className="top-0">
          <nav>
            <div className="content-center p-4">
              {/* Nav Bar Logo */}
              <img className="nav-brand" src="assets/img/logo.jpg" />
            </div>
          </nav>
        </header>
        <section>
          <Center mt="5">
            <Box bg="blue" w="90%" p={4} color="white" borderRadius="md">
              {status.operational
                ? "All Systems Operational"
                : `${status.outageCount} Systems Outage`}
            </Box>
          </Center>
          <br />
          <VStack>
            {systems.map((system) => (
              <Flex
                id={system._id}
                borderRadius="md"
                boxShadow="lg"
                w="90%"
                p={3}
                bg="white"
              >
                <Text pl={3}>{system.name}</Text>
                <Spacer />
                {system.status === "up" && (
                  <CheckCircleIcon mr={5} mt="1" color="green" />
                )}

                {system.status === "down" && (
                  <WarningIcon mr={5} mt="1" color="red" />
                )}
              </Flex>
            ))}
          </VStack>
        </section>
        {config.mailing ? (
          <VStack p={10} m={10} borderWidth={1} borderRadius="lg">
            <h1 className="font-sans text-xl">Want to see Back in action?</h1>
            <p className="font-sans">
              Subscribe via Email and <br />
              Get notified about the System Status
            </p>
            <Center>
              <FormControl id="email" width="90%">
                <FormLabel>Email address</FormLabel>
                <Input
                  type="email"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                />
                <Box
                  width="8em"
                  mt="3"
                  height="3em"
                  border="1px"
                  color="white"
                  bg="blue"
                  borderRadius="lg"
                  p="3"
                  onClick={() => handleSubmit(email)}
                >
                  <EmailIcon mr={3} />
                  Subscribe
                </Box>
              </FormControl>
            </Center>
          </VStack>
        ) : (
          ""
        )}
        <footer className="px-4 py-16 mx-auto max-w-7xl">
          <nav className="grid grid-cols-2 gap-12 mb-12 md:grid-cols-3 lg:grid-cols-5">
            <div>
              <p className="mb-4 text-sm font-medium text-primary">
                Handy Links
              </p>
              <a
                className="flex mb-3 text-sm font-medium text-gray-700 transition md:mb-2 hover:text-primary"
                href="https://github.com/ToolsHD/UPStats"
              >
                Opensource
              </a>
              <a
                className="flex mb-3 text-sm font-medium text-gray-700 transition md:mb-2 hover:text-primary"
                href="#"
              >
                Features
              </a>
              <a
                className="flex mb-3 text-sm font-medium text-gray-700 transition md:mb-2 hover:text-primary"
                href="#"
              >
                Pricing
              </a>
            </div>
          </nav>
          <div className="flex flex-col items-center justify-between md:flex-row">
            <a href="/" className="mb-4 md:mb-0">
              <img id="footer-img" src="assets/img/footer.jpg" />
              <span className="sr-only">UpStats</span>
            </a>
            <p className="text-sm text-center text-gray-600 md:text-left">
              © 2021 <a href="#">UP Stats</a>
            </p>
          </div>
        </footer>
        <div>
          <button onClick="topFunction()" id="scroll-to-top">
            <svg
              xmlns="http://www.w3.org/2000/svg"
              className="h-6 w-6"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M5 10l7-7m0 0l7 7m-7-7v18"
              />
            </svg>
          </button>
        </div>
      </main>
    </>
  );
}
Example #11
Source File: ChallengeExpandedCard.jsx    From scaffold-directory with MIT License 4 votes vote down vote up
ChallengeExpandedCard = ({ challengeId, challenge, builderAttemptedChallenges }) => {
  const { borderColor, secondaryFontColor } = useCustomColorModes();

  const builderHasCompletedDependenciesChallenges = challenge.dependencies?.every(id => {
    if (!builderAttemptedChallenges[id]) {
      return false;
    }
    if (!(builderAttemptedChallenges[id].status === CHALLENGE_SUBMISSION_STATUS.ACCEPTED)) {
      return false;
    }
    if (challenge.lockedTimestamp) {
      return (
        new Date().getTime() - builderAttemptedChallenges[id].submittedTimestamp > challenge.lockedTimestamp * 60 * 1000
      );
    }

    return true;
  });

  const pendingDependenciesChallenges = challenge.dependencies?.filter(dependency => {
    return (
      !builderAttemptedChallenges[dependency] ||
      builderAttemptedChallenges[dependency].status !== CHALLENGE_SUBMISSION_STATUS.ACCEPTED
    );
  });

  const lockReasonToolTip = "The following challenges are not completed: " + pendingDependenciesChallenges.join(", ");

  const isRampUpChallenge = challenge.dependencies?.length === 0;
  const challengeStatus = builderAttemptedChallenges[challengeId]?.status;

  let colorScheme;
  let label;
  switch (challengeStatus) {
    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
  }

  const isChallengeLocked = challenge.disabled || !builderHasCompletedDependenciesChallenges;

  if (challenge.checkpoint) {
    return (
      <Box bg="#f9f9f9">
        <Flex maxW={500} overflow="hidden" m="0 auto 24px" opacity={isChallengeLocked ? "0.5" : "1"}>
          <Flex pt={6} pb={4} px={4} direction="column" grow={1}>
            <Flex alignItems="center" pb={4} direction="column">
              <Text fontWeight="bold" fontSize="lg" mb={2}>
                {challenge.label}
              </Text>
              <Center borderBottom="1px" borderColor={borderColor} w="200px" flexShrink={0} p={1}>
                <Image src={challenge.previewImage} objectFit="cover" />
              </Center>
            </Flex>
            <Text color={secondaryFontColor} mb={4} textAlign="center">
              {challenge.description}
            </Text>
            <Spacer />
            <ButtonGroup>
              <Button
                as={isChallengeLocked ? Button : Link}
                href={isChallengeLocked ? null : challenge.externalLink?.link}
                isDisabled={isChallengeLocked}
                variant={isChallengeLocked ? "outline" : "solid"}
                isFullWidth
                isExternal
              >
                {builderHasCompletedDependenciesChallenges ? (
                  <chakra.span>{challenge.externalLink.claim}</chakra.span>
                ) : (
                  <>
                    <span role="img" aria-label="lock icon">
                      ?
                    </span>
                    <chakra.span ml={1}>Locked</chakra.span>
                  </>
                )}
              </Button>
              {!builderHasCompletedDependenciesChallenges && (
                <Tooltip label={lockReasonToolTip}>
                  <IconButton icon={<QuestionOutlineIcon />} />
                </Tooltip>
              )}
            </ButtonGroup>
          </Flex>
        </Flex>
      </Box>
    );
  }

  return (
    <Flex maxW={880} borderWidth="1px" borderRadius="lg" borderColor={borderColor} overflow="hidden" mb={6}>
      <Center borderBottom="1px" borderColor={borderColor} w="200px" flexShrink={0} p={1}>
        {challenge.previewImage ? (
          <Image src={challenge.previewImage} objectFit="cover" />
        ) : (
          <Text p={3} textAlign="center">
            {challengeId} image
          </Text>
        )}
      </Center>
      <Flex pt={6} pb={4} px={4} direction="column" grow={1}>
        <Flex justify="space-between" pb={4}>
          <Text fontWeight="bold">{challenge.label}</Text>
          {isRampUpChallenge && challengeStatus && (
            <Badge borderRadius="xl" colorScheme={colorScheme} textTransform="none" py={0.5} px={2.5}>
              {label}
            </Badge>
          )}
        </Flex>
        <Text color={secondaryFontColor} mb={4}>
          {challenge.description}
        </Text>
        <Spacer />
        {challenge.externalLink?.link ? (
          // Redirect to externalLink if set (instead of challenge detail view)
          <ButtonGroup>
            <Button
              as={isChallengeLocked ? Button : Link}
              href={isChallengeLocked ? null : challenge.externalLink?.link}
              isDisabled={isChallengeLocked}
              variant={isChallengeLocked ? "outline" : "solid"}
              isFullWidth
              isExternal
            >
              {builderHasCompletedDependenciesChallenges ? (
                <chakra.span>{challenge.externalLink.claim}</chakra.span>
              ) : (
                <>
                  <span role="img" aria-label="lock icon">
                    ?
                  </span>
                  <chakra.span ml={1}>Locked</chakra.span>
                </>
              )}
            </Button>
            {!builderHasCompletedDependenciesChallenges && (
              <Tooltip label={lockReasonToolTip}>
                <IconButton icon={<QuestionOutlineIcon />} />
              </Tooltip>
            )}
          </ButtonGroup>
        ) : (
          <ButtonGroup>
            <Button
              as={RouteLink}
              to={!isChallengeLocked && `/challenge/${challengeId}`}
              isDisabled={isChallengeLocked}
              variant={isChallengeLocked ? "outline" : "solid"}
              isFullWidth
            >
              {!isChallengeLocked ? (
                <>
                  {" "}
                  <span role="img" aria-label="castle icon">
                    ⚔️
                  </span>
                  <chakra.span ml={1}>Quest</chakra.span>
                </>
              ) : (
                <>
                  <span role="img" aria-label="lock icon">
                    ?
                  </span>
                  <chakra.span ml={1}>Locked</chakra.span>
                </>
              )}
            </Button>
            {!builderHasCompletedDependenciesChallenges && (
              <Tooltip label={lockReasonToolTip}>
                <IconButton icon={<QuestionOutlineIcon />} />
              </Tooltip>
            )}
          </ButtonGroup>
        )}
      </Flex>
    </Flex>
  );
}
Example #12
Source File: Header.jsx    From scaffold-directory with MIT License 4 votes vote down vote up
export default function Header({
  injectedProvider,
  userRole,
  address,
  mainnetProvider,
  userProvider,
  loadWeb3Modal,
  logoutOfWeb3Modal,
  setUserRole,
}) {
  const { secondaryFontColor, borderColor } = useCustomColorModes();
  const primaryColorString = useColorModeValue("var(--chakra-colors-gray-700)", "var(--chakra-colors-gray-200)");
  const isSignerProviderConnected =
    injectedProvider && injectedProvider.getSigner && injectedProvider.getSigner()._isSigner;
  const userIsRegistered = userRole && USER_ROLES.anonymous !== userRole;

  return (
    <Box
      borderBottom="1px"
      borderColor={borderColor}
      mb={10}
      px={{ base: 4, lg: 8 }}
      h={{ base: userIsRegistered ? "120px" : "80px", lg: "80px" }}
    >
      {ENVIRONMENT !== "production" && (
        <Box pos="fixed" p="2px" fontSize={14} w="100%" bgColor="yellow.200" left={0} textAlign="center">
          Working on a {ENVIRONMENT} environment.
        </Box>
      )}
      <Flex
        align={{ base: userIsRegistered ? "start" : "center", lg: "center" }}
        h="full"
        fontWeight="semibold"
        pos="relative"
      >
        <Flex shrink={0} mr={9} mt={{ base: userIsRegistered ? 5 : 0, lg: 0 }}>
          <NavLink to="/" exact>
            <span role="img" aria-label="castle icon">
              ?‍♀️
            </span>{" "}
            <chakra.strong display={{ base: "none", md: "inline-block" }}>SpeedRunEthereum.com</chakra.strong>
            <chakra.strong display={{ base: "inline-block", md: "none" }}>
              {isSignerProviderConnected ? "SRE" : "SpeedRunEthereum.com"}
            </chakra.strong>
          </NavLink>
        </Flex>
        <HStack
          as="ul"
          mr={{ base: 0, lg: 6 }}
          style={{ listStyle: "none" }}
          spacing={{ base: 6, lg: 9 }}
          pos={{ base: "absolute", lg: "static" }}
          justifyContent={{ base: "center", lg: "left" }}
          top="80px"
          left={0}
        >
          {userRole && USER_ROLES.anonymous !== userRole && (
            <chakra.li key="/portfolio" color={secondaryFontColor} _hover={{ color: primaryColorString }}>
              <NavLink
                to="/portfolio"
                isActive={(match, location) => location.pathname.includes("/builders/")}
                activeStyle={{
                  color: primaryColorString,
                }}
              >
                Portfolio
              </NavLink>
            </chakra.li>
          )}
          {/* ToDo. At least Builder */}
          {(USER_ROLES.builder === userRole || USER_ROLES.admin === userRole) && (
            <>
              <chakra.li key="/builders" color={secondaryFontColor} _hover={{ color: primaryColorString }}>
                <NavLink
                  to="/builders"
                  exact
                  activeStyle={{
                    color: primaryColorString,
                  }}
                >
                  Builders
                </NavLink>
              </chakra.li>
            </>
          )}
          {USER_ROLES.admin === userRole && (
            <>
              <chakra.li key="/submission-review" color={secondaryFontColor} _hover={{ color: primaryColorString }}>
                <NavLink
                  to="/submission-review"
                  exact
                  activeStyle={{
                    color: primaryColorString,
                  }}
                >
                  Review Submissions
                </NavLink>
              </chakra.li>
              <chakra.li key="/activity" color={secondaryFontColor} _hover={{ color: primaryColorString }}>
                <NavLink
                  to="/activity"
                  exact
                  activeStyle={{
                    color: primaryColorString,
                  }}
                >
                  Activity
                </NavLink>
              </chakra.li>
            </>
          )}
        </HStack>
        <Spacer />
        <Box mt={{ base: userIsRegistered ? 3 : 0, lg: 0 }}>
          <Account
            address={address}
            connectText="Connect Wallet"
            ensProvider={mainnetProvider}
            isWalletConnected={isSignerProviderConnected}
            loadWeb3Modal={loadWeb3Modal}
            logoutOfWeb3Modal={() => {
              logoutOfWeb3Modal();
              setUserRole(null);
            }}
            setUserRole={setUserRole}
            userProvider={userProvider}
            userRole={userRole}
          />
        </Box>
      </Flex>
    </Box>
  );
}
Example #13
Source File: BuilderProfileView.jsx    From scaffold-directory with MIT License 4 votes vote down vote up
export default function BuilderProfileView({ serverUrl, mainnetProvider, address, userProvider, userRole }) {
  const { builderAddress } = useParams();
  const { primaryFontColor, secondaryFontColor, borderColor, iconBgColor } = useCustomColorModes();
  const [builder, setBuilder] = useState();
  const [challengeEvents, setChallengeEvents] = useState([]);
  const [isLoadingBuilder, setIsLoadingBuilder] = useState(false);
  const [isBuilderOnBg, setIsBuilderOnBg] = useState(false);
  const [isLoadingTimestamps, setIsLoadingTimestamps] = useState(false);
  const toast = useToast({ position: "top", isClosable: true });
  const toastVariant = useColorModeValue("subtle", "solid");
  const challenges = builder?.challenges ? Object.entries(builder.challenges) : undefined;
  const acceptedChallenges = getAcceptedChallenges(builder?.challenges);
  const isMyProfile = builderAddress === address;

  const fetchBuilder = async () => {
    setIsLoadingBuilder(true);
    const fetchedBuilder = await axios.get(serverUrl + `/builders/${builderAddress}`);
    setBuilder(fetchedBuilder.data);

    try {
      await axios.get(bgBackendUrl + `/builders/${builderAddress}`);
    } catch (e) {
      // Builder Not found in BG
      setIsLoadingBuilder(false);
      return;
    }

    setIsBuilderOnBg(true);
    setIsLoadingBuilder(false);
  };

  useEffect(() => {
    fetchBuilder();
    // eslint-disable-next-line
  }, [builderAddress]);

  useEffect(() => {
    if (!builderAddress) {
      return;
    }

    async function fetchChallengeEvents() {
      setIsLoadingTimestamps(true);
      try {
        const fetchedChallengeEvents = await getChallengeEventsForUser(builderAddress);
        setChallengeEvents(fetchedChallengeEvents.sort(byTimestamp).reverse());
        setIsLoadingTimestamps(false);
      } catch (error) {
        toast({
          description: "Can't get challenges metadata. Please try again",
          status: "error",
          variant: toastVariant,
        });
      }
    }
    fetchChallengeEvents();
    // eslint-disable-next-line
  }, [builderAddress]);

  return (
    <Container maxW="container.xl">
      <SimpleGrid gap={14} columns={{ base: 1, xl: 4 }}>
        <GridItem colSpan={1}>
          <BuilderProfileCard
            builder={builder}
            mainnetProvider={mainnetProvider}
            isMyProfile={isMyProfile}
            userProvider={userProvider}
            fetchBuilder={fetchBuilder}
            userRole={userRole}
          />
        </GridItem>
        {isBuilderOnBg ? (
          <GridItem colSpan={{ base: 1, xl: 3 }}>
            <Box borderColor={borderColor} borderWidth={1} p={5}>
              <Flex direction="column" align="center" justify="center">
                <Image src="/assets/bg.png" mb={3} />
                <Text mb={3} fontSize="lg" fontWeight="bold">
                  This builder has upgraded to BuidlGuidl.
                </Text>
                <Button as={Link} href={`${BG_FRONTEND_URL}/builders/${builderAddress}`} isExternal colorScheme="blue">
                  View their profile on Buidlguidl
                </Button>
              </Flex>
            </Box>
          </GridItem>
        ) : (
          <GridItem colSpan={{ base: 1, xl: 3 }}>
            <HStack spacing={4} mb={8}>
              <Flex borderRadius="lg" borderColor={borderColor} borderWidth={1} p={4} w="full" justify="space-between">
                <Flex bg={iconBgColor} borderRadius="lg" w={12} h={12} justify="center" align="center">
                  <InfoOutlineIcon w={5} h={5} />
                </Flex>
                <div>
                  <Text fontSize="xl" fontWeight="medium" textAlign="right">
                    {acceptedChallenges.length}
                  </Text>
                  <Text fontSize="sm" color={secondaryFontColor} textAlign="right">
                    challenges completed
                  </Text>
                </div>
              </Flex>
              <Flex borderRadius="lg" borderColor={borderColor} borderWidth={1} p={4} w="full" justify="space-between">
                <Flex bg={iconBgColor} borderRadius="lg" w={12} h={12} justify="center" align="center">
                  <InfoOutlineIcon w={5} h={5} />
                </Flex>
                <div>
                  <Text fontSize="xl" fontWeight="medium" textAlign="right">
                    {builder?.function ? (
                      <Tag colorScheme={userFunctionDescription[builder?.function].colorScheme} variant="solid">
                        {userFunctionDescription[builder?.function].label}
                      </Tag>
                    ) : (
                      "-"
                    )}
                  </Text>
                  <Text fontSize="sm" color={secondaryFontColor} textAlign="right">
                    Role
                  </Text>
                </div>
              </Flex>
            </HStack>
            <Flex mb={4}>
              <Text fontSize="2xl" fontWeight="bold">
                Challenges
              </Text>
              <Spacer />
            </Flex>
            {isLoadingBuilder && <BuilderProfileChallengesTableSkeleton />}
            {!isLoadingBuilder &&
              (challenges ? (
                <Box overflowX="auto">
                  <Table>
                    {isMyProfile && (
                      <TableCaption>
                        <Button as={RouteLink} colorScheme="blue" to="/">
                          Start a challenge
                        </Button>
                      </TableCaption>
                    )}
                    <Thead>
                      <Tr>
                        <Th>Name</Th>
                        <Th>Contract</Th>
                        <Th>Live Demo</Th>
                        <Th>Updated</Th>
                        <Th>Status</Th>
                      </Tr>
                    </Thead>
                    <Tbody>
                      {challenges.map(([challengeId, lastSubmission]) => {
                        if (!challengeInfo[challengeId]) {
                          return null;
                        }
                        const lastEventForChallenge = challengeEvents.filter(
                          event => event.payload.challengeId === challengeId,
                        )[0];
                        return (
                          <Tr key={challengeId}>
                            <Td>
                              <Link as={RouteLink} to={`/challenge/${challengeId}`} fontWeight="700" color="teal.500">
                                {challengeInfo[challengeId].label}
                              </Link>
                            </Td>
                            <Td>
                              <Link
                                // Legacy branchUrl
                                href={lastSubmission.contractUrl || lastSubmission.branchUrl}
                                color="teal.500"
                                target="_blank"
                                rel="noopener noreferrer"
                              >
                                Code
                              </Link>
                            </Td>
                            <Td>
                              <Link
                                href={lastSubmission.deployedUrl}
                                color="teal.500"
                                target="_blank"
                                rel="noopener noreferrer"
                              >
                                Demo
                              </Link>
                            </Td>
                            <Td>
                              {isLoadingTimestamps ? (
                                <SkeletonText noOfLines={1} />
                              ) : (
                                <DateWithTooltip timestamp={lastEventForChallenge?.timestamp} />
                              )}
                            </Td>
                            <Td>
                              <ChallengeStatusTag
                                status={lastSubmission.status}
                                comment={lastSubmission.reviewComment}
                                autograding={lastSubmission.autograding}
                              />
                            </Td>
                          </Tr>
                        );
                      })}
                    </Tbody>
                  </Table>
                </Box>
              ) : (
                <Flex
                  justify="center"
                  align="center"
                  borderRadius="lg"
                  borderColor={borderColor}
                  borderWidth={1}
                  py={36}
                  w="full"
                >
                  {isMyProfile ? (
                    <Box maxW="xs" textAlign="center">
                      <Text fontWeight="medium" color={primaryFontColor} mb={2}>
                        Start a new challenge
                      </Text>
                      <Text color={secondaryFontColor} mb={4}>
                        Show off your skills. Learn everything you need to build on Ethereum!
                      </Text>
                      <Button as={RouteLink} colorScheme="blue" to="/">
                        Start a challenge
                      </Button>
                    </Box>
                  ) : (
                    <Box maxW="xs" textAlign="center">
                      <Text color={secondaryFontColor} mb={4}>
                        This builder hasn't completed any challenges.
                      </Text>
                    </Box>
                  )}
                </Flex>
              ))}
          </GridItem>
        )}
      </SimpleGrid>
    </Container>
  );
}