next-seo#NextSeo JavaScript 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: SEO.js    From tambouille with MIT License 6 votes vote down vote up
PageSeo = ({ description, url, title = null }) => {
  return (
    <NextSeo
      title={title ? `${title} | ${siteMetadata.title}` : siteMetadata.title}
      description={description}
      canonical={url}
      openGraph={{
        url,
        title,
        description,
      }}
    />
  )
}
Example #2
Source File: global.jsx    From NextBook with MIT License 6 votes vote down vote up
export default function GlobalLayout({ title, part, description, children }) {
  const { projectTitle, projectURL, projectDescription } = config
  const htmlTitle = part ? `${title} - ${part}` : title

  return (
    <>
      <NextSeo
        title={`${htmlTitle} | ${projectTitle}`}
        description={description ? description : projectDescription}
        openGraph={{
          type: 'website',
          url: projectURL,
          title: title,
          description: description
        }}
      />

      <Head>
        <meta
          content='width=device-width, initial-scale=1.0, maximum-scale=5.0'
          name='viewport'
        />
        <link rel='icon' href='/favicon.ico' />
        <link rel='icon' href='/icon.svg' type='image/svg+xml' />
        <link rel='apple-touch-icon' href='/512.png' />
        <link rel='manifest' href='/manifest.json' />
      </Head>

      <header className='z-40 md:shadow-md bg-gray-200 dark:bg-gray-800 fixed w-screen top-0 h-10 md:h-14 font-medium'>
        <NavBar />
      </header>

      <div className='content-wrapper mt-10 md:mt-14 flex xl:container xl:mx-auto'>
        <SideBar />
        <div className='md-wrapper flex md:ml-56 xl:ml-64'>{children}</div>
      </div>
    </>
  )
}
Example #3
Source File: about.jsx    From club-connect with GNU General Public License v3.0 6 votes vote down vote up
About = (props) => {
  return (
    <>
      <Head>
        <title>{pageTitle}</title>
      </Head>

      <NextSeo
        title={pageTitle}
        openGraph={{
          title: pageTitle,
          url: 'https://bccompsci.club/about',
        }}
      />

      <div>
        <TopSection />
        <WhoWeAreSection />
        <WhatWeDoSection />
        <TeamSection />
        <Ending width={props.width} />
      </div>
    </>
  );
}
Example #4
Source File: BlogSeo.js    From benjamincarlson.io with MIT License 6 votes vote down vote up
BlogSeo = ({ title, summary, publishedAt, url, image }) => {
    const date = new Date(publishedAt).toISOString()
    const featuredImage = {
        url: `https://benjamincarlson.io${image}`,
        alt: title
    }

    return (
        <>
            <NextSeo
                title={`${title} – Benjamin Carlson`}
                description={summary}
                canonical={url}
                openGraph={{
                    type: 'article',
                    article: {
                        publishedTime: date
                    },
                    url,
                    title,
                    description: summary,
                    images: [featuredImage]
                }}
            />
            <ArticleJsonLd
                authorName="Benjamin Carlson"
                dateModified={date}
                datePublished={date}
                description={summary}
                images={[featuredImage]}
                publisherLogo="/static/favicons/android-chrome-192x192.png"
                publisherName="Benjamin Carlson"
                title={title}
                url={url}
            />
        </>
    )
}
Example #5
Source File: index.js    From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal 6 votes vote down vote up
ForumCategoryIndexPage = () => {
  return (
    <>
      <NextSeo
        title={`Remotebond Forum a hub for everything related to remote work`}
        description="The Remotebond Forum is a how-to content hub for all things remote work."
        canonical={`https://remotebond.com/forum`}
        openGraph={{
          url: `https://remotebond.com/forum`,
          title: `Remotebond Forum a hub for everything related to remote work`,
          description: `The Remotebond Forum is a how-to content hub for all things remote work.`,
        }}
      />
      <BreadcrumbJsonLd
        itemListElements={[
          {
            position: 1,
            name: "remotebond.com",
            item: "https://remotebond.com",
          },
          {
            position: 2,
            name: "Forum",
          },
        ]}
      />
      <PageHeader
        title={`Remotebond Forum`}
        subtitle={`The Remotebond Forum is a how-to content hub for all things remote work. From best practices for job seekers, tools, resources and news to hiring tips and processes, the Remotebond forum is meant to be community-driven documentation on how to get remote work right.`}
      />
    </>
  )
}
Example #6
Source File: Seo.js    From mailmask with GNU Affero General Public License v3.0 6 votes vote down vote up
Seo = ({ title, description, publishedTime }) => (
  <NextSeo
    title={title || defaultTitle}
    titleTemplate={title ? '%s | Mailmask' : defaultTitle}
    description={description || `${defaultTitle}. Unlimited, free temporary email addresses, all forwarding to your real email address. Beat spam, protect your privacy.`}
    openGraph={{
      type: 'website',
      locale: 'en_GB',
      site_name: 'Mailmask',
      article: {
        publishedTime: publishedTime ? new Date(publishedTime).toISOString() : '2020-05-31T11:10:51.498Z',
      },
      images: [
        {
          url: 'https://pbs.twimg.com/profile_banners/1275361568511922176/1592904999/1500x500',
          width: 1500,
          height: 500,
          alt: 'Mailmask - easily stop unwanted email',
        },
      ]
    }}
    twitter={{
      handle: '@hiddentao',
      site: '@mskhq',
      cardType: 'summary_large_image',
    }}
  />
)
Example #7
Source File: Header.jsx    From ui with MIT License 6 votes vote down vote up
Header = (props) => {
  const {
    experimentId, experimentData, title, extra,
  } = props;
  const experiment = useSelector((state) => state?.experiments[experimentId]);
  const experimentName = experimentData?.experimentName || experiment?.name;

  const truncateText = (text) => (
    (text && text.length > 28) ? `${text.substr(0, 27)}…` : text
  );

  return (
    <>
      <NextSeo
        title={experimentData ? `${title} · ${truncateText(experimentName)}` : title}
      />

      <PageHeader
        className={integrationTestConstants.classes.PAGE_HEADER}
        title={title}
        style={{ width: '100%', paddingTop: '10px', paddingBottom: '10px' }}
        extra={(
          <Space size='large'>
            <Space>
              <HelpButton />
              <FeedbackButton />
              <ReferralButton />
              {extra}
            </Space>
            <UserButton />
          </Space>
        )}
      />
    </>
  );
}
Example #8
Source File: seo.jsx    From docs with MIT License 6 votes vote down vote up
export function SEO({ title, description, slug = "" }) {
  const titleFormatted = `${title ? title : "Nhost documentation"}`;
  const url = `https://docs.nhost.io/${slug}`;

  return (
    <React.Fragment>
      <NextSeo
        title={titleFormatted}
        description={description}
        canonical={url}
        openGraph={{
          url: url,
          title: titleFormatted,
          description: description,
        }}
      />
    </React.Fragment>
  );
}
Example #9
Source File: seo.js    From stacker.news with MIT License 6 votes vote down vote up
export function SeoSearch ({ sub }) {
  const router = useRouter()
  const subStr = sub ? ` ~${sub}` : ''
  const title = `${router.query.q || 'search'} \\ stacker news${subStr}`
  const desc = `SN${subStr} search: ${router.query.q || ''}`

  return (
    <NextSeo
      title={title}
      description={desc}
      openGraph={{
        title: title,
        description: desc,
        images: [
          {
            url: 'https://stacker.news/api/capture' + router.asPath
          }
        ],
        site_name: 'Stacker News'
      }}
      twitter={{
        site: '@stacker_news',
        cardType: 'summary_large_image'
      }}
    />
  )
}
Example #10
Source File: seo.js    From strapi-starter-next-corporate with MIT License 6 votes vote down vote up
Seo = ({ metadata }) => {
  // Prevent errors if no metadata was set
  if (!metadata) return null

  return (
    <NextSeo
      title={metadata.metaTitle}
      description={metadata.metaDescription}
      openGraph={{
        // Title and description are mandatory
        title: metadata.metaTitle,
        description: metadata.metaDescription,
        // Only include OG image if we have it
        // Careful: if you disable image optimization in Strapi, this will break
        ...(metadata.shareImage && {
          images: Object.values(metadata.shareImage.formats).map((image) => {
            return {
              url: getStrapiMedia(image.url),
              width: image.width,
              height: image.height,
            }
          }),
        }),
      }}
      // Only included Twitter data if we have it
      twitter={{
        ...(metadata.twitterCardType && { cardType: metadata.twitterCardType }),
        // Handle is the twitter username of the content creator
        ...(metadata.twitterUsername && { handle: metadata.twitterUsername }),
      }}
    />
  )
}
Example #11
Source File: _app.jsx    From neighbor-express with MIT License 6 votes vote down vote up
function CustomSeo() {
	let { state, dispatch } = useContext(CMSContext);
	const title = getCmsRecordFromKey('title', state);
	const openGraph = title
		? {
				title: title.title,
				description: title.body,
		  }
		: null;
	return title ? <NextSeo title={title.title} description={title.body} openGraph={openGraph} /> : null;
}
Example #12
Source File: Layout.js    From Modtoberfest-Site with MIT License 5 votes vote down vote up
export default function Layout({
  fluid,
  children,
  className,
  title = "Modtoberfest",
  description,
  canonical,
  image,
  url,
  ...props
}) {
  return (
    <>
      <NextSeo
        title={title}
        description={description}
        canonical={`https://modtoberfest.com${canonical || "/"}`}
        openGraph={{
          type: "website",
          title: title,
          url: `https://modtoberfest.com${url || canonical || "/"}`,
          description: description,
          images: [
            {
              url: image || "https://modtoberfest.com/logo/badge-bg-pad.png",
              alt: title + " logo",
            },
          ],
          site_name: "Modtoberfest",
        }}
        twitter={{
          cardType: "summary_large_image",
        }}
      />
      <div className="flex flex-col min-h-screen h-full">
        <NavBar />
        <main className={classNames("md:px-8 md:pt-1", className)}>
          {children}
        </main>
      </div>
    </>
  );
}
Example #13
Source File: SEO.js    From tambouille with MIT License 5 votes vote down vote up
BlogSeo = ({ summary, date, lastmod, url, title, tags, images = [] }) => {
  const publishedAt = new Date(date).toISOString()
  const modifiedAt = new Date(lastmod || date).toISOString()
  let imagesArr =
    images.length === 0
      ? [siteMetadata.socialBanner]
      : typeof images === 'string'
      ? [images]
      : images

  const featuredImages = imagesArr.map((img) => ({
    url: `${siteMetadata.siteUrl}${img}`,
    alt: title ?? siteMetadata.title,
  }))

  return (
    <>
      <NextSeo
        title={title ? `${title} | ${siteMetadata.title}` : siteMetadata.title}
        description={summary}
        canonical={url}
        openGraph={{
          type: 'article',
          article: {
            publishedTime: publishedAt,
            modifiedTime: modifiedAt,
            authors: [`${siteMetadata.siteUrl}/about`],
            tags,
          },
          url,
          title: title ?? siteMetadata.title,
          description: summary,
          images: featuredImages,
        }}
        additionalMetaTags={[
          {
            name: 'twitter:image',
            content: featuredImages[0].url,
          },
        ]}
      />
      <ArticleJsonLd
        authorName={siteMetadata.author}
        dateModified={modifiedAt}
        datePublished={publishedAt}
        description={summary}
        images={featuredImages}
        publisherName={siteMetadata.author}
        title={title ?? siteMetadata.title}
        url={url}
      />
    </>
  )
}
Example #14
Source File: contribute.jsx    From club-connect with GNU General Public License v3.0 5 votes vote down vote up
Contribute = () => {
  return (
    <>
      <Head>
        <title>{pageTitle}</title>
      </Head>

      <NextSeo
        title={pageTitle}
        openGraph={{
          title: pageTitle,
          url: 'https://bccompsci.club/contribute',
        }}
      />

      <div
        className={`${commonStyles.container} ${commonStyles.text} ${contributeStyles.contribute}`}
      >
        <section>
          <h1 className={commonStyles.centerElement}>Contribute to the Club</h1>
          <p>
            The Brooklyn College Computer Science Club is a community-first,
            student-led organization made possible by a community of passionate
            students and innovative minds. Students from any major or background
            are welcome to learn and grow in our diverse and inclusive
            community.
          </p>

          <p>
            In order to further achieve our goal of being a community-first
            club, we're looking for some of our very own club members that share
            our vision to help shape the future of the Computer Science Club!
          </p>

          <p>
            If you're interested in contributing to the club, here are a few
            ways you can do so:
          </p>
          <ul className={contributeStyles.list}>
            <li>
              <ScrollDownPage to="volunteer">
                Volunteer for the club
              </ScrollDownPage>
            </li>

            <li>
              <ScrollDownPage to="open-source">
                Contribute to the club's open source software
              </ScrollDownPage>
            </li>

            <li>
              <ScrollDownPage to="host-event">
                Host and lead an event at the club
              </ScrollDownPage>
            </li>
          </ul>
        </section>

        {/* Sections of ways to contribute */}
        <Volunteer />
        <OpenSource />
        <HostEvent />
      </div>
    </>
  );
}
Example #15
Source File: blog.js    From benjamincarlson.io with MIT License 5 votes vote down vote up
export default function Blog({ posts }) {
    const [searchValue, setSearchValue] = useState('')

    const filteredBlogPosts = posts
        .sort(
            (a, b) =>
                Number(new Date(b.publishedAt)) - Number(new Date(a.publishedAt))
        )
        .filter((frontMatter) =>
            frontMatter.data?.title?.toLowerCase()?.includes(searchValue.toLowerCase()) ||
            frontMatter.data?.summary?.toLowerCase()?.includes(searchValue.toLowerCase())
        )

    return (
        <>
            <NextSeo
                title={title}
                description={description}
                canonical={url}
                openGraph={{
                    url,
                    title,
                    description
                }}
            />
            <Container>
                <Stack
                    as="main"
                    spacing={8}
                    justifyContent="center"
                    alignItems="flex-start"
                    m="0 auto 0 auto"
                    maxWidth="1000px"
                >
                    <Flex
                        flexDirection="column"
                        justifyContent="flex-start"
                        alignItems="flex-start"
                        maxWidth="1000px"
                        px={4}
                        minH="100vh"
                    >
                        <motion.div
                            initial={{ y: -20, opacity: 0 }}
                            animate={{ y: 0, opacity: 1 }}
                            transition={{ duration: .7, delay: .4 }}
                        >
                            <Heading letterSpacing="tight" as="h1" size="2xl" my={4}>
                                Blog ({posts.length} posts)
                            </Heading>
                            <Text mb={2}>I now write for <Link isExternal href="https://www.coffeeclass.io/articles" color="blue.500">coffeeclass.io</Link>. Visit that site to view all my tutorials!</Text>
                            <InputGroup mb={4} mr={4} w="100%">
                                <Input
                                    aria-label="Search by post title or summary"
                                    onChange={(e) => setSearchValue(e.target.value)}
                                    placeholder="Search by post title or summary"
                                />
                                <InputRightElement>
                                    <SearchIcon color="gray.300" />
                                </InputRightElement>
                            </InputGroup>
                            {!filteredBlogPosts.length && 'No posts found.'}
                            {filteredBlogPosts.map((frontMatter, index) => (
                                <BlogPost
                                    key={frontMatter.data.title}
                                    href={posts[index].filePath.replace(/\.mdx?$/, '')}
                                    {...frontMatter.data}
                                />
                            ))}
                        </motion.div>
                    </Flex>
                </Stack>
            </Container>
        </>
    )
}
Example #16
Source File: ToolPage.jsx    From awesome-tools with MIT License 5 votes vote down vote up
export default function ToolPage(props) {
  const type = types[props.types[0]];
  const slackMembers = useSlackMembers();

  return (
    <>
      <NextSeo
        title={`${props.title} — ${type.descriptor}`}
        description={`${props.title} examples, tutorials, compatibility, and popularity`}
      />

      <div className="container custom-container mt-lg">
        <main>
          <Header
            logo={props.logo}
            title={props.title}
            developer={props.developer}
            website={props?.links?.website}
            github={props?.slugs?.github}
            achievement={props?.feature_label}
          />
          <Description based={props.based_on} description={props.description} />
          <DescriptionCards
            licenses={props.licenses}
            frameworks={props.frameworks}
            languages={props.languages}
            links={props.links}
            slugs={props.slugs}
          />
          {props.gallery && props.gallery.length !== 0 && (
            <Gallery gallery={props.gallery} link={props?.links?.examples} />
          )}
          {props.github_data && (
            <Popularity
              slugs={props.slugs}
              github={props.github_data}
              positions={props.positions}
              percentages={props.percentages}
            />
          )}
          {props.integrations?.length > 0 && (
            <Integrations integrations={props.integrations} />
          )}
          {props.content && props.content.length > 0 && (
            <HowToGetStarted content={props.content} />
          )}
          <HowToGetHelp
            slackMembers={slackMembers}
            logo={props.logo}
            name={props.title}
            links={props.links}
            positions={props.positions}
            stackoverflow={
              props?.tags?.stackoverflow
                ? `https://stackoverflow.com/questions/tagged/${encodeURIComponent(
                  props?.tags?.stackoverflow.join(" or "),
                )}`
                : null
            }
            stackoverflow_data={props.stackoverflow_data}
          />
        </main>
      </div>
    </>
  );
}
Example #17
Source File: _app.js    From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal 5 votes vote down vote up
App = ({ Component, pageProps }) => {
  const router = useRouter()
  useEffect(() => {
    const handleRouteChange = (url) => {
      gtag.pageview(url)
    }
    router.events.on("routeChangeComplete", handleRouteChange)
    return () => {
      router.events.off("routeChangeComplete", handleRouteChange)
    }
  }, [router.events])
  return (
    <>
      <DefaultSeo {...SEO} />
      <NextSeo
        title="Remotebond - Remote jobs in Software Development, Sales and more"
        description="Looking for a remote job? Hire Remote! Remotebond has thousands of remote work jobs as a Developer, Designer, Customer Support Rep, Sales Professional, Marketing Professional, Project Manager and more!"
      />
      <Head>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
        <meta name="msapplication-config" content="/browserconfig.xml" />
        <meta name="theme-color" content="#ffffff" />
        <link
          rel="apple-touch-icon"
          sizes="180x180"
          href="/siteimg/apple-touch-icon.png"
        />
        <link
          rel="icon"
          type="image/png"
          sizes="32x32"
          href="/siteimg/favicon-32x32.png"
        />
        <link
          rel="icon"
          type="image/png"
          sizes="16x16"
          href="/siteimg/favicon-16x16.png"
        />
        <link rel="manifest" href="/site.webmanifest" />
        <link
          rel="mask-icon"
          href="/siteimg/safari-pinned-tab.svg"
          color="#3c99f7"
        />
        <link rel="shortcut icon" href="/siteimg/favicon.ico" />
        <meta name="msapplication-TileColor" content="#3c99f7" />
        <script
          type="application/ld+json"
          dangerouslySetInnerHTML={{
            __html: JSON.stringify({
              "@context": "http://schema.org",
              "@type": "Organization",
              name: "Remotebond",
              url: "https://remotebond.com",
              logo: "https://remotebond.com/siteimg/logo.png",
              sameAs: ["https://twitter.com/remotebond"],
            }),
          }}
        ></script>
      </Head>
      <SWRConfig
        value={{
          fetcher: fetch,
          onError: (err) => {
            console.error(err)
          },
        }}
      >
        <Layout user={pageProps.user}>
          <Component {...pageProps} />
          <NextNprogress color="#1c64f2" options={{ showSpinner: false }} />
        </Layout>
      </SWRConfig>
    </>
  )
}
Example #18
Source File: index.js    From NextJS-Boilerplate-withAtomicDesign with MIT License 5 votes vote down vote up
render(){
    const { children, title, description, url, images, showSidebar } = this.props;
    return(
    <Fragment>
      <DefaultSeo openGraph={appConfig.openGraph}/>
      <NextSeo 
        title={title}
        description={description}
        openGraph={{
          url,
          title,
          description,
          images
        }}
      />
      <SiteHeader />
        <MainSection>
          <div className="container">
              <div className="row">
                <div className={showSidebar ? 'main-content' : 'full-mainContent'}>{children}</div>
                {showSidebar && <SiteSidebar />}
              </div>
          </div>
        </MainSection>
      <SiteFooter />
      <style jsx global>
        {`
          * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
          }
          .row {
            display:flex;
            flex-wrap:wrap;
          }
          .container {
            width:1020px;
            margin: auto;
          }
          .section-container {
            padding: 40px 0;
          }
          .full-mainContent {
            width:100%;
            padding:14px;
          }
          .main-content {
            width:70%;
            padding:14px;
          }
        `}
      </style>
    </Fragment>
    )
  }
