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: index.js From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal | 6 votes |
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 #2
Source File: _app.jsx From neighbor-express with MIT License | 6 votes |
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 #3
Source File: seo.js From strapi-starter-next-corporate with MIT License | 6 votes |
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 #4
Source File: seo.js From stacker.news with MIT License | 6 votes |
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 #5
Source File: seo.jsx From docs with MIT License | 6 votes |
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 #6
Source File: Header.jsx From ui with MIT License | 6 votes |
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 #7
Source File: Seo.js From mailmask with GNU Affero General Public License v3.0 | 6 votes |
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 #8
Source File: BlogSeo.js From benjamincarlson.io with MIT License | 6 votes |
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 #9
Source File: index.jsx From club-connect with GNU General Public License v3.0 | 6 votes |
Join = () => {
const [memberJoined, setMemberJoined] = useState(false);
return (
<>
<Head>
<title>{pageTitle}</title>
</Head>
<NextSeo
title={pageTitle}
openGraph={{
title: pageTitle,
url: 'https://bccompsci.club/join',
}}
/>
{!memberJoined ? (
<JoinForm setMemberJoined={setMemberJoined} />
) : (
<JoinSuccess />
)}
</>
);
}
Example #10
Source File: SEO.js From tambouille with MIT License | 6 votes |
PageSeo = ({ description, url, title = null }) => {
return (
<NextSeo
title={title ? `${title} | ${siteMetadata.title}` : siteMetadata.title}
description={description}
canonical={url}
openGraph={{
url,
title,
description,
}}
/>
)
}
Example #11
Source File: global.jsx From NextBook with MIT License | 6 votes |
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 #12
Source File: about.jsx From club-connect with GNU General Public License v3.0 | 6 votes |
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 #13
Source File: SEO.js From tambouille with MIT License | 5 votes |
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: seo.js From stacker.news with MIT License | 5 votes |
// 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 #15
Source File: index.js From NextJS-Boilerplate-withAtomicDesign with MIT License | 5 votes |
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 #16
Source File: resetpassword.jsx From club-connect with GNU General Public License v3.0 | 5 votes |
ResetPassword = () => {
const [resetEmailSent, setResetEmailSent] = useState(false);
const [passwordResetKey, setPasswordResetKey] = useState(null);
useEffect(() => {
const parsedQueryString = queryString.parse(location.search);
if (parsedQueryString.key) {
setPasswordResetKey(parsedQueryString.key);
}
}, []);
return (
<>
<Head>
<title>{pageTitle}</title>
</Head>
<NextSeo
title={pageTitle}
openGraph={{
title: pageTitle,
url: 'https://bccompsci.club/resetpassword',
}}
/>
<div>
<section className={`${authStyles.auth} ${authStyles.authBackground}`}>
<div className={authStyles.flexContainer}>
<div className={authStyles.container}>
<h1>Reset Password</h1>
{passwordResetKey ? (
<CompleteResetPasswordForm
passwordResetKey={passwordResetKey}
/>
) : (
<>
{resetEmailSent ? (
<ResetEmailSent />
) : (
<RequestPasswordResetForm
setResetEmailSent={setResetEmailSent}
/>
)}
</>
)}
</div>
</div>
</section>
</div>
</>
);
}
Example #17
Source File: index.js From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal | 5 votes |
IndexPage = (props) => {
// Jobs Data
const categories = props.categories.data
const softwareDevJobs = props.softwareDevJobs.data
const customerSupportJobs = props.customerSupportJobs.data
const salesMarketingJobs = props.salesMarketingJobs.data
const designJobs = props.designJobs.data
const nonTechJobs = props.nonTechJobs.data
// Forum threads data
const forumTopics = props.forumTopics.data
return (
<>
<NextSeo canonical={`https://remotebond.com`} />
{/* Hero Section */}
<Hero />
{/* Forum topics scoller */}
<TopicsScroller topics={forumTopics} />
{/* Filters */}
<FilterBar categories={categories} />
{/* Posting group */}
<JobsList
title="Software Development"
slug="/remote-dev-jobs"
jobs={softwareDevJobs}
/>
<MailchimpSubscribe
url={_URL}
render={({ subscribe, status, message }) => (
<SubscribeEmailForm
status={status}
message={message}
onValidated={(formData) => subscribe(formData)}
/>
)}
/>
<JobsList
title="Customer Support"
slug="/remote-customer-support-jobs"
jobs={customerSupportJobs}
/>
<JobsList
title="Sales & Marketing"
slug="/remote-sales-marketing-jobs"
jobs={salesMarketingJobs}
/>
<JobsList title="Design" slug="/remote-design-jobs" jobs={designJobs} />
<JobsList
title="Non Tech"
slug="/remote-non-tech-jobs"
jobs={nonTechJobs}
/>
</>
)
}
Example #18
Source File: Layout.js From Modtoberfest-Site with MIT License | 5 votes |
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 #19
Source File: _app.js From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal | 5 votes |
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 #20
Source File: resources.jsx From club-connect with GNU General Public License v3.0 | 5 votes |
Resources = () => {
return (
<>
<Head>
<title>{pageTitle}</title>
</Head>
<NextSeo
title={pageTitle}
openGraph={{
title: pageTitle,
url: 'https://bccompsci.club/resources',
}}
/>
<div
className={`${commonStyles.container} ${commonStyles.text} ${resourcesStyles.resources}`}
>
<h1 className={commonStyles.centerElement}>Resources</h1>
<LearnResources />
<br />
<h1 className={commonStyles.centerElement}>Useful Tools</h1>
<ToolsResources />
<Alert variant="primary" className={resourcesStyles.contribute}>
<Alert.Heading>Contribute to this list!</Alert.Heading>
<p>
Have any resources you want to share with us? Post them in our
Discord community under the <code>#resources</code> channel or
<Alert.Link
href="https://github.com/bc-compsci-club/bccompsci.club"
rel="noopener noreferrer"
target="_blank"
>
submit a pull request here
</Alert.Link>
!
</p>
</Alert>
</div>
</>
);
}
Example #21
Source File: ToolPageForFramework.jsx From awesome-tools with MIT License | 5 votes |
export default function ToolPageForFramework(props) {
const type = types[props.types[0]];
const framework = frameworks[props.framework];
const integration = props.integrations?.find(i => i.framework === props.framework);
const slackMembers = useSlackMembers();
return (
<>
<NextSeo
title={`${props.title} — ${type.descriptor} for ${framework.name} developers`}
description={`${props.title} support in ${framework.name}${integration && ` with ${integration.slugs.npm}`}, examples, tutorials, compatibility, and popularity`}
/>
<div className="container custom-container mt-lg">
<main>
<Header
logo={props.logo}
title={props.title}
framework={framework.name}
developer={props.developer}
website={props?.links?.website}
github={props?.slugs?.github}
achievement={props?.feature_label}
/>
<Description description={props.description} />
<DescriptionCards
licenses={props.licenses}
frameworks={props.frameworks}
languages={props.languages}
links={props.links}
slugs={props.slugs}
/>
{integration && (
<Integrations integration={integration} />
)}
{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.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 #22
Source File: blog.js From benjamincarlson.io with MIT License | 5 votes |
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 #23
Source File: ToolPage.jsx From awesome-tools with MIT License | 5 votes |
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 #24
Source File: projects.js From benjamincarlson.io with MIT License | 5 votes |
Projects = () => {
const { colorMode } = useColorMode()
const colorSecondary = {
light: 'gray.600',
dark: 'gray.400'
}
const iconColor = {
light: 'gray.600',
dark: 'gray.300'
}
return (
<>
<NextSeo
title={title}
description={description}
canonical={url}
openGraph={{
url,
title,
description
}}
/>
<Container>
<Flex
flexDirection="column"
maxWidth="1000px"
alignSelf={[null, "center"]}
>
<motion.div
initial={{ y: -20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: .7, delay: .4 }}
>
<Heading letterSpacing="tight" my={4} as="h1" size="2xl">
Projects
</Heading>
<Text color={colorSecondary[colorMode]}>Between school, work, youtube, and individual curiosity, I have worked on many projects over the years. If you enjoy or use any of these projects, please consider <Link href="https://github.com/sponsors/bjcarlson42" isExternal color="blue.500">sponsoring me</Link> on GitHub!
</Text>
<GitHubSponsorCard />
<ProjectListFull />
</motion.div>
</Flex>
</Container>
</>
)
}
Example #25
Source File: index.js From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal | 4 votes |
JobsPage = ({ job, slug }) => {
const salarayAmount = randomInt(40000, 80000)
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>
)
}
let newDate = new Date(job.pub_date)
newDate.setMonth(newDate.getMonth() + 1)
const jobExpireDate = new Date(newDate).toISOString()
const saniztizedAndStripped = sanitizeHtml(strip_tags(job.description))
const isEmail = validateEmail(job.apply_url)
return (
<>
<NextSeo
title={`Remote ${job.title} job at ${job.company_name}`}
description={`${saniztizedAndStripped.substr(0, 140)}...`}
canonical={`https://remotebond.com/remote-jobs/${slug}`}
openGraph={{
url: `https://remotebond.com/remote-jobs/${slug}`,
title: `Remote ${job.title} job at ${job.company_name}`,
description: `${saniztizedAndStripped.substr(0, 140)}...`,
}}
/>
<BreadcrumbJsonLd
itemListElements={[
{
position: 1,
name: "remotebond.com",
item: "https://remotebond.com",
},
{
position: 2,
name: "Remote Jobs",
item: "https://remotebond.com/remote-jobs",
},
{
position: 3,
name: `Remote ${job.title} job at ${job.company_name}`,
},
]}
/>
<JobPostingJsonLd
datePosted={job.pub_date}
description={strip_tags(job.description)}
hiringOrganization={{
name: job.company_name,
sameAs: null,
}}
jobLocation={{
streetAddress: "Anywhere",
addressLocality: "Anywhere",
addressRegion: "Anywhere",
postalCode: "Anywhere",
addressCountry: "Anywhere",
}}
title={job.title}
baseSalary={{
currency: "USD",
value: salarayAmount,
unitText: "YEAR",
}}
employmentType="FULL_TIME"
jobLocationType="TELECOMMUTE"
validThrough={jobExpireDate}
/>
<JobHeader
title={job.title}
company={job.company_name}
applyUrl={job.apply_url}
location={job.location}
isEmail={isEmail}
/>
<Breadcrumbs jobTitle={job.title} category={job.primary_category} />
<div className="max-w-screen-xl mx-auto py-10 px-4 sm:px-6">
<div className="w-full md:w-3/4">
<div
className="prose prose-sm sm:prose lg:prose-lg xl:prose-xl jobDescription__container py-6"
dangerouslySetInnerHTML={{ __html: job.description }}
></div>
<div className="flex justify-center mb-8">
<span className="inline-flex rounded-md shadow-sm">
{!isEmail ? (
<a
href={`${job.apply_url}?utm_source=remotebond.com&ref=remotebond.com`}
target="_blank"
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"
>
Apply for this job
</a>
) : (
<a
href={`mailto:${job.apply_url}?subject=Application for ${job.title} via Remotebond`}
target="_blank"
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"
>
Apply for this job
</a>
)}
</span>
</div>
{/* Notification */}
<div className="rounded-md bg-blue-50 p-4">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-blue-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3">
<p className="text-xs leading-5 text-blue-700">
Keep in mind you never have to pay to apply. Never pay for
equipment or training. The basic rule is; NEVER pay for
anything when applying. When talking to the job poster, make
sure you're talking to someone from the actual company. By
clicking the apply button you will leave Remotebond to the
external application website.
</p>
<br />
<p className="text-xs leading-5 text-blue-700">
Remotebond accepts no liability or responsibility as a
consequence of any reliance upon information on there
(external sites) or here.
</p>
</div>
</div>
</div>
</div>
</div>
</>
)
}
Example #26
Source File: login.jsx From club-connect with GNU General Public License v3.0 | 4 votes |
LogIn = () => {
const router = useRouter();
const dispatch = useDispatch();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [formSubmitting, setFormSubmitting] = useState(false);
useEffect(async () => {
// Redirect to dashboard if logged in already
if (getUserIsLoggedIn()) {
await router.push('/dashboard');
}
}, []);
const handleSubmit = async (e) => {
e.preventDefault();
setFormSubmitting(true);
// Log the user in and retrieve JWT
const authenticationCredentials = {
email: email,
password: password,
};
try {
await axios.post(
`${API_ROOT}/accounts/login`,
authenticationCredentials,
{
withCredentials: true,
}
);
} catch (err) {
// err.response might be undefined
const errStatus = err.response && err.response.status;
if (errStatus === 401) {
toastErrorCenter(
'Your email or password is incorrect. Please check your credentials and try again.'
);
} else if (errStatus === 429) {
toastErrorCenter(
'You have entered an incorrect email or password too many times. Please try again in an hour.'
);
} else {
toastErrorCenter(
'An error occurred while trying to log you in. Please try again.'
);
}
setFormSubmitting(false);
console.error(err);
return;
}
// Set application state and localStorage to be logged in
await setLoggedIn(dispatch);
setFormSubmitting(false);
// Redirect to the appropriate page
const parsedQueryString = queryString.parse(location.search);
if (parsedQueryString.returnToPage) {
router.push(parsedQueryString.returnToPage);
} else {
router.push('/dashboard');
}
};
return (
<>
<Head>
<title>{pageTitle}</title>
</Head>
<NextSeo
title={pageTitle}
openGraph={{
title: pageTitle,
url: 'https://bccompsci.club/login',
}}
/>
<div>
<section className={`${authStyles.auth} ${authStyles.authBackground}`}>
<div className={authStyles.flexContainer}>
<div className={authStyles.container}>
<h1>Member Log In</h1>
<form name="join" id="join-form" onSubmit={handleSubmit}>
<div className={authStyles.fullWidthField}>
<label htmlFor="email">Email Address</label>
<input
type="email"
name="email"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
disabled={formSubmitting}
required
/>
</div>
<div className={authStyles.fullWidthField}>
<label htmlFor="password">Password</label>
<input
type="password"
name="password"
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
disabled={formSubmitting}
required
/>
</div>
<div className={loginFormStyles.resetPassword}>
<Link href="/resetpassword">Forgot password?</Link>
</div>
<Button
classNamePassed={formStyles.cardSubmitButton}
type="submit"
disabled={formSubmitting}
big
>
Log In
</Button>
</form>
<div className={authStyles.alternateAction}>
<p>
<strong>
Not a member yet? <Link href="/join">Join Now.</Link>
</strong>
</p>
</div>
</div>
</div>
</section>
</div>
</>
);
}
Example #27
Source File: index.js From benjamincarlson.io with MIT License | 4 votes |
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 #28
Source File: [username].js From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal | 4 votes |
UserProfilePage = ({ user }) => {
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>
)
}
return (
<>
<NextSeo
title={`Remote worker ${user.username} on Remotebond`}
description={`View the remote worker profile of ${user.username} on Remotebond`}
canonical={`https://remotebond.com/u/${user.username}`}
openGraph={{
url: `https://remotebond.com/u/${user.username}`,
title: `Remote worker ${user.username} on Remotebond`,
description: `View the remote worker profile of ${user.username} on Remotebond`,
}}
/>
<div className="flex flex-col flex-1">
<div className="relative overflow-hidden bg-black">
<div className="max-w-screen-xl mx-auto py-12 px-4 sm:px-6 lg:py-16 lg:px-8">
<div></div>
</div>
</div>
<div className="flex flex-1 justify-center bg-gray-50 px-4 sm:px-6 lg:px-8">
<div className="max-w-screen-xl mx-auto w-full -my-14 relative z-10 mb-14">
<div className="flex flex-col items-center justify-center mb-6">
{user.profile_image ? (
<img
className="inline-block h-28 w-28 rounded-md mb-2 shadow-md border-white border-2"
src={`${user.profile_image}`}
alt=""
/>
) : (
<div className="inline-block h-28 w-28 rounded-md mb-2 shadow-md border-white border-2 bg-rb-gray-9 text-rb-gray-5">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"
clip-rule="evenodd"
/>
</svg>
</div>
)}
<div className="max-w-screen-lg text-rb-gray-8 text-center">
<h1 className="font-medium text-xl">{`@${user.username}`}</h1>
<p className="">
{user.tagline ? user.tagline : "Hello, I'm using Remotebond!"}
</p>
</div>
</div>
<div className="w-full sm:w-full">
<div className="bg-white shadow overflow-hidden sm:rounded-lg">
<div className="px-4 py-5 border-b border-gray-200 sm:px-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
General Information
</h3>
<p className="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
Personal details and links.
</p>
</div>
<div>
<dl>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
Full name
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{`${user.first_name && user.first_name} ${
user.last_name && user.last_name
}`}
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
Skillset
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<ul className="flex flex-wrap">
{user.tags.length &&
user.tags.map((tag, idx) => {
return (
<li key={idx} className="mr-3 my-1">
<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium leading-4 bg-blue-100 text-blue-800">
{tag}
</span>
</li>
)
})}
</ul>
</dd>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
Email address
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{/* {`${user.email}`} */}
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
Salary expectation
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{user.salary_indication ? salary.indication : ""}
</dd>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
About
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{user.about ? user.about : ""}
</dd>
</div>
</dl>
</div>
</div>
</div>
</div>
</div>
</div>
</>
)
}
Example #29
Source File: ListPage.jsx From awesome-tools with MIT License | 4 votes |
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>
</>
);
}