Compare commits
No commits in common. "master" and "fix/article-interaction-buttons" have entirely different histories.
master
...
fix/articl
25
Dockerfile
25
Dockerfile
@ -17,25 +17,22 @@ COPY . .
|
|||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Bundle static assets with nginx
|
# Bundle static assets with nginx
|
||||||
FROM node:16-alpine as production
|
FROM nginx:1.21.6 as production
|
||||||
# Copy built assets from builder
|
# Copy built assets from builder
|
||||||
WORKDIR /app
|
COPY --from=builder /app/build /usr/share/nginx/html
|
||||||
COPY --from=builder /app/build .
|
# Add nginx.config
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
# Expose ports
|
# Expose ports
|
||||||
EXPOSE 3000
|
EXPOSE 80
|
||||||
|
|
||||||
|
COPY entrypoint.sh .
|
||||||
COPY .env.production .
|
COPY .env.production .
|
||||||
|
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
ENV USER_NAME=node_user USER_UID=2000 GROUP_NAME=node_group GROUP_UID=2000
|
|
||||||
|
|
||||||
RUN npm i -g serve \
|
# Execute script
|
||||||
&& deluser --remove-home node \
|
RUN ["chmod", "+x", "./entrypoint.sh"]
|
||||||
&& addgroup --g ${GROUP_UID} -S ${GROUP_NAME} \
|
ENTRYPOINT ["./entrypoint.sh"]
|
||||||
&& adduser -D -S -s /sbin/nologin -u ${USER_UID} -G ${GROUP_NAME} ${USER_NAME}\
|
|
||||||
&& chown -R ${USER_NAME}:${GROUP_NAME} "/app/"
|
|
||||||
|
|
||||||
|
# Start serving
|
||||||
USER "${USER_NAME}"
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
CMD serve -s .
|
|
194
package-lock.json
generated
194
package-lock.json
generated
@ -8,10 +8,6 @@
|
|||||||
"name": "freeland",
|
"name": "freeland",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.2.0",
|
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.2.0",
|
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.2.0",
|
|
||||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
|
||||||
"@headlessui/react": "^1.6.6",
|
"@headlessui/react": "^1.6.6",
|
||||||
"@reduxjs/toolkit": "^1.8.3",
|
"@reduxjs/toolkit": "^1.8.3",
|
||||||
"@types/node": "^16.11.47",
|
"@types/node": "^16.11.47",
|
||||||
@ -35,7 +31,6 @@
|
|||||||
"react-hotkeys": "^2.0.0",
|
"react-hotkeys": "^2.0.0",
|
||||||
"react-i18next": "^11.18.3",
|
"react-i18next": "^11.18.3",
|
||||||
"react-loading-skeleton": "^3.1.0",
|
"react-loading-skeleton": "^3.1.0",
|
||||||
"react-lottie": "^1.2.3",
|
|
||||||
"react-markdown": "^8.0.3",
|
"react-markdown": "^8.0.3",
|
||||||
"react-redux": "^8.0.2",
|
"react-redux": "^8.0.2",
|
||||||
"react-router-dom": "^6.3.0",
|
"react-router-dom": "^6.3.0",
|
||||||
@ -70,7 +65,6 @@
|
|||||||
"@testing-library/react": "^13.3.0",
|
"@testing-library/react": "^13.3.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"@types/jest": "^27.5.2",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/react-lottie": "^1.2.6",
|
|
||||||
"@types/react-syntax-highlighter": "^15.5.5",
|
"@types/react-syntax-highlighter": "^15.5.5",
|
||||||
"autoprefixer": "^10.4.8",
|
"autoprefixer": "^10.4.8",
|
||||||
"babel-plugin-named-exports-order": "^0.0.2",
|
"babel-plugin-named-exports-order": "^0.0.2",
|
||||||
@ -2390,63 +2384,6 @@
|
|||||||
"js-yaml": "bin/js-yaml.js"
|
"js-yaml": "bin/js-yaml.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fortawesome/fontawesome-common-types": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-rBevIsj2nclStJ7AxTdfsa3ovHb1H+qApwrxcTVo+NNdeJiB9V75hsKfrkG5AwNcRUNxrPPiScGYCNmLMoh8pg==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@fortawesome/fontawesome-svg-core": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-Cf2mAAeMWFMzpLC7Y9H1I4o3wEU+XovVJhTiNG8ZNgSQj53yl7OCJaS80K4YjrABWZzbAHVaoHE1dVJ27AAYXw==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@fortawesome/fontawesome-common-types": "6.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@fortawesome/free-brands-svg-icons": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-fm1y4NyZ2qKYNmYhdMz9VAWRw1Et7PMHNunSw3W0SVAwKwv6o0qiJworLH3Y9SnmhHzAymXJwCX1op22FFvGiA==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@fortawesome/fontawesome-common-types": "6.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@fortawesome/free-solid-svg-icons": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-UjCILHIQ4I8cN46EiQn0CZL/h8AwCGgR//1c4R96Q5viSRwuKVo0NdQEc4bm+69ZwC0dUvjbDqAHF1RR5FA3XA==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@fortawesome/fontawesome-common-types": "6.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@fortawesome/react-fontawesome": {
|
|
||||||
"version": "0.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz",
|
|
||||||
"integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==",
|
|
||||||
"dependencies": {
|
|
||||||
"prop-types": "^15.8.1"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@fortawesome/fontawesome-svg-core": "~1 || ~6",
|
|
||||||
"react": ">=16.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@gar/promisify": {
|
"node_modules/@gar/promisify": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
|
||||||
@ -11560,15 +11497,6 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/react-lottie": {
|
|
||||||
"version": "1.2.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-lottie/-/react-lottie-1.2.6.tgz",
|
|
||||||
"integrity": "sha512-fvGJHD7SeUdVESHo7f7erRnXkTWaa/6Mo5TB+R0/ieSftKoFspA4sMlF2qMH6BljXI7ehFJbBtrD5bzDxPCkGg==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/react": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/react-syntax-highlighter": {
|
"node_modules/@types/react-syntax-highlighter": {
|
||||||
"version": "15.5.5",
|
"version": "15.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.5.tgz",
|
||||||
@ -13611,27 +13539,6 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/babel-runtime": {
|
|
||||||
"version": "6.26.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
|
||||||
"integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"core-js": "^2.4.0",
|
|
||||||
"regenerator-runtime": "^0.11.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/babel-runtime/node_modules/core-js": {
|
|
||||||
"version": "2.6.12",
|
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
|
|
||||||
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
|
|
||||||
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
|
|
||||||
"hasInstallScript": true
|
|
||||||
},
|
|
||||||
"node_modules/babel-runtime/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.11.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
|
|
||||||
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
|
|
||||||
},
|
|
||||||
"node_modules/bail": {
|
"node_modules/bail": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
|
||||||
@ -25678,11 +25585,6 @@
|
|||||||
"loose-envify": "cli.js"
|
"loose-envify": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lottie-web": {
|
|
||||||
"version": "5.9.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.9.6.tgz",
|
|
||||||
"integrity": "sha512-JFs7KsHwflugH5qIXBpB4905yC1Sub2MZWtl/elvO/QC6qj1ApqbUZJyjzJseJUtVpgiDaXQLjBlIJGS7UUUXA=="
|
|
||||||
},
|
|
||||||
"node_modules/loud-rejection": {
|
"node_modules/loud-rejection": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
|
||||||
@ -30420,21 +30322,6 @@
|
|||||||
"react": ">=16.8.0"
|
"react": ">=16.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-lottie": {
|
|
||||||
"version": "1.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-lottie/-/react-lottie-1.2.3.tgz",
|
|
||||||
"integrity": "sha512-qLCERxUr8M+4mm1LU0Ruxw5Y5Fn/OmYkGfnA+JDM/dZb3oKwVAJCjwnjkj9TMHtzR2U6sMEUD3ZZ1RaHagM7kA==",
|
|
||||||
"dependencies": {
|
|
||||||
"babel-runtime": "^6.26.0",
|
|
||||||
"lottie-web": "^5.1.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"npm": "^3.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^0.14.7 || ^15.0.0 || ^16.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-markdown": {
|
"node_modules/react-markdown": {
|
||||||
"version": "8.0.3",
|
"version": "8.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.3.tgz",
|
||||||
@ -41602,43 +41489,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@fortawesome/fontawesome-common-types": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-rBevIsj2nclStJ7AxTdfsa3ovHb1H+qApwrxcTVo+NNdeJiB9V75hsKfrkG5AwNcRUNxrPPiScGYCNmLMoh8pg=="
|
|
||||||
},
|
|
||||||
"@fortawesome/fontawesome-svg-core": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-Cf2mAAeMWFMzpLC7Y9H1I4o3wEU+XovVJhTiNG8ZNgSQj53yl7OCJaS80K4YjrABWZzbAHVaoHE1dVJ27AAYXw==",
|
|
||||||
"requires": {
|
|
||||||
"@fortawesome/fontawesome-common-types": "6.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@fortawesome/free-brands-svg-icons": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-fm1y4NyZ2qKYNmYhdMz9VAWRw1Et7PMHNunSw3W0SVAwKwv6o0qiJworLH3Y9SnmhHzAymXJwCX1op22FFvGiA==",
|
|
||||||
"requires": {
|
|
||||||
"@fortawesome/fontawesome-common-types": "6.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@fortawesome/free-solid-svg-icons": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-UjCILHIQ4I8cN46EiQn0CZL/h8AwCGgR//1c4R96Q5viSRwuKVo0NdQEc4bm+69ZwC0dUvjbDqAHF1RR5FA3XA==",
|
|
||||||
"requires": {
|
|
||||||
"@fortawesome/fontawesome-common-types": "6.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@fortawesome/react-fontawesome": {
|
|
||||||
"version": "0.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz",
|
|
||||||
"integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==",
|
|
||||||
"requires": {
|
|
||||||
"prop-types": "^15.8.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@gar/promisify": {
|
"@gar/promisify": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
|
||||||
@ -48649,15 +48499,6 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/react-lottie": {
|
|
||||||
"version": "1.2.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-lottie/-/react-lottie-1.2.6.tgz",
|
|
||||||
"integrity": "sha512-fvGJHD7SeUdVESHo7f7erRnXkTWaa/6Mo5TB+R0/ieSftKoFspA4sMlF2qMH6BljXI7ehFJbBtrD5bzDxPCkGg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/react": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/react-syntax-highlighter": {
|
"@types/react-syntax-highlighter": {
|
||||||
"version": "15.5.5",
|
"version": "15.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.5.tgz",
|
||||||
@ -50266,27 +50107,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"babel-runtime": {
|
|
||||||
"version": "6.26.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
|
||||||
"integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
|
|
||||||
"requires": {
|
|
||||||
"core-js": "^2.4.0",
|
|
||||||
"regenerator-runtime": "^0.11.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"core-js": {
|
|
||||||
"version": "2.6.12",
|
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
|
|
||||||
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
|
|
||||||
},
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.11.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
|
|
||||||
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bail": {
|
"bail": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
|
||||||
@ -59412,11 +59232,6 @@
|
|||||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lottie-web": {
|
|
||||||
"version": "5.9.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.9.6.tgz",
|
|
||||||
"integrity": "sha512-JFs7KsHwflugH5qIXBpB4905yC1Sub2MZWtl/elvO/QC6qj1ApqbUZJyjzJseJUtVpgiDaXQLjBlIJGS7UUUXA=="
|
|
||||||
},
|
|
||||||
"loud-rejection": {
|
"loud-rejection": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
|
||||||
@ -62690,15 +62505,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.1.0.tgz",
|
||||||
"integrity": "sha512-j1U1CWWs68nBPOg7tkQqnlFcAMFF6oEK6MgqAo15f8A5p7mjH6xyKn2gHbkcimpwfO0VQXqxAswnSYVr8lWzjw=="
|
"integrity": "sha512-j1U1CWWs68nBPOg7tkQqnlFcAMFF6oEK6MgqAo15f8A5p7mjH6xyKn2gHbkcimpwfO0VQXqxAswnSYVr8lWzjw=="
|
||||||
},
|
},
|
||||||
"react-lottie": {
|
|
||||||
"version": "1.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-lottie/-/react-lottie-1.2.3.tgz",
|
|
||||||
"integrity": "sha512-qLCERxUr8M+4mm1LU0Ruxw5Y5Fn/OmYkGfnA+JDM/dZb3oKwVAJCjwnjkj9TMHtzR2U6sMEUD3ZZ1RaHagM7kA==",
|
|
||||||
"requires": {
|
|
||||||
"babel-runtime": "^6.26.0",
|
|
||||||
"lottie-web": "^5.1.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"react-markdown": {
|
"react-markdown": {
|
||||||
"version": "8.0.3",
|
"version": "8.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.3.tgz",
|
||||||
|
@ -3,10 +3,6 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.2.0",
|
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.2.0",
|
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.2.0",
|
|
||||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
|
||||||
"@headlessui/react": "^1.6.6",
|
"@headlessui/react": "^1.6.6",
|
||||||
"@reduxjs/toolkit": "^1.8.3",
|
"@reduxjs/toolkit": "^1.8.3",
|
||||||
"@types/node": "^16.11.47",
|
"@types/node": "^16.11.47",
|
||||||
@ -30,7 +26,6 @@
|
|||||||
"react-hotkeys": "^2.0.0",
|
"react-hotkeys": "^2.0.0",
|
||||||
"react-i18next": "^11.18.3",
|
"react-i18next": "^11.18.3",
|
||||||
"react-loading-skeleton": "^3.1.0",
|
"react-loading-skeleton": "^3.1.0",
|
||||||
"react-lottie": "^1.2.3",
|
|
||||||
"react-markdown": "^8.0.3",
|
"react-markdown": "^8.0.3",
|
||||||
"react-redux": "^8.0.2",
|
"react-redux": "^8.0.2",
|
||||||
"react-router-dom": "^6.3.0",
|
"react-router-dom": "^6.3.0",
|
||||||
@ -110,7 +105,6 @@
|
|||||||
"@testing-library/react": "^13.3.0",
|
"@testing-library/react": "^13.3.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"@types/jest": "^27.5.2",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/react-lottie": "^1.2.6",
|
|
||||||
"@types/react-syntax-highlighter": "^15.5.5",
|
"@types/react-syntax-highlighter": "^15.5.5",
|
||||||
"autoprefixer": "^10.4.8",
|
"autoprefixer": "^10.4.8",
|
||||||
"babel-plugin-named-exports-order": "^0.0.2",
|
"babel-plugin-named-exports-order": "^0.0.2",
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>Scipaper</title>
|
<title>Freeland</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
@ -62,35 +62,26 @@
|
|||||||
},
|
},
|
||||||
"articlePage": {
|
"articlePage": {
|
||||||
"abstract": "Abstract",
|
"abstract": "Abstract",
|
||||||
"keywords": "Keywords",
|
"keywords": "Keywords"
|
||||||
"interactionButtons":{
|
|
||||||
"abstract": "Abstract",
|
|
||||||
"readFile": "Read File",
|
|
||||||
"download" : "Download",
|
|
||||||
"share" : "Share",
|
|
||||||
"cite" : "Cite",
|
|
||||||
"copied": "Copied"
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"createNew": "Create New",
|
"createNew": "Create an article",
|
||||||
"about": {
|
"about": {
|
||||||
"navTitle": "About",
|
"navTitle": "About the project",
|
||||||
"aboutProject": "About Scipaper",
|
"aboutProject": "About Scipaper",
|
||||||
"contacts": "Contacts",
|
"contacts": "Contacts",
|
||||||
"help": "Help"
|
"help": "Help"
|
||||||
},
|
},
|
||||||
"library": {
|
"library": {
|
||||||
"navTitle": "My library",
|
"navTitle": "My library",
|
||||||
"publications": "Publications",
|
"publications": "Publications",
|
||||||
"favorites": "Favorites",
|
"favorites": "Favorites",
|
||||||
"collections": "Collections",
|
"collections": "Collections",
|
||||||
"recentViewed": "History"
|
"recentViewed": "History"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"signIn": "Sign In",
|
"signIn": "Sign In",
|
||||||
"signUp": "Sign Up"
|
"signUp": "Sign Up"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
@ -105,15 +96,15 @@
|
|||||||
"supportedBy": "Created"
|
"supportedBy": "Created"
|
||||||
},
|
},
|
||||||
"mainPage": {
|
"mainPage": {
|
||||||
"title": "Scientific Library with Free Access",
|
"title": "Scientific Library with free access",
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
"article_one": "Articles",
|
"article_one": "Articles",
|
||||||
"article_few": "Articles",
|
"article_few": "Articles",
|
||||||
"article_many": "Articles",
|
"article_many": "Articles",
|
||||||
"advancedSearch": "Advanced search",
|
"advancedSearch": "Advanced search",
|
||||||
"featuredArticles": {
|
"featuredArticles": {
|
||||||
"title": "Featured articles",
|
"title": "Popular articles",
|
||||||
"descriptionPart1": "Select the category of science you are interested in",
|
"descriptionPart1": "Choose the one you are interested in",
|
||||||
"descriptionPart2": "Scientific category",
|
"descriptionPart2": "Scientific category",
|
||||||
"categories": {
|
"categories": {
|
||||||
"Medical": "Medical",
|
"Medical": "Medical",
|
||||||
@ -124,25 +115,14 @@
|
|||||||
"Social": "Social"
|
"Social": "Social"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"featuredAuthors": "Featured authors",
|
"featuredAuthors": "Popular authors",
|
||||||
"more": "See More ",
|
"more": "More",
|
||||||
"showAll": "Show all"
|
"showAll": "Show all"
|
||||||
},
|
},
|
||||||
"searchResults": {
|
"searchResults": {
|
||||||
"title": "Search results",
|
"title": "Search results",
|
||||||
"totalResults":"Total results",
|
"totalResults":"Total results",
|
||||||
"nothingFound": "Nothing found"
|
"nothingFound": "Nothing found"
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"authors":"Authors",
|
|
||||||
"publicationsType": "Publications Type",
|
|
||||||
"content":"Content",
|
|
||||||
"publisher":"Publisher",
|
|
||||||
"publicationTopic":"Publication Topic",
|
|
||||||
"appliedFitlers":"Applied Fitlers",
|
|
||||||
"clearAll":"Clear All",
|
|
||||||
"enterAuthorsName":"Enter Author Name",
|
|
||||||
"showAll":"Show All"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -73,15 +73,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"createNew": "Создать статью",
|
"createNew": "Создать статью",
|
||||||
"about": {
|
"about": {
|
||||||
"navTitle": "О проекте",
|
"navTitle": "О проекте",
|
||||||
"aboutProject": "О Scipaper",
|
"aboutProject": "О Scipaper",
|
||||||
"contacts": "Контакты",
|
"contacts": "Контакты",
|
||||||
"help": "Помощь"
|
"help": "Помощь"
|
||||||
},
|
},
|
||||||
"library": {
|
"library": {
|
||||||
"navTitle": "Моя библиотека",
|
"navTitle": "Моя библиотека",
|
||||||
"publications": "Публикации",
|
"publications": "Публикации",
|
||||||
"favorites": "Избранное",
|
"favorites": "Избранное",
|
||||||
"collections": "Коллекции",
|
"collections": "Коллекции",
|
||||||
@ -131,15 +131,5 @@
|
|||||||
"title": "Результаты поиска",
|
"title": "Результаты поиска",
|
||||||
"totalResults":"Всего найдено",
|
"totalResults":"Всего найдено",
|
||||||
"nothingFound": "Ничего не найдено"
|
"nothingFound": "Ничего не найдено"
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"authors":"Авторы",
|
|
||||||
"publicationsType": "Публикации",
|
|
||||||
"publisher":"Издатель",
|
|
||||||
"publicationTopic":"Тема публикации",
|
|
||||||
"appliedFitlers":"Фильтры",
|
|
||||||
"clearAll":"Очистить всё",
|
|
||||||
"enterAuthorsName":"Введите имя автора",
|
|
||||||
"showAll":"Показать все"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,16 @@ import { Article } from "../domain/articleEntity";
|
|||||||
import { create } from "../domain/articleModel";
|
import { create } from "../domain/articleModel";
|
||||||
import { FetchArticleByIdDTO } from "./dto/fetch_article_by_id_dto";
|
import { FetchArticleByIdDTO } from "./dto/fetch_article_by_id_dto";
|
||||||
import Failure from "core/failure";
|
import Failure from "core/failure";
|
||||||
import { integratorApiClient } from "core/httpClient";
|
|
||||||
|
|
||||||
const articleEndpoint = "/papers/"
|
|
||||||
|
|
||||||
async function getArticle(id: string): Promise<Article> {
|
async function getArticle(id: string): Promise<Article> {
|
||||||
try {
|
try {
|
||||||
const response = await integratorApiClient.get<FetchArticleByIdDTO>(
|
// await new Promise((res, _) => {
|
||||||
// `https://run.mocky.io/v3/62cd4581-d864-4d46-b1d6-02b45b5d1994/${id}`
|
// setTimeout(() => res(null), 2000);
|
||||||
|
// });
|
||||||
|
const response = await axios.get<FetchArticleByIdDTO>(
|
||||||
|
`https://run.mocky.io/v3/62cd4581-d864-4d46-b1d6-02b45b5d1994/${id}`
|
||||||
// `https://jsonplaceholder.typicode.com/posts/${id}`
|
// `https://jsonplaceholder.typicode.com/posts/${id}`
|
||||||
// `https://run.mocky.io/v3/066be3d8-0568-439a-8b20-062deed49a97`
|
// `http://scipaper.ru/v1/papers/${id}`
|
||||||
articleEndpoint + id
|
|
||||||
);
|
);
|
||||||
const dto = response.data;
|
const dto = response.data;
|
||||||
return create({
|
return create({
|
||||||
|
File diff suppressed because one or more lines are too long
@ -5,7 +5,7 @@
|
|||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { StyleType } from "core/_variants";
|
import { StyleType } from "core/_variants";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { ReactComponent as DeleteIcon } from "../assets/svg/xmark.svg";
|
import {ReactComponent as DeleteIcon} from "./Filters/svg/chest.svg"
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* Component props */
|
/* Component props */
|
||||||
@ -49,13 +49,11 @@ function Badge({
|
|||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
{closeOption && (
|
{closeOption && (
|
||||||
<button onClick={onClick} className="h-4 w-5">
|
<button
|
||||||
<div>
|
onClick={onClick}
|
||||||
<DeleteIcon
|
className=" text-white pr-1 pl-3 py-1"
|
||||||
className="relative top-1 left-1 h-4 w-5 fill-white hover:fill-white stroke-white
|
>
|
||||||
"
|
<div><DeleteIcon className="h-[9px] w-[9px]" /></div>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,198 +0,0 @@
|
|||||||
import { Menu, Transition } from "@headlessui/react";
|
|
||||||
import React, { Fragment } from "react";
|
|
||||||
import classNames from "classnames";
|
|
||||||
import { Disclosure } from "@headlessui/react";
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
/* Components */
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
import ContextMenuAction from "./drop-down-menu/ContextMenuAction";
|
|
||||||
import ContextMenu from "./drop-down-menu/ContextMenu";
|
|
||||||
import { Button } from "./Button/Button";
|
|
||||||
import Link from "./typography/Link";
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
/* Icons */
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
import { ReactComponent as SVGFavoriteOutlined } from "assets/svg/favorite-outlined.svg";
|
|
||||||
import { ReactComponent as SVGHamburger } from "assets/svg/hamburger.svg";
|
|
||||||
import { ReactComponent as SVGFolder } from "assets/svg/folder.svg";
|
|
||||||
import { ReactComponent as SVGFile } from "assets/svg/file.svg";
|
|
||||||
import { ReactComponent as SVGEye } from "assets/svg/eye.svg";
|
|
||||||
import { ReactComponent as SVGArrowUp } from "assets/svg/arrow-up.svg";
|
|
||||||
import { ReactComponent as SVGCaretDown } from "assets/svg/caret-down.svg";
|
|
||||||
|
|
||||||
type Props = React.ComponentPropsWithoutRef<"div">;
|
|
||||||
|
|
||||||
const Burger = (props: Props) => {
|
|
||||||
return (
|
|
||||||
<div {...props}>
|
|
||||||
<Menu as="div" className="relative inline-block text-left z-30">
|
|
||||||
<div>
|
|
||||||
<Menu.Button as={Button} emphasis="low">
|
|
||||||
<Button.Icon>
|
|
||||||
<SVGHamburger className="h-6 w-6" />
|
|
||||||
</Button.Icon>
|
|
||||||
</Menu.Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Transition
|
|
||||||
as={Fragment}
|
|
||||||
enter="transition ease-out duration-100"
|
|
||||||
enterFrom="transform opacity-0 scale-95"
|
|
||||||
enterTo="transform opacity-100 scale-100"
|
|
||||||
leave="transition ease-in duration-75"
|
|
||||||
leaveFrom="transform opacity-100 scale-100"
|
|
||||||
leaveTo="transform opacity-0 scale-95"
|
|
||||||
>
|
|
||||||
<Menu.Items
|
|
||||||
className="origin-top-right absolute right-0 mt-5 w-44 rounded-md
|
|
||||||
shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none"
|
|
||||||
>
|
|
||||||
<div className="py-1">
|
|
||||||
<Disclosure>
|
|
||||||
<Disclosure.Button className="uppercase text-base px-2 py-1">
|
|
||||||
<Link className="text-[#096DD9]">create new</Link>
|
|
||||||
</Disclosure.Button>
|
|
||||||
</Disclosure>
|
|
||||||
<hr />
|
|
||||||
<Disclosure>
|
|
||||||
{({ open }) => (
|
|
||||||
<>
|
|
||||||
<Disclosure.Button
|
|
||||||
className="uppercase px-2 flex justify-between w-full items-center
|
|
||||||
py-1
|
|
||||||
hover:bg-gray-100
|
|
||||||
text-base
|
|
||||||
"
|
|
||||||
>
|
|
||||||
my library
|
|
||||||
<SVGArrowUp
|
|
||||||
className={`${
|
|
||||||
open ? "rotate-180 transform" : "rotate-360"
|
|
||||||
} h-5 w-5 `}
|
|
||||||
/>
|
|
||||||
</Disclosure.Button>
|
|
||||||
|
|
||||||
<Link to="#" className="w-full">
|
|
||||||
<Disclosure.Panel
|
|
||||||
className="px-2 flex items-center font-normal gap-1 py-1 w-full ease-in-out duration-300
|
|
||||||
rounded
|
|
||||||
hover:bg-gray-200
|
|
||||||
text-base
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<SVGFile className="stroke-black w-4 h-4" />
|
|
||||||
My Publications
|
|
||||||
</Disclosure.Panel>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link to="#" className="w-full">
|
|
||||||
<Disclosure.Panel
|
|
||||||
className="px-2 flex items-center font-normal gap-1 py-1 w-full ease-in-out duration-300
|
|
||||||
rounded
|
|
||||||
hover:bg-gray-200
|
|
||||||
text-base
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<SVGFavoriteOutlined className="stroke-black w-4 h-4" />
|
|
||||||
My Favorites
|
|
||||||
</Disclosure.Panel>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link to="#" className="w-full">
|
|
||||||
<Disclosure.Panel
|
|
||||||
className="px-2 flex items-center font-normal gap-1 py-1 w-full ease-in-out duration-300
|
|
||||||
rounded
|
|
||||||
hover:bg-gray-200
|
|
||||||
text-base
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<SVGFolder className="stroke-black fill-black w-4 h-4" />
|
|
||||||
My Collections
|
|
||||||
</Disclosure.Panel>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link to="#" className="w-full">
|
|
||||||
<Disclosure.Panel
|
|
||||||
className="px-2 flex items-center font-normal gap-1 py-1 w-full ease-in-out duration-300
|
|
||||||
rounded
|
|
||||||
hover:bg-gray-200
|
|
||||||
text-base
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<SVGEye className="stroke-black w-4 h-4" />
|
|
||||||
Recent Viewed
|
|
||||||
</Disclosure.Panel>
|
|
||||||
</Link>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Disclosure>
|
|
||||||
<hr />
|
|
||||||
{/* Third list - start */}
|
|
||||||
<Disclosure>
|
|
||||||
{({ open }) => (
|
|
||||||
<>
|
|
||||||
<Disclosure.Button
|
|
||||||
className="uppercase px-2 flex justify-between w-full items-center
|
|
||||||
py-1
|
|
||||||
hover:bg-gray-100
|
|
||||||
text-base
|
|
||||||
"
|
|
||||||
>
|
|
||||||
About
|
|
||||||
<SVGArrowUp
|
|
||||||
className={`${
|
|
||||||
open ? "rotate-180 transform" : "rotate-360"
|
|
||||||
} h-5 w-5 `}
|
|
||||||
/>
|
|
||||||
</Disclosure.Button>
|
|
||||||
|
|
||||||
<Link to="#" className="w-full">
|
|
||||||
<Disclosure.Panel
|
|
||||||
className="px-2 flex items-center font-normal gap-1 py-1 w-full ease-in-out duration-300
|
|
||||||
rounded
|
|
||||||
hover:bg-gray-200
|
|
||||||
text-base
|
|
||||||
"
|
|
||||||
>
|
|
||||||
About Freeland
|
|
||||||
</Disclosure.Panel>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link to="#" className="w-full">
|
|
||||||
<Disclosure.Panel
|
|
||||||
className="px-2 flex items-center font-normal gap-1 py-1 w-full ease-in-out duration-300
|
|
||||||
rounded
|
|
||||||
hover:bg-gray-200
|
|
||||||
text-base
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Contact Us
|
|
||||||
</Disclosure.Panel>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link to="#" className="w-full">
|
|
||||||
<Disclosure.Panel
|
|
||||||
className="px-2 flex items-center font-normal gap-1 py-1 w-full ease-in-out duration-300
|
|
||||||
rounded
|
|
||||||
hover:bg-gray-200
|
|
||||||
text-base
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Help
|
|
||||||
</Disclosure.Panel>
|
|
||||||
</Link>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Disclosure>
|
|
||||||
{/* Third list - end */}
|
|
||||||
</div>
|
|
||||||
</Menu.Items>
|
|
||||||
</Transition>
|
|
||||||
</Menu>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Burger;
|
|
@ -13,7 +13,7 @@ type Props = {
|
|||||||
} & Omit<React.ComponentPropsWithoutRef<"div">, "">;
|
} & Omit<React.ComponentPropsWithoutRef<"div">, "">;
|
||||||
|
|
||||||
function CategoryCard({ count, title, iconChild, className, ...props }: Props) {
|
function CategoryCard({ count, title, iconChild, className, ...props }: Props) {
|
||||||
const [t, i18next] = useTranslation();
|
const [t, i18next] = useTranslation()
|
||||||
const iconChildStyle =
|
const iconChildStyle =
|
||||||
"h-7 fill-gray-500 stroke-gray-500 group-focus:fill-blue-600 group-active:fill-blue-600 group-focus:stroke-blue-600 group-active:stroke-blue-600";
|
"h-7 fill-gray-500 stroke-gray-500 group-focus:fill-blue-600 group-active:fill-blue-600 group-focus:stroke-blue-600 group-active:stroke-blue-600";
|
||||||
|
|
||||||
@ -43,8 +43,7 @@ function CategoryCard({ count, title, iconChild, className, ...props }: Props) {
|
|||||||
fontWeightVariant="normal"
|
fontWeightVariant="normal"
|
||||||
className="text-xs text-gray-500 group-active:text-blue-600 group-focus:text-blue-600"
|
className="text-xs text-gray-500 group-active:text-blue-600 group-focus:text-blue-600"
|
||||||
>
|
>
|
||||||
{count}{" "}
|
{count} {t("mainPage.article", {count: count}).toString()}
|
||||||
{t("mainPage.article_many", { count: count }).toString()}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,7 +22,7 @@ const Checkbox = ({ children, className, isChecked, ...props }: Props) => {
|
|||||||
)}
|
)}
|
||||||
htmlFor={props.id}
|
htmlFor={props.id}
|
||||||
>
|
>
|
||||||
<div className="w-5 h-5 relative">
|
<div className="w-6 h-6 relative">
|
||||||
<input
|
<input
|
||||||
className="peer appearance-none transition-colors bg-transparent border-2 border-gray-300 w-6 h-6
|
className="peer appearance-none transition-colors bg-transparent border-2 border-gray-300 w-6 h-6
|
||||||
rounded checked:bg-blue-500 checked:border-blue-500
|
rounded checked:bg-blue-500 checked:border-blue-500
|
||||||
@ -33,8 +33,8 @@ const Checkbox = ({ children, className, isChecked, ...props }: Props) => {
|
|||||||
checked={isChecked}
|
checked={isChecked}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
<div className="h-2 w-2 absolute top-0.5 left-0.5">
|
<div className="h-2 w-2 absolute top-0 left-0">
|
||||||
<Checkmark className="h-5 w-5 fill-white hover:fill-white stroke-white" />
|
<Checkmark className="h-6 w-6 fill-white hover:fill-white stroke-white" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{children}
|
{children}
|
||||||
|
@ -5,8 +5,6 @@ import React from "react";
|
|||||||
import Badge from "components/Badge";
|
import Badge from "components/Badge";
|
||||||
import { IProduct } from "./IProdutct";
|
import { IProduct } from "./IProdutct";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* Component props */
|
/* Component props */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
@ -25,9 +23,6 @@ export default function AppiledFilters({
|
|||||||
clearAll,
|
clearAll,
|
||||||
className,
|
className,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
|
|
||||||
const [t, i18next] = useTranslation()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
@ -37,13 +32,13 @@ export default function AppiledFilters({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex flex-row items-center justify-between space-x-3 ">
|
<div className="flex flex-row items-center justify-between space-x-3 ">
|
||||||
<div className="font-medium">{t("filters.appliedFitlers")}</div>
|
<div className="font-medium">Фильтры</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
onClick={clearAll}
|
onClick={clearAll}
|
||||||
className="font-normal text-sm text-gray-400"
|
className="font-normal text-sm text-gray-400"
|
||||||
>
|
>
|
||||||
{t("filters.clearAll")}
|
Очистить всё
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,6 @@ import SearchFilterBar from "./SearchFilterBar";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { useDebounce } from "./functions/debounce";
|
import { useDebounce } from "./functions/debounce";
|
||||||
import { IProduct } from "./IProdutct";
|
import { IProduct } from "./IProdutct";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -27,8 +26,6 @@ export default function Fiter({ className }: Props) {
|
|||||||
};
|
};
|
||||||
const debounced = useDebounce(query);
|
const debounced = useDebounce(query);
|
||||||
|
|
||||||
const [t, i18next] = useTranslation();
|
|
||||||
|
|
||||||
async function fetchProducts() {
|
async function fetchProducts() {
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
`https://dummyjson.com/products/search?q=${debounced}`
|
`https://dummyjson.com/products/search?q=${debounced}`
|
||||||
@ -86,24 +83,24 @@ export default function Fiter({ className }: Props) {
|
|||||||
delFilter={DelFilter}
|
delFilter={DelFilter}
|
||||||
clearAll={clearAll}
|
clearAll={clearAll}
|
||||||
></AppiledFilters>
|
></AppiledFilters>
|
||||||
<Disclosure caption={t("filters.authors")}>
|
<Disclosure caption="Авторы">
|
||||||
<SearchFilterBar
|
<SearchFilterBar
|
||||||
hints={hints}
|
hints={hints}
|
||||||
isChecked={isChecked}
|
isChecked={isChecked}
|
||||||
handleChange={handleChange}
|
handleChange={handleChange}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
query={query}
|
query={query}
|
||||||
placeHolder={t("filters.enterAuthorsName")}
|
placeHolder={"Введите имя автора"}
|
||||||
/>
|
/>
|
||||||
</Disclosure>
|
</Disclosure>
|
||||||
<Disclosure caption={t("filters.publicationsType")}>
|
<Disclosure caption="Публикации">
|
||||||
<p>{t("filters.content")}</p>
|
<p>контент...</p>
|
||||||
</Disclosure>
|
</Disclosure>
|
||||||
<Disclosure caption={t("filters.publisher")}>
|
<Disclosure caption="Тип издания">
|
||||||
<p>{t("filters.content")}</p>
|
<p>контент...</p>
|
||||||
</Disclosure>
|
</Disclosure>
|
||||||
<Disclosure caption={t("filters.publicationTopic")}>
|
<Disclosure caption="Тематика публикаций">
|
||||||
<p>{t("filters.content")}</p>
|
<p>контент...</p>
|
||||||
</Disclosure>
|
</Disclosure>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,10 +2,8 @@ import { useState, useCallback, Fragment } from "react";
|
|||||||
import { Combobox, Transition } from "@headlessui/react";
|
import { Combobox, Transition } from "@headlessui/react";
|
||||||
import { IProduct } from "./IProdutct";
|
import { IProduct } from "./IProdutct";
|
||||||
import Checkbox from "components/Checkbox";
|
import Checkbox from "components/Checkbox";
|
||||||
import { ReactComponent as SearchIcon } from "assets/svg/search.svg";
|
import { ReactComponent as SearchIcon } from "./svg/searchIcon.svg";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
hints: IProduct[];
|
hints: IProduct[];
|
||||||
@ -28,7 +26,6 @@ export default function SearchFilterBar({
|
|||||||
}: Props): JSX.Element {
|
}: Props): JSX.Element {
|
||||||
const [checkList, setCheckList] = useState(hints);
|
const [checkList, setCheckList] = useState(hints);
|
||||||
const [showFilters, SetShowFilters] = useState(false);
|
const [showFilters, SetShowFilters] = useState(false);
|
||||||
const [t, i18next] = useTranslation()
|
|
||||||
|
|
||||||
const ShowAllFilters = useCallback(() => {
|
const ShowAllFilters = useCallback(() => {
|
||||||
SetShowFilters((prev) => !prev);
|
SetShowFilters((prev) => !prev);
|
||||||
@ -47,8 +44,8 @@ export default function SearchFilterBar({
|
|||||||
>
|
>
|
||||||
<div className="basis-6 ">
|
<div className="basis-6 ">
|
||||||
<Combobox.Button>
|
<Combobox.Button>
|
||||||
<div className="pl-1 pt-1.5">
|
<div className="pl-1 pt-1">
|
||||||
<SearchIcon className="h-5 w-6 fill-gray-400 hover:fill-gray-400 stroke-gray-400" />
|
<SearchIcon />
|
||||||
</div>
|
</div>
|
||||||
</Combobox.Button>
|
</Combobox.Button>
|
||||||
</div>
|
</div>
|
||||||
@ -76,18 +73,18 @@ export default function SearchFilterBar({
|
|||||||
{
|
{
|
||||||
"max-h-60 h-60 overflow-auto": showFilters === true,
|
"max-h-60 h-60 overflow-auto": showFilters === true,
|
||||||
"max-h-40 h-40 overflow-hidden":
|
"max-h-40 h-40 overflow-hidden":
|
||||||
showFilters === false || hints.length <= 5,
|
showFilters === false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
])}
|
])}
|
||||||
>
|
>
|
||||||
<li className="">
|
<li className="">
|
||||||
{hints.length >= 6 && query !== "" && (
|
{hints.length >= 5 && query !== "" && (
|
||||||
<button
|
<button
|
||||||
onClick={ShowAllFilters}
|
onClick={ShowAllFilters}
|
||||||
className="text-right text-blue-500 pl-2 text-sm font-medium"
|
className="text-right text-blue-500 pl-2 text-sm font-medium"
|
||||||
>
|
>
|
||||||
{t("filters.showAll")}({hints.length})
|
Показать всё({hints.length})
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
@ -105,7 +102,7 @@ export default function SearchFilterBar({
|
|||||||
</li>
|
</li>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<p className="text-blue-300 pl-2">Ничего не найдено</p>
|
<p className="text-blue-300 pl-2">Nothing Found</p>
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
)}
|
)}
|
||||||
|
4
src/components/Filters/svg/chest.svg
Normal file
4
src/components/Filters/svg/chest.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="12" height="13" viewBox="0 0 12 13" fill="white" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M10.9497 11.4498L1.05026 1.55027" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
<path d="M10.9497 1.55029L1.05025 11.4498" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 304 B |
3
src/components/Filters/svg/searchIcon.svg
Normal file
3
src/components/Filters/svg/searchIcon.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15.1003 14.1184L10.4628 9.48086C11.1824 8.55051 11.5717 7.41301 11.5717 6.21658C11.5717 4.78444 11.0128 3.44158 10.0021 2.42908C8.99135 1.41658 7.64492 0.859436 6.21456 0.859436C4.78421 0.859436 3.43778 1.41836 2.42706 2.42908C1.41456 3.43979 0.857422 4.78444 0.857422 6.21658C0.857422 7.64694 1.41635 8.99336 2.42706 10.0041C3.43778 11.0166 4.78242 11.5737 6.21456 11.5737C7.41099 11.5737 8.54671 11.1844 9.47707 10.4666L14.1146 15.1023C14.1282 15.1159 14.1443 15.1267 14.1621 15.1341C14.1799 15.1414 14.1989 15.1452 14.2181 15.1452C14.2374 15.1452 14.2564 15.1414 14.2742 15.1341C14.292 15.1267 14.3081 15.1159 14.3217 15.1023L15.1003 14.3255C15.1139 14.3119 15.1247 14.2958 15.132 14.278C15.1394 14.2602 15.1432 14.2412 15.1432 14.2219C15.1432 14.2027 15.1394 14.1837 15.132 14.1659C15.1247 14.1481 15.1139 14.132 15.1003 14.1184ZM9.04314 9.04515C8.28599 9.80051 7.28242 10.2166 6.21456 10.2166C5.14671 10.2166 4.14314 9.80051 3.38599 9.04515C2.63064 8.28801 2.21456 7.28444 2.21456 6.21658C2.21456 5.14872 2.63064 4.14336 3.38599 3.38801C4.14314 2.63265 5.14671 2.21658 6.21456 2.21658C7.28242 2.21658 8.28778 2.63086 9.04314 3.38801C9.79849 4.14515 10.2146 5.14872 10.2146 6.21658C10.2146 7.28444 9.79849 8.28979 9.04314 9.04515Z" fill="#8C8C8C"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -1,89 +0,0 @@
|
|||||||
import React, { Fragment, useState } from "react";
|
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
import { Button } from "./Button/Button";
|
|
||||||
import { Menu, Transition } from "@headlessui/react";
|
|
||||||
import classNames from "classnames";
|
|
||||||
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
||||||
import { faLanguage } from "@fortawesome/free-solid-svg-icons";
|
|
||||||
|
|
||||||
type Props = React.ComponentPropsWithoutRef<"div">;
|
|
||||||
|
|
||||||
const LocalizationButton = (props: Props) => {
|
|
||||||
const { t, i18n } = useTranslation();
|
|
||||||
const changeLanguage = (lng: string) => {
|
|
||||||
i18n.changeLanguage(lng);
|
|
||||||
setLanguage(lng);
|
|
||||||
};
|
|
||||||
const [language, setLanguage] = useState("en");
|
|
||||||
return (
|
|
||||||
<div {...props}>
|
|
||||||
<Menu as="div" className="relative inline-block text-left">
|
|
||||||
<div>
|
|
||||||
<Menu.Button
|
|
||||||
as={Button}
|
|
||||||
emphasis="low"
|
|
||||||
className="flex items-center gap-2 border"
|
|
||||||
>
|
|
||||||
<div className=" w-4">
|
|
||||||
<FontAwesomeIcon icon={faLanguage} />
|
|
||||||
</div>
|
|
||||||
{/* {language} */}
|
|
||||||
</Menu.Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Transition
|
|
||||||
as={Fragment}
|
|
||||||
enter="transition ease-out duration-100"
|
|
||||||
enterFrom="transform opacity-0 scale-95"
|
|
||||||
enterTo="transform opacity-100 scale-100"
|
|
||||||
leave="transition ease-in duration-75"
|
|
||||||
leaveFrom="transform opacity-100 scale-100"
|
|
||||||
leaveTo="transform opacity-0 scale-95"
|
|
||||||
>
|
|
||||||
<Menu.Items
|
|
||||||
className="origin-top-right absolute right-0 mt-5 w-12 rounded-md
|
|
||||||
shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none"
|
|
||||||
>
|
|
||||||
<div className="py-1">
|
|
||||||
<Menu.Item>
|
|
||||||
{({ active }) => (
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
changeLanguage("en");
|
|
||||||
}}
|
|
||||||
className={classNames(
|
|
||||||
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
|
|
||||||
"block px-4 py-2 text-sm"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
En
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Item>
|
|
||||||
{({ active }) => (
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
changeLanguage("ru");
|
|
||||||
}}
|
|
||||||
|
|
||||||
className={classNames(
|
|
||||||
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
|
|
||||||
"block px-4 py-2 text-sm"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Ru
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</Menu.Item>
|
|
||||||
</div>
|
|
||||||
</Menu.Items>
|
|
||||||
</Transition>
|
|
||||||
</Menu>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LocalizationButton;
|
|
File diff suppressed because one or more lines are too long
39
src/components/Logofreeland.tsx
Executable file
39
src/components/Logofreeland.tsx
Executable file
File diff suppressed because one or more lines are too long
@ -168,12 +168,14 @@ const FeaturedArticlesCards = () => {
|
|||||||
</Card.CardContent>
|
</Card.CardContent>
|
||||||
|
|
||||||
<Card.CardAction href={Articale.Link}>
|
<Card.CardAction href={Articale.Link}>
|
||||||
<Typography
|
<Link to="*">
|
||||||
className="text-blue-500 font-bold"
|
<Typography
|
||||||
fontWeightVariant="bold"
|
className="text-blue-500 font-bold"
|
||||||
>
|
fontWeightVariant="bold"
|
||||||
{t("mainPage.more")}
|
>
|
||||||
</Typography>
|
{t("mainPage.more")}
|
||||||
|
</Typography>
|
||||||
|
</Link>
|
||||||
<SVGCaretRight className="fill-blue-500 w-4 h-4" />
|
<SVGCaretRight className="fill-blue-500 w-4 h-4" />
|
||||||
</Card.CardAction>
|
</Card.CardAction>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -2,14 +2,16 @@
|
|||||||
/* Imports */
|
/* Imports */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { t as nextT } from "i18next";
|
import {t as nextT} from "i18next";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { SearchBar } from "../../search/SearchBar";
|
import { SearchBar } from "../../search/SearchBar";
|
||||||
import { formatNumber } from "core/helpers";
|
import { formatNumber } from "core/helpers";
|
||||||
|
|
||||||
export default function MainSection() {
|
export default function MainSection() {
|
||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
const amountArticles = 4202020;
|
const amountArticles = 4202020
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="bg-main bg-center bg-cover bg-origin-border bg-no-repeat min-h-[100vh] py-32 px-2 sm:px-6 md:px-6 lg:px-0 items-center flex justify-center ">
|
<section className="bg-main bg-center bg-cover bg-origin-border bg-no-repeat min-h-[100vh] py-32 px-2 sm:px-6 md:px-6 lg:px-0 items-center flex justify-center ">
|
||||||
@ -19,14 +21,8 @@ export default function MainSection() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row items-center justify-center space-x-3 pt-2">
|
<div className="flex flex-row items-center justify-center space-x-3 pt-2">
|
||||||
<div className=" text-2xl text-gray-400">{t("mainPage.search")}</div>
|
<div className=" text-2xl text-gray-400">{t("mainPage.search")}</div>
|
||||||
<div className=" text-3xl text-blue-500">
|
<div className=" text-3xl text-blue-500">{formatNumber(amountArticles)}</div>
|
||||||
{formatNumber(amountArticles)}
|
<div className=" text-2xl text-gray-400">{nextT("mainPage.article", {count: amountArticles}).toString()}</div>
|
||||||
</div>
|
|
||||||
<div className=" text-2xl text-gray-400">
|
|
||||||
{nextT("mainPage.article_many", {
|
|
||||||
count: amountArticles,
|
|
||||||
}).toString()}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="max-w-xl m-auto pt-16 ">
|
<div className="max-w-xl m-auto pt-16 ">
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* MarkDown */
|
/* MarkDown */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
@ -16,137 +18,33 @@ import Heading from "./typography/Heading";
|
|||||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||||
import { dark } from "react-syntax-highlighter/dist/esm/styles/prism";
|
import { dark } from "react-syntax-highlighter/dist/esm/styles/prism";
|
||||||
import Link from "./typography/Link";
|
import Link from "./typography/Link";
|
||||||
import style from "react-syntax-highlighter/dist/esm/styles/hljs/a11y-dark";
|
import { indexOf } from "lodash";
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
markdown: string;
|
markdown: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Markdown = ({ markdown }: Props) => {
|
const Markdown = ({ markdown }: Props) => {
|
||||||
|
let newMarkdown = markdown.replace(/\n/g, " \n");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
remarkPlugins={[remarkGfm]}
|
remarkPlugins={[remarkGfm]}
|
||||||
children={markdown}
|
children={newMarkdown}
|
||||||
components={{
|
components={{
|
||||||
ul: ({ node, ...props }) => (
|
h1: Heading,
|
||||||
<ul
|
h2: Typography,
|
||||||
style={{
|
a: (props) => {
|
||||||
listStyleType: "disc",
|
return (
|
||||||
}}
|
<Link
|
||||||
className="mx-8"
|
href={props.href}
|
||||||
{...props}
|
className="text-sky-600 font-bold text-base"
|
||||||
/>
|
{...props}
|
||||||
),
|
>
|
||||||
|
{props.children}
|
||||||
ol: ({ node, ...props }) => (
|
</Link>
|
||||||
<ol className="list-decimal mx-8" {...props} />
|
);
|
||||||
),
|
},
|
||||||
|
|
||||||
h1: ({ node, ...props }) => (
|
|
||||||
<h1
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginInlineEnd: 0,
|
|
||||||
marginInlineStart: 0,
|
|
||||||
marginBlockStart: 11,
|
|
||||||
marginBlockEnd: 11,
|
|
||||||
|
|
||||||
fontSize: 32,
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
|
|
||||||
h2: ({ node, ...props }) => (
|
|
||||||
<h1
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
|
|
||||||
marginInlineEnd: 0,
|
|
||||||
marginInlineStart: 0,
|
|
||||||
|
|
||||||
marginBlockStart: 13.28,
|
|
||||||
marginBlockEnd: 13.28,
|
|
||||||
|
|
||||||
fontSize: 24,
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
|
|
||||||
h3: ({ node, ...props }) => (
|
|
||||||
<h1
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
|
|
||||||
marginInlineEnd: 0,
|
|
||||||
marginInlineStart: 0,
|
|
||||||
|
|
||||||
marginBlockStart: 16,
|
|
||||||
marginBlockEnd: 16,
|
|
||||||
|
|
||||||
fontSize: 18.72,
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
|
|
||||||
h4: ({ node, ...props }) => (
|
|
||||||
<h1
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
|
|
||||||
marginInlineEnd: 0,
|
|
||||||
marginInlineStart: 0,
|
|
||||||
|
|
||||||
marginBlockStart: 21.28,
|
|
||||||
marginBlockEnd: 21.28,
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
|
|
||||||
h5: ({ node, ...props }) => (
|
|
||||||
<h1
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
|
|
||||||
marginInlineEnd: 0,
|
|
||||||
marginInlineStart: 0,
|
|
||||||
|
|
||||||
marginBlockStart: 26.72,
|
|
||||||
marginBlockEnd: 26.72,
|
|
||||||
|
|
||||||
fontSize: 13.28,
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
|
|
||||||
h6: ({ node, ...props }) => (
|
|
||||||
<h1
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
|
|
||||||
marginInlineEnd: 0,
|
|
||||||
marginInlineStart: 0,
|
|
||||||
|
|
||||||
marginBlockStart: 37.28,
|
|
||||||
marginBlockEnd: 37.28,
|
|
||||||
|
|
||||||
fontSize: 10.72,
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
p: Typography,
|
|
||||||
|
|
||||||
a: ({ node, ...props }) => (
|
|
||||||
<Link
|
|
||||||
className=" inline-flex text-sm font-bold text-blue-500"
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
|
|
||||||
code({ node, inline, className, children, ...props }) {
|
code({ node, inline, className, children, ...props }) {
|
||||||
const match = /language-(\w+)/.exec(className || "");
|
const match = /language-(\w+)/.exec(className || "");
|
||||||
|
@ -36,7 +36,7 @@ export const SearchResultSection = () => {
|
|||||||
{t("searchResults.title")}
|
{t("searchResults.title")}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography className="text-gray-300 text-sm">
|
<Typography className="text-gray-300 text-sm">
|
||||||
{t("searchResults.totalResults")}: {searchResults?.meta.total}
|
{t("searchResults.totalResults")}: {searchResults?.meta.total}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
<hr className="w-full border-gray-100" />
|
<hr className="w-full border-gray-100" />
|
||||||
|
@ -12,7 +12,6 @@ import * as ArticlePart from "../../components/Article/Article";
|
|||||||
import BaseLayout from "components/BaseLayout";
|
import BaseLayout from "components/BaseLayout";
|
||||||
import Container from "components/Container";
|
import Container from "components/Container";
|
||||||
import NotFound from "./NotFound";
|
import NotFound from "./NotFound";
|
||||||
import Markdown from "components/Markdown";
|
|
||||||
|
|
||||||
const AnArticleBody = () => {
|
const AnArticleBody = () => {
|
||||||
const store = useArticleStore();
|
const store = useArticleStore();
|
||||||
@ -47,12 +46,7 @@ const AnArticleBody = () => {
|
|||||||
<ArticlePart.Article.Title className="text-3xl">
|
<ArticlePart.Article.Title className="text-3xl">
|
||||||
{article?.title}
|
{article?.title}
|
||||||
</ArticlePart.Article.Title>
|
</ArticlePart.Article.Title>
|
||||||
|
<div className="py-6">{article?.content}</div>
|
||||||
<div className="py-6">
|
|
||||||
<Markdown
|
|
||||||
markdown={article?.content ?? ''}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -3,19 +3,7 @@ import Container from "components/Container";
|
|||||||
import { Button } from "components/Button/Button";
|
import { Button } from "components/Button/Button";
|
||||||
import Link from "components/typography/Link";
|
import Link from "components/typography/Link";
|
||||||
|
|
||||||
import Lottie from "react-lottie";
|
|
||||||
import animationData from "../../assets/lotties/notFoundAnimation.json";
|
|
||||||
|
|
||||||
const NotFound = () => {
|
const NotFound = () => {
|
||||||
const defaultOptions = {
|
|
||||||
loop: true,
|
|
||||||
autoplay: true,
|
|
||||||
animationData: animationData,
|
|
||||||
rendererSettings: {
|
|
||||||
preserveAspectRatio: "xMidYMid slice",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
variant="straight"
|
variant="straight"
|
||||||
@ -23,8 +11,13 @@ const NotFound = () => {
|
|||||||
font-serif h-screen my-auto
|
font-serif h-screen my-auto
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<Lottie options={defaultOptions} height={200} width={200} />
|
<div
|
||||||
<span className="font-bold text-5xl ">404</span>
|
className="bg-[url('https://cdn.dribbble.com/users/285475/screenshots/2083086/dribbble_1.gif')]
|
||||||
|
h-[450px]
|
||||||
|
w-full text-center text-7xl "
|
||||||
|
>
|
||||||
|
404
|
||||||
|
</div>
|
||||||
<h3 className="font-bold text-2xl text-center">Page does not exist</h3>
|
<h3 className="font-bold text-2xl text-center">Page does not exist</h3>
|
||||||
<h4 className="text-center">
|
<h4 className="text-center">
|
||||||
Maybe you got a broken link, or maybe you made a misprint in the address
|
Maybe you got a broken link, or maybe you made a misprint in the address
|
||||||
|
@ -5,6 +5,7 @@ import { useState, useTransition } from "react";
|
|||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
import ContextMenuAction from "../drop-down-menu/ContextMenuAction";
|
import ContextMenuAction from "../drop-down-menu/ContextMenuAction";
|
||||||
import ContextMenu from "../drop-down-menu/ContextMenu";
|
import ContextMenu from "../drop-down-menu/ContextMenu";
|
||||||
|
import Logofreeland from "../Logofreeland";
|
||||||
import { Button } from "../Button/Button";
|
import { Button } from "../Button/Button";
|
||||||
import Avatar from "../Avatar";
|
import Avatar from "../Avatar";
|
||||||
import Navbar from "../Navbar";
|
import Navbar from "../Navbar";
|
||||||
@ -24,10 +25,6 @@ import {
|
|||||||
} from "components/icons";
|
} from "components/icons";
|
||||||
import i18n from "localization/i18n";
|
import i18n from "localization/i18n";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import Link from "components/typography/Link";
|
|
||||||
import LocalizationButton from "components/LocalizationButton";
|
|
||||||
import LogoScipaper from "components/LogoScipaper";
|
|
||||||
import Burger from "components/Burger";
|
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
const [authenticated, setAuthenticated] = useState(false);
|
const [authenticated, setAuthenticated] = useState(false);
|
||||||
@ -52,14 +49,14 @@ const Header = () => {
|
|||||||
{/* Logo and Menu */}
|
{/* Logo and Menu */}
|
||||||
<div className="flex gap-8 xl:gap-x-16">
|
<div className="flex gap-8 xl:gap-x-16">
|
||||||
{/* Logo - start - className="w-7 sm:w-10 " /> */}
|
{/* Logo - start - className="w-7 sm:w-10 " /> */}
|
||||||
<Link className="Logo flex items-center gap-1 sm:gap-2 " to="/">
|
<a className="Logo flex items-center gap-1 sm:gap-2 " href="/">
|
||||||
<Logo
|
<Logo
|
||||||
className={classNames(authenticated ? "w-10" : "w-7 sm:w-10")}
|
className={classNames(authenticated ? "w-10" : "w-7 sm:w-10")}
|
||||||
/>
|
/>
|
||||||
<LogoScipaper
|
<Logofreeland
|
||||||
className={classNames(authenticated ? "w-28" : "w-20 sm:w-28")}
|
className={classNames(authenticated ? "w-28" : "w-20 sm:w-28")}
|
||||||
/>
|
/>
|
||||||
</Link>
|
</a>
|
||||||
{/* Logo - end - */}
|
{/* Logo - end - */}
|
||||||
|
|
||||||
{/* Menu( Create new - My library - About ) Start */}
|
{/* Menu( Create new - My library - About ) Start */}
|
||||||
@ -72,36 +69,36 @@ const Header = () => {
|
|||||||
className="text-blue-500 px-4 font-bold uppercase"
|
className="text-blue-500 px-4 font-bold uppercase"
|
||||||
to="/create-new"
|
to="/create-new"
|
||||||
>
|
>
|
||||||
{t("navbar.createNew")}
|
{t('navbar.createNew')}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
{/* Link Create now - end - */}
|
{/* Link Create now - end - */}
|
||||||
|
|
||||||
{/* Dropdown Menu My library - start - */}
|
{/* Dropdown Menu My library - start - */}
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
emphasis="high"
|
emphasis="high"
|
||||||
button={t("navbar.library.navTitle")}
|
button={t('navbar.library.navTitle')}
|
||||||
className="border-none uppercase"
|
className="border-none uppercase"
|
||||||
>
|
>
|
||||||
<ContextMenuAction
|
<ContextMenuAction
|
||||||
caption={t("navbar.library.publications")}
|
caption={t('navbar.library.publications')}
|
||||||
action={() => console.log("My publications")}
|
action={() => console.log("My publications")}
|
||||||
icon={<SVGFile className="stroke-black " />}
|
icon={<SVGFile className="stroke-black " />}
|
||||||
></ContextMenuAction>
|
></ContextMenuAction>
|
||||||
|
|
||||||
<ContextMenuAction
|
<ContextMenuAction
|
||||||
caption={t("navbar.library.favorites")}
|
caption={t('navbar.library.favorites')}
|
||||||
action={() => console.log("My Favorites")}
|
action={() => console.log("My Favorites")}
|
||||||
icon={<SVGFavoriteOutlined className="stroke-black" />}
|
icon={<SVGFavoriteOutlined className="stroke-black" />}
|
||||||
></ContextMenuAction>
|
></ContextMenuAction>
|
||||||
|
|
||||||
<ContextMenuAction
|
<ContextMenuAction
|
||||||
caption={t("navbar.library.collections")}
|
caption={t('navbar.library.collections')}
|
||||||
action={() => console.log("My Collections")}
|
action={() => console.log("My Collections")}
|
||||||
icon={<SVGFolder className="stroke-black fill-black" />}
|
icon={<SVGFolder className="stroke-black fill-black" />}
|
||||||
></ContextMenuAction>
|
></ContextMenuAction>
|
||||||
|
|
||||||
<ContextMenuAction
|
<ContextMenuAction
|
||||||
caption={t("navbar.library.recentViewed")}
|
caption={t('navbar.library.recentViewed')}
|
||||||
action={() => console.log("Recent Viewed")}
|
action={() => console.log("Recent Viewed")}
|
||||||
icon={<SVGEye className="stroke-black " />}
|
icon={<SVGEye className="stroke-black " />}
|
||||||
></ContextMenuAction>
|
></ContextMenuAction>
|
||||||
@ -111,21 +108,21 @@ const Header = () => {
|
|||||||
{/* Dropdown Menu About - start - */}
|
{/* Dropdown Menu About - start - */}
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
emphasis="high"
|
emphasis="high"
|
||||||
button={t("navbar.about.navTitle")}
|
button={t('navbar.about.navTitle')}
|
||||||
className="border-none uppercase"
|
className="border-none uppercase"
|
||||||
>
|
>
|
||||||
<ContextMenuAction
|
<ContextMenuAction
|
||||||
caption={t("navbar.about.aboutProject")}
|
caption={t('navbar.about.aboutProject')}
|
||||||
action={() => console.log("About Freeland")}
|
action={() => console.log("About Freeland")}
|
||||||
></ContextMenuAction>
|
></ContextMenuAction>
|
||||||
|
|
||||||
<ContextMenuAction
|
<ContextMenuAction
|
||||||
caption={t("navbar.about.contacts")}
|
caption={t('navbar.about.contacts')}
|
||||||
action={() => console.log("Contact Us")}
|
action={() => console.log("Contact Us")}
|
||||||
></ContextMenuAction>
|
></ContextMenuAction>
|
||||||
|
|
||||||
<ContextMenuAction
|
<ContextMenuAction
|
||||||
caption={t("navbar.about.help")}
|
caption={t('navbar.about.help')}
|
||||||
action={() => console.log("Help")}
|
action={() => console.log("Help")}
|
||||||
></ContextMenuAction>
|
></ContextMenuAction>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
@ -138,43 +135,40 @@ const Header = () => {
|
|||||||
<div className="flex items-center font-bold text-sm gap-1 md:gap-2 ">
|
<div className="flex items-center font-bold text-sm gap-1 md:gap-2 ">
|
||||||
{!authenticated
|
{!authenticated
|
||||||
? [
|
? [
|
||||||
<>
|
<Button
|
||||||
<LocalizationButton className="hidden md:flex" />
|
emphasis="low"
|
||||||
<Button
|
onClick={onClick}
|
||||||
emphasis="low"
|
className="text-xs sm:px-4 sm:text-sm "
|
||||||
onClick={onClick}
|
>
|
||||||
className="text-xs sm:px-4 sm:text-sm "
|
{t('navbar.auth.signIn')}
|
||||||
>
|
</Button>,
|
||||||
{t("navbar.auth.signIn")}
|
<Button
|
||||||
</Button>
|
emphasis="medium"
|
||||||
</>,
|
className="hidden md:flex"
|
||||||
<Button
|
onClick={onClick}
|
||||||
emphasis="medium"
|
>
|
||||||
className="hidden md:flex"
|
{t('navbar.auth.signUp')}
|
||||||
onClick={onClick}
|
</Button>,
|
||||||
>
|
]
|
||||||
{t("navbar.auth.signUp")}
|
|
||||||
</Button>,
|
|
||||||
]
|
|
||||||
: [
|
: [
|
||||||
<Button emphasis="low">
|
<Button emphasis="low">
|
||||||
<Button.Icon>
|
<Button.Icon>
|
||||||
{!notification ? (
|
{!notification ? (
|
||||||
<SVGBell className="h-6 w-6 fill-gray-900 stroke-gray-900" />
|
<SVGBell className="h-6 w-6 fill-gray-900 stroke-gray-900" />
|
||||||
) : (
|
) : (
|
||||||
<SVGBellNotification className="h-6 w-6 fill-gray-900 stroke-gray-900" />
|
<SVGBellNotification className="h-6 w-6 fill-gray-900 stroke-gray-900" />
|
||||||
)}
|
)}
|
||||||
</Button.Icon>
|
</Button.Icon>
|
||||||
</Button>,
|
</Button>,
|
||||||
|
|
||||||
<Button emphasis="low" className="hidden lg:flex">
|
<Button emphasis="low" className="hidden lg:flex">
|
||||||
<Button.Icon>
|
<Button.Icon>
|
||||||
<Avatar className="bg-[rgb(255,122,69)] text-white">K</Avatar>
|
<Avatar className="bg-[rgb(255,122,69)] text-white">K</Avatar>
|
||||||
</Button.Icon>
|
</Button.Icon>
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
{/* Burger component will be shown for the small screens */}
|
{/* Burger component will be shown for the small screens */}
|
||||||
<Burger className="block lg:hidden" />
|
<Navbar className="block lg:hidden" />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
|
@ -51,7 +51,7 @@ export default function Link({
|
|||||||
: style
|
: style
|
||||||
}
|
}
|
||||||
aria-disabled={disabled}
|
aria-disabled={disabled}
|
||||||
className={classNames("flex items-center", className)}
|
className="flex items-center"
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
@ -22,7 +22,7 @@ const fallbackLng: Langs = "ru";
|
|||||||
|
|
||||||
i18n
|
i18n
|
||||||
.use(Backend)
|
.use(Backend)
|
||||||
.use(LanguageDetector)
|
// .use(LanguageDetector)
|
||||||
.use(initReactI18next)
|
.use(initReactI18next)
|
||||||
.init({
|
.init({
|
||||||
debug: process.env.NODE_ENV === "development" ? true : false,
|
debug: process.env.NODE_ENV === "development" ? true : false,
|
||||||
|
@ -10,8 +10,8 @@ const searchEndpoint = "/papers/search";
|
|||||||
async function search(request: string): Promise<SearchResults> {
|
async function search(request: string): Promise<SearchResults> {
|
||||||
try {
|
try {
|
||||||
const response = await integratorApiClient.get<SearchResultsDTO>(
|
const response = await integratorApiClient.get<SearchResultsDTO>(
|
||||||
searchEndpoint + `?query=` + request
|
// searchEndpoint + `?query=` + request
|
||||||
// "https://run.mocky.io/v3/ea705665-2479-4039-8b81-412e011fc145"
|
"https://run.mocky.io/v3/ea705665-2479-4039-8b81-412e011fc145"
|
||||||
);
|
);
|
||||||
const dto = response.data;
|
const dto = response.data;
|
||||||
return create({
|
return create({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user