next-seo#NextSeo TypeScript Examples

The following examples show how to use next-seo#NextSeo. 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: PageMeta.tsx    From norfolkdevelopers-website with MIT License 6 votes vote down vote up
export default function PageMeta(props: Props) {
  const title = props.title
    ? `${props.title} | ${ siteConfig.siteSEOName }`
    : `${ siteConfig.siteSEOName } | ${siteConfig.shortDescription}`;
  const description = props.description || siteConfig.description;

  return (
    <NextSeo
      openGraph={{
        title: props.title
          ? props.title
          : title,
        description,
        site_name: siteConfig.siteSEOName,
        images: props.image
          ? [ { url: props.image } ]
          : [ { url: `${siteConfig.rootUrl}/static/images/default-open-graph.jpg` } ],
      }}
      twitter={{
        handle: "@NorfolkDev",
        site: "@NorfolkDev",
        cardType: "summary_large_image",
      }}
      {...props}
      title={title}
      description={description}
    />
  );
}
Example #2
Source File: [slug].tsx    From storefront with MIT License 6 votes vote down vote up
Page: NextPage<Props> = ({ page }) => {
  if (page == null) {
    return <Error statusCode={404} />;
  }
  return (
    <Layout>
      <NextSeo
        title={page.seo?.title ?? ''}
        description={page.seo?.metaDesc ?? ''}
        openGraph={{
          title: page.seo?.opengraphTitle ?? '',
          description: page.seo?.opengraphDescription ?? '',
        }}
      />
      <Hero image={page.featuredImage?.node} title={page.title} />
      <Container>
        <Box sx={{ mb: 6, mt: 4 }}>
          <BlockRenderer>{page.content}</BlockRenderer>
        </Box>
      </Container>
    </Layout>
  );
}
Example #3
Source File: head.tsx    From basement-grotesque with SIL Open Font License 1.1 6 votes vote down vote up
Head = (props: HeadProps) => {
  const router = useRouter()
  const isDark = useMedia('(prefers-color-scheme: dark)')

  const nextSeoProps: NextSeoProps = useMemo(() => {
    return {
      ...props.rawNextSeoProps,
      title: props.title ?? defaultMeta.title,
      description: props.description ?? defaultMeta.description,
      canonical: `${siteOrigin}${router.pathname}`,
      openGraph: {
        images: [{ url: props.ogImage ?? defaultMeta.ogImage }]
      },
      twitter: {
        handle: '@basementstudio',
        site: '@basementstudio',
        cardType: 'summary_large_image'
      },
      noindex: props.noIndex
    }
  }, [props, router.pathname])

  return (
    <>
      <NextSeo {...nextSeoProps} />
      <NextHead>
        <meta charSet="utf-8" />
        <meta
          name="viewport"
          content="minimum-scale=1, initial-scale=1, width=device-width, user-scalable=0"
        />
        <meta name="theme-color" content="#ffffff" />
        <link rel="icon" href={isDark ? '/favicon-dark.svg' : '/favicon.svg'} />
        <link rel="mask-icon" href="/favicon.svg" color="#000" />
      </NextHead>
    </>
  )
}
Example #4
Source File: index.tsx    From apps with GNU Affero General Public License v3.0 6 votes vote down vote up
Home = (): ReactElement => {
  return (
    <>
      <NextSeo {...seo} />
      <SiteLinksSearchBoxJsonLd
        url="https://app.daily.dev"
        potentialActions={[
          {
            target: 'https://app.daily.dev/search?q',
            queryInput: 'search_term_string',
          },
        ]}
      />
    </>
  );
}
Example #5
Source File: 404.tsx    From frontend with Apache License 2.0 6 votes vote down vote up
export default function Custom404() {
    const { t } = useTranslation()
    return (
        <Main>
            <NextSeo title={t('client-error')} />
            <div className='main-container'>
                <h1>{t('whoops')}</h1>
                <p>
                    {t('an-error-occurred-client')}
                </p>
                <p>
                    <Trans i18nKey={"common:retry-or-go-home"}>
                        You might want to retry or go back <a href='.'>home</a>.
                    </Trans>
                </p>
            </div>
        </Main>
    )
}
Example #6
Source File: Docs.tsx    From core with GNU Affero General Public License v3.0 6 votes vote down vote up
Docs: React.FC<DocsProps> = ({ title, header, description, subheader, children }) => {
	const t = typeof header === 'string' ? header : title
	const d = description || subheader
	return (
		<>
			<NextSeo title={t} description={d}
				openGraph={{
					title: t,
					description: d
				}}
			/>
			<div className='dark:bg-discord-black bg-discord-blurple z-20'>
				<Container className='py-20' ignoreColor>
					<h1 className='mt-10 text-center text-gray-100 text-4xl font-bold sm:text-left'>
						{header}
					</h1>
					<h2 className='mt-5 text-center text-gray-200 text-xl font-medium sm:text-left'>
						{description}
					</h2>
					<h2 className='mt-5 text-center text-gray-200 text-xl font-medium sm:text-left'>
						{subheader}
					</h2>
				</Container>
			</div>
			<Container className='pt-10 pb-20'>
				<div>{children}</div>
			</Container>
		</>
	)
}
Example #7
Source File: calculator.tsx    From po8klasie with GNU General Public License v3.0 6 votes vote down vote up
CalculatorPage: FC = () => {
  return (
    <AppLayout>
      <NextSeo
        title="Kalkulator punktów"
        description="Oblicz swoje punkty rekrutacyjne z kalkulatorem punktów wyszukiwarki szkół średnich po8klasie"
      />
      <div className="w-container mx-auto">
        <h1 className="flex items-center text-3xl font-bold mt-5 lg:mt-10">
          Kalkulator punktów
          <span className="flex rounded-full bg-primaryBg text-primary uppercase px-2 py-1 text-xs font-bold ml-3">
            New
          </span>
        </h1>
        <p className="my-10">
          Podaj swoje oceny, wyniki z egzaminu ósmoklasisty oraz dodatkowe osiągnięcia (jeśli takie
          masz) i oblicz punkty, jakie uzyskasz podczas rekrutacji do szkoły średniej.
        </p>
        <div
          className="bg-primaryBg border-l-4 border-primary text-primary p-4 lg:w-1/2 xl:w-1/3 rounded "
          role="alert"
        >
          <p className="font-bold mb-2 flex items-center font-primary">
            <AiOutlineWarning className="mr-2 text-xl" />
            Przypomnienie
          </p>
          <p>Progi punktowe zmieniają się co roku i zależą od wielu czynników.</p>
        </div>
        <Calculator />
      </div>
    </AppLayout>
  );
}
Example #8
Source File: Dashboard.tsx    From coindrop with GNU General Public License v3.0 6 votes vote down vote up
Dashboard: FunctionComponent = () => {
    const router = useRouter();
    const { user } = useUser();
    useDidMountEffect(() => {
        if (!user) {
            router.push('/');
        }
    }, [user]);

    return (
        <>
            <NextSeo
                title="Dashboard | Coindrop"
            />
            {user?.id
            ? (
                <UserOwnedPiggybanks
                    uid={user.id}
                />
            ) : (
                <Text>You are not logged in. Redirecting...</Text>
            )}
        </>
    );
}
Example #9
Source File: layout.tsx    From next-mdx with MIT License 6 votes vote down vote up
export function Layout({
  title = "",
  description = "",
  children,
}: LayoutProps) {
  const { asPath: path } = useRouter()
  return (
    <>
      <NextSeo
        title={path === "/" ? site.name : `${title} - ${site.name}`}
        description={description}
        canonical={`${process.env.NEXT_PUBLIC_BASE_URL}${path}`}
        openGraph={{
          title,
          description,
          url: `${process.env.NEXT_PUBLIC_BASE_URL}${path}`,
          images: [
            {
              url: `${process.env.NEXT_PUBLIC_BASE_URL}/images/meta.jpg`,
              width: 800,
              height: 600,
            },
          ],
        }}
      />
      <Navbar />
      <main>{children}</main>
      <Footer />
    </>
  )
}
Example #10
Source File: index.tsx    From next-password-protect with MIT License 6 votes vote down vote up
Home = () => {
  const clearCookie = async () => {
    await fetch('/api/logout', {
      method: 'post',
      credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
    });
    window.location.reload();
  };

  return (
    <>
      <NextSeo
        title="Next password protect"
        description="Next password protect example app"
      />
      <h1>Logged in page</h1>
      <button onClick={clearCookie}>Logout</button>
    </>
  );
}
Example #11
Source File: index.tsx    From resume-nextjs with MIT License 6 votes vote down vote up
function Yosume() {
  return (
    <>
      <NextSeo {...Payload._global.seo} />
      <Head>
        <title>{Payload._global.headTitle}</title>
        <link rel="shortcut icon" href={Payload._global.favicon} />
      </Head>
      <Container style={Style.global}>
        <Profile.Component payload={Payload.profile} />
        <Introduce.Component payload={Payload.introduce} />
        <Skill.Component payload={Payload.skill} />
        <Experience.Component payload={Payload.experience} />
        <Project.Component payload={Payload.project} />
        <OpenSource.Component payload={Payload.openSource} />
        <Presentation.Component payload={Payload.presentation} />
        <Article.Component payload={Payload.article} />
        <Education.Component payload={Payload.education} />
        <Etc.Component payload={Payload.etc} />
        <Footer.Component payload={Payload.footer} />
      </Container>
    </>
  );
}
Example #12
Source File: CollectionView.tsx    From nextjs-shopify with MIT License 5 votes vote down vote up
CollectionPreview: FC<Props> = ({
  collection: initialCollection,
  productGridOptions,
  renderSeo,
}) => {
  const [collection, setCollection] = useState(initialCollection)
  const [loading, setLoading] = useState(false)

  useEffect(() => setCollection(initialCollection), [initialCollection])

  useEffect(() => {
    const fetchCollection = async () => {
      setLoading(true)
      const result = await getCollection(shopifyConfig, {
        handle: collection,
      })
      setCollection(result)
      setLoading(false)
    }
    if (typeof collection === 'string') {
      fetchCollection()
    }
  }, [collection])

  if (!collection || typeof collection === 'string' || loading) {
    return <LoadingDots />
  }

  const { title, description, products } = collection

  return (
    <Themed.div
      sx={{ display: 'flex', flexDirection: 'column' }}
      key={collection.id}
    >
      {renderSeo && (
        <NextSeo
          title={collection.title}
          description={collection.description}
          openGraph={{
            type: 'website',
            title,
            description,
          }}
        />
      )}
      <div sx={{ display: 'flex', flexDirection: 'column' }}>
        <span sx={{ mt: 0, mb: 2 }}>
          <Themed.h1>{collection.title}</Themed.h1>
        </span>
        <div dangerouslySetInnerHTML={{ __html: collection.description! }} />
      </div>
      <Themed.div sx={{ p: 5 }}>
        <ProductGrid {...productGridOptions} products={products} />
      </Themed.div>
    </Themed.div>
  )
}
Example #13
Source File: GitHubPage.tsx    From pagely with MIT License 5 votes vote down vote up
export default function Home({
  data,
  subdomain,
  repoUrl,
  customHead,
  customCss,
}) {
  if (!data) {
    return null;
  }

  const {
    title,
    ogImageUrl,
    name: siteName,
    description: siteDesc,
    template,
    faviconLink,
  } = data;
  const url = 'https://' + subdomain + '.pagely.site';

  const ogImage =
    ogImageUrl === ''
      ? 'https://ogimage.glitch.me/i/' + encodeURIComponent(title)
      : ogImageUrl;

  return (
    <div>
      <Head>
        <style>{`
					.pagely-container {
						font-family: 'Inter', 'monospace' !important;
					}
				`}</style>
        <link rel='shortcut icon' href={faviconLink} type='image/x-icon' />
        <style dangerouslySetInnerHTML={{ __html: customCss }} />
        <div dangerouslySetInnerHTML={{ __html: customHead }} />
      </Head>
      <NextSeo
        title={siteName}
        description={siteDesc}
        canonical={url}
        openGraph={{
          title: siteName,
          url: url,
          images: [
            {
              url: ogImage === 'https://no-og.image' ? '' : ogImage,
              alt: title,
            },
          ],
          description: siteDesc,
        }}
        twitter={{
          cardType: 'summary_large_image',
        }}
      />
      {/* <h1 className='text-3xl font-bold'>{customHead}</h1> */}
      {template === 'minimal' && <Minimal repoUrl={repoUrl} {...data} />}
    </div>
  );
}
Example #14
Source File: _app.tsx    From staticshield with MIT License 5 votes vote down vote up
function MyApp({ Component, pageProps, router }) {
  return (
    <UserProvider>
      {process.env.NODE_ENV !== 'development' && (
        <Script
          strategy='afterInteractive'
          data-domains='staticshield.vercel.app'
          data-website-id={process.env.NEXT_PUBLIC_ANALYTICS_ID}
          src={process.env.NEXT_PUBLIC_ANALYTICS_URL}></Script>
      )}
      <Script strategy='afterInteractive' id='analytics'>
        (function(c,l,a,r,i,t,y){'{'}
        c[a]=c[a]||() =&gt; {'{'}(c[a].q=c[a].q||[]).push(arguments){'}'};
        t=l.createElement(r);t.async=1;t.src=&quot;https://www.clarity.ms/tag/&quot;+i;
        y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
        {'}'})(window, document, &quot;clarity&quot;, &quot;script&quot;,
        &quot;7c9tgf3vlc&quot;);
      </Script>
      <Head>
        <link rel='preconnect' href='https://vitals.vercel-insights.com/' />
        <link rel='manifest' href='/manifest.json' />
        <meta name='theme-color' content='#000' />
        <meta
          name='google-site-verification'
          content={process.env.NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION_ID}
        />
      </Head>
      <NextSeo
        title='StaticShield'
        description='StaticShield is the easiest way to password protect websites'
        openGraph={{
          url: 'https://staticshield.vercel.app',
          title: 'StaticShield',
          description:
            'StaticShield is the easiest way to password protect websites',
          images: [
            {
              url: 'https://staticshield.vercel.app/ogimage.png',
            },
          ],
          site_name: 'SiteName',
        }}
        twitter={{
          handle: '@lalitcodes',
          cardType: 'summary_large_image',
        }}
      />

      <PwaImages />
      <motion.div
        key={router.route}
        initial='pageInitial'
        animate='pageAnimate'
        variants={{
          pageInitial: {
            opacity: 0,
          },
          pageAnimate: {
            opacity: 1,
          },
        }}>
        <ProgressBar height={3} color='#0170F3' />
        <GeistProvider>
          <CssBaseline />
          <Component {...pageProps} />
        </GeistProvider>
      </motion.div>
    </UserProvider>
  );
}
Example #15
Source File: 404.tsx    From apps with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function Custom404Seo(): ReactElement {
  return (
    <Custom404>
      <NextSeo title="Page not found" nofollow noindex />
    </Custom404>
  );
}
Example #16
Source File: DendronSEO.tsx    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function DendronSEO({
  note,
  config,
}: {
  note: NoteProps;
  config: IntermediateDendronConfig;
}) {
  const dendronRouter = useDendronRouter();
  const path = dendronRouter.router.asPath;

  // don't generate for following pages
  if (
    _.some(["403"], (ent) => {
      return path === `/notes/${ent}/`;
    })
  ) {
    return null;
  }

  const siteSeoProps = PublishUtils.getSEOPropsFromConfig(config);
  const noteSeoProps = PublishUtils.getSEOPropsFromNote(note);
  const cleanSeoProps: SEOProps = _.defaults(noteSeoProps, siteSeoProps);

  const title = cleanSeoProps.title;
  const description = cleanSeoProps.excerpt;
  const images = cleanSeoProps?.image ? [cleanSeoProps.image] : [];
  const publishingConfig = ConfigUtils.getPublishingConfig(config);
  const canonical = getCanonicalUrl({
    sitePath: path,
    seoProps: cleanSeoProps,
    siteConfig: publishingConfig,
  });
  const maybeTwitter: NextSeoProps["twitter"] = cleanSeoProps.twitter
    ? {
        handle: cleanSeoProps.twitter,
        site: cleanSeoProps.twitter,
        cardType: "summary_large_image",
      }
    : undefined;
  const getTags = (note: NoteProps): string[] => {
    if (note.tags) {
      if (Array.isArray(note.tags)) {
        return note.tags;
      } else {
        return [note.tags];
      }
    } else {
      return [];
    }
  };
  return (
    <NextSeo
      title={title}
      description={description}
      canonical={canonical}
      noindex={cleanSeoProps.noindex}
      twitter={maybeTwitter}
      openGraph={{
        title,
        description,
        url: canonical,
        images,
        type: `article`,
        article: {
          publishedTime: unix2SEOTime(cleanSeoProps.created),
          modifiedTime: unix2SEOTime(cleanSeoProps.updated),
          tags: getTags(note),
        },
      }}
    />
  );
}
Example #17
Source File: [appDetails].tsx    From frontend with Apache License 2.0 5 votes vote down vote up
export default function Details({
  app,
  summary,
  stats,
  developerApps,
}: {
  app: Appstream
  summary?: Summary
  stats: AppStats
  developerApps: Appstream[]
}) {
  const screenshots = app.screenshots
    ? app.screenshots.filter(pickScreenshot).map((screenshot: Screenshot) => ({
      url: pickScreenshot(screenshot).url,
    }))
    : []

  return (
    <Main>
      <NextSeo
        title={app?.name}
        description={app?.summary}
        openGraph={{
          images: [
            {
              url: app?.icon,
            },
            ...screenshots,
          ],
        }}
      />
      <ApplicationDetails
        app={app}
        summary={summary}
        stats={stats}
        developerApps={developerApps.filter(devApp => devApp.id !== app.id)}
      />
    </Main >
  )
}
Example #18
Source File: Hero.tsx    From core with GNU Affero General Public License v3.0 5 votes vote down vote up
Hero:React.FC<HeroProps> = ({ type='all', header, description }) => {
	const link = `/${type}/categories`
	return <>
		<NextSeo title={header} description={description} openGraph={{
			title: header,
			description
		}} />
		<div className='dark:bg-discord-black bg-discord-blurple text-gray-100 md:p-0 mb-8'>
			<Container className='pt-24 pb-16 md:pb-20' ignoreColor>
				<h1 className='hidden md:block text-left text-3xl font-bold'>
					{ header && `${header} - `}한국 디스코드 리스트
				</h1>
				<h1 className='md:hidden text-center text-3xl font-semibold'>
					{ header && <span className='text-4xl'>{header}<br/></span>}한국 디스코드 리스트
				</h1>
				<p className='text-center sm:text-left text-xl font-base mt-2'>{description || `${type !== 'all' ? '다양한 ' : ''}국내 디스코드${{ all: '의 모든 것을', bots: ' 봇들을', servers: ' 서버들을' }[type]} 한 곳에서 확인하세요!`}</p>
				<Search />
				<div className='flex flex-wrap mt-5'>
					{
						type === 'all' ? <>
							<Tag text={
								<>
									<i className='fas fa-robot text-koreanbots-blue'/> 봇 리스트
								</>
							} dark bigger href='/bots' />
							<Tag text={
								<>
									<i className='fas fa-users text-koreanbots-blue'/> 서버 리스트
								</>
							} dark bigger href='/servers' />
							{
								botCategories.slice(0, 2).map(t => <Tag key={t} text={<><i className={botCategoryIcon[t]} /> {t} 봇</>} dark bigger href={`/bots/categories/${t}`} />)
							}
							
							{
								serverCategories.slice(0, 2).map(t => <Tag key={t} text={<><i className={serverCategoryIcon[t]} /> {t} 서버</>} dark bigger href={`/servers/categories/${t}`} />)
							}
						</>: <>
							<Tag key='list' text={<>
								<i className='fas fa-heart text-red-600'/> 하트 랭킹
							</>} dark bigger href={type === 'bots' ? '/bots/list/votes' : '/servers/list/votes'} />
							{ (type === 'bots' ? botCategories : serverCategories).slice(0, 4).map(t=> <Tag key={t} text={<>
								<i className={(type === 'bots' ? botCategoryIcon : serverCategoryIcon)[t]} /> {t}
							</>} dark bigger href={`${link}/${t}`} />) }
							<Tag key='tag' text={<>
								<i className='fas fa-tag'/> 카테고리 더보기
							</>} dark bigger href={link} />
						</>
					}
				</div>
			</Container>
		</div>
	</>
}
Example #19
Source File: dashboard.tsx    From livepeer-com with MIT License 5 votes vote down vote up
function DashboardLayout({
  id,
  children,
  breadcrumbs,
  title,
  description,
  noindex = true,
  image,
  url,
  canonical,
  requireLoggedIn = true,
}: Props) {
  useEffect(() => {
    if (window.location.hostname === "livepeer.com") {
      ReactGA.pageview(window.location.pathname + window.location.search);
      hotjar.initialize(2525106, 6);
    }
  }, []);

  let seo = {
    title,
    description,
    noindex,
    openGraph: {
      title,
      description,
      url,
      images: [
        {
          url: image ? image.url : "https://livepeer.com/img/OG.png",
          alt: image ? image.alt : "Livepeer.com",
          width: 1200,
          height: 642,
        },
      ],
    },
  };

  if (canonical) {
    seo["canonical"] = canonical;
  }

  return (
    <>
      {requireLoggedIn && <DashboardRedirect />}
      <Elements stripe={getStripe()}>
        <Head>
          <meta name="viewport" content="width=1023" />
        </Head>
        <NextSeo {...seo} />
        <Sidebar id={id} />
        <Box css={{ pl: 270, width: "100%" }}>
          <Header breadcrumbs={breadcrumbs} />
          <Box
            css={{
              margin: "0 auto",
              maxWidth: "1520px",
            }}>
            {children}
          </Box>
        </Box>
      </Elements>
    </>
  );
}
Example #20
Source File: dash.tsx    From dh-web with GNU General Public License v3.0 5 votes vote down vote up
function Dashboard() {
    const theme = useTheme();
    const one = useMediaQuery(`(min-width:${theme.breakpoints.one + 1}px)`);
    const two = useMediaQuery(`(min-width:${theme.breakpoints.two + 1}px)`);
    const three = useMediaQuery(`(min-width:${theme.breakpoints.three + 1}px)`);

    return (
        <>
            <NextSeo
                defaultTitle="Dogehouse Revived"
                title="Dashboard | Dogehouse Revived"
                description="Taking voice conversations to the moon ?"
                additionalLinkTags={[
                    {
                        rel: "icon",
                        href: "https://cdn.lvk.sh/dogehouse/logo.svg",
                    },
                    {
                        rel: "apple-touch-icon",
                        href: "https://cdn.lvk.sh/dogehouse/logo.svg",
                        sizes: "76x76"
                    }
                ]}
            />
            <Grid>
                {
                    one &&
                    <Column>
                        <Logo small={!three} />
                        <FriendsList />
                    </Column>
                }
                <Column>
                    <SearchWrapper>
                        <Search />
                        {!two && <ProfileIconDataContainer />}
                    </SearchWrapper>
                    <div>
                        <Rooms />
                    </div>
                </Column>
                {
                    two &&
                    <Column>
                        <ProfileWrapper>
                            <ProfileIconDataContainer />
                        </ProfileWrapper>
                        <div>
                            <ProfileWidgetDataContainer />
                            <ScheduleDataContainer />
                        </div>
                    </Column>
                }
            </Grid >
        </>
    );
}
Example #21
Source File: [schoolID].tsx    From po8klasie with GNU General Public License v3.0 5 votes vote down vote up
SchoolPage: FC<SchoolPageProps> = ({ PROJECT: { appearance, schoolInfo }, school }) => (
  <AppLayout projectAppearance={appearance}>
    <NextSeo title={appearance.appName} />
    <SchoolHero school={school} />
    <SchoolPageContent schoolInfoConfig={schoolInfo} school={school} />
  </AppLayout>
)
Example #22
Source File: Page.tsx    From website with MIT License 5 votes vote down vote up
Page: React.FC<PageProps> = ({ children, title }) => (
  <AppRoot>
    <NextSeo title={title || ''} />
    <TopNavigation title={title || ''} />
    {children}
    <Footer />
  </AppRoot>
)
Example #23
Source File: shop.tsx    From coindrop with GNU General Public License v3.0 5 votes vote down vote up
Shop: FC = () => {
    const [selectedTipCard, setSelectedTipCard] = useState("tip500");
    const green = useColorModeValue("green.500", "green.300");
    return (
        <Box>
            <NextSeo
                title="Tip Donation Payment Cards | Zero Fees | Coindrop Shop"
                description="Buy physical cards that can be used for tipping. Cards link to your Coindrop page where you can receive payments, donations, and tips with zero fees."
            />
            <Heading
                as="h1"
                size="2xl"
                textAlign="center"
                my={6}
            >
                Shop
            </Heading>
            <Box>
                <Flex
                    direction={["column", "row"]}
                    align={["center", "start"]}
                >
                    <Flex>
                        <Image src="/shop/tip-card.png" height="300" width="300" />
                    </Flex>
                    <Box ml={4}>
                        <Heading
                            my={4}
                        >
                            Tip Cards
                        </Heading>
                        <Text>
                            Accept donations and tips in the real world.
                            <br />
                            <br />
                            Cards measure 3 inches x 3 inches. Text and design can be customized.
                            <br />
                            <br />
                        </Text>
                        <Flex wrap="wrap" justify="space-around">
                            <Flex mt={2} direction="row" wrap="wrap" align="center">
                                <Text>Quantity:</Text>
                                <Box ml={2}>
                                    <Select
                                        value={selectedTipCard}
                                        onChange={(event) => {
                                            setSelectedTipCard(event.target.value);
                                        }}
                                    >
                                        <option value="tip500">500</option>
                                        <option value="tip1000">1,000</option>
                                        <option value="tip2500">2,500</option>
                                        <option value="tip5000">5,000</option>
                                        <option value="tip10000">10,000</option>
                                        <option value="tip25000">25,000</option>
                                    </Select>
                                </Box>
                            </Flex>
                            <Box>
                                <Flex mt={3} direction="row" wrap="wrap" align="center">
                                    <Text fontSize="3xl" fontWeight="bold" color={green}>
                                        ${products[selectedTipCard].price}
                                    </Text>
                                    <Text fontSize="sm" ml={2}>
                                        {` (${products[selectedTipCard].pricePer} per card)`}
                                    </Text>
                                </Flex>
                                <TipCardBuyButtons selectedId={selectedTipCard} />
                            </Box>
                        </Flex>
                    </Box>
                </Flex>
            </Box>
        </Box>
    );
}
Example #24
Source File: about.tsx    From samuelkraft-next with MIT License 5 votes vote down vote up
About = (): JSX.Element => {
  const linkProps = {
    target: '_blank',
    rel: 'noopener noreferrer',
  }
  const seoTitle = 'About Samuel Kraft'
  return (
    <Page>
      <NextSeo
        title={seoTitle}
        openGraph={{
          title: seoTitle,
          url: `https://samuelkraft.com/about/`,
          site_name: 'Samuel Kraft',
        }}
        twitter={{
          cardType: 'summary_large_image',
        }}
      />
      <Image src={me} alt="Picture of me (samuel kraft)" placeholder="blur" className={styles.image} priority />
      <div className={styles.text}>
        <p>Hey I’m Samuel, a frontend developer &amp; designer currently living in ?? Stockholm, Sweden.</p>
        <p>
          Right now I’m working at{' '}
          <a href="https://bitrefill.com/" {...linkProps}>
            Bitrefill
          </a>
          , designing &amp; building the future of crypto. Before that I worked at{' '}
          <a href="https://www.tracklib.com/" {...linkProps}>
            Tracklib
          </a>
          , the record store for sampling.
        </p>
        <p>
          I grew up in Nacka just outside of Stockholm (the perfect distance from town while living next door to amazing nature ?) and come
          from a background of studying Photography. I love working in the realm between design and code. Some stuff that makes me excited
          are CSS, React, Design Systems, Component Kits, UI Animation and delightful interfaces ✨.
        </p>
        <p>
          In my spare time I love being outdoors, training and travelling with my family (check out{' '}
          <a href="https://www.instagram.com/thejetlagfamily/" {...linkProps}>
            @thejetlagfamily
          </a>{' '}
          ✈️).
        </p>
      </div>
      <Button href="mailto:[email protected]">Contact me</Button>
    </Page>
  )
}
Example #25
Source File: ProductView.tsx    From nextjs-shopify with MIT License 4 votes vote down vote up
ProductBox: React.FC<Props> = ({
  product,
  renderSeo,
  description = product.description,
  title = product.title,
}) => {
  const [loading, setLoading] = useState(false)
  const addItem = useAddItemToCart()
  const colors: string[] | undefined = product?.options
    ?.find((option) => option?.name?.toLowerCase() === 'color')
    ?.values?.map((op) => op.value as string)

  const sizes: string[] | undefined = product?.options
    ?.find((option) => option?.name?.toLowerCase() === 'size')
    ?.values?.map((op) => op.value as string)

  const variants = useMemo(
    () => prepareVariantsWithOptions(product?.variants),
    [product?.variants]
  )
  const images = useMemo(() => prepareVariantsImages(variants, 'color'), [
    variants,
  ])

  const { openSidebar } = useUI()

  const [variant, setVariant] = useState(variants[0] || {})
  const [color, setColor] = useState(variant.color)
  const [size, setSize] = useState(variant.size)

  useEffect(() => {
    const newVariant = variants.find((variant) => {
      return (
        (variant.size === size || !size) && (variant.color === color || !color)
      )
    })

    if (variant.id !== newVariant?.id) {
      setVariant(newVariant)
    }
  }, [size, color, variants, variant.id])

  const addToCart = async () => {
    setLoading(true)
    try {
      await addItem(variant.id, 1)
      openSidebar()
      setLoading(false)
    } catch (err) {
      setLoading(false)
    }
  }
  const allImages = images
    .map(({ src }) => ({ src: src.src }))
    .concat(
      product.images &&
        product.images.filter(
          ({ src }) => !images.find((image) => image.src.src === src)
        )
    )

  return (
    <React.Fragment>
      {renderSeo && (
        <NextSeo
          title={title}
          description={description}
          openGraph={{
            type: 'website',
            title: title,
            description: description,
            images: [
              {
                url: product.images?.[0]?.src!,
                width: 800,
                height: 600,
                alt: title,
              },
            ],
          }}
        />
      )}
      <Grid gap={4} columns={[1, 2]}>
        <div>
          <div
            sx={{
              border: '1px solid gray',
              padding: 2,
              marginBottom: 2,
            }}
          >
            <ImageCarousel
              showZoom
              alt={title}
              width={1050}
              height={1050}
              priority
              onThumbnailClick={(index) => {
                if (images[index]?.color) {
                  setColor(images[index].color)
                }
              }}
              images={allImages?.length > 0 ? allImages: [{
                  src: `https://via.placeholder.com/1050x1050`,
                }]}
            ></ImageCarousel>
          </div>
        </div>
        <div sx={{ display: 'flex', flexDirection: 'column' }}>
          <span sx={{ mt: 0, mb: 2 }}>
            <Themed.h1>{title}</Themed.h1>
            <Themed.h4 aria-label="price" sx={{ mt: 0, mb: 2 }}>
              {getPrice(variant.priceV2.amount, variant.priceV2.currencyCode)}
            </Themed.h4>
          </span>
          <div dangerouslySetInnerHTML={{ __html: description! }} />
          <div>
            <Grid padding={2} columns={2}>
              {colors?.length && (
                <OptionPicker
                  key="Color"
                  name="Color"
                  options={colors}
                  selected={color}
                  onChange={(event) => setColor(event.target.value)}
                />
              )}
              {sizes?.length && (
                <OptionPicker
                  key="Size"
                  name="Size"
                  options={sizes}
                  selected={size}
                  onChange={(event) => setSize(event.target.value)}
                />
              )}
            </Grid>
          </div>
          <Button
            name="add-to-cart"
            disabled={loading}
            sx={{ margin: 2, display: 'block' }}
            onClick={addToCart}
          >
            Add to Cart {loading && <LoadingDots />}
          </Button>
        </div>
      </Grid>
    </React.Fragment>
  )
}
Example #26
Source File: Homepage.tsx    From pagely with MIT License 4 votes vote down vote up
export default function Page() {
  return (
    <div>
      <Navbar />
      <SignedIn>
        <RedirectIfUser />
      </SignedIn>
      <Head>
        {/* eslint-disable-next-line @next/next/no-sync-scripts */}
        <script
          data-name='BMC-Widget'
          data-cfasync='false'
          src='https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js'
          data-id='lalitcodes'
          data-description='Support me on Buy me a coffee!'
          data-message="If you like my app, please consider buying me a coffee ☕️If you cannot, it's fine ?. Hope you enjoy my app"
          data-color='#5F7FFF'
          data-position='Right'
          data-x_margin='18'
          data-y_margin='18'></script>
      </Head>
      <NextSeo
        title='Pagely'
        description='Launch SEO friendly, blazing fast websites from Notion, Google Sheets, GitHub, Airtable with Pagely"'
        canonical='https://www.pagely.site/'
        openGraph={{
          title: 'Pagely',
          url: 'https://www.pagely.site/',
          images: [
            {
              url: 'https://www.pagely.site/ogimage.png',
              alt: 'Launch SEO friendly, blazing fast websites from Notion, Google Sheets, GitHub, Airtable with Pagely',
            },
          ],
          description:
            'Launch SEO friendly, blazing fast websites from Notion,Google Sheets, GitHub, Airtable with Pagely',
        }}
        twitter={{
          cardType: 'summary_large_image',
          handle: '@lalitcodes',
        }}
      />
      <div className='mx-10'>
        <div className='max-w-5xl mx-auto mt-24'>
          <div className='text-center'>
            <p className='mb-1 text-xs font-semibold tracking-widest text-gray-500 uppercase title-font'>
              No coding required
            </p>
            <h1 className='text-5xl font-extrabold'>
              Build beautiful websites. In light speed
            </h1>
            <h2 className='mt-5 text-xl text-gray-600'>
              Launch websites from{' '}
              <span className='relative inline-block mx-1 top-1'>
                <SiNotion />
              </span>
              <span className='font-medium text-gray-700'>Notion</span>,
              <span className='relative inline-block mx-1 top-1'>
                <SiGooglesheets />
              </span>
              <span className='font-medium text-gray-700'>Google Sheets</span>,{' '}
              <span className='relative inline-block mx-1 top-1'>
                <SiGithub />
              </span>
              <span className='font-medium text-gray-700'>GitHub </span>or{' '}
              <span className='relative inline-block mx-1 top-1'>
                <SiAirtable />
              </span>{' '}
              <span className='font-medium text-gray-700'>Airtable</span>
            </h2>
          </div>
        </div>

        <Link href='/sign-up' passHref={true}>
          <div className='max-w-xs py-4 mx-auto my-20 text-center text-gray-100 rounded-md shadow-sm cursor-pointer focus:ring-1 focus:ring-blue-500 bg-custom-blue hover:bg-blue-600'>
            <a>Get started now -{'>'}</a>
          </div>
        </Link>

        <div className='py-12 bg-gray-100 rounded-xl'>
          <div className='px-4 mx-auto max-w-7xl sm:px-6 lg:px-8'>
            <div className='lg:text-center'>
              <h2 className='mb-1 text-xs font-semibold tracking-widest text-gray-500 uppercase title-font'>
                Mind-blowing
              </h2>
              <p className='mt-2 text-3xl font-extrabold leading-8 tracking-tight text-gray-900 sm:text-4xl'>
                Features
              </p>
              <p className='max-w-2xl mt-4 text-xl text-gray-500 lg:mx-auto'>
                Customize most of your Pagely site <br />
                with widgets, styles and more…
              </p>
            </div>

            <div className='mt-10'>
              <dl className='space-y-10 md:space-y-0 md:grid md:grid-cols-2 md:gap-x-8 md:gap-y-10'>
                {features.map((feature) => (
                  <div key={feature.name} className='relative'>
                    <dt>
                      <div className='absolute flex items-center justify-center w-12 h-12 text-white bg-blue-500 rounded-md'>
                        <feature.icon className='w-6 h-6' aria-hidden='true' />
                      </div>
                      <p className='ml-16 text-lg font-medium leading-6 text-gray-900'>
                        {feature.name}
                      </p>
                    </dt>
                    <dd className='mt-2 ml-16 text-base text-gray-500'>
                      {feature.description}
                    </dd>
                  </div>
                ))}
              </dl>
            </div>
          </div>
        </div>
        <div className='my-10'>
          <a
            href='https://lalit2005.hashnode.dev/pagely'
            target='_blank'
            rel='noopener noreferrer'>
            <p className='text-4xl font-bold text-center text-blue-700 transition-all hover:text-blue-500 hover:underline'>
              Made by Lalit
            </p>
          </a>
        </div>
      </div>
    </div>
  );
}
Example #27
Source File: [slug].tsx    From storefront with MIT License 4 votes vote down vote up
Product: NextPage = () => {
  const router = useRouter();

  const { data: { product } = { product: undefined }, loading } = useProductQuery({
    variables: {
      slug: `${router.query.slug}`,
    },
  });

  useEffect(() => {
    if (product != null) {
      ReactGA.plugin.execute('ec', 'addProduct', {
        id: product.id,
        name: product.name,
        category: product.productCategories?.nodes?.[0]?.name,
        price:
          (product.__typename === 'SimpleProduct' ||
            product.__typename === 'VariableProduct' ||
            product.__typename === 'ExternalProduct') &&
          product.price != null
            ? parseFloat(product.price)
            : undefined,
      });
      ReactGA.plugin.execute('ec', 'setAction', 'detail');
    }
  }, [product]);

  return (
    <Layout>
      {loading || product == null ? (
        <Loader fullHeight />
      ) : (
        <>
          <NextSeo
            title={product.seo?.title ?? undefined}
            description={product.seo?.metaDesc ?? undefined}
            openGraph={{
              title: product.seo?.opengraphTitle ?? undefined,
              description: product.seo?.opengraphDescription ?? undefined,
              type: 'product',
              images:
                product.seo?.opengraphImage?.sourceUrl != null
                  ? [
                      {
                        url: product.seo.opengraphImage.sourceUrl,
                        alt: product.seo.opengraphImage.altText ?? undefined,
                        width: product.seo.opengraphImage.mediaDetails?.width ?? undefined,
                        height: product.seo.opengraphImage.mediaDetails?.height ?? undefined,
                      },
                    ]
                  : undefined,
            }}
          />
          <ProductJSON product={product} />
          <Container>
            <Box sx={{ my: 6, overflow: { xs: 'hidden', md: 'inherit' } }}>
              <Grid container spacing={6}>
                <Grid item xs={12} md={6}>
                  <ProductGallery product={product} />
                </Grid>
                <Grid item xs={12} md={6}>
                  <Box sx={{ position: 'sticky', top: 48 }}>
                    <ProductSummary product={product} />
                    <AddToCart product={product} />
                    <ProductMeta product={product} />
                  </Box>
                </Grid>
              </Grid>
              {!isBlank(product.shortDescription) && !isBlank(product.description) && (
                <Box sx={{ mt: 6 }}>
                  <Typography gutterBottom variant="h3">
                    Description
                  </Typography>
                  <RichText>{product.description}</RichText>
                </Box>
              )}
              <ProductAttributes product={product} />
            </Box>
            {(product.related?.nodes?.length ?? 0) > 0 && (
              <Box sx={{ mb: 6 }}>
                <Typography gutterBottom variant="h3">
                  Related products
                </Typography>
                <ProductGrid products={product.related?.nodes ?? []} />
              </Box>
            )}
          </Container>
        </>
      )}
    </Layout>
  );
}
Example #28
Source File: KeywordManagement.tsx    From apps with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function KeywordManagement({
  keyword,
  subtitle,
  onOperationCompleted,
}: KeywordManagerProps): ReactElement {
  const { windowLoaded } = useContext(ProgressiveEnhancementContext);
  const [currentAction, setCurrentAction] = useState<string | null>(null);

  const nextKeyword = async () => {
    if (onOperationCompleted) {
      await onOperationCompleted();
    }
    setCurrentAction(null);
  };

  const { mutateAsync: allowKeyword } = useMutation(
    () =>
      request(`${apiUrl}/graphql`, ALLOW_KEYWORD_MUTATION, {
        keyword: keyword.value,
      }),
    {
      onSuccess: () => nextKeyword(),
    },
  );

  const { mutateAsync: denyKeyword } = useMutation(
    () =>
      request(`${apiUrl}/graphql`, DENY_KEYWORD_MUTATION, {
        keyword: keyword.value,
      }),
    {
      onSuccess: () => nextKeyword(),
    },
  );

  const posts = useInfiniteQuery<FeedData>(
    ['keyword_post', keyword.value],
    ({ pageParam }) =>
      request(`${apiUrl}/graphql`, KEYWORD_FEED_QUERY, {
        keyword: keyword.value,
        first: 4,
        after: pageParam,
      }),
    {
      getNextPageParam: (lastPage) =>
        lastPage.page.pageInfo.hasNextPage && lastPage.page.pageInfo.endCursor,
    },
  );

  const onAllow = () => {
    setCurrentAction('allow');
    return allowKeyword();
  };

  const onSynonym = () => setCurrentAction('synonym');

  const onDeny = () => {
    setCurrentAction('deny');
    return denyKeyword();
  };

  const disableActions = !!currentAction;

  return (
    <ResponsivePageContainer style={{ paddingBottom: sizeN(23) }}>
      <NextSeo title="Pending Keywords" nofollow noindex />
      <h1 className="m-0 font-bold typo-title2">{keyword.value}</h1>
      <div className="flex justify-between items-center my-1 text-theme-label-tertiary typo-callout">
        <span>Occurrences: {keyword.occurrences}</span>
        <span>{subtitle}</span>
      </div>
      <ActivitySection
        title="Keyword Posts"
        query={posts}
        emptyScreen={
          <div className="font-bold typo-title3" data-testid="emptyPosts">
            No posts
          </div>
        }
        elementToNode={(post) => (
          <Link
            href={post.commentsPermalink}
            passHref
            key={post.id}
            prefetch={false}
          >
            <a
              target="_blank"
              rel="noopener noreferrer"
              aria-label={post.title}
              className="flex items-start tablet:items-center py-3 no-underline"
            >
              <LazyImage
                imgSrc={smallPostImage(post.image)}
                imgAlt="Post cover image"
                className="w-16 h-16 rounded-2xl"
              />
              <p
                className="flex-1 self-center p-0 tablet:mr-6 ml-4 whitespace-pre-wrap break-words-overflow text-theme-label-primary typo-callout multi-truncate"
                style={{
                  maxHeight: '3.75rem',
                  maxWidth: '19.25rem',
                  lineClamp: 3,
                }}
              >
                {post.title}
              </p>
            </a>
          </Link>
        )}
      />
      <div
        className={classNames(
          'fixed flex left-0 right-0 bottom-0 w-full items-center justify-between mx-auto py-6 px-4 bg-theme-bg-primary',
          styles.buttons,
        )}
      >
        <Button
          loading={currentAction === 'allow'}
          onClick={onAllow}
          disabled={disableActions}
          className="btn-primary"
        >
          Allow
        </Button>
        <Button
          disabled={disableActions}
          onClick={onSynonym}
          className="btn-secondary"
        >
          Synonym
        </Button>
        <Button
          loading={currentAction === 'deny'}
          onClick={onDeny}
          disabled={disableActions}
          className="btn-primary-ketchup"
        >
          Deny
        </Button>
      </div>
      {(windowLoaded || currentAction === 'synonym') && (
        <KeywordSynonymModal
          isOpen={currentAction === 'synonym'}
          selectedKeyword={keyword.value}
          onRequestClose={nextKeyword}
        />
      )}
    </ResponsivePageContainer>
  );
}
Example #29
Source File: about.tsx    From frontend with Apache License 2.0 4 votes vote down vote up
About = () => {
  const { t } = useTranslation()

  return (
    <Main>
      <NextSeo
        title={t('about')}
        description={t('about-description')}
      />
      <div
        className={styles.about}
        style={{
          display: 'flex',
          flexDirection: 'column',
        }}
      >
        {/* <!-- header --> */}
        <header
          style={{ display: 'flex' }}
          className={`${styles.headerContainer} ${styles.storeContentContainerNarrow}`}
        >
          <div className={styles.headerContent}>
            <h1>{t('about-pagename')}</h1>
            <Trans i18nKey={"common:about-block"}>
              <p>
                Flathub aims to be the place to get and distribute apps for Linux.
                It is powered by <a href='https://flatpak.org'>Flatpak</a> which
                allows Flathub apps to run on almost any Linux distribution.
              </p>

              <p>
                If you are a Linux user, you can use Flathub to gain access to a
                growing collection of Flatpak applications. You just need to
                follow the{' '}
                <a href='https://flatpak.org/setup/'>setup instructions</a>.
              </p>
            </Trans>
          </div>
        </header>

        {/* <!-- main content --> */}
        <section
          style={{ display: 'flex', flexDirection: 'column' }}
          className={styles.storeContentContainerNarrow}
        >
          <h2>{t('submitting-apps')}</h2>
          <Trans i18nKey={"common:submitting-apps-block"}>
            <p>
              App developers can{' '}
              <a href='https://github.com/flathub/flathub/wiki/App-Submission'>
                submit their applications
              </a>{' '}
              to be distributed to Flathub&apos;s growing user base, thus
              providing a single gateway to the entire Linux desktop ecosystem.
            </p>
            <p>
              At the moment, applications must either be legally redistributable
              or be available as a third party download. However, if you are a
              proprietary app developer and are interested in using Flathub, we
              would love to talk to you.
            </p>
          </Trans>

          <h2>{t('get-involved')}</h2>
          <Trans i18nKey={"common:get-involved-block"}>
            <p>
              Flathub is an attempt to transform the Linux desktop ecosystem for
              the better, and we need your help. If you can write documentation,
              create websites, administer servers or write code, we would love
              your help.
            </p>
          </Trans>

          <h2>{t('reporting-issues')}</h2>
          <Trans i18nKey={"common:reporting-issues-block"}>
            <p>
              Security or legal issues can be reported to the{' '}
              <a href='mailto:[email protected]'>
                Flathub maintainers
              </a>
              .
            </p>
          </Trans>

          <h2>{t('acknowledgements')}</h2>
          <Trans i18nKey={"common:acknowledgements-block"}>
            <p>
              Flathub wouldn&apos;t be possible without the generous support of
              the following organizations and individuals.
            </p>
          </Trans>
          <div>
            <div>Codethink</div>
            <div>Cloud Native Computing Foundation</div>
            <div>Fastly</div>
            <div>Mythic Beasts</div>
            <div>Prerender.io</div>
            <div>Scaleway</div>
            <br />

            <div>Alex Larsson</div>
            <div>Andreas Nilsson</div>
            <div>Arun Raghavan</div>
            <div>Bartłomiej Piotrowski</div>
            <div>Christian Hergert</div>
            <div>Christopher Halse Rogers</div>
            <div>Cosimo Cecchi</div>
            <div>Emmanuele Bassi</div>
            <div>G Stavracas Neto</div>
            <div>Jakub Steiner</div>
            <div>James Shubin</div>
            <div>Joaquim Rocha</div>
            <div>Jorge García Oncins</div>
            <div>Lubomír Sedlář</div>
            <div>Nathan Dyer</div>
            <div>Nick Richards</div>
            <div>Mario Sanchez Prada</div>
            <div>Matthias Clasen</div>
            <div>Michael Doherty</div>
            <div>Robert McQueen</div>
            <div>Zach Oglesby</div>
          </div>
        </section>
      </div >
    </Main >
  )
}