@chakra-ui/react#ModalOverlay TypeScript Examples
The following examples show how to use
@chakra-ui/react#ModalOverlay.
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: receiving-call-modal.tsx From video-chat with MIT License | 6 votes |
export function ReceivingCallOverlay(props: Props){
if (!props.calling) return <></>
return(
<Modal isOpen={props.calling} isCentered onClose={() => {}}>
<ModalOverlay>
<ModalContent
p="16"
backgroundColor="gray.800"
alignItems="center"
justifyContent="center"
display="flex"
flexDirection="column"
>
<ModalHeader color="white">{props.caller} is calling you</ModalHeader>
<ModalBody display="flex" alignItems="center" justifyContent="space-evenly" w="full">
<Button colorScheme="green" onClick={props.answer}>Answer call</Button>
<Button colorScheme="red" onClick={props.refuse}>Refuse call</Button>
</ModalBody>
</ModalContent>
</ModalOverlay>
</Modal>
)
}
Example #2
Source File: index.tsx From calories-in with MIT License | 6 votes |
function VariantNameModal({ onClose, isOpen, variantFormIndex }: Props) {
const initialRef = useRef<HTMLInputElement>(null)
const finalFocusRef = useRef(null)
return (
<Modal
isOpen={isOpen}
preserveScrollBarGap={true}
onClose={onClose}
initialFocusRef={initialRef}
finalFocusRef={finalFocusRef}
size="sm"
>
<ModalOverlay />
<VariantNameFormProvider variantFormIndex={variantFormIndex}>
<Content
title="Rename Day"
onClose={onClose}
initialRef={initialRef}
variantFormIndex={variantFormIndex}
/>
</VariantNameFormProvider>
</Modal>
)
}
Example #3
Source File: index.tsx From calories-in with MIT License | 6 votes |
function VariantsDetailsModal({ onClose, isOpen, initialVariantForm }: Props) {
return (
<Modal
isOpen={isOpen}
preserveScrollBarGap={true}
onClose={onClose}
scrollBehavior="inside"
size="md"
>
<ModalOverlay />
<Content onClose={onClose} initialVariantForm={initialVariantForm} />
</Modal>
)
}
Example #4
Source File: index.tsx From calories-in with MIT License | 6 votes |
function EditNotesModal({
onClose,
isOpen,
notes,
onEditNotes,
fieldId,
ownerName,
textAreaHeight,
...rest
}: Props) {
const initialRef = useRef<HTMLInputElement>(null)
const finalFocusRef = useRef(null)
return (
<Modal
isOpen={isOpen}
preserveScrollBarGap={true}
onClose={onClose}
initialFocusRef={initialRef}
finalFocusRef={finalFocusRef}
{...rest}
>
<ModalOverlay />
<Content
onClose={onClose}
onEditNotes={onEditNotes}
initialRef={initialRef}
fieldId={fieldId}
notes={notes}
ownerName={ownerName}
textAreaHeight={textAreaHeight}
/>
</Modal>
)
}
Example #5
Source File: Modal.tsx From calories-in with MIT License | 6 votes |
function Modal({ isOpen, onClose }: Props) {
const selectRef = useRef<HTMLSelectElement>(null)
return (
<ModalBase isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Filters</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Content selectRef={selectRef} />
</ModalBody>
<ModalFooter>
<Footer onClose={onClose} />
</ModalFooter>
</ModalContent>
</ModalBase>
)
}
Example #6
Source File: MissingFoodsModal.tsx From calories-in with MIT License | 6 votes |
function MissingFoodsModal({ isOpen, onClose, onImport }: Props) {
return (
<Modal isOpen={isOpen} onClose={onClose} size="md" isCentered>
<ModalOverlay />
<ModalContent>
<ModalHeader>Missing foods</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text fontWeight="medium">
The meal plan you contains foods that are not part of your list.
</Text>
<br />
<Text>
You can try to import the missing foods or continue without them.
</Text>
</ModalBody>
<ModalFooter>
<Button onClick={onClose} mr={3}>
Continue
</Button>
<Button
variant="solid"
colorScheme="teal"
onClick={() => {
onImport()
onClose()
}}
>
Import foods
</Button>
</ModalFooter>
</ModalContent>
</Modal>
)
}
Example #7
Source File: index.tsx From calories-in with MIT License | 6 votes |
function FoodModal({
onClose,
isOpen,
food,
onFoodCreatedOrUpdated,
onFoodDeleted,
}: Props) {
const nameInputRef = useRef<HTMLInputElement>(null)
const title = food ? 'Food Details' : 'Create Food'
return (
<Modal
isOpen={isOpen}
preserveScrollBarGap={true}
initialFocusRef={!food ? nameInputRef : undefined}
onClose={onClose}
scrollBehavior="inside"
size={food ? 'md' : 'lg'}
>
<ModalOverlay />
<Content
nameInputRef={nameInputRef}
onClose={onClose}
title={title}
food={food}
onFoodCreatedOrUpdated={onFoodCreatedOrUpdated}
onFoodDeleted={onFoodDeleted}
/>
</Modal>
)
}
Example #8
Source File: DeleteConfirmationModal.tsx From calories-in with MIT License | 6 votes |
function DeleteConfirmationModal({
isOpen,
onCancel,
onConfirm,
text,
confirmButtonLabel,
}: Props) {
return (
<Modal isOpen={isOpen} onClose={onCancel} size="xs" isCentered>
<ModalOverlay />
<ModalContent>
<ModalHeader>Delete food</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text>{text}</Text>
<br />
<Text fontWeight="medium">This action cannot be undone.</Text>
</ModalBody>
<ModalFooter>
<Button variant="outline" onClick={onCancel}>
Cancel
</Button>
<Button colorScheme="red" ml={3} onClick={onConfirm}>
{confirmButtonLabel}
</Button>
</ModalFooter>
</ModalContent>
</Modal>
)
}
Example #9
Source File: index.tsx From rari-dApp with GNU Affero General Public License v3.0 | 6 votes |
DepositModal = (props: Props) => {
return (
<Modal
motionPreset="slideInBottom"
isOpen={props.isOpen}
onClose={props.onClose}
isCentered
>
<ModalOverlay />
<ModalContent
{...MODAL_PROPS}
height={{
md: requiresSFIStaking(props.trancheRating) ? "380px" : "295px",
base: requiresSFIStaking(props.trancheRating) ? "390px" : "310px",
}}
>
<AmountSelect
onClose={props.onClose}
tranchePool={props.tranchePool}
trancheRating={props.trancheRating}
/>
</ModalContent>
</Modal>
);
}
Example #10
Source File: index.tsx From rari-dApp with GNU Affero General Public License v3.0 | 6 votes |
DepositModal = (props: Props) => {
const [currentScreen, setCurrentScreen] = useState(CurrentScreen.MAIN);
const [mode, setMode] = useState(Mode.DEPOSIT);
return (
<Modal
motionPreset="slideInBottom"
isOpen={props.isOpen}
onClose={props.onClose}
isCentered
>
<ModalOverlay />
<ModalContent {...MODAL_PROPS} height="300px">
{currentScreen === CurrentScreen.MAIN ? (
<AmountSelect
onClose={props.onClose}
openOptions={() => setCurrentScreen(CurrentScreen.OPTIONS)}
mode={mode}
/>
) : (
<OptionsMenu
onClose={() => setCurrentScreen(CurrentScreen.MAIN)}
onSetMode={setMode}
mode={mode}
/>
)}
</ModalContent>
</Modal>
);
}
Example #11
Source File: index.tsx From rari-dApp with GNU Affero General Public License v3.0 | 6 votes |
DepositModal = (props: Props) => {
const [mode, setMode] = useState(props.defaultMode);
useEffect(() => {
setMode(props.defaultMode);
}, [props.isOpen, props.defaultMode]);
return (
<Modal
motionPreset="slideInBottom"
isOpen={props.isOpen}
onClose={props.onClose}
isCentered
>
<ModalOverlay />
<ModalContent {...MODAL_PROPS}>
<AmountSelect
comptrollerAddress={props.comptrollerAddress}
onClose={props.onClose}
assets={props.assets}
index={props.index}
mode={mode}
setMode={setMode}
isBorrowPaused={props.isBorrowPaused}
/>
</ModalContent>
</Modal>
);
}
Example #12
Source File: note-modal.tsx From notebook with MIT License | 6 votes |
NoteModal: React.SFC<NoteFormProps> = ({
isOpen,
onClose,
selectedNote
}) => {
return (
<AnimatePresence>
<motion.div layoutId={selectedNote?.id}>
<Modal
isOpen={isOpen}
onClose={onClose}
scrollBehavior={"inside"}
isCentered
motionPreset="slideInBottom"
>
<ModalOverlay />
<ModalContent>
<motion.div>
<ModalHeader isTruncated paddingRight="10">
{selectedNote?.title}
</ModalHeader>
</motion.div>
<ModalCloseButton />
<motion.div>
<ModalBody pb={6}>{selectedNote?.body}</ModalBody>
</motion.div>
</ModalContent>
</Modal>
</motion.div>
</AnimatePresence>
);
}
Example #13
Source File: loading-overlay.tsx From video-chat with MIT License | 5 votes |
export function LoadingOverlay(props: Props) {
if (!props.loading) return <></>;
return (
<Modal isOpen={props.loading} isCentered onClose={() => {}}>
<ModalOverlay>
<ModalContent
p="16"
backgroundColor="gray.800"
flexDirection="row"
justifyContent="space-between"
alignItems="center"
>
<Text color="purple.600" fontWeight="bold" fontSize="2rem">Calling</Text>
<motion.div
style={loadingContainer}
variants={loadingContainerVariants}
initial="start"
animate="end"
>
<motion.span
style={loadingCircle}
variants={loadingCircleVariants}
transition={loadingCircleTransition}
/>
<motion.span
style={loadingCircle}
variants={loadingCircleVariants}
transition={loadingCircleTransition}
/>
<motion.span
style={loadingCircle}
variants={loadingCircleVariants}
transition={loadingCircleTransition}
/>
</motion.div>
</ModalContent>
</ModalOverlay>
</Modal>
);
}
Example #14
Source File: index.tsx From rari-dApp with GNU Affero General Public License v3.0 | 5 votes |
DepositModal = (props: Props) => {
const [mode, setMode] = useState(Mode.DEPOSIT);
const [currentScreen, setCurrentScreen] = useState(CurrentScreen.MAIN);
useEffect(() => {
// When the modal closes return to the main screen.
if (!props.isOpen) {
setCurrentScreen(CurrentScreen.MAIN);
}
}, [props.isOpen]);
const poolType = usePoolType();
const [selectedToken, setSelectedToken] = useState(() => {
if (poolType === Pool.ETH) {
return "ETH";
} else {
return "USDC";
}
});
return (
<Modal
motionPreset="slideInBottom"
isOpen={props.isOpen}
onClose={props.onClose}
isCentered
>
<ModalOverlay />
<ModalContent
{...MODAL_PROPS}
height={{
md: poolHasDivergenceRisk(poolType) ? "320px" : "295px",
base: poolHasDivergenceRisk(poolType) ? "350px" : "310px",
}}
>
{currentScreen === CurrentScreen.MAIN ? (
<AmountSelect
onClose={props.onClose}
openCoinSelect={() => setCurrentScreen(CurrentScreen.COIN_SELECT)}
openOptions={() => setCurrentScreen(CurrentScreen.OPTIONS)}
selectedToken={selectedToken}
mode={mode}
/>
) : currentScreen === CurrentScreen.COIN_SELECT ? (
<TokenSelect
onClose={() => setCurrentScreen(CurrentScreen.MAIN)}
onSelectToken={setSelectedToken}
mode={mode}
/>
) : (
<OptionsMenu
onClose={() => setCurrentScreen(CurrentScreen.MAIN)}
onSetMode={setMode}
mode={mode}
/>
)}
</ModalContent>
</Modal>
);
}
Example #15
Source File: ClaimRGTModal.tsx From rari-dApp with GNU Affero General Public License v3.0 | 5 votes |
ClaimRGTModal = ({
isOpen,
onClose,
defaultMode,
}: {
isOpen: boolean;
onClose: () => any;
defaultMode?: ClaimMode;
}) => {
const { t } = useTranslation();
const [amount, setAmount] = useState(0);
const { fuse } = useRari();
// pool2
// private
// yieldagg
const [showPrivate, setShowPrivate] = useState<boolean>(true);
// If user presses meta key or control key + slash they will toggle the private allocation claim mode.
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if ((e.metaKey || e.ctrlKey) && e.code === "Slash") {
e.preventDefault();
setShowPrivate(true);
}
};
document.addEventListener("keydown", handler);
return () => document.removeEventListener("keydown", handler);
}, []);
return (
<Modal
motionPreset="slideInBottom"
isOpen={isOpen}
onClose={onClose}
isCentered
>
<ModalOverlay />
<ModalContent {...MODAL_PROPS}>
<ModalTitleWithCloseButton
text={t("Claim Rewards")}
onClose={onClose}
/>
<ModalDivider />
<Column
width="100%"
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
p={3}
>
<ClaimRewards showPrivate={showPrivate} />
</Column>
</ModalContent>
</Modal>
);
}
Example #16
Source File: index.tsx From calories-in with MIT License | 5 votes |
function FoodsListModal({ onClose, isOpen, foodsToImport }: Props) {
const title = foodsToImport ? 'Import Foods' : 'Export Foods'
const { userFoods } = useFoods()
const foodsActions = useFoodsActions()
const toast = useToast()
const foods = foodsToImport || userFoods
function onImport() {
if (foodsToImport) {
foodsActions.setFoods(foodsToImport)
toast({
position: 'top',
status: 'success',
title: 'Foods imported',
isClosable: true,
})
onClose()
}
}
return (
<Modal
isOpen={isOpen}
preserveScrollBarGap={true}
onClose={onClose}
scrollBehavior="inside"
>
<ModalOverlay />
<FoodsFilterStoreProvider
initialFilter={{ ...DEFAULT_FILTER, onlyFoodsAddedByUser: true }}
shouldSaveFilter={false}
>
<FoodsStoreProvider initialFoods={foods}>
<Content
onClose={onClose}
title={title}
onImport={onImport}
action={foodsToImport ? 'import' : 'export'}
/>
</FoodsStoreProvider>
</FoodsFilterStoreProvider>
</Modal>
)
}
Example #17
Source File: AuthModal.tsx From coindrop with GNU General Public License v3.0 | 5 votes |
AuthModal: FunctionComponent<Props> = ({ isOpen }) => {
const router = useRouter();
const onClose = () => router.push('/', undefined, { shallow: true });
return (
<Modal
id="auth-modal"
isOpen={isOpen}
onClose={onClose}
>
<ModalOverlay />
<ModalContent>
<ModalHeader textAlign="center" mb={-3}>Sign in to continue</ModalHeader>
<ModalCloseButton />
<ModalBody>
<FirebaseAuth />
<Text textAlign="center" fontSize="xs" mb={2}>
{'If you\'re having trouble logging in, please try again with '}
<Link
href="https://www.google.com/chrome/"
target="_blank"
rel="noreferrer"
textDecoration="underline"
>
Chrome
</Link>
{' or '}
<Link
href="https://www.mozilla.org/firefox"
target="_blank"
rel="noreferrer"
textDecoration="underline"
>
Firefox
</Link>
.
</Text>
</ModalBody>
</ModalContent>
</Modal>
);
}
Example #18
Source File: index.tsx From calories-in with MIT License | 5 votes |
function ExportModal({ isOpen, onClose }: Props) {
return (
<Modal size="sm" isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<Content onClose={onClose} />
</Modal>
)
}
Example #19
Source File: ShareButtonModal.tsx From coindrop with GNU General Public License v3.0 | 5 votes |
ShareButtonModal: FunctionComponent<Props> = ({ buttonColor }) => {
const { isOpen, onClose, onOpen } = useDisclosure();
const { query: { piggybankName: piggybankNameQuery }} = useRouter();
const piggybankName = Array.isArray(piggybankNameQuery) ? piggybankNameQuery[0] : piggybankNameQuery;
const publicUrl = `coindrop.to/${piggybankName}`;
const fullPublicUrl = `https://${publicUrl}`;
return (
<>
<Button
leftIcon={<ShareIcon />}
onClick={onOpen}
colorScheme={buttonColor}
isDisabled={isOpen}
>
Share
</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalCloseButton />
<Heading
mt={4}
as="h2"
size="md"
mx={12}
textAlign="center"
>
{publicUrl}
</Heading>
<ModalBody>
<Box mb={4}>
<Box>
<Heading as="h2" size="lg">
Link
</Heading>
</Box>
<Center mt={2}>
<CopyLinkShareButton textToCopy={publicUrl} />
</Center>
</Box>
<ShareEmbedButton
fullPublicUrl={fullPublicUrl}
/>
<PiggybankQRCode
fullPublicUrl={fullPublicUrl}
publicUrl={publicUrl}
/>
<TipCards />
</ModalBody>
<ModalFooter />
</ModalContent>
</Modal>
</>
);
}
Example #20
Source File: PaymentMethodButtonModal.tsx From coindrop with GNU General Public License v3.0 | 5 votes |
PaymentMethodButtonModal: FunctionComponent<Props> = ({ isOpen, onClose, paymentMethod, paymentMethodDisplayName, paymentMethodValue }) => {
const { onCopy, hasCopied } = useClipboard(paymentMethodValue);
const { piggybankDbData } = useContext(PublicPiggybankDataContext);
const { name } = piggybankDbData;
const Icon = paymentMethodIcons[paymentMethod];
const addressIsUrl = isUrl(paymentMethodValue, {
require_protocol: true,
require_valid_protocol: true,
protocols: ['http', 'https'],
allow_protocol_relative_urls: false,
});
return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent mx={6}>
<ModalHeader
textAlign="center"
mt={3}
mx="auto"
>
{name}
{"'s "}
{paymentMethodDisplayName}
{' address'}
</ModalHeader>
<ModalCloseButton />
<ModalBody
pt={0}
mb={3}
mx="auto"
>
<Flex justify="center" align="center">
<Icon
mr={2}
boxSize="48px"
/>
<Text
wordBreak="break-all"
textAlign="center"
>
{paymentMethodValue}
</Text>
</Flex>
<Flex
my={2}
align="center"
justify="center"
>
{addressIsUrl ? (
<Link href={paymentMethodValue} isExternal>
<Button
leftIcon={<ExternalLinkIcon />}
href={paymentMethodValue}
mr={2}
>
Open
</Button>
</Link>
) : (
<Button
leftIcon={hasCopied ? <CheckIcon /> : <CopyIcon />}
onClick={onCopy}
>
{hasCopied ? "Copied" : "Copy"}
</Button>
)}
</Flex>
<Text mb={2} textAlign="center">or scan QR Code:</Text>
<Flex justify="center">
<QRCode
id="payment-method-qr-code"
value={paymentMethodValue}
size={225}
/>
</Flex>
</ModalBody>
</ModalContent>
</Modal>
);
}
Example #21
Source File: EditPiggybankModal.tsx From coindrop with GNU General Public License v3.0 | 4 votes |
EditPiggybankModal: FunctionComponent<Props> = ({ isOpen, onClose }) => {
const [isSubmitting, setIsSubmitting] = useState(false);
const { colors } = useTheme();
const { user } = useUser();
const { colorMode } = useColorMode();
const accentColorLevelInitial = getAccentColorLevelInitial(colorMode);
const accentColorLevelHover = getAccentColorLevelHover(colorMode);
const { push: routerPush, query: { piggybankName } } = useRouter();
const initialPiggybankId = Array.isArray(piggybankName) ? piggybankName[0] : piggybankName;
const { piggybankDbData } = useContext(PublicPiggybankDataContext);
const { avatar_storage_id: currentAvatarStorageId } = piggybankDbData;
const initialPaymentMethodsDataFieldArray = convertPaymentMethodsDataToFieldArray(piggybankDbData.paymentMethods);
const initialAccentColor = piggybankDbData.accentColor ?? 'orange';
const {
register,
handleSubmit,
setValue,
watch,
control,
formState: { isDirty },
} = useForm({
defaultValues: {
piggybankId: initialPiggybankId,
accentColor: initialAccentColor,
website: piggybankDbData.website ?? '',
name: piggybankDbData.name ?? '',
verb: piggybankDbData.verb ?? 'pay',
paymentMethods: sortByIsPreferredThenAlphabetical(initialPaymentMethodsDataFieldArray),
},
});
const paymentMethodsFieldArrayName = "paymentMethods";
const { fields, append, remove } = useFieldArray({
control,
name: paymentMethodsFieldArrayName,
});
const {
accentColor: watchedAccentColor,
piggybankId: watchedPiggybankId,
} = watch(["accentColor", "piggybankId"]);
const isAccentColorDirty = initialAccentColor !== watchedAccentColor;
const isUrlUnchanged = initialPiggybankId === watchedPiggybankId;
const { isPiggybankIdAvailable, setIsAddressTouched } = useContext(AdditionalValidation);
const onSubmit = async (formData) => {
try {
setIsSubmitting(true);
const dataToSubmit = {
...formData,
paymentMethods: convertPaymentMethodsFieldArrayToDbMap(formData.paymentMethods ?? []),
owner_uid: user.id,
avatar_storage_id: currentAvatarStorageId ?? null,
};
if (isUrlUnchanged) {
await db.collection('piggybanks').doc(initialPiggybankId).set(dataToSubmit);
mutate(['publicPiggybankData', initialPiggybankId], dataToSubmit);
} else {
await axios.post(
'/api/createPiggybank',
{
oldPiggybankName: initialPiggybankId,
newPiggybankName: formData.piggybankId,
piggybankData: dataToSubmit,
},
{
headers: {
token: user.token,
},
},
);
try {
await db.collection('piggybanks').doc(initialPiggybankId).delete();
} catch (err) {
console.log('error deleting old Coindrop page');
}
routerPush(`/${formData.piggybankId}`);
}
fetch(`/${initialPiggybankId}`, { headers: { isToForceStaticRegeneration: "true" }});
onClose();
} catch (error) {
setIsSubmitting(false);
// TODO: handle errors
throw error;
}
};
const handleAccentColorChange = (e) => {
e.preventDefault();
setValue("accentColor", e.target.dataset.colorname);
};
useEffect(() => {
register("accentColor");
}, [register]);
const formControlTopMargin = 2;
return (
<Modal
isOpen={isOpen}
onClose={onClose}
size="xl"
closeOnOverlayClick={false}
>
<ModalOverlay />
<ModalContent>
<ModalHeader>Configure</ModalHeader>
<ModalCloseButton />
<form id="configure-coindrop-form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<AvatarInput />
<FormControl
isRequired
mt={formControlTopMargin}
>
<FormLabel htmlFor="input-piggybankId">URL</FormLabel>
<EditUrlInput
register={register}
value={watchedPiggybankId}
/>
</FormControl>
<FormControl
mt={formControlTopMargin}
>
<FormLabel
htmlFor="input-accentColor"
>
Theme
</FormLabel>
<Flex wrap="wrap" justify="center">
{themeColorOptions.map(colorName => {
const isColorSelected = watchedAccentColor === colorName;
const accentColorInitial = colors[colorName][accentColorLevelInitial];
const accentColorHover = colors[colorName][accentColorLevelHover];
return (
<Box
key={colorName}
as="button"
bg={isColorSelected ? accentColorHover : accentColorInitial}
_hover={{
bg: accentColorHover,
}}
w="36px"
h="36px"
borderRadius="50%"
mx={1}
my={1}
onClick={handleAccentColorChange}
data-colorname={colorName}
>
{isColorSelected && (
<CheckIcon color="#FFF" />
)}
</Box>
);
})}
</Flex>
</FormControl>
<FormControl
isRequired
mt={formControlTopMargin}
>
<FormLabel
htmlFor="input-name"
>
Name
</FormLabel>
<Input
id="input-name"
name="name"
ref={register}
/>
</FormControl>
<FormControl
isRequired
mt={formControlTopMargin}
>
<FormLabel
htmlFor="input-verb"
>
Payment action name
</FormLabel>
<Select
id="input-verb"
name="verb"
ref={register}
>
<option value="pay">Pay</option>
<option value="donate to">Donate to</option>
<option value="support">Support</option>
<option value="tip">Tip</option>
</Select>
</FormControl>
<FormControl
mt={formControlTopMargin}
>
<FormLabel
htmlFor="input-website"
>
Website
</FormLabel>
<Input
id="input-website"
name="website"
ref={register}
placeholder="http://"
type="url"
/>
</FormControl>
<FormControl
mt={formControlTopMargin}
>
<FormLabel
htmlFor="input-paymentmethods"
>
Payment Methods
</FormLabel>
<PaymentMethodsInput
fields={fields}
control={control}
register={register}
remove={remove}
append={append}
fieldArrayName={paymentMethodsFieldArrayName}
/>
</FormControl>
</ModalBody>
<Flex
id="modal-footer"
justify="space-between"
m={6}
>
<DeleteButton
piggybankName={initialPiggybankId}
/>
<Flex>
<Button
variant="ghost"
onClick={onClose}
>
Cancel
</Button>
<Button
id="save-configuration-btn"
colorScheme="green"
mx={1}
type="submit"
isLoading={isSubmitting}
loadingText="Saving"
isDisabled={
(
!isDirty
&& !isAccentColorDirty // controlled accentColor field is not showing up in formState.dirtyFields
)
|| !isPiggybankIdAvailable
|| !initialPiggybankId
}
onClick={() => setIsAddressTouched(true)}
>
Save
</Button>
</Flex>
</Flex>
</form>
</ModalContent>
</Modal>
);
}
Example #22
Source File: carousel.tsx From notebook with MIT License | 4 votes |
Carousel: React.SFC<CarouselProps> = ({
onOpen,
onClose,
isOpen,
repoId
}) => {
const [[page, direction], setPage] = React.useState([0, 0]);
const [imageIndex, setImageIndex] = React.useState<number>(0);
const paginate = (newDirection: number) => {
setPage([page + newDirection, newDirection]);
};
React.useEffect(() => {
setImageIndex(repoId);
}, [repoId]);
const nextImage = (newDirection: number) => {
paginate(newDirection);
setImageIndex(imageIndex + 1 < coverImages.length ? imageIndex + 1 : 0);
};
const prevImage = (newDirection: number) => {
paginate(newDirection);
setImageIndex(
0 === imageIndex ? coverImages.length - 1 : imageIndex - 1
);
};
return (
<Modal isCentered onClose={onClose} size={"6xl"} isOpen={isOpen}>
<ModalOverlay />
<ModalContent>
<ModalBody padding="0">
<div className="carousel-container">
<AnimatePresence initial={false} custom={direction}>
<motion.img
key={page}
src={coverImages[imageIndex]}
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
x: { type: "spring", stiffness: 300, damping: 30 },
opacity: { duration: 0.2 }
}}
drag="x"
dragConstraints={{ left: 0, right: 0 }}
dragElastic={1}
onDragEnd={(e, { offset, velocity }) => {
const swipe = swipePower(offset.x, velocity.x);
if (swipe < -swipeConfidenceThreshold) {
paginate(1);
} else if (swipe > swipeConfidenceThreshold) {
paginate(-1);
}
}}
/>
</AnimatePresence>
<div className="next" onClick={() => nextImage(1)}>
<IconButton
aria-label="left image"
icon={<ChevronLeftIcon />}
cursor="pointer"
as={ChevronRightIcon}
size="md"
colorScheme="teal"
borderRadius="full"
/>
</div>
<div className="prev" onClick={() => prevImage(-1)}>
<IconButton
aria-label="right image"
icon={<ChevronRightIcon />}
cursor="pointer"
as={ChevronLeftIcon}
size="md"
colorScheme="teal"
borderRadius="full"
/>
</div>
</div>
</ModalBody>
</ModalContent>
</Modal>
);
}
Example #23
Source File: note-form.tsx From notebook with MIT License | 4 votes |
NoteForm: React.SFC<NoteFormProps> = ({
isOpen,
onClose,
selectedNote,
handleNoteCreate,
handleNoteUpdate
}) => {
const { register, handleSubmit, formState, errors } = useForm<FormInputs>({
mode: "onChange"
});
const onSubmit: SubmitHandler<FormInputs> = data => {
let newNote: note = {
id: "",
title: data.title,
body: data.body
};
if (handleNoteCreate) {
newNote.id = nanoid();
if (handleNoteCreate) handleNoteCreate(newNote);
} else {
newNote.id = selectedNote ? selectedNote.id : "";
if (handleNoteUpdate) handleNoteUpdate(newNote);
}
onClose();
};
const validateTitle = (value: string) => {
if (!value) {
return "Title is required";
} else return true;
};
const validateBody = (value: string) => {
if (!value) {
return "Body is required";
} else return true;
};
return (
<Modal
isOpen={isOpen}
onClose={onClose}
size="lg"
isCentered
motionPreset="slideInBottom"
>
<ModalOverlay />
<ModalContent>
<form onSubmit={handleSubmit(onSubmit)}>
<ModalHeader>{selectedNote ? "Edit" : "Create"} a Note</ModalHeader>
<ModalCloseButton />
<ModalBody pb={6}>
<FormControl isInvalid={!!errors?.title} isRequired>
<FormLabel>Title</FormLabel>
<Input
name="title"
placeholder="Title"
defaultValue={selectedNote?.title}
ref={register({ validate: validateTitle })}
/>
<FormErrorMessage>
{!!errors?.title && errors?.title?.message}
</FormErrorMessage>
</FormControl>
<FormControl size="lg" mt={4} isInvalid={!!errors?.body} isRequired>
<FormLabel>Body</FormLabel>
<Textarea
name="body"
placeholder="Body"
size="md"
borderRadius="5px"
defaultValue={selectedNote?.body}
ref={register({ validate: validateBody })}
/>
<FormErrorMessage>
{!!errors?.body && errors?.body?.message}
</FormErrorMessage>
</FormControl>
</ModalBody>
<ModalFooter>
<Button
type="submit"
colorScheme="blue"
isLoading={formState.isSubmitting}
mr={3}
>
Save
</Button>
<Button onClick={onClose}>Cancel</Button>
</ModalFooter>
</form>
</ModalContent>
</Modal>
);
}
Example #24
Source File: offline-data-card.tsx From portfolio with MIT License | 4 votes |
RepositoryCard = (props: RepositoryCardProps) => {
const {
key,
title,
description,
cover,
blurHash,
technologies,
url,
live,
stars,
fork,
} = props;
const { isOpen, onOpen, onClose } = useDisclosure();
const handleClick = () => {
onOpen();
// window.open(link);
// if (type == "link" || type == "article") {
// window.open(link);
// } else {
// onOpen();
// }
};
const handleLinkClick = (
e: React.MouseEvent<HTMLParagraphElement, MouseEvent>,
link: string
) => {
window.open(link);
e.stopPropagation();
};
const transition = { duration: 0.5, ease: [0.43, 0.13, 0.23, 0.96] };
const thumbnailVariants = {
initial: { scale: 0.9, opacity: 0 },
enter: { scale: 1, opacity: 1, transition },
exit: {
scale: 0.5,
opacity: 0,
transition: { duration: 1.5, ...transition }
}
};
const imageVariants = {
hover: { scale: 1.1 }
};
return (
<CardTransition>
<Box onClick={handleClick} cursor="pointer" size="xl">
<VStack
// w="100%"
rounded="xl"
borderWidth="1px"
bg={useColorModeValue("white", "gray.800")}
borderColor={useColorModeValue("gray.100", "gray.700")}
_hover={{
shadow: "lg",
textDecoration: "none"
}}
overflow="hidden"
align="start"
spacing={0}
>
<Box position="relative" w="100%">
<MotionBox variants={thumbnailVariants}>
<MotionBox
whileHover="hover"
variants={imageVariants}
transition={transition}
>
<AspectRatio
ratio={1.85 / 1}
maxW="400px"
w="100%"
borderBottomWidth="1px"
borderColor={useColorModeValue("gray.100", "gray.700")}
>
{/* <Image
src={cover}
fallback={<Skeleton />}
objectFit="cover"
/> */}
<LazyImage
src={cover}
blurHash={blurHash}
/>
</AspectRatio>
</MotionBox>
</MotionBox>
</Box>
<VStack py={2} px={[2, 4]} spacing={1} align="start" w="100%">
<Flex justifyContent={"space-between"} width="100%">
<Tooltip hasArrow label="Github link" placement="top">
<HStack>
<Icon as={FiGithub} boxSize="0.9em" mt={"1px"} />
{/* <Link href={url} isExternal> */}
<Text
fontSize="sm"
noOfLines={1}
fontWeight="600"
align="left"
onClick={e => handleLinkClick(e, url)}
>
{title}
</Text>
</HStack>
</Tooltip>
{/* </Link> */}
<Flex>
<Icon as={AiOutlineStar} boxSize="0.9em" mt={"1px"} />
<Box as="span" ml="1" fontSize="sm">
{stars}
</Box>
</Flex>
</Flex>
<Flex justifyContent={"space-between"} width="100%">
<Box>
<HStack spacing="1">
{technologies.map(tech => (
<Tag size="sm" colorScheme={getTagColor(tech)}>
<Text fontSize={["0.55rem", "inherit", "inherit"]}>
{tech}
</Text>
</Tag>
))}
</HStack>
</Box>
</Flex>
{/* <Flex justifyContent={"space-between"} width="100%">
<Flex>
<AiOutlineStar color="teal.300" />
<Box as="span" ml="1" fontSize="sm">
{stars}
</Box>
</Flex>
<Box >
<Text
fontSize="xs"
fontWeight="400"
color={useColorModeValue("gray.400", "gray.500")}
>
{created}
</Text>
</Box>
</Flex> */}
</VStack>
</VStack>
<Modal isOpen={isOpen} onClose={onClose} isCentered allowPinchZoom>
<ModalOverlay />
<ModalContent bg="none" maxW={"28rem"} w="auto">
<ModalBody p={0} rounded="lg" overflow="hidden" bg="none">
<Center>
<Image src={cover} rounded="lg" />
{/* {type == "image" ? (
<Image src={cover} rounded="lg" />
) : (
<ReactPlayer url={link} controls playing />
)} */}
</Center>
</ModalBody>
</ModalContent>
</Modal>
</Box>
</CardTransition>
);
}
Example #25
Source File: index.tsx From jsonschema-editor-react with Apache License 2.0 | 4 votes |
SchemaArray: React.FunctionComponent<SchemaArrayProps> = (
props: React.PropsWithChildren<SchemaArrayProps>
) => {
const { schemaState, isReadOnly } = props;
const state = useState(schemaState.items as JSONSchema7);
const isReadOnlyState = useState(isReadOnly);
const { length } = state.path.filter((name) => name !== "properties");
const tagPaddingLeftStyle = {
paddingLeft: `${20 * (length + 1)}px`,
};
const onCloseAdvanced = (): void => {
localState.isAdvancedOpen.set(false);
};
const showadvanced = (): void => {
localState.isAdvancedOpen.set(true);
};
const focusRef = React.createRef<HTMLElement>();
const localState = useState({
isAdvancedOpen: false,
});
return (
<>
<Flex
direction="row"
wrap="nowrap"
className="array-item"
mt={2}
mr={5}
style={tagPaddingLeftStyle}
>
<Input
key="Items"
isDisabled
value="Items"
size="sm"
flexShrink={1}
margin={2}
variant="outline"
/>
<Checkbox isDisabled margin={2} colorScheme="blue" />
<Select
variant="outline"
isDisabled={isReadOnlyState.value}
value={state.type.value as JSONSchema7TypeName}
size="sm"
margin={2}
placeholder="Choose data type"
onChange={(evt: React.ChangeEvent<HTMLSelectElement>) => {
const newSchema = handleTypeChange(
evt.target.value as JSONSchema7TypeName,
false
);
state.set(newSchema as JSONSchema7);
}}
>
{SchemaTypes.map((item, index) => {
return (
<option key={String(index)} value={item}>
{item}
</option>
);
})}
</Select>
<Input
value={state.title.value}
isDisabled={isReadOnlyState.value}
size="sm"
margin={2}
variant="outline"
placeholder="Add Title"
onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
state.title.set(evt.target.value);
}}
/>
<Input
value={state.description.value}
isDisabled={isReadOnlyState.value}
size="sm"
margin={2}
variant="outline"
placeholder="Add Description"
onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
state.description.set(evt.target.value);
}}
/>
<Tooltip
hasArrow
aria-label="Advanced Settings"
label="Advanced Settings"
placement="top"
>
<IconButton
isRound
isDisabled={isReadOnlyState.value}
size="sm"
mt={2}
mb={2}
ml={1}
variant="link"
colorScheme="blue"
fontSize="16px"
icon={<FiSettings />}
aria-label="Advanced Settings"
onClick={() => {
showadvanced();
}}
/>
</Tooltip>
{state.type.value === "object" && (
<Tooltip
hasArrow
aria-label="Add Child Node"
label="Add Child Node"
placement="top"
>
<IconButton
isRound
isDisabled={isReadOnlyState.value}
size="sm"
mt={2}
mb={2}
mr={2}
variant="link"
colorScheme="green"
fontSize="16px"
icon={<IoIosAddCircleOutline />}
aria-label="Add Child Node"
onClick={() => {
const fieldName = `field_${random()}`;
(state.properties as State<{
[key: string]: JSONSchema7;
}>)[fieldName].set(getDefaultSchema(DataType.string));
}}
/>
</Tooltip>
)}
</Flex>
{state.type?.value === "object" && (
<SchemaObject isReadOnly={isReadOnlyState} schemaState={state} />
)}
{state.type?.value === "array" && (
<SchemaArray isReadOnly={isReadOnlyState} schemaState={state} />
)}
<Modal
isOpen={localState.isAdvancedOpen.get()}
finalFocusRef={focusRef}
size="lg"
onClose={onCloseAdvanced}
>
<ModalOverlay />
<ModalContent>
<ModalHeader textAlign="center">Advanced Schema Settings</ModalHeader>
<ModalBody>
<AdvancedSettings itemStateProp={state} />
</ModalBody>
<ModalFooter>
<Button
colorScheme="blue"
variant="ghost"
mr={3}
onClick={onCloseAdvanced}
>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
}
Example #26
Source File: index.tsx From jsonschema-editor-react with Apache License 2.0 | 4 votes |
SchemaObject: React.FunctionComponent<SchemaObjectProps> = (
props: React.PropsWithChildren<SchemaObjectProps>
) => {
const { schemaState, isReadOnly } = props;
const schema = useState(schemaState);
const properties = useState(schema.properties);
const propertiesOrNull:
| State<{
[key: string]: JSONSchema7Definition;
}>
| undefined = properties.ornull;
const isReadOnlyState = useState(isReadOnly);
const onCloseAdvanced = (): void => {
localState.isAdvancedOpen.set(false);
};
const showadvanced = (item: string): void => {
localState.isAdvancedOpen.set(true);
localState.item.set(item);
};
const focusRef = React.createRef<HTMLElement>();
const localState = useState({
isAdvancedOpen: false,
item: "",
});
if (!propertiesOrNull) {
return <></>;
} else {
return (
<div className="object-style">
{propertiesOrNull?.keys?.map((name) => {
return (
<SchemaItem
key={String(name)}
itemStateProp={
propertiesOrNull.nested(name as string) as State<JSONSchema7>
}
parentStateProp={schema}
name={name as string}
showadvanced={showadvanced}
required={schema.required.value as string[]}
isReadOnly={isReadOnlyState}
/>
);
})}
<Modal
isOpen={localState.isAdvancedOpen.get()}
finalFocusRef={focusRef}
size="lg"
onClose={onCloseAdvanced}
>
<ModalOverlay />
<ModalContent>
<ModalHeader textAlign="center">
Advanced Schema Settings
</ModalHeader>
<ModalBody>
<AdvancedSettings
itemStateProp={
propertiesOrNull.nested(
localState.item.value as string
) as State<JSONSchema7>
}
/>
</ModalBody>
<ModalFooter>
<Button
colorScheme="blue"
variant="ghost"
mr={3}
onClick={onCloseAdvanced}
>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
);
}
}
Example #27
Source File: About.tsx From calories-in with MIT License | 4 votes |
function About({ isOpen, onClose }: Props) {
function onContact() {
window.location.href = 'mailto:[email protected]'
}
return (
<Modal isOpen={isOpen} onClose={onClose} size="2xl" scrollBehavior="inside">
<ModalOverlay />
<ModalContent>
<ModalHeader>About </ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text fontSize="lg">
<Text>Hi, I'm Vladimir, the person behind this project.</Text>
<br />
<Text>
<Text fontWeight="semibold" as="span" textColor="teal.600">
Calories-In
</Text>{' '}
is made for people who follow meal plans that involve preparing
everything by yourself and gives them full control to fine tune
the nutritional values.
</Text>
<br />
<Text>
The idea was born out of my experience of trying to find a better
alternative to Google Sheets for calculating the macros of my own
meal plans. I wanted to be able to do this on desktop as it's more
convenient but nothing really felt fast and simple enough.
</Text>
<br />
<Text>The main differences to other apps in this space are:</Text>
<br />
<List ml={8}>
<ListItem>
<ListIcon as={CheckCircle} color="teal.600" />
<Text fontWeight="semibold" as="span" textColor="teal.600">
Faster search
</Text>{' '}
: There are actually not that many foods you need when you
prepare everything yourself. This means all of the food data can
be downloaded beforehand which makes the search super fast. Of
course you can add your own foods if you'd like.{' '}
</ListItem>
<br />
<ListItem>
<ListIcon as={CheckCircle} color="teal.600" />
<Text fontWeight="semibold" as="span" textColor="teal.600">
Undo/Redo
</Text>{' '}
: Building a plan from scratch or updating an existing one
involves some back and forth choosing the right foods and
adjusting their amounts. This is especially true if you want to
be as close as possible to a specific calorie limit and have
your macros be a certain percentages split.
</ListItem>
<br />
<ListItem>
<ListIcon as={CheckCircle} color="teal.600" />
<Text fontWeight="semibold" as="span" textColor="teal.600">
Faster export
</Text>{' '}
: Creating the PDF file for your meal plan is done entirely
inside the browser. It does not involve generating and
downloading it from a server. This means I can keep the cost of
running the website low and you get your file in just a few
seconds.
</ListItem>
<br />
<ListItem>
<ListIcon as={CheckCircle} color="teal.600" />
<Text fontWeight="semibold" as="span" textColor="teal.600">
Simpler
</Text>{' '}
: There are no other pages except the editor. Most of the other
tools are bloated with additional features for professionals,
such as managing clients, creating invoices, etc.
</ListItem>
<br />
<ListItem>
<ListIcon as={CheckCircle} color="teal.600" />
<Text fontWeight="semibold" as="span" textColor="teal.600">
Fully mobile
</Text>{' '}
: You can use your phone or tablet to build your meal plans
right from your browser. If you add the app to your home screen
it will look and feel almost like a native one.
</ListItem>
</List>
<Text>
<br />
Let me know if you found it useful or have any comments in
general:
</Text>
<br />
<Button size="lg" colorScheme="teal" onClick={onContact}>
Contact me directly
</Button>
<br />
<br />
<Text>No email will go unanswered, I promise :)</Text>
</Text>
</ModalBody>
<ModalFooter>
<Button size="lg" onClick={onClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
)
}
Example #28
Source File: EditRewardsDistributorModal.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
EditRewardsDistributorModal = ({
rewardsDistributor,
pool,
isOpen,
onClose,
}: {
rewardsDistributor: RewardsDistributor;
pool: FusePoolData;
isOpen: boolean;
onClose: () => any;
}) => {
const { t } = useTranslation();
const { address, fuse } = useRari();
const rewardsDistributorInstance = useRewardsDistributorInstance(
rewardsDistributor.address
);
const tokenData = useTokenData(rewardsDistributor.rewardToken);
const isAdmin = address === rewardsDistributor.admin;
// Balances
const { data: balanceERC20 } = useTokenBalance(
rewardsDistributor.rewardToken,
rewardsDistributor.address
);
const { data: myBalance } = useTokenBalance(rewardsDistributor.rewardToken);
const toast = useToast();
// Inputs
const [sendAmt, setSendAmt] = useState<number>(0);
const [supplySpeed, setSupplySpeed] = useState<number>(0.001);
const [borrowSpeed, setBorrowSpeed] = useState<number>(0.001);
// Loading states
const [fundingDistributor, setFundingDistributor] = useState(false);
const [seizing, setSeizing] = useState(false);
const [changingSpeed, setChangingSpeed] = useState(false);
const [changingBorrowSpeed, setChangingBorrowSpeed] = useState(false);
const [selectedAsset, setSelectedAsset] = useState<
USDPricedFuseAsset | undefined
>(pool?.assets[0] ?? undefined);
// RewardsSpeeds
const [supplySpeedForCToken, borrowSpeedForCToken] = useRewardSpeedsOfCToken(
rewardsDistributor.address,
selectedAsset?.cToken
);
const { hasCopied, onCopy } = useClipboard(rewardsDistributor?.address ?? "");
// Sends tokens to distributor
const fundDistributor = async () => {
// Create ERC20 instance of rewardToken
const token = new fuse.web3.eth.Contract(
JSON.parse(
fuse.compoundContracts["contracts/EIP20Interface.sol:EIP20Interface"]
.abi
),
rewardsDistributor.rewardToken
);
setFundingDistributor(true);
try {
await token.methods
.transfer(
rewardsDistributor.address,
Fuse.Web3.utils
.toBN(sendAmt)
.mul(
Fuse.Web3.utils
.toBN(10)
.pow(Fuse.Web3.utils.toBN(tokenData?.decimals ?? 18))
)
)
.send({
from: address,
});
setFundingDistributor(false);
} catch (err) {
handleGenericError(err, toast);
setFundingDistributor(false);
}
};
// Adds LM to supply side of a CToken in this fuse pool
const changeSupplySpeed = async () => {
try {
if (!isAdmin) throw new Error("User is not admin of this Distributor!");
setChangingSpeed(true);
await rewardsDistributorInstance.methods
._setCompSupplySpeed(
selectedAsset?.cToken,
Fuse.Web3.utils.toBN(supplySpeed * 10 ** (tokenData?.decimals ?? 18)) // set supplySpeed to 0.001e18 for now
)
.send({ from: address });
setChangingSpeed(false);
} catch (err) {
handleGenericError(err, toast);
setChangingSpeed(false);
}
};
// Adds LM to supply side of a CToken in this fuse pool
const changeBorrowSpeed = async () => {
try {
if (!isAdmin) throw new Error("User is not admin of this Distributor!");
setChangingBorrowSpeed(true);
await rewardsDistributorInstance.methods
._setCompBorrowSpeed(
selectedAsset?.cToken,
Fuse.Web3.utils.toBN(borrowSpeed * 10 ** (tokenData?.decimals ?? 18)) // set supplySpeed to 0.001e18 for now
)
.send({ from: address });
setChangingBorrowSpeed(false);
} catch (err) {
handleGenericError(err, toast);
setChangingBorrowSpeed(false);
}
};
const handleSeizeTokens = async () => {
setSeizing(true);
if (isAdmin) {
await rewardsDistributorInstance.methods._grantComp(
address,
balanceERC20
);
} else {
toast({
title: "Admin Only!",
description: "Only admin can seize tokens!",
status: "error",
duration: 9000,
isClosable: true,
position: "top-right",
});
}
setSeizing(false);
};
return (
<Modal
motionPreset="slideInBottom"
isOpen={isOpen}
onClose={onClose}
isCentered
>
<ModalOverlay />
<ModalContent {...MODAL_PROPS}>
<Heading fontSize="27px" my={4} textAlign="center">
{t("Edit Rewards Distributor")}
</Heading>
<ModalDivider />
{/* RewardToken data */}
<Column
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
p={4}
>
<>
{tokenData?.logoURL ? (
<Image
mt={4}
src={tokenData.logoURL}
boxSize="50px"
borderRadius="50%"
backgroundImage={`url(${SmallWhiteCircle})`}
backgroundSize="100% auto"
/>
) : null}
<Heading
my={tokenData?.symbol ? 3 : 6}
fontSize="22px"
color={tokenData?.color ?? "#FFF"}
>
{tokenData ? tokenData.name ?? "Invalid Address!" : "Loading..."}
</Heading>
<Text>
{balanceERC20 && tokenData && tokenData.decimals
? (
parseFloat(balanceERC20?.toString()) /
10 ** tokenData.decimals
).toFixed(3)
: 0}{" "}
{tokenData?.symbol}
</Text>
<Text onClick={onCopy}>
Contract: {shortAddress(rewardsDistributor.address)}{" "}
{hasCopied && "Copied!"}
</Text>
</>
</Column>
<AdminAlert
isAdmin={isAdmin}
mt={2}
isNotAdminText="You are not the admin of this RewardsDistributor. Only the admin can configure rewards."
/>
{/* Basic Info */}
<Column
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
py={4}
>
{/* <Row mainAxisAlignment="flex-start" crossAxisAlignment="center">
<Text>Address: {rewardsDistributor.address}</Text>
</Row>
<Row mainAxisAlignment="flex-start" crossAxisAlignment="center">
<Text>Admin: {rewardsDistributor.admin}</Text>
</Row>
<Row mainAxisAlignment="flex-start" crossAxisAlignment="center">
<Text>
Balance:{" "}
{balanceERC20 ? parseFloat(balanceERC20?.toString()) / 1e18 : 0}{" "}
{tokenData?.symbol}
</Text>
</Row> */}
<ModalDivider />
{/* Fund distributor */}
<Column
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
p={4}
>
<Heading fontSize={"lg"}> Fund Distributor </Heading>
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
mt={1}
>
<NumberInput
step={0.1}
min={0}
onChange={(valueString) => {
console.log({ valueString });
setSendAmt(parseFloat(valueString));
}}
>
<NumberInputField
width="100%"
textAlign="center"
placeholder={"0 " + tokenData?.symbol}
/>
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<Button
onClick={fundDistributor}
bg="black"
disabled={fundingDistributor}
>
{fundingDistributor ? <Spinner /> : "Send"}
</Button>
{isAdmin && (!balanceERC20?.isZero() ?? false) && (
<Button onClick={handleSeizeTokens} bg="red" disabled={seizing}>
{seizing ? <Spinner /> : "Withdraw Tokens"}
</Button>
)}
</Row>
<Text mt={1}>
Your balance:{" "}
{myBalance
? (
parseFloat(myBalance?.toString()) /
10 ** (tokenData?.decimals ?? 18)
).toFixed(2)
: 0}{" "}
{tokenData?.symbol}
</Text>
</Column>
{/* Add or Edit a CToken to the Distributor */}
{pool.assets.length ? (
<Column
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
p={4}
>
<Heading fontSize={"lg"}> Manage CToken Rewards </Heading>
{/* Select Asset */}
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
mt={1}
>
{pool.assets.map(
(asset: USDPricedFuseAsset, index: number, array: any[]) => {
return (
<Box
pr={index === array.length - 1 ? 4 : 2}
key={asset.cToken}
flexShrink={0}
>
<DashboardBox
as="button"
onClick={() => setSelectedAsset(asset)}
{...(asset.cToken === selectedAsset?.cToken
? activeStyle
: noop)}
>
<Center expand px={4} py={1} fontWeight="bold">
{asset.underlyingSymbol}
</Center>
</DashboardBox>
</Box>
);
}
)}
</Row>
{/* Change Supply Speed */}
<Column
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
py={3}
>
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
>
<NumberInput
step={0.1}
min={0}
onChange={(supplySpeed) => {
console.log({ supplySpeed });
setSupplySpeed(parseFloat(supplySpeed));
}}
>
<NumberInputField
width="100%"
textAlign="center"
placeholder={"0 " + tokenData?.symbol}
/>
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<Button
onClick={changeSupplySpeed}
bg="black"
disabled={changingSpeed || !isAdmin}
>
{changingSpeed ? <Spinner /> : "Set"}
</Button>
</Row>
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
>
<Text>
Supply Speed:{" "}
{(parseFloat(supplySpeedForCToken) / 1e18).toFixed(4)}
</Text>
</Row>
</Column>
{/* Change Borrow Speed */}
<Column
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
py={3}
>
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
>
<NumberInput
step={0.1}
min={0}
onChange={(borrowSpeed) => {
console.log({ borrowSpeed });
setBorrowSpeed(parseFloat(borrowSpeed));
}}
>
<NumberInputField
width="100%"
textAlign="center"
placeholder={"0 " + tokenData?.symbol}
/>
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<Button
onClick={changeBorrowSpeed}
bg="black"
disabled={changingBorrowSpeed || !isAdmin}
>
{changingBorrowSpeed ? <Spinner /> : "Set"}
</Button>
</Row>
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
>
<Text>
Borrow Speed:{" "}
{(parseFloat(borrowSpeedForCToken) / 1e18).toFixed(2)}
</Text>
</Row>
</Column>
</Column>
) : (
<Center p={4}>
<Text fontWeight="bold">
Add CTokens to this pool to configure their rewards.
</Text>
</Center>
)}
</Column>
</ModalContent>
</Modal>
);
}
Example #29
Source File: Inspector.tsx From openchakra with MIT License | 4 votes |
Inspector = () => {
const dispatch = useDispatch()
const component = useSelector(getSelectedComponent)
const { isOpen, onOpen, onClose } = useDisclosure()
const [componentName, onChangeComponentName] = useState('')
const componentsNames = useSelector(getComponentNames)
const { clearActiveProps } = useInspectorUpdate()
const saveComponent = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
dispatch.components.setComponentName({
componentId: component.id,
name: componentName,
})
onClose()
onChangeComponentName('')
}
const isValidComponentName = useMemo(() => {
return (
!!componentName.match(/^[A-Z]\w*$/g) &&
!componentsNames.includes(componentName) &&
// @ts-ignore
!componentsList.includes(componentName)
)
}, [componentName, componentsNames])
const { type, rootParentType, id, children } = component
const isRoot = id === 'root'
const parentIsRoot = component.parent === 'root'
const docType = rootParentType || type
const componentHasChildren = children.length > 0
useEffect(() => {
clearActiveProps()
}, [clearActiveProps])
return (
<>
<Box bg="white">
<Box
fontWeight="semibold"
fontSize="md"
color="yellow.900"
py={2}
px={2}
boxShadow="sm"
bg="yellow.100"
display="flex"
justifyContent="space-between"
flexDir="column"
>
{isRoot ? 'Document' : type}
{!!component.componentName && (
<Text fontSize="xs" fontWeight="light">
{component.componentName}
</Text>
)}
</Box>
{!isRoot && (
<Stack
direction="row"
py={2}
spacing={2}
align="center"
zIndex={99}
px={2}
flexWrap="wrap"
justify="flex-end"
>
<CodeActionButton />
{!component.componentName && (
<ActionButton
label="Name component"
icon={<EditIcon path="" />}
onClick={onOpen}
/>
)}
<ActionButton
label="Duplicate"
onClick={() => dispatch.components.duplicate()}
icon={<CopyIcon path="" />}
/>
<ActionButton
label="Reset props"
icon={<IoMdRefresh />}
onClick={() => dispatch.components.resetProps(component.id)}
/>
<ActionButton
label="Chakra UI Doc"
as={Link}
onClick={() => {
window.open(
`https://chakra-ui.com/${docType.toLowerCase()}`,
'_blank',
)
}}
icon={<GoRepo />}
/>
<ActionButton
bg="red.500"
label="Remove"
onClick={() => dispatch.components.deleteComponent(component.id)}
icon={<FiTrash2 />}
/>
</Stack>
)}
</Box>
<Box pb={1} bg="white" px={3}>
<Panels component={component} isRoot={isRoot} />
</Box>
<StylesPanel
isRoot={isRoot}
showChildren={componentHasChildren}
parentIsRoot={parentIsRoot}
/>
<Modal onClose={onClose} isOpen={isOpen} isCentered>
<ModalOverlay>
<ModalContent>
<form onSubmit={saveComponent}>
<ModalHeader>Save this component</ModalHeader>
<ModalCloseButton />
<ModalBody>
<FormControl isInvalid={!isValidComponentName}>
<FormLabel>Component name</FormLabel>
<Input
size="md"
autoFocus
variant="outline"
isFullWidth
focusBorderColor="blue.500"
errorBorderColor="red.500"
value={componentName}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
onChangeComponentName(e.target.value)
}
/>
{!isValidComponentName && (
<FormErrorMessage>
Component name must start with a capital character and
must not contain space or special character, and name
should not be already taken (including existing chakra-ui
components).
</FormErrorMessage>
)}
<FormHelperText>
This will name your component that you will see in the code
panel as a separated component.
</FormHelperText>
</FormControl>
</ModalBody>
<ModalFooter>
<Button
colorScheme="blue"
mr={3}
type="submit"
isDisabled={!isValidComponentName}
>
Save
</Button>
<Button onClick={onClose}>Cancel</Button>
</ModalFooter>
</form>
</ModalContent>
</ModalOverlay>
</Modal>
</>
)
}