diff --git a/package.json b/package.json index d45adbf..8a351a6 100644 --- a/package.json +++ b/package.json @@ -16,13 +16,17 @@ "axios": "^0.21.1", "bootstrap": "^4.4.1", "excerpts": "^0.0.3", + "i18next": "^19.8.7", + "i18next-xhr-backend": "^3.2.2", "node-sass": "^4.14.1", "react": "^16.13.1", "react-dom": "^16.13.1", "react-helmet": "^5.2.1", + "react-i18next": "^11.8.6", "react-js-pagination": "^3.0.3", "react-scripts": "3.4.1", - "swagger-ui-react": "3.25.0" + "swagger-ui-react": "3.25.0", + "uswds": "^2.10.0" }, "scripts": { "start": "react-scripts start", diff --git a/public/locales/en/about.json b/public/locales/en/about.json new file mode 100644 index 0000000..a95bd8c --- /dev/null +++ b/public/locales/en/about.json @@ -0,0 +1,6 @@ +{ + "title": "About this site", + "p1": "This is the default state of the DKAN data catalog.", + "p2": "This tool helps create open data catalogs using React and other libraries.", + "announcement": "Update this about page before publishing." +} \ No newline at end of file diff --git a/public/locales/en/publishers.json b/public/locales/en/publishers.json new file mode 100644 index 0000000..00e31b4 --- /dev/null +++ b/public/locales/en/publishers.json @@ -0,0 +1,4 @@ +{ + "title": "Dataset Publishers", + "description": "Groups allow you to classify datasets that share a common publisher or organizational group (i.e. Parks and Recreation Department, Department of Education). Behind the scenes, Groups can offer an additional set of roles and permissions that ensure quality and security when publishing data. This is especially important for large sites that may have several working groups publishing data to the same site." +} \ No newline at end of file diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json new file mode 100644 index 0000000..15cbc8a --- /dev/null +++ b/public/locales/en/translation.json @@ -0,0 +1,3 @@ +{ + "en": "English" +} \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index e8562c2..335f249 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -8,7 +8,6 @@ import NotFound from './templates/not_found'; import Dataset from './templates/dataset'; import ApiDocsSpecific from './templates/dataset/api'; import Publishers from './templates/publishers'; -import '@civicactions/data-catalog-components/dist/index.css'; import './theme/index.scss'; import { library } from '@fortawesome/fontawesome-svg-core'; diff --git a/src/assets/config.json b/src/assets/config.json index 4948625..e29870a 100644 --- a/src/assets/config.json +++ b/src/assets/config.json @@ -1,5 +1,4 @@ { - "container": "container", "site": "Open Data Catalog", "slogan": "Your slogan here.", "logo": "https://dkan-default-content-files.s3.amazonaws.com/files/logo.svg" diff --git a/src/components/FeaturedDatasets/index.jsx b/src/components/FeaturedDatasets/index.jsx index 02dced0..8728d27 100644 --- a/src/components/FeaturedDatasets/index.jsx +++ b/src/components/FeaturedDatasets/index.jsx @@ -8,19 +8,19 @@ import './featureddatasets.scss'; const FeaturedDatasets = ({ datasets }) => { return ( -
+

Featured Datasets

    - {datasets.map((item) => ( -
  1. - -

    {item.title}

    - - - {excerpts(item.description, {words: 35})} - -
  2. - ))} + {datasets.map((item) => ( +
  3. + +

    {item.title}

    + + + {excerpts(item.description, {words: 35})} + +
  4. + ))}
); diff --git a/src/components/Layout/index.jsx b/src/components/Layout/index.jsx index 2147146..68278c1 100644 --- a/src/components/Layout/index.jsx +++ b/src/components/Layout/index.jsx @@ -13,27 +13,27 @@ const Layout = ({ return (
-
+
( - - {item.label} - - ))} - customClasses={config.container} + navItems={links.main.map(item => ( + + {item.label} + + ))} + customClasses="grid-container" />
- {children} + {children}
-
+
); }; diff --git a/src/i18n.js b/src/i18n.js new file mode 100644 index 0000000..ee93857 --- /dev/null +++ b/src/i18n.js @@ -0,0 +1,21 @@ +import i18n from "i18next"; +import { initReactI18next } from "react-i18next"; +import Backend from 'i18next-xhr-backend'; + +i18n + .use(Backend) + .use(initReactI18next) // passes i18n down to react-i18next + .init({ + debug: true, + lng: "en", + fallbackLng: 'en', + whitelist: ['en', 'de'], + interpolation: { + escapeValue: false // react already safes from xss + }, + backend: { + loadPath: '/frontend/build/locales/{{lng}}/{{ns}}.json', + }, + }); + + export default i18n; \ No newline at end of file diff --git a/src/index.css b/src/index.css deleted file mode 100644 index ec2585e..0000000 --- a/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} diff --git a/src/index.js b/src/index.js index f5185c1..40a9c06 100644 --- a/src/index.js +++ b/src/index.js @@ -1,12 +1,14 @@ -import React from 'react'; +import React, { Suspense } from 'react'; import ReactDOM from 'react-dom'; -import './index.css'; +import './i18n'; import App from './App'; import * as serviceWorker from './serviceWorker'; ReactDOM.render( - + + + , document.getElementById('root') ); diff --git a/src/templates/about/index.jsx b/src/templates/about/index.jsx index 1b9751e..14e8b2e 100644 --- a/src/templates/about/index.jsx +++ b/src/templates/about/index.jsx @@ -1,28 +1,24 @@ -import React from "react"; +import React from 'react'; +import { useTranslation } from 'react-i18next'; import { Announcement } from "@civicactions/data-catalog-components"; import Layout from '../../components/Layout'; import config from "../../assets/config"; -const About = ({ path }) => ( +const About = () => { + const { t } = useTranslation('about'); + return( -
-

About this site

-
-
-

This is the default state of the DKAN data catalog.

-

- This tool helps create open data catalogs using React and other - libraries. -

-
-
- -

Update this about page before publishing.

-
-
-
-
+
+

{t('about:title', 'Fallback')}

+
+
+

{t('about:p1')}

+

{t('about:p2')}

+
+
+
-); + ) +}; export default About; diff --git a/src/templates/api/index.jsx b/src/templates/api/index.jsx index 2c8e2aa..982483e 100644 --- a/src/templates/api/index.jsx +++ b/src/templates/api/index.jsx @@ -5,10 +5,10 @@ import { ApiDocs } from "@civicactions/data-catalog-components"; const ApiDocsFull = ({ path }) => ( -
+
{typeof window !== `undefined` && ( - + )}
diff --git a/src/templates/dataset/api.jsx b/src/templates/dataset/api.jsx index 7078a04..0b86e78 100644 --- a/src/templates/dataset/api.jsx +++ b/src/templates/dataset/api.jsx @@ -22,8 +22,8 @@ const ApiDocsSpecific = ({ id, location }) => { } else { axios.get(`${process.env.REACT_APP_ROOT_URL}/metastore/schemas/dataset/items/${id}?show-reference-ids`) .then((res) => { - setItem(res.data); - setLoading(false); + setItem(res.data); + setLoading(false); }) } }, [id, state]) @@ -41,47 +41,46 @@ const ApiDocsSpecific = ({ id, location }) => { } return ( -
+
- } - > -
- -
- {renderOrg} -
-
-
-
-