Example #19
Source File: seo.js    From stacker.news with MIT License 5 votes vote down vote up
// for a sub we need
// item seo
// index page seo
// recent page seo

export default function Seo ({ sub, item, user }) {
  const router = useRouter()
  const pathNoQuery = router.asPath.split('?')[0]
  const defaultTitle = pathNoQuery.slice(1)
  const snStr = `stacker news${sub ? ` ~${sub}` : ''}`
  let fullTitle = `${defaultTitle && `${defaultTitle} \\ `}stacker news`
  let desc = "It's like Hacker News but we pay you Bitcoin."
  if (item) {
    if (item.title) {
      fullTitle = `${item.title} \\ ${snStr}`
    } else if (item.root) {
      fullTitle = `reply on: ${item.root.title} \\ ${snStr}`
    }
    // at least for now subs (ie the only one is jobs) will always have text
    if (item.text) {
      desc = RemoveMarkdown(item.text)
      if (desc) {
        desc = desc.replace(/\s+/g, ' ')
      }
    } else {
      desc = `@${item.user.name} stacked ${item.sats} sats ${item.url ? `posting ${item.url}` : 'with this discussion'}`
    }
    if (item.ncomments) {
      desc += ` [${item.ncomments} comments`
      if (item.boost) {
        desc += `, ${item.boost} boost`
      }
      desc += ']'
    } else if (item.boost) {
      desc += ` [${item.boost} boost]`
    }
  }
  if (user) {
    desc = `@${user.name} has [${user.stacked} stacked, ${user.nitems} posts, ${user.ncomments} comments]`
  }

  return (
    <NextSeo
      title={fullTitle}
      description={desc}
      openGraph={{
        title: fullTitle,
        description: desc,
        images: [
          {
            url: 'https://stacker.news/api/capture' + pathNoQuery
          }
        ],
        site_name: 'Stacker News'
      }}
      twitter={{
        site: '@stacker_news',
        cardType: 'summary_large_image'
      }}
    />
  )
}
Example #20
Source File: ClubEvent.jsx    From club-connect with GNU General Public License v3.0 4 votes vote down vote up
ClubEvent = (props) => {
  const {
    id,
    internalName,
    title,
    banner,
    presenter,
    presenterImage,
    startDateTime,
    endDateTime,
    eventLocation,
    shortDescription,
    longDescription,
    externalLink,
    externalLinkButtonText,
  } = props.clubEventData;

  const calendarData = {
    title: title,
    description: `${shortDescription}\n\n${longDescription}\n\nMore Details: https://bccompsci.club/events/${id}/${internalName}\nJoin the Event: https://bccompsci.club/events/${id}/${internalName}/join`,
    startDatetime: dayjs(startDateTime).format('YYYYMMDDTHHmmss'),
    endDatetime: dayjs(endDateTime).format('YYYYMMDDTHHmmss'),
    duration: Math.abs(dayjs(startDateTime).diff(endDateTime, 'h')),
    eventLocation: `https://bccompsci.club/events/${id}/${internalName}/join`,
    timezone: 'America/New_York',
  };

  const shareData = {
    eventUrl: `https://bccompsci.club/events/${id}/${internalName}`,
    shareTitle: `Join me at ${title}!`,
    shareDescription: `Join me at ${title}, an event presented by ${presenter} and hosted by the Brooklyn College Computer Science Club! Register here:`,
  };

  const router = useRouter();

  const [shareModalIsOpen, setShareModalIsOpen] = useState(false);

  useEffect(async () => {
    const pathArray = router.asPath.split('/');

    // Redirect to meeting link if /join is after the event name
    if (pathArray[4] === 'join' && externalLink) {
      location.replace(externalLink);
      return;
    }

    // Set the event's internal name in the URL if the internal name doesn't match the one in the URL
    if (pathArray[3] !== internalName) {
      await router.push(`/events/${id}/${internalName}`);
      return;
    }

    modalCalendarData = calendarData; // Temporary solution until Redux is added
  }, []);

  const CalendarModal = AddToCalendarHOC(
    AddToCalendarButton,
    AddToCalendarModal
  );

  const toggleShareModal = () => {
    setShareModalIsOpen(!shareModalIsOpen);
  };

  const closeShareModal = () => {
    setShareModalIsOpen(false);
  };

  return (
    <>
      <NextSeo
        title={`${title} – ${SITE_NAME_BASE}`}
        description={
          shortDescription
            ? shortDescription
            : `${title} is an event hosted by the Brooklyn College Computer Science Club.`
        }
        openGraph={{
          site_name: SITE_NAME_BASE,
          title: title,
          description: shortDescription
            ? shortDescription
            : `${title} is an event hosted by the Brooklyn College Computer Science Club.`,
          images: [{ url: banner ? banner : defaultBanner }],
          type: 'events.event',
          url: `https://bccompsci.club/events/${id}/${internalName}`,
        }}
        twitter={{
          cardType: 'summary_large_image',
        }}
      />

      <section className={clubEventStyles.event}>
        <div className={clubEventStyles.bannerAndInformation}>
          <div className={clubEventStyles.bannerContainer}>
            <img
              className={clubEventStyles.clubEventBanner}
              src={banner ? banner : defaultBanner}
              alt={title}
            />
          </div>

          <div className={clubEventStyles.information}>
            <h1 className={clubEventStyles.title}>{title}</h1>
            <div className={clubEventStyles.presenter}>
              <img
                className={clubEventStyles.presenterImageContainer}
                src={presenterImage ? presenterImage : defaultPresenterImage}
                alt={presenter}
              />
              <p>
                Presented by
                <br />
                {presenter ? presenter : 'Unspecified'}
              </p>
            </div>
            <div className={clubEventStyles.time}>
              <img src={clockIcon} alt="Event time" />
              <p>
                {dayjs(startDateTime).format('MMMM D, YYYY')}
                <br />
                {dayjs(startDateTime).format('h:mm A')} -{' '}
                {dayjs(endDateTime).format('h:mm A')}
              </p>
            </div>
            <div className={clubEventStyles.location}>
              <img src={locationPinIcon} alt="Location" />
              <p>{eventLocation ? eventLocation : 'Unspecified'}</p>
            </div>
            <div className={clubEventStyles.link}>
              {externalLink ? (
                <a
                  href={externalLink}
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  {externalLinkButtonText
                    ? externalLinkButtonText
                    : 'More Details'}
                </a>
              ) : (
                <a
                  href="javascript:void(0)"
                  onClick={() =>
                    alert('Coming soon! Check back shortly for updates.')
                  }
                >
                  {externalLinkButtonText
                    ? externalLinkButtonText
                    : 'More Details'}
                </a>
              )}
            </div>
          </div>
        </div>
        <div className={clubEventStyles.descriptionsAndActions}>
          <div className={clubEventStyles.descriptions}>
            <p className={clubEventStyles.shortDescription}>
              {shortDescription}
            </p>
            <p className="event-long-description">{longDescription}</p>
          </div>
          <div className={clubEventStyles.actions}>
            <div className="event-add-to-calendar">
              <CalendarModal
                className="event-add-to-calendar-modal"
                event={calendarData}
                items={
                  isIosUserAgent
                    ? [SHARE_SITES.GOOGLE, SHARE_SITES.ICAL, SHARE_SITES.YAHOO]
                    : [
                        SHARE_SITES.GOOGLE,
                        SHARE_SITES.ICAL,
                        SHARE_SITES.YAHOO,
                        SHARE_SITES.OUTLOOK,
                      ]
                }
              />
            </div>

            <div className="event-share">
              <ShareButton
                toggleShareModal={toggleShareModal}
                shareData={shareData}
              />
              <ShareModal
                onRequestClose={closeShareModal}
                shareModalIsOpen={shareModalIsOpen}
                shareData={shareData}
              />
            </div>

            {getUserIsLoggedIn() && getUserData().role === 'Admin' && (
              <>
                <button onClick={() => router.push(`/events/edit?id=${id}`)}>
                  <EditRoundedIcon
                    style={{
                      color: '#4d5eff',
                    }}
                  />
                  <span>Edit Event</span>
                </button>

                <button
                  style={{ backgroundColor: '#ffcfcf' }}
                  onClick={async () => {
                    const confirmDeleteEvent = confirm(
                      'Are you sure you want to delete this event?'
                    );

                    if (confirmDeleteEvent) {
                      try {
                        await axios.delete(`${API_ROOT}/events/${id}`, {
                          withCredentials: true,
                        });
                      } catch (err) {
                        toastErrorCenter(
                          'An error occurred while deleting the event.'
                        );
                        console.error(err);
                        return;
                      }

                      toastSuccessCenter(
                        'The event has been successfully deleted.'
                      );
                      router.push('/events');
                    }
                  }}
                >
                  <DeleteForeverRoundedIcon style={{ color: '#ff4d4d' }} />
                  <span>Delete Event</span>
                </button>
              </>
            )}
          </div>
        </div>
      </section>
    </>
  );
}
Example #21
Source File: index.js    From benjamincarlson.io with MIT License 4 votes vote down vote up
export default function Index() {
  const { colorMode } = useColorMode()

  const colorSecondary = {
    light: 'gray.600',
    dark: 'gray.400'
  }

  const iconColor = {
    light: 'gray.600',
    dark: 'gray.300'
  }

  const linkColor = {
    light: 'blue.400',
    dark: 'blue.600'
  }

  return (
    <>
      <NextSeo
        title={title}
        description={description}
        canonical={url}
        openGraph={{
          url,
          title,
          description
        }}
      />
      <Container>
        <Flex
          flexDirection="column"
          maxWidth="1000px"
          alignSelf={[null, "center"]}
        >
          {/* hero is defined inside of components/Container.js which allows it to have a different bg color without applying p to a bunch of tags */}
          <motion.div
            initial={{ y: -20, opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            transition={{ duration: .7, delay: 2 }}
          >
            <Box as="section" mt={10} mb={20}>
              <Heading letterSpacing="tight" mt={8} size="lg" fontWeight={700} as="h2" mb={4}>About Me</Heading>
              <Text color={colorSecondary[colorMode]}>Hi everyone ?, I'm Benjamin Carlson. I go to <Link color="blue.500" href="https://www2.ccsu.edu/" isExternal>Central Connecticut State University</Link> where I study computer science and mathematics. My personal website is where I showcase my projects, writing, statistics, experience, and more. It also serves as a sandbox to play around with new technologies, as seen by the <Link href="https://github.com/bjcarlson42/benjamincarlson.io#overview" color={linkColor[colorMode]} isExternal>evolution</Link> of this website! Feel free to reach out via email or any social media.</Text>
            </Box>

            <Box as="section" mt={10} mb={20}>
              <Heading letterSpacing="tight" mt={8} size="lg" fontWeight={700} as="h2" mb={4}>Featured Projects ?‍?</Heading>
              <SimpleGrid minChildWidth="300px" spacing="40px">
                <ProjectCard
                  title="coffeeclass.io"
                  description="coffeeclass.io is a tutorial website I started to teach programming and computer science skills in a fun and easy to learn manner."
                  repoHref="https://github.com/carlson-technologies/coffeeclass.io"
                  demoHref="https://www.coffeeclass.io?utm_source=website&utm_campaign=benjamincarlson.io"
                  languageColor="#2b7489"
                  language="TypeScript"
                />
                <ProjectCard
                  title="benjamincarlson.io"
                  description="This website is a personal website I built to showcase my projects and experience."
                  repoHref="https://github.com/bjcarlson42/benjamincarlson.io"
                  demoHref="https://benjamincarlson.io"
                  languageColor="#f1e05a"
                  language="JavaScript"
                />
                <ProjectCard
                  title="Word Of The Day App"
                  description="A word of the day app built using Google's Flutter - a cross platform mobile app framework. View current and past words and save your favorites!"
                  repoHref="https://github.com/bjcarlson42/wotd"
                  youtubeId="https://youtu.be/17wMTF_bnnc"
                  languageColor="#00B4AB"
                  language="Dart"
                />
              </SimpleGrid>
            </Box>

            <Box as="section" mt={10} mb={20}>
              <Heading letterSpacing="tight" mt={8} mb={4} size="lg" fontWeight={700} as="h2">Publications ?</Heading>
              <Text color={colorSecondary[colorMode]}>I began writing about programming back in 2019 on my first blog that is no longer alive. Since then I have expanded to different media outlets and covered a variety of topics from programming, to productivity, to business.</Text>
              {/* <Flex align="center" mt={4}> */}
              <SimpleGrid minChildWidth="200px" spacing="20px" my={10}>
                <Flex flexDir="column">
                  <Icon as={YoutubeIcon} color="red.500" fontSize="2xl" mb={2} />
                  <Heading as="h3" size="md" fontWeight={400} mb={2} letterSpacing="tight">
                    <Link href='https://youtube.com/benjamincarlson' color={linkColor[colorMode]} isExternal>YouTube</Link>
                  </Heading>
                  <Text>I started uploading YouTube videos in 2020 when the pandemic started. I mostly upload programming tutorial videos but I also upload developer vlogs and informational videos. I have uploaded (almost) weekly since then and have grown my channel to an audience of over 4k subscribers and 450k views!</Text>
                </Flex>
                <Flex flexDir="column">
                  <Icon as={SiMedium} fontSize="2xl" mb={2} />
                  <Heading as="h3" size="md" fontWeight={400} mb={2} letterSpacing="tight">
                    <Link href='https://benjamincarlson.medium.com' color={linkColor[colorMode]} isExternal>Medium</Link>
                  </Heading>
                  <Text>Medium was the first publication I started. I wrote my <Link color="blue.500" href="https://levelup.gitconnected.com/using-javascript-to-scramble-a-rubiks-cube-306f52908f18" isExternal>first article</Link> in March 2020, and since then I have written about a dozen more articles. Nowadays I write less for Medium and more for coffeeclass.io.</Text>
                </Flex>
                <Flex flexDir="column">
                  <Icon as={FiCoffee} color="yellow.500" fontSize="2xl" mb={2} />
                  <Heading as="h3" size="md" fontWeight={400} mb={2} letterSpacing="tight">
                    <Link href='https://www.coffeeclass.io' color={linkColor[colorMode]} isExternal>coffeeclass.io</Link>
                  </Heading>
                  <Text>Because I enjoyed uploading YouTube videos about programming and writing about programming on Medium, I decided to start my own programming tutorial website, coffeeclass.io. If you are interested in writing about code, see our <Link color="blue.500" href="https://www.coffeeclass.io/contribute/getting-started" isExternal>getting started</Link> page.</Text>
                </Flex>
                <Flex flexDir="column">
                  <Icon as={BsGear} color="gray.500" fontSize="2xl" mb={2} />
                  <Heading as="h3" size="md" fontWeight={400} mb={2} letterSpacing="tight">
                    <Link href='https://www.engineering.coffeeclass.io' color={linkColor[colorMode]} isExternal>engineering.coffeeclass.io</Link>
                  </Heading>
                  <Text>The behind the scenes look at coffeeclass.io. On this site I write about the development of coffeeclass.io. Everything from the current tech stack, future plans, growing pains, and more.</Text>
                </Flex>
              </SimpleGrid>
              {/* </Flex> */}
              <Flex
                mb={4}
                bgColor={useColorModeValue("gray.100", "gray.900")}
                p={[5, 20, 50]}
                borderRadius={3}
                as="blockquote"
                borderLeft="10px solid"
                borderLeftColor={useColorModeValue("blue.400", "blue.700")}
              >
                <Icon as={GrBlockQuote} fontSize={40} color={colorSecondary[colorMode]} mr={4} />
                <Flex flexDir="column">
                  <Text fontSize="xl" fontStyle="italic" color={colorSecondary[colorMode]}>If You Can Think and Speak and Write, You Are Absolutely Deadly.</Text>
                  <Text fontSize="xl" fontWeight="bold" mt={2}>Jordan B. Peterson</Text>
                </Flex>
              </Flex>
            </Box>

            <Todo />
            <TechStack />

            <Box as="section">
              <Text mt={10}>Looks like you've made it to the end of this page... feel free to <Link href="https://youtube.com/benjamincarlson" isExternal color={linkColor[colorMode]}>check out my YouTube channel</Link> or
                visit <Link href="https://www.coffeeclass.io/?utm_source=website&utm_campaign=benjamincarlson.io" isExternal color={linkColor[colorMode]}>coffeeclass.io</Link> where
                you can find even more programming content.
              </Text>
            </Box>
          </motion.div>

        </Flex>
      </Container>
    </>
  )
}
Example #22
Source File: ListPage.jsx    From awesome-tools with MIT License 4 votes vote down vote up
export default function ListPage({
  tools,
  framework,
  title,
  showType = true,
  showCompatibleWith = true,
  showLicense = true,
}) {
  const router = useRouter();
  const query = router.query;
  const [ isFirstLoad, setLoad ] = useState(false);
  const [ exploreTools, setExploreTools ] = useState([]);
  const [ frameworks, setFrameworks ] = useState([]);
  const [ languages, setLanguages ] = useState([]);
  const [ licenses, setLicenses ] = useState([]);
  const [ renders, setRenders ] = useState([]);

  useEffect(() => {
    if (Object.keys(query).length && !isFirstLoad) {
      setParamsFromRouter(
        query,
        setExploreTools,
        setFrameworks,
        setLanguages,
        setLicenses,
        setRenders,
      );
      setLoad(true);
    }
  }, [ query ]);

  useEffect(() => {
    router.push(
      {
        scroll: false,
        query: {
          ...(framework && { framework }),
          tools: exploreTools,
          ...(!framework && { frameworks }),
          languages,
          licenses,
          renders
        },
      },
      undefined,
      { scroll: false },
    );
  }, [ framework, exploreTools, frameworks, languages, licenses, renders ]);

  const filteredTools = filter(
    tools,
    frameworks,
    languages,
    licenses,
    renders,
    exploreTools,
  );

  const setItem = (array, set, item) => {
    const index = array.indexOf(item);
    if (index === -1) {
      set([ ...array, item ]);
      // return true;
    } else {
      array.splice(index, 1);
      set([ ...array ]);
      // return false;
    }
  };

  return (
    <>
      <NextSeo
        title={`${title} — the awesome list`}
        description={`${title} for application developers: charting libraries, data grids, maps, etc.`}
      />

      <div className="container custom-container">
        <main>
          <H1>{title} <br className="xl-hidden" /> for application developers</H1>

          {showType && (
            <div className="row mb-md">
              {Object.values(allTypes).map(type => (
                <ExploreToolsCard
                  onClick={() => setItem(exploreTools, setExploreTools, type.slug)}
                  active={exploreTools.includes(type.slug) ? "active" : null}
                  text={type.name}
                  image={type.image}
                />
              ))}
            </div>
          )}

          {showCompatibleWith && (
            <div className="flex flex-wrap-row flex-items-center mb-sm">
              <AccentedText className="mr-xs">Compatible with</AccentedText>

              {Object.values(allFrameworks).map(framework => (
                <Chip
                  key={framework.slug}
                  className="mr-xs"
                  icon={framework.icon}
                  title={framework.name}
                  active={frameworks.includes(framework.slug) ? "active" : null}
                  onClick={() => setItem(frameworks, setFrameworks, framework.slug)}
                />
              ))}
            </div>
          )}

          <div className="flex flex-wrap-row flex-items-center mb-sm">
            <AccentedText className="mr-xs">With support for</AccentedText>

            <Chip
              icon="typescript.svg"
              title="TypeScript"
              active={languages.includes("typescript") ? "active" : null}
              onClick={() => setItem(languages, setLanguages, "typescript")} />
            {showLicense && (<AccentedText className="mr-xs ml-xs">and</AccentedText>)}
            {showLicense && (
              <>
                <Chip
                  className="mr-xs"
                  icon="open-source.svg"
                  title="open source"
                  active={licenses.includes("open-source") ? "active" : null}
                  onClick={() => setItem(licenses, setLicenses, "open-source")} />
                <Chip
                  icon="proprietary.svg"
                  title="proprietary"
                  active={licenses.includes("proprietary") ? "active" : null}
                  onClick={() => setItem(licenses, setLicenses, "proprietary")} />
                <AccentedText className="ml-xs">license</AccentedText>
              </>
            )}
          </div>
          <div className="flex flex-wrap-row flex-items-center">
            <AccentedText className="mr-xs">Rendering</AccentedText>

            <Chip
              title="Canvas"
              className="mr-xs"
              active={renders.includes("canvas") ? "active" : null}
              onClick={() => setItem(renders, setRenders, "canvas")} />
            <Chip
              title="SVG"
              className="mr-xs"
              active={renders.includes("svg") ? "active" : null}
              onClick={() => setItem(renders, setRenders, "svg")} />
            <Chip
              title="HTML"
              active={renders.includes("html") ? "active" : null}
              onClick={() => setItem(renders, setRenders, "html")} />
          </div>

          <div className="number-control-wrap">
            <ToolsNumberControl
              filteredTools={filteredTools}
              isChanged={
                exploreTools.length ||
                frameworks.length ||
                languages.length ||
                licenses.length ||
                renders.length
              }
              clearFilters={() => {
                clearFilters([
                  setExploreTools,
                  setFrameworks,
                  setLanguages,
                  setLicenses,
                  setRenders,
                ]);
              }}
            />
          </div>

          <div>
            <div className="row">
              {filteredTools &&
              filteredTools.map((tool) => (
                <div className="col-xl-6 mb-md" key={tool.id + Math.random()}>
                  {/* to lazy load on scroll need to set heigth */}
                  <ToolCard {...tool} />
                </div>
              ))}
            </div>
          </div>
        </main>
      </div>
    </>
  );
}
Example #23
Source File: [tag].js    From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal 4 votes vote down vote up
JobsPage = ({
  jobs,
  slug,
  initialData,
  initialAfter,
  firstPubDate,
  initialPubDate,
}) => {
  const router = useRouter()
  if (router.isFallback) {
    return (
      <div className="max-w-screen-xl mx-auto py-10 px-4 sm:px-6">
        <h1>Loading...</h1>
      </div>
    )
  }

  const [cursor, setCursor] = useState({
    key: initialAfter,
    date: firstPubDate,
    page: 0,
    before: null,
    isPrevClicked: false,
    isNextClicked: false,
  })
  const [isLoading, setIsLoading] = useState(false)
  const [firstRender, setFirstRender] = useState(true)

  const newJobs = () => {
    if (cursor.isPrevClicked) {
      return `/api/jobs/prev?key=${cursor.before}&d=${cursor.prevDate}&tag=${slug}`
    }

    if (!cursor.date && !cursor.isPrevClicked) {
      return `/api/jobs/next?tag=${slug}`
    } else {
      return `/api/jobs/next?key=${cursor.key}&d=${cursor.date}&tag=${slug}`
    }
  }

  const { data, mutate } = useSWR(!isLoading ? newJobs : null)

  const tagStr = slug.replace(/-/g, " ")
  let date = new Date()
  let dateOptions = {
    year: "numeric",
    month: "long",
  }
  const loadMoreJobs = () => {
    setCursor({
      key: data.after[2]
        ? data.after[2]["@ref"].id
        : data.after[1]
        ? data.after[1]["@ref"].id
        : null,
      prevDate: data.before[0], //data.data[0].data.pub_date,
      date: data.after[0], //data.data.slice(-1)[0].data.pub_date,
      page: cursor.page + 1,
      before:
        data && data.before && data.before[2]
          ? data.before[2]["@ref"].id
          : data.before[1]
          ? data.before[1]["@ref"].id
          : null,
      isPrevClicked: false,
      isNextClicked: true,
    })
    setIsLoading(true)
  }

  const loadPrevPage = () => {
    setCursor({
      key:
        data.after && data.after[2]
          ? data.after[2]["@ref"].id
          : data.after && data.after[1]
          ? data.after[1]["@ref"].id
          : null,
      prevDate: data.before[0], //data.data[0].data.pub_date,
      date: data.after ? data.after[0] : null, //data.data.slice(-1)[0].data.pub_date,
      page: cursor.page - 1,
      before:
        data.before && data.before[2]
          ? data.before[2]["@ref"].id
          : data.before[1]
          ? data.before[1]["@ref"].id
          : null,
      isPrevClicked: true,
      isNextClicked: false,
    })
  }

  // Fetch new jobs on state change
  useEffect(() => {
    if (firstRender) {
      setFirstRender(false)
    } else {
      mutate()
      setIsLoading(false)
    }
  }, [cursor])
  return (
    <>
      <NextSeo
        title={`Remote ${tagStr} jobs`}
        description={`The latest and most popular remote ${tagStr} jobs around the web. Jobs included from top remote companies. Find your new ${tagStr} career on Remotebond.`}
        canonical={`https://remotebond.com/remote-${slug}-jobs`}
        openGraph={{
          url: `https://remotebond.com/remote-${slug}-jobs`,
          title: `Remote ${tagStr} jobs`,
          description: `The latest and most popular remote ${tagStr} jobs around the web. Jobs included from top remote companies. Find your new ${tagStr} career on Remotebond.`,
        }}
      />
      <BreadcrumbJsonLd
        itemListElements={[
          {
            position: 1,
            name: "remotebond.com",
            item: "https://remotebond.com",
          },
          {
            position: 2,
            name: `Remote ${tagStr} jobs`,
          },
        ]}
      />
      <div className="relative overflow-hidden bg-black mb-12">
        <div className="max-w-screen-xl mx-auto text-center py-6 md:py-12 px-4 sm:px-6">
          <h1 className="text-white font-black text-2xl md:text-4xl my-4">
            Remote <span className="capitalize">{tagStr}</span> Jobs
          </h1>
          <h2 className="text-base md:text-xl text-rb-gray-4 w-3/4 mx-auto">
            Browse {initialData.length} remote {tagStr} jobs in{" "}
            {date.toLocaleDateString("en-EN", dateOptions)}
          </h2>
          <span className="inline-flex rounded-md shadow-sm mt-8">
            <Link href={`/hire-remotely`} as={`/hire-remotely`}>
              <a
                title="Hire remotely with Remotebond"
                className="inline-flex items-center px-6 py-3 border border-transparent text-base leading-6 font-bold rounded-md text-white bg-rb-green-6 hover:bg-rb-green-5 hover:text-white focus:outline-none focus:border-rb-green-7 focus:shadow-outline-blue active:bg-rb-green-7 transition ease-in-out duration-150"
              >
                Post a job for $25
              </a>
            </Link>
          </span>
        </div>
      </div>

      <div className="max-w-screen-xl w-full mx-auto py-10 px-4 sm:px-6">
        {cursor.page !== 0 && data && data.data && !isLoading ? (
          <JobsList
            slug={`remote-${slug}-jobs`}
            jobs={data.data}
            loadMoreJobs={loadMoreJobs}
            loadPrevPage={loadPrevPage}
            isLoadingJobs={isLoading}
            isPaginated
            hasPrevPage={cursor.before}
            hasMoreJobs={data.after}
          />
        ) : cursor.page !== 0 ? (
          <Loader />
        ) : null}

        {/* Weird hack to have pre-rendered content, useSWR is acting weird with initialData */}
        {cursor.page === 0 && initialData && (
          <JobsList
            slug={`remote-${slug}-jobs`}
            jobs={initialData.data}
            loadMoreJobs={loadMoreJobs}
            loadPrevPage={loadPrevPage}
            isLoadingJobs={isLoading}
            isPaginated
            hasPrevPage={null}
            hasMoreJobs={initialData.after}
          />
        )}
      </div>
    </>
  )
}