@chakra-ui/react#Center TypeScript Examples

The following examples show how to use @chakra-ui/react#Center. 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: Home.tsx    From wiregui with MIT License 6 votes vote down vote up
export default function Home() {
  return (
    <Content>
      <Flex direction="column" justify="center" marginLeft="30%">
        <Center>
          <Image
            src="../icons/dragon.png"
            width="50%"
            opacity="50%"
            filter="grayscale(100%)"
            draggable="false"
          />
        </Center>
        <Center mt="10" opacity="75%">
          Click{" "}
          <Badge mx="1" variant="outline" colorScheme="orange">
            New Tunnel
          </Badge>{" "}
          to add a new tunnel
        </Center>
        <Center mt="4" opacity="75%">
          Click an existing tunnel to toggle
        </Center>
      </Flex>
    </Content>
  );
}
Example #2
Source File: EmptyList.tsx    From calories-in with MIT License 6 votes vote down vote up
function EmptyList({ onAddMeal }: Props) {
  return (
    <Center
      textAlign="center"
      bg="white"
      boxShadow="base"
      borderRadius={6}
      flex={1}
      p={6}
      flexDirection="column"
    >
      <VStack spacing={6}>
        <Text fontSize="xl" fontWeight="medium" textColor="gray.500">
          You haven't added any meals to this day yet
        </Text>
        <Text maxWidth="450px" mt={3} fontSize="md" textColor="gray.500">
          Days can be specific weekdays or just types of days. For example: a
          training or a rest day.
        </Text>
        <Button
          mt={3}
          onClick={onAddMeal}
          colorScheme="teal"
          variant="outline"
          size="md"
          leftIcon={<PlusStyled size={16} pointerEvents="none" />}
        >
          Add meal
        </Button>
      </VStack>
    </Center>
  )
}
Example #3
Source File: Loader.tsx    From calories-in with MIT License 6 votes vote down vote up
function Loader({ label }: Props) {
  return (
    <Center height="200px" spacing={2}>
      <Flex flexDirection="column" alignItems="center">
        <Spinner size="lg" color="teal" />
        <Text mt={4} fontSize="lg" fontWeight="medium">
          {label}
        </Text>
      </Flex>
    </Center>
  )
}
Example #4
Source File: Badge.tsx    From calories-in with MIT License 6 votes vote down vote up
function Badge({ children, count, forwardedRef, ...rest }: Props) {
  const prevCount = useSameOrPreviousValue(count)

  return (
    <Box position="relative" ref={forwardedRef} {...rest}>
      {children}

      <Fade in={count > 0}>
        <Center
          width="20px"
          top="-5px"
          right="-5px"
          height="20px"
          bg="teal.500"
          position="absolute"
          borderRadius="full"
          pointerEvents="none"
          boxShadow="base"
        >
          <Text fontWeight="bold" fontSize="xs" textColor="white">
            {count === 0 ? prevCount : count}
          </Text>
        </Center>
      </Fade>
    </Box>
  )
}
Example #5
Source File: TrackVideo.tsx    From takeout-app with MIT License 6 votes vote down vote up
TrackOfflineView: React.FC = () => {
  return (
    <AspectRatio ratio={16 / 9}>
      <Center w="100%" h="100%">
        <VStack>
          <Box w="95px" h="95px" css={{ filter: "grayscale(1)" }}>
            <picture>
              <source type="image/webp" srcSet="/assets/hero_hamburger.webp" />
              <Image src="/assets/hero_hamburger.svg" w="100%" h="100%" alt="" />
            </picture>
          </Box>
          <Heading as="div" color={Colors.textMuted}>
            Offline...
          </Heading>
        </VStack>
      </Center>
    </AspectRatio>
  );
}
Example #6
Source File: ScreenHeroFiller.tsx    From takeout-app with MIT License 6 votes vote down vote up
ScreenHeroFiller: React.FC = () => {
  return (
    <Center w="100%" h="100%">
      <VStack spacing="3vw" css={{ "& svg": { height: "auto", width: "100%" } }}>
        <Image src="/assets/hero_hamburger.webp" h="30vw" />
        <Logo />
      </VStack>
    </Center>
  );
}
Example #7
Source File: TipCards.tsx    From coindrop with GNU General Public License v3.0 6 votes vote down vote up
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 #8
Source File: ShareOptions.tsx    From coindrop with GNU General Public License v3.0 6 votes vote down vote up
ShareOptionsForRestaurants: FC = () => (
    <Center>
        <Box mt={6}>
            <Image src={tipCardRestaurantPng} height="350px" width="350px" />
            <Text mt={2} mb={2} textAlign="center">
                Text and design can be customized
            </Text>
            <Text mt={2} mb={3} textAlign="center">
                Starting at $19 for 500 cards
            </Text>
            <Center>
                <a
                    href="/shop"
                >
                    <Button>
                        Order Now
                    </Button>
                </a>
            </Center>
        </Box>
    </Center>
)
Example #9
Source File: ComponentMapping.tsx    From coindrop with GNU General Public License v3.0 6 votes vote down vote up
components = {
    h1: ({ children }) => <Heading as="h1" my="1.5rem" size="2xl">{children}</Heading>,
    h2: ({ children }) => <Heading as="h2" my="1.5rem" size="xl">{children}</Heading>,
    h3: ({ children }) => <Heading as="h3" my="1.5rem" size="lg">{children}</Heading>,
    h4: ({ children }) => <Heading as="h4" my="1.5rem" size="md">{children}</Heading>,
    p: ({ children }) => <Text mb="1.5rem" fontSize="lg">{children}</Text>,
    Center,
    ul: ({ children }) => <UnorderedList mb="1.5rem">{children}</UnorderedList>,
    ol: ({ children }) => <OrderedList mb="1.5rem">{children}</OrderedList>,
    li: ({ children }) => <ListItem fontSize="lg">{children}</ListItem>,
    Image,
    ImageBorder,
    code: Code,
    CodeBlock,
    a: ({ children, href }) => <u><Link href={href} isExternal>{children}</Link></u>,
    NextLink: ({ children, href }) => <u><NextLink href={href}>{children}</NextLink></u>,
}
Example #10
Source File: Layout.tsx    From next-crud with MIT License 6 votes vote down vote up
Layout: React.FC<IProps> = ({ title, backRoute, children }) => {
  return (
    <Box height="100vh">
      <Header title={title} backRoute={backRoute} />
      <Container mt={4}>
        <Center>{children}</Center>
      </Container>
    </Box>
  )
}
Example #11
Source File: IntroStepper.tsx    From dope-monorepo with GNU General Public License v3.0 6 votes vote down vote up
export default function IntroStepper(props: Props) {
    const [ loading, setLoading ] = useState(false);
    
    useEffect(() => {
        props.manager.events.on('game', () => setLoading(true));
    }, []);

    return (
        <ChakraProvider theme={theme}>
            <Center style={{
                height: "100vh",
                backdropFilter: "brightness(50%)",
            }}>
                {loading ? <Spinner size="xl" color="white" /> : <Container style={{
                    padding: "1rem",
                    borderStyle: "solid",
                    boxShadow: "0px 0px 15px rgba(0,0,0,1)",
                    borderColor: "black",
                    borderWidth: "0px",
                    backgroundColor: "white",
                    borderRadius: "7px",
                }}>
                {
                    props.hustlerData?.length > 0 ? 
                        <HasHustler 
                            manager={props.manager} 
                            hustlerData={props.hustlerData}
                        /> : 
                        <NoHustler 
                            manager={props.manager} 
                            hustlerData={props.hustlerData}
                        />
                }
                </Container>}
            </Center>
        </ChakraProvider>
    );
}
Example #12
Source File: EventWelcome.tsx    From dope-monorepo with GNU General Public License v3.0 6 votes vote down vote up
export default function EventWelcome(props: Props) {
    const [ loading, setLoading ] = useState(false);
    
    useEffect(() => {
        props.manager.events.on('game', () => setLoading(true));
    }, []);

    return (
        <ChakraProvider theme={theme}>
            <Center style={{
                height: "100vh",
                backdropFilter: "brightness(50%)",
            }}>
                {loading ? <Spinner size="xl" color="white" /> : <Container style={{
                    padding: "1rem",
                    borderStyle: "solid",
                    boxShadow: "0px 0px 15px rgba(0,0,0,1)",
                    borderColor: "black",
                    borderWidth: "0px",
                    backgroundColor: "white",
                    borderRadius: "7px",
                }}>
                {
                    <Stepper 
                        manager={props.manager} 
                    />
                }
                </Container>}
            </Center>
        </ChakraProvider>
    );
}
Example #13
Source File: DropZone.tsx    From bluebubbles-server with Apache License 2.0 6 votes vote down vote up
DropZone = ({ text, isDragging = false, isLoaded = false, loadedText = null }: DropZoneProps): JSX.Element => {
    const dragColor = getColor(isLoaded, isDragging);
    const dragFontSize = isDragging ? 'lg' : 'md';
    const dragIconSize = isDragging ? 36 : 28;
    return (
        <Box
            borderRadius='3xl'
            borderWidth='1px'
            minHeight='100px'
            border='dashed'
            borderColor={dragColor}
            pl={5}
            pr={5}
        >
            <Center height='100%'>
                <Flex flexDirection="row" justifyContent="center" alignItems='center'>
                    <Box transition='all 2s ease'>
                        {/* The key is required for the color to change */}
                        <RiDragDropLine key={dragColor} size={dragIconSize} color={dragColor} />
                    </Box>
                    
                    <Text
                        ml={3}
                        color={dragColor}
                        transition='all .2s ease'
                        fontSize={dragFontSize}
                        textAlign='center'
                    >
                        {isLoaded && !isDragging ? loadedText : text}
                    </Text>
                </Flex>
            </Center>
        </Box>
    );
}
Example #14
Source File: SortHandler.tsx    From ke with MIT License 6 votes vote down vote up
export function SortHandler({ orderDirection, onChange, headerValue }: SortHandlerProps): JSX.Element {
  return (
    <Flex>
      <Box pr="2">{headerValue}</Box>
      <Spacer />
      <Center>
        <SortDirection value={orderDirection} onChange={onChange} />
      </Center>
    </Flex>
  )
}
Example #15
Source File: OrderedTable.factory.tsx    From ke with MIT License 6 votes vote down vote up
function addOrdering(header: HeaderConfig | ReactNode, orderingName: string | number): HeaderConfig {
  const normalizedHeader = normalizeHeader(header)
  const { value } = normalizedHeader

  const orderedValue =
    typeof value === 'function' ? (
      (columnIndex: number) => (
        <Flex>
          <Box p="2">{value(columnIndex)}</Box>
          <Spacer />
          <Center>
            <Field name={orderingName} as={Order} />
          </Center>
        </Flex>
      )
    ) : (
      <Flex>
        <Box pr="2">{value}</Box>
        <Spacer />
        <Center>
          <Field name={orderingName} as={Order} />
        </Center>
      </Flex>
    )

  return {
    ...normalizedHeader,
    value: orderedValue,
  }
}
Example #16
Source File: index.tsx    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function Home() {
  const { isError, gardens, error } = useDendronGardens();
  if (isError) return <div>failed to load: {JSON.stringify(error)}</div>;
  let extra: any;
  // if (_.isEmpty(gardens)) {
  //   extra = <Button>New Garden from Git</Button>;
  // }
  if (_.isEmpty(gardens)) {
    extra = (
      <Box maxW="32rem">
        <VStack spacing={4} align="stretch">
          <Center>
            <Heading mb={4}>Welcome to Dendron</Heading>
          </Center>
          <Text fontSize="xl">
            If you haven&apos;t already done so, you can install Dendron by following
            the instructions &nbsp;
            <Link
              href="https://dendron.so/notes/678c77d9-ef2c-4537-97b5-64556d6337f1.html"
              isExternal
            >
              here
            </Link>
          </Text>
          <Button>Publish a new site from Git (coming soon) </Button>
        </VStack>
      </Box>
    );
  }
  return (
    <>
      <Head>
        <title>Dendron</title>
        <link rel="icon" href="/favicon.ico" />
        <script type="text/javascript" src="/static/memberful.js" />
      </Head>

      <Grid justifyContent="center">{extra}</Grid>
    </>
  );
}
Example #17
Source File: AllCoupons.tsx    From fresh-coupons with GNU General Public License v3.0 5 votes vote down vote up
function AllCoupons() {
  const {isOpen, onOpen, onClose} = useDisclosure()
  const btnRef = React.useRef<HTMLButtonElement>(null)

  const courses = useCourses()

  return (
    <>
      <Button ref={btnRef} colorScheme="teal" onClick={onOpen}>
        Open
      </Button>
      <Drawer
        isOpen={isOpen}
        placement="right"
        onClose={onClose}
        size={"4xl"}
        finalFocusRef={btnRef}
      >
        <DrawerOverlay/>
        <DrawerContent>
          <DrawerCloseButton/>
          <DrawerBody>
            <Box my={9}>
              <Center>
                <Heading my={3} className={"course-list-title"} textAlign="center">Premium courses with
                  discount</Heading>
              </Center>
              <Stack spacing="10" py="5">
                {Object.entries(courses.coursesWithCoupon)
                  .sort(([_, course]) => course.courseDetails.language === 'English' ? -1 : 1)
                  .map(([url, course]) => (
                  <CourseCard key={url} course={course}/>
                ))}
              </Stack>
            </Box>
            <Box>
              <Center>
                <Heading my={3} className={"course-list-title"} textAlign="center">More free courses</Heading>
              </Center>
              <Stack spacing="10" py="5">
                {Object.entries(courses.freeCourses).map(([url, course]) => (
                  <CourseCard key={url} course={course}/>
                ))}
              </Stack>
            </Box>
          </DrawerBody>
        </DrawerContent>
      </Drawer>
    </>
  )
}
Example #18
Source File: Hustlers.tsx    From dope-monorepo with GNU General Public License v3.0 5 votes vote down vote up
Hustlers = () => {
    const [hustlers, setHustlers] = React.useState<any>();

    useEffect(() => {
        if (!(window.ethereum as any)?.selectedAddress) return;

        fetch(`https://api.dopewars.gg/wallets/${ethers.utils.getAddress(
            (window.ethereum as any).selectedAddress,
          )}/hustlers`).then(res => res.json()).then(res => setHustlers(res));
    }, []);
    
    return (
        <div>
            {hustlers ? <SimpleGrid columns={2} spacing={5} paddingBottom="8">
                {
                    hustlers.map((hustler: any, i: number) =>
                        <VStack key={i}>
                            <Text paddingBottom="0px">
                                {hustler.id} {hustler.name ? " - " + hustler.name : ""}
                            </Text>
                            <object width="70%" type="image/svg+xml" data={hustler.svg} />
                            { localStorage.getItem(`gameSelectedHustler_${(window.ethereum as any).selectedAddress}`) !== hustler.id ? <Popover>
                                <PopoverTrigger>
                                    <Button variant="primary">
                                        Set as selected hustler
                                    </Button>
                                </PopoverTrigger>
                                <PopoverContent>
                                    <PopoverArrow />
                                    <PopoverCloseButton />
                                    <PopoverHeader>Are you sure?</PopoverHeader>
                                    <PopoverBody>The game needs to be reloaded in order to modify your selected hustler</PopoverBody>
                                    <PopoverFooter>
                                        <Button variant="primary" onClick={() => {
                                            localStorage.setItem(`gameSelectedHustler_${(window.ethereum as any).selectedAddress}`, hustler.id);
                                            window.location.reload();
                                        }}>
                                            Confirm
                                        </Button>
                                    </PopoverFooter>
                                </PopoverContent>
                            </Popover> : undefined }
                        </VStack>
                    )
                }
            </SimpleGrid> : <Center padding="4">
                    <Spinner size="lg"/>
                </Center>
            }
            <Center>
                <a href="/inventory">
                    <Button variant="primary">
                        Details
                    </Button>
                </a>
            </Center>
        </div>
    )
}
Example #19
Source File: ScreenSponsorRotation.tsx    From takeout-app with MIT License 5 votes vote down vote up
ScreenSponsorRotation: React.FC = () => {
  const { data } = Api.useConferenceSponsorships();

  const [page, setPage] = React.useState<ConferenceSponsorship[]>([]);

  React.useEffect(() => {
    if (!data) return;
    const sponsors = data.conference_sponsorships;

    const pages: ConferenceSponsorship[][] = [];
    const sharedDisplaySponsors: ConferenceSponsorship[] = [];

    sponsors.forEach((s) => {
      if (s.large_display) {
        pages.push([s]);
      } else {
        sharedDisplaySponsors.push(s);
      }
    });

    const PAGE_SIZE = 4;
    for (let i = 0; i < sharedDisplaySponsors.length; i += PAGE_SIZE) {
      pages.push(sharedDisplaySponsors.slice(i, i + PAGE_SIZE));
    }

    setPage(pages[0]);

    let pageNum = 0;
    const interval = setInterval(() => {
      pageNum = (pageNum + 1) % pages.length;
      setPage(pages[pageNum]);
    }, 10 * 1000);

    sponsors.forEach((s) => {
      let img = new window.Image();
      img.src = s.avatar_url;
    });

    return () => clearInterval(interval);
  }, [data]);

  if (page.length == 0) return <></>;

  return (
    <Box w="45vw" h="100%" px="6vw" pt="4vw" bgColor="#ffffff">
      <Center>
        <VStack spacing="2.8vw">
          <Text fontWeight="500" fontSize="2vw" lineHeight="4.6vw">
            Sponsored by
          </Text>

          <ScreenSponsorLogoSet sponsors={page} />
        </VStack>
      </Center>
    </Box>
  );
}
Example #20
Source File: index.tsx    From coindrop with GNU General Public License v3.0 5 votes vote down vote up
UserSettingsPage: FC = () => {
    const { user } = useUser();
    const userId = user?.id;
    const fetcher = () => getUserData(userId);
    const { data: userData, error: fetchError, mutate } = useSWR(
        userId ? 'user-data' : null,
        fetcher,
    );
    const email = user?.email;
    const Settings = () => {
        if (fetchError) {
            return (
                <Text>
                    ⚠️ Error fetching user data. Please refresh the page or contact support.
                </Text>
            );
        }
        if (userData) {
            return (
                <UserDataForm
                    userData={userData}
                    mutate={mutate}
                    userId={userId}
                />
            );
        }
        return (
            <Center>
                <Spinner data-testid="no-user-data-spinner" />
            </Center>
        );
    };
    if (!user) {
        return <Spinner data-testid="no-user-spinner" />;
    }
    return (
        <Box>
            <Heading as="h1" textAlign="center" my={4}>
                My Account
            </Heading>
            <SectionHeading size="lg">
                Profile
            </SectionHeading>
            <SectionContainer>
                <FormLabel>Email address</FormLabel>
                <Text ml={2}>{email}</Text>
            </SectionContainer>
            <SectionHeading size="lg">
                Settings
            </SectionHeading>
            <Settings />
            <SectionHeading size="lg">
                Danger Zone
            </SectionHeading>
            <DeleteAccount />
        </Box>
    );
}
Example #21
Source File: ColorPicker.tsx    From dope-monorepo with GNU General Public License v3.0 5 votes vote down vote up
ColorPicker = ({ colors, selectedColor, changeCallback }: ColorPickerProps) => {
  const [color, setColor] = useState(selectedColor ?? colors[0]);

  const handleColorInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    handleColorChange(e.target.value);
  };

  const handleColorChange = (color: string) => {
    setColor(color);
    if (typeof changeCallback === 'function') changeCallback(color);
  };

  return (
    <>
      <Popover variant="picker">
        <PopoverTrigger>
          <Button
            aria-label={color}
            background={color}
            height="64px"
            width="64px"
            padding={0}
            minWidth="unset"
            borderRadius={3}
          ></Button>
        </PopoverTrigger>
        <PopoverContent width="196px">
          <PopoverArrow bg={color} />
          <PopoverCloseButton color="white" />
          <PopoverHeader
            height="100px"
            backgroundColor={color}
            borderTopLeftRadius={5}
            borderTopRightRadius={5}
            color="white"
          >
            <Center height="100%">{color}</Center>
          </PopoverHeader>
          <PopoverBody height="96px">
            <SimpleGrid columns={5} spacing={2}>
              {colors.map(c => (
                <Button
                  key={c}
                  aria-label={c}
                  background={c}
                  height="32px"
                  width="32px"
                  padding={0}
                  minWidth="unset"
                  borderRadius={3}
                  _hover={{ background: c }}
                  onClick={() => {
                    handleColorChange(c);
                  }}
                ></Button>
              ))}
            </SimpleGrid>
            <Input
              borderRadius={3}
              marginTop={3}
              placeholder="red.100"
              size="sm"
              value={color}
              onChange={handleColorInputChange}
            />
          </PopoverBody>
        </PopoverContent>
      </Popover>
    </>
  );
}
Example #22
Source File: PiggybankQRCode.tsx    From coindrop with GNU General Public License v3.0 5 votes vote down vote up
PiggybankQRCode: FunctionComponent<Props> = ({ publicUrl, fullPublicUrl }) => {
    const onPrint = () => {
        const canvas = document.getElementById('coindrop-qr-code') as HTMLCanvasElement;
        const imgCanvas = canvas.toDataURL();
        const myWindow = window.open();
        myWindow.document.write(`<div><div>${publicUrl}</div><br /><img src="${imgCanvas}" /></div>`);
        myWindow.focus();
        myWindow.print();
    };
    return (
        <>
            <Heading
                as="h2"
                size="lg"
                mt={4}
            >
                QR Code
            </Heading>
            <Center mt={4}>
                <QRCode
                    id="coindrop-qr-code"
                    value={fullPublicUrl}
                    size={225}
                    imageSettings={{
                        src: piggy64Png,
                        x: null,
                        y: null,
                        height: 64,
                        width: 64,
                        excavate: true,
                    }}
                />
            </Center>
            <Center>
                <Button
                    mt={4}
                    leftIcon={<PrintIcon />}
                    onClick={onPrint}
                    colorScheme="green"
                >
                    Print QR Code
                </Button>
            </Center>
        </>
    );
}
Example #23
Source File: ShareButtonModal.tsx    From coindrop with GNU General Public License v3.0 5 votes vote down vote up
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 #24
Source File: section.tsx    From portfolio with MIT License 5 votes vote down vote up
Section = (props) => {
  const { full, children, ...rest } = props;
  return (
    <Center as="section" {...rest} w="100%">
      {full ? children : <Container>{children}</Container>}
    </Center>
  );
}
Example #25
Source File: AvatarInput.tsx    From coindrop with GNU General Public License v3.0 4 votes vote down vote up
AvatarInput: FunctionComponent = () => {
    const inputRef = useRef<FileInputRef>(null);
    const { piggybankDbData } = useContext(PublicPiggybankDataContext);
    const currentAvatarStorageId = piggybankDbData.avatar_storage_id;
    const { query: { piggybankName: piggybankNameQuery } } = useRouter();
    const piggybankName = typeof piggybankNameQuery === 'string' ? piggybankNameQuery : piggybankNameQuery[0];
    const { user } = useUser();
    const uid = user?.id;
    const piggybankRef = db.collection('piggybanks').doc(piggybankName);
    const fileSizeError = "Image too large";
    const contentTypeError = "Only images are accepted";
    const imageDimensionsError = "Image height and width must be >= 250px";
    const [fileSelectErrorMessage, setFileSelectErrorMessage] = useState("");
    function clearInput() { inputRef.current.value = null; }
    const setAvatar = async (newAvatarStorageId) => {
      Promise.all([
        piggybankRef.set({ avatar_storage_id: newAvatarStorageId }, { merge: true }),
        deleteImage({
          storageId: currentAvatarStorageId,
          ownerUid: uid,
          piggybankName,
        }),
      ]);
      mutate(['publicPiggybankData', piggybankName], { ...piggybankDbData, avatar_storage_id: newAvatarStorageId });
    };
    const onInputChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
      setFileSelectErrorMessage(null);
      const file = event?.target?.files?.[0];
      const storageRef = storage.ref();
      const newAvatarStorageId = uuidV4();
      const newAvatarPath = piggybankImageStoragePath({ ownerUid: uid, piggybankName, imageAs: "avatar", imageStorageId: newAvatarStorageId });
      const newAvatarRef = storageRef.child(newAvatarPath);
      if (file) {
        try {
          const contentType = file.type;
          if (!contentType.startsWith("image/")) {
            throw new Error(contentTypeError);
          }
          if (file.size > 1000000) {
            throw new Error(fileSizeError);
          }
          const { width, height } = await getImageDimensions(file);
          if (width < 250 || height < 250) {
            throw new Error(imageDimensionsError);
          }
          await newAvatarRef.put(file);
          clearInput();
          setAvatar(newAvatarStorageId);
        } catch (err) {
          const { message } = err;
          if (message === fileSizeError) {
            setFileSelectErrorMessage("Image too large. Please resize image to < 1MB.");
          } else if (message === contentTypeError) {
            setFileSelectErrorMessage("Only .jpg, .png, and .webp images are accepted.");
          } else if (message === imageDimensionsError) {
            setFileSelectErrorMessage("Width and height must be at least 250px");
          } else {
            setFileSelectErrorMessage("Error during upload. Please try again.");
          }
          clearInput();
        }
      }
    };
    return (
      <>
        <FormLabel htmlFor="avatar-input">Image</FormLabel>
        <Stack id="avatar-input-container">
          <Box mx="auto">
            {
              currentAvatarStorageId
              ? <Avatar />
              : (
                <NextImage
                  id="avatar-img"
                  width={200}
                  height={200}
                  src="/avatar-placeholder.png"
                  alt="avatar placeholder"
                  data-cy="avatar-placeholder"
                />
              )
            }
          </Box>
          <Center>
            <Flex wrap="wrap" justify="center">
              <Box mt={1}>
                <FileInput
                  text={currentAvatarStorageId ? "Upload new image" : "Upload image"}
                  id="avatar-input"
                  ref={inputRef}
                  accept="image/png, image/jpeg, image/webp"
                  onChange={onInputChange}
                />
              </Box>
              {currentAvatarStorageId && (
                <Box ml={2} mt={1}>
                  <Button
                    onClick={() => {
                      setAvatar(null);
                    }}
                    colorScheme="red"
                    size="sm"
                    leftIcon={<DeleteIcon />}
                    data-cy="remove-image-btn"
                  >
                    Remove image
                  </Button>
                </Box>
              )}
            </Flex>
          </Center>
          {fileSelectErrorMessage && (
            <Text textAlign="center" color="red.500">
              <WarningIcon mr={2} />
              {fileSelectErrorMessage}
            </Text>
          )}
        </Stack>
      </>
    );
}
Example #26
Source File: notes-list.tsx    From notebook with MIT License 4 votes vote down vote up
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: repositories-list-item.tsx    From notebook with MIT License 4 votes vote down vote up
RepositoriesListItem: React.SFC<RepositoriesListItemProps> = ({
  repo
}) => {
  const [repoId, setRepoId] = React.useState<number>(0);
  const bg = useColorModeValue("white", "#2f3244");
  const textColor = useColorModeValue("gray.600", "#b5b1b1");
  const { isOpen, onOpen, onClose } = useDisclosure();

  const handleClick = (id: number) => {
    setRepoId(id);
    onOpen();
  };

  return (
    <>
      <Center>
        <Box
          maxW="sm"
          height="fit-content"
          borderWidth="1px"
          borderRadius="lg"
          overflow="hidden"
          boxShadow="md"
          mx="5px"
          mb="10px"
          mt="10px"
          _hover={{ boxShadow: "lg" }}
        >
          {/* <Image
          height={{ base: "28vh", lg: "32vh" }}
          cursor={repo.coverImage ? "pointer" : "auto"}
          width={"100%"}
          src={repo.coverImage}
          objectFit="cover"
          alt="cover image"
          fallbackSrc="https://via.placeholder.com/320x216/DCDFDF/ffffff/?text=CoverImage"
          fallbackSrc={placeholder}
          onClick={() => handleClick(repo.coverImage)}
        /> */}
          <LazyImage
            id={repo.id}
            src={repo.coverImage}
            blurHash={repo.blurHash}
            handleClick={handleClick}
          />

          <Box p="5" bg={bg}>
            <Flex justifyContent="space-between" alignItems="center">
              <Box
                mt="1"
                fontWeight="semibold"
                as="h6"
                fontSize="md"
                lineHeight="tight"
                textAlign="left"
                isTruncated
              >
                <Link
                  href={repo.liveLink || repo.githubLink}
                  textDecoration={"none !important"}
                  isExternal
                >
                  {repo.title}
                  <ExternalLinkIcon mx="3px" />
                </Link>
              </Box>
              <Box mt="1">
                {repo.stars ? (
                  <Link
                    href={repo.githubLink}
                    textDecoration={"none !important"}
                    isExternal
                  >
                    <Tooltip hasArrow label="Github stars" placement="top-end">
                      <Box>
                        <StarIcon color="teal.300" fontSize="sm" />
                        <Box as="span" ml="2" color={textColor} fontSize="sm">
                          {repo.stars}
                        </Box>
                      </Box>
                    </Tooltip>
                  </Link>
                ) : (
                  ""
                )}
              </Box>
            </Flex>
            <Box textAlign="left">
              <HStack spacing="1" mt="2" mb="2">
                {repo.technologies.map((tech, index) => (
                  <Badge
                    borderRadius="full"
                    px="1"
                    colorScheme={tech.color}
                    textTransform="lowercase"
                    key={index}
                  >
                    {tech.name}
                  </Badge>
                ))}
              </HStack>
            </Box>
            <Box color={textColor} fontSize="md" textAlign="left">
              {repo.desc}
            </Box>
          </Box>
        </Box>
      </Center>
      <Carousel
        repoId={repoId}
        onOpen={onOpen}
        onClose={onClose}
        isOpen={isOpen}
      />
    </>
  );
}
Example #28
Source File: offline-data-card.tsx    From portfolio with MIT License 4 votes vote down vote up
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 #29
Source File: PublicPiggybankPage.tsx    From coindrop with GNU General Public License v3.0 4 votes vote down vote up
PublicPiggybankPage: FunctionComponent = () => {
    const { query: { piggybankName } } = useRouter();
    const { piggybankDbData } = useContext(PublicPiggybankDataContext);
    const theme = useTheme();
    const { user } = useUser();
    const { colorMode } = useColorMode();
    const accentColorLevelInitial = getAccentColorLevelInitial(colorMode);
    const accentColorLevelHover = getAccentColorLevelHover(colorMode);
    const {
        name,
        website,
        accentColor = "orange",
        verb,
        owner_uid,
    } = piggybankDbData;
    const accentColorInitial = theme.colors[accentColor][accentColorLevelInitial];
    const accentColorHover = theme.colors[accentColor][accentColorLevelHover];
    const pagePaymentMethodsDataEntries = Object.entries(piggybankDbData.paymentMethods ?? {});
    const preferredAddresses = pagePaymentMethodsDataEntries.filter(([, paymentMethodData]: any) => paymentMethodData.isPreferred);
    const otherAddresses = pagePaymentMethodsDataEntries.filter(([, paymentMethodData]: any) => !paymentMethodData.isPreferred);
    const WrapGroup: FunctionComponent = ({ children }) => (
        <Wrap
            justify="center"
        >
            {children}
        </Wrap>
    );

    type PaymentMethodButtonsFromEntriesProps = {
        entries: PaymentMethodDbObjEntry[]
    }
    const PaymentMethodButtonsFromEntries: FunctionComponent<PaymentMethodButtonsFromEntriesProps> = ({ entries }) => (
        <WrapGroup>
            {entries
            .sort(sortArrayByEntriesKeyAlphabetical)
            .map(([paymentMethodId, paymentMethodData]) => (
                <WrapItem key={paymentMethodId}>
                    <PaymentMethodButton
                        key={paymentMethodId}
                        paymentMethod={paymentMethodId}
                        paymentMethodValue={paymentMethodData.address}
                        isPreferred={paymentMethodData.isPreferred}
                        accentColor={accentColor}
                    />
                </WrapItem>
            ))}
        </WrapGroup>
    );
    const piggybankExists = !!owner_uid;
    const initialSetupComplete = name && accentColor && verb && pagePaymentMethodsDataEntries.length > 0;
    return (
        <>
        <NextSeo
            title={`${name ?? piggybankName}'s Coindrop (coindrop.to/${piggybankName})`}
            description={`Send money to ${name} with no fees`}
        />
        <Container
            maxW={theme.breakpoints.lg}
            mx="auto"
        >
            {user?.id
            && user.id === owner_uid
            && (
                <>
                <DataRefetcher />
                <ManagePiggybankBar
                    editButtonOptions={
                        initialSetupComplete
                        ? ({
                            text: 'Configure',
                            color: undefined,
                            icon: <SettingsIcon />,
                        }) : ({
                            text: 'Set up',
                            color: 'green',
                            icon: <SettingsIcon />,
                        })
                    }
                    initialSetupComplete={initialSetupComplete}
                />
                </>
            )}
            {initialSetupComplete ? (
                <Box
                    mb={6}
                >
                    <Box
                        padding="10px"
                        my={2}
                        mx={3}
                    >
                        <Center>
                            <Avatar />
                        </Center>
                        <Heading textAlign="center">
                            Choose a payment method to
                            {` ${verb} `}
                            {website ? (
                                <Link href={website} target="_blank" rel="noreferrer">
                                    <Heading
                                        as="span"
                                        color={accentColorInitial}
                                        textDecoration="underline"
                                        css={css`
                                            &:hover {
                                                color: ${accentColorHover};
                                            }
                                        `}
                                    >
                                            {name}
                                    </Heading>
                                </Link>
                            ) : (
                                <Heading
                                    as="span"
                                    color={accentColorInitial}
                                >
                                        {name}
                                </Heading>
                            )}
                            :
                        </Heading>
                    </Box>
                    <PaymentMethodButtonsFromEntries
                        entries={preferredAddresses}
                    />
                    <PaymentMethodButtonsFromEntries
                        entries={otherAddresses}
                    />
                    <PoweredByCoindropLink />
                </Box>
            ) : (
                <Heading mt={4} textAlign="center">
                    {piggybankExists ? 'This Coindrop has not been set up yet.' : 'This Coindrop does not exist'}
                    {/* TODO: Include action buttons to log in or landing page */}
                </Heading>
            )}
        </Container>
        </>
    );
}