[monorepo][lg] - start of monorepo
This commit is contained in:
@@ -1,61 +0,0 @@
|
||||
const Footer: React.FC = () => {
|
||||
const navigation = {
|
||||
main: [
|
||||
{ name: 'Blog', href: '/blog' },
|
||||
{ name: 'Search', href: '/search' },
|
||||
{ name: 'Docs', href: '/docs' },
|
||||
],
|
||||
social: [
|
||||
{
|
||||
name: 'GitHub',
|
||||
href: 'https://github.com/datopian/portal.js',
|
||||
// eslint-disable-next-line
|
||||
icon: (props) => (
|
||||
<svg fill="currentColor" viewBox="0 0 24 24" {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return (
|
||||
<footer className="bg-white">
|
||||
<div className="max-w-7xl mx-auto py-12 px-4 overflow-hidden sm:px-6 lg:px-8">
|
||||
<nav
|
||||
className="-mx-5 -my-2 flex flex-wrap justify-center"
|
||||
aria-label="Footer"
|
||||
>
|
||||
{navigation.main.map((item) => (
|
||||
<div key={item.name} className="px-5 py-2">
|
||||
<a
|
||||
href={item.href}
|
||||
className="text-base text-gray-500 hover:text-gray-900"
|
||||
>
|
||||
{item.name}
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</nav>
|
||||
<div className="mt-8 flex justify-center space-x-6">
|
||||
{navigation.social.map((item) => (
|
||||
<a
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
className="text-gray-400 hover:text-gray-500"
|
||||
>
|
||||
<span className="sr-only">{item.name}</span>
|
||||
<item.icon className="h-6 w-6" aria-hidden="true" />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
@@ -1,7 +0,0 @@
|
||||
import Template from './HeroTemplate';
|
||||
|
||||
const Hero: React.FC = () => {
|
||||
return <Template />;
|
||||
};
|
||||
|
||||
export default Hero;
|
||||
@@ -1,130 +0,0 @@
|
||||
import useTranslation from 'next-translate/useTranslation';
|
||||
import SearchForm from '../search/Form';
|
||||
|
||||
export default function Example() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="relative bg-white overflow-hidden">
|
||||
<div
|
||||
className="hidden lg:block lg:absolute lg:inset-0"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<svg
|
||||
className="absolute top-0 left-1/2 transform translate-x-64 -translate-y-8"
|
||||
width={640}
|
||||
height={784}
|
||||
fill="none"
|
||||
viewBox="0 0 640 784"
|
||||
>
|
||||
<defs>
|
||||
<pattern
|
||||
id="9ebea6f4-a1f5-4d96-8c4e-4c2abf658047"
|
||||
x={118}
|
||||
y={0}
|
||||
width={20}
|
||||
height={20}
|
||||
patternUnits="userSpaceOnUse"
|
||||
>
|
||||
<rect
|
||||
x={0}
|
||||
y={0}
|
||||
width={4}
|
||||
height={4}
|
||||
className="text-gray-200"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect
|
||||
y={72}
|
||||
width={640}
|
||||
height={640}
|
||||
className="text-gray-50"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<rect
|
||||
x={118}
|
||||
width={404}
|
||||
height={784}
|
||||
fill="url(#9ebea6f4-a1f5-4d96-8c4e-4c2abf658047)"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div className="relative pt-6 pb-16 sm:pb-24 lg:pb-32">
|
||||
<main className="mt-16 mx-auto max-w-7xl px-4 sm:mt-24 sm:px-6 lg:mt-32">
|
||||
<div className="lg:grid lg:grid-cols-12 lg:gap-8">
|
||||
<div className="sm:text-center md:max-w-2xl md:mx-auto lg:col-span-6 lg:text-left">
|
||||
<h1>
|
||||
<span className="block text-sm font-semibold uppercase tracking-wide text-gray-500 sm:text-base lg:text-sm xl:text-base">
|
||||
Quality Data ready to Integrate
|
||||
</span>
|
||||
<span className="mt-1 block text-4xl tracking-tight font-extrabold sm:text-5xl xl:text-6xl">
|
||||
<span className="block text-gray-900">Find and Share</span>
|
||||
<span className="block text-indigo-600">Quality Data</span>
|
||||
</span>
|
||||
</h1>
|
||||
<p className="mt-3 text-base text-gray-500 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
|
||||
{t(`common:description`)}
|
||||
</p>
|
||||
<div className="mt-8 sm:max-w-lg sm:mx-auto sm:text-center lg:text-left lg:mx-0">
|
||||
<SearchForm />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-12 relative sm:max-w-lg sm:mx-auto lg:mt-0 lg:max-w-none lg:mx-0 lg:col-span-6 lg:flex lg:items-center">
|
||||
<svg
|
||||
className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-8 scale-75 origin-top sm:scale-100 lg:hidden"
|
||||
width={640}
|
||||
height={784}
|
||||
fill="none"
|
||||
viewBox="0 0 640 784"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<defs>
|
||||
<pattern
|
||||
id="4f4f415c-a0e9-44c2-9601-6ded5a34a13e"
|
||||
x={118}
|
||||
y={0}
|
||||
width={20}
|
||||
height={20}
|
||||
patternUnits="userSpaceOnUse"
|
||||
>
|
||||
<rect
|
||||
x={0}
|
||||
y={0}
|
||||
width={4}
|
||||
height={4}
|
||||
className="text-gray-200"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect
|
||||
y={72}
|
||||
width={640}
|
||||
height={640}
|
||||
className="text-gray-50"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<rect
|
||||
x={118}
|
||||
width={404}
|
||||
height={784}
|
||||
fill="url(#4f4f415c-a0e9-44c2-9601-6ded5a34a13e)"
|
||||
/>
|
||||
</svg>
|
||||
<div className="relative mx-auto w-full rounded-lg shadow-lg lg:max-w-md">
|
||||
<img
|
||||
className="w-full"
|
||||
src="/images/banner.svg"
|
||||
alt="banner_img"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import Template from './NavTemplate';
|
||||
|
||||
const NavBar: React.FC = () => {
|
||||
const navMenu = [
|
||||
{ title: 'Blog', path: '/blog' },
|
||||
{ title: 'Search', path: '/search' },
|
||||
{ title: 'Docs', path: 'http://tech.datopian.com/frontend/' },
|
||||
{ title: 'GitHub', path: 'https://github.com/datopian/portal.js' },
|
||||
];
|
||||
|
||||
return <Template menu={navMenu} logo={'/images/logo.svg'} />;
|
||||
};
|
||||
|
||||
export default NavBar;
|
||||
@@ -1,118 +0,0 @@
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Disclosure } from '@headlessui/react';
|
||||
import { SearchIcon } from '@heroicons/react/solid';
|
||||
import { MenuIcon, XIcon } from '@heroicons/react/outline';
|
||||
|
||||
const NavBar: React.FC<{ menu: any; logo: string }> = ({ menu, logo }) => {
|
||||
const router = useRouter();
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
router.push({
|
||||
pathname: '/search',
|
||||
query: { q: searchQuery },
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Disclosure as="nav" className="bg-white shadow">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<div className="max-w-7xl mx-auto px-2 sm:px-4 lg:px-8">
|
||||
<div className="flex justify-between h-16">
|
||||
<div className="flex px-2 lg:px-0">
|
||||
<div className="flex-shrink-0 flex items-center">
|
||||
<a href="/">
|
||||
<img
|
||||
className="block lg:hidden h-8 w-auto"
|
||||
src={logo}
|
||||
alt="Portal.js"
|
||||
/>
|
||||
<img
|
||||
className="hidden lg:block h-8 w-auto"
|
||||
src={logo}
|
||||
alt="Portal.js"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="hidden lg:ml-6 lg:flex lg:space-x-8">
|
||||
{/* Current: "border-indigo-500 text-gray-900", Default: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700" */}
|
||||
{menu.map((item, index) => (
|
||||
<a
|
||||
key={'menu-link' + index}
|
||||
href={item.path}
|
||||
className="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
|
||||
>
|
||||
{item.title}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 flex items-center justify-center px-2 lg:ml-6 lg:justify-end">
|
||||
<div className="max-w-lg w-full lg:max-w-xs">
|
||||
<label htmlFor="search" className="sr-only">
|
||||
Search
|
||||
</label>
|
||||
<div className="relative">
|
||||
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<SearchIcon
|
||||
className="h-5 w-5 text-gray-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<form
|
||||
onSubmit={(e) => handleSubmit(e)}
|
||||
className="items-center"
|
||||
>
|
||||
<input
|
||||
id="search"
|
||||
type="search"
|
||||
name="search"
|
||||
onChange={(e) => {
|
||||
setSearchQuery(e.target.value);
|
||||
}}
|
||||
placeholder="Search"
|
||||
aria-label="Search"
|
||||
className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center lg:hidden">
|
||||
{/* Mobile menu button */}
|
||||
<Disclosure.Button className="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
|
||||
<span className="sr-only">Open main menu</span>
|
||||
{open ? (
|
||||
<XIcon className="block h-6 w-6" aria-hidden="true" />
|
||||
) : (
|
||||
<MenuIcon className="block h-6 w-6" aria-hidden="true" />
|
||||
)}
|
||||
</Disclosure.Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Disclosure.Panel className="lg:hidden">
|
||||
<div className="pt-2 pb-3 space-y-1">
|
||||
{/* Current: "bg-indigo-50 border-indigo-500 text-indigo-700", Default: "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800" */}
|
||||
{menu.map((item, index) => (
|
||||
<a
|
||||
key={'mobile-menu-link' + index}
|
||||
href={item.path}
|
||||
className="border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium"
|
||||
>
|
||||
{item.title}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</Disclosure.Panel>
|
||||
</>
|
||||
)}
|
||||
</Disclosure>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavBar;
|
||||
@@ -1,96 +0,0 @@
|
||||
/* eslint-disable jsx-a11y/anchor-is-valid */
|
||||
import { useQuery } from '@apollo/react-hooks';
|
||||
import {
|
||||
CollectionIcon,
|
||||
PresentationChartBarIcon,
|
||||
} from '@heroicons/react/solid';
|
||||
import { ErrorMessage } from '../_shared';
|
||||
import { SEARCH_QUERY } from '../../graphql/queries';
|
||||
|
||||
const RecentDataset: React.FC = () => {
|
||||
const { loading, error, data } = useQuery(SEARCH_QUERY, {
|
||||
variables: {
|
||||
sort: 'metadata_created desc',
|
||||
rows: 3,
|
||||
},
|
||||
// Setting this value to true will make the component rerender when
|
||||
// the "networkStatus" changes, so we are able to know if it is fetching
|
||||
// more data
|
||||
notifyOnNetworkStatusChange: true,
|
||||
});
|
||||
|
||||
if (error) return <ErrorMessage message="Error loading search results." />;
|
||||
if (loading) return <div>Loading</div>;
|
||||
|
||||
const { result } = data.search;
|
||||
|
||||
return (
|
||||
<section className="my-10 p-4">
|
||||
<h3 className="text-lg leading-6 font-medium text-gray-900">
|
||||
Recent Datasets
|
||||
</h3>
|
||||
<ul className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{result.results.map((dataset) => (
|
||||
<li
|
||||
key={dataset.id}
|
||||
className="col-span-1 bg-white rounded-lg shadow divide-y divide-gray-200"
|
||||
>
|
||||
<div className="w-full flex items-center justify-between p-6 space-x-6">
|
||||
<div className="flex-1 truncate">
|
||||
<div className="flex items-center space-x-3">
|
||||
<h3 className="text-gray-900 text-sm font-medium truncate">
|
||||
{dataset.title || dataset.name}
|
||||
</h3>
|
||||
<span className="flex-shrink-0 inline-block px-2 py-0.5 text-green-800 text-xs font-medium bg-green-100 rounded-full">
|
||||
dataset
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-1 text-gray-500 text-sm truncate">
|
||||
{dataset.organization.title || dataset.organization.name}
|
||||
</p>
|
||||
</div>
|
||||
<img
|
||||
className="w-10 h-10 bg-gray-300 rounded-full flex-shrink-0"
|
||||
src={
|
||||
dataset.organization.image ||
|
||||
'https://datahub.io/static/img/datahub-cube-edited.svg'
|
||||
}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="-mt-px flex divide-x divide-gray-200">
|
||||
<div className="w-0 flex-1 flex">
|
||||
<a
|
||||
href={`/@${dataset.organization.name}`}
|
||||
className="relative -mr-px w-0 flex-1 inline-flex items-center justify-center py-4 text-sm text-gray-700 font-medium border border-transparent rounded-bl-lg hover:text-gray-500"
|
||||
>
|
||||
<CollectionIcon
|
||||
className="w-5 h-5 text-gray-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span className="ml-3">Organization</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="-ml-px w-0 flex-1 flex">
|
||||
<a
|
||||
href={`/@${dataset.organization.name}/${dataset.name}`}
|
||||
className="relative w-0 flex-1 inline-flex items-center justify-center py-4 text-sm text-gray-700 font-medium border border-transparent rounded-br-lg hover:text-gray-500"
|
||||
>
|
||||
<PresentationChartBarIcon
|
||||
className="w-5 h-5 text-gray-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span className="ml-3">Preview</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default RecentDataset;
|
||||
@@ -1,54 +0,0 @@
|
||||
/* eslint-disable jsx-a11y/anchor-is-valid */
|
||||
import { useQuery } from '@apollo/react-hooks';
|
||||
import { ErrorMessage } from '../_shared';
|
||||
import { GET_STATS_QUERY } from '../../graphql/queries';
|
||||
|
||||
const Stats: React.FC = () => {
|
||||
const { loading, error, data } = useQuery(GET_STATS_QUERY, {
|
||||
variables: {},
|
||||
// Setting this value to true will make the component rerender when
|
||||
// the "networkStatus" changes, so we are able to know if it is fetching
|
||||
// more data
|
||||
notifyOnNetworkStatusChange: true,
|
||||
});
|
||||
|
||||
if (error) return <ErrorMessage message="Error loading search results." />;
|
||||
if (loading) return <div>Loading</div>;
|
||||
|
||||
const stats = [
|
||||
{ name: 'Datasets', stat: data.datasets.result.count },
|
||||
{
|
||||
name: 'Organizations',
|
||||
stat: data.orgs.result ? data.orgs.result.length : 0,
|
||||
},
|
||||
{
|
||||
name: 'Groups',
|
||||
stat: data.groups.result ? data.groups.result.length : 0,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
<h3 className="text-lg leading-6 font-medium text-gray-900">
|
||||
DataHub Stats
|
||||
</h3>
|
||||
<dl className="mt-5 grid grid-cols-1 gap-5 sm:grid-cols-3">
|
||||
{stats.map((item) => (
|
||||
<div
|
||||
key={item.name}
|
||||
className="px-4 py-5 bg-white shadow rounded-lg overflow-hidden sm:p-6"
|
||||
>
|
||||
<dt className="text-sm font-medium text-gray-500 truncate">
|
||||
{item.name}
|
||||
</dt>
|
||||
<dd className="mt-1 text-3xl font-semibold text-gray-900">
|
||||
{item.stat}
|
||||
</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Stats;
|
||||
Reference in New Issue
Block a user