@chakra-ui/react#useColorModeValue TypeScript Examples
The following examples show how to use
@chakra-ui/react#useColorModeValue.
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: Logo.tsx From coindrop with GNU General Public License v3.0 | 6 votes |
PiggyLogo: FC<IconProps> = (iconProps) => {
const theme = useTheme();
const { colorMode } = useColorMode();
const logoOutlineColor = useColorModeValue(theme.colors.gray['800'], theme.colors.gray['900']);
// eslint-disable-next-line react/jsx-props-no-spreading
return colorMode === 'light'
? <PiggyLogoIcon color={logoOutlineColor} {...iconProps} />
: <PiggyLogoIconDarkMode color={logoOutlineColor} {...iconProps} />;
}
Example #2
Source File: top-nav.tsx From portfolio with MIT License | 6 votes |
NavLink = (props: NavLinkProps) => {
return (
<Link
as={RouterNavLink}
px={2}
py={1}
rounded={"md"}
_hover={{
textDecoration: "none",
bg: useColorModeValue("gray.200", "gray.900")
}}
_activeLink={{
color: useColorModeValue("blue.500", "blue.200")
}}
onClick={() => props.onClose()}
to={props.path}
>
{props.name}
</Link>
);
}
Example #3
Source File: Counter.tsx From ksana.in with Apache License 2.0 | 6 votes |
export function Counter({ count = 0 }) {
const textColor = useColorModeValue('gray.500', 'gray.300')
const arrString: string[] = count.toString().split('')
return (
<Stack spacing="2">
<Stack spacing="2" direction="row" alignItems="center" justify="center" wrap="wrap">
{arrString.map((c, index) => (
<Flex
key={index}
as="div"
width={{ base: '40px', md: '60px' }}
height={{ base: '40px', md: '60px' }}
fontWeight={700}
fontSize={{ base: '2xl', md: '4xl' }}
lineHeight={'110%'}
bg="orange.400"
color="white"
rounded={'md'}
display="flex"
alignItems="center"
justify="center"
>
{c}
</Flex>
))}
</Stack>
<Text textAlign="center" color={textColor}>
Tautan telah dipercantik oleh ksana.in dan akan terus bertambah
</Text>
</Stack>
)
}
Example #4
Source File: card-skeleton.tsx From portfolio with MIT License | 6 votes |
CardSkeleton = () => {
const bgColor = useColorModeValue("white", "gray.900");
const cards:number[] = [1, 2, 3, 4, 5, 6, 7, 8]
return (
<>
{cards.map(id => {
return (
<Box
key={id}
size="xl"
py={2}
rounded="xl"
borderWidth="1px"
bg={bgColor}
>
<Stack isInline justifyContent="space-between" py={2} px={[2, 3]}>
<Box width="100%">
<HStack isInline justifyContent="space-between">
<Skeleton height="14px" width="40%" />
<Skeleton height="14px" width="20%" />
</HStack>
<VStack align="start" marginTop={2}>
<Skeleton height="8px" width="30%" />
</VStack>
<Box marginTop={2}>
<Skeleton height="8px" width="100%" />
<Stack spacing={2} mt={1} isInline alignItems="center">
<Skeleton height="8px" width="80%" />
</Stack>
</Box>
</Box>
</Stack>
</Box>
);
})}
</>
);
}
Example #5
Source File: sign-up.tsx From ksana.in with Apache License 2.0 | 6 votes |
function Register() {
const bgColor = useColorModeValue('gray.50', 'gray.800')
return (
<LayoutAuth minH={'100vh'} bg={bgColor}>
<MetaHead
title="Daftar Akun | Ksana.in"
description="Tertarik mencoba layanan pemendek tautan / URL yang gratis dan sangat mudah digunakan? Mari daftarkan akun baru di Ksana.in"
/>
<AuthSignUp />
</LayoutAuth>
)
}
Example #6
Source File: Timeline.tsx From portfolio with MIT License | 6 votes |
TimelineItem: React.FC<TimelineItemProps> = ({
icon = FiCheckCircle,
boxProps = {},
skipTrail = false,
children,
...props
}) => {
const color = useColorModeValue("gray.700", "gray.500");
return (
<Flex minH={20} {...props}>
<Flex flexDir="column" alignItems="center" mr={4} pos="relative">
<Circle
size={12}
bg={useColorModeValue("gray.600", "gray.500")}
opacity={useColorModeValue(0.07, 0.15)}
sx={{}}
/>
<Box
as={icon}
size="1.25rem"
color={color}
pos="absolute"
left="0.875rem"
top="0.875rem"
/>
{!skipTrail && <Box w="1px" flex={1} bg={color} my={1} />}
</Flex>
<Box pt={3} {...boxProps}>
{children}
</Box>
</Flex>
);
}
Example #7
Source File: Logo.tsx From coindrop with GNU General Public License v3.0 | 6 votes |
Logo: FC<Props> = ({ text = 'coindrop', subtitle }) => {
const theme = useTheme();
const fontColor = useColorModeValue(theme.colors.gray['600'], theme.colors.gray['50']);
const LogoText = () => (
<Text
fontSize={["4xl", "5xl"]}
fontFamily="Changa, system-ui, sans-serif"
fontWeight={500}
color={fontColor}
ml={2}
lineHeight={["1.5rem", "2.5rem"]}
>
{text}
</Text>
);
return (
<Flex
ml={1}
mr={2}
mb={[2, 0]}
align="center"
>
<PiggyLogo boxSize={["48px", "64px"]} />
<Box>
<LogoText />
{subtitle && (
<Text textAlign="center">
{subtitle}
</Text>
)}
</Box>
</Flex>
);
}
Example #8
Source File: ColorModeSwitcher.tsx From notebook with MIT License | 6 votes |
ColorModeSwitcher: React.FC<ColorModeSwitcherProps> = (props) => {
const { toggleColorMode } = useColorMode()
const text = useColorModeValue("dark", "light")
const SwitchIcon = useColorModeValue(FaMoon, FaSun)
return (
<IconButton
size="md"
fontSize="lg"
variant="ghost"
color="current"
marginLeft="2"
onClick={toggleColorMode}
icon={<SwitchIcon />}
aria-label={`Switch to ${text} mode`}
{...props}
/>
)
}
Example #9
Source File: CourseCard.tsx From fresh-coupons with GNU General Public License v3.0 | 6 votes |
function CourseLanguage({language, ...props}: CourseLanguageProps) {
return (
<HStack spacing={1} {...props}>
<Icon boxSize={8} as={MdLanguage} color="gray.400"/>
<Text
fontSize="sm"
fontWeight="medium"
color={useColorModeValue('gray.600', 'gray.300')}
>
{language}
</Text>
</HStack>
)
}
Example #10
Source File: withColorModeHooks.tsx From bluebubbles-server with Apache License 2.0 | 6 votes |
withColorModeHooks = (Elem: any): (props: any) => JSX.Element => {
// eslint-disable-next-line react/display-name
return (props: any): JSX.Element => {
return <Elem
useColorModeValue={useColorModeValue}
useColorMode={useColorMode()}
{...props}
/>;
};
}
Example #11
Source File: PoweredByCoindropLink.tsx From coindrop with GNU General Public License v3.0 | 6 votes |
PoweredByCoindropLink: FunctionComponent = () => {
const bgHover = useColorModeValue("gray.50", "gray.600");
return (
<Box
textAlign="center"
my={6}
>
<NextLink href="/" passHref>
<ChakraLink style={{textDecoration: "none"}}>
<Button
variant="ghost"
_hover={{
bg: bgHover,
}}
>
<Flex
align="center"
justify="center"
>
<PiggyLogo mr={1} boxSize="2rem" />
<Text>
Powered by Coindrop
</Text>
</Flex>
</Button>
</ChakraLink>
</NextLink>
</Box>
);
}
Example #12
Source File: Card.tsx From fresh-coupons with GNU General Public License v3.0 | 6 votes |
Card = (props: BoxProps) => (
<Box
maxW="3xl"
position="relative"
mx="auto"
bg={useColorModeValue('white', 'gray.700')}
rounded={{ md: 'xl' }}
padding="10"
shadow={{ md: 'base' }}
px={{ base: '6', md: '8' }}
{...props}
/>
)
Example #13
Source File: CreateCoindropError.tsx From coindrop with GNU General Public License v3.0 | 5 votes |
CreateCoindropError: FC<{ error: string }> = ({ error }) => {
const errorTextColor = useColorModeValue("red.500", "red.300");
return (
<Text mt={2} textAlign="center" color={errorTextColor}>
{error}
</Text>
);
}
Example #14
Source File: Hero.tsx From ksana.in with Apache License 2.0 | 5 votes |
export function Hero() {
const textColor = useColorModeValue('gray.500', 'gray.300')
return (
<Box w={'full'}>
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={10}>
<Container maxW={'6xl'} as="section" mt="32">
<VStack spacing={{ base: 8, md: 10 }} px={{ base: 8, md: 10 }}>
<Heading
as="h2"
textAlign="center"
fontWeight={700}
fontSize={{ base: '4xl', sm: '5xl', md: '6xl' }}
lineHeight={'110%'}
>
Pemendek tautan yang{' '}
<Text color="orange.400" as="span">
mudah
</Text>{' '}
dan{' '}
<Text color="orange.400" as="span">
gratis
</Text>
</Heading>
<Text
as="span"
textAlign="center"
color={textColor}
fontSize={{ base: 'lg', sm: 'xl', md: '2xl' }}
lineHeight={'110%'}
>
Percantik tautanmu, jadikan agar mudah diingat, bagikan ke orang lain dengan percaya
diri
</Text>
<Button
size="lg"
rounded="full"
px={6}
color={'white'}
bg="orange.400"
_hover={{
bg: 'orange.500'
}}
as={'a'}
href={login}
leftIcon={<HiPlay />}
>
Coba sekarang
</Button>
</VStack>
</Container>
<Flex as="section" mt={{ base: 0, md: 20 }} justifyContent="center">
<Image
width={400}
height={400}
src={'/images/illustrations/ill_by_manypixels.svg'}
alt="Women with Internet"
priority={true}
/>
</Flex>
</SimpleGrid>
</Box>
)
}
Example #15
Source File: PrivateApiRequirements.tsx From bluebubbles-server with Apache License 2.0 | 5 votes |
PrivateApiRequirements = (): JSX.Element => {
const requirements: Array<RequirementsItem> = (useAppSelector(state => state.config.private_api_requirements) ?? []);
const [showProgress, setShowProgress] = useBoolean();
const refreshRequirements = () => {
setShowProgress.on();
getPrivateApiRequirements().then(requirements => {
// I like longer spinning
setTimeout(() => {
setShowProgress.off();
}, 1000);
if (!requirements) return;
store.dispatch(setConfig({ name: 'private_api_requirements', value: requirements }));
});
};
return (
<Box border='1px solid' borderColor={useColorModeValue('gray.200', 'gray.700')} borderRadius='xl' p={3} width='325px'>
<Stack direction='row' align='center'>
<Text fontSize='lg' fontWeight='bold'>Private API Requirements</Text>
<Box
_hover={{ cursor: 'pointer' }}
animation={showProgress ? `${spin} infinite 1s linear` : undefined}
onClick={refreshRequirements}
>
<BiRefresh />
</Box>
</Stack>
<UnorderedList mt={2} ml={8}>
{requirements.map(e => (
<ListItem key={e.name}>
<Stack direction='row' align='center'>
<Text fontSize='md'><strong>{e.name}</strong>:
<Box as='span' color={e.pass ? 'green' : 'red'}>{e.pass ? 'Pass' : 'Fail'}</Box>
</Text>
{(!e.pass) ? (
<Popover trigger='hover'>
<PopoverTrigger>
<Box ml={2} _hover={{ color: 'brand.primary', cursor: 'pointer' }}>
<AiOutlineInfoCircle />
</Box>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverCloseButton />
<PopoverHeader>How to Fix</PopoverHeader>
<PopoverBody>
<Text>
{e.solution}
</Text>
</PopoverBody>
</PopoverContent>
</Popover>
): null}
</Stack>
</ListItem>
))}
</UnorderedList>
</Box>
);
}
Example #16
Source File: TotalStats.tsx From ksana.in with Apache License 2.0 | 5 votes |
export function TotalStats({ data }: ITotalStatsProps) {
const bgBox = useColorModeValue('white', 'gray.800')
const sum = data.reduce((a: number, b: IUrl) => a + b.hit, 0)
return (
<>
{data && data.length > 0 ? (
<Stack direction="row" justifyContent="center">
<VStack
w="full"
bg={bgBox}
boxShadow={'2xl'}
rounded={'md'}
justifyContent="center"
textAlign="center"
overflow={'hidden'}
py="2"
position="relative"
>
<Text fontSize="xs">Total Tautan</Text>
<Text fontSize="2xl" color="orange.400" fontWeight="700" zIndex="1">
{new Intl.NumberFormat('id-ID').format(data.length)}
</Text>
<IconButton
aria-label="Tautan"
bg="orange.400"
color="white"
borderRadius="3xl"
position="absolute"
bottom="-.2em"
right="-.2em"
opacity="0.5"
w="12"
h="12"
margin="0"
fontSize="4xl"
zIndex="0"
icon={<HiLink />}
/>
</VStack>
<VStack
w="full"
bg={bgBox}
boxShadow={'2xl'}
rounded={'md'}
justifyContent="center"
textAlign="center"
overflow={'hidden'}
py="2"
position="relative"
>
<Text fontSize="xs">Total Kunjungan</Text>
<Text fontSize="2xl" color="orange.400" fontWeight="700" zIndex="1">
{new Intl.NumberFormat('id-ID').format(sum)}
</Text>
<IconButton
aria-label="Tautan"
bg="orange.400"
color="white"
borderRadius="3xl"
position="absolute"
bottom="-.2em"
right="-.2em"
opacity="0.5"
w="12"
h="12"
margin="0"
fontSize="4xl"
zIndex="0"
icon={<HiChartBar />}
/>
</VStack>
</Stack>
) : null}
</>
)
}
Example #17
Source File: faq.tsx From coindrop with GNU General Public License v3.0 | 5 votes |
FAQ: FunctionComponent = () => {
const theme = useTheme();
const panelBgColor = useColorModeValue("gray.50", undefined);
return (
<Box>
<Box my={6}>
<Heading as="h1" textAlign="center">
FAQ
</Heading>
<Text textAlign="center">
Frequently Asked Questions
</Text>
</Box>
<Container maxW={theme.breakpoints.lg}>
<Accordion defaultIndex={-1} allowToggle>
{accordionText.map(({title, body}) => (
<AccordionItem key={title}>
<AccordionButton>
<Box flex="1" textAlign="left">
{title}
</Box>
<AccordionIcon />
</AccordionButton>
<AccordionPanel>
<Box
p={4}
bg={panelBgColor}
>
{body}
</Box>
</AccordionPanel>
</AccordionItem>
))}
</Accordion>
</Container>
<Text textAlign="center" mt={4} fontSize="sm">
{"Do you have a question that's not answered here? Send it to "}
<Link href={`mailto:${coindropEmail}`} isExternal>
{coindropEmail}
</Link>
</Text>
</Box>
);
}
Example #18
Source File: footer.tsx From portfolio with MIT License | 5 votes |
Footer = () => {
return (
<Stack
as="footer"
isInline
spacing={[1, 2]}
p={4}
justifyContent="space-between"
alignItems="center"
w={["100%", "85%", "80%"]}
maxW={800}
mx="auto"
>
<Flex
flexDirection={["column", "column", "row"]}
flexFlow={["column-reverse", "column-reverse"]}
justifyContent={["center", "space-between"]}
alignItems="center"
w="100%"
ju
>
{/* <HStack> */}
<Text
textAlign="center"
fontSize="sm"
color={useColorModeValue("gray.500", "gray.200")}
>
© {new Date().getFullYear()} Muhammad Ahmad{" "}
</Text>
{/* <Box fontSize="md" textAlign="left">
Website built with
<Box
as="span"
mx="2"
_before={{
cursor: "default",
content: '"❤️"'
}}
_hover={{
_before: {
content: '"☕️"'
}
}}
/>
in Pakistan{" "}??
</Box> */}
{/* </HStack> */}
<Box textAlign="center">
{siteConfig.author.accounts.map((sc, index) => (
<IconButton
key={index}
as={Link}
isExternal
href={sc.url}
aria-label={sc.label}
size="lg"
colorScheme={sc.type}
icon={sc.icon}
{...iconProps}
/>
))}
</Box>
</Flex>
</Stack>
);
}
Example #19
Source File: PermissionRequirements.tsx From bluebubbles-server with Apache License 2.0 | 5 votes |
PermissionRequirements = (): JSX.Element => {
const permissions: Array<RequirementsItem> = (useAppSelector(state => state.config.permissions) ?? []);
const [showProgress, setShowProgress] = useBoolean();
const refreshRequirements = () => {
setShowProgress.on();
checkPermissions().then(permissions => {
// I like longer spinning
setTimeout(() => {
setShowProgress.off();
}, 1000);
if (!permissions) return;
store.dispatch(setConfig({ name: 'permissions', value: permissions }));
});
};
return (
<Box border='1px solid' borderColor={useColorModeValue('gray.200', 'gray.700')} borderRadius='xl' p={3} width='325px'>
<Stack direction='row' align='center'>
<Text fontSize='lg' fontWeight='bold'>macOS Permissions</Text>
<Box
_hover={{ cursor: 'pointer' }}
animation={showProgress ? `${spin} infinite 1s linear` : undefined}
onClick={refreshRequirements}
>
<BiRefresh />
</Box>
</Stack>
<UnorderedList mt={2} ml={8}>
{permissions.map(e => (
<ListItem key={e.name}>
<Stack direction='row' align='center'>
<Text fontSize='md'><strong>{e.name}</strong>:
<Box as='span' color={e.pass ? 'green' : 'red'}>{e.pass ? 'Pass' : 'Fail'}</Box>
</Text>
{(e.pass) ? (
<Popover trigger='hover'>
<PopoverTrigger>
<Box ml={2} _hover={{ color: 'brand.primary', cursor: 'pointer' }}>
<AiOutlineInfoCircle />
</Box>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverCloseButton />
<PopoverHeader>How to Fix</PopoverHeader>
<PopoverBody>
<Text>
{e.solution}
</Text>
</PopoverBody>
</PopoverContent>
</Popover>
): null}
</Stack>
</ListItem>
))}
</UnorderedList>
</Box>
);
}
Example #20
Source File: ColorModeSwitcher.tsx From portfolio with MIT License | 5 votes |
ColorModeSwitcher: React.FC<ColorModeSwitcherProps> = props => {
const { toggleColorMode } = useColorMode();
const text = useColorModeValue("dark", "light");
const SwitchIcon = useColorModeValue(FaMoon, FaSun);
const [play] = useSound(lightswitch, {
volume: 0.05,
sprite: {
on: [0, 300],
off: [500, 300]
}
});
const handleClick = () => {
text === "dark" ? play({ id: "on" }) : play({ id: "off" });
toggleColorMode();
};
return (
<Tooltip
label={text === "dark" ? "Dark mode" : "Light mode"}
aria-label="A tooltip"
>
<IconButton
size="md"
fontSize="md"
variant="ghost"
color="current"
marginLeft="2"
onClick={handleClick}
icon={<SwitchIcon />}
aria-label={`Switch to ${text} mode`}
_hover={{
bg: useColorModeValue("gray.200", "gray.900")
}}
{...props}
/>
</Tooltip>
);
}
Example #21
Source File: Layout.tsx From lucide with ISC License | 4 votes |
Layout = ({ aside, children }: LayoutProps) => {
const router = useRouter();
const { toggleMobileMenu } = useMobileNavigationContext();
const { toggleColorMode } = useColorMode();
const currentColorMode = useColorModeValue('dark', 'light');
const ColorModeToggle = useColorModeValue(Moon, Sun);
const MobileMenuToggle = useMobileNavigationValue(Menu, X);
const showBaseNavigation = useBreakpointValue({ base: false, md: true });
const IconbuttonProps = {
size: 'md',
fontSize: 'lg',
variant: 'ghost',
color: 'current',
ml: '3',
};
function setQuery(query) {
router.push({
pathname: '/',
query: { query: query },
},
undefined,
{ shallow: true })
}
useKeyBindings({
Escape: {
fn: () => setQuery(''),
},
KeyT: {
fn: () => toggleColorMode(),
},
});
return (
<Box h="100vh">
<Flex mb={16} w="full">
<Flex
alignItems="center"
justifyContent="space-between"
pt={4}
pb={4}
margin="0 auto"
w="full"
px={5}
>
<Flex justifyContent="center" alignItems="center">
<Logo />
</Flex>
<Flex justifyContent="center" alignItems="center">
{showBaseNavigation ? (
<>
<NextLink href="/docs" passHref>
<Link marginRight={12} fontSize="xl">
Documentation
</Link>
</NextLink>
<NextLink href="/packages" passHref>
<Link marginRight={12} fontSize="xl">
Packages
</Link>
</NextLink>
<NextLink href="/license" passHref>
<Link marginRight={12} fontSize="xl">
License
</Link>
</NextLink>
<Link
href="https://github.com/lucide-icons/lucide"
isExternal
marginRight={6}
fontSize="xl"
>
Github
</Link>
</>
) : null}
<IconButton
aria-label={`Switch to ${currentColorMode} mode`}
onClick={toggleColorMode}
{...IconbuttonProps}
icon={<ColorModeToggle />}
/>
{!showBaseNavigation ? (
<IconButton
aria-label={`Open Mobile menu`}
onClick={toggleMobileMenu}
{...IconbuttonProps}
icon={<MobileMenuToggle />}
/>
) : null}
</Flex>
</Flex>
</Flex>
<Flex>
{aside ? <Box as="aside" marginRight={{ base: 0, lg: -240, }}>{aside}</Box> : null}
<Flex margin="0 auto" direction="column" maxW="1250px" px={5} width="100%">
{children}
<Divider mb={6} mt={12} />
<p style={{ alignSelf: 'center' }}>
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss">
<img src="/vercel.svg" alt="Powered by Vercel" width="200" />
</a>
</p>
<br />
</Flex>
</Flex>
</Box>
);
}
Example #22
Source File: Item.tsx From ksana.in with Apache License 2.0 | 4 votes |
export function Item({ user, data }: IUrlItemProps) {
const { showAlert, hideAlert } = useAlertContext()
const [updateId, setUpdateId] = useState<string>('')
const [updateSlug, setUpdateSlug] = useState<string>('')
const [isSuccessCopy, setSuccessCopy] = useState<boolean>(false)
const [isLoadingShare, setLoadingShare] = useState<boolean>(false)
const [isLoadingSave, setLoadingSave] = useState<boolean>(false)
const isSupportShare: boolean =
typeof window !== 'undefined' ? navigator.share !== undefined : false
const bgBox = useColorModeValue('white', 'gray.800')
const bgInput = useColorModeValue('blackAlpha.100', 'whiteAlpha.100')
const showSuccessCopy = () => {
setSuccessCopy(true)
setTimeout(() => {
setSuccessCopy(false)
}, 2000)
}
const handleCopy = async (text: string) => {
if (navigator.clipboard) {
await navigator.clipboard.writeText(text)
} else {
copy(text)
}
showSuccessCopy()
}
const handleShare = async (url: string) => {
if (navigator.share) {
setLoadingShare(true)
const jsonRes = await getMeta(url)
const shareObj = {
title: jsonRes.title,
text: jsonRes.description,
url: url
}
navigator
.share(shareObj)
// eslint-disable-next-line no-console
.then(() => setLoadingShare(false))
.catch((error) => {
setLoadingShare(false)
// eslint-disable-next-line no-console
console.error('Error sharing', error, shareObj)
})
}
}
const handleClickEdit = async (id: string) => {
if (updateId === id) {
setUpdateId('')
setUpdateSlug('')
} else {
setUpdateId(id)
setUpdateSlug('')
}
}
const handleChangeUpdatedSlug = async (e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
setUpdateSlug(value)
}
const handleClickSave = async () => {
if (updateSlug) {
setLoadingSave(true)
const { error } = await patchSlug({
id: updateId,
slug: sanitizeSlug(updateSlug),
userId: user?.id
})
if (error) {
showAlert({
title: 'Terjadi galat pada saat memperbarui data',
message: `Pesan: ${error.message}`,
onClose: () => {
hideAlert()
setLoadingSave(false)
}
})
} else {
mutate(apiUrlsGet(user?.id))
setUpdateId('')
setUpdateSlug('')
setLoadingSave(false)
}
}
}
const onConfimDelete = async (id: string) => {
const { error } = await deleteUrl({ id: id, userId: user?.id })
if (error) {
hideAlert()
showAlert({
title: 'Terjadi galat pada saat berusaha menghapus data',
message: `Pesan: ${error.message}`,
onClose: () => {
hideAlert()
}
})
}
hideAlert()
mutate(apiUrlsGet(user?.id))
}
const handleDelete = async (id: string, slug: string) => {
showAlert({
title: 'Konfirmasi hapus',
message: `Apakah kamu yakin untuk menghapus data ${HOME}${slug}? Aksi ini juga akan menghilangkan semua data statistik terkait.`,
cancelText: 'Batalkan',
confirmText: 'Ya, hapus',
onConfirm: () => {
onConfimDelete(id)
},
onClose: hideAlert
})
}
return (
<Box
key={data.slug}
w={'full'}
bg={bgBox}
boxShadow={'2xl'}
rounded={'md'}
overflow={'hidden'}
p={{ base: '4', md: '6' }}
>
{!!data.is_dynamic && (
<Tag size="sm" colorScheme="green">
Tautan dinamis
</Tag>
)}
<Flex alignItems="center" mb="4">
<Link
as="a"
fontSize={{ base: 'md', md: 'lg' }}
fontWeight="700"
color="orange.400"
href={`${HOME}${data.slug}${!!data.is_dynamic ? '/{param}' : ''}`}
display="block"
>
{`/${data.slug}`}
{!!data.is_dynamic && '/{param}'}
</Link>
</Flex>
{updateId && updateId === data.id && (
<HStack alignItems="center" mb="4" mt="2">
<Input
size="lg"
name="slug"
placeholder={'Tulis slug baru'}
bg={bgInput}
border={0}
value={updateSlug}
onChange={handleChangeUpdatedSlug}
/>
<IconButton
onClick={handleClickSave}
aria-label="Simpan slug"
size="lg"
bg="orange.400"
borderRadius="md"
isLoading={isLoadingSave}
icon={<HiSave color="#FFF" />}
/>
</HStack>
)}
<Text fontSize="small" color="gray.400" display="block" mb="2">
{data.real_url}
</Text>
<Text fontSize="small" color="gray.400">
<Text as="span" fontWeight="bold" color="orange.400">
{new Intl.NumberFormat('id-ID').format(data.hit)}
</Text>
{` `} kunjungan
</Text>
<HStack spacing={2} mt={4} flexWrap="wrap">
<IconButton
onClick={() => {
handleCopy(`${HOME}${data.slug}`)
}}
aria-label="Copy"
variant="ghost"
borderRadius="md"
icon={isSuccessCopy ? <HiCheck color="#48BB78" /> : <HiDuplicate color="#ED8936" />}
/>
{isSupportShare ? (
<IconButton
onClick={() => {
handleShare(`${HOME}${data.slug}`)
}}
aria-label="Copy"
variant="ghost"
borderRadius="md"
isLoading={isLoadingShare}
icon={<HiShare color="#ED8936" />}
/>
) : (
<SharePopover url={`${HOME}${data.slug}`} />
)}
<IconButton
onClick={() => {
handleClickEdit(data.id)
}}
aria-label="Ubah"
variant="ghost"
borderRadius="md"
icon={<HiPencil color="#ED8936" />}
/>
<IconButton
onClick={() => {
handleDelete(data.id, data.slug)
}}
aria-label="Hapus"
variant="ghost"
borderRadius="md"
icon={<HiTrash color="#ED8936" />}
/>
</HStack>
</Box>
)
}
Example #23
Source File: Navigation.tsx From bluebubbles-server with Apache License 2.0 | 4 votes |
MobileNav = ({ onOpen, onNotificationOpen, unreadCount, ...rest }: MobileProps) => {
const { colorMode, toggleColorMode } = useColorMode();
return (
<Flex
ml={{ base: 0, md: 60 }}
px={{ base: 4, md: 4 }}
height="20"
alignItems="center"
borderBottomWidth="1px"
borderBottomColor={useColorModeValue('gray.200', 'gray.700')}
justifyContent={{ base: 'space-between', md: 'flex-end' }}
{...rest}
>
<IconButton
display={{ base: 'flex', md: 'none' }}
onClick={onOpen}
variant="outline"
aria-label="open menu"
icon={<FiMenu />}
/>
<Text display={{ base: 'flex', md: 'none' }} fontSize="2xl" fontFamily="monospace" fontWeight="bold">
<img src={logo} className="logo-small" alt="logo" />
</Text>
<HStack spacing={{ base: '0', md: '1' }}>
<Tooltip label="Website Home" aria-label="website-tip">
<Link href="https://bluebubbles.app" style={{ textDecoration: 'none' }} target="_blank">
<IconButton size="lg" variant="ghost" aria-label="website" icon={<AiOutlineHome />} />
</Link>
</Tooltip>
<Tooltip label="BlueBubbles Web" aria-label="website-tip">
<Link href="https://bluebubbles.app/web" style={{ textDecoration: 'none' }} target="_blank">
<IconButton size="lg" variant="ghost" aria-label="bluebubbles web" icon={<FiMessageCircle />} />
</Link>
</Tooltip>
<Tooltip label="Sponsor Us" aria-label="sponsor-tip">
<Link href="https://github.com/sponsors/BlueBubblesApp" style={{ textDecoration: 'none' }} target="_blank">
<IconButton size="lg" variant="ghost" aria-label="donate" icon={<AiOutlineHeart />} />
</Link>
</Tooltip>
<Tooltip label="Support Us" aria-label="donate-tip">
<Link href="https://bluebubbles.app/donate" style={{ textDecoration: 'none' }} target="_blank">
<IconButton size="lg" variant="ghost" aria-label="donate" icon={<MdOutlineAttachMoney />} />
</Link>
</Tooltip>
<Tooltip label="Join our Discord" aria-label="discord-tip">
<Link href="https://discord.gg/yC4wr38" style={{ textDecoration: 'none' }} target="_blank">
<IconButton size="lg" variant="ghost" aria-label="discord" icon={<FaDiscord />} />
</Link>
</Tooltip>
<Tooltip label="Read our Source Code" aria-label="github-tip">
<Link href="https://github.com/BlueBubblesApp" style={{ textDecoration: 'none' }} target="_blank">
<IconButton size="lg" variant="ghost" aria-label="github" icon={<FiGithub />} />
</Link>
</Tooltip>
<Box position='relative' float='left'>
<IconButton
size="lg"
verticalAlign='middle'
zIndex={1}
variant="ghost"
aria-label="notifications"
icon={<FiBell />}
onClick={() => onNotificationOpen()}
/>
{(unreadCount > 0) ? (
<Badge
borderRadius='lg'
variant='solid'
colorScheme='red'
position='absolute'
margin={0}
top={1}
right={1}
zIndex={2}
>{unreadCount}</Badge>
) : null}
</Box>
<Spacer />
<Divider orientation="vertical" width={1} height={15} borderColor='gray' />
<Spacer />
<Spacer />
<Spacer />
<FormControl display='flex' alignItems='center'>
<Box mr={2}><MdOutlineDarkMode size={20} /></Box>
<Switch id='theme-mode-toggle' onChange={toggleColorMode} isChecked={colorMode === 'light'} />
<Box ml={2}><MdOutlineLightMode size={20} /></Box>
</FormControl>
</HStack>
</Flex>
);
}
Example #24
Source File: Form.tsx From ksana.in with Apache License 2.0 | 4 votes |
export function Form() {
const router = useRouter()
const { showAlert, hideAlert } = useAlertContext()
const bgBox = useColorModeValue('white', 'gray.700')
const [loading, setLoading] = useState<boolean>(false)
const [errorForm, setErrorForm] = useState<string>('')
const [email, setEmail] = useState<string>('')
const handleChangeEmail = (e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
setEmail(value)
}
const checkIsEmpty = () => {
if (email === '') {
setErrorForm('Email tidak boleh dikosongkan.')
return true
}
setErrorForm('')
return false
}
const handleResetPassword = async () => {
const { error } = await forgetPassword({ email })
if (!error) {
showAlert({
title: 'Lupa password',
message: 'Tautan untuk melakukan setel ulang kata sandi telah dikirim ke email kamu.',
onClose: () => {
hideAlert()
router.push('/')
}
})
}
}
const handleSubmit = async () => {
setLoading(true)
const isEmpty = checkIsEmpty()
if (!isEmpty) {
await handleResetPassword()
}
setLoading(false)
}
return (
<Stack spacing={8} mx={'auto'} mt="20" maxW={'lg'} py={12} px={6}>
<Stack align={'center'}>
<Heading fontSize={'4xl'} color="orange.400">
Lupa password
</Heading>
</Stack>
<Box rounded={'lg'} bg={bgBox} boxShadow={'lg'} p={8}>
<Stack spacing={4}>
<FormControl id="email" isRequired>
<FormLabel>Email</FormLabel>
<Input
isInvalid={Boolean(errorForm)}
type="email"
name="email"
value={email}
onChange={handleChangeEmail}
autoComplete="username"
/>
</FormControl>
<Button
isLoading={loading}
loadingText="Memproses"
w="full"
bg="orange.400"
_hover={{
bg: 'orange.500'
}}
onClick={handleSubmit}
>
Minta reset password
</Button>
</Stack>
</Box>
</Stack>
)
}
Example #25
Source File: ContextMenuList.tsx From wiregui with MIT License | 4 votes |
ContextMenuList: React.FC<Props & MotionBoxProps> = ({
children,
menuId,
render,
...boxProps
}) => {
const [contextMenusState, setContextMenusState] =
useRecoilState(contextMenusAtom);
const menuRef: RefObject<HTMLDivElement> = useRef(null);
const menu = useMemo(
() => contextMenusState.menus.find((m) => m.id === menuId),
[contextMenusState]
);
// where should the menu be shown?
// the ContextMenuTrigger sets this
const [position, setPosition] = useState<Position>({
left: -100,
right: 0,
top: -100,
bottom: 0,
});
// TODO: Any less manual way to do this
// figure out where to show the menu
useEffect(() => {
let left: number | undefined;
let right: number | undefined;
let top: number | undefined;
let bottom: number | undefined;
const x = contextMenusState.position.x;
const y = contextMenusState.position.y;
const menuHeight = menuRef?.current?.clientHeight;
const menuWidth = menuRef?.current?.clientWidth;
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
if (!menuHeight || !menuWidth) {
return;
}
if (x + menuWidth > windowWidth) {
right = windowWidth - x;
} else {
left = x;
}
if (y + menuHeight > windowHeight) {
bottom = windowHeight - y;
} else {
top = y;
}
setPosition({
top: `${top}px`,
bottom: `${bottom}px`,
left: `${left}px`,
right: `${right}px`,
});
}, [menuRef, contextMenusState.position.x, contextMenusState.position.y]);
// when clicking outside the menu, close it
useOutsideClick({
ref: menuRef,
handler: () => {
// close all menus
closeContextMenus();
},
});
const bgColor = useColorModeValue("gray.50", "gray.300");
const closeContextMenus = () => {
setContextMenusState((oldState) => {
return {
...oldState,
position: {
x: -100,
y: -100,
},
menus: oldState.menus.map((m) => ({
...m,
isOpen: false,
})),
};
});
};
return (
<MotionBox
variants={motionVariants}
animate={menu && menu.isOpen ? "enter" : "exit"}
ref={menuRef}
borderWidth={1}
position="fixed"
bg={bgColor}
minW={40}
w={52}
// maxW={96}
borderRadius="md"
display="flex"
flexDirection="column"
zIndex="popover"
{...position}
{...boxProps}
>
{/* either use the render prop or the children */}
{render
? render({
menuId,
closeContextMenus,
passData: contextMenusState.passData,
})
: children}
</MotionBox>
);
}
Example #26
Source File: notes-list.tsx From notebook with MIT License | 4 votes |
NotesList: React.SFC<NotesListProps> = ({
notes,
handleClick,
setNotes
}) => {
const bg = useColorModeValue("white", "#2f3244");
const [selectedNote, setSelectedNote] = React.useState<note>();
const toast = useToast();
const { isOpen, onOpen, onClose } = useDisclosure();
const onDelete = (
id: string,
e: React.MouseEvent<SVGElement, MouseEvent>
) => {
const newNotes: note[] = notes.filter((note: note) => note.id !== id);
setNotes(newNotes);
showToast();
e.stopPropagation();
};
const onClick = (id: string, e: React.MouseEvent<SVGElement, MouseEvent>) => {
handleClick(id);
e.stopPropagation();
};
const handleSelectedNote = (note: note) => {
setSelectedNote(note);
onOpen();
};
const showToast = () => {
toast({
title: "Note deleted.",
status: "success",
position: "top",
duration: 2000,
isClosable: true
});
};
return (
<>
<AnimateSharedLayout type="crossfade">
<Box minH={"50vh"}>
{/* <SimpleGrid
columns={[1, 2, 2, 3]}
mt="40px"
gridGap="10px"
position="relative"
overflow="hidden"
> */}
<StackGrid columnWidth={330}>
{notes.map(note => (
<Fade in={true}>
<motion.div
whileHover={{ y: -10 }}
layoutId={note.id}
onClick={() => handleSelectedNote(note)}
>
<Center py={2} px={2} key={note.id}>
<Box
maxH={"400px"}
w="100%"
boxShadow={"lg"}
rounded={"md"}
p={6}
overflow={"hidden"}
cursor="pointer"
_hover={{ boxShadow: "xl" }}
bg={bg}
role="group"
// onClick={() => handleClick(note.id, true)}
>
<Stack>
<Flex
_groupHover={{ justifyContent: "space-between" }}
justifyContent="center"
align="center"
>
<Box>
<Text
color={"green.500"}
textTransform={"uppercase"}
fontWeight={800}
fontSize={"sm"}
letterSpacing={1.1}
>
Note
</Text>
</Box>
<Box
_groupHover={{ display: "block" }}
display="none"
>
<HStack spacing="2">
<Icon
color={"green.500"}
_hover={{ color: "green.600" }}
_groupHover={{ display: "block" }}
as={EditIcon}
w={4}
h={4}
onClick={e => onClick(note.id, e)}
/>
<Icon
color={"green.500"}
_hover={{ color: "#ca364a" }}
_groupHover={{ display: "block" }}
as={DeleteIcon}
w={4}
h={4}
onClick={e => onDelete(note.id, e)}
/>
</HStack>
</Box>
</Flex>
<Heading
fontSize={"xl"}
fontFamily={"body"}
textTransform="capitalize"
noOfLines={2}
>
{note.title}
</Heading>
<Text
color={"gray.500"}
fontSize="md"
noOfLines={{ base: 3, md: 4 }}
>
{note.body}
</Text>
</Stack>
</Box>
</Center>
</motion.div>
</Fade>
))}
</StackGrid>
{/* </SimpleGrid> */}
</Box>
{isOpen ? (
<NoteModal
isOpen={isOpen}
onClose={onClose}
selectedNote={selectedNote}
/>
) : (
""
)}
</AnimateSharedLayout>
</>
);
}
Example #27
Source File: CompetitorComparisonTable.tsx From coindrop with GNU General Public License v3.0 | 4 votes |
CompetitorComparisonTable: FunctionComponent = () => {
const theme = useTheme();
const green = useColorModeValue(theme.colors.green['500'], theme.colors.green['300']);
const red = useColorModeValue(theme.colors.red['500'], theme.colors.red['300']);
const orange = useColorModeValue(theme.colors.orange['500'], theme.colors.orange['300']);
const logoOutlineColor = useColorModeValue(theme.colors.gray['800'], theme.colors.gray['900']);
const StyledTd: FunctionComponent<{ value: string | number }> = ({ value }) => {
let backgroundColor;
switch (value) {
case 'Unlimited':
case 'Any':
case 'None':
case 'Freemium':
case 'Yes':
backgroundColor = green;
break;
case '$9/mo':
backgroundColor = orange;
break;
default:
backgroundColor = red;
}
return (
<td style={{backgroundColor, color: "white"}}>
{value}
</td>
);
};
return (
<Box>
<Flex
id="full-width-comparison-table"
justify="center"
textAlign="center"
display={['none', 'none', 'flex']}
>
<table className={styles.comparisontable}>
<thead>
<tr>
<th> </th>
<th>
<Flex align="center">
{coindropData.displayName}
<PiggyLogoIcon ml={1} size="19px" color={logoOutlineColor} />
</Flex>
</th>
{competitorData.map(obj => (
<th key={obj.id}>
{obj.displayName}
{obj.icon}
</th>
))}
</tr>
</thead>
<tbody>
<tr>
<td>Fees</td>
{data.map(obj => (
<StyledTd value={obj.fees} key={obj.id} />
))}
</tr>
<tr>
<td>Payment methods</td>
{data.map(obj => (
<StyledTd value={obj.paymentMethods} key={obj.id} />
))}
</tr>
<tr>
<td># Pages per account</td>
{data.map(obj => (
<StyledTd value={obj.numPagesPerAccount} key={obj.id} />
))}
</tr>
<tr>
<td>Open-source</td>
{data.map(obj => (
<StyledTd value={obj.isOpenSource} key={obj.id} />
))}
</tr>
<tr>
<td>Subscribers</td>
{data.map(obj => (
<StyledTd value={obj.subscriberFeatures} key={obj.id} />
))}
</tr>
</tbody>
</table>
</Flex>
{competitorData.map(obj => (
<Flex
key={obj.id}
id={`partial-width-comparison-table-${obj.id}`}
justify="center"
textAlign="center"
display={['flex', 'flex', 'none']}
>
<table className={styles.comparisontable}>
<thead>
<tr>
<th> </th>
<th>
<Flex align="center">
Coindrop
<PiggyLogoIcon ml={1} size="19px" color={logoOutlineColor} />
</Flex>
</th>
<th>
{obj.displayName}
{obj.icon}
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Fees</td>
<StyledTd value={coindropData.fees} />
<StyledTd value={obj.fees} />
</tr>
<tr>
<td>Payment methods</td>
<StyledTd value={coindropData.paymentMethods} />
<StyledTd value={obj.paymentMethods} />
</tr>
<tr>
<td># Pages per account</td>
<StyledTd value={coindropData.numPagesPerAccount} />
<StyledTd value={obj.numPagesPerAccount} />
</tr>
<tr>
<td>Open-source</td>
<StyledTd value={coindropData.isOpenSource} />
<StyledTd value={obj.isOpenSource} />
</tr>
<tr>
<td>Subscribers</td>
<StyledTd value={coindropData.subscriberFeatures} />
<StyledTd value={obj.subscriberFeatures} />
</tr>
</tbody>
</table>
</Flex>
))}
</Box>
);
}
Example #28
Source File: AuthForm.tsx From ksana.in with Apache License 2.0 | 4 votes |
export function AuthForm({ state }: IAuthFormProps) {
const router = useRouter()
const { showAlert, hideAlert } = useAlertContext()
const bgBox = useColorModeValue('white', 'gray.700')
const [internalState, setInternalState] = useState<any>(state)
const [isLogin, setIsLogin] = useState<any>(state === 'login')
const [loading, setLoading] = useState<boolean>(false)
const [errorForm, setErrorForm] = useState<string>('')
const [email, setEmail] = useState<string>('')
const [password, setPassword] = useState<string>('')
const toggleState = () => {
if (internalState === 'login') {
setInternalState('register')
setIsLogin(false)
} else {
setInternalState('login')
setIsLogin(true)
}
}
const handleChangeEmail = (e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
setEmail(value)
}
const handleChangePassword = (e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
setPassword(value)
}
const checkIsEmpty = () => {
if (email === '' || password === '') {
setErrorForm('Email dan password tidak boleh dikosongkan.')
return true
}
setErrorForm('')
return false
}
const handleSubmit = async () => {
setLoading(true)
const isEmpty = checkIsEmpty()
if (!isEmpty) {
if (isLogin) {
await handleLogin()
} else {
await handleRegister()
}
}
setLoading(false)
}
const handleLoginGoogle = async () => {
setLoading(true)
await loginWithGoogle()
setLoading(false)
}
const handleLoginGithub = async () => {
setLoading(true)
await loginWithGithub()
setLoading(false)
}
const handleLoginTwitter = async () => {
setLoading(true)
await loginWithTwitter()
setLoading(false)
}
const processResponse = async ({ session, error, stateType = 'login' }: IProcessResponse) => {
if (error) {
setErrorForm(error.message)
return false
}
if (session && !error) {
if (stateType === 'login') {
// only set for the login flow
await setSessionToServer(EVENT_SIGN_IN, session)
}
showAlert({
title: `${stateType === 'login' ? 'Login' : 'Register'} success`,
message: `${
stateType === 'login'
? 'Selamat datang kembali!'
: 'Terima kasih telah mendaftar. Silahkan melakukan verifikasi dengan mengklik tautan yang kami kirimkan melalui email.'
}`,
onClose: () => {
hideAlert()
if (stateType === 'login') {
setTimeout(() => {
// trigger hard redirect to dashboard page
// TODO: mutate SWR to reload the user data
window.location.assign(dashboard)
}, 500)
} else {
router.push('/')
}
}
})
}
}
const handleLogin = async () => {
const { session, error } = await login({
email: email,
password: password
})
processResponse({ session, error, stateType: 'login' })
}
const handleRegister = async () => {
const { session, error } = await register({
email: email,
password: password
})
processResponse({ session, error, stateType: 'register' })
if (!error) {
showAlert({
title: 'Registrasi Berhasil!',
message:
'Terima kasih telah mendaftar. Silahkan melakukan verifikasi dengan mengklik tautan yang kami kirimkan melalui email.'
})
} else {
showAlert({
title: 'Registrasi Gagal!',
message: 'Silahkan ulangi proses registrasi!'
})
}
}
const handleKeyPress = (e: KeyboardEvent) => {
if (e.code === '13') {
handleSubmit()
}
}
return (
<Stack spacing={8} mx={'auto'} mt="20" maxW={'lg'} py={12} px={6}>
<Stack align={'center'}>
<Heading
fontWeight={700}
fontSize={{ base: '3xl', sm: '4xl', md: '5xl' }}
lineHeight={'110%'}
color="orange.400"
>
{isLogin ? 'Masuk ke akunmu' : 'Daftarkan akun baru'}
</Heading>
</Stack>
<Box rounded={'lg'} bg={bgBox} boxShadow={'lg'} p={8}>
<VStack
direction="row"
align={'center'}
justify={'center'}
borderBottom="1px"
borderColor="gray.200"
py="4"
>
{isEnableGoogleLogin && (
<Button
isLoading={loading}
loadingText="Memproses"
variant={'outline'}
w="full"
onClick={handleLoginGoogle}
leftIcon={<FcGoogle />}
>
{isLogin ? 'Masuk dengan Google' : 'Daftar dengan Google'}
</Button>
)}
{isEnableTwitterLogin && (
<Button
isLoading={loading}
loadingText="Memproses"
variant={'outline'}
w="full"
onClick={handleLoginTwitter}
leftIcon={<SiTwitter fill="#1DA1F2" />}
>
{isLogin ? 'Masuk dengan Twitter' : 'Daftar dengan Twitter'}
</Button>
)}
{isEnableGithubLogin && (
<Button
isLoading={loading}
loadingText="Memproses"
variant={'outline'}
w="full"
onClick={handleLoginGithub}
leftIcon={<SiGithub />}
>
{isLogin ? 'Masuk dengan Github' : 'Daftar dengan Github'}
</Button>
)}
</VStack>
<Stack spacing={4} mt="4">
<FormControl id="email" isRequired>
<FormLabel>Email</FormLabel>
<Input
isInvalid={Boolean(errorForm)}
type="email"
name="email"
value={email}
onChange={handleChangeEmail}
onKeyPress={handleKeyPress}
autoComplete="username"
/>
</FormControl>
<FormControl id="password" isRequired>
<FormLabel>Password</FormLabel>
<Input
isInvalid={Boolean(errorForm)}
type="password"
name="password"
value={password}
onChange={handleChangePassword}
onKeyPress={handleKeyPress}
autoComplete={isLogin ? 'current-password' : 'new-password'}
/>
</FormControl>
{errorForm && (
<Text color="red.300" fontSize="xs">
Galat: {errorForm}
</Text>
)}
<Stack spacing={10}>
{isLogin ? (
<Stack
direction={{ base: 'column', sm: 'row' }}
align={'start'}
justify={'space-between'}
>
<Button variant="link" as={Link} color={'orange.400'} href={forgetPasword}>
Lupa password?
</Button>
</Stack>
) : null}
<Button
isLoading={loading}
loadingText="Memproses"
w="full"
bg="orange.400"
_hover={{
bg: 'orange.500'
}}
color="white"
onClick={handleSubmit}
>
{isLogin ? 'Masuk' : 'Daftar Sekarang'}
</Button>
</Stack>
{isLogin ? (
<Stack direction="row" align={'center'} justify={'center'}>
<Text>Belum punya akun? </Text>
<Button variant="link" as={Link} color={'orange.400'} onClick={toggleState}>
Daftar sekarang
</Button>
</Stack>
) : (
<Stack direction="row" align={'center'} justify={'center'}>
<Text>Sudah punya akun? </Text>
<Button variant="link" as={Link} color={'orange.400'} onClick={toggleState}>
Masuk
</Button>
</Stack>
)}
</Stack>
</Box>
</Stack>
)
}
Example #29
Source File: notebook-post.tsx From portfolio with MIT License | 4 votes |
NotebookPost: React.SFC<PostProps> = () => {
const textColor = useColorModeValue("gray.500", "gray.200");
const post = articles[4];
return (
<>
<VStack mt={0} mb={6} spacing={1} align="start">
<Heading as="h1" fontSize="3xl" lineHeight="shorter" fontWeight="bold">
{post.title}
</Heading>
<Divider
orientation="horizontal"
opacity={1}
borderBottomWidth={0}
height={"1px"}
bg={"gray.200"}
/>
</VStack>
<Flex
justifyContent={"space-between"}
flexDirection={["column", "row", "row"]}
>
<HStack spacing={2} isInline>
<Text fontSize="sm" fontWeight="400" color={textColor}>
{post.published}
</Text>
<Text fontSize="sm" fontWeight="400" color={textColor}>
•
</Text>
<Tooltip hasArrow label="Views" placement="top">
<Flex alignItems="center">
<Text
fontSize="sm"
noOfLines={1}
fontWeight="400"
align="left"
color={textColor}
>
{post.views}
</Text>
<Icon as={FaEye} ml={1} color={textColor} />
</Flex>
</Tooltip>
<Text fontSize="sm" fontWeight="600" color={textColor}>
•
</Text>
<Tooltip hasArrow label="Read time" placement="top">
<Text
fontSize="sm"
noOfLines={1}
fontWeight="400"
align="left"
color={textColor}
>
{post.readTime}
</Text>
</Tooltip>
</HStack>
<HStack spacing={1} alignItems="center">
{post.tags.map(tag => (
<Tag
size="sm"
padding="0 3px"
key={tag}
colorScheme={getTagColor(tag)}
>
{tag}
</Tag>
))}
</HStack>
</Flex>
<HStack align="end" mt={5}>
<Link href={post.live} isExternal>
<Button
ml={2}
variant="outline"
size={["sm"]}
color={useColorModeValue("green.600", "green.200")}
bg={useColorModeValue("white", "gray.800")}
leftIcon={<BiLinkExternal size={18} />}
>
Demo
</Button>
</Link>
<Link href={post.github_url} isExternal>
<Button
ml={2}
variant="outline"
size={["sm"]}
color={useColorModeValue("green.600", "green.200")}
bg={useColorModeValue("white", "gray.800")}
leftIcon={<FiGithub size={18} />}
>
Github link
</Button>
</Link>
</HStack>
<Box height={["35vh", "45vh", "55vh", "70vh"]} marginTop={5}>
<Carousel images={post.images} />
</Box>
<VStack spacing={5} align={"start"} mt={6}>
<Header fontSize={"xl"} mt={0} mb={0}>
What will you learn?
</Header>
<Box fontSize="md">
<UnorderedList textAlign="left" paddingLeft={5} m={0}>
<ListItem>How to create a CRUD app with react</ListItem>
<ListItem>How to create a responsive app using ChakraUi</ListItem>
<ListItem>How to use animations with framer-motion</ListItem>
<ListItem>How to create slider with framer-motion</ListItem>
</UnorderedList>
</Box>
</VStack>
<VStack spacing={5} align={"start"} mt={6}>
<Header fontSize={"xl"} mt={0} mb={0}>
Built with
</Header>
<Box fontSize="md">
<UnorderedList textAlign="left" paddingLeft={5} m={0}>
<ListItem>
Programming language -{" "}
<Link
href="https://www.typescriptlang.org/"
isExternal
color={"blue.500"}
>
Typescript
</Link>
</ListItem>
<ListItem>
Front-end library -{" "}
<Link
href="https://github.com/facebook/react/"
isExternal
color={"blue.500"}
>
React
</Link>
</ListItem>
<ListItem>
UI components -{" "}
<Link href="https://chakra-ui.com/" isExternal color={"blue.500"}>
Chakra-ui
</Link>
</ListItem>
<ListItem>
Animation library -{" "}
<Link
href="https://www.framer.com/motion/"
isExternal
color={"blue.500"}
>
Framer motion
</Link>
</ListItem>
<ListItem>
Notes display -{" "}
<Link
href="https://github.com/tsuyoshiwada/react-stack-grid"
isExternal
color={"blue.500"}
>
react-stack-grid
</Link>
</ListItem>
<ListItem>
Forms Validation -{" "}
<Link
href="https://react-hook-form.com/"
isExternal
color={"blue.500"}
>
React hook form
</Link>
</ListItem>
<ListItem>
Icons -{" "}
<Link
href="https://react-icons.github.io/react-icons/"
isExternal
color={"blue.500"}
>
React icons
</Link>
</ListItem>
<ListItem>
Images placeholder -{" "}
<Link href="https://blurha.sh/" isExternal color={"blue.500"}>
blurhash
</Link>
</ListItem>
<ListItem>
Progressive image loading -{" "}
<Link
href="https://github.com/FormidableLabs/react-progressive-image"
isExternal
color={"blue.500"}
>
react-progressive-image
</Link>
</ListItem>
</UnorderedList>
</Box>
</VStack>
</>
);
}