Compare commits
8 Commits
luccas_exp
...
ckan_examp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80c0d1db63 | ||
|
|
0694c4764f | ||
|
|
234bbcec49 | ||
|
|
83bffccf52 | ||
|
|
97f97fb767 | ||
|
|
158dc12da2 | ||
|
|
0d835cca32 | ||
|
|
cb51660cbb |
1
examples/ckan-example/.env
Normal file
1
examples/ckan-example/.env
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DMS=https://demo.dev.datopian.com
|
||||||
34
examples/ckan-example/.eslintrc.json
Normal file
34
examples/ckan-example/.eslintrc.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"plugin:@nrwl/nx/react-typescript",
|
||||||
|
"next",
|
||||||
|
"next/core-web-vitals",
|
||||||
|
"../../.eslintrc.json"
|
||||||
|
],
|
||||||
|
"ignorePatterns": ["!**/*", ".next/**/*"],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
|
"rules": {
|
||||||
|
"@next/next/no-html-link-for-pages": [
|
||||||
|
"error",
|
||||||
|
"examples/ckan-example/pages"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"@next/next/no-html-link-for-pages": "off"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"jest": true
|
||||||
|
}
|
||||||
|
}
|
||||||
17
examples/ckan-example/README.md
Normal file
17
examples/ckan-example/README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
This is a repo intended to serve as an example of a data catalog that get its data from a CKAN Instance.
|
||||||
|
|
||||||
|
- Creating a new file inside o `examples` with `create-next-app` like so:
|
||||||
|
```
|
||||||
|
npx create-next-app <app-name> --example https://github.com/datopian/portaljs/tree/main/ --example-path examples/ckan-example
|
||||||
|
```
|
||||||
|
- Inside `<app-name>` go to the `project.json` file and replace all instances of `ckan-example` with `<app-name>`
|
||||||
|
- Set the `DMS` env variable to the Url of the CKAN Instance Ex: `export DMS=https://demo.dev.datopian.com`
|
||||||
|
- Run the app using:
|
||||||
|
```
|
||||||
|
nx serve <app-name>
|
||||||
|
```
|
||||||
|
Congratulations, you now have something similar to this running on `http://localhost:4200`
|
||||||
|

|
||||||
|
If yo go to any one of those pages by clicking on `More info` you will see something similar to this
|
||||||
|

