diff --git a/package.json b/package.json
index c8a0c0a..7f515d6 100644
--- a/package.json
+++ b/package.json
@@ -9,10 +9,12 @@
"lint": "eslint --fix ./src/**/*.js"
},
"dependencies": {
+ "@smooth-ui/core-sc": "^7.0.4",
"@yarnpkg/pnpify": "^2.3.3",
"jquery": "^3.5.1",
"next": "^9.5.5",
"next-optimized-images": "^2.6.2",
+ "polished": "^4.0.3",
"preact": "^10.5.4",
"prop-types": "15.7.2",
"react": "^16.13.1",
@@ -20,6 +22,7 @@
"react-is": "^16.13.1",
"react-slick": "^0.27.11",
"react-spring": "^8.0.27",
+ "reakit": "^1.2.4",
"resolve": "^1.17.0",
"slick-carousel": "^1.8.1",
"styled-components": "^4.4.1",
diff --git a/src/components/Errors/Errors.js b/src/components/Errors/Errors.js
new file mode 100644
index 0000000..7e7c97b
--- /dev/null
+++ b/src/components/Errors/Errors.js
@@ -0,0 +1,79 @@
+import React, { useState } from 'react';
+import styled from 'styled-components';
+import { lighten } from 'polished';
+import Typography from '../Typography';
+
+const Headline = styled(Typography)`
+ line-height: 1.5rem;
+`;
+
+const Container = styled.div`
+ width: 28rem;
+ position: fixed;
+ bottom: 2rem;
+ left: 50%;
+ transform: translateX(-50%);
+ color: ${({ theme }) => theme.color.danger};
+ background: ${({ theme }) => lighten(0.53, theme.color.danger)};
+ border: 1px solid ${({ theme }) => lighten(0.45, theme.color.danger)};
+ padding: 2rem;
+ z-index: 1;
+ border-radius: .25rem;
+ font-size: 1rem;
+ line-height: 1.4rem;
+ box-shadow: 0 .5rem 1rem -.25rem rgba(0,0,0,.1);
+ text-align: left;
+`;
+
+const CloseButton = styled.span`
+ position: absolute;
+ top: 2rem;
+ right: 2rem;
+ cursor: pointer;
+ opacity: 1;
+ transition: opacity 200ms ease-out;
+
+ &:hover {
+ opacity: .6;
+ }
+`;
+
+const Title = styled(Headline)`
+
+`;
+
+const ErrorEl = styled.div`
+ padding-top: 1rem;
+ border-top: 1px solid ${({ theme }) => lighten(0.45, theme.color.danger)};
+
+ & > p {
+ margin-top: 0;
+ margin-bottom: 0.5rem;
+ }
+`;
+
+const getErrorTitle = (errors) => {
+ if (errors.length === 1) return 'An unexpected error has occurred';
+ return `${errors.length} unexpected errors have occurred`;
+};
+
+const Errors = ({ errors }) => {
+ const [isOpened, setIsOpened] = useState(true);
+ const onClose = () => setIsOpened(false);
+
+ return (errors.length > 0 && isOpened ? (
+
+ ✕
+ {getErrorTitle(errors)}
+ {errors.map((error) => (
+
+ {error.split('\n').map((errorLine) => (
+ {errorLine}
+ ))}
+
+ ))}
+
+ ) : null);
+};
+
+export default Errors;
diff --git a/src/components/Errors/index.js b/src/components/Errors/index.js
new file mode 100644
index 0000000..2776183
--- /dev/null
+++ b/src/components/Errors/index.js
@@ -0,0 +1,3 @@
+import Errors from './Errors';
+
+export default Errors;
diff --git a/src/lib/theme/dark/color.js b/src/lib/theme/dark/color.js
index 8a75a82..16ba17e 100644
--- a/src/lib/theme/dark/color.js
+++ b/src/lib/theme/dark/color.js
@@ -8,6 +8,7 @@ export default {
typoPrimary: '#fff',
typoSecondary: '#6F767D',
typoTertiary: '#77777c',
+ danger: '#ce1126',
typoAccent: 'rgb(143, 75, 0)',
};
diff --git a/src/lib/theme/light/color.js b/src/lib/theme/light/color.js
index d5e2263..f4b77eb 100644
--- a/src/lib/theme/light/color.js
+++ b/src/lib/theme/light/color.js
@@ -8,6 +8,7 @@ export default {
typoPrimary: '#252525',
typoSecondary: '#6F767D',
typoTertiary: '#77777c',
+ danger: '#ce1126',
typoAccent: 'rgb(143, 75, 0)',
};
diff --git a/src/pages/index.js b/src/pages/index.js
index b4697ec..794b41e 100644
--- a/src/pages/index.js
+++ b/src/pages/index.js
@@ -2,6 +2,7 @@
import React from 'react';
import styled, { ThemeProvider } from 'styled-components';
import { space } from 'styled-system';
+import Errors from '../components/Errors';
import Typography from '../components/Typography';
import OuterRow from '../components/Layout/OuterRow';
// import Feature from '../components/_project/home/Feature'
@@ -43,9 +44,10 @@ const ButtonWrapper = styled('div')`
`;
const Index = (props) => {
- const { contributors, photoUrls } = props;
+ const { contributors, photoUrls, errors } = props;
return (
+
US-Iran Relations
@@ -155,7 +157,9 @@ const Index = (props) => {
<>
-
+ {!errors && (
+
+ )}
>
@@ -164,22 +168,26 @@ const Index = (props) => {
};
export async function getStaticProps() {
- const res = await fetch(`${process.env.API_URL}/items/contributors`);
- const contributors = await res.json();
- const photoUrls = {};
- await Promise.all(contributors.data.map(async (contributor) => {
- const { photo } = contributor;
- const photoRes = photo
- ? await fetch(`${process.env.API_URL}/files/${photo}`)
- : await fetch(`${process.env.API_URL}/files/11`);
- const { data } = await photoRes.json();
- const photoUrl = `${process.env.API_URL}/assets/${data.private_hash}`;
- photoUrls[contributor.photo] = photoUrl;
- }));
-
- return {
- props: { contributors, photoUrls }, // will be passed to the page component as props
- };
+ const res = await fetch(`${process.env.API_URL}/items/contributors`)
+ .catch((err) => ({
+ error: err.message,
+ }));
+ if (!res.error) {
+ const contributors = await res.json();
+ const photoUrls = {};
+ await Promise.all(contributors.data.map(async (contributor) => {
+ const { photo } = contributor;
+ const photoRes = photo
+ ? await fetch(`${process.env.API_URL}/files/${photo}`)
+ : await fetch(`${process.env.API_URL}/files/11`);
+ const { data } = await photoRes.json();
+ const photoUrl = `${process.env.API_URL}/assets/${data.private_hash}`;
+ photoUrls[contributor.photo] = photoUrl;
+ }));
+ return {
+ props: { contributors, photoUrls },
+ };
+ } return { props: { errors: [res.error] } };
}
export default Index;
diff --git a/yarn.lock b/yarn.lock
index c0feff6..f09529b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1416,6 +1416,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.2.0":
+ version: 7.12.0
+ resolution: "@babel/runtime@npm:7.12.0"
+ dependencies:
+ regenerator-runtime: ^0.13.4
+ checksum: 22362076a3e957be517f8bf3e7891a4b160e8f516dd37b62aa7ffefa5b17cab35189965f694be69c073796a62040d1dbad6b4b26d8bd31f616d66545f6701b93
+ languageName: node
+ linkType: hard
+
"@babel/runtime@npm:^7.3.1":
version: 7.3.4
resolution: "@babel/runtime@npm:7.3.4"
@@ -1663,6 +1672,13 @@ __metadata:
languageName: node
linkType: hard
+"@popperjs/core@npm:^2.4.4":
+ version: 2.5.3
+ resolution: "@popperjs/core@npm:2.5.3"
+ checksum: 53a693e058732f6f38773ea3a9e498e9578b375e5352899eff63a9cb9906c54f141dc0b544a7789652303ce342be769e0d76420a8066f9ec973dda4086de2b55
+ languageName: node
+ linkType: hard
+
"@sindresorhus/is@npm:^3.1.1":
version: 3.1.2
resolution: "@sindresorhus/is@npm:3.1.2"
@@ -1670,6 +1686,22 @@ __metadata:
languageName: node
linkType: hard
+"@smooth-ui/core-sc@npm:^7.0.4":
+ version: 7.1.1
+ resolution: "@smooth-ui/core-sc@npm:7.1.1"
+ dependencies:
+ polished: ^2.3.3
+ prop-types: ^15.6.2
+ react-focus-lock: ^1.17.6
+ react-transition-group: ^2.5.2
+ peerDependencies:
+ react: ">=16.3.0"
+ react-dom: ">=16.3.0"
+ styled-components: ^4.0.0
+ checksum: 2aa09fe74ada1e2e3115796ab7b118d7623416c681877d1b3bbfb8f77dca266af2e9344eeb12915d333177c663978ad884d6861e3625f1a97630c4cac19aad97
+ languageName: node
+ linkType: hard
+
"@szmarczak/http-timer@npm:^4.0.5":
version: 4.0.5
resolution: "@szmarczak/http-timer@npm:4.0.5"
@@ -2747,6 +2779,13 @@ __metadata:
languageName: node
linkType: hard
+"body-scroll-lock@npm:^3.1.5":
+ version: 3.1.5
+ resolution: "body-scroll-lock@npm:3.1.5"
+ checksum: e8de58edc0fd7d483e3971045ff83fe6d722592d5153e9bfc9da2962a179a6522b432a4b35344bc8ae522eec080cc87301ce4ded4878f26254bf42a4f26d27ed
+ languageName: node
+ linkType: hard
+
"brace-expansion@npm:^1.1.7":
version: 1.1.11
resolution: "brace-expansion@npm:1.1.11"
@@ -3907,6 +3946,15 @@ __metadata:
languageName: node
linkType: hard
+"dom-helpers@npm:^3.4.0":
+ version: 3.4.0
+ resolution: "dom-helpers@npm:3.4.0"
+ dependencies:
+ "@babel/runtime": ^7.1.2
+ checksum: 7625598dbfef65a50801e194b88f277ab398dd92c27398280fd8d69294326f05d9b0588922560ba50e10d9fe5ee8096f90995d679b7db2b776afd579d495b962
+ languageName: node
+ linkType: hard
+
"dom-serializer@npm:1.0.1":
version: 1.0.1
resolution: "dom-serializer@npm:1.0.1"
@@ -4825,6 +4873,13 @@ __metadata:
languageName: node
linkType: hard
+"focus-lock@npm:^0.6.3":
+ version: 0.6.8
+ resolution: "focus-lock@npm:0.6.8"
+ checksum: 3fa9df85c3d31c30c9447cac1a7b6c3416ae2458af84a5dcd3997c63cff812e3749e026db430f85539631bd7fd820cfaf15d9d8a8ee0d0835313b568198c771e
+ languageName: node
+ linkType: hard
+
"for-in@npm:^1.0.2":
version: 1.0.2
resolution: "for-in@npm:1.0.2"
@@ -5292,6 +5347,7 @@ fsevents@~2.1.2:
version: 0.0.0-use.local
resolution: "hidden-perspectives-microsite@workspace:."
dependencies:
+ "@smooth-ui/core-sc": ^7.0.4
"@yarnpkg/pnpify": ^2.3.3
babel-plugin-styled-components: ^1.11.1
eslint: ^7.11.0
@@ -5304,6 +5360,7 @@ fsevents@~2.1.2:
jquery: ^3.5.1
next: ^9.5.5
next-optimized-images: ^2.6.2
+ polished: ^4.0.3
preact: ^10.5.4
prop-types: 15.7.2
react: ^16.13.1
@@ -5311,6 +5368,7 @@ fsevents@~2.1.2:
react-is: ^16.13.1
react-slick: ^0.27.11
react-spring: ^8.0.27
+ reakit: ^1.2.4
resolve: ^1.17.0
slick-carousel: ^1.8.1
styled-components: ^4.4.1
@@ -7662,6 +7720,24 @@ fsevents@~2.1.2:
languageName: node
linkType: hard
+"polished@npm:^2.3.3":
+ version: 2.3.3
+ resolution: "polished@npm:2.3.3"
+ dependencies:
+ "@babel/runtime": ^7.2.0
+ checksum: 2bd37216fc6c03a65841fa8264db26ea6ce6732141a24114cfcc0ebc0afb0bcabf21c2c9416da89dc16b4e0926b14d5696f053fbaf53769a769465d3cf5c10d3
+ languageName: node
+ linkType: hard
+
+"polished@npm:^4.0.3":
+ version: 4.0.3
+ resolution: "polished@npm:4.0.3"
+ dependencies:
+ "@babel/runtime": ^7.12.0
+ checksum: ae644280769a5ebd87101f7452a82233fb81e6ac824acffd90e470ce76098abfcfecf989a1ffb328aaa88804ed265f3308a861c6bf48611eecc69ac5767130da
+ languageName: node
+ linkType: hard
+
"posix-character-classes@npm:^0.1.0":
version: 0.1.1
resolution: "posix-character-classes@npm:0.1.1"
@@ -8015,6 +8091,17 @@ fsevents@~2.1.2:
languageName: node
linkType: hard
+"react-clientside-effect@npm:^1.2.0":
+ version: 1.2.2
+ resolution: "react-clientside-effect@npm:1.2.2"
+ dependencies:
+ "@babel/runtime": ^7.0.0
+ peerDependencies:
+ react: ^15.3.0 || ^16.0.0
+ checksum: 364329073a09955f8eef24247a3f38f13e0e4abf446cc011b53850cc197b6d1ec9932c1918970eef3cc0a01ec7a289ee68963fd7e37faf2aa9033c4c0d95dc72
+ languageName: node
+ linkType: hard
+
"react-dom@npm:^16.13.1":
version: 16.13.1
resolution: "react-dom@npm:16.13.1"
@@ -8029,6 +8116,20 @@ fsevents@~2.1.2:
languageName: node
linkType: hard
+"react-focus-lock@npm:^1.17.6":
+ version: 1.19.1
+ resolution: "react-focus-lock@npm:1.19.1"
+ dependencies:
+ "@babel/runtime": ^7.0.0
+ focus-lock: ^0.6.3
+ prop-types: ^15.6.2
+ react-clientside-effect: ^1.2.0
+ peerDependencies:
+ react: ^15.0.0 || ^16.0.0
+ checksum: e5b579035330c3893d14c95c2c2dc934d793bbc6f70b2c294634652928893e71ea4c8c8c710629b7b1972d65e30366d477fa0d1e793129d1e7334fd6820a8269
+ languageName: node
+ linkType: hard
+
"react-is@npm:16.13.1, react-is@npm:^16.13.1, react-is@npm:^16.6.0":
version: 16.13.1
resolution: "react-is@npm:16.13.1"
@@ -8043,6 +8144,13 @@ fsevents@~2.1.2:
languageName: node
linkType: hard
+"react-lifecycles-compat@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "react-lifecycles-compat@npm:3.0.4"
+ checksum: 82176a55ef7526414d770d5e07dc1d28b4c7f20281f22c6f53f3a98df9dbbb5d70c94bebee57b4ea8ccc2eee430b907ca7b564a42fbdd0ed21e7c43bfee35404
+ languageName: node
+ linkType: hard
+
"react-refresh@npm:0.8.3":
version: 0.8.3
resolution: "react-refresh@npm:0.8.3"
@@ -8079,6 +8187,21 @@ fsevents@~2.1.2:
languageName: node
linkType: hard
+"react-transition-group@npm:^2.5.2":
+ version: 2.9.0
+ resolution: "react-transition-group@npm:2.9.0"
+ dependencies:
+ dom-helpers: ^3.4.0
+ loose-envify: ^1.4.0
+ prop-types: ^15.6.2
+ react-lifecycles-compat: ^3.0.4
+ peerDependencies:
+ react: ">=15.0.0"
+ react-dom: ">=15.0.0"
+ checksum: eefed08c48a0d377b5fac3ac7fac54ed986d5dcdd4494f36075954c9d2d257072a9d18cc02c6d8e6698034722b1ff9419ad0c24ef068dea742edcff9f8ea4ba9
+ languageName: node
+ linkType: hard
+
"react@npm:^16.13.1":
version: 16.13.1
resolution: "react@npm:16.13.1"
@@ -8157,6 +8280,55 @@ fsevents@~2.1.2:
languageName: node
linkType: hard
+"reakit-system@npm:^0.14.5":
+ version: 0.14.5
+ resolution: "reakit-system@npm:0.14.5"
+ dependencies:
+ reakit-utils: ^0.14.4
+ peerDependencies:
+ react: ^16.8.0
+ react-dom: ^16.8.0
+ checksum: 84fee2cd780b89df161b6b110d3017585f4256ec92f18b9a590b8a6cbe556183826fff5b9d0d549af645b4d33399e68ed58884c5361161a56d5a76d4219cc719
+ languageName: node
+ linkType: hard
+
+"reakit-utils@npm:^0.14.4":
+ version: 0.14.4
+ resolution: "reakit-utils@npm:0.14.4"
+ peerDependencies:
+ react: ^16.8.0
+ react-dom: ^16.8.0
+ checksum: 7ee4aac3d40d3c5d97d0855e6214f3c525c6cfbc21d4fce28a97a6bca1b8cc4277f4d2cfe29275fc1763282e96d391e45d550dfe55b6f1a3ddf9ee94565a7268
+ languageName: node
+ linkType: hard
+
+"reakit-warning@npm:^0.5.5":
+ version: 0.5.5
+ resolution: "reakit-warning@npm:0.5.5"
+ dependencies:
+ reakit-utils: ^0.14.4
+ peerDependencies:
+ react: ^16.8.0
+ checksum: 80e8010114508608676805189bc035eebcb2ea71250361aac27824544c721e916fb9ee69382522e3b2f3c30f1ed0e2570647080512f348595d038a1d07c064f1
+ languageName: node
+ linkType: hard
+
+"reakit@npm:^1.2.4":
+ version: 1.2.5
+ resolution: "reakit@npm:1.2.5"
+ dependencies:
+ "@popperjs/core": ^2.4.4
+ body-scroll-lock: ^3.1.5
+ reakit-system: ^0.14.5
+ reakit-utils: ^0.14.4
+ reakit-warning: ^0.5.5
+ peerDependencies:
+ react: ^16.8.0
+ react-dom: ^16.8.0
+ checksum: 45a8c820cb14a6e37941b29ba6ab1887679669836443408adaec55ab868840728cc2d4f8d0a9dae5e682a093611aef71af0a1a7c153ccae761e4a76fbba4464d
+ languageName: node
+ linkType: hard
+
"regenerate-unicode-properties@npm:^8.2.0":
version: 8.2.0
resolution: "regenerate-unicode-properties@npm:8.2.0"