[example][m] - start of ckan-example
This commit is contained in:
188
examples/ckan-example/pages/@org/[org]/[dataset]/index.tsx
Normal file
188
examples/ckan-example/pages/@org/[org]/[dataset]/index.tsx
Normal file
@@ -0,0 +1,188 @@
|
||||
import { GetServerSideProps } from 'next';
|
||||
import getConfig from 'next/config';
|
||||
import React from 'react';
|
||||
import {
|
||||
CalendarIcon,
|
||||
CloudArrowUpIcon,
|
||||
FolderOpenIcon,
|
||||
LockClosedIcon,
|
||||
MapPinIcon,
|
||||
PaperClipIcon,
|
||||
ServerIcon,
|
||||
UserIcon,
|
||||
} from '@heroicons/react/20/solid';
|
||||
|
||||
const dms = getConfig().publicRuntimeConfig.DMS;
|
||||
|
||||
const formatter = new Intl.DateTimeFormat('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
second: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||
const { dataset } = context.query;
|
||||
const response = await fetch(
|
||||
`${dms}/api/3/action/package_show?id=${dataset}`
|
||||
);
|
||||
const _dataset = await response.json();
|
||||
return {
|
||||
props: {
|
||||
dataset: _dataset.result,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const positions = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Back End Developer',
|
||||
type: 'Full-time',
|
||||
location: 'Remote',
|
||||
department: 'Engineering',
|
||||
closeDate: '2020-01-07',
|
||||
closeDateFull: 'January 7, 2020',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Front End Developer',
|
||||
type: 'Full-time',
|
||||
location: 'Remote',
|
||||
department: 'Engineering',
|
||||
closeDate: '2020-01-07',
|
||||
closeDateFull: 'January 7, 2020',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'User Interface Designer',
|
||||
type: 'Full-time',
|
||||
location: 'Remote',
|
||||
department: 'Design',
|
||||
closeDate: '2020-01-14',
|
||||
closeDateFull: 'January 14, 2020',
|
||||
},
|
||||
];
|
||||
|
||||
export default function DatasetPage({ dataset }) {
|
||||
return (
|
||||
<div className="overflow-hidden bg-white py-24 sm:py-32">
|
||||
<div className="mx-auto max-w-7xl px-6 lg:px-8">
|
||||
<div className="mx-auto grid max-w-2xl grid-cols-1 gap-x-8 gap-y-16 sm:gap-y-20 lg:mx-0 lg:max-w-none lg:grid-cols-2">
|
||||
<div className="lg:pr-8 lg:pt-4">
|
||||
<div className="lg:max-w-lg">
|
||||
<h2 className="text-base font-semibold leading-7 text-indigo-600">
|
||||
{dataset.organization.title
|
||||
? dataset.organization.title
|
||||
: dataset.organization.name}
|
||||
</h2>
|
||||
<p className="mt-2 text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
|
||||
{dataset.title ? dataset.title : dataset.name}
|
||||
</p>
|
||||
<p className="mt-6 leading-8 text-gray-600">
|
||||
{dataset.notes ? dataset.notes : 'No description'}
|
||||
</p>
|
||||
<div className="mt-6 border-t border-gray-100">
|
||||
<dl className="divide-y divide-gray-100">
|
||||
{dataset.tags.length > 0 && (
|
||||
<div className="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
|
||||
<dt className="text-sm font-medium leading-6 text-gray-900">
|
||||
Tags
|
||||
</dt>
|
||||
<dd className="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
|
||||
{dataset.tags.map((tag) => tag.display_name).join(', ')}
|
||||
</dd>
|
||||
</div>
|
||||
)}
|
||||
{dataset.url && (
|
||||
<div className="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
|
||||
<dt className="text-sm font-medium leading-6 text-gray-900">
|
||||
Url
|
||||
</dt>
|
||||
<dd className="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
|
||||
{dataset.url}
|
||||
</dd>
|
||||
</div>
|
||||
)}
|
||||
<div className="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
|
||||
<dt className="text-sm font-medium leading-6 text-gray-900">
|
||||
Created
|
||||
</dt>
|
||||
<dd className="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
|
||||
{formatter.format(new Date(dataset.metadata_created))}
|
||||
</dd>
|
||||
</div>
|
||||
<div className="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
|
||||
<dt className="text-sm font-medium leading-6 text-gray-900">
|
||||
Modified
|
||||
</dt>
|
||||
<dd className="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
|
||||
{formatter.format(new Date(dataset.metadata_modified))}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="lg:pr-8 lg:pt-4">
|
||||
<h2 className="text-base font-semibold leading-7 text-indigo-600">
|
||||
Resources
|
||||
</h2>
|
||||
<div className="overflow-hidden bg-white shadow sm:rounded-md mt-2">
|
||||
<ul role="list" className="divide-y divide-gray-200">
|
||||
{dataset.resources.map((resource) => (
|
||||
<li key={resource.id}>
|
||||
<a href={resource.url} className="block hover:bg-gray-50">
|
||||
<div className="px-4 py-4 sm:px-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="truncate text-sm font-medium text-indigo-600">
|
||||
{resource.name}
|
||||
</p>
|
||||
{resource.datastore_active && (
|
||||
<div className="ml-2 flex flex-shrink-0">
|
||||
<p className="inline-flex rounded-full bg-green-100 px-2 text-xs font-semibold leading-5 text-green-800">
|
||||
Datastore active
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-2 sm:flex sm:justify-between">
|
||||
<div className="sm:flex">
|
||||
<p className="flex items-center text-sm text-gray-500">
|
||||
<FolderOpenIcon
|
||||
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{resource.format}
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-2 flex items-center text-sm text-gray-500 sm:mt-0">
|
||||
<CalendarIcon
|
||||
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<p>
|
||||
Last modified:{' '}
|
||||
<time dateTime={resource.metadata_modified}>
|
||||
{formatter.format(
|
||||
new Date(resource.metadata_modified)
|
||||
)}
|
||||
</time>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
18
examples/ckan-example/pages/_app.tsx
Normal file
18
examples/ckan-example/pages/_app.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { AppProps } from 'next/app';
|
||||
import Head from 'next/head';
|
||||
import './styles.css'
|
||||
|
||||
function CustomApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Welcome to ckan-example!</title>
|
||||
</Head>
|
||||
<main className="app">
|
||||
<Component {...pageProps} />
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default CustomApp;
|
||||
114
examples/ckan-example/pages/index.tsx
Normal file
114
examples/ckan-example/pages/index.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import getConfig from 'next/config';
|
||||
import styles from './index.module.css';
|
||||
|
||||
const dms = getConfig().publicRuntimeConfig.DMS
|
||||
|
||||
const formatter = new Intl.DateTimeFormat('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
second: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
|
||||
export async function getServerSideProps() {
|
||||
const response = await fetch(`${dms}/api/3/action/package_search`)
|
||||
const datasets = await response.json()
|
||||
const datasetsWithDetails = await Promise.all(datasets.result.results.map(async (dataset) => {
|
||||
const response = await fetch(`${dms}/api/3/action/package_show?id=` + dataset.name)
|
||||
const json = await response.json()
|
||||
return json.result
|
||||
}))
|
||||
|
||||
return {
|
||||
props: {
|
||||
datasets: datasetsWithDetails
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function Index({ datasets }) {
|
||||
return (
|
||||
<div className="bg-white">
|
||||
<div className="mx-auto max-w-7xl px-6 py-16 sm:py-24 lg:px-8">
|
||||
<h2 className="text-2xl font-bold leading-10 tracking-tight text-indigo-500">
|
||||
My Datasets
|
||||
</h2>
|
||||
<p className="mt-6 max-w-2xl text-base leading-7 text-gray-600">
|
||||
Here is a list of all my datasets for easy access and sharing, they
|
||||
are all available in the following{' '}
|
||||
<a
|
||||
href="#"
|
||||
className="font-semibold text-indigo-600 hover:text-indigo-500"
|
||||
>
|
||||
CKAN Instance
|
||||
</a>
|
||||
</p>
|
||||
<div className="mt-20">
|
||||
<div className="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div className="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
|
||||
<table className="min-w-full divide-y divide-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
|
||||
>
|
||||
Title
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
|
||||
>
|
||||
Description
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
|
||||
>
|
||||
Last updated
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
className="relative py-3.5 pl-3 pr-4 sm:pr-0"
|
||||
></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200">
|
||||
{datasets.map((dataset) => (
|
||||
<tr>
|
||||
<td className="px-3 py-4 text-sm text-gray-500">
|
||||
{dataset.title}
|
||||
</td>
|
||||
<td className="px-3 py-4 text-sm text-gray-500">
|
||||
{dataset.notes}
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
{formatter.format(
|
||||
new Date(dataset.metadata_modified)
|
||||
)}
|
||||
</td>
|
||||
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
|
||||
<a
|
||||
href={`/@${dataset.organization.name}/${dataset.name}`}
|
||||
className="text-indigo-600 hover:text-indigo-900"
|
||||
>
|
||||
More info
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Index;
|
||||
3
examples/ckan-example/pages/styles.css
Normal file
3
examples/ckan-example/pages/styles.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
Reference in New Issue
Block a user