@chakra-ui/react#Icon TypeScript Examples
The following examples show how to use
@chakra-ui/react#Icon.
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: NotificationsTable.tsx From bluebubbles-server with Apache License 2.0 | 6 votes |
NotificationsTable = ({ notifications }: { notifications: Array<NotificationItem> }): JSX.Element => {
return (
<Table variant="striped" colorScheme="blue">
<TableCaption>
Alerts are normal to have. As long as the server recovers,
you have nothing to worry about. Alerts are mostly helpful when you
are experiencing an issue and want to see if any errors have occured.
</TableCaption>
<Thead>
<Tr>
<Th>Type</Th>
<Th>Notification</Th>
<Th isNumeric>Time / Read</Th>
</Tr>
</Thead>
<Tbody>
{notifications.map(item => (
<Tr key={item.id} color={(item?.read ?? false) ? 'gray.400' : 'current'}>
<Td>
<Icon
ml={2}
fontSize="24"
as={AlertTypeIcon[item.type] ?? AiOutlineWarning}
/>
</Td>
<Td>{item.message}</Td>
<Td isNumeric>
<Flex flexDirection="row" justifyContent='flex-end' alignItems='center'>
<Text mr={1}>{item.timestamp.toLocaleString()}</Text>
{(item?.read ?? false) ? <BsCheckAll fontSize={24} /> : null}
</Flex>
</Td>
</Tr>
))}
</Tbody>
</Table>
);
}
Example #2
Source File: TipCards.tsx From coindrop with GNU General Public License v3.0 | 6 votes |
TipCards: FunctionComponent = () => (
<>
<Heading
as="h2"
size="lg"
mt={4}
>
Physical Cards
</Heading>
<Center mt={4}>
<Image src={tipCardPng} height="225" width="225" />
</Center>
<Center>
<a href="/shop">
<Button
mt={4}
href="/shop"
leftIcon={<Icon as={CgShoppingCart} />}
colorScheme="green"
>
Buy Now
</Button>
</a>
</Center>
</>
)
Example #3
Source File: SocialLinks.tsx From coindrop with GNU General Public License v3.0 | 6 votes |
SocialLink: FunctionComponent<SocialLinkProps> = ({ icon, href }) => (
<Link
href={href}
ml={3}
isExternal
className={styles.link}
>
<Icon
as={icon}
boxSize="1.5rem"
/>
</Link>
)
Example #4
Source File: index.tsx From ksana.in with Apache License 2.0 | 6 votes |
export function Features() {
return (
<Container maxW={'5xl'} mx="auto" as="section" mt="16">
<Stack p={4} spacing="16">
<Heading textAlign="center" as="h3">
Fitur Kunci Ksana.in
</Heading>
<SimpleGrid columns={{ base: 1, md: 3 }} spacing={10}>
<Feature
icon={<Icon as={FcLink} w={10} h={10} />}
title={'Mempercantik Tautan'}
text={'Tidak perlu lagi mengingat tautan yang panjang, pesan tautan dambaanmu sekarang'}
/>
<Feature
icon={<Icon as={FcTreeStructure} w={10} h={10} />}
title={'Bagikan Tautan'}
text={
'Sangat mudah membagikan tautan ke berbagai sosial media dan pesan instan, langsung dari halaman dashboard'
}
/>
<Feature
icon={<Icon as={FcBullish} w={10} h={10} />}
title={'Pantau Statistik'}
text={'Pantau jumlah pengguna yang mengunjungi tautanmu dengan mudah'}
/>
</SimpleGrid>
</Stack>
</Container>
)
}
Example #5
Source File: Logo.tsx From lucide with ISC License | 6 votes |
Logo = () => (
<NextLink href="/" passHref>
<Link display="flex" _hover={{ textDecoration: 'none' }}>
<Icon boxSize={12} marginRight="8px">
<LogoImage />
</Icon>
<Text fontSize="40px" fontWeight="normal" lineHeight="48px">
Lucide
</Text>
</Link>
</NextLink>
)
Example #6
Source File: ChakraDateInput.tsx From ke with MIT License | 6 votes |
ChakraDateInput = forwardRef<HTMLInputElement, ChakraDateInputProps>(
({ className, inputClassName, ...props }, ref) => (
<InputGroup className={className}>
<InputLeftElement
zIndex="unset"
fontSize="20px"
width="44px"
justifyContent="flex-start"
pl="16px"
pointerEvents="none"
>
<Icon as={Calendar} />
</InputLeftElement>
{/* Это обёртка */}
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<Input paddingStart="44px" className={inputClassName} {...props} ref={ref} />
</InputGroup>
)
)
Example #7
Source File: ToClipboard.tsx From ke with MIT License | 6 votes |
ToClipboard = ({ value, onClick, notifier, children, ...rest }: ToClipboardProps): JSX.Element => {
const handleClick = useCallback(() => {
let realValue: string | undefined
if (typeof value === 'function') {
realValue = value()
} else {
realValue = value
}
if (realValue) {
navigator.clipboard.writeText(realValue)
if (notifier) notifier.notifySuccess('Скопировано в буфер обмена')
}
if (onClick) onClick()
}, [onClick, notifier, value])
return (
<Box as="button" type="button" display="flex" alignItems="center" onClick={handleClick} {...rest}>
<Icon as={Copy} h={4} w={4} display="inline-block" color="blue.500" />
{!!children && <Box ml={3}>{children}</Box>}
</Box>
)
}
Example #8
Source File: CourseRating.tsx From fresh-coupons with GNU General Public License v3.0 | 6 votes |
CourseRating = (props: CustomerReviewsProps) => {
const { rating, reviewCount, ...stackProps } = props
if(!reviewCount || !rating) return (
<Text fontSize="sm" fontWeight="medium" color={useColorModeValue('gray.600', 'gray.300')}>
Not enough rating
</Text>
)
return (
<HStack spacing="1" {...stackProps}>
<Badge colorScheme="orange" variant="solid" px="2" rounded="full">
{rating}
</Badge>
{length && reviewCount && (
<>
<Flex align="center">
{Array.from({length: +rating!}).map((_, index) => (
<Icon key={index} as={HiStar} color="orange.500"/>
))}
</Flex>
<Text fontSize="sm" fontWeight="medium" color={useColorModeValue('gray.600', 'gray.300')}>
({reviewCount})
</Text>
</>
)}
</HStack>
)
}
Example #9
Source File: CourseCard.tsx From fresh-coupons with GNU General Public License v3.0 | 6 votes |
function CourseInstructors({instructors, ...props}: CourseInstructorsProps) {
if (!instructors) {
return <></>
}
return (
<HStack mt="4" spacing={3} {...props}>
{instructors && instructors.map(instructor => (
<HStack spacing={1} key={instructor.url}>
<Icon as={BsPersonSquare} color="gray.400"/>
<Link
href={`https://${instructor.url}`}
isExternal
fontSize="sm"
fontWeight="medium"
_visited={{
color: "cadetblue"
}}
color={useColorModeValue('gray.600', 'gray.300')}
>
{instructor.name}
<ExternalLinkIcon mx="2"/>
</Link>
</HStack>
))}
</HStack>
)
}
Example #10
Source File: Navigation.tsx From bluebubbles-server with Apache License 2.0 | 6 votes |
NavItem = ({ icon, to, children, ...rest }: NavItemProps) => {
const location = useLocation();
return (
<Flex
align="center"
p="4"
mx="4"
borderRadius="lg"
role="group"
cursor="pointer"
_hover={{
bg: 'brand.primary',
color: 'white'
}}
color={location.pathname === to ? 'brand.primary' : 'current'}
{...rest}
>
{icon && (
<Icon
mr="4"
fontSize="16"
_groupHover={{
color: 'white'
}}
as={icon}
/>
)}
{children}
</Flex>
);
}
Example #11
Source File: CourseCard.tsx From fresh-coupons with GNU General Public License v3.0 | 6 votes |
function EnrolledStudentsCount({enrolledStudentsCount, ...props}: EnrolledStudentsCountProps) {
if (!enrolledStudentsCount) {
return <></>
}
return (
<HStack {...props}>
<Icon as={HiUserGroup} fontSize="xl" color="gray.400"/>
<Text
fontSize="sm"
fontWeight="medium"
color={useColorModeValue('gray.600', 'gray.300')}
>
<b>{enrolledStudentsCount}</b> enrolled
</Text>
</HStack>
)
}
Example #12
Source File: CourseCard.tsx From fresh-coupons with GNU General Public License v3.0 | 6 votes |
function CourseDuration({duration, isFreeCourse = false}: { duration: string | null, isFreeCourse : boolean }) {
if (!duration) {
return <></>
}
if (isFreeCourse) {
duration = `${Math.round(+duration/360)/10} hours`
}
return (
<HStack spacing="1">
<Icon boxSize={8} as={HiOutlineClock} color="gray.400"/>
<Text
fontSize="sm"
fontWeight="medium"
color={useColorModeValue('gray.600', 'gray.300')}
>
{duration}
</Text>
</HStack>
)
}
Example #13
Source File: CourseCard.tsx From fresh-coupons with GNU General Public License v3.0 | 6 votes |
function LastUpdated({lastUpdated, ...props}: LastUpdatedProps) {
if (!lastUpdated) {
return <></>
}
return (
<HStack spacing="1" {...props}>
<Icon boxSize={8} as={HiOutlineCalendar} color="gray.400"/>
<Text
fontSize="sm"
fontWeight="medium"
color={useColorModeValue('gray.600', 'gray.300')}
>
{lastUpdated}
</Text>
</HStack>
)
}
Example #14
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 #15
Source File: MultiPoolPortal.tsx From rari-dApp with GNU Affero General Public License v3.0 | 5 votes |
NewsAndTwitterLink = ({
celebrate = false,
}: {
celebrate?: boolean;
}) => {
const { t } = useTranslation();
return (
<Column
expand
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
>
<Link href="https://twitter.com/RariCapital" isExternal>
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
px={4}
py={3}
>
<Icon as={FaTwitter} boxSize="20px" />
<Heading ml={2} size="sm">
{t("Latest Rari News")}
</Heading>
</Row>
</Link>
<ModalDivider />
<Column
expand
px={4}
mainAxisAlignment="center"
crossAxisAlignment="flex-start"
>
<NewsMarquee celebrate={celebrate} />
</Column>
</Column>
);
}
Example #16
Source File: WebhooksTable.tsx From bluebubbles-server with Apache License 2.0 | 5 votes |
WebhooksTable = ({ webhooks }: { webhooks: Array<WebhookItem> }): JSX.Element => {
const dispatch = useAppDispatch();
const dialogRef = useRef(null);
const [selectedId, setSelectedId] = useState(undefined as number | undefined);
return (
<Box>
<Table variant="striped" colorScheme="blue">
<TableCaption>These are callbacks to receive events from the BlueBubbles Server</TableCaption>
<Thead>
<Tr>
<Th>URL</Th>
<Th>Event Subscriptions</Th>
<Th isNumeric>Actions</Th>
</Tr>
</Thead>
<Tbody>
{webhooks.map(item => (
<Tr key={item.id}>
<Td>{item.url}</Td>
<Td>{JSON.parse(item.events).map((e: string) => webhookEventValueToLabel(e)).join(', ')}</Td>
<Td isNumeric>
<Grid templateColumns="repeat(2, 1fr)">
<Tooltip label='Edit' placement='bottom'>
<GridItem _hover={{ cursor: 'pointer' }} onClick={() => setSelectedId(item.id)}>
<Icon as={AiOutlineEdit} />
</GridItem>
</Tooltip>
<Tooltip label='Delete' placement='bottom'>
<GridItem _hover={{ cursor: 'pointer' }} onClick={() => dispatch(remove(item.id))}>
<Icon as={FiTrash} />
</GridItem>
</Tooltip>
</Grid>
</Td>
</Tr>
))}
</Tbody>
</Table>
<AddWebhookDialog
existingId={selectedId}
modalRef={dialogRef}
isOpen={!!selectedId}
onClose={() => {
setSelectedId(undefined);
}}
/>
</Box>
);
}
Example #17
Source File: SearchInput.tsx From lucide with ISC License | 5 votes |
SearchInput = (
({ onChange, count }: SearchInputProps) => {
const { colorMode } = useColorMode();
const [urlValue, setUrlValue] = useRouterParam('search');
const [inputValue, setInputValue] = useState('');
const debouncedValue = useDebounce(inputValue.trim(), 300);
useUpdateEffect(() => {
onChange(debouncedValue);
setUrlValue(debouncedValue);
}, [debouncedValue]);
useEffect(() => {
if (urlValue && !inputValue) {
setInputValue(urlValue);
onChange(urlValue);
}
}, [urlValue]);
const ref = useRef(null);
// Keyboard `/` shortcut
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === '/' && ref.current !== document.activeElement) {
event.preventDefault();
ref.current.focus();
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, []);
return (
<InputGroup position="sticky" top={4} zIndex={1}>
<InputLeftElement
children={
<Icon>
<SearchIcon />
</Icon>
}
/>
<Input
ref={ref}
placeholder={`Search ${count} icons (Press "/" to focus)`}
onChange={(event) => setInputValue(event.target.value)}
value={inputValue}
bg={colorMode == 'light' ? theme.colors.white : theme.colors.gray[700]}
/>
</InputGroup>
);
}
)
Example #18
Source File: ColorPicker.tsx From lucide with ISC License | 5 votes |
function ColorPicker({ hsv, hsl, onChange, value: color }: ColorPickerProps) {
const [value, setValue] = useState(color);
const input = useRef<HTMLInputElement>(null);
useEffect(() => {
if (color !== value && input.current !== document.activeElement) {
setValue(color === 'currentColor' ? color : String(color).toUpperCase());
}
}, [color]);
const handleChange = (e) => {
let value = e.target.value;
setValue(value);
onChange(value, e);
};
return (
<div>
<FormLabel htmlFor="color" fontWeight={'bold'}>
Color
</FormLabel>
<InputGroup>
<InputLeftElement
children={
<Icon>
<rect x={0} width={24} y={0} height={24} fill={value} rx={2} />
</Icon>
}
/>
<Input value={value} name="color" onChange={handleChange} ref={input} />
</InputGroup>
<div
style={{
width: '100%',
paddingBottom: '75%',
position: 'relative',
overflow: 'hidden',
marginTop: '0.5rem',
borderRadius: '0.375rem',
border: '1px solid',
borderColor: 'inherit',
}}
>
<Saturation hsl={hsl} hsv={hsv} onChange={onChange} />
</div>
<div
style={{
minHeight: '2em',
position: 'relative',
margin: '0.5rem 0 0 0',
borderRadius: '0.375rem',
border: '1px solid',
borderColor: 'inherit',
overflow: 'hidden',
}}
>
<Hue hsl={hsl} onChange={onChange} direction={'horizontal'} />
</div>
</div>
);
}
Example #19
Source File: MultiPoolPortal.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
PoolDetailCard = ({ pool }: { pool: Pool }) => {
const { t } = useTranslation();
const { rari, isAuthed } = useRari();
const { poolType, poolName, poolLogo } = usePoolInfo(pool);
const {
isOpen: isDepositModalOpen,
onOpen: openDepositModal,
onClose: closeDepositModal,
} = useDisclosure();
const authedOpenModal = useAuthedCallback(openDepositModal);
const { data: balanceData, isLoading: isPoolBalanceLoading } =
usePoolBalance(pool);
const poolAPY = usePoolAPY(pool);
const noSlippageCurrencies = useNoSlippageCurrencies(pool);
if (isPoolBalanceLoading) {
return (
<Center
height={{
md: isAuthed ? "235px" : "110px",
base: isAuthed ? "330px" : "215px",
}}
>
<Spinner />
</Center>
);
}
const myBalance = balanceData!;
const formattedBalance = formatBalanceBN(rari, myBalance, pool === Pool.ETH);
// const rgtAPR = useRGTAPR();
return (
<>
{isDepositModalOpen ? (
<PoolTypeProvider pool={pool}>
<DepositModal
isOpen={isDepositModalOpen}
onClose={closeDepositModal}
/>
</PoolTypeProvider>
) : null}
<Column
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
expand
p={4}
>
<Box width="50px" height="50px" flexShrink={0}>
<Image src={poolLogo} />
</Box>
<Row mainAxisAlignment="flex-start" crossAxisAlignment="center" mt={2}>
<Heading fontSize="xl" lineHeight="2.5rem" ml="12px">
{poolName}
</Heading>
<SimpleTooltip
label={
"Rebalances " +
(noSlippageCurrencies
? noSlippageCurrencies.join(" + ")
: " ? ") +
" between " +
getSDKPool({ rari, pool: poolType })
// Filter out empty pools
.allocations.POOLS.filter((el) => !!el)
.join(", ")
}
>
<QuestionIcon ml={2} mb="3px" boxSize="12px" />
</SimpleTooltip>
</Row>
<SimpleTooltip label={t("Your balance in this pool")}>
<Text mt={4} mb={5} fontSize="md" textAlign="center">
{isPoolBalanceLoading ? "$?" : formattedBalance}
</Text>
</SimpleTooltip>
<Text fontWeight="bold" textAlign="center">
{poolAPY ?? "?"}% APY
{/* +{" "}
<SimpleTooltip label={t("Extra returns from $RGT")}>
<span>
({rgtAPR ?? "?"}%{" "}
<Image display="inline" src={SmallLogo} boxSize="20px" />)
</span>
</SimpleTooltip> */}
</Text>
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
width="100%"
mt="auto"
>
<Link
/* @ts-ignore */
as={RouterLink}
width="100%"
className="no-underline"
to={"/pools/" + pool.toString()}
>
<DashboardBox
mt={4}
width="100%"
height="45px"
borderRadius="7px"
fontSize="xl"
fontWeight="bold"
>
<Center expand>{t("Access")}</Center>
</DashboardBox>
</Link>
<DashboardBox
mt={4}
flexShrink={0}
as="button"
onClick={authedOpenModal}
height="45px"
ml={2}
width="45px"
borderRadius="7px"
fontSize="xl"
fontWeight="bold"
>
<Center expand>
<Icon as={MdSwapHoriz} boxSize="30px" />
</Center>
</DashboardBox>
</Row>
</Column>
</>
);
}
Example #20
Source File: TranchesPage.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
TrancheColumn = ({
tranchePool,
trancheRating,
}: {
tranchePool: TranchePool;
trancheRating: TrancheRating;
}) => {
const { t } = useTranslation();
const isMobile = useIsSmallScreen();
const { saffronData } = useSaffronData();
const principal = usePrincipal(tranchePool, trancheRating);
const {
isOpen: isDepositModalOpen,
onOpen: openDepositModal,
onClose: closeDepositModal,
} = useDisclosure();
const authedOpenModal = useAuthedCallback(openDepositModal);
return (
<>
<DepositModal
trancheRating={trancheRating}
tranchePool={tranchePool}
isOpen={isDepositModalOpen}
onClose={closeDepositModal}
/>
<Column
mainAxisAlignment="space-between"
crossAxisAlignment="center"
expand
ml={isMobile ? 0 : 4}
mt={isMobile ? 8 : 0}
// TODO: REMOVE STYLE ONCE AA TRANCHE IS ADDED
style={
trancheRating === TrancheRating.AA
? {
opacity: tranchePool !== "USDC" ? "0.3" : "1",
pointerEvents: "none",
}
: {}
}
>
<Column mainAxisAlignment="flex-start" crossAxisAlignment="center">
<Heading size="sm">
{trancheRating} {t("Tranche")}
</Heading>
<SimpleTooltip label={t("Your balance in this tranche")}>
<Text textAlign="center" mt={4}>
{principal ?? "?"} {tranchePool}
</Text>
</SimpleTooltip>
<Text textAlign="center" fontWeight="bold" mt={4}>
{trancheRating === "AA"
? // TODO REMOVE HARDCODED CHECK ABOUT AA TRANCHE ONCE IT'S IMPLEMENTED
"0.45%"
: saffronData
? saffronData.pools[tranchePoolIndex(tranchePool)].tranches?.[
trancheRating
]?.["total-apy"] + "% APY"
: "?% APY"}
</Text>
</Column>
<DashboardBox
onClick={authedOpenModal}
mt={4}
as="button"
height="45px"
width={isMobile ? "100%" : "85%"}
borderRadius="7px"
fontSize="xl"
fontWeight="bold"
>
<Center expand>
<Icon as={MdSwapHoriz} boxSize="30px" />
</Center>
</DashboardBox>
</Column>
</>
);
}
Example #21
Source File: top-nav.tsx From portfolio with MIT License | 4 votes |
export default function TopNav() {
const { isOpen, onOpen, onClose } = useDisclosure();
const menuProps = {
bg: useColorModeValue("gray.200", "gray.900"),
color: useColorModeValue("blue.500", "blue.200")
};
return (
<>
<Box bg={useColorModeValue("white", "gray.700")} px={4} boxShadow={"lg"}>
<Flex
h={16}
alignItems={"center"}
justifyContent={"space-between"}
w={["90%", "85%", "80%"]}
maxW={800}
mx="auto"
>
<IconButton
size={"md"}
icon={isOpen ? <AiOutlineClose /> : <GiHamburgerMenu />}
aria-label={"Open Menu"}
display={["inherit", "inherit", "none"]}
onClick={isOpen ? onClose : onOpen}
/>
<HStack spacing={8} alignItems={"center"}>
<Box>
<Avatar
as={Link}
size={"sm"}
href={"/portfolio"}
src={UserIcon}
// src={"https://avatars2.githubusercontent.com/u/37842853?v=4"}
/>
</Box>
<HStack
as={"nav"}
spacing={4}
display={{ base: "none", md: "flex" }}
>
{webLinks.map((link, index) => (
<NavLink
key={index}
name={link.name}
path={link.path}
onClose={onClose}
/>
))}
<Menu isLazy>
<MenuButton
as={Button}
variant="ghost"
size="sm"
px={2}
py={1.5}
fontSize={"1em"}
rounded={"md"}
height={"auto "}
_hover={menuProps}
_expanded={menuProps}
_focus={{ boxShadow: "outline" }}
rightIcon={<BiChevronDown size={18} />}
>
Links
</MenuButton>
<MenuList zIndex={5}>
<Link as={RouterNavLink} to="/tech-stack">
<MenuItem>
<HStack>
<Icon
as={AiTwotoneThunderbolt}
size={18}
color={useColorModeValue("blue.500", "blue.200")}
/>
<Text>Tech Stack</Text>
</HStack>
</MenuItem>
</Link>
<Link as={RouterNavLink} to="/open-source">
<MenuItem>
<HStack>
<Icon
as={BsBook}
size={18}
color={useColorModeValue("blue.500", "blue.200")}
/>
<Text>Open Source</Text>
</HStack>
</MenuItem>
</Link>
<Link as={RouterNavLink} to="/story-timeline">
<MenuItem>
<HStack>
<Icon
as={MdTimeline}
size={18}
color={useColorModeValue("blue.500", "blue.200")}
/>
<Text>Developer Story</Text>
</HStack>
</MenuItem>
</Link>
<Link as={RouterNavLink} to="/achievements">
<MenuItem>
<HStack>
<Icon
as={BsCheckCircle}
size={18}
color={useColorModeValue("blue.500", "blue.200")}
/>
<Text>Achievements</Text>
</HStack>
</MenuItem>
</Link>
</MenuList>
</Menu>
</HStack>
</HStack>
<Flex alignItems={"center"}>
<IconButton
as={Link}
href={"https://github.com/MA-Ahmad"}
size={"md"}
icon={<FaGithub />}
aria-label={"Github account"}
bg={useColorModeValue("white", "gray.700")}
_hover={{
textDecoration: "none",
bg: useColorModeValue("gray.200", "gray.900")
}}
/>
<ColorModeSwitcher justifySelf="flex-end" />
</Flex>
</Flex>
{isOpen ? (
<Box
pb={4}
w={["100%", "100%", "80%"]}
maxW={800}
display={["inherit", "inherit", "none"]}
>
<Stack as={"nav"} spacing={4}>
{mobileLinks.map((link, index) => (
<NavLink
index={index}
name={link.name}
path={link.path}
onClose={onClose}
/>
))}
</Stack>
</Box>
) : null}
</Box>
</>
);
}
Example #22
Source File: tech-stack.tsx From portfolio with MIT License | 4 votes |
TechStack = () => {
const [skillsList, setSkillsList] = useState([]);
React.useEffect(() => {
setSkillsList(skills);
}, []);
const filterSkills = tab => {
console.log(skills.filter(skill => skill.type === tab));
if (tab.length) setSkillsList(skills.filter(skill => skill.type === tab));
else setSkillsList(skills);
};
return (
<PageSlideFade>
<VStack spacing={8}>
<Section>
<VStack>
<Header mt={0} mb={1}>
Tech Stack
</Header>
<Text
fontSize={"xl"}
color={useColorModeValue("gray.500", "gray.200")}
maxW="lg"
textAlign="center"
>
A list of my favorite tools and technologies that I use on a
regular basis.
</Text>
</VStack>
</Section>
<Section>
<Tabs
variant="soft-rounded"
colorScheme="blue"
align="center"
w="100%"
>
<TabList display="flex" flexWrap="wrap">
<Tab
bg={useColorModeValue("gray.100", "gray.800")}
color={useColorModeValue("gray.600", "gray.500")}
_selected={{
color: "green.800",
bg: "green.100"
}}
mr={2}
mt={2}
onClick={() => filterSkills("")}
>
<HStack spacing={1}>
<Icon as={AiTwotoneThunderbolt} weight="fill" />
<Text>All</Text>
</HStack>
</Tab>
<Tab
bg={useColorModeValue("gray.100", "gray.800")}
color={useColorModeValue("gray.500", "gray.500")}
_selected={{
color: useColorModeValue("gray.100", "gray.800"),
bg: useColorModeValue("gray.900", "gray.100")
}}
mr={2}
mt={2}
onClick={() => filterSkills("development")}
>
<HStack spacing={1}>
<Icon as={BiDesktop} weight="fill" />
<Text>Web Development</Text>
</HStack>
</Tab>
<Tab
bg={useColorModeValue("gray.100", "gray.800")}
color={useColorModeValue("gray.600", "gray.500")}
_selected={{
color: "green.800",
bg: "green.100"
}}
mr={2}
mt={2}
onClick={() => filterSkills("design")}
>
<HStack spacing={1}>
<Icon as={GiSpiderWeb} weight="fill" />
<Text>Web Design</Text>
</HStack>
</Tab>
<Tab
bg={useColorModeValue("gray.100", "gray.800")}
color={useColorModeValue("gray.600", "gray.500")}
_selected={{
color: "red.800",
bg: "red.100"
}}
mr={2}
mt={2}
onClick={() => filterSkills("devops")}
>
<HStack spacing={1}>
<Icon as={AiOutlineCloudServer} weight="fill" />
<Text>Devops</Text>
</HStack>
</Tab>
</TabList>
<TabPanels minHeight={"45vh"}>
<TabPanel px={0}>
<MotionBox
variants={container}
initial="hidden"
animate="visible"
>
<SimpleGrid columns={[1, 1, 2]} spacing={4} mt={8}>
{skillsList.map((tool, index) => (
<SkillCard
key={index}
name={tool.name}
description={tool.description}
image={tool.image}
platform={"web"}
link={tool.link}
/>
))}
</SimpleGrid>
</MotionBox>
</TabPanel>
<TabPanel px={0}>
<MotionBox
variants={container}
initial="hidden"
animate="visible"
>
<SimpleGrid columns={[1, 2]} spacing={4} mt={8}>
{skillsList.map((tool, index) => (
<SkillCard
key={index}
name={tool.name}
description={tool.description}
image={tool.image}
platform={"web"}
link={tool.link}
/>
))}
</SimpleGrid>
</MotionBox>
</TabPanel>
<TabPanel px={0}>
<MotionBox
variants={container}
initial="hidden"
animate="visible"
>
<SimpleGrid columns={[1, 2]} spacing={4} mt={8}>
{skillsList.map((tool, index) => (
<SkillCard
key={index}
name={tool.name}
description={tool.description}
image={tool.image}
platform={"web"}
link={tool.link}
/>
))}
</SimpleGrid>
</MotionBox>
</TabPanel>
<TabPanel px={0}>
<MotionBox
variants={container}
initial="hidden"
animate="visible"
>
<SimpleGrid columns={[1, 2]} spacing={4} mt={8}>
{skillsList.map((tool, index) => (
<SkillCard
key={index}
name={tool.name}
description={tool.description}
image={tool.image}
platform={"web"}
link={tool.link}
/>
))}
</SimpleGrid>
</MotionBox>
</TabPanel>
</TabPanels>
</Tabs>
</Section>
</VStack>
</PageSlideFade>
);
}
Example #23
Source File: AppDomains.tsx From ledokku with MIT License | 4 votes |
AppDomains = ({ appId }: AppDomainProps) => {
const toast = useToast();
const { data, loading /* error */ } = useAppByIdQuery({
variables: {
appId,
},
ssr: false,
skip: !appId,
});
const {
data: domainsData,
loading: domainsDataLoading,
refetch: appDomainsRefetch,
} = useDomainsQuery({
variables: {
appId,
},
});
const [
removeDomainMutation,
{ loading: removeDomainMutationLoading },
] = useRemoveDomainMutation();
const handleRemoveDomain = async (domain: string) => {
try {
await removeDomainMutation({
variables: {
input: {
appId,
domainName: domain,
},
},
refetchQueries: [{ query: DomainsDocument, variables: { appId } }],
});
toast.success('Domain removed successfully');
} catch (error) {
toast.error(error.message);
}
};
if (!data) {
return null;
}
// // TODO display error
if (loading) {
// TODO nice loading
return <p>Loading...</p>;
}
const { app } = data;
if (!app) {
// TODO nice 404
return <p>App not found.</p>;
}
return (
<>
<Box py="5">
<Heading as="h2" size="md">
Domain management
</Heading>
<Text fontSize="sm" color="gray.400">
List of domains you have added to {app.name} app
</Text>
</Box>
<Grid templateColumns={{ sm: 'repeat(1, 1fr)', md: 'repeat(3, 1fr)' }}>
<GridItem colSpan={2}>
<Box mb="8">
{domainsDataLoading ? <Spinner /> : null}
{domainsData?.domains.domains.length === 0 ? (
<Text fontSize="sm" color="gray.400">
Currently you haven't added any custom domains to your app
</Text>
) : null}
{domainsData?.domains.domains.map((domain: any) => (
<Flex
key={domain}
justifyContent="space-between"
alignItems="center"
>
<Link
href={`http://${domain}`}
isExternal
display="flex"
alignItems="center"
>
{domain} <Icon as={FiExternalLink} mx="2" />
</Link>
<IconButton
aria-label="Delete"
variant="ghost"
colorScheme="red"
icon={<FiTrash2 />}
disabled={removeDomainMutationLoading}
onClick={() => handleRemoveDomain(domain)}
/>
</Flex>
))}
</Box>
<AddAppDomain appId={appId} appDomainsRefetch={appDomainsRefetch} />
</GridItem>
</Grid>
</>
);
}
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: live-data-card.tsx From portfolio with MIT License | 4 votes |
RepositoryCard = (props: RepositoryCardProps) => {
const {
title,
description,
language,
url,
stargazers_count,
forks_count,
} = props;
const handleLinkClick = (
e: React.MouseEvent<HTMLParagraphElement, MouseEvent>,
link: string
) => {
window.open(link);
e.stopPropagation();
};
return (
<MotionBox whileHover={{ y: -5 }}>
<Box
size="xl"
py={2}
px={[2, 4]}
mt={2}
rounded="xl"
borderWidth="1px"
bg={useColorModeValue("white", "gray.800")}
borderColor={useColorModeValue("gray.100", "gray.700")}
_hover={{
shadow: "lg",
textDecoration: "none"
}}
>
<VStack overflow="hidden" align="start" spacing={1}>
<VStack spacing={1} align="start" w="100%">
<Flex
justifyContent={"space-between"}
width="100%"
onClick={e => handleLinkClick(e, url)}
>
<Tooltip hasArrow label="Github link" placement="top">
<HStack cursor={"pointer"}>
<Icon as={FiGithub} boxSize="0.9em" mt={"1px"} />
<Text
fontSize="sm"
noOfLines={1}
fontWeight="600"
align="left"
color={"blue.500"}
>
{title}
</Text>
</HStack>
</Tooltip>
<HStack cursor={"pointer"} onClick={e => handleLinkClick(e, url)}>
{forks_count && (
<Box _hover={{ color: "blue.500" }}>
<Icon as={BiGitRepoForked} boxSize="0.9em" mt={"1px"} />
<Box as="span" ml="1" fontSize="sm">
{forks_count}
</Box>
</Box>
)}
<Box _hover={{ color: "blue.500" }}>
<Icon as={BiStar} boxSize="0.9em" mt={"1px"} />
<Box as="span" ml="1" fontSize="sm">
{stargazers_count}
</Box>
</Box>
</HStack>
</Flex>
{language && (
<Flex justifyContent={"space-between"} width="100%">
<Box>
<HStack spacing="1">
<Tag size="sm" colorScheme={getTagColor(language)}>
<Text fontSize={["0.55rem", "inherit", "inherit"]}>
{language}
</Text>
</Tag>
</HStack>
</Box>
</Flex>
)}
</VStack>
<Box>
<Text color="gray.500" fontSize="sm" noOfLines={2} textAlign="left">
{description}
</Text>
</Box>{" "}
</VStack>
</Box>
</MotionBox>
);
}
Example #26
Source File: post-card.tsx From portfolio with MIT License | 4 votes |
PostCard: React.SFC<PostCardProps> = ({ article }) => {
const textColor = useColorModeValue("gray.500", "gray.200");
const devIcon = useColorModeValue(dev, dev2);
return (
<CardTransition>
<VStack
spacing={1}
p={4}
isExternal
_hover={{ shadow: "md", textDecoration: "none" }}
borderWidth="1px"
position="relative"
rounded="md"
bg={useColorModeValue("white", "gray.800")}
align="left"
>
{article.external ? (
<Tooltip hasArrow label="Dev.to" placement="top">
<Image
src={devIcon}
width="2rem"
height="2rem"
position="absolute"
color="#cbd5e0"
right="0.5rem"
top="-14px"
/>
</Tooltip>
) : (
<Tooltip hasArrow label="mahmad.me" placement="top">
<Box position="absolute" color="#cbd5e0" right="0.5rem" top="-14px">
<Badge ml="1" variant="solid" colorScheme="blackAlpha">
Website
</Badge>
</Box>
</Tooltip>
)}
<Heading fontSize="lg" align="left" mt={0}>
{article.external ? (
<Text as={Link} href={article.link} target="_blank">
{article.title}
</Text>
) : (
<Link as={NavLink} to={article.link}>
{article.title}
</Link>
)}
{article.isNew && (
<Badge
ml="1"
mb="1"
colorScheme="green"
fontSize="0.7em"
lineHeight={1.5}
>
New
</Badge>
)}
</Heading>
<HStack spacing={2} isInline>
<Tooltip hasArrow label="Published" placement="top">
<Text fontSize="sm" fontWeight="400" color={textColor}>
{article.published}
</Text>
</Tooltip>
<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}
>
{article.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}
>
{article.readTime}
</Text>
</Tooltip>
<HStack spacing={1} alignItems="center" d={["none", "none", "flex"]}>
{article.tags.map(tag => (
<Tag
size="sm"
padding="0 3px"
key={tag}
colorScheme={getTagColor(tag)}
>
{tag}
</Tag>
))}
</HStack>
</HStack>
<HStack spacing={1} alignItems="center" d={["flex", "flex", "none"]}>
{article.tags.map(tag => (
<Tag
size="sm"
padding="0 3px"
key={tag}
colorScheme={getTagColor(tag)}
>
{tag}
</Tag>
))}
</HStack>
<Text align="left" fontSize="md" noOfLines={4} color={textColor}>
{article.desc}
</Text>
</VStack>
</CardTransition>
);
}
Example #27
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>
</>
);
}
Example #28
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 #29
Source File: ContactsTable.tsx From bluebubbles-server with Apache License 2.0 | 4 votes |
ContactsTable = ({
contacts,
onCreate,
onDelete,
onUpdate,
onAddressAdd,
onAddressDelete
}: {
contacts: Array<ContactItem>,
onCreate?: (contact: ContactItem) => void,
onDelete?: (contactId: number | string) => void,
onUpdate?: (contact: Partial<ContactItem>) => void,
onAddressAdd?: (contactId: number | string, address: string) => void;
onAddressDelete?: (contactAddressId: number) => void;
}): JSX.Element => {
const dialogRef = useRef(null);
const [dialogOpen, setDialogOpen] = useBoolean();
const [selectedContact, setSelectedContact] = useState(null as any | null);
return (
<Box>
<Table variant="striped" colorScheme="blue" size='sm'>
<Thead>
<Tr>
<Th>Edit</Th>
<Th>Display Name</Th>
<Th isNumeric>Addresses</Th>
</Tr>
</Thead>
<Tbody>
{contacts.map(item => {
const name = (item.displayName && item.displayName.length > 0)
? item.displayName
: [item?.firstName, item?.lastName].filter((e) => e && e.length > 0).join(' ');
const addresses = [
...(item.phoneNumbers ?? []).map(e => e.address),
...(item.emails ?? []).map(e => e.address)
];
return (
<Tr key={`${item.sourceType}-${item.id}-${name}-${addresses.join('_')}`}>
<Td _hover={{ cursor: (item?.sourceType === 'api') ? 'auto' : 'pointer' }} onClick={() => {
if (item?.sourceType === 'api') return;
setSelectedContact(item);
setDialogOpen.on();
}}>
{(item?.sourceType === 'api') ? (
<Tooltip label="Not Editable" hasArrow aria-label='not editable tooltip'>
<span>
<Icon as={MdOutlineEditOff} />
</span>
</Tooltip>
): (
<Tooltip label="Click to Edit" hasArrow aria-label='editable tooltip'>
<span>
<Icon as={AiOutlineEdit} />
</span>
</Tooltip>
)}
</Td>
<Td>{name}</Td>
<Td isNumeric>{addresses.map((addr) => (
<Badge ml={2} key={`${name}-${addr}-${addresses.length}`}>{addr}</Badge>
))}</Td>
</Tr>
);
})}
</Tbody>
</Table>
<ContactDialog
modalRef={dialogRef}
isOpen={dialogOpen}
existingContact={selectedContact}
onDelete={onDelete}
onCreate={onCreate}
onUpdate={onUpdate}
onAddressAdd={onAddressAdd}
onAddressDelete={onAddressDelete}
onClose={() => {
setSelectedContact(null);
setDialogOpen.off();
}}
/>
</Box>
);
}