[examples/openspending] - openspending v0.2 (#907)
* [examples/openspending] - openspending v0.2 * [examples/openspending][m] - fix build * [examples/openspending][xs] - fix build * [examples/openspending][xs] - add prebuild step * [examples/openspending][m] - fix requested by demenech * [examples/openspending][sm] - remove links + fix bug
This commit is contained in:
65
examples/openspending/pages/[...slug].tsx
Normal file
65
examples/openspending/pages/[...slug].tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import fs from 'fs';
|
||||
import clientPromise from '@/lib/mddb';
|
||||
import { GetStaticProps } from 'next';
|
||||
import Layout from '../components/_shared/Layout';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { formatDate } from '@/utils/formatDate';
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import matter from 'gray-matter'
|
||||
|
||||
export default function Page({ source, meta }) {
|
||||
return (
|
||||
<Layout>
|
||||
<article className="docs prose-a:text-primary dark:prose-a:text-primary-dark prose-strong:text-primary dark:prose-strong:text-primary-dark prose-code:text-primary dark:prose-code:text-primary-dark prose-headings:text-primary dark:prose-headings:text-primary-dark prose text-primary dark:text-primary-dark prose-headings:font-headings dark:prose-invert prose-a:break-words mx-auto p-6">
|
||||
<header>
|
||||
<div className="mb-4 flex-col items-center">
|
||||
{meta.title && (
|
||||
<h1 className="flex justify-center">{meta.title}</h1>
|
||||
)}
|
||||
{meta.date && (
|
||||
<p className="text-sm text-zinc-400 dark:text-zinc-500 flex justify-center">
|
||||
<time dateTime={meta.date}>{formatDate(meta.date)}</time>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
<section>
|
||||
<ReactMarkdown rehypePlugins={[rehypeRaw]}>{source}</ReactMarkdown>
|
||||
</section>
|
||||
</article>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async ({ params }) => {
|
||||
const urlPath = params?.slug ? (params.slug as string[]).join('/') : '/';
|
||||
|
||||
const mddb = await clientPromise;
|
||||
const dbFile = await mddb.getFileByUrl(urlPath);
|
||||
|
||||
let source = fs.readFileSync(dbFile.file_path, { encoding: 'utf-8' });
|
||||
let {content } = matter(source);
|
||||
return {
|
||||
props: {
|
||||
source: content,
|
||||
meta: dbFile.metadata,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const mddb = await clientPromise;
|
||||
let allDocuments = await mddb.getFiles({ extensions: ['md', 'mdx'] });
|
||||
|
||||
const paths = allDocuments
|
||||
.filter((page) => page.metadata?.isDraft !== true)
|
||||
.map((page) => {
|
||||
const parts = page.url_path!.split('/');
|
||||
return { params: { slug: parts } };
|
||||
});
|
||||
|
||||
return {
|
||||
paths,
|
||||
fallback: false,
|
||||
};
|
||||
}
|
||||
@@ -3,10 +3,31 @@ import './styles.css';
|
||||
import { NextSeo } from 'next-seo';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { pageview } from '@flowershow/core';
|
||||
import Script from 'next/script';
|
||||
import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
import {
|
||||
Layout,
|
||||
SearchProvider,
|
||||
pageview,
|
||||
ThemeProvider,
|
||||
NavItem,
|
||||
NavGroup,
|
||||
} from '@flowershow/core';
|
||||
|
||||
export interface CustomAppProps {
|
||||
meta: {
|
||||
showToc: boolean;
|
||||
showEditLink: boolean;
|
||||
showSidebar: boolean;
|
||||
showComments: boolean;
|
||||
urlPath: string; // not sure what's this for
|
||||
editUrl?: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
siteMap?: Array<NavItem | NavGroup>;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
function CustomApp({ Component, pageProps }: AppProps) {
|
||||
const router = useRouter();
|
||||
@@ -25,19 +46,24 @@ function CustomApp({ Component, pageProps }: AppProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="shortcut icon" href="/squared_logo.png" />
|
||||
</Head>
|
||||
<NextSeo title="OpenSpending" />
|
||||
<Script
|
||||
strategy="afterInteractive"
|
||||
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TOKEN}`}
|
||||
/>
|
||||
<Script
|
||||
id="gtag-init"
|
||||
strategy="afterInteractive"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
<ThemeProvider
|
||||
disableTransitionOnChange
|
||||
attribute="class"
|
||||
forcedTheme={'light'}
|
||||
>
|
||||
<Head>
|
||||
<link rel="shortcut icon" href="/squared_logo.png" />
|
||||
</Head>
|
||||
<NextSeo title="OpenSpending" />
|
||||
<Script
|
||||
strategy="afterInteractive"
|
||||
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TOKEN}`}
|
||||
/>
|
||||
<Script
|
||||
id="gtag-init"
|
||||
strategy="afterInteractive"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
@@ -45,12 +71,13 @@ function CustomApp({ Component, pageProps }: AppProps) {
|
||||
page_path: window.location.pathname,
|
||||
});
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
}}
|
||||
/>
|
||||
|
||||
<main className="app">
|
||||
<Component {...pageProps} />
|
||||
</main>
|
||||
<main className="app">
|
||||
<Component {...pageProps} />
|
||||
</main>
|
||||
</ThemeProvider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
62
examples/openspending/pages/blog.tsx
Normal file
62
examples/openspending/pages/blog.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import fs from 'fs';
|
||||
import React from 'react';
|
||||
import { GetStaticProps } from 'next';
|
||||
import { BlogsList, SimpleLayout } from '@flowershow/core';
|
||||
import clientPromise from '../lib/mddb';
|
||||
import type { CustomAppProps } from './_app';
|
||||
import Layout from '@/components/_shared/Layout';
|
||||
|
||||
interface BlogIndexPageProps extends CustomAppProps {
|
||||
blogs: any[]; // TODO types
|
||||
}
|
||||
|
||||
export default function Blog({
|
||||
blogs,
|
||||
meta: { title, description },
|
||||
}: BlogIndexPageProps) {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="blog-list">
|
||||
<SimpleLayout title={title} description={description}>
|
||||
<BlogsList blogs={blogs} />
|
||||
</SimpleLayout>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async () => {
|
||||
const mddb = await clientPromise;
|
||||
const blogFiles = await mddb.getFiles({ folder: 'blog' });
|
||||
|
||||
const blogs = blogFiles.map((item) => ({
|
||||
_id: item._id,
|
||||
file_path: item.file_path,
|
||||
urlPath: item.url_path,
|
||||
date: item.url_path
|
||||
.split('/')
|
||||
.slice(-1)[0]
|
||||
.split('-')
|
||||
.slice(0, 3)
|
||||
.join('-'),
|
||||
...item.metadata,
|
||||
}));
|
||||
|
||||
return {
|
||||
props: {
|
||||
meta: {
|
||||
title: 'Blog posts',
|
||||
showSidebar: false,
|
||||
showToc: false,
|
||||
showComments: false,
|
||||
showEditLink: false,
|
||||
urlPath: '/blog',
|
||||
},
|
||||
blogs: blogs.sort((a, b) => {
|
||||
const bDate = new Date(b.date);
|
||||
const aDate = new Date(a.date);
|
||||
return bDate.getTime() - aDate.getTime();
|
||||
}),
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -32,15 +32,20 @@ export async function getStaticProps() {
|
||||
// TODO: title should be the full name
|
||||
.map((code) => ({ code, title: code }));
|
||||
|
||||
const minPeriod = projects.map(project => project.fiscalPeriod ? project.fiscalPeriod.start : null).filter(item => item !== null).sort()[0]
|
||||
const maxPeriod = projects.map(project => project.fiscalPeriod ? project.fiscalPeriod.end : null).filter(item => item !== null).sort().slice(-1)[0]
|
||||
|
||||
return {
|
||||
props: {
|
||||
projects: JSON.stringify(projects),
|
||||
availableCountries,
|
||||
minPeriod,
|
||||
maxPeriod
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function Home({ projects, availableCountries }) {
|
||||
export function Home({ projects, availableCountries, minPeriod, maxPeriod }) {
|
||||
projects = JSON.parse(projects);
|
||||
|
||||
return (
|
||||
@@ -70,6 +75,8 @@ export function Home({ projects, availableCountries }) {
|
||||
<DatasetsSearch
|
||||
datasets={projects}
|
||||
availableCountries={availableCountries}
|
||||
minPeriod={minPeriod}
|
||||
maxPeriod={maxPeriod}
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
@@ -78,3 +78,7 @@ pre {
|
||||
color: rgba(55, 65, 81, 1);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.blog-list button {
|
||||
color: black;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user