react-icons/bi#BiCloudUpload TypeScript Examples

The following examples show how to use react-icons/bi#BiCloudUpload. 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: notion.tsx    From pagely with MIT License 4 votes vote down vote up
Notion = () => {
  const {
    handleSubmit,
    register,
    setValue,
    formState: { errors },
  } = useForm<NewNotionSiteFormValues>({
    resolver: zodResolver(newNotionSiteSchema),
  });

  const [loading, setLoading] = useState<boolean>(false);
  const router = useRouter();

  useEffect(() => {
    router.prefetch('/dashboard');
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleFormSubmit = async (data: NewNotionSiteFormValues) => {
    setLoading(true);
    if (validateData(data) !== null) {
      setLoading(false);
      return;
    }
    const { name, description, subdomain, ogImageUrl, notionPageUrl } = data;
    const res = await axios.post('/api/new/notion', {
      siteName: name,
      siteDesc: description,
      subdomain,
      ogImageUrl,
      notionPageUrl,
    });
    if (res.data.success) {
      toast.success('Notion site created!');
      setLoading(false);
      router.push('/dashboard');
    } else if (res.data.success === false) {
      toast.error(res.data.error);
      setLoading(false);
    }
  };

  return (
    <MainLayout>
      <div>
        <div className='max-w-5xl mx-auto'>
          <h1 className='mt-10 text-4xl font-bold'>
            That&apos;s. Just fill out this quick form now
          </h1>
          <form
            className='max-w-sm mt-10'
            onSubmit={handleSubmit(handleFormSubmit)}>
            <label className='block'>
              <span className='mb-2 text-gray-700'>
                Subdomain (URL for your website)
                <InfoPopover content='This is the subdomain of your website. It is the part of the URL before the domain name. For example, in the image below thesubdomain is "one". (And its free!!)'>
                  <Image
                    placeholder='blur'
                    src={SubdomainImage}
                    alt='Subdomain'
                    className='inline-block w-full rounded'
                  />
                </InfoPopover>
              </span>
              <p className='mt-1 text-sm text-gray-600'>
                You cannot change this later
              </p>
              <div className='flex items-baseline'>
                <input
                  type='text'
                  className='inline-block w-full mt-1 border-gray-300 shadow-sm rounded-l-md focus:border-blue-300 focus:ring focus:ring-blue-200'
                  placeholder='elon'
                  {...register('subdomain')}
                />
                <span className='inline-block py-[0.5rem] select-none border-t border-b border-r pl-1 pr-2 bg-gray-100 rounded-r-md'>
                  .pagely.site
                </span>
              </div>
              <p className='mt-2 text-sm text-red-500'>
                {errors.subdomain && errors.subdomain.message}
              </p>
            </label>
            <label className='block mt-10'>
              <span className='mb-2 text-gray-700'>Name of your website</span>
              <InfoPopover content='This is the name of your website. It is also the title in Twitter cards and OG cards.'>
                <Image
                  placeholder='blur'
                  src={TweetTitleImage}
                  alt=''
                  className='inline-block w-full rounded'
                />
              </InfoPopover>
              <p className='mt-1 text-sm text-gray-600'>
                This name will be used for generating OG title
              </p>
              <div className='flex items-center'>
                <input
                  type='text'
                  className='inline-block w-full mt-1 mr-1 border-gray-300 rounded-md shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200'
                  placeholder='Blog - Elon'
                  {...register('name')}
                />
              </div>
              <p className='mt-2 text-sm text-red-500'>
                {errors.name && errors.name.message}
              </p>
            </label>
            <label className='block mt-10'>
              <span className='text-gray-700'>Description</span>
              <InfoPopover content='This is the description of your website. It is also the description in Twitter cards and OG cards.'>
                <Image
                  placeholder='blur'
                  src={TweetDescImage}
                  alt=''
                  className='inline-block w-full rounded'
                />
              </InfoPopover>
              <p className='mt-1 text-sm text-gray-600'>
                This description will be used for generating OG and Twitter description
              </p>
              <textarea
                className='block w-full mt-1 text-base border-gray-300 rounded-md shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50'
                rows={4}
                placeholder='Read my blog to...'
                {...register('description')}
              />
              <p className='mt-2 text-sm text-red-500'>
                {errors.description && errors.description.message}
              </p>
            </label>

            <label className='block mt-10'>
              <span className='text-gray-700'>OG Image URL</span>
              <InfoPopover content='This is the image that will appear in the OG cards and Twitter cards. 1200x630 is the recommended dimension for the OG image. If you do not need, just set it to https://no-og.image'>
                <Image
                  placeholder='blur'
                  src={OgImage}
                  alt=''
                  className='inline-block w-full rounded'
                />
              </InfoPopover>
              <p className='mt-1 text-sm text-gray-600'>
                If left blank, the OG Image will be automatically generated from
                site name and Notion page&apos;s title!!
              </p>
              <div className='flex items-center'>
                <input
                  type='text'
                  className='inline-block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200'
                  placeholder='https://picsum.photos/1200/630'
                  {...register('ogImageUrl')}
                />
              </div>
              <p className='mt-2 text-sm text-red-500'>
                {errors.ogImageUrl && errors.ogImageUrl.message}
              </p>
              <div>
                <div className='inline-block px-2 py-px mt-2 text-sm text-gray-700 border border-gray-200 rounded cursor-pointer bg-gray-50 hover:bg-gray-100'>
                  <Dropzone
                    onDrop={(files) => {
                      uploadImage(files, setValue);
                    }}>
                    {({ getRootProps, getInputProps }) => (
                      <div {...getRootProps()}>
                        <input type='file' {...getInputProps()} />
                        <BiCloudUpload className='relative inline-block w-5 h-5 bottom-px' />{' '}
                        Upload image
                      </div>
                    )}
                  </Dropzone>
                </div>
                <p className='mt-1 text-sm text-gray-500'>
                  Or just drag &apos;n&apos; drop an image over the button !
                </p>
              </div>
            </label>

            <label className='block mt-10'>
              <span className='text-gray-700'>Notion Page URL</span>
              <InfoPopover content="You can find your Notion page URL in the Notion dashboard once you share the page to web. Pagely uses this URL to fetch the page's content.">
                <Image
                  placeholder='blur'
                  src={NotionImage}
                  alt=''
                  className='inline-block w-full rounded'
                />
              </InfoPopover>
              <p className='mt-1 text-sm text-gray-600'>
                <span className="font-bold">Make sure your Notion page is public</span>. You will get the URL once you share your page to web
              </p>
              <input
                type='text'
                className='block w-full mt-1 text-base border-gray-300 rounded-md shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50'
                placeholder='https://notion.so/My-Notion-Page-...'
                {...register('notionPageUrl')}
              />
              <p className='mt-2 text-sm text-red-500'>
                {errors.notionPageUrl && errors.notionPageUrl.message}
              </p>
            </label>
            <button
              type='submit'
              className='inline-flex items-center justify-center my-10 text-lg font-medium text-white border border-transparent rounded shadow-md bg-custom-blue hover:bg-blue-700 focus:outline-none focus:ring-blue-500 focus:ring-2 focus:ring-offset-2'>
              {loading ? (
                <span className={`px-5 py-[6px] ${loading && 'py-[11px]'}`}>
                  <Loader height={18} width={200} color='#fff' type='Puff' />
                </span>
              ) : (
                <span className='px-5 py-[6px] '>
                  Get the website now -&gt;
                </span>
              )}
            </button>
          </form>
        </div>
      </div>
      <Toaster />
    </MainLayout>
  );
}
Example #2
Source File: seo.tsx    From pagely with MIT License 4 votes vote down vote up
Page = () => {
  const router = useRouter();
  const { data, mutate } = useClerkSWR<notionSites>(
    `/api/getSiteData/notion/?siteId=${router.query.notionId}`
  );

  const [isImageLoading, setIsImageLoading] = useState<boolean>(true);
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const updateUrlWithSession = useUrlWithSession(
    '/api/updateSiteData/notion/seo'
  );
  const {
    handleSubmit,
    register,
    setValue,
    formState: { errors },
    control,
  } = useForm<NotionSeoSettings>({
    resolver: zodResolver(notionPageSeoSchema),
    defaultValues: {
      ogImageUrl: data?.ogImageUrl,
      siteName: data?.siteName,
      siteDesc: data?.siteDesc,
    },
  });

  const updateSeoData = (formData) => {
    setIsLoading(true);
    console.log('updating SEO');
    const { ogImageUrl, siteName, siteDesc } = formData;
    console.log('values obtained' + JSON.stringify(formData));
    console.log('about to post');
    axios
      .post(updateUrlWithSession, {
        siteId: data?.id,
        ogImageUrl: ogImageUrl,
        siteName: siteName,
        siteDesc: siteDesc,
      })
      .then(() => {
        console.log('done updating');
        setIsLoading(false);
        toast.success('SEO settings updated.');
        mutate(
          {
            ...data,
            ogImageUrl: ogImageUrl,
            siteName: siteName,
            siteDesc: siteDesc,
          },
          false
        );
        console.log('done');
      })
      .catch((err) => {
        console.log('caught error');

        setIsLoading(false);
        toast.error('Failed to update SEO settings\n' + err.message, {
          duration: 5000,
        });
      });
    console.log('done posting');
  };

  return (
    <div>
      {process.env.NODE_ENV !== 'production' && (
        <DevTool control={control} placement='top-right' />
      )}
      <SidebarLayout activeTab='seo'>
        <h1 className='text-4xl font-extrabold'>SEO Settings</h1>
        <p className='mt-4 text-gray-800 font-base'>
          {data?.siteName || 'Just a second...'}
        </p>
        <div className='my-5 mt-10'>
          <h2 className='mb-5 text-2xl font-bold'>Twitter Preview</h2>
          <TwitterPreview data={data} />
        </div>
        <form
          id='notion-seo-form'
          className='mt-8'
          onSubmit={(e) => {
            e.preventDefault();
            handleSubmit(updateSeoData)();
          }}>
          <hr className='my-10 text-gray-400' />
          <h2 className='mb-5 text-2xl font-bold'>OG Image</h2>
          <div className='max-w-[600px] max-h-[315px]'>
            {data?.ogImageUrl === 'https://no-og.image' ? (
              <Image
                alt='No OG Image'
                src={NoOgImage}
                onLoad={() => setIsImageLoading(false)}
                className='border border-gray-400 rounded'
              />
            ) : (
              // eslint-disable-next-line @next/next/no-img-element
              <img
                src={
                  data?.ogImageUrl ||
                  'https://ogimage.glitch.me/i/' +
                    encodeURIComponent(data?.siteName)
                }
                alt={data?.siteName}
                className='object-cover rounded-md'
                onLoad={() => setIsImageLoading(false)}
              />
            )}
            {isImageLoading && <Skeleton width='600px' height='315px' />}
          </div>
          <div>
            <label className='block mt-3'>
              <span className='mt-1 text-sm text-gray-600'>
                If left blank, the OG Image will be automatically generated from
                site name and Notion page&apos;s title!!
              </span>
              <InfoPopover content='This is the image that will appear in the OG cards and Twitter cards. 1200x630 is the recommended dimension for the OG image. This can boost your conversion rate by upto 2 times!!'>
                <Image
                  placeholder='blur'
                  src={OgImage}
                  alt=''
                  className='inline-block w-full rounded'
                />
              </InfoPopover>
              <div className='flex items-center'>
                <input
                  type='text'
                  className='inline-block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200'
                  placeholder='https://picsum.photos/1200/630'
                  {...register('ogImageUrl')}
                />
              </div>
              <p className='mt-2 text-sm text-red-500'>
                {errors.ogImageUrl && errors.ogImageUrl.message}
              </p>
              <div>
                <div>
                  <div className='inline-block px-2 py-px mt-2 text-sm text-gray-700 border border-gray-200 rounded cursor-pointer bg-gray-50 hover:bg-gray-100'>
                    <Dropzone
                      onDrop={(files) => {
                        uploadImage(files, setValue);
                      }}>
                      {({ getRootProps, getInputProps }) => (
                        <div {...getRootProps()}>
                          <input type='file' {...getInputProps()} />
                          <BiCloudUpload className='relative inline-block w-5 h-5 bottom-px' />{' '}
                          Upload image
                        </div>
                      )}
                    </Dropzone>
                  </div>
                  <p className='mt-1 text-sm text-gray-500'>
                    Or just drag &apos;n&apos; drop an image over the button !
                  </p>
                </div>
              </div>
            </label>
          </div>

          <hr className='my-10 text-gray-200' />

          <div>
            <h2 className='mb-5 text-2xl font-bold'>OG Title</h2>
            <p className='text-gray-800'>{data?.siteName}</p>
            <div>
              <label className='block mt-3'>
                <span className='mt-1 text-sm text-gray-600'>
                  This name will be used for generating OG title
                </span>
                <InfoPopover content='This is the name of your website. It is also the title in Twitter cards and OG cards.'>
                  <Image
                    placeholder='blur'
                    src={TweetTitleImage}
                    alt=''
                    className='inline-block w-full rounded'
                  />
                </InfoPopover>
                <div className='flex items-center'>
                  <input
                    type='text'
                    className='inline-block w-full mt-1 mr-1 border-gray-300 rounded-md shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200'
                    placeholder='Blog - Elon'
                    {...register('siteName')}
                  />
                </div>
                <p className='mt-2 text-sm text-red-500'>
                  {errors.siteName && errors.siteName.message}
                </p>
              </label>
            </div>
          </div>
          <hr className='my-10 text-gray-200' />

          <div className='mb-5'>
            <h2 className='mb-5 text-2xl font-bold'>OG Description</h2>
            <p className='text-gray-800'>{data?.siteDesc}</p>
            <div>
              <label className='block mt-3'>
                <span className='mt-1 text-sm text-gray-600'>
                  This name will be used for generating OG and Twitter
                  descriptions
                </span>

                <InfoPopover content='This is the description of your website. It is also the description in Twitter cards and OG cards.'>
                  <Image
                    placeholder='blur'
                    src={TweetDescImage}
                    alt=''
                    className='inline-block w-full rounded'
                  />
                </InfoPopover>
                <textarea
                  className='block w-full mt-1 text-base border-gray-300 rounded-md shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50'
                  rows={4}
                  placeholder='Read my blog to...'
                  {...register('siteDesc')}
                />
                <p className='mt-2 text-sm text-red-500'>
                  {errors.siteDesc && errors.siteDesc.message}
                </p>
              </label>
            </div>
          </div>
          <div>
            <button
              type='submit'
              form='notion-seo-form'
              className={`h-10 px-3 mb-10 bg-gray-800 rounded shadow-md text-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-800 hover:bg-gray-700 ${
                isLoading && 'opacity-50 cursor-wait'
              }`}>
              {isLoading ? 'Saving changes...' : 'Save changes'}
            </button>
          </div>
        </form>
      </SidebarLayout>
    </div>
  );
}