diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 6946232..f52bd5e 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -17,8 +17,6 @@ jobs: - name: yarn run: yarn --network-concurrency 1 - - name: lint:css - run: yarn lint:css - name: lint:js run: yarn lint:js - name: test @@ -26,4 +24,4 @@ jobs: env: CI: true - name: build - run: yarn build + run: CI=false yarn build diff --git a/.gitignore b/.gitignore index 974c32d..28ebdd6 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +# Local Netlify folder +.netlify diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 83f54bc..0000000 --- a/.prettierignore +++ /dev/null @@ -1,4 +0,0 @@ -/prettierrc.js -/eslintrc.js -/build -/node_modules \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index f6cc42b..0000000 --- a/.prettierrc.js +++ /dev/null @@ -1,51 +0,0 @@ -module.exports = { - // Include parentheses around a sole arrow function parameter - arrowParens: "avoid", - - // Controls the printing of spaces inside object literals - bracketSpacing: true, - - // Specify the end of line used by prettier - endOfLine: "auto", - - // Specify the global whitespace sensitivity for HTML files. - // Valid options: - // 'css' - Respect the default value of CSS display property. - // 'strict' - Whitespaces are considered sensitive. - // 'ignore' - Whitespaces are considered insensitive. - htmlWhitespaceSensitivity: "css", - - // If true, puts the `>` of a multi-line jsx element at the end of the last line instead of being alone on the next line - jsxBracketSameLine: false, - - // Use single quotes instead of double quotes in JSX - jsxSingleQuote: false, - - // Override the parser. You shouldn't have to change this setting. - parser: "babylon", - - // Fit code within this line limit - printWidth: 80, - - // (Markdown) wrap prose over multiple lines - proseWrap: "preserve", - - // Whether to add a semicolon at the end of every line - semi: true, - - // If true, will use single instead of double quotes - singleQuote: false, - - // Number of spaces it should use per tab - tabWidth: 2, - - // Controls the printing of trailing commas wherever possible. - // Valid options: - // 'none' - No trailing commas - // 'es5' - Trailing commas where valid in ES5 (objects, arrays, etc) - // 'all' - Trailing commas wherever possible (function arguments) - trailingComma: "none", - - // Indent lines with tabs - useTabs: false -}; diff --git a/.stylelintrc b/.stylelintrc deleted file mode 100644 index 1f83a29..0000000 --- a/.stylelintrc +++ /dev/null @@ -1,43 +0,0 @@ -{ - "extends": "stylelint-config-recommended", - "rules": { - "block-no-empty": null, - "no-empty-source": null, - "unit-disallowed-list": [ - "cm", - "mm", - "in", - "pt", - "pc", - "ch", - "vmin", - "vmax", - "ex" - ], - "max-empty-lines": 2, - "indentation": 2, - "max-nesting-depth": 3, - "font-family-no-missing-generic-family-keyword": null, - "rule-empty-line-before": [ - "always", - { - "ignore": ["after-comment", "first-nested"], - "severity": "warning" - } - ], - "at-rule-no-unknown": null, - "property-no-unknown": [ - true, - { - "ignoreProperties": ["composes"] - } - ], - "selector-pseudo-class-no-unknown": [ - true, - { - "ignorePseudoClasses": ["global"] - } - ] - }, - "ignoreFiles": "**/*.js" -} diff --git a/jsconfig.json b/jsconfig.json index c93dc26..7474bdc 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@/*":["src/*"] + "src/*":["src/*"] } } } \ No newline at end of file diff --git a/package.json b/package.json index c41eb93..7c6e103 100644 --- a/package.json +++ b/package.json @@ -3,42 +3,25 @@ "version": "0.1.0", "private": true, "dependencies": { - "crypto-js": "^3.3.0", + "crypto-js": "^4.1.1", "dcrtimejs": "https://github.com/tiagoalvesdulce/dcrtimejs", + "i18next": "^22.1.4", "js-file-download": "^0.4.12", - "pi-ui": "https://github.com/decred/pi-ui", "query-string": "^6.14.0", "react": "^16.14.0", "react-dom": "^16.14.0", "react-dropzone": "^10.2.2", - "react-router-dom": "^5.2.0", - "react-scripts": "^3.4.4" + "react-i18next": "^12.1.1", + "react-router-dom": "^5.2.0" }, "scripts": { "start": "REACT_APP_NETWORK=testnet HTTPS=true react-scripts start", "build": "react-scripts build", "build-testnet": "REACT_APP_NETWORK=testnet react-scripts build", - "test": "react-scripts test", + "test": "react-scripts test --passWithNoTests", "eject": "react-scripts eject", - "lint:css": "stylelint --fix 'src/**/*.css'", "lint:js": "eslint --fix --ext=.js,.jsx src" }, - "eslintConfig": { - "extends": "react-app" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "src/**/*.{js,jsx}": [ - "prettier --write", - "yarn lint:css", - "yarn lint:js", - "git add" - ] - }, "browserslist": [ ">0.2%", "not dead", @@ -46,6 +29,7 @@ "not op_mini all" ], "devDependencies": { + "react-scripts": "^3.4.4", "babel-eslint": "^10.1.0", "eslint": "^6.8.0", "eslint-config-prettier": "^6.15.0", @@ -55,12 +39,6 @@ "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-react": "^7.22.0", "eslint-plugin-react-hooks": "^1.7.0", - "husky": "^3.1.0", - "lint-staged": "^9.5.0", - "npm-run-all": "^4.1.5", - "prettier": "^1.19.1", - "stylelint": "^13.10.0", - "stylelint-config-recommended": "^3.0.0", - "typescript": "^3.9.9" + "react-error-overlay": "6.0.9" } } diff --git a/public/_redirects b/public/_redirects new file mode 100644 index 0000000..78f7f20 --- /dev/null +++ b/public/_redirects @@ -0,0 +1 @@ +/* /index.html 200 \ No newline at end of file diff --git a/public/assets/clippy.svg b/public/assets/clippy.svg deleted file mode 100644 index 6f6b80b..0000000 --- a/public/assets/clippy.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/assets/logo.svg b/public/assets/logo.svg deleted file mode 100644 index a36aa23..0000000 --- a/public/assets/logo.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/assets/source-sans-pro-v9-latin-regular.woff b/public/assets/source-sans-pro-v9-latin-regular.woff deleted file mode 100644 index dbdec39..0000000 Binary files a/public/assets/source-sans-pro-v9-latin-regular.woff and /dev/null differ diff --git a/public/favicon-small.ico b/public/favicon-small.ico new file mode 100644 index 0000000..a220787 Binary files /dev/null and b/public/favicon-small.ico differ diff --git a/public/favicon.ico b/public/favicon.ico index 5ecdd5e..1ca105b 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/fonts/inter/Inter-Black.woff b/public/fonts/inter/Inter-Black.woff new file mode 100644 index 0000000..a18593a Binary files /dev/null and b/public/fonts/inter/Inter-Black.woff differ diff --git a/public/fonts/inter/Inter-Black.woff2 b/public/fonts/inter/Inter-Black.woff2 new file mode 100644 index 0000000..68f64c9 Binary files /dev/null and b/public/fonts/inter/Inter-Black.woff2 differ diff --git a/public/fonts/inter/Inter-BlackItalic.woff b/public/fonts/inter/Inter-BlackItalic.woff new file mode 100644 index 0000000..b6b0194 Binary files /dev/null and b/public/fonts/inter/Inter-BlackItalic.woff differ diff --git a/public/fonts/inter/Inter-BlackItalic.woff2 b/public/fonts/inter/Inter-BlackItalic.woff2 new file mode 100644 index 0000000..1c9c7ca Binary files /dev/null and b/public/fonts/inter/Inter-BlackItalic.woff2 differ diff --git a/public/fonts/inter/Inter-Bold.woff b/public/fonts/inter/Inter-Bold.woff new file mode 100644 index 0000000..eaf3d4b Binary files /dev/null and b/public/fonts/inter/Inter-Bold.woff differ diff --git a/public/fonts/inter/Inter-Bold.woff2 b/public/fonts/inter/Inter-Bold.woff2 new file mode 100644 index 0000000..2846f29 Binary files /dev/null and b/public/fonts/inter/Inter-Bold.woff2 differ diff --git a/public/fonts/inter/Inter-BoldItalic.woff b/public/fonts/inter/Inter-BoldItalic.woff new file mode 100644 index 0000000..3275076 Binary files /dev/null and b/public/fonts/inter/Inter-BoldItalic.woff differ diff --git a/public/fonts/inter/Inter-BoldItalic.woff2 b/public/fonts/inter/Inter-BoldItalic.woff2 new file mode 100644 index 0000000..0b1fe8e Binary files /dev/null and b/public/fonts/inter/Inter-BoldItalic.woff2 differ diff --git a/public/fonts/inter/Inter-ExtraBold.woff b/public/fonts/inter/Inter-ExtraBold.woff new file mode 100644 index 0000000..c2c17ed Binary files /dev/null and b/public/fonts/inter/Inter-ExtraBold.woff differ diff --git a/public/fonts/inter/Inter-ExtraBold.woff2 b/public/fonts/inter/Inter-ExtraBold.woff2 new file mode 100644 index 0000000..c24c2bd Binary files /dev/null and b/public/fonts/inter/Inter-ExtraBold.woff2 differ diff --git a/public/fonts/inter/Inter-ExtraBoldItalic.woff b/public/fonts/inter/Inter-ExtraBoldItalic.woff new file mode 100644 index 0000000..c42f705 Binary files /dev/null and b/public/fonts/inter/Inter-ExtraBoldItalic.woff differ diff --git a/public/fonts/inter/Inter-ExtraBoldItalic.woff2 b/public/fonts/inter/Inter-ExtraBoldItalic.woff2 new file mode 100644 index 0000000..4a81dc7 Binary files /dev/null and b/public/fonts/inter/Inter-ExtraBoldItalic.woff2 differ diff --git a/public/fonts/inter/Inter-ExtraLight.woff b/public/fonts/inter/Inter-ExtraLight.woff new file mode 100644 index 0000000..d0de5f3 Binary files /dev/null and b/public/fonts/inter/Inter-ExtraLight.woff differ diff --git a/public/fonts/inter/Inter-ExtraLight.woff2 b/public/fonts/inter/Inter-ExtraLight.woff2 new file mode 100644 index 0000000..f2ea706 Binary files /dev/null and b/public/fonts/inter/Inter-ExtraLight.woff2 differ diff --git a/public/fonts/inter/Inter-ExtraLightItalic.woff b/public/fonts/inter/Inter-ExtraLightItalic.woff new file mode 100644 index 0000000..81f1a28 Binary files /dev/null and b/public/fonts/inter/Inter-ExtraLightItalic.woff differ diff --git a/public/fonts/inter/Inter-ExtraLightItalic.woff2 b/public/fonts/inter/Inter-ExtraLightItalic.woff2 new file mode 100644 index 0000000..9af717b Binary files /dev/null and b/public/fonts/inter/Inter-ExtraLightItalic.woff2 differ diff --git a/public/fonts/inter/Inter-Italic.woff b/public/fonts/inter/Inter-Italic.woff new file mode 100644 index 0000000..a806b38 Binary files /dev/null and b/public/fonts/inter/Inter-Italic.woff differ diff --git a/public/fonts/inter/Inter-Italic.woff2 b/public/fonts/inter/Inter-Italic.woff2 new file mode 100644 index 0000000..a619fc5 Binary files /dev/null and b/public/fonts/inter/Inter-Italic.woff2 differ diff --git a/public/fonts/inter/Inter-Light.woff b/public/fonts/inter/Inter-Light.woff new file mode 100644 index 0000000..c496464 Binary files /dev/null and b/public/fonts/inter/Inter-Light.woff differ diff --git a/public/fonts/inter/Inter-Light.woff2 b/public/fonts/inter/Inter-Light.woff2 new file mode 100644 index 0000000..bc4be66 Binary files /dev/null and b/public/fonts/inter/Inter-Light.woff2 differ diff --git a/public/fonts/inter/Inter-LightItalic.woff b/public/fonts/inter/Inter-LightItalic.woff new file mode 100644 index 0000000..f84a9de Binary files /dev/null and b/public/fonts/inter/Inter-LightItalic.woff differ diff --git a/public/fonts/inter/Inter-LightItalic.woff2 b/public/fonts/inter/Inter-LightItalic.woff2 new file mode 100644 index 0000000..842b2df Binary files /dev/null and b/public/fonts/inter/Inter-LightItalic.woff2 differ diff --git a/public/fonts/inter/Inter-Medium.woff b/public/fonts/inter/Inter-Medium.woff new file mode 100644 index 0000000..d546843 Binary files /dev/null and b/public/fonts/inter/Inter-Medium.woff differ diff --git a/public/fonts/inter/Inter-Medium.woff2 b/public/fonts/inter/Inter-Medium.woff2 new file mode 100644 index 0000000..f92498a Binary files /dev/null and b/public/fonts/inter/Inter-Medium.woff2 differ diff --git a/public/fonts/inter/Inter-MediumItalic.woff b/public/fonts/inter/Inter-MediumItalic.woff new file mode 100644 index 0000000..459a656 Binary files /dev/null and b/public/fonts/inter/Inter-MediumItalic.woff differ diff --git a/public/fonts/inter/Inter-MediumItalic.woff2 b/public/fonts/inter/Inter-MediumItalic.woff2 new file mode 100644 index 0000000..0e3019f Binary files /dev/null and b/public/fonts/inter/Inter-MediumItalic.woff2 differ diff --git a/public/fonts/inter/Inter-Regular.woff b/public/fonts/inter/Inter-Regular.woff new file mode 100644 index 0000000..62d3a61 Binary files /dev/null and b/public/fonts/inter/Inter-Regular.woff differ diff --git a/public/fonts/inter/Inter-Regular.woff2 b/public/fonts/inter/Inter-Regular.woff2 new file mode 100644 index 0000000..6c2b689 Binary files /dev/null and b/public/fonts/inter/Inter-Regular.woff2 differ diff --git a/public/fonts/inter/Inter-SemiBold.woff b/public/fonts/inter/Inter-SemiBold.woff new file mode 100644 index 0000000..a815f43 Binary files /dev/null and b/public/fonts/inter/Inter-SemiBold.woff differ diff --git a/public/fonts/inter/Inter-SemiBold.woff2 b/public/fonts/inter/Inter-SemiBold.woff2 new file mode 100644 index 0000000..611e90c Binary files /dev/null and b/public/fonts/inter/Inter-SemiBold.woff2 differ diff --git a/public/fonts/inter/Inter-SemiBoldItalic.woff b/public/fonts/inter/Inter-SemiBoldItalic.woff new file mode 100644 index 0000000..909e43a Binary files /dev/null and b/public/fonts/inter/Inter-SemiBoldItalic.woff differ diff --git a/public/fonts/inter/Inter-SemiBoldItalic.woff2 b/public/fonts/inter/Inter-SemiBoldItalic.woff2 new file mode 100644 index 0000000..545685b Binary files /dev/null and b/public/fonts/inter/Inter-SemiBoldItalic.woff2 differ diff --git a/public/fonts/inter/Inter-Thin.woff b/public/fonts/inter/Inter-Thin.woff new file mode 100644 index 0000000..62bc58c Binary files /dev/null and b/public/fonts/inter/Inter-Thin.woff differ diff --git a/public/fonts/inter/Inter-Thin.woff2 b/public/fonts/inter/Inter-Thin.woff2 new file mode 100644 index 0000000..abbc3a5 Binary files /dev/null and b/public/fonts/inter/Inter-Thin.woff2 differ diff --git a/public/fonts/inter/Inter-ThinItalic.woff b/public/fonts/inter/Inter-ThinItalic.woff new file mode 100644 index 0000000..700a7f0 Binary files /dev/null and b/public/fonts/inter/Inter-ThinItalic.woff differ diff --git a/public/fonts/inter/Inter-ThinItalic.woff2 b/public/fonts/inter/Inter-ThinItalic.woff2 new file mode 100644 index 0000000..ab0b200 Binary files /dev/null and b/public/fonts/inter/Inter-ThinItalic.woff2 differ diff --git a/public/fonts/inter/Inter-italic.var.woff2 b/public/fonts/inter/Inter-italic.var.woff2 new file mode 100644 index 0000000..b826d5a Binary files /dev/null and b/public/fonts/inter/Inter-italic.var.woff2 differ diff --git a/public/fonts/inter/Inter-roman.var.woff2 b/public/fonts/inter/Inter-roman.var.woff2 new file mode 100644 index 0000000..6a256a0 Binary files /dev/null and b/public/fonts/inter/Inter-roman.var.woff2 differ diff --git a/public/fonts/inter/Inter.var.woff2 b/public/fonts/inter/Inter.var.woff2 new file mode 100644 index 0000000..365eedc Binary files /dev/null and b/public/fonts/inter/Inter.var.woff2 differ diff --git a/public/icon-192.png b/public/icon-192.png new file mode 100644 index 0000000..47394a1 Binary files /dev/null and b/public/icon-192.png differ diff --git a/public/icon-512.png b/public/icon-512.png new file mode 100644 index 0000000..49dc7dd Binary files /dev/null and b/public/icon-512.png differ diff --git a/public/icons/icon-frontpage-discord.svg b/public/icons/icon-frontpage-discord.svg new file mode 100644 index 0000000..0f3fbb7 --- /dev/null +++ b/public/icons/icon-frontpage-discord.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/icon-frontpage-github.svg b/public/icons/icon-frontpage-github.svg new file mode 100644 index 0000000..b22a940 --- /dev/null +++ b/public/icons/icon-frontpage-github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/icon-frontpage-matrix.svg b/public/icons/icon-frontpage-matrix.svg new file mode 100644 index 0000000..6b68824 --- /dev/null +++ b/public/icons/icon-frontpage-matrix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/icon-frontpage-medium.svg b/public/icons/icon-frontpage-medium.svg new file mode 100644 index 0000000..8203c00 --- /dev/null +++ b/public/icons/icon-frontpage-medium.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/icon-frontpage-reddit.svg b/public/icons/icon-frontpage-reddit.svg new file mode 100644 index 0000000..250f775 --- /dev/null +++ b/public/icons/icon-frontpage-reddit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/icon-frontpage-telegram.svg b/public/icons/icon-frontpage-telegram.svg new file mode 100644 index 0000000..330edb6 --- /dev/null +++ b/public/icons/icon-frontpage-telegram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/icon-frontpage-twitter.svg b/public/icons/icon-frontpage-twitter.svg new file mode 100644 index 0000000..6b4c222 --- /dev/null +++ b/public/icons/icon-frontpage-twitter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/icon-frontpage-youtube.svg b/public/icons/icon-frontpage-youtube.svg new file mode 100644 index 0000000..bbca019 --- /dev/null +++ b/public/icons/icon-frontpage-youtube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/index.html b/public/index.html index bc1d58c..6e1e6eb 100644 --- a/public/index.html +++ b/public/index.html @@ -3,9 +3,9 @@ - - - + + + - Decred Timestamp Service + Timestamply
diff --git a/public/inter.css b/public/inter.css new file mode 100644 index 0000000..71a6b69 --- /dev/null +++ b/public/inter.css @@ -0,0 +1,228 @@ +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100; + font-display: swap; + src: + url("fonts/inter/Inter-Thin.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-Thin.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100; + font-display: swap; + src: + url("fonts/inter/Inter-ThinItalic.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-ThinItalic.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 200; + font-display: swap; + src: + url("fonts/inter/Inter-ExtraLight.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-ExtraLight.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 200; + font-display: swap; + src: + url("fonts/inter/Inter-ExtraLightItalic.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-ExtraLightItalic.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 300; + font-display: swap; + src: + url("fonts/inter/Inter-Light.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-Light.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 300; + font-display: swap; + src: + url("fonts/inter/Inter-LightItalic.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-LightItalic.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 400; + font-display: swap; + src: + url("fonts/inter/Inter-Regular.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-Regular.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 400; + font-display: swap; + src: + url("fonts/inter/Inter-Italic.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-Italic.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 500; + font-display: swap; + src: + url("fonts/inter/Inter-Medium.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-Medium.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 500; + font-display: swap; + src: + url("fonts/inter/Inter-MediumItalic.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-MediumItalic.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 600; + font-display: swap; + src: + url("fonts/inter/Inter-SemiBold.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-SemiBold.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 600; + font-display: swap; + src: + url("fonts/inter/Inter-SemiBoldItalic.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-SemiBoldItalic.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 700; + font-display: swap; + src: + url("fonts/inter/Inter-Bold.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-Bold.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 700; + font-display: swap; + src: + url("fonts/inter/Inter-BoldItalic.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-BoldItalic.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 800; + font-display: swap; + src: + url("fonts/inter/Inter-ExtraBold.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-ExtraBold.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 800; + font-display: swap; + src: + url("fonts/inter/Inter-ExtraBoldItalic.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-ExtraBoldItalic.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 900; + font-display: swap; + src: + url("fonts/inter/Inter-Black.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-Black.woff?v=3.19") format("woff"); +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 900; + font-display: swap; + src: + url("fonts/inter/Inter-BlackItalic.woff2?v=3.19") format("woff2"), + url("fonts/inter/Inter-BlackItalic.woff?v=3.19") format("woff"); +} + +/* ------------------------------------------------------- +Variable font. +Usage: + + html { font-family: 'Inter', sans-serif; } + @supports (font-variation-settings: normal) { + html { font-family: 'Inter var', sans-serif; } + } +*/ +@font-face { + font-family: "Inter var"; + font-weight: 100 900; + font-display: swap; + font-style: normal; + font-named-instance: "Regular"; + src: url("fonts/inter/Inter-roman.var.woff2?v=3.19") format("woff2"); +} + +@font-face { + font-family: "Inter var"; + font-weight: 100 900; + font-display: swap; + font-style: italic; + font-named-instance: "Italic"; + src: url("fonts/inter/Inter-italic.var.woff2?v=3.19") format("woff2"); +} + + +/* -------------------------------------------------------------------------- +[EXPERIMENTAL] Multi-axis, single variable font. + +Slant axis is not yet widely supported (as of February 2019) and thus this +multi-axis single variable font is opt-in rather than the default. + +When using this, you will probably need to set font-variation-settings +explicitly, e.g. + + * { font-variation-settings: "slnt" 0deg } + .italic { font-variation-settings: "slnt" 10deg } + +*/ +@font-face { + font-family: "Inter var experimental"; + font-weight: 100 900; + font-display: swap; + font-style: oblique 0deg 10deg; + src: url("fonts/inter/Inter.var.woff2?v=3.19") format("woff2"); +} diff --git a/public/ios-homescreen.png b/public/ios-homescreen.png new file mode 100644 index 0000000..f5d7f36 Binary files /dev/null and b/public/ios-homescreen.png differ diff --git a/public/logo-light.svg b/public/logo-light.svg new file mode 100644 index 0000000..d85c0a2 --- /dev/null +++ b/public/logo-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/manifest.json b/public/manifest.json index 8045e55..a302ec8 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,15 +1,12 @@ { - "short_name": "Timestamp", - "name": "Timestamp", + "short_name": "Timestamply", + "name": "Timestamply", "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - } + { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" }, + { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" } ], "start_url": ".", "display": "standalone", "theme_color": "#2970FF", - "background_color": "#fdfdfd" + "background_color": "#F7F7F9" } diff --git a/public/styles.css b/public/styles.css index 66e2539..617cc13 100644 --- a/public/styles.css +++ b/public/styles.css @@ -1,100 +1,181 @@ -@font-face { - font-family: "Source Sans Pro"; - src: url(assets/source-sans-pro-v9-latin-regular.woff); -} - :root { - /* pi-ui color variables */ - --color-white: #ffffff; - --color-primary: #2970ff; - --color-gray-dark: #3d5873; - --color-gray-lighter: #e6eaed; - --color-gray-lightest: #f3f5f6; - --color-gray-lightest2: #f9fafa; - --color-shadow-light: rgba(0, 0, 0, 0.2); - --text-heading-color: var(--color-gray-dark); - /* custom color variables */ - --color-red: red; + --blue: #2970FF; + --blue-darkest: #091440; + --white-lilac: #F7F7F9; + --white: #FFFFFF; + --shadow: rgba(0, 0, 0, 0.1); + --white-lavender: #DFE0E6; } html { - background-color: var(--color-gray-lightest); + background-color: var(--white-lilac); + font-size: 10px; +} + +h1 { + margin: 0; } body { margin: 0; - font-family: "Source Sans Pro"; + font-family: Inter; + color: var(--blue-darkest); +} + +.content { + display: flex; + flex-direction: column; + height: 100%; + min-height: 100vh; } .header { display: flex; - position: relative; - width: 100%; - height: 60px; justify-content: space-between; - align-items: center; - background-color: var(--color-gray-lightest2); + padding: 3rem; + background: var(--white); } -.logo { - padding-left: 30px; +.main { + padding: 3rem; + flex-grow: 1; } -.nojsMessage { - color: var(--color-red); - font-size: 13px; - margin-right: 20px; +.card { + box-shadow: 0px 0.4rem 1.6rem var(--shadow); + max-width: 50rem; + padding: 2rem; + margin: 2rem auto; + background: var(--white); + border-radius: 0.5rem; } -.body { +.title { + margin-bottom: 1rem; + font-weight: 400; + font-size: 2.1rem; +} + +.nav { + font-size: 1.5rem; display: flex; - justify-content: center; align-items: center; - flex-direction: column; - width: 100%; - margin-top: 30px; } -.card { - width: 540px; - background: var(--color-white) 0% 0% no-repeat padding-box; - box-shadow: 0px 4px 16px var(--color-shadow-light); - opacity: 1; - margin-bottom: 20px; - padding: 20px; +.nav > a { + text-decoration: none; + color: var(--blue-darkest); } -.title { - width: 540px; - height: 34px; - font-size: 27px; - color: var(--text-heading-color); +.nav > a:visited { + color: var(--blue-darkest); +} + +.form { + display: flex; } .digestInput { + border: 1px solid transparent; + border-radius: 0.5rem; + background: var(--white-lavender); + font-size: 1.5rem; + color: var(--blue-darkest); + font-weight: 500; + outline: none; + padding: 0.6rem 0.8rem; width: 100%; - margin-bottom: 20px; - background-color: transparent; - outline: 0; - border: 0; - width: 100%; - border-bottom: 0.1rem solid var(--color-gray-lighter); - font-size: 13px; - transition: all 0.25s; - line-height: 2rem; + box-sizing: border-box; + margin-right: 1rem; } .submitButton { - color: var(--color-white); - padding: 0.6rem 1rem; - border: 1px solid var(--color-primary); - border-radius: 0.5rem; - background-color: var(--color-primary); + background: var(--blue); + padding: 0.7rem 1.5rem; + border-radius: 1.5rem; + font-family: Inter; + font-weight: 500; + border: 0; cursor: pointer; + user-select: none; + color: var(--white); } -@media screen and (max-width: 650px){ - .card { - width: 80%; +.footer { + padding: 3.5rem 3.5rem 5.5rem 3.5rem; + background: var(--white); + font-size: 1.5rem; + flex-grow: 1; + } + + /* This is needed for the site to be usable on very small + screen sizes */ + @media screen and (max-width: 470px) { + .footer { + padding: 3.5rem 2rem 3.5rem 2rem; + } + } + + .container { + display: flex; + flex-wrap: wrap; + flex-direction: column-reverse; + margin: 0 auto; + } + + .column { + display: flex; + flex-direction: row; + flex-wrap: wrap; + width: 100%; + align-items: flex-start; + opacity: 0.55; + } + + .column > a { + margin: 0 1.6rem 0.3rem 0; + text-decoration: none; + color: var(--blue-darkest); + } + + .socialMedia { + display: flex; + width: 100%; + justify-content: space-between; + flex-wrap: wrap; + margin-bottom: 2rem; + color: var(--blue-darkest); + } + + @media screen and (min-width: 1000px) { + .container { + display: flex; + flex-wrap: wrap; + flex-direction: row; + width: 100%; + max-width: 100.4rem; + } + + .column { + display: flex; + flex-direction: column; + width: 25%; + align-items: flex-start; + justify-content: flex-start; + } + + .socialMedia { + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; + margin-bottom: 0; + } + + .column > a { + margin: 0 1.6rem 1.2rem 0; + } + + .socialMedia > a { + margin: 0 3.4rem 1.3rem 0; } -} \ No newline at end of file + } \ No newline at end of file diff --git a/src/.eslintrc.js b/src/.eslintrc.js index c292240..1cbcc0b 100644 --- a/src/.eslintrc.js +++ b/src/.eslintrc.js @@ -14,48 +14,12 @@ module.exports = { jsx: true } }, - extends: ["eslint:recommended", "prettier"], + extends: ["eslint:recommended", "react-app", "prettier"], rules: { - "linebreak-style": ["error", "unix"], - "jsx-quotes": ["error", "prefer-double"], - quotes: ["error", "double"], - semi: ["error", "always"], - "no-trailing-spaces": ["error"], - "no-console": ["off"], - "eol-last": ["error", "always"], - "no-alert": "error", - "no-eval": "error", - "no-implied-eval": "error", - "require-await": "error", - "array-bracket-newline": ["error", "consistent"], - "block-spacing": "error", - "brace-style": ["error", "1tbs", { allowSingleLine: true }], - "comma-dangle": ["error", "never"], - "comma-spacing": [ - "error", - { - before: false, - after: true - } - ], - "comma-style": ["error", "last"], - "computed-property-spacing": ["error", "never"], - "func-call-spacing": ["error", "never"], - "key-spacing": [ - "error", - { - beforeColon: false, - afterColon: true - } - ], - "no-lonely-if": "error", - "object-curly-spacing": ["error", "always"], - "no-var": "error", - "prefer-const": "error", - "arrow-spacing": "error", - "react/jsx-uses-vars": 1, - "react/jsx-uses-react": 1, - "react/jsx-no-target-blank": [2, { enforceDynamicLinks: "always" }] + quotes: 2, + semi: 2, + "comma-dangle": 2, + indent: ["error", 4] }, globals: { Uint8Array: true diff --git a/src/App.js b/src/App.js index d072774..1878f01 100644 --- a/src/App.js +++ b/src/App.js @@ -1,27 +1,34 @@ import React, { Suspense } from "react"; import { BrowserRouter as Router } from "react-router-dom"; -import { - defaultLightTheme, - ThemeProvider, - DEFAULT_LIGHT_THEME_NAME, - Spinner -} from "pi-ui"; import Routes from "./Routes"; +import ErrorBoundary from "./components/ErrorBoundary"; +import ThemeProvider from "./theme/themeProvider"; +import lightTheme from "./theme/lightTheme"; +import darkTheme from "./theme/darkTheme"; +import LoadingSkeleton from "./components/Loading"; +import ScrollToTop from "./components/ScrollToTop"; +import "./i18n"; const themes = { - [DEFAULT_LIGHT_THEME_NAME]: defaultLightTheme + "light": lightTheme, + "dark": darkTheme }; const App = () => { - return ( - - - }> - - - - - ); + const theme = localStorage.getItem("theme"); + return ( + + + + + }> + + + + + + + ); }; export default App; diff --git a/src/App.test.js b/src/App.test.js deleted file mode 100644 index 23c181f..0000000 --- a/src/App.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from "react"; -import ReactDOM from "react-dom"; -import App from "./App"; - -it("renders without crashing", () => { - const div = document.createElement("div"); - ReactDOM.render(, div); - ReactDOM.unmountComponentAtNode(div); -}); diff --git a/src/Routes.jsx b/src/Routes.jsx index fd67771..c3bdefb 100644 --- a/src/Routes.jsx +++ b/src/Routes.jsx @@ -3,12 +3,18 @@ import { Switch, Route } from "react-router-dom"; const TimestampPage = lazy(() => import("./pages/Timestamp")); const ResultsPage = lazy(() => import("./pages/Results")); +const VerifyPage = lazy(() => import("./pages/Verify")); +const NotFoundPage = lazy(() => import("./pages/404")); const Routes = () => ( - - - - + + + + + + + + ); export default Routes; diff --git a/src/assets/anchored_icon.svg b/src/assets/anchored_icon.svg deleted file mode 100644 index 8783298..0000000 --- a/src/assets/anchored_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/assets/background/background-dark.svg b/src/assets/background/background-dark.svg new file mode 100644 index 0000000..551c909 --- /dev/null +++ b/src/assets/background/background-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/background/background-light.svg b/src/assets/background/background-light.svg new file mode 100644 index 0000000..f6dc863 --- /dev/null +++ b/src/assets/background/background-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/copy_icon.svg b/src/assets/copy_icon.svg deleted file mode 100644 index ae883bf..0000000 --- a/src/assets/copy_icon.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/assets/delete_icon.svg b/src/assets/delete_icon.svg deleted file mode 100644 index 0c7e7ce..0000000 --- a/src/assets/delete_icon.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/assets/download_icon.svg b/src/assets/download_icon.svg deleted file mode 100644 index a15ea91..0000000 --- a/src/assets/download_icon.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/assets/file_icon.svg b/src/assets/file_icon.svg deleted file mode 100644 index 2663dac..0000000 --- a/src/assets/file_icon.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/src/assets/fonts/inter/Inter-Black.woff b/src/assets/fonts/inter/Inter-Black.woff new file mode 100644 index 0000000..a18593a Binary files /dev/null and b/src/assets/fonts/inter/Inter-Black.woff differ diff --git a/src/assets/fonts/inter/Inter-Black.woff2 b/src/assets/fonts/inter/Inter-Black.woff2 new file mode 100644 index 0000000..68f64c9 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Black.woff2 differ diff --git a/src/assets/fonts/inter/Inter-BlackItalic.woff b/src/assets/fonts/inter/Inter-BlackItalic.woff new file mode 100644 index 0000000..b6b0194 Binary files /dev/null and b/src/assets/fonts/inter/Inter-BlackItalic.woff differ diff --git a/src/assets/fonts/inter/Inter-BlackItalic.woff2 b/src/assets/fonts/inter/Inter-BlackItalic.woff2 new file mode 100644 index 0000000..1c9c7ca Binary files /dev/null and b/src/assets/fonts/inter/Inter-BlackItalic.woff2 differ diff --git a/src/assets/fonts/inter/Inter-Bold.woff b/src/assets/fonts/inter/Inter-Bold.woff new file mode 100644 index 0000000..eaf3d4b Binary files /dev/null and b/src/assets/fonts/inter/Inter-Bold.woff differ diff --git a/src/assets/fonts/inter/Inter-Bold.woff2 b/src/assets/fonts/inter/Inter-Bold.woff2 new file mode 100644 index 0000000..2846f29 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Bold.woff2 differ diff --git a/src/assets/fonts/inter/Inter-BoldItalic.woff b/src/assets/fonts/inter/Inter-BoldItalic.woff new file mode 100644 index 0000000..3275076 Binary files /dev/null and b/src/assets/fonts/inter/Inter-BoldItalic.woff differ diff --git a/src/assets/fonts/inter/Inter-BoldItalic.woff2 b/src/assets/fonts/inter/Inter-BoldItalic.woff2 new file mode 100644 index 0000000..0b1fe8e Binary files /dev/null and b/src/assets/fonts/inter/Inter-BoldItalic.woff2 differ diff --git a/src/assets/fonts/inter/Inter-ExtraBold.woff b/src/assets/fonts/inter/Inter-ExtraBold.woff new file mode 100644 index 0000000..c2c17ed Binary files /dev/null and b/src/assets/fonts/inter/Inter-ExtraBold.woff differ diff --git a/src/assets/fonts/inter/Inter-ExtraBold.woff2 b/src/assets/fonts/inter/Inter-ExtraBold.woff2 new file mode 100644 index 0000000..c24c2bd Binary files /dev/null and b/src/assets/fonts/inter/Inter-ExtraBold.woff2 differ diff --git a/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff b/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff new file mode 100644 index 0000000..c42f705 Binary files /dev/null and b/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff differ diff --git a/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff2 b/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff2 new file mode 100644 index 0000000..4a81dc7 Binary files /dev/null and b/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff2 differ diff --git a/src/assets/fonts/inter/Inter-ExtraLight.woff b/src/assets/fonts/inter/Inter-ExtraLight.woff new file mode 100644 index 0000000..d0de5f3 Binary files /dev/null and b/src/assets/fonts/inter/Inter-ExtraLight.woff differ diff --git a/src/assets/fonts/inter/Inter-ExtraLight.woff2 b/src/assets/fonts/inter/Inter-ExtraLight.woff2 new file mode 100644 index 0000000..f2ea706 Binary files /dev/null and b/src/assets/fonts/inter/Inter-ExtraLight.woff2 differ diff --git a/src/assets/fonts/inter/Inter-ExtraLightItalic.woff b/src/assets/fonts/inter/Inter-ExtraLightItalic.woff new file mode 100644 index 0000000..81f1a28 Binary files /dev/null and b/src/assets/fonts/inter/Inter-ExtraLightItalic.woff differ diff --git a/src/assets/fonts/inter/Inter-ExtraLightItalic.woff2 b/src/assets/fonts/inter/Inter-ExtraLightItalic.woff2 new file mode 100644 index 0000000..9af717b Binary files /dev/null and b/src/assets/fonts/inter/Inter-ExtraLightItalic.woff2 differ diff --git a/src/assets/fonts/inter/Inter-Italic.woff b/src/assets/fonts/inter/Inter-Italic.woff new file mode 100644 index 0000000..a806b38 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Italic.woff differ diff --git a/src/assets/fonts/inter/Inter-Italic.woff2 b/src/assets/fonts/inter/Inter-Italic.woff2 new file mode 100644 index 0000000..a619fc5 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Italic.woff2 differ diff --git a/src/assets/fonts/inter/Inter-Light.woff b/src/assets/fonts/inter/Inter-Light.woff new file mode 100644 index 0000000..c496464 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Light.woff differ diff --git a/src/assets/fonts/inter/Inter-Light.woff2 b/src/assets/fonts/inter/Inter-Light.woff2 new file mode 100644 index 0000000..bc4be66 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Light.woff2 differ diff --git a/src/assets/fonts/inter/Inter-LightItalic.woff b/src/assets/fonts/inter/Inter-LightItalic.woff new file mode 100644 index 0000000..f84a9de Binary files /dev/null and b/src/assets/fonts/inter/Inter-LightItalic.woff differ diff --git a/src/assets/fonts/inter/Inter-LightItalic.woff2 b/src/assets/fonts/inter/Inter-LightItalic.woff2 new file mode 100644 index 0000000..842b2df Binary files /dev/null and b/src/assets/fonts/inter/Inter-LightItalic.woff2 differ diff --git a/src/assets/fonts/inter/Inter-Medium.woff b/src/assets/fonts/inter/Inter-Medium.woff new file mode 100644 index 0000000..d546843 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Medium.woff differ diff --git a/src/assets/fonts/inter/Inter-Medium.woff2 b/src/assets/fonts/inter/Inter-Medium.woff2 new file mode 100644 index 0000000..f92498a Binary files /dev/null and b/src/assets/fonts/inter/Inter-Medium.woff2 differ diff --git a/src/assets/fonts/inter/Inter-MediumItalic.woff b/src/assets/fonts/inter/Inter-MediumItalic.woff new file mode 100644 index 0000000..459a656 Binary files /dev/null and b/src/assets/fonts/inter/Inter-MediumItalic.woff differ diff --git a/src/assets/fonts/inter/Inter-MediumItalic.woff2 b/src/assets/fonts/inter/Inter-MediumItalic.woff2 new file mode 100644 index 0000000..0e3019f Binary files /dev/null and b/src/assets/fonts/inter/Inter-MediumItalic.woff2 differ diff --git a/src/assets/fonts/inter/Inter-Regular.woff b/src/assets/fonts/inter/Inter-Regular.woff new file mode 100644 index 0000000..62d3a61 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Regular.woff differ diff --git a/src/assets/fonts/inter/Inter-Regular.woff2 b/src/assets/fonts/inter/Inter-Regular.woff2 new file mode 100644 index 0000000..6c2b689 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Regular.woff2 differ diff --git a/src/assets/fonts/inter/Inter-SemiBold.woff b/src/assets/fonts/inter/Inter-SemiBold.woff new file mode 100644 index 0000000..a815f43 Binary files /dev/null and b/src/assets/fonts/inter/Inter-SemiBold.woff differ diff --git a/src/assets/fonts/inter/Inter-SemiBold.woff2 b/src/assets/fonts/inter/Inter-SemiBold.woff2 new file mode 100644 index 0000000..611e90c Binary files /dev/null and b/src/assets/fonts/inter/Inter-SemiBold.woff2 differ diff --git a/src/assets/fonts/inter/Inter-SemiBoldItalic.woff b/src/assets/fonts/inter/Inter-SemiBoldItalic.woff new file mode 100644 index 0000000..909e43a Binary files /dev/null and b/src/assets/fonts/inter/Inter-SemiBoldItalic.woff differ diff --git a/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 b/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 new file mode 100644 index 0000000..545685b Binary files /dev/null and b/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 differ diff --git a/src/assets/fonts/inter/Inter-Thin.woff b/src/assets/fonts/inter/Inter-Thin.woff new file mode 100644 index 0000000..62bc58c Binary files /dev/null and b/src/assets/fonts/inter/Inter-Thin.woff differ diff --git a/src/assets/fonts/inter/Inter-Thin.woff2 b/src/assets/fonts/inter/Inter-Thin.woff2 new file mode 100644 index 0000000..abbc3a5 Binary files /dev/null and b/src/assets/fonts/inter/Inter-Thin.woff2 differ diff --git a/src/assets/fonts/inter/Inter-ThinItalic.woff b/src/assets/fonts/inter/Inter-ThinItalic.woff new file mode 100644 index 0000000..700a7f0 Binary files /dev/null and b/src/assets/fonts/inter/Inter-ThinItalic.woff differ diff --git a/src/assets/fonts/inter/Inter-ThinItalic.woff2 b/src/assets/fonts/inter/Inter-ThinItalic.woff2 new file mode 100644 index 0000000..ab0b200 Binary files /dev/null and b/src/assets/fonts/inter/Inter-ThinItalic.woff2 differ diff --git a/src/assets/fonts/inter/Inter-italic.var.woff2 b/src/assets/fonts/inter/Inter-italic.var.woff2 new file mode 100644 index 0000000..b826d5a Binary files /dev/null and b/src/assets/fonts/inter/Inter-italic.var.woff2 differ diff --git a/src/assets/fonts/inter/Inter-roman.var.woff2 b/src/assets/fonts/inter/Inter-roman.var.woff2 new file mode 100644 index 0000000..6a256a0 Binary files /dev/null and b/src/assets/fonts/inter/Inter-roman.var.woff2 differ diff --git a/src/assets/fonts/inter/Inter.var.woff2 b/src/assets/fonts/inter/Inter.var.woff2 new file mode 100644 index 0000000..365eedc Binary files /dev/null and b/src/assets/fonts/inter/Inter.var.woff2 differ diff --git a/src/assets/hash_icon.svg b/src/assets/hash_icon.svg deleted file mode 100644 index 589235f..0000000 --- a/src/assets/hash_icon.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/assets/icons/close-menu-dark.svg b/src/assets/icons/close-menu-dark.svg new file mode 100644 index 0000000..4bf9cba --- /dev/null +++ b/src/assets/icons/close-menu-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/close-menu-light.svg b/src/assets/icons/close-menu-light.svg new file mode 100644 index 0000000..f355422 --- /dev/null +++ b/src/assets/icons/close-menu-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/color-mode-dark.svg b/src/assets/icons/color-mode-dark.svg new file mode 100644 index 0000000..be7a58c --- /dev/null +++ b/src/assets/icons/color-mode-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/color-mode-light.svg b/src/assets/icons/color-mode-light.svg new file mode 100644 index 0000000..4839bc7 --- /dev/null +++ b/src/assets/icons/color-mode-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/copy-to-clipboard.svg b/src/assets/icons/copy-to-clipboard.svg new file mode 100644 index 0000000..2930bec --- /dev/null +++ b/src/assets/icons/copy-to-clipboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/error404-dark.svg b/src/assets/icons/error404-dark.svg new file mode 100644 index 0000000..2715c99 --- /dev/null +++ b/src/assets/icons/error404-dark.svg @@ -0,0 +1 @@ +404Page not found404Page not found \ No newline at end of file diff --git a/src/assets/icons/error404-light.svg b/src/assets/icons/error404-light.svg new file mode 100644 index 0000000..a4b06e1 --- /dev/null +++ b/src/assets/icons/error404-light.svg @@ -0,0 +1 @@ +404Page not found404Page not found \ No newline at end of file diff --git a/src/assets/icons/goback-button-arrow.svg b/src/assets/icons/goback-button-arrow.svg new file mode 100644 index 0000000..9a0d9d1 --- /dev/null +++ b/src/assets/icons/goback-button-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/hash-search-dark.svg b/src/assets/icons/hash-search-dark.svg new file mode 100644 index 0000000..3223391 --- /dev/null +++ b/src/assets/icons/hash-search-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/hash-search-light.svg b/src/assets/icons/hash-search-light.svg new file mode 100644 index 0000000..b045839 --- /dev/null +++ b/src/assets/icons/hash-search-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/icon-frontpage-discord.svg b/src/assets/icons/icon-frontpage-discord.svg new file mode 100644 index 0000000..3d1b4bb --- /dev/null +++ b/src/assets/icons/icon-frontpage-discord.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/icon-frontpage-github.svg b/src/assets/icons/icon-frontpage-github.svg new file mode 100644 index 0000000..364ed40 --- /dev/null +++ b/src/assets/icons/icon-frontpage-github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/icon-frontpage-matrix.svg b/src/assets/icons/icon-frontpage-matrix.svg new file mode 100644 index 0000000..795b3aa --- /dev/null +++ b/src/assets/icons/icon-frontpage-matrix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/icon-frontpage-medium.svg b/src/assets/icons/icon-frontpage-medium.svg new file mode 100644 index 0000000..8ef4f1d --- /dev/null +++ b/src/assets/icons/icon-frontpage-medium.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/icon-frontpage-reddit.svg b/src/assets/icons/icon-frontpage-reddit.svg new file mode 100644 index 0000000..cb628c1 --- /dev/null +++ b/src/assets/icons/icon-frontpage-reddit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/icon-frontpage-telegram.svg b/src/assets/icons/icon-frontpage-telegram.svg new file mode 100644 index 0000000..b3b6b6b --- /dev/null +++ b/src/assets/icons/icon-frontpage-telegram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/icon-frontpage-twitter.svg b/src/assets/icons/icon-frontpage-twitter.svg new file mode 100644 index 0000000..f6f8bc9 --- /dev/null +++ b/src/assets/icons/icon-frontpage-twitter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/icon-frontpage-youtube.svg b/src/assets/icons/icon-frontpage-youtube.svg new file mode 100644 index 0000000..027713d --- /dev/null +++ b/src/assets/icons/icon-frontpage-youtube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/logo-dark.svg b/src/assets/icons/logo-dark.svg new file mode 100644 index 0000000..c498dcb --- /dev/null +++ b/src/assets/icons/logo-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/logo-light.svg b/src/assets/icons/logo-light.svg new file mode 100644 index 0000000..d85c0a2 --- /dev/null +++ b/src/assets/icons/logo-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/not-found-dark.svg b/src/assets/icons/not-found-dark.svg new file mode 100644 index 0000000..0f49bcc --- /dev/null +++ b/src/assets/icons/not-found-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/not-found-light.svg b/src/assets/icons/not-found-light.svg new file mode 100644 index 0000000..a0cd81f --- /dev/null +++ b/src/assets/icons/not-found-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/notice-close-dark.svg b/src/assets/icons/notice-close-dark.svg new file mode 100644 index 0000000..0403e96 --- /dev/null +++ b/src/assets/icons/notice-close-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/notice-close-light.svg b/src/assets/icons/notice-close-light.svg new file mode 100644 index 0000000..901df27 --- /dev/null +++ b/src/assets/icons/notice-close-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/open-menu-dark.svg b/src/assets/icons/open-menu-dark.svg new file mode 100644 index 0000000..cd76e28 --- /dev/null +++ b/src/assets/icons/open-menu-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/open-menu-light.svg b/src/assets/icons/open-menu-light.svg new file mode 100644 index 0000000..1d292f2 --- /dev/null +++ b/src/assets/icons/open-menu-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/pending-dark.svg b/src/assets/icons/pending-dark.svg new file mode 100644 index 0000000..1a06926 --- /dev/null +++ b/src/assets/icons/pending-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/pending-light.svg b/src/assets/icons/pending-light.svg new file mode 100644 index 0000000..02a7013 --- /dev/null +++ b/src/assets/icons/pending-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/pending.svg b/src/assets/icons/pending.svg new file mode 100644 index 0000000..87c571b --- /dev/null +++ b/src/assets/icons/pending.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/timestamped-dark.svg b/src/assets/icons/timestamped-dark.svg new file mode 100644 index 0000000..b48aef1 --- /dev/null +++ b/src/assets/icons/timestamped-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/timestamped-light.svg b/src/assets/icons/timestamped-light.svg new file mode 100644 index 0000000..052821f --- /dev/null +++ b/src/assets/icons/timestamped-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/tooltip-hover.svg b/src/assets/icons/tooltip-hover.svg new file mode 100644 index 0000000..e7ee0b4 --- /dev/null +++ b/src/assets/icons/tooltip-hover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/tooltip.svg b/src/assets/icons/tooltip.svg new file mode 100644 index 0000000..b33588c --- /dev/null +++ b/src/assets/icons/tooltip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/waiting-for-anchoring-dark.svg b/src/assets/icons/waiting-for-anchoring-dark.svg new file mode 100644 index 0000000..b8a6e6f --- /dev/null +++ b/src/assets/icons/waiting-for-anchoring-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/waiting-for-anchoring-light.svg b/src/assets/icons/waiting-for-anchoring-light.svg new file mode 100644 index 0000000..a22508f --- /dev/null +++ b/src/assets/icons/waiting-for-anchoring-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/logo.svg b/src/assets/logo.svg deleted file mode 100644 index a36aa23..0000000 --- a/src/assets/logo.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/Button/Button.jsx b/src/components/Button/Button.jsx new file mode 100644 index 0000000..ba0baaf --- /dev/null +++ b/src/components/Button/Button.jsx @@ -0,0 +1,30 @@ +import React from "react"; +import styles from "./Button.module.css"; +import cls from "src/helpers/cls"; + +const Button = ({type = "button", text, amount, handleClick, className, Icon, kind = "primary"}) => { + let buttonClass = null; + switch(kind) { + case "primary": + buttonClass = styles.buttonPrimary; + break; + case "secondary": + buttonClass = styles.buttonSecondary; + break; + case "tertiary": + buttonClass = styles.buttonTertiary; + break; + case "disabled": + buttonClass = styles.buttonDisabled; + break; + default: + throw new Error("Invalid kind"); + } + return ( + + ); +}; + +export default Button; \ No newline at end of file diff --git a/src/components/Button/Button.module.css b/src/components/Button/Button.module.css new file mode 100644 index 0000000..a98c38c --- /dev/null +++ b/src/components/Button/Button.module.css @@ -0,0 +1,47 @@ +.button { + composes: button from global; + padding: 0.7rem 1.5rem; + border-radius: 1.5rem; +} + +.buttonWithIcon { + padding: 0.7rem 1.5rem 0.7rem 0.9rem; +} + +.buttonDisabled { + composes: button; + background: var(--button-disabled-bg-color); + color: var(--button-disabled-color); + cursor: not-allowed; +} + +.buttonPrimary { + composes: button; + background: var(--button-primary-bg-color); + color: var(--button-primary-color); +} + +.buttonPrimary:hover { + background: var(--button-primary-bg-hover-color); +} + +.buttonSecondary { + composes: button; + background: var(--button-secondary-bg-color); + color: var(--button-secondary-color); +} + +.buttonSecondary:hover { + background: var(--button-secondary-bg-hover-color); +} + +.buttonTertiary { + composes: button; + background: transparent; + color: var(--button-tertiary-color); + border: 0.1rem solid var(--button-tertiary-border-color); +} + +.buttonTertiary:hover { + border: 0.1rem solid var(--button-tertiary-border-hover-color); +} \ No newline at end of file diff --git a/src/components/Button/index.js b/src/components/Button/index.js new file mode 100644 index 0000000..c4719be --- /dev/null +++ b/src/components/Button/index.js @@ -0,0 +1 @@ +export { default } from "./Button"; diff --git a/src/components/ButtonIcon/ButtonIcon.jsx b/src/components/ButtonIcon/ButtonIcon.jsx new file mode 100644 index 0000000..ca79936 --- /dev/null +++ b/src/components/ButtonIcon/ButtonIcon.jsx @@ -0,0 +1,12 @@ +import React from "react"; +import styles from "./ButtonIcon.module.css"; + +const ButtonIcon = ({Icon, handleClick, color}) => { + return ( + + ); +}; + +export default ButtonIcon; \ No newline at end of file diff --git a/src/components/ButtonIcon/ButtonIcon.module.css b/src/components/ButtonIcon/ButtonIcon.module.css new file mode 100644 index 0000000..783d8db --- /dev/null +++ b/src/components/ButtonIcon/ButtonIcon.module.css @@ -0,0 +1,14 @@ +.buttonIcon { + composes: button from global; + border-radius: 0.5rem; + border: 0; +} + +.buttonIcon:hover { + /* + Important is required because the color is set inline. + The only way we can overwrite it is using !important. + */ + color: var(--button-icon-hover-color) !important; + background: var(--button-icon-hover-bg-color); +} diff --git a/src/components/ButtonIcon/index.js b/src/components/ButtonIcon/index.js new file mode 100644 index 0000000..e8dfe5a --- /dev/null +++ b/src/components/ButtonIcon/index.js @@ -0,0 +1 @@ +export { default } from "./ButtonIcon"; \ No newline at end of file diff --git a/src/components/Checkbox/Checkbox.jsx b/src/components/Checkbox/Checkbox.jsx new file mode 100644 index 0000000..0dd2907 --- /dev/null +++ b/src/components/Checkbox/Checkbox.jsx @@ -0,0 +1,11 @@ +import React from "react"; +import ButtonIcon from "src/components/ButtonIcon"; +import CheckboxIcon from "src/components/CheckboxIcon"; + +const Checkbox = ({checked, handleClick}) => { + return ( + } handleClick={handleClick} color={"var(--checkbox-color)"}/> + ); +}; + +export default Checkbox; \ No newline at end of file diff --git a/src/components/Checkbox/index.js b/src/components/Checkbox/index.js new file mode 100644 index 0000000..75ef52e --- /dev/null +++ b/src/components/Checkbox/index.js @@ -0,0 +1 @@ +export { default } from "./Checkbox"; \ No newline at end of file diff --git a/src/components/CheckboxIcon/CheckboxIcon.jsx b/src/components/CheckboxIcon/CheckboxIcon.jsx new file mode 100644 index 0000000..0bfa155 --- /dev/null +++ b/src/components/CheckboxIcon/CheckboxIcon.jsx @@ -0,0 +1,21 @@ +import React from "react"; +import styles from "./CheckboxIcon.module.css"; + +const CheckboxIcon = ({checked}) => { + return ( + + + + + + + + + + + + ); +}; + +export default CheckboxIcon; + diff --git a/src/components/CheckboxIcon/CheckboxIcon.module.css b/src/components/CheckboxIcon/CheckboxIcon.module.css new file mode 100644 index 0000000..a5b3bd7 --- /dev/null +++ b/src/components/CheckboxIcon/CheckboxIcon.module.css @@ -0,0 +1,24 @@ +.checkboxWrapper { + fill: none; +} + +.checkboxCheck { + fill: var(--checkbox-check-color); +} + +.checkboxCheckNone { + fill: none; +} + +.checkboxSquare, .checkboxFiller1 { + fill: none; +} + +.checkboxSquare { + stroke: currentColor; + stroke-miterlimit: 10; +} + +.checkboxFiller2 { + stroke:none; +} \ No newline at end of file diff --git a/src/components/CheckboxIcon/index.js b/src/components/CheckboxIcon/index.js new file mode 100644 index 0000000..373d0b7 --- /dev/null +++ b/src/components/CheckboxIcon/index.js @@ -0,0 +1 @@ +export { default } from "./CheckboxIcon"; \ No newline at end of file diff --git a/src/components/Copy/Copy.jsx b/src/components/Copy/Copy.jsx new file mode 100644 index 0000000..9c8c2ed --- /dev/null +++ b/src/components/Copy/Copy.jsx @@ -0,0 +1,16 @@ +import React from "react"; +import Tooltip from "src/components/Tooltip"; +import ButtonIcon from "src/components/ButtonIcon"; +import {ReactComponent as CopyIcon} from "../../assets/icons/copy-to-clipboard.svg"; + +const copyToClipboard = (text) => { + navigator.clipboard.writeText(text); +}; + +const Copy = ({text}) => { + return ( + } handleClick={() => copyToClipboard(text)} color={"var(--copy-to-clipboard-color)"}/>} tooltipText="Copied!" tooltipHover={false} tooltipTextStyle={{width: "52px", left: "calc(50% - 26px)"}} /> + ); +}; + +export default Copy; \ No newline at end of file diff --git a/src/components/Copy/index.js b/src/components/Copy/index.js new file mode 100644 index 0000000..3edd5a9 --- /dev/null +++ b/src/components/Copy/index.js @@ -0,0 +1 @@ +export { default } from "./Copy"; \ No newline at end of file diff --git a/src/components/Dropdown/Dropdown.jsx b/src/components/Dropdown/Dropdown.jsx new file mode 100644 index 0000000..d5dc004 --- /dev/null +++ b/src/components/Dropdown/Dropdown.jsx @@ -0,0 +1,17 @@ +import React, {useState} from "react"; +import { DropdownMenu } from "./DropdownMenu"; +import { DropdownToggle } from "./DropdownToggle"; +import styles from "./Dropdown.module.css"; +import cls from "src/helpers/cls"; + +const Dropdown = ({toggleText, menuOptions, className, toggleClassName, ariaLabel, handleClickOption}) => { + const [showMenu, setShowMenu] = useState(false); + return ( +
+ setShowMenu(true)} ariaLabel={ariaLabel} ariaExpanded={showMenu} className={toggleClassName} /> + {showMenu ? setShowMenu(false)} handleClickOption={handleClickOption} /> : null} +
+ ); +}; + +export default Dropdown; \ No newline at end of file diff --git a/src/components/Dropdown/Dropdown.module.css b/src/components/Dropdown/Dropdown.module.css new file mode 100644 index 0000000..8e4b7ad --- /dev/null +++ b/src/components/Dropdown/Dropdown.module.css @@ -0,0 +1,49 @@ +.toggleButton { + composes: button from global; + border: 0; + font-weight: 400; + width: auto; + height: auto; + display: block; + color: var(--header-lang-toggle-color); + padding: 0 1.2rem; + min-width: 5.54rem; + box-sizing: border-box; +} + +.dropdownMenu { + display: block; + margin: 0; + padding: 0.8rem 0; + list-style: none; + position: absolute; + top: 9.8rem; + background: var(--header-bg-color); + z-index: 1000; +} + +.dropdownMenuItem { + font-family: inherit; + width: 100%; + padding: 0.6rem 1.6rem; + clear: both; + font-weight: 400; + color: inherit; + text-align: inherit; + text-decoration: none; + white-space: nowrap; + background: transparent; + border: 0; + font-size: var(--font-size-lg); + cursor: pointer; +} + +.dropdownMenuItem:hover { + background: rgba(255,255,255,0.05); +} + + +.dropdown { + display: flex; +} + diff --git a/src/components/Dropdown/DropdownMenu.jsx b/src/components/Dropdown/DropdownMenu.jsx new file mode 100644 index 0000000..cdfc877 --- /dev/null +++ b/src/components/Dropdown/DropdownMenu.jsx @@ -0,0 +1,17 @@ +import React, {useState} from "react"; +import useOutsideClick from "src/helpers/useOutsideClick"; +import styles from "./Dropdown.module.css"; + +export const DropdownMenu = ({options, handleClickOutside, handleClickOption}) => { + const [dropdownMenuEl, setdropdownMenuEl] = useState(null); + useOutsideClick(dropdownMenuEl, handleClickOutside); + return ( +
    + {options.map(op => ( +
  • + +
  • + ))} +
+ ); +}; \ No newline at end of file diff --git a/src/components/Dropdown/DropdownToggle.jsx b/src/components/Dropdown/DropdownToggle.jsx new file mode 100644 index 0000000..f9fc760 --- /dev/null +++ b/src/components/Dropdown/DropdownToggle.jsx @@ -0,0 +1,11 @@ +import React from "react"; +import styles from "./Dropdown.module.css"; +import cls from "src/helpers/cls"; + +export const DropdownToggle = ({text, handleClick, ariaLabel, ariaExpanded, className}) => { + return ( + + ); +}; \ No newline at end of file diff --git a/src/components/Dropdown/index.js b/src/components/Dropdown/index.js new file mode 100644 index 0000000..4d208f4 --- /dev/null +++ b/src/components/Dropdown/index.js @@ -0,0 +1 @@ +export { default } from "./Dropdown"; diff --git a/src/components/ErrorBoundary.jsx b/src/components/ErrorBoundary.jsx index 24eae08..8d4b758 100644 --- a/src/components/ErrorBoundary.jsx +++ b/src/components/ErrorBoundary.jsx @@ -1,26 +1,25 @@ import React, { Component } from "react"; -import { Message } from "pi-ui"; export default class ErrorBoundary extends Component { - constructor(props) { - super(props); - this.state = { - error: false - }; - } + constructor(props) { + super(props); + this.state = { + error: false + }; + } - static getDerivedStateFromError(error) { - return { - error: error - }; - } + static getDerivedStateFromError(error) { + return { + error: error + }; + } - render() { - const { error } = this.state; - return error ? ( - {error.toString()} - ) : ( - this.props.children - ); - } + render() { + const { error } = this.state; + return error ? ( +
{error.toString()}
+ ) : ( + this.props.children + ); + } } diff --git a/src/components/ErrorList/ErrorList.jsx b/src/components/ErrorList/ErrorList.jsx new file mode 100644 index 0000000..1ae57e7 --- /dev/null +++ b/src/components/ErrorList/ErrorList.jsx @@ -0,0 +1,15 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import styles from "./ErrorList.module.css"; + +const ErrorList = ({errors}) => { + const { t } = useTranslation(); + + return ( +
    + {errors.map(error =>
  • {t(error.key, error.options)}
  • )} +
+ ); +}; + +export default ErrorList; \ No newline at end of file diff --git a/src/components/ErrorList/ErrorList.module.css b/src/components/ErrorList/ErrorList.module.css new file mode 100644 index 0000000..8963ca6 --- /dev/null +++ b/src/components/ErrorList/ErrorList.module.css @@ -0,0 +1,8 @@ +.list { + composes: list from global; +} + +.listItem { + word-break: break-word; + text-overflow: clip; +} \ No newline at end of file diff --git a/src/components/ErrorList/index.js b/src/components/ErrorList/index.js new file mode 100644 index 0000000..3bc00a0 --- /dev/null +++ b/src/components/ErrorList/index.js @@ -0,0 +1 @@ +export { default } from "./ErrorList"; diff --git a/src/components/FileInput/FileInput.jsx b/src/components/FileInput/FileInput.jsx index d38d982..66d06c5 100644 --- a/src/components/FileInput/FileInput.jsx +++ b/src/components/FileInput/FileInput.jsx @@ -1,78 +1,85 @@ import React, { useState } from "react"; import PropTypes from "prop-types"; import Dropzone from "react-dropzone"; -import { Text, classNames } from "pi-ui"; -import FileIcon from "src/assets/file_icon.svg"; -import DeleteIcon from "src/assets/delete_icon.svg"; +import cls from "src/helpers/cls"; import { processFiles } from "./helpers"; import styles from "./FileInput.module.css"; +import {useTranslation} from "react-i18next"; +import {ERROR_DUPLICATE, ERROR_BIG_FILE} from "src/constants"; -const FileInput = ({ files, setFiles }) => { - const [processing, setProcessing] = useState(false); +const FileInput = ({ filesObj, error, setError, text, handleDrop, isVerify }) => { + const [processing, setProcessing] = useState(false); + const {t} = useTranslation(); - const onRemoveFile = idx => () => - setFiles(files.filter((_f, i) => i !== idx)); - - return ( - <> -
0 ? { paddingTop: "2em" } : {}}> - {files.map((file, i) => ( -
- fileicon - - {file.name} - - deleteicon -
- ))} -
-
- { - setProcessing(true); - processFiles(accFiles).then(processedFiles => { - setProcessing(false); - setFiles([...files, ...processedFiles]); - }); - }} - > - {({ getRootProps, getInputProps, isDragActive }) => ( -
+ { + setProcessing(true); + try { + const errors = []; + const processedFiles = await processFiles(accFiles, isVerify); + const duplicates = []; + const res = processedFiles.filter(d => { + const digest = filesObj?.[d.digest]; + if (digest) { + duplicates.push(digest); + } + return !digest; + }); + if (duplicates.length > 0) { + errors.push({key: ERROR_DUPLICATE, options: {hashes: duplicates.map(dup => dup.digest).join(", ")}}); + } + await handleDrop(res); + setProcessing(false); + if (rejFiles.length > 0) { // max file size + errors.push({key: ERROR_BIG_FILE, options: {rejected: rejFiles.map(rejFile => { + return `${t("file")}: '${rejFile.name}' - ${rejFile.size/1000000}mb. `; + }).join(" ")}}); + } + if (errors.length > 0) { + setError(errors); + } else { + setError(null); + } + } + catch(e) { + setProcessing(false); + setError([e]); + } + }} > - - - {!processing - ? "Drop your files here or click to select them" - : "Processing your files..."} - -
- )} -
-
- - ); + {({ getRootProps, getInputProps, isDragActive }) => ( +
+ + + {!processing + ? text + : t("fileInput.processing")} + +
+ )} + + + ); }; FileInput.propTypes = { - files: PropTypes.array, - setFiles: PropTypes.func + files: PropTypes.array, + setFiles: PropTypes.func, + isVerify: PropTypes.bool }; export default FileInput; diff --git a/src/components/FileInput/FileInput.module.css b/src/components/FileInput/FileInput.module.css index e92b7e6..68a2d97 100644 --- a/src/components/FileInput/FileInput.module.css +++ b/src/components/FileInput/FileInput.module.css @@ -1,54 +1,45 @@ -.dropzoneWrapper { - padding-bottom: 42px; -} - -.dropzoneText { - width: 100%; - text-align: center; - color: var(--color-primary-dark); - font-size: 13px; -} - -.fileInputLine { - display: flex; - padding-top: 10px; - padding-bottom: 10px; - height: 50px; - width: 100%; -} - -.textFileName { - margin-top: 5px; - margin-left: 5px; - font-size: 13px; - color: var(--color-gray-dark); - width: 100%; -} - -.deleteIcon { - cursor: pointer; -} .dropzone { - height: 80px; - flex: 1; + font-size: var(--font-size-xl); display: flex; flex-direction: column; align-items: center; justify-content: center; - border-width: 1.5px; - border-radius: 2px; - border-color: var(--color-gray-light); + border-width: 0.2rem; + border-radius: 0.5rem; + border-color: var(--file-input-border-color); border-style: dashed; + text-align: center; outline: none; + user-select: none; cursor: pointer; - transition: border .24s ease-in-out; + transition: border 0.5s ease-in; + padding: 2rem 3rem; +} + +.dropzone:hover { + background: var(--file-input-hover-bg-color); } - + +@media screen and (min-width: 769px) { + .dropzone { + box-sizing: border-box; + height: 9rem; + } +} + .dropzoneActive { - border-color: var(--color-primary); + border-color: var(--font-color); } - + .dropzone:focus { - border-color: var(--color-primary); -} \ No newline at end of file + border-color: var(--font-color); +} + +.error { + composes: error from global; +} + +.dropzoneWrapper { + position: relative; +} diff --git a/src/components/FileInput/helpers.js b/src/components/FileInput/helpers.js index 2a0f3d2..e2c5bdf 100644 --- a/src/components/FileInput/helpers.js +++ b/src/components/FileInput/helpers.js @@ -1,23 +1,58 @@ import { digestPayload } from "src/helpers/dcrtime"; -import { setDigestName } from "src/helpers/localstorage"; +import CryptoJS from "crypto-js"; +import {ERROR_INVALID_HASH_ON_FILE, ERROR_INVALID_HASHES_FILE} from "src/constants"; // processFiles adds the base64 payload into the file data -export const processFiles = files => - new Promise(resolve => { - const processedFiles = []; - files.forEach(file => { - const reader = new FileReader(); - reader.onload = (f => event => { - const payload = event.target.result.split(",")[1]; - const digest = digestPayload(payload); - setDigestName(digest, f.name); - processedFiles.push({ - name: f.name, - payload, - digest +export const processFiles = (files, isVerify) => + new Promise((resolve, reject) => { + const processedFiles = []; + if (files.length === 0) { + resolve([]); + } + files.forEach((file, idx) => { + const reader = new FileReader(); + reader.onload = (f => event => { + if (f.size >= 75000000) reject(Error(`Input field file '${f.name}' is too big (size: ${f.size/1000000}mb). Max size is 75mb.`)); + const payload = event.target.result.split(",")[1]; + if (f.type === "application/json" && isVerify) { + // it is a hashes file + const words = CryptoJS.enc.Base64.parse(payload); + const textString = CryptoJS.enc.Utf8.stringify(words); + const json = JSON.parse(textString); + if (json.id === "timestamply_v1_hashlist") { + const hashes = json.hashes; + if (!Array.isArray(hashes)) { + reject({key: ERROR_INVALID_HASHES_FILE}); + return; + } + hashes.forEach(hash => { + if (hash.length !== 64) { + reject({key: ERROR_INVALID_HASH_ON_FILE, options: {hash: hash}}); + } + processedFiles.push({ + name: f.name, + digest: hash + }); + }); + } else { + processedFiles.push({ + name: f.name, + payload, + digest: digestPayload(payload) + }); + } + } + else { + processedFiles.push({ + name: f.name, + payload, + digest: digestPayload(payload) + }); + } + if (idx === files.length - 1) { + resolve(processedFiles); + } + })(file); + reader.readAsDataURL(file); }); - if (processedFiles.length === files.length) resolve(processedFiles); - })(file); - reader.readAsDataURL(file); }); - }); diff --git a/src/components/HashConfList/HashConfList.jsx b/src/components/HashConfList/HashConfList.jsx new file mode 100644 index 0000000..937cb19 --- /dev/null +++ b/src/components/HashConfList/HashConfList.jsx @@ -0,0 +1,116 @@ +import React from "react"; +import styles from "./HashConfList.module.css"; +import Copy from "src/components/Copy"; +import Checkbox from "src/components/Checkbox"; +import Tooltip from "src/components/Tooltip"; +import { withRouter } from "react-router-dom"; +import { isDigestAnchored, isDigestWaitingAnchoring, isDigestAnchorPending } from "src/helpers/dcrtime"; +import {ReactComponent as TimestampedDark} from "../../assets/icons/timestamped-dark.svg"; +import {ReactComponent as TimestampedLight} from "../../assets/icons/timestamped-light.svg"; +import {ReactComponent as PendingLight} from "../../assets/icons/pending-light.svg"; +import {ReactComponent as PendingDark} from "../../assets/icons/pending-dark.svg"; +import {ReactComponent as WaitingLight} from "../../assets/icons/waiting-for-anchoring-light.svg"; +import {ReactComponent as WaitingDark} from "../../assets/icons/waiting-for-anchoring-dark.svg"; +import {ReactComponent as NotFoundLight} from "../../assets/icons/not-found-light.svg"; +import {ReactComponent as NotFoundDark} from "../../assets/icons/not-found-dark.svg"; +import useTheme from "src/theme/useTheme"; +import { useTranslation } from "react-i18next"; + +const getProgressClass = (digest) => { + if (isDigestAnchored(digest)) { + return styles.hashWrapper6; + } + switch(digest.chaininformation?.confirmations) { + case 1: + return styles.hashWrapper1; + case 2: + return styles.hashWrapper2; + case 3: + return styles.hashWrapper3; + case 4: + return styles.hashWrapper4; + case 5: + return styles.hashWrapper5; + default: + return styles.hashWrapper0; + } +}; + +const getStatus = digest => { + if (isDigestAnchored(digest)) { + return "Timestamped"; + } + if (isDigestWaitingAnchoring(digest)) { + return "Awaiting anchoring time"; + } + if (isDigestAnchorPending(digest)) { + return "Pending"; + } + return "Not Found"; +}; + +const getStatusComponent = (theme, hash) => { + const isDarkTheme = theme === "dark"; + switch (getStatus(hash)) { + case "Timestamped": + if (isDarkTheme) return TimestampedDark; + return TimestampedLight; + case "Pending": + if (isDarkTheme) return PendingDark; + return PendingLight; + case "Awaiting anchoring time": + if (isDarkTheme) return WaitingDark; + return WaitingLight; + default: + if (isDarkTheme) return NotFoundDark; + return NotFoundLight; + }; +}; + +const getTooltipText = (hash, t) => { + const st = getStatus(hash); + switch (st) { + case "Timestamped": + return t("hashView.timestamped"); + case "Awaiting anchoring time": + return t("hashView.awaiting"); + case "Pending": + return t("hashView.pending"); + case "Not found": + return t("hashView.notFound"); + default: + return t("hashView.notFound"); + } +}; + +const StatusComponent = ({theme, hash}) => { + const {t} = useTranslation(); + const Comp = getStatusComponent(theme, hash); + const tooltipText = getTooltipText(hash, t); + return ( + } tooltipText={tooltipText} tooltipHover tooltipTextStyle={{width: "8.5rem", left: "calc(50% - 4.75rem)"}} /> + ); +}; + + +const HashConfList = ({hashes, handleCheckboxClick, checked, history, noCheck}) => { + const {theme} = useTheme(); + return ( +
    + {hashes.map(h =>
  • + + + + + {noCheck ? null : ( + + )} + +
  • )} +
+ ); +}; + +export default withRouter(HashConfList); \ No newline at end of file diff --git a/src/components/HashConfList/HashConfList.module.css b/src/components/HashConfList/HashConfList.module.css new file mode 100644 index 0000000..1721c5f --- /dev/null +++ b/src/components/HashConfList/HashConfList.module.css @@ -0,0 +1,77 @@ +.hashConfList { + composes: list from global; +} + +.hashConfListItem { + display: flex; + justify-content: space-between; + margin-top: 1rem; +} + +.iconsWrapper { + display: flex; +} + +.hashWrapper { + text-align: start; + white-space: nowrap; + overflow-x: hidden; + text-overflow: ellipsis; + box-sizing: border-box; + padding: 0rem 0.8rem; + flex-grow: 1; + margin-right: 0.5rem; + border-radius: 0.2rem; + cursor: pointer; + border: 0; + outline: 0; + font-size: var(--font-size-md); + font-family: Inter; + color: var(--white); + user-select: none; +} + +.hashWrapper:hover { + border: 0.1rem solid var(--progress-bar-border-color); + padding: 0rem 0.7rem; +} + +.hashWrapper:focus { + border: 0.1rem solid var(--progress-bar-border-color); + padding: 0rem 0.7rem; +} + +.hashWrapper0 { + composes: hashWrapper; + background-image: linear-gradient(to right, var(--progress-bar-bg-color) 0%, var(--progress-bar-bg-color) 100%); +} + +.hashWrapper1 { + composes: hashWrapper; + background-image: linear-gradient(to right, var(--progress-bar-bg-color-step) 0%, var(--progress-bar-bg-color-step) 16.67%, var(--progress-bar-bg-color) 16.67%, var(--progress-bar-bg-color) 100%); +} + +.hashWrapper2 { + composes: hashWrapper; + background-image: linear-gradient(to right, var(--progress-bar-bg-color-step) 0%, var(--progress-bar-bg-color-step) 33.33%, var(--progress-bar-bg-color) 33.33%, var(--progress-bar-bg-color) 100%); +} + +.hashWrapper3 { + composes: hashWrapper; + background-image: linear-gradient(to right, var(--progress-bar-bg-color-step) 0%, var(--progress-bar-bg-color-step) 50%, var(--progress-bar-bg-color) 50%, var(--progress-bar-bg-color) 100%); +} + +.hashWrapper4 { + composes: hashWrapper; + background-image: linear-gradient(to right, var(--progress-bar-bg-color-step) 0%, var(--progress-bar-bg-color-step) 66.67%, var(--progress-bar-bg-color) 66.67%, var(--progress-bar-bg-color) 100%); +} + +.hashWrapper5 { + composes: hashWrapper; + background-image: linear-gradient(to right, var(--progress-bar-bg-color-step) 0%, var(--progress-bar-bg-color-step) 83.33%, var(--progress-bar-bg-color) 83.33%, var(--progress-bar-bg-color) 100%); +} + +.hashWrapper6 { + composes: hashWrapper; + background: var(--progress-bar-bg-color-done); +} \ No newline at end of file diff --git a/src/components/HashConfList/index.js b/src/components/HashConfList/index.js new file mode 100644 index 0000000..86539dc --- /dev/null +++ b/src/components/HashConfList/index.js @@ -0,0 +1 @@ +export { default } from "./HashConfList"; diff --git a/src/components/HashInput/HashInput.jsx b/src/components/HashInput/HashInput.jsx deleted file mode 100644 index 26556f8..0000000 --- a/src/components/HashInput/HashInput.jsx +++ /dev/null @@ -1,69 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { Text } from "pi-ui"; -import HashIcon from "src/assets/hash_icon.svg"; -import DeleteIcon from "src/assets/delete_icon.svg"; -import styles from "./HashInput.module.css"; - -const HashInput = ({ hashes, setHashes }) => { - // Initialize first hash input - if (!hashes.length) { - setHashes([{ id: 0, digest: "" }]); - } - - const onAddHash = () => { - const newId = hashes[hashes.length - 1].id + 1; - return setHashes([...hashes, { id: newId, digest: "" }]); - }; - - const onRemoveHash = id => () => - setHashes(hashes.filter(hash => hash.id !== id)); - - const onChangeHash = id => e => - setHashes( - hashes.map(h => { - if (h.id === id) { - h.digest = e.target.value; - } - return h; - }) - ); - - return ( -
- {hashes.map((hash, i) => ( -
- hash -
- -
- icon -
- ))} - - - Add another - -
- ); -}; - -HashInput.propTypes = { - hashes: PropTypes.array, - setHashes: PropTypes.func -}; - -export default HashInput; diff --git a/src/components/HashInput/HashInput.module.css b/src/components/HashInput/HashInput.module.css deleted file mode 100644 index cf214cc..0000000 --- a/src/components/HashInput/HashInput.module.css +++ /dev/null @@ -1,61 +0,0 @@ -.hashInputWrapper { - margin-top: 57px; - margin-bottom: 47px; -} - -.addButtonWrapper { - cursor: pointer; -} - -.addButton { - cursor: pointer; - width: 18px; - height: 18px; - margin-right: 7px; - margin-left: 3px; - border: none; - border-radius: 5px; - color: var(--color-white); - background-color: var(--color-primary); - outline: none; -} - -.addButtonText { - color: var(--color-primary); - font-size: 13px; -} - -.hashInputLine { - display: flex; - align-items: center; - padding-bottom: 20px; -} - -.hashIcon { - padding-right: 5px; -} - -.deleteIcon { - cursor: pointer; -} - -.textInput { - background-color: transparent; - outline: 0; - border: 0; - width: 100%; - border-bottom: 0.1rem solid var(--color-gray-lighter); - font-size: 13px; - padding-left: 10px; - transition: all 0.25s; - line-height: var(--spacing-2); -} - -.textInput::placeholder { - color: var(--color-gray-light); - font-size: 13px; -} - -.textInputWrapper { - width: 100%; -} \ No newline at end of file diff --git a/src/components/HashInput/index.js b/src/components/HashInput/index.js deleted file mode 100644 index e5dc400..0000000 --- a/src/components/HashInput/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./HashInput"; diff --git a/src/components/InputText/InputText.jsx b/src/components/InputText/InputText.jsx new file mode 100644 index 0000000..24f9593 --- /dev/null +++ b/src/components/InputText/InputText.jsx @@ -0,0 +1,14 @@ +import React from "react"; +import styles from "./InputText.module.css"; +import cls from "src/helpers/cls"; + +const InputText = ({placeholder, value, onChange, className, Icon, error}) => { + return ( +
+ + {Icon ? : null} +
+ ); +}; + +export default InputText; \ No newline at end of file diff --git a/src/components/InputText/InputText.module.css b/src/components/InputText/InputText.module.css new file mode 100644 index 0000000..ebf6ada --- /dev/null +++ b/src/components/InputText/InputText.module.css @@ -0,0 +1,47 @@ +.inputText { + border: 0.1rem solid transparent; + border-radius: 0.5rem; + background: var(--input-bg-color); + font-size: var(--font-size-lg); + color: var(--font-color); + font-weight: 500; + outline: none; + padding: 0.6rem 0.8rem; + width: 100%; + box-sizing: border-box; +} + +.inputWrapper { + flex-grow: 1; + position: relative; +} + +.error { + composes: error from global; +} + +.inputText:hover { + border: 0.1rem solid var(--input-hover-border-color); +} + +.inputText:focus { + border: 0.1rem solid var(--input-hover-border-color); +} + +.inputText:active { + border: 0.1rem solid var(--input-hover-border-color); +} + +.inputText::placeholder { + color: var(--input-placeholder-color); +} + +.iconWrapper { + position: absolute; + right: 1.1rem; + top: 1.1rem; + padding: 0; + background: transparent; + border: 0; + cursor: pointer; +} \ No newline at end of file diff --git a/src/components/InputText/index.js b/src/components/InputText/index.js new file mode 100644 index 0000000..5d4ca09 --- /dev/null +++ b/src/components/InputText/index.js @@ -0,0 +1 @@ +export { default } from "./InputText"; diff --git a/src/components/LangDropdown/LangDropdown.jsx b/src/components/LangDropdown/LangDropdown.jsx new file mode 100644 index 0000000..bfdb72b --- /dev/null +++ b/src/components/LangDropdown/LangDropdown.jsx @@ -0,0 +1,22 @@ +import React, {useEffect, useState} from "react"; +import Dropdown from "src/components/Dropdown"; +import styles from "./LangDropdown.module.css"; +import { useTranslation } from "react-i18next"; + +const LangDropdown = ({className}) => { + const { i18n } = useTranslation(); + const allLangOptions = ["ENG", "PT"]; + const [selectedLang, setSelectedLang] = useState(localStorage.getItem("lang") || "ENG"); + useEffect(() => { + if (selectedLang === "ENG") i18n.changeLanguage("en"); + if (selectedLang === "PT") i18n.changeLanguage("pt"); + localStorage.setItem("lang", selectedLang); + }, [selectedLang, setSelectedLang, i18n]); + const handleClickOption = (op) => setSelectedLang(op); + const menuOptions = allLangOptions.filter(l => l !== selectedLang); + return ( + + ); +}; + +export default LangDropdown; \ No newline at end of file diff --git a/src/components/LangDropdown/LangDropdown.module.css b/src/components/LangDropdown/LangDropdown.module.css new file mode 100644 index 0000000..df8ab39 --- /dev/null +++ b/src/components/LangDropdown/LangDropdown.module.css @@ -0,0 +1,3 @@ +.toggleButton { + border-bottom: 0.2rem solid transparent; +} \ No newline at end of file diff --git a/src/components/LangDropdown/index.js b/src/components/LangDropdown/index.js new file mode 100644 index 0000000..8eaf220 --- /dev/null +++ b/src/components/LangDropdown/index.js @@ -0,0 +1 @@ +export { default } from "./LangDropdown"; diff --git a/src/components/LatestHashesSection/LatestHashes.jsx b/src/components/LatestHashesSection/LatestHashes.jsx new file mode 100644 index 0000000..4d4aade --- /dev/null +++ b/src/components/LatestHashesSection/LatestHashes.jsx @@ -0,0 +1,120 @@ +import React, { useEffect, useState } from "react"; +import styles from "./LatestHashes.module.css"; +import InputText from "src/components/InputText"; +import Copy from "src/components/Copy"; +import {ReactComponent as SearchLight} from "../../assets/icons/hash-search-light.svg"; +import {ReactComponent as SearchDark} from "../../assets/icons/hash-search-dark.svg"; +import useTheme from "src/theme/useTheme"; +import { + handleVerify +} from "src/helpers/dcrtime"; +import { withRouter } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import { handleGetLastDigests } from "src/helpers/dcrtime"; +import { timeago } from "src/helpers/timeago"; +import { ERROR_SEARCH_INVALID } from "src/constants"; +import Spinner from "src/components/Spinner"; +import ErrorList from "src/components/ErrorList"; +import cls from "src/helpers/cls"; + +const Timeago = ({timeago}) => { + const {t} = useTranslation(); + return t(timeago.key, timeago.options); +}; + +const LatestHashes = ({history, fetchLast, setFetchLast}) => { + const {theme} = useTheme(); + const isDarkTheme = theme === "dark"; + const {t} = useTranslation(); + const [searchByHash, setSearchByHash] = useState(""); + const [searchByHashError, setSearchByHashError] = useState(null); + const [lastDigests, setLastDigests] = useState([]); + const [digests, setDigests] = useState([]); + const [loading, setLoading] = useState(false); + + useEffect(() => { + const fetchLastDigests = async () => { + const lastD = await handleGetLastDigests(); + setLastDigests(lastD.digests); + setDigests(lastD.digests); + setLoading(false); + }; + setLoading(true); + setTimeout(() => fetchLastDigests(), 700); + }, []); + + useEffect(() => { + const fetchLastDigests = async () => { + const lastD = await handleGetLastDigests(); + setLastDigests(lastD.digests); + setDigests(lastD.digests); + setLoading(false); + }; + if (fetchLast) { + setLoading(true); + setFetchLast(false); + fetchLastDigests(); + } + }, [fetchLast, setFetchLast]); + + const handleInputChange = (e) => { + setSearchByHash(e.target.value); + setSearchByHashError(null); + if (e.target.value === "") { + setDigests(lastDigests); + } + }; + + const handleSubmitSearch = async (e) => { + e.preventDefault(); + const param = [{digest: searchByHash}]; + try { + const {digests} = await handleVerify(param); + setDigests([...digests]); + } catch (e) { + if (e === "Invalid Digests array") { + setSearchByHashError({key: ERROR_SEARCH_INVALID}); + } + } + }; + + return ( +
+
+
+

+ {t("latestHashes.title")} +

+
+ + +
+ {loading ?
: + ( + <> + {searchByHashError && ( + <> +

Error log

+ +
+ + )} +
    + {digests.map(h =>
  • +
    history.push(`/results#hashes=${h.digest}`)}> + + {h.digest} +
    +
    + +
    +
  • )} +
+ + )} +
+
+ ); +}; + +export default withRouter(LatestHashes); \ No newline at end of file diff --git a/src/components/LatestHashesSection/LatestHashes.module.css b/src/components/LatestHashesSection/LatestHashes.module.css new file mode 100644 index 0000000..ea1de27 --- /dev/null +++ b/src/components/LatestHashesSection/LatestHashes.module.css @@ -0,0 +1,138 @@ +.latestHashes { + margin-top: 10rem; + background: var(--latest-hash-section-bg-color); + padding: 2rem 3.5rem 5.5rem 3.5rem; +} + +.content { + max-width: 103.5rem; + margin: 0 auto; +} + +.heading { + margin: 0; + font-size: var(--font-size-xl); + font-weight: normal; +} + +.singleLineHeading { + composes: singleLineHeading from global; +} + +.singleLineHeading::after { + margin: 0; +} + +.spinnerWrapper { + display: flex; + justify-content: center; +} + +.hashesList { + composes: list from global; +} + +.hashesListItem { + display: flex; + align-items: center; +} + +.hashTimeWrapper { + box-sizing: border-box; + width: calc(100% - 2.2rem); + display: flex; + flex-grow: 1; + justify-content: space-between; + border: 0.1rem solid transparent; + border-radius: 0.2rem; + padding: 0.3rem 0.8rem; + margin-right: 0.5rem; +} + +.hashTimeWrapper:hover { + border: 0.1rem solid var(--latest-hash-hover-color); + cursor: pointer; + user-select: none; +} + +.hashesListItem:not(:last-of-type) { + margin-bottom: 1rem; +} + +.timeago { + color: var(--latest-hash-timeago-color); + padding-right: 1rem; + min-width: 5rem; +} + +.hash { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.error { + composes: error from global; +} + +.title { + display: flex; + justify-content: space-between; + margin-bottom: 3.5rem; +} + +.input { + box-sizing: border-box; + padding: 0.7rem 3.2rem 0.8rem 1.5rem !important; + border-radius: 1.7rem !important; + min-width: 23.8rem; + width: 23.8rem; + max-width: 29.2rem; +} + +.searchWrapper { + position: relative; +} + +.input:hover + button > svg > g > g, .input:hover + button > svg > g > line { + stroke: var(--search-icon-hover-color); +} + +.input:active + button > svg > g > g, .input:active + button > svg > g > line { + stroke: var(--search-icon-hover-color); +} + +.input:focus + button > svg > g > g, .input:focus + button > svg > g > line { + stroke: var(--search-icon-hover-color); +} + +.input::placeholder { + color: var(--search-input-placeholder-color) !important; +} + +@media screen and (min-width: 769px) { + .input { + width: 28.2rem; + } +} + +@media screen and (min-width: 1000px) { + .input { + width: 29.2rem; + } +} + +/* This is needed for the site to be usable on very small +screen sizes */ +@media screen and (max-width: 470px) { + .title { + flex-direction: column; + } + .input { + width: 100%; + max-width: 100%; + } + .heading { + margin-bottom: 2.5rem; + } + } \ No newline at end of file diff --git a/src/components/LatestHashesSection/index.js b/src/components/LatestHashesSection/index.js new file mode 100644 index 0000000..aa1a9bc --- /dev/null +++ b/src/components/LatestHashesSection/index.js @@ -0,0 +1 @@ +export { default } from "./LatestHashes"; diff --git a/src/components/Layout/Footer.jsx b/src/components/Layout/Footer.jsx index 0b50754..1b01418 100644 --- a/src/components/Layout/Footer.jsx +++ b/src/components/Layout/Footer.jsx @@ -1,21 +1,64 @@ import React from "react"; import styles from "./Footer.module.css"; +import {ReactComponent as TwitterLogo} from "../../assets/icons/icon-frontpage-twitter.svg"; +import {ReactComponent as MatrixLogo} from "../../assets/icons/icon-frontpage-matrix.svg"; +import {ReactComponent as MediumLogo} from "../../assets/icons/icon-frontpage-medium.svg"; +import {ReactComponent as RedditLogo} from "../../assets/icons/icon-frontpage-reddit.svg"; +import {ReactComponent as YoutubeLogo} from "../../assets/icons/icon-frontpage-youtube.svg"; +import {ReactComponent as DiscordLogo} from "../../assets/icons/icon-frontpage-discord.svg"; +import {useTranslation} from "react-i18next"; -const Footer = () => ( -
-
- Decred developers | 2016 - {new Date().getFullYear()} - - The source code is available at{" "} - - GitHub - - -
-
-); +const Footer = () => { + const {t} = useTranslation(); + return ( + + ); +}; export default Footer; diff --git a/src/components/Layout/Footer.module.css b/src/components/Layout/Footer.module.css index afc6ce0..b44f7dc 100644 --- a/src/components/Layout/Footer.module.css +++ b/src/components/Layout/Footer.module.css @@ -1,24 +1,80 @@ .footer { - height: 80px; - width: 100vw; - padding: 2rem; - margin-top: 40px; - background: var(--color-primary-dark); - flex-shrink: 0; + padding: 3.5rem 3.5rem 5.5rem 3.5rem; + background: var(--footer-bg-color); + font-size: var(--font-size-lg); + flex-grow: 1; } -.textWrapper { +/* This is needed for the site to be usable on very small +screen sizes */ +@media screen and (max-width: 470px) { + .footer { + padding: 3.5rem 2rem 3.5rem 2rem; + } +} + +.container { + display: flex; + flex-wrap: wrap; + flex-direction: column-reverse; + margin: 0 auto; +} + +.column { + display: flex; + flex-direction: row; + flex-wrap: wrap; + width: 100%; + align-items: flex-start; + opacity: 0.55; +} + +.column > a { + margin: 0 1.6rem 0.3rem 0; +} + +.decredDevs { + composes: column; +} + +.socialMedia { display: flex; - flex-direction: column; - align-items: flex-end; + width: 100%; justify-content: space-between; - height: 36px; - min-width: 210px; - font-size: 13px; - color: var(--color-gray); + flex-wrap: wrap; + margin-bottom: 2rem; + color: var(--sm-color); } -.ghLink { - color: var(--color-primary); - text-decoration: none; +@media screen and (min-width: 1000px) { + .container { + display: flex; + flex-wrap: wrap; + flex-direction: row; + width: 100%; + max-width: 100.4rem; + } + + .column { + display: flex; + flex-direction: column; + width: 25%; + align-items: flex-start; + justify-content: flex-start; + } + + .column > a { + margin: 0 1.6rem 1.2rem 0; + } + + .socialMedia { + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; + margin-bottom: 0; + } + + .socialMedia > a { + margin: 0 3.4rem 1.3rem 0; + } } \ No newline at end of file diff --git a/src/components/Layout/Header.jsx b/src/components/Layout/Header.jsx index 42f2531..13bbcb5 100644 --- a/src/components/Layout/Header.jsx +++ b/src/components/Layout/Header.jsx @@ -1,34 +1,26 @@ -import React, { useState } from "react"; -import { Header as HeaderUI, BoxTextInput } from "pi-ui"; +import React, {useState} from "react"; import { NavLink, withRouter } from "react-router-dom"; -import Logo from "src/assets/logo.svg"; +import useTheme from "src/theme/useTheme"; +import LogoLight from "src/assets/icons/logo-light.svg"; +import LogoDark from "src/assets/icons/logo-dark.svg"; +import Menu from "src/components/Menu"; import styles from "./Header.module.css"; -const Header = ({ history }) => { - const [query, setQuery] = useState(""); - return ( - - - presentation - -
- setQuery(e.target.value)} - onSubmit={() => { - history.push(`results#hashes=${query}`); - window.location.reload(); - }} - /> -
-
- ); +const Header = () => { + const {theme} = useTheme(); + const isDarkTheme = theme === "dark"; + const logo = isDarkTheme ? LogoDark : LogoLight; + const [showMenu, setShowMenu] = useState(false); + return ( +
+
+ + timestamply logo + + +
+
+ ); }; export default withRouter(Header); diff --git a/src/components/Layout/Header.module.css b/src/components/Layout/Header.module.css index 0df9fbf..6697ceb 100644 --- a/src/components/Layout/Header.module.css +++ b/src/components/Layout/Header.module.css @@ -1,40 +1,32 @@ .header { - color: var(--color-gray-lightest2); - border: 0 !important; - height: 70px; -} - -.headerContainer { + border: 0; + height: 9.8rem; + /* Add min-height to prevent flex-grow to shrink it */ + min-height: 9.8rem; + padding: 0 3.5rem; display: flex; - justify-content: center; - width: 100vw; -} - -.searchBox { - width: 540px; - margin-top: 10px; - margin-right: 70px; -} - -.searchInput { - border: 1px solid; - border-color: var(--color-gray-light); + background: var(--header-bg-gradient); } -.searchInput:hover { - border-color: rgba(41, 112, 255, 0.5); +.container { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + max-width: 100.4rem; + margin: 0 auto; } -.searchInput:focus { - border-color: var(--color-primary); +/* This is needed for the site to be usable on very small +screen sizes */ +@media screen and (max-width: 470px) { + .header { + padding: 0 2rem; + } } -@media screen and (max-width: 768px){ - - .searchBox { - width: 100%; - padding-left: 50px; - margin-right: 0; +@media screen and (min-width: 769px) { + .header { + background: var(--header-bg-color); } - -} +} \ No newline at end of file diff --git a/src/components/Layout/Page.jsx b/src/components/Layout/Page.jsx index 796baf1..7b9f454 100644 --- a/src/components/Layout/Page.jsx +++ b/src/components/Layout/Page.jsx @@ -3,27 +3,33 @@ import PropTypes from "prop-types"; import Header from "./Header"; import Footer from "./Footer"; import styles from "./Page.module.css"; -import { Container, Main } from "pi-ui"; import ErrorBoundary from "src/components/ErrorBoundary"; +import useTheme from "src/theme/useTheme"; const Page = ({ children }) => { - return ( - <> - -
-
- - {children} - -
-