Merge pull request #783 from datopian/feature/website-v0.2.2
Website v0.2.2
This commit is contained in:
commit
ae833febdc
26
site/components/ButtonLink.tsx
Normal file
26
site/components/ButtonLink.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function ButtonLink({
|
||||
style = 'primary',
|
||||
className = '',
|
||||
href = '',
|
||||
children,
|
||||
}) {
|
||||
let styleClassName = '';
|
||||
|
||||
if (style == 'primary') {
|
||||
styleClassName = 'text-primary bg-blue-400 hover:bg-blue-300';
|
||||
} else if (style == 'secondary') {
|
||||
styleClassName =
|
||||
'text-secondary border !border-secondary hover:text-primary hover:bg-blue-300';
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={`inline-block h-12 px-6 py-3 border border-transparent text-base font-medium rounded-md focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-300/50 active:bg-sky-500 ${styleClassName} ${className}`}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
@ -4,6 +4,8 @@ import EmailIcon from './icons/EmailIcon';
|
||||
import GitHubIcon from './icons/GitHubIcon';
|
||||
|
||||
import { siteConfig } from '@/config/siteConfig';
|
||||
import { getContributorsCount, getRepoInfo } from '@/lib/getGitHubData';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const Stat = ({ title, value, ...props }) => {
|
||||
return (
|
||||
@ -29,6 +31,33 @@ const IconButton = ({ Icon, text, href, ...props }) => {
|
||||
};
|
||||
|
||||
export default function Community() {
|
||||
const [repoInfo, setRepoInfo] = useState<any>();
|
||||
const [contributorsCount, setContributorsCount] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
// This runs on client side and it's unlikely that users
|
||||
// will exceed the GitHub API usage limit, but added a
|
||||
// handling for that just in case.
|
||||
|
||||
getRepoInfo().then((res) => {
|
||||
if (res.success) {
|
||||
res.info.then((data) => setRepoInfo(data));
|
||||
} else {
|
||||
// If the request fail e.g API usage limit, use
|
||||
// a placeholder
|
||||
setRepoInfo({ stargazers_count: '+2k' });
|
||||
}
|
||||
});
|
||||
|
||||
getContributorsCount().then((res) => {
|
||||
if (res.success) {
|
||||
setContributorsCount(res.count);
|
||||
} else {
|
||||
setContributorsCount('+70');
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<h2 className="text-3xl font-bold text-primary dark:text-primary-dark ">
|
||||
@ -38,8 +67,12 @@ export default function Community() {
|
||||
We are growing. Get in touch or become a contributor!
|
||||
</p>
|
||||
<div className="flex justify-center mt-12">
|
||||
<Stat title="Stars on GitHub" value="+2k" className="mr-10" />
|
||||
<Stat title="Contributors" value="+70" />
|
||||
<Stat
|
||||
title="Stars on GitHub"
|
||||
value={repoInfo?.stargazers_count}
|
||||
className="mr-10"
|
||||
/>
|
||||
<Stat title="Contributors" value={contributorsCount} />
|
||||
</div>
|
||||
<div className="flex flex-wrap justify-center mt-12">
|
||||
<IconButton
|
||||
|
||||
@ -32,17 +32,30 @@ const items = [
|
||||
image: '/images/showcases/datahub.png',
|
||||
description: 'Demo Data Portal by DataHub',
|
||||
},
|
||||
{
|
||||
title: 'Example: Simple Data Catalog',
|
||||
href: 'https://example.portaljs.org/',
|
||||
image: '/images/showcases/example-simple-catalog.png',
|
||||
description: 'Simple data catalog',
|
||||
},
|
||||
{
|
||||
title: 'Example: Portal with CKAN',
|
||||
href: 'https://ckan-example.portaljs.org/',
|
||||
image: '/images/showcases/example-ckan.png',
|
||||
description: 'Simple portal with data coming from CKAN',
|
||||
},
|
||||
];
|
||||
|
||||
export default function Gallery() {
|
||||
return (
|
||||
<Container>
|
||||
<h2 className="text-3xl font-bold text-primary dark:text-primary-dark ">
|
||||
<h2
|
||||
className="text-3xl font-bold text-primary dark:text-primary-dark"
|
||||
id="gallery"
|
||||
>
|
||||
Gallery
|
||||
</h2>
|
||||
<p className="text-lg mt-8 ">
|
||||
Discover what's being powered by Portal.JS
|
||||
</p>
|
||||
<p className="text-lg mt-8">Discover what's being powered by Portal.JS</p>
|
||||
<div className="not-prose my-12 grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
{items.map((item) => {
|
||||
return <GalleryItem item={item} />;
|
||||
|
||||
@ -9,7 +9,7 @@ export default function GalleryItem({ item }) {
|
||||
className="bg-cover bg-no-repeat bg-top aspect-video w-full group-hover:blur-sm group-hover:scale-105 transition-all duration-200"
|
||||
style={{ backgroundImage: `url(${item.image})` }}
|
||||
>
|
||||
<div className="w-full h-full group-hover:backdrop-brightness-50 transition-all duration-200"></div>
|
||||
<div className="w-full h-full bg-black opacity-0 group-hover:opacity-50 transition-all duration-200"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="opacity-0 group-hover:opacity-100 absolute top-0 bottom-0 right-0 left-0 transition-all duration-200 px-2 flex items-center justify-center">
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import clsx from 'clsx';
|
||||
import Highlight, { defaultProps } from 'prism-react-renderer';
|
||||
import { Fragment, useRef } from 'react';
|
||||
import ButtonLink from './ButtonLink';
|
||||
import NewsletterForm from './NewsletterForm';
|
||||
|
||||
const codeLanguage = 'javascript';
|
||||
@ -32,7 +33,10 @@ export function Hero() {
|
||||
const el = useRef(null);
|
||||
|
||||
return (
|
||||
<div className="overflow-hidden -mb-32 mt-[-4.5rem] pb-32 pt-[4.5rem] lg:mt-[-4.75rem] lg:pt-[4.75rem]" id="hero">
|
||||
<div
|
||||
className="overflow-hidden -mb-32 mt-[-4.5rem] pb-32 pt-[4.5rem] lg:mt-[-4.75rem] lg:pt-[4.75rem]"
|
||||
id="hero"
|
||||
>
|
||||
<div className="py-16 sm:px-2 lg:relative lg:py-20 lg:px-0">
|
||||
{/* Commented code on line 37, 39 and 113 will reenable the two columns hero */}
|
||||
{/* <div className="mx-auto grid max-w-2xl grid-cols-1 items-center gap-y-16 gap-x-8 px-4 lg:max-w-8xl lg:grid-cols-2 lg:px-8 xl:gap-x-16 xl:px-12"> */}
|
||||
@ -50,7 +54,18 @@ export function Hero() {
|
||||
present a single dataset or build a full-scale data
|
||||
catalog/portal.
|
||||
</p>
|
||||
<NewsletterForm />
|
||||
|
||||
<ButtonLink className="mt-8" href="/docs">
|
||||
Get Started
|
||||
</ButtonLink>
|
||||
|
||||
<ButtonLink className="ml-3" href="#gallery" style="secondary">
|
||||
Gallery
|
||||
</ButtonLink>
|
||||
|
||||
<div className="md:max-w-md mx-auto">
|
||||
<NewsletterForm />
|
||||
</div>
|
||||
<p className="my-10 text-l tracking-wide">
|
||||
<span>A project of</span>
|
||||
<a
|
||||
|
||||
@ -51,7 +51,7 @@ export default function NewsletterForm() {
|
||||
>
|
||||
<path d="M460.116 373.846l-20.823-12.022c-5.541-3.199-7.54-10.159-4.663-15.874 30.137-59.886 28.343-131.652-5.386-189.946-33.641-58.394-94.896-95.833-161.827-99.676C261.028 55.961 256 50.751 256 44.352V20.309c0-6.904 5.808-12.337 12.703-11.982 83.556 4.306 160.163 50.864 202.11 123.677 42.063 72.696 44.079 162.316 6.031 236.832-3.14 6.148-10.75 8.461-16.728 5.01z" />
|
||||
</svg>
|
||||
Notify me
|
||||
Notify Me
|
||||
</button>
|
||||
<input
|
||||
type="text"
|
||||
|
||||
27
site/lib/getGitHubData.ts
Normal file
27
site/lib/getGitHubData.ts
Normal file
@ -0,0 +1,27 @@
|
||||
export function getRepoInfo() {
|
||||
return fetch('https://api.github.com/repositories/2579069').then((res) => {
|
||||
if (res.status < 400) {
|
||||
return { success: true, info: res.json() };
|
||||
} else {
|
||||
return { success: false, info: null };
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function getContributorsCount() {
|
||||
// Based on https://stackoverflow.com/questions/44347339/github-api-how-efficiently-get-the-total-contributors-amount-per-repository
|
||||
return fetch(
|
||||
'https://api.github.com/repos/datopian/portaljs/contributors?per_page=1&anon=false'
|
||||
).then((res) => {
|
||||
if (res.status < 400) {
|
||||
const pattern = /&page=(\d+)>; rel="last"/;
|
||||
const linkHeader = res.headers.get('link');
|
||||
|
||||
const count = pattern.exec(linkHeader)[1];
|
||||
|
||||
return { success: true, count: count };
|
||||
} else {
|
||||
return { success: false, count: null };
|
||||
}
|
||||
});
|
||||
}
|
||||
BIN
site/public/images/showcases/example-ckan.png
Normal file
BIN
site/public/images/showcases/example-ckan.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 165 KiB |
BIN
site/public/images/showcases/example-simple-catalog.png
Normal file
BIN
site/public/images/showcases/example-simple-catalog.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
Loading…
x
Reference in New Issue
Block a user