|
||||||
|
|
||||||
6
examples/ckan-example/index.d.ts
vendored
Normal file
6
examples/ckan-example/index.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
declare module '*.svg' {
|
||||||
|
const content: any;
|
||||||
|
export const ReactComponent: any;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
11
examples/ckan-example/jest.config.ts
Normal file
11
examples/ckan-example/jest.config.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
export default {
|
||||||
|
displayName: 'ckan-example',
|
||||||
|
preset: '../../jest.preset.js',
|
||||||
|
transform: {
|
||||||
|
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
|
||||||
|
'^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/next/babel'] }],
|
||||||
|
},
|
||||||
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||||
|
coverageDirectory: '../../coverage/examples/ckan-example',
|
||||||
|
};
|
||||||
5
examples/ckan-example/next-env.d.ts
vendored
Normal file
5
examples/ckan-example/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/// <reference types="next" />
|
||||||
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
|
// NOTE: This file should not be edited
|
||||||
|
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||||
28
examples/ckan-example/next.config.js
Normal file
28
examples/ckan-example/next.config.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const { withNx } = require('@nrwl/next/plugins/with-nx');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import('@nrwl/next/plugins/with-nx').WithNxOptions}
|
||||||
|
**/
|
||||||
|
const nextConfig = {
|
||||||
|
publicRuntimeConfig: {
|
||||||
|
DMS: process.env.DMS ? process.env.DMS : '',
|
||||||
|
},
|
||||||
|
async rewrites() {
|
||||||
|
return {
|
||||||
|
beforeFiles: [
|
||||||
|
{
|
||||||
|
source: '/@:org/:project*',
|
||||||
|
destination: '/@org/:org/:project*',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
nx: {
|
||||||
|
// Set this to true if you would like to use SVGR
|
||||||
|
// See: https://github.com/gregberge/svgr
|
||||||
|
svgr: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = withNx(nextConfig);
|
||||||
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;
|
||||||
15
examples/ckan-example/postcss.config.js
Normal file
15
examples/ckan-example/postcss.config.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
const { join } = require('path');
|
||||||
|
|
||||||
|
// Note: If you use library-specific PostCSS/Tailwind configuration then you should remove the `postcssConfig` build
|
||||||
|
// option from your application's configuration (i.e. project.json).
|
||||||
|
//
|
||||||
|
// See: https://nx.dev/guides/using-tailwind-css-in-react#step-4:-applying-configuration-to-libraries
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {
|
||||||
|
config: join(__dirname, 'tailwind.config.js'),
|
||||||
|
},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
69
examples/ckan-example/project.json
Normal file
69
examples/ckan-example/project.json
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"name": "ckan-example",
|
||||||
|
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||||
|
"sourceRoot": "examples/ckan-example",
|
||||||
|
"projectType": "application",
|
||||||
|
"targets": {
|
||||||
|
"build": {
|
||||||
|
"executor": "@nrwl/next:build",
|
||||||
|
"outputs": ["{options.outputPath}"],
|
||||||
|
"defaultConfiguration": "production",
|
||||||
|
"options": {
|
||||||
|
"root": "examples/ckan-example",
|
||||||
|
"outputPath": "dist/examples/ckan-example"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"development": {
|
||||||
|
"outputPath": "examples/ckan-example"
|
||||||
|
},
|
||||||
|
"production": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"executor": "@nrwl/next:server",
|
||||||
|
"defaultConfiguration": "development",
|
||||||
|
"options": {
|
||||||
|
"buildTarget": "ckan-example:build",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"development": {
|
||||||
|
"buildTarget": "ckan-example:build:development",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"production": {
|
||||||
|
"buildTarget": "ckan-example:build:production",
|
||||||
|
"dev": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"export": {
|
||||||
|
"executor": "@nrwl/next:export",
|
||||||
|
"options": {
|
||||||
|
"buildTarget": "ckan-example:build:production"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"executor": "@nrwl/jest:jest",
|
||||||
|
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||||
|
"options": {
|
||||||
|
"jestConfig": "examples/ckan-example/jest.config.ts",
|
||||||
|
"passWithNoTests": true
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"ci": {
|
||||||
|
"ci": true,
|
||||||
|
"codeCoverage": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"executor": "@nrwl/linter:eslint",
|
||||||
|
"outputs": ["{options.outputFile}"],
|
||||||
|
"options": {
|
||||||
|
"lintFilePatterns": ["examples/ckan-example/**/*.{ts,tsx,js,jsx}"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
0
examples/ckan-example/public/.gitkeep
Normal file
0
examples/ckan-example/public/.gitkeep
Normal file
11
examples/ckan-example/specs/index.spec.tsx
Normal file
11
examples/ckan-example/specs/index.spec.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
|
import Index from '../pages/index';
|
||||||
|
|
||||||
|
describe('Index', () => {
|
||||||
|
it('should render successfully', () => {
|
||||||
|
const { baseElement } = render(<Index />);
|
||||||
|
expect(baseElement).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
17
examples/ckan-example/tailwind.config.js
Normal file
17
examples/ckan-example/tailwind.config.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
const { createGlobPatternsForDependencies } = require('@nrwl/react/tailwind');
|
||||||
|
const { join } = require('path');
|
||||||
|
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: [
|
||||||
|
join(
|
||||||
|
__dirname,
|
||||||
|
'{src,pages,components}/**/*!(*.stories|*.spec).{ts,tsx,html}'
|
||||||
|
),
|
||||||
|
...createGlobPatternsForDependencies(__dirname),
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
23
examples/ckan-example/tsconfig.json
Normal file
23
examples/ckan-example/tsconfig.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "preserve",
|
||||||
|
"allowJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"strict": false,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"incremental": true,
|
||||||
|
"types": ["jest", "node"]
|
||||||
|
},
|
||||||
|
"include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "next-env.d.ts"],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"jest.config.ts",
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/**/*.test.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
21
examples/ckan-example/tsconfig.spec.json
Normal file
21
examples/ckan-example/tsconfig.spec.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"module": "commonjs",
|
||||||
|
"types": ["jest", "node"],
|
||||||
|
"jsx": "react"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"jest.config.ts",
|
||||||
|
"src/**/*.test.ts",
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/**/*.test.tsx",
|
||||||
|
"src/**/*.spec.tsx",
|
||||||
|
"src/**/*.test.js",
|
||||||
|
"src/**/*.spec.js",
|
||||||
|
"src/**/*.test.jsx",
|
||||||
|
"src/**/*.spec.jsx",
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
|
|
||||||
"ignorePatterns": ["!**/*"],
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
|
||||||
"rules": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import { defineConfig } from 'cypress';
|
|
||||||
import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
e2e: nxE2EPreset(__dirname),
|
|
||||||
});
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "simple-example-e2e",
|
|
||||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
||||||
"sourceRoot": "examples/simple-example-e2e/src",
|
|
||||||
"projectType": "application",
|
|
||||||
"targets": {
|
|
||||||
"e2e": {
|
|
||||||
"executor": "@nrwl/cypress:cypress",
|
|
||||||
"options": {
|
|
||||||
"cypressConfig": "examples/simple-example-e2e/cypress.config.ts",
|
|
||||||
"devServerTarget": "simple-example:serve:development",
|
|
||||||
"testingType": "e2e"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"devServerTarget": "simple-example:serve:production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"executor": "@nrwl/linter:eslint",
|
|
||||||
"outputs": ["{options.outputFile}"],
|
|
||||||
"options": {
|
|
||||||
"lintFilePatterns": ["examples/simple-example-e2e/**/*.{js,ts}"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": [],
|
|
||||||
"implicitDependencies": ["simple-example"]
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { getGreeting } from '../support/app.po';
|
|
||||||
|
|
||||||
describe('simple-example', () => {
|
|
||||||
beforeEach(() => cy.visit('/'));
|
|
||||||
|
|
||||||
it('should display welcome message', () => {
|
|
||||||
// Custom command example, see `../support/commands.ts` file
|
|
||||||
cy.login('my-email@something.com', 'myPassword');
|
|
||||||
|
|
||||||
// Function helper example, see `../support/app.po.ts` file
|
|
||||||
getGreeting().contains('Welcome simple-example');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Using fixtures to represent data",
|
|
||||||
"email": "hello@cypress.io"
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export const getGreeting = () => cy.get('h1');
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
// ***********************************************
|
|
||||||
// This example commands.js shows you how to
|
|
||||||
// create various custom commands and overwrite
|
|
||||||
// existing commands.
|
|
||||||
//
|
|
||||||
// For more comprehensive examples of custom
|
|
||||||
// commands please read more here:
|
|
||||||
// https://on.cypress.io/custom-commands
|
|
||||||
// ***********************************************
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
||||||
declare namespace Cypress {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
interface Chainable<Subject> {
|
|
||||||
login(email: string, password: string): void;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// -- This is a parent command --
|
|
||||||
Cypress.Commands.add('login', (email, password) => {
|
|
||||||
console.log('Custom command example: Login', email, password);
|
|
||||||
});
|
|
||||||
//
|
|
||||||
// -- This is a child command --
|
|
||||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// -- This is a dual command --
|
|
||||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// -- This will overwrite an existing command --
|
|
||||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
// ***********************************************************
|
|
||||||
// This example support/index.js is processed and
|
|
||||||
// loaded automatically before your test files.
|
|
||||||
//
|
|
||||||
// This is a great place to put global configuration and
|
|
||||||
// behavior that modifies Cypress.
|
|
||||||
//
|
|
||||||
// You can change the location of this file or turn off
|
|
||||||
// automatically serving support files with the
|
|
||||||
// 'supportFile' configuration option.
|
|
||||||
//
|
|
||||||
// You can read more here:
|
|
||||||
// https://on.cypress.io/configuration
|
|
||||||
// ***********************************************************
|
|
||||||
|
|
||||||
// Import commands.js using ES2015 syntax:
|
|
||||||
import './commands';
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"sourceMap": false,
|
|
||||||
"outDir": "../../dist/out-tsc",
|
|
||||||
"allowJs": true,
|
|
||||||
"types": ["cypress", "node"]
|
|
||||||
},
|
|
||||||
"include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"]
|
|
||||||
}
|
|
||||||
17
examples/simple-example/README.md
Normal file
17
examples/simple-example/README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
This is a repo intended to serve as a simple example of a data catalog that get its data from a series of github repos, you can init an example just like this one by.
|
||||||
|
|
||||||
|
- Creating a new file inside o `examples` with `create-next-app` like so:
|
||||||
|
```
|
||||||
|
npx create-next-app <app-name> --example https://github.com/datopian/portaljs/tree/main/ --example-path examples/simple-example
|
||||||
|
```
|
||||||
|
- Inside `<app-name>` go to the `project.json` file and replace all instances of `simple-example` with `<app-name>`
|
||||||
|
- Edit the file `datasets.json` to your liking, some examples can be found inside this [repo](https://github.com/datasets)
|
||||||
|
- Run the app using:
|
||||||
|
```
|
||||||
|
nx serve <app-name>
|
||||||
|
```
|
||||||
|
Congratulations, you now have something similar to this running on `http://localhost:4200`
|
||||||
|

|
||||||
|
If yo go to any one of those pages by clicking on `More info` you will see something similar to this
|
||||||
|

|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Vega as VegaOg } from "react-vega";
|
import { Vega as VegaOg } from "react-vega";
|
||||||
export default function Vega(props) {
|
export default function Vega(props) {
|
||||||
return <VegaOg {...props} />;
|
return <VegaOg className="w-full" {...props} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { VegaLite as VegaOg } from "react-vega";
|
import { VegaLite as VegaOg } from "react-vega";
|
||||||
export default function Vega(props) {
|
export default function Vega(props) {
|
||||||
return <VegaOg {...props} />;
|
return <VegaOg className="w-full" {...props} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export function convertSimpleToVegaLite(view, resource) {
|
|||||||
tooltip: true,
|
tooltip: true,
|
||||||
},
|
},
|
||||||
title: view.title,
|
title: view.title,
|
||||||
width: "container",
|
width: 500,
|
||||||
height: 300,
|
height: 300,
|
||||||
selection: {
|
selection: {
|
||||||
grid: {
|
grid: {
|
||||||
|
|||||||
7
examples/simple-example/package.json
Normal file
7
examples/simple-example/package.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "simple-example",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import Highlight, { defaultProps } from 'prism-react-renderer';
|
import Highlight, { defaultProps } from 'prism-react-renderer';
|
||||||
import { Fragment, useRef } from 'react';
|
import { Fragment, useRef } from 'react';
|
||||||
|
import NewsletterForm from './NewsletterForm';
|
||||||
|
|
||||||
const codeLanguage = 'javascript';
|
const codeLanguage = 'javascript';
|
||||||
const code = `export default {
|
const code = `export default {
|
||||||
@@ -49,51 +50,7 @@ export function Hero() {
|
|||||||
present a single dataset or build a full-scale data
|
present a single dataset or build a full-scale data
|
||||||
catalog/portal.
|
catalog/portal.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 sm:mx-auto sm:text-center lg:text-left lg:mx-0">
|
<NewsletterForm />
|
||||||
<p className="text-base font-medium text-slate-400 dark:text-slate-400">
|
|
||||||
Sign up to get notified about updates
|
|
||||||
</p>
|
|
||||||
<form
|
|
||||||
method="POST"
|
|
||||||
name="get-updates"
|
|
||||||
data-netlify="true"
|
|
||||||
action="/subscribed"
|
|
||||||
className="mt-3 sm:flex"
|
|
||||||
>
|
|
||||||
<label htmlFor="name" className="sr-only">
|
|
||||||
Name
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
name="name"
|
|
||||||
type="text"
|
|
||||||
required
|
|
||||||
placeholder="Your name"
|
|
||||||
className="block w-full sm:flex-auto sm:w-32 px-2 py-3 text-base rounded-md bg-slate-200 dark:bg-slate-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-400 focus:ring-offset-gray-900"
|
|
||||||
/>
|
|
||||||
<label htmlFor="email" className="sr-only">
|
|
||||||
Email address
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
required
|
|
||||||
placeholder="Your email"
|
|
||||||
className="block w-full mt-3 sm:flex-auto sm:w-64 sm:mt-0 sm:ml-3 px-2 py-3 text-base rounded-md bg-slate-200 dark:bg-slate-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-400 focus:ring-offset-gray-900"
|
|
||||||
/>
|
|
||||||
<input type="hidden" name="form-name" value="get-updates" />
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
className="flex-none mt-3 px-6 py-3 border border-transparent text-base font-medium rounded-md text-slate-900 bg-blue-400 hover:bg-blue-300 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-300/50 active:bg-sky-500 sm:mt-0 sm:ml-3"
|
|
||||||
>
|
|
||||||
Notify me
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
{/* <p className="mt-3 text-sm text-slate-400 dark:text-slate-300 sm:mt-4">
|
|
||||||
We are actively trialling and developing Flowershow. If you'd
|
|
||||||
like to get notified about our progress and important updates,
|
|
||||||
please sign up.
|
|
||||||
</p> */}
|
|
||||||
</div>
|
|
||||||
<p className="my-10 text-l tracking-wide">
|
<p className="my-10 text-l tracking-wide">
|
||||||
<span>A project of</span>
|
<span>A project of</span>
|
||||||
<a
|
<a
|
||||||
|
|||||||
147
site/components/NewsletterForm.tsx
Normal file
147
site/components/NewsletterForm.tsx
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
import Script from 'next/script';
|
||||||
|
|
||||||
|
export default function NewsletterForm() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://sibforms.com/forms/end-form/build/sib-styles.css"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
id="sib-form-container"
|
||||||
|
className="mt-8 sm:mx-auto sm:text-center lg:text-left lg:mx-0"
|
||||||
|
>
|
||||||
|
<p className="text-base font-medium text-slate-400 dark:text-slate-400">
|
||||||
|
Sign up to get notified about updates
|
||||||
|
</p>
|
||||||
|
<div id="sib-container" className="!bg-transparent !p-0 !pb-5">
|
||||||
|
<form
|
||||||
|
id="sib-form"
|
||||||
|
method="POST"
|
||||||
|
action="https://0613d040.sibforms.com/serve/MUIEAGd31Nknuf7_fodoNJ3t0B71KWpbFfnzgk_VewvONuLQG8JO3qOotew23kQT3HpoJQUG_vzcjOTjn29B6GpXxPbSml_XWwHgG2mWq-jhrjfqpHCcPoOY_ge-rN2vDFWYZ80l242DTYGDRRWtTusdAYIk2oyf-nhJyOqQrUzTnXlAlKc7SxWgynSQ1GHr3jU5s57h6986IoK4"
|
||||||
|
data-type="subscription"
|
||||||
|
className="mt-3 sm:flex"
|
||||||
|
>
|
||||||
|
<div className="sib-input sib-form-block !p-0 block w-full sm:flex-auto sm:w-32">
|
||||||
|
<div className="form__entry entry_block w-full">
|
||||||
|
<label htmlFor="name" className="sr-only entry__label">
|
||||||
|
Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="NAME"
|
||||||
|
name="NAME"
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
placeholder="Your name"
|
||||||
|
className="input entry__field !w-full px-2 py-3 text-base rounded-md bg-slate-200 dark:bg-slate-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-400 focus:ring-offset-gray-900"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<label className="entry__error entry__error--primary text-red-400 text-sm"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="sib-input sib-form-block !p-0 block w-full sm:flex-auto sm:w-64 mt-3 sm:mt-0 sm:ml-3">
|
||||||
|
<div className="form__entry entry_block w-full">
|
||||||
|
<label htmlFor="email" className="sr-only entry__label">
|
||||||
|
Email address
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="EMAIL"
|
||||||
|
name="EMAIL"
|
||||||
|
type="email"
|
||||||
|
required
|
||||||
|
placeholder="Your email"
|
||||||
|
className="input entry__field !w-full px-2 py-3 text-base rounded-md bg-slate-200 dark:bg-slate-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-400 focus:ring-offset-gray-900"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<label className="entry__error entry__error--primary px-2 text-red-400 text-sm"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="hidden" name="form-name" value="get-updates" />
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="sib-form-block__button sib-form-block__button-with-loader h-12 flex-none mt-3 px-6 py-3 border border-transparent text-base font-medium rounded-md text-slate-900 bg-blue-400 hover:bg-blue-300 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-300/50 active:bg-sky-500 sm:mt-0 sm:ml-3"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="icon clickable__icon progress-indicator__icon sib-hide-loader-icon hidden"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
>
|
||||||
|
<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
|
||||||
|
</button>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="email_address_check"
|
||||||
|
value=""
|
||||||
|
className="input--hidden"
|
||||||
|
/>
|
||||||
|
<input type="hidden" name="locale" value="en" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="error-message"
|
||||||
|
className="sib-form-message-panel !border-none"
|
||||||
|
>
|
||||||
|
<div className="sib-form-message-panel__text sib-form-message-panel__text--center !text-red-400 justify-center">
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
className="sib-icon sib-notification__icon"
|
||||||
|
>
|
||||||
|
<path d="M256 40c118.621 0 216 96.075 216 216 0 119.291-96.61 216-216 216-119.244 0-216-96.562-216-216 0-119.203 96.602-216 216-216m0-32C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm-11.49 120h22.979c6.823 0 12.274 5.682 11.99 12.5l-7 168c-.268 6.428-5.556 11.5-11.99 11.5h-8.979c-6.433 0-11.722-5.073-11.99-11.5l-7-168c-.283-6.818 5.167-12.5 11.99-12.5zM256 340c-15.464 0-28 12.536-28 28s12.536 28 28 28 28-12.536 28-28-12.536-28-28-28z" />
|
||||||
|
</svg>
|
||||||
|
<span className="sib-form-message-panel__inner-text !text-md">
|
||||||
|
Your subscription could not be saved. Please try again.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="success-message"
|
||||||
|
className="sib-form-message-panel !border-none"
|
||||||
|
>
|
||||||
|
<div className="sib-form-message-panel__text sib-form-message-panel__text--center text-green-400 justify-center">
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
className="sib-icon sib-notification__icon"
|
||||||
|
>
|
||||||
|
<path d="M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 464c-118.664 0-216-96.055-216-216 0-118.663 96.055-216 216-216 118.664 0 216 96.055 216 216 0 118.663-96.055 216-216 216zm141.63-274.961L217.15 376.071c-4.705 4.667-12.303 4.637-16.97-.068l-85.878-86.572c-4.667-4.705-4.637-12.303.068-16.97l8.52-8.451c4.705-4.667 12.303-4.637 16.97.068l68.976 69.533 163.441-162.13c4.705-4.667 12.303-4.637 16.97.068l8.451 8.52c4.668 4.705 4.637 12.303-.068 16.97z" />
|
||||||
|
</svg>
|
||||||
|
<span className="sib-form-message-panel__inner-text !text-md !text-green-500">
|
||||||
|
Your subscription has been successful.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Script
|
||||||
|
id="newsletter-form-validation-message"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: `
|
||||||
|
window.REQUIRED_CODE_ERROR_MESSAGE = 'Please choose a country code';
|
||||||
|
window.LOCALE = 'en';
|
||||||
|
window.EMAIL_INVALID_MESSAGE = window.SMS_INVALID_MESSAGE = "The information provided is invalid. Please review the field format and try again.";
|
||||||
|
|
||||||
|
window.REQUIRED_ERROR_MESSAGE = "This field cannot be left blank. ";
|
||||||
|
|
||||||
|
window.GENERIC_INVALID_MESSAGE = "The information provided is invalid. Please review the field format and try again.";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
window.translation = {
|
||||||
|
common: {
|
||||||
|
selectedList: '{quantity} list selected',
|
||||||
|
selectedLists: '{quantity} lists selected'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var AUTOHIDE = Boolean(0);
|
||||||
|
`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Script
|
||||||
|
id="newsletter-submit-form"
|
||||||
|
src="https://sibforms.com/forms/end-form/build/main.js"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user