@chakra-ui/react#ModalFooter JavaScript Examples

The following examples show how to use @chakra-ui/react#ModalFooter. 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: AddModalDialog.js    From web-client with Apache License 2.0 7 votes vote down vote up
VulnerabilityCategoryAddModalDialog = ({ isOpen, onClose, onCancel }) => {
    const emptyCategory = { name: '', description: '' };
    const [newCategory, updateNewCategory] = useState(emptyCategory);

    const onCreateCategoryFormSubmit = ev => {
        if (!document.getElementById('vulnerability_category_form').checkValidity()) {
            return false;
        }

        ev.preventDefault();

        secureApiFetch(`/vulnerabilities/categories`, {
            method: 'POST',
            body: JSON.stringify(newCategory)
        }).then(() => {
            onClose();
            actionCompletedToast(`The vulnerability category has been created.`);
        })
            .finally(() => {
                updateNewCategory(emptyCategory)
            })
    }

    return <Modal size="xl" isOpen={isOpen} onClose={onCancel}>
        <ModalOverlay />
        <ModalContent>
            <ModalHeader>New vulnerability category details</ModalHeader>
            <ModalCloseButton />
            <ModalBody>
                <VulnerabilityCategoryForm category={newCategory} onFormSubmit={onCreateCategoryFormSubmit} categorySetter={updateNewCategory} />
            </ModalBody>

            <ModalFooter>
                <Button onClick={onCancel} mr={3}>Cancel</Button>
                <Button type="submit" form="vulnerability_category_form" colorScheme="blue" onClick={onCreateCategoryFormSubmit}>Save</Button>
            </ModalFooter>
        </ModalContent>
    </Modal>
}
Example #2
Source File: components.js    From idena-web with MIT License 6 votes vote down vote up
export function DialogFooter({children, ...props}) {
  return (
    <ModalFooter p={0} {...props}>
      <Stack isInline spacing={2} justify="flex-end" w={['100%', 'auto']}>
        {children}
      </Stack>
    </ModalFooter>
  )
}
Example #3
Source File: ModalDialog.js    From web-client with Apache License 2.0 6 votes vote down vote up
TargetModalDialog = ({ project, isOpen, onSubmit, onCancel }) => {
    const emptyTarget = { project_id: project.id, name: null, kind: TargetKinds[0].value };
    const [target, setTarget] = useState(emptyTarget)

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

        secureApiFetch(`/targets`, { method: 'POST', body: JSON.stringify(target) })
            .then(() => {
                onSubmit();
                actionCompletedToast(`The target "${target.name}" has been added.`);
            })
            .catch(err => {
                errorToast(err);
            })
            .finally(() => {
                setTarget(emptyTarget)
            })
    }

    return <Modal size="xl" isOpen={isOpen} onClose={onCancel}>
        <ModalOverlay />
        <ModalContent>
            <ModalHeader><HStack><TargetIcon style={{ width: '24px' }} /> <h4>New target details</h4></HStack></ModalHeader>
            <ModalCloseButton />
            <ModalBody>
                <TargetForm newTarget={target} onFormSubmit={onAddTargetFormSubmit} targetSetter={setTarget} />
            </ModalBody>

            <ModalFooter>
                <Button onClick={onCancel} mr={3}>Cancel</Button>
                <Button colorScheme="blue" onClick={onAddTargetFormSubmit}>Save</Button>
            </ModalFooter>
        </ModalContent>
    </Modal>
}
Example #4
Source File: EditModalDialog.js    From web-client with Apache License 2.0 6 votes vote down vote up
VulnerabilityCategoryEditModalDialog = ({ category, isOpen, onClose, onCancel }) => {
    const [newCategory, updateNewCategory] = useState(category);

    const onCreateCategoryFormSubmit = ev => {
        if (!document.getElementById('vulnerability_category_form').checkValidity()) {
            return false;
        }

        ev.preventDefault();

        secureApiFetch(`/vulnerabilities/categories/${category.id}`, {
            method: 'PUT',
            body: JSON.stringify(newCategory)
        }).then(() => {
            onClose();
            actionCompletedToast(`The vulnerability category has been updated.`);
        })
            .finally(() => {
            })
    }

    return <Modal size="xl" isOpen={isOpen} onClose={onCancel}>
        <ModalOverlay />
        <ModalContent>
            <ModalHeader>Vulnerability category details</ModalHeader>
            <ModalCloseButton />
            <ModalBody>
                <VulnerabilityCategoryForm category={newCategory} onFormSubmit={onCreateCategoryFormSubmit} categorySetter={updateNewCategory} />
            </ModalBody>

            <ModalFooter>
                <Button onClick={onCancel} mr={3}>Cancel</Button>
                <Button type="submit" form="vulnerability_category_form" colorScheme="blue" onClick={onCreateCategoryFormSubmit}>Save</Button>
            </ModalFooter>
        </ModalContent>
    </Modal>
}
Example #5
Source File: Toolbar.js    From sided.news.web with MIT License 5 votes vote down vote up
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 #6
Source File: ModalDialog.js    From web-client with Apache License 2.0 5 votes vote down vote up
NoteModalDialog = ({ parentType, parent, isOpen, onClose, onCancel }) => {
    const emptyNote = { ...NoteModel, parent_type: parentType, parent_id: parent.id }
    const [newNote, updateNewNote] = useState(emptyNote)

    const beforeCancelCallback = ev => {
        updateNewNote(emptyNote)
        onCancel(ev);
    }

    const onCreateNoteFormSubmit = async (ev) => {
        ev.preventDefault();

        await secureApiFetch(`/notes`, {
            method: 'POST',
            body: JSON.stringify(newNote)
        }).then(() => {
            onClose();
            actionCompletedToast(`The note has been created.`);
        })
            .finally(() => {
                updateNewNote(emptyNote)
            })
    }

    return <Modal size="xl" isOpen={isOpen} onClose={beforeCancelCallback}>
        <ModalOverlay />
        <ModalContent>
            <ModalHeader>New notes details</ModalHeader>
            <ModalCloseButton />
            <ModalBody>
                <NotesForm note={newNote} onFormSubmit={onCreateNoteFormSubmit} noteSetter={updateNewNote} />
            </ModalBody>

            <ModalFooter>
                <Button onClick={beforeCancelCallback} mr={3}>Cancel</Button>
                <Button colorScheme="blue" onClick={onCreateNoteFormSubmit}>Save</Button>
            </ModalFooter>
        </ModalContent>
    </Modal>
}
Example #7
Source File: ModalDialog.js    From web-client with Apache License 2.0 5 votes vote down vote up
ReportModalDialog = ({ isOpen, onSubmit, onCancel }) => {
    const fileRef = useRef();

    const emptyReportTemplate = {
        version_name: "",
        version_description: null,
        resultFile: null,
    }
    const [reportTemplate, setReportTemplate] = useState(emptyReportTemplate)

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

        const formData = new FormData();
        formData.append('version_name', reportTemplate.version_name);
        formData.append('version_description', reportTemplate.version_description);
        formData.append('resultFile', fileRef.current.files[0]);

        secureApiFetch(`/reports/templates`, { method: 'POST', body: formData })
            .then(() => {
                onSubmit();
                actionCompletedToast(`The report template "${reportTemplate.version_name}" has been added.`);
            })
            .catch(err => {
                errorToast(err);
            })
            .finally(() => {
                setReportTemplate(emptyReportTemplate)
            })
    }

    const onFormChange = ev => {
        setReportTemplate({ ...reportTemplate, [ev.target.name]: ev.target.value })
    }

    return <Modal size="xl" isOpen={isOpen} onClose={onCancel}>
        <ModalOverlay />
        <ModalContent>
            <ModalHeader><h4>New report template details</h4></ModalHeader>
            <ModalCloseButton />
            <ModalBody>
                <form id="reportTemplateForm" onSubmit={onCreateReportFormSubmit}>
                    <FormControl isRequired>
                        <FormLabel>Version name</FormLabel>
                        <Input type="text" name="version_name" onChange={onFormChange} autoFocus />
                    </FormControl>
                    <FormControl>
                        <FormLabel>Version description</FormLabel>
                        <Input type="text" name="version_description" onChange={onFormChange} />
                    </FormControl>
                    <FormControl isRequired>
                        <FormLabel>File</FormLabel>
                        <Input type="file" ref={fileRef} name="resultFile" onChange={onFormChange} />
                    </FormControl>
                </form>
            </ModalBody>

            <ModalFooter>
                <Button onClick={onCancel} mr={3}>Cancel</Button>
                <Button form="reportTemplateForm" type="submit" colorScheme="blue">Save</Button>
            </ModalFooter>
        </ModalContent>
    </Modal>
}
Example #8
Source File: about.js    From handsign-tensorflow with BSD 2-Clause "Simplified" License 5 votes vote down vote up
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 #9
Source File: Todos.jsx    From fastapi-react with MIT License 5 votes vote down vote up
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 #10
Source File: BecomeMember.js    From DAOInsure with MIT License 4 votes vote down vote up
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 #11
Source File: Todo.js    From benjamincarlson.io with MIT License 4 votes vote down vote up
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 #12
Source File: ChallengeReviewRow.jsx    From scaffold-directory with MIT License 4 votes vote down vote up
export default function ChallengeReviewRow({ challenge, isLoading, approveClick, rejectClick, userProvider }) {
  const [comment, setComment] = useState(challenge.reviewComment ?? "");
  const [testPassed, setTestPassed] = useState(null);
  const [isRunningTests, setIsRunningTests] = useState(false);
  const { isOpen, onOpen, onClose } = useDisclosure();
  const address = useUserAddress(userProvider);

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

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

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

      setIsRunningTests(true);
      setTestPassed(null);

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

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

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

  const submittedMoment = moment(challenge.submittedTimestamp);

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

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

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

        setFormValues({ ...formValues, [ev.target.name]: ev.target.value });
    };

    const beforeCancelCallback = ev => {
        setFormValues(defaultFormValues);
        onCancel(ev);
    }

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

        const params = {
            projectId: projectId,
            reportTemplateId: formValues.reportTemplateId,
            name: formValues.name,
            description: formValues.description
        };

        secureApiFetch(`/reports`, { method: 'POST', body: JSON.stringify(params) })
            .then(() => {
                onSubmit();
                actionCompletedToast(`The report version "${formValues.name}" has been added.`);
            })
            .catch(err => {
                console.error(err);
            })
            .finally(() => {
                setFormValues(defaultFormValues)
            })
    }

    useEffect(() => {
        if (templates !== null && templates.length > 0) {
            setFormValues((prev) => ({ ...prev, reportTemplateId: templates[0].id }))
        }
    }, [templates]);

    return <Modal size="xl" isOpen={isOpen} onClose={beforeCancelCallback}>
        <ModalOverlay />
        <ModalContent>
            <ModalHeader><HStack><TargetIcon style={{ width: '24px' }} /> <h4>New report version details</h4></HStack></ModalHeader>
            <ModalCloseButton />
            <ModalBody>
                <form id="reportVersionReportForm" onSubmit={onFormSubmit} className="crud" style={{ marginTop: '20px' }}>
                    <FormControl isRequired>
                        <FormLabel>Template</FormLabel>
                        {templates && <Select name="reportTemplateId" value={formValues.reportTemplateId} onChange={onFormValueChange}>
                            {templates.map(template => <option key={template.id} value={template.id}>{template.version_name}</option>)}
                        </Select>}
                    </FormControl>

                    <FormControl isRequired>
                        <FormLabel>Name</FormLabel>
                        <Input type="text" name="name" value={formValues.name} onChange={onFormValueChange}
                            placeholder="eg 1.0, 202103" autoFocus />
                    </FormControl>

                    <FormControl isRequired>
                        <FormLabel>Description</FormLabel>
                        <Input type="text" name="description" value={formValues.description}
                            onChange={onFormValueChange}
                            placeholder="eg Initial version, Draft"
                        />
                    </FormControl>
                </form>
            </ModalBody>

            <ModalFooter>
                <Button onClick={beforeCancelCallback} mr={3}>Cancel</Button>
                <Button form="reportVersionReportForm" type="submit" colorScheme="blue">Save</Button>
            </ModalFooter>
        </ModalContent>
    </Modal>
}