{item.title}

- -
+ backgroundStyle={{ backgroundColor: "#f9fafb" }} + foregroundStyle={{ backgroundColor: "#f9fafb" }} + show={loading} + message={ + + } + > +
+
+ {renderOrg} +
+
+
+
+

{item.title}

+ +
diff --git a/src/templates/dataset/index.jsx b/src/templates/dataset/index.jsx index 5828014..bbfef36 100644 --- a/src/templates/dataset/index.jsx +++ b/src/templates/dataset/index.jsx @@ -55,9 +55,9 @@ const Dataset = ({id, location}) => { return null; } else { return theme.map(topic => { - return ( - - ); + return ( + + ); }); } } @@ -118,47 +118,47 @@ const Dataset = ({id, location}) => { return ( -
-
-
- {renderOrg} -
- The information on this page is also available via the{" "} - - API - . -
-
-
-

{item.title}

- {theme.length > 0 &&
{themes(theme)}
} - - {(hasWindow && item.distribution) && - item.distribution.map(dist => { - return ; - })} - - {/* */} -
- - - - - ); +
+
+
+ {renderOrg} +
+ The information on this page is also available via the{" "} + + API + . +
+
+
+

{item.title}

+ {theme.length > 0 &&
{themes(theme)}
} + + {(hasWindow && item.distribution) && + item.distribution.map(dist => { + return ; + })} + + {/*
*/} +
+ + + + + ); }; export default Dataset; diff --git a/src/templates/home/index.jsx b/src/templates/home/index.jsx index 34f19b1..24900b8 100644 --- a/src/templates/home/index.jsx +++ b/src/templates/home/index.jsx @@ -10,6 +10,7 @@ import { import Layout from '../../components/Layout'; import FeaturedDatasets from '../../components/FeaturedDatasets'; import copy from "../../assets/copy.json"; +import config from "../../assets/config"; const Home = () => { const [datasets, setDatasets] = React.useState(null); @@ -33,7 +34,7 @@ const Home = () => { } if (datasets) { const orderedDatasets = datasets.sort(function(a,b) { - return a.title - b.title; + return a.title - b.title; }); setFDatasets(orderedDatasets.length > 3 ? orderedDatasets.slice(orderedDatasets.length -3, orderedDatasets.length) : orderedDatasets); @@ -43,10 +44,10 @@ const Home = () => { React.useEffect(() => { setItems(themes.map(x => { let item = { - identifier: x.identifier, - ref: `search?theme=${x.data}`, - title: x.data, - size: "100" + identifier: x.identifier, + ref: `search?theme=${x.data}`, + title: x.data, + size: "100" }; return item; })) @@ -54,24 +55,23 @@ const Home = () => { return ( -
- -
- -
- - -
+
+ +
+ +
+ + +
); } diff --git a/src/templates/publishers/index.jsx b/src/templates/publishers/index.jsx index 2272bb5..5d1d424 100644 --- a/src/templates/publishers/index.jsx +++ b/src/templates/publishers/index.jsx @@ -1,26 +1,20 @@ import React from 'react'; +import { useTranslation } from 'react-i18next'; import { PublisherList } from "@civicactions/data-catalog-components"; import config from "../../assets/config"; import Layout from '../../components/Layout'; import orgs from "../../assets/publishers"; const Publishers = () => { + const { t } = useTranslation('publishers'); return ( -
-

Dataset Publishers

+
+

{t('publishers:title', 'Fallback Title')}

-

- Groups allow you to classify datasets that share a common - publisher or organizational group (i.e. Parks and Recreation - Department, Department of Education). Behind the scenes, Groups - can offer an additional set of roles and permissions that ensure - quality and security when publishing data. This is especially - important for large sites that may have several working groups - publishing data to the same site. -

+

{t('publishers:description')}

- +
diff --git a/src/templates/search/index.jsx b/src/templates/search/index.jsx index b2fac0f..b02d95c 100644 --- a/src/templates/search/index.jsx +++ b/src/templates/search/index.jsx @@ -9,22 +9,22 @@ const SearchTemplate = ({path}) => { const location = useLocation(); return ( -
-

Datasets

- -
- - -
-
+
+

Datasets

+ +
+
+
+
+
); diff --git a/src/theme/index.scss b/src/theme/index.scss index ccc68b4..a64a6c5 100644 --- a/src/theme/index.scss +++ b/src/theme/index.scss @@ -1,31 +1,38 @@ +$theme-font-path: "~uswds/dist/fonts"; +$theme-image-path: "~uswds/dist/img"; +@import "~uswds/dist/scss/uswds"; + +@import "~@civicactions/data-catalog-components/dist/scss/index"; + + // Fonts and General css. -@import "./fonts/rubik-cufonfonts-webfont/style.css"; -@import "./styles/general.scss"; +// @import "./fonts/rubik-cufonfonts-webfont/style.css"; +// @import "./styles/general.scss"; -// Component styles. -@import "./styles/filedownload.scss"; -@import "./styles/iconlist.scss"; -@import "./styles/iconlistitem.scss"; -@import "./styles/menu.scss"; -@import "./styles/organization.scss"; -@import "./styles/publisherslist.scss"; -@import "./styles/resource.scss"; -@import "./styles/searchinput.scss"; -@import "./styles/searchlistitem.scss"; -@import "./styles/searchfacets.scss"; -@import "./styles/tags.scss"; -@import "./styles/table.scss"; -@import "./styles/topicwrapper.scss"; +// // Component styles. +// @import "./styles/filedownload.scss"; +// @import "./styles/iconlist.scss"; +// @import "./styles/iconlistitem.scss"; +// @import "./styles/menu.scss"; +// @import "./styles/organization.scss"; +// @import "./styles/publisherslist.scss"; +// @import "./styles/resource.scss"; +// @import "./styles/searchinput.scss"; +// @import "./styles/searchlistitem.scss"; +// @import "./styles/searchfacets.scss"; +// @import "./styles/tags.scss"; +// @import "./styles/table.scss"; +// @import "./styles/topicwrapper.scss"; -// Template styles. -@import "./styles/featureddatasets.scss"; -@import "./styles/dataset.scss"; -@import "./styles/datatable.scss"; -@import "./styles/header.scss"; -@import "./styles/hero.scss"; -@import "./styles/footer.scss"; -@import "./styles/navbar.scss"; -@import "./styles/blocks.scss"; -@import "./styles/announcement.scss"; -@import "./styles/searchcontent.scss"; -@import "./styles/searchsidebar.scss"; +// // Template styles. +// @import "./styles/featureddatasets.scss"; +// @import "./styles/dataset.scss"; +// @import "./styles/datatable.scss"; +// @import "./styles/header.scss"; +// @import "./styles/hero.scss"; +// @import "./styles/footer.scss"; +// @import "./styles/navbar.scss"; +// @import "./styles/blocks.scss"; +// @import "./styles/announcement.scss"; +// @import "./styles/searchcontent.scss"; +// @import "./styles/searchsidebar.scss";