├── .babelrc ├── .env.example ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── src ├── App.js ├── Router.js ├── api │ ├── auth.js │ ├── data.js │ ├── errors.js │ └── geo.js ├── assets │ ├── agreement │ │ ├── contributor_terms.html │ │ └── terms_of_service.html │ ├── countries.json │ ├── fonts │ │ ├── ibmplexmono │ │ │ ├── Ibmplexmono.ttf │ │ │ ├── Ibmplexmono.woff │ │ │ ├── Ibmplexmono.woff2 │ │ │ ├── Ibmplexmonobold.ttf │ │ │ ├── Ibmplexmonobold.woff │ │ │ ├── Ibmplexmonobold.woff2 │ │ │ ├── Ibmplexmonobolditalic.ttf │ │ │ ├── Ibmplexmonobolditalic.woff │ │ │ ├── Ibmplexmonobolditalic.woff2 │ │ │ ├── Ibmplexmonoextralight.ttf │ │ │ ├── Ibmplexmonoextralight.woff │ │ │ ├── Ibmplexmonoextralight.woff2 │ │ │ ├── Ibmplexmonoextralightitalic.ttf │ │ │ ├── Ibmplexmonoextralightitalic.woff │ │ │ ├── Ibmplexmonoextralightitalic.woff2 │ │ │ ├── Ibmplexmonoitalic.ttf │ │ │ ├── Ibmplexmonoitalic.woff │ │ │ ├── Ibmplexmonoitalic.woff2 │ │ │ ├── Ibmplexmonolight.ttf │ │ │ ├── Ibmplexmonolight.woff │ │ │ ├── Ibmplexmonolight.woff2 │ │ │ ├── Ibmplexmonolightitalic.ttf │ │ │ ├── Ibmplexmonolightitalic.woff │ │ │ ├── Ibmplexmonolightitalic.woff2 │ │ │ ├── Ibmplexmonomedium.ttf │ │ │ ├── Ibmplexmonomedium.woff │ │ │ ├── Ibmplexmonomedium.woff2 │ │ │ ├── Ibmplexmonomediumitalic.ttf │ │ │ ├── Ibmplexmonomediumitalic.woff │ │ │ ├── Ibmplexmonomediumitalic.woff2 │ │ │ ├── Ibmplexmonosemibold.ttf │ │ │ ├── Ibmplexmonosemibold.woff │ │ │ ├── Ibmplexmonosemibold.woff2 │ │ │ ├── Ibmplexmonosemibolditalic.ttf │ │ │ ├── Ibmplexmonosemibolditalic.woff │ │ │ ├── Ibmplexmonosemibolditalic.woff2 │ │ │ ├── Ibmplexmonothin.ttf │ │ │ ├── Ibmplexmonothin.woff │ │ │ ├── Ibmplexmonothin.woff2 │ │ │ ├── Ibmplexmonothinitalic.ttf │ │ │ ├── Ibmplexmonothinitalic.woff │ │ │ └── Ibmplexmonothinitalic.woff2 │ │ └── ibmplexsans │ │ │ ├── Ibmplexsans.ttf │ │ │ ├── Ibmplexsans.woff │ │ │ ├── Ibmplexsans.woff2 │ │ │ ├── Ibmplexsansbold.ttf │ │ │ ├── Ibmplexsansbold.woff │ │ │ ├── Ibmplexsansbold.woff2 │ │ │ ├── Ibmplexsansbolditalic.ttf │ │ │ ├── Ibmplexsansbolditalic.woff │ │ │ ├── Ibmplexsansbolditalic.woff2 │ │ │ ├── Ibmplexsansextralight.ttf │ │ │ ├── Ibmplexsansextralight.woff │ │ │ ├── Ibmplexsansextralight.woff2 │ │ │ ├── Ibmplexsansextralightitalic.ttf │ │ │ ├── Ibmplexsansextralightitalic.woff │ │ │ ├── Ibmplexsansextralightitalic.woff2 │ │ │ ├── Ibmplexsansitalic.ttf │ │ │ ├── Ibmplexsansitalic.woff │ │ │ ├── Ibmplexsansitalic.woff2 │ │ │ ├── Ibmplexsanslight.ttf │ │ │ ├── Ibmplexsanslight.woff │ │ │ ├── Ibmplexsanslight.woff2 │ │ │ ├── Ibmplexsanslightitalic.ttf │ │ │ ├── Ibmplexsanslightitalic.woff │ │ │ ├── Ibmplexsanslightitalic.woff2 │ │ │ ├── Ibmplexsansmedium.ttf │ │ │ ├── Ibmplexsansmedium.woff │ │ │ ├── Ibmplexsansmedium.woff2 │ │ │ ├── Ibmplexsansmediumitalic.ttf │ │ │ ├── Ibmplexsansmediumitalic.woff │ │ │ ├── Ibmplexsansmediumitalic.woff2 │ │ │ ├── Ibmplexsanssemibold.ttf │ │ │ ├── Ibmplexsanssemibold.woff │ │ │ ├── Ibmplexsanssemibold.woff2 │ │ │ ├── Ibmplexsanssemibolditalic.ttf │ │ │ ├── Ibmplexsanssemibolditalic.woff │ │ │ ├── Ibmplexsanssemibolditalic.woff2 │ │ │ ├── Ibmplexsansthin.ttf │ │ │ ├── Ibmplexsansthin.woff │ │ │ ├── Ibmplexsansthin.woff2 │ │ │ ├── Ibmplexsansthinitalic.ttf │ │ │ ├── Ibmplexsansthinitalic.woff │ │ │ └── Ibmplexsansthinitalic.woff2 │ ├── images │ │ ├── OpenPlaceReview.svg │ │ ├── arrow_opr_apps_number.png │ │ ├── avatar-default.png │ │ ├── block-icon.png │ │ ├── blockchain_icons │ │ │ ├── all_types.svg │ │ │ ├── blockchain.svg │ │ │ ├── blockchain_active.svg │ │ │ ├── blocks.svg │ │ │ ├── operations │ │ │ │ ├── ic_block_normal.svg │ │ │ │ ├── ic_bot.svg │ │ │ │ ├── ic_object_type.svg │ │ │ │ ├── ic_place.svg │ │ │ │ ├── ic_role.svg │ │ │ │ ├── ic_user.svg │ │ │ │ ├── ic_user_login.svg │ │ │ │ ├── ic_user_login_normal.svg │ │ │ │ ├── ic_user_logout_normal.svg │ │ │ │ ├── ic_user_permission.svg │ │ │ │ ├── ic_user_role.svg │ │ │ │ ├── ic_user_signup.svg │ │ │ │ ├── ic_validate.svg │ │ │ │ ├── ic_validation_normal.svg │ │ │ │ ├── ic_validaton.svg │ │ │ │ └── ic_vote.svg │ │ │ └── queue.svg │ │ ├── border_screen2.png │ │ ├── border_screen4.png │ │ ├── bottom_line_header.png │ │ ├── center_bottom_header.png │ │ ├── cover_full.png │ │ ├── custom-icon.png │ │ ├── evgene_lisovsky.png │ │ ├── google_maps_logo.svg │ │ ├── green_arrow.svg │ │ ├── group_2.png │ │ ├── group_2_buttom_center.png │ │ ├── group_2_buttom_left.png │ │ ├── group_2_buttom_right.png │ │ ├── group_2_middle_center.png │ │ ├── group_2_middle_left.png │ │ ├── group_2_middle_right.png │ │ ├── group_2_top_center.png │ │ ├── group_2_top_left.png │ │ ├── group_2_top_right.png │ │ ├── ic_block_normal.png │ │ ├── ic_block_selected.png │ │ ├── ic_object_normal.png │ │ ├── ic_object_selected.png │ │ ├── ic_permission_normal.png │ │ ├── ic_permission_selected.png │ │ ├── ic_queue_normal.png │ │ ├── ic_queue_selected.png │ │ ├── ic_user_info_normal.png │ │ ├── ic_user_info_selected.png │ │ ├── ic_user_login_normal.png │ │ ├── ic_user_login_selected.png │ │ ├── ic_user_signup_normal.png │ │ ├── ic_validation_normal.png │ │ ├── ic_validation_selected.png │ │ ├── icon-blocks.png │ │ ├── icon-facebook.png │ │ ├── icon-github.png │ │ ├── icon-google.png │ │ ├── icon-menu.svg │ │ ├── icon-nickname.png │ │ ├── icon-osm.png │ │ ├── icons │ │ │ ├── favicon-144x144.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-180x180.png │ │ │ ├── favicon-192x192.png │ │ │ ├── favicon-32x32.png │ │ │ └── filter.svg │ │ ├── leader_1.png │ │ ├── leader_2.png │ │ ├── left_bottom_header.png │ │ ├── loader.png │ │ ├── logo_landing.png │ │ ├── map_icons │ │ │ ├── apartment.svg │ │ │ ├── aquarium.svg │ │ │ ├── artwork.svg │ │ │ ├── bar.svg │ │ │ ├── biergarten.svg │ │ │ ├── cafe.svg │ │ │ ├── camp_pitch.svg │ │ │ ├── camp_site.svg │ │ │ ├── caravan_site.svg │ │ │ ├── default-marker.svg │ │ │ ├── fast_food.svg │ │ │ ├── food_court.svg │ │ │ ├── gallery.svg │ │ │ ├── guest_house.svg │ │ │ ├── hostel.svg │ │ │ ├── hotel.svg │ │ │ ├── ice_cream.svg │ │ │ ├── locomotive.svg │ │ │ ├── memorial.svg │ │ │ ├── mine.svg │ │ │ ├── monument.svg │ │ │ ├── motel.svg │ │ │ ├── museum.svg │ │ │ ├── picnic_site.svg │ │ │ ├── poi_deleted_shield_map.svg │ │ │ ├── poi_green_shield_map.svg │ │ │ ├── poi_shield_map.svg │ │ │ ├── poi_yellow_shield_map.svg │ │ │ ├── pub.svg │ │ │ ├── restaurant.svg │ │ │ ├── ruins.svg │ │ │ ├── rune_stone.svg │ │ │ ├── ship.svg │ │ │ ├── stone.svg │ │ │ ├── technical_monument.svg │ │ │ ├── theme_park.svg │ │ │ ├── view_point.svg │ │ │ ├── wreck.svg │ │ │ └── zoo.svg │ │ ├── map_sources │ │ │ ├── ic_action_remove_shaped.png │ │ │ ├── ic_colored_done.png │ │ │ ├── ic_logo_wikipedia.png │ │ │ ├── ic_warning.png │ │ │ ├── openStreetMap.png │ │ │ └── trip-advisor.png │ │ ├── mapbox-logo-white.svg │ │ ├── mapsme_logo.svg │ │ ├── monetization.png │ │ ├── ogr_logo_color.png │ │ ├── openness_github.png │ │ ├── openness_opendb.png │ │ ├── operation-database.png │ │ ├── operation-user.png │ │ ├── opr_logo_color.png │ │ ├── osm_icon.svg │ │ ├── page404.png │ │ ├── red_arrow.svg │ │ ├── right_bottom_header.png │ │ ├── screen_3_maps.png │ │ ├── screen_5_graphic.png │ │ ├── screen_6_graphic_1.png │ │ ├── screen_6_graphic_2.png │ │ ├── tab_1_diagramm.svg │ │ ├── tab_2_diagramm.svg │ │ ├── tab_3_diagramm.svg │ │ ├── tab_4_diagramm.svg │ │ ├── tab_5_diagramm.svg │ │ ├── trust_img.png │ │ ├── user_need_border.png │ │ ├── vertical_line_header.png │ │ ├── vertical_right_line_header.png │ │ └── victor_shcherb.png │ ├── iso_639-1_languages.json │ └── scss │ │ ├── app.scss │ │ └── app │ │ ├── auth.scss │ │ ├── error.scss │ │ ├── fonts.scss │ │ ├── landing.scss │ │ ├── main.scss │ │ └── map.scss ├── components │ ├── Error.js │ ├── blocks │ │ ├── Header.js │ │ └── misc │ │ │ └── Expand.js │ ├── landing │ │ ├── DiscontinuedLayout.js │ │ ├── DiscontinuedPage.js │ │ ├── Footer.js │ │ ├── LandingLayout.js │ │ ├── LandingPage.js │ │ └── LandingRouter.js │ ├── main │ │ ├── Error404.js │ │ ├── ErrorBoundary.js │ │ ├── MainLayout.js │ │ ├── MainRouter.js │ │ ├── auth │ │ │ ├── AuthConfirmPage.js │ │ │ ├── AuthLayout.js │ │ │ ├── AuthRouter.js │ │ │ ├── EmailConfirmation.js │ │ │ ├── LoginPage.js │ │ │ ├── OAuthConfirmation.js │ │ │ ├── Profile.js │ │ │ ├── ResetPwd.js │ │ │ ├── ResetPwdConfirmation.js │ │ │ ├── ResetPwdForm.js │ │ │ ├── SignUpPage.js │ │ │ ├── blocks │ │ │ │ ├── AuthSelector.js │ │ │ │ └── forms │ │ │ │ │ ├── LoginForm.js │ │ │ │ │ ├── OAuthLogInForm.js │ │ │ │ │ ├── OAuthSignUpForm.js │ │ │ │ │ ├── SignUpForm.js │ │ │ │ │ ├── blocks │ │ │ │ │ ├── Agreement.js │ │ │ │ │ ├── Form.js │ │ │ │ │ ├── FormAlert.js │ │ │ │ │ ├── FormItem.js │ │ │ │ │ ├── FormTextFiels.js │ │ │ │ │ ├── OptionalUserFields.js │ │ │ │ │ └── SumbitButton.js │ │ │ │ │ └── hooks │ │ │ │ │ ├── useForm.js │ │ │ │ │ ├── useTypingTimeout.js │ │ │ │ │ ├── useValidate.js │ │ │ │ │ ├── useValidatePasswords.js │ │ │ │ │ └── useValidateUsername.js │ │ │ ├── hooks │ │ │ │ └── useAuthCallback.js │ │ │ └── providers │ │ │ │ ├── AuthContext.js │ │ │ │ └── AuthProvider.js │ │ ├── blockchain │ │ │ ├── BlockPage.js │ │ │ ├── BlockchainLayout.js │ │ │ ├── BlockchainRouter.js │ │ │ ├── BlocksPage.js │ │ │ ├── ObjectsPage.js │ │ │ ├── QueuePage.js │ │ │ ├── TransactionPage.js │ │ │ ├── TransactionsPage.js │ │ │ ├── blocks │ │ │ │ ├── BlockIcon.js │ │ │ │ ├── BlockInfo.js │ │ │ │ ├── BlocksHeader.js │ │ │ │ ├── BlocksList.js │ │ │ │ ├── FilterOperations.js │ │ │ │ ├── Icon.js │ │ │ │ ├── JSONViewer │ │ │ │ │ ├── ExpandBtn.js │ │ │ │ │ ├── JSONViewer.js │ │ │ │ │ └── SumaryViewer.js │ │ │ │ ├── ObjectsSummary.js │ │ │ │ ├── Selection.js │ │ │ │ ├── SpecChar.js │ │ │ │ ├── SummaryBlock.js │ │ │ │ ├── Value.js │ │ │ │ ├── list-items │ │ │ │ │ ├── BlockItem.js │ │ │ │ │ ├── DataListItem.js │ │ │ │ │ ├── ObjectItem.js │ │ │ │ │ └── OperationItem.js │ │ │ │ └── sidebar │ │ │ │ │ ├── BlocksFilter.js │ │ │ │ │ ├── ListItemSidebar.js │ │ │ │ │ ├── Objects.js │ │ │ │ │ ├── Queue.js │ │ │ │ │ ├── Sidebar.js │ │ │ │ │ ├── SidebarHeader.js │ │ │ │ │ ├── SidebarItem.js │ │ │ │ │ └── ValueSidebarItem.js │ │ │ ├── hooks │ │ │ │ └── useFormatting.js │ │ │ └── providers │ │ │ │ ├── OperationsContext.js │ │ │ │ └── OperationsProvider.js │ │ └── blocks │ │ │ ├── Footer.js │ │ │ ├── Loader.js │ │ │ └── OPRLink.js │ ├── map │ │ ├── Map.js │ │ ├── MapLayout.js │ │ ├── MarkerEntity.js │ │ ├── MarkerIcon.js │ │ ├── MergeList.js │ │ ├── OPRLayer.js │ │ ├── ViewTracker.js │ │ ├── blocks │ │ │ ├── AttributesBar.js │ │ │ ├── AttributesBarList.js │ │ │ ├── BlockExpandable.js │ │ │ ├── CategorySelector.js │ │ │ ├── Filter.js │ │ │ ├── ImagesBlock.js │ │ │ ├── MarkerActions.js │ │ │ ├── MarkerBlock.js │ │ │ ├── MergeDialogPlaceCard.js │ │ │ ├── MergePlacesCardList.js │ │ │ ├── ModalLightbox.js │ │ │ ├── OPRMessageOverlay.js │ │ │ ├── ReviewImagesBlock.js │ │ │ ├── ReviewPlaces.js │ │ │ ├── StatusBar.js │ │ │ ├── TagsTable.js │ │ │ ├── carousels │ │ │ │ ├── ImagesCarousel.js │ │ │ │ └── MergeCarousel.js │ │ │ ├── dialogs │ │ │ │ ├── MergeDuplicateDialog.js │ │ │ │ ├── MergeListDialog.js │ │ │ │ ├── PermanentlyClosedDialog.js │ │ │ │ └── TripAdvisorLinkDialog.js │ │ │ └── sidebar │ │ │ │ ├── MapSidebar.js │ │ │ │ └── MapSidebarBlock.js │ │ ├── hooks │ │ │ ├── useBatchDiff.js │ │ │ ├── useBatchOp.js │ │ │ ├── useCommitOp.js │ │ │ ├── useDiff.js │ │ │ ├── useExtractObject.js │ │ │ ├── useMergeGroupList.js │ │ │ ├── usePersistedState.js │ │ │ └── useTaskSelectionState.js │ │ └── tasks │ │ │ ├── ReviewDuplicatePlacesTask.js │ │ │ ├── ReviewImagesTask.js │ │ │ ├── ReviewTripAdvisorTask.js │ │ │ ├── Task.js │ │ │ └── Tasks.js │ └── util │ │ ├── Utils.js │ │ └── UtilsDiff.js ├── config.js ├── index.html ├── index.js ├── libs │ ├── cookies.js │ └── storage.js └── theme.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"] 3 | } 4 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | NODE_ENV= 2 | BLOCK_LOAD_LIMIT= 3 | BLOCK_SIDEBAR_LIMIT= 4 | OPS_TRANSFORM_SRC= 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | .vscode 4 | 5 | html/ 6 | node_modules/ 7 | 8 | .env 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### The project has been discontinued 15 June 2023 2 | 3 | The blockchain was working for 2+ years as a centralized, with enabled replication present, bots and API. 4 | Main result could be considered in https://github.com/OpenPlaceReviews/opendb. 5 | The project has been published under open license (if not specified somewhere treat it as Public Domain). 6 | 7 | # Open Place Reviews 8 | This is a main Landing Page for OpenPlaceReviews site 9 | 10 | # Setup 11 | 12 | * Clone repo 13 | * cd to repo folder 14 | * set config environment values 15 | 16 | It possible by copy .env.example to .env 17 | or set variables on host system environment 18 | 19 | Environment variables: 20 | ```.dotenv 21 | NODE_ENV 22 | BLOCK_LOAD_LIMIT 23 | BLOCK_SIDEBAR_LIMIT 24 | ``` 25 | 26 | Then 27 | 28 | * run ```npm install``` 29 | * run ```npm run start``` 30 | 31 | ### Possible npm commands 32 | 33 | 1. start - build development boundle and open in browser 34 | 2. build - build production boundle with minification 35 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/index.html -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "open-place-reviews", 3 | "version": "0.0.1", 4 | "description": "", 5 | "author": "", 6 | "license": "UNLICENSED", 7 | "private": true, 8 | "scripts": { 9 | "start": "webpack-dev-server --progress --mode development", 10 | "watch": "webpack --progress --mode development --watch", 11 | "build": "webpack --progress --mode production" 12 | }, 13 | "dependencies": { 14 | "@material-ui/core": "^4.11.0", 15 | "@material-ui/icons": "^4.9.1", 16 | "@material-ui/lab": "^4.0.0-alpha.56", 17 | "@material-ui/styles": "^4.11.1", 18 | "axios": "^0.20.0", 19 | "babel-plugin-wildcard": "^6.0.0", 20 | "js-cookie": "^2.2.1", 21 | "jss-plugin-compose": "^10.5.0", 22 | "leaflet": "^1.7.1", 23 | "leaflet.markercluster": "^1.4.1", 24 | "lodash": "^4.17.20", 25 | "moment": "^2.29.1", 26 | "open-location-code": "^1.0.3", 27 | "prop-types": "^15.7.2", 28 | "qs": "^6.9.4", 29 | "react": "^16.13.1", 30 | "react-datepicker": "^3.6.0", 31 | "react-dom": "^16.13.1", 32 | "react-json-view": "^1.19.1", 33 | "react-jss": "^10.5.0", 34 | "react-leaflet": "^3.0.2", 35 | "react-material-ui-carousel": "^2.1.1", 36 | "react-promise-tracker": "^2.1.0", 37 | "react-router": "^5.2.0", 38 | "react-router-dom": "^5.2.0" 39 | }, 40 | "devDependencies": { 41 | "@babel/core": "^7.11.6", 42 | "@babel/plugin-transform-react-jsx-source": "^7.12.1", 43 | "@babel/preset-env": "^7.12.7", 44 | "@babel/preset-react": "^7.10.4", 45 | "@svgr/webpack": "^5.5.0", 46 | "babel-loader": "^8.1.0", 47 | "clean-webpack-plugin": "^3.0.0", 48 | "copy-webpack-plugin": "^6.2.0", 49 | "core-js": "^3.6.5", 50 | "css-loader": "^4.3.0", 51 | "dotenv-webpack": "^6.0.0", 52 | "file-loader": "^6.1.0", 53 | "html-loader": "^1.3.1", 54 | "html-webpack-plugin": "^4.5.0", 55 | "mini-css-extract-plugin": "^0.12.0", 56 | "regenerator-runtime": "^0.13.7", 57 | "sass": "^1.27.0", 58 | "sass-loader": "^10.0.2", 59 | "style-loader": "^1.3.0", 60 | "webpack": "^4.44.2", 61 | "webpack-cli": "^3.3.12", 62 | "webpack-dev-server": "^3.11.0" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "core-js/stable"; 3 | import "regenerator-runtime/runtime"; 4 | 5 | import theme from "./theme"; 6 | 7 | import AuthProvider from "./components/main/auth/providers/AuthProvider"; 8 | import {ThemeProvider} from "react-jss"; 9 | import Router from "./Router"; 10 | 11 | export default function App() { 12 | return 13 | 14 | 15 | 16 | ; 17 | }; 18 | -------------------------------------------------------------------------------- /src/Router.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {BrowserRouter, Route, Switch} from "react-router-dom"; 3 | import LandingLayout from "./components/landing/LandingLayout"; 4 | import DiscontinuedLayout from "./components/landing/DiscontinuedLayout"; 5 | import MainLayout from "./components/main/MainLayout"; 6 | import MapLayout from "./components/map/MapLayout"; 7 | 8 | export default function Router() { 9 | return 10 | 11 | 12 | 13 | 14 | 15 | 16 | ; 17 | }; 18 | -------------------------------------------------------------------------------- /src/api/errors.js: -------------------------------------------------------------------------------- 1 | export class NotFoundError extends Error { 2 | constructor(...params) { 3 | super(...params); 4 | this.code = 404; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/api/geo.js: -------------------------------------------------------------------------------- 1 | import { get } from "axios"; 2 | import Utils from "../components/util/Utils"; 3 | 4 | const API_BASE = ""; 5 | const FETCH_DATA = `${API_BASE}/api/public/geo/index/data`; 6 | const FETCH_HISTORY_DATA = `${API_BASE}/api/public/history`; 7 | 8 | export const fetchData = async (reqParams = {}) => { 9 | const params = {}; 10 | 11 | if (reqParams.tileId) { 12 | params.tileid = reqParams.tileId; 13 | } 14 | const { data } = await get(FETCH_DATA, { params }) 15 | return data; 16 | }; 17 | 18 | export const fetchHistoryData = async (reqParams = {}) => { 19 | const params = {}; 20 | 21 | if (reqParams.startDate) { 22 | params.date = Utils.formatDate(reqParams.startDate); 23 | } 24 | if (reqParams.endDate) { 25 | params.date2 = Utils.formatDate(reqParams.endDate); 26 | } 27 | if (reqParams.requestFilter) { 28 | params.requestFilter = reqParams.requestFilter; 29 | } 30 | 31 | const { data } = await get(FETCH_HISTORY_DATA, { params }) 32 | return data; 33 | }; -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmono.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmono.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmono.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmono.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmono.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonobold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonobold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonobold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonobold.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonobold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonobold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonobolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonobolditalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonobolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonobolditalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonobolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonobolditalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonoextralight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonoextralight.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonoextralight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonoextralight.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonoextralight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonoextralight.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonoextralightitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonoextralightitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonoextralightitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonoextralightitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonoextralightitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonoextralightitalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonoitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonoitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonoitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonoitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonoitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonoitalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonolight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonolight.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonolight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonolight.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonolight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonolight.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonolightitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonolightitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonolightitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonolightitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonolightitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonolightitalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonomedium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonomedium.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonomedium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonomedium.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonomedium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonomedium.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonomediumitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonomediumitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonomediumitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonomediumitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonomediumitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonomediumitalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonosemibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonosemibold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonosemibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonosemibold.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonosemibold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonosemibold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonosemibolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonosemibolditalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonosemibolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonosemibolditalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonosemibolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonosemibolditalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonothin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonothin.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonothin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonothin.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonothin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonothin.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonothinitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonothinitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonothinitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonothinitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexmono/Ibmplexmonothinitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexmono/Ibmplexmonothinitalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsans.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsans.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsans.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsans.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsans.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansbold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansbold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansbold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansbold.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansbold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansbold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansbolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansbolditalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansbolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansbolditalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansbolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansbolditalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansextralight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansextralight.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansextralight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansextralight.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansextralight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansextralight.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansextralightitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansextralightitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansextralightitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansextralightitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansextralightitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansextralightitalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansitalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanslight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanslight.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanslight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanslight.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanslight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanslight.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanslightitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanslightitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanslightitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanslightitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanslightitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanslightitalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansmedium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansmedium.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansmedium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansmedium.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansmedium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansmedium.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansmediumitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansmediumitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansmediumitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansmediumitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansmediumitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansmediumitalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanssemibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanssemibold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanssemibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanssemibold.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanssemibold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanssemibold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanssemibolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanssemibolditalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanssemibolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanssemibolditalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsanssemibolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsanssemibolditalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansthin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansthin.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansthin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansthin.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansthin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansthin.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansthinitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansthinitalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansthinitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansthinitalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/ibmplexsans/Ibmplexsansthinitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/fonts/ibmplexsans/Ibmplexsansthinitalic.woff2 -------------------------------------------------------------------------------- /src/assets/images/arrow_opr_apps_number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/arrow_opr_apps_number.png -------------------------------------------------------------------------------- /src/assets/images/avatar-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/avatar-default.png -------------------------------------------------------------------------------- /src/assets/images/block-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/block-icon.png -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/all_types.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/blockchain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/blockchain_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/blocks.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_block_normal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_bot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_object_type.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_place.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_role.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_user_login.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_user_login_normal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_user_logout_normal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_user_permission.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_user_role.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_user_signup.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_validate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_validation_normal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_validaton.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/operations/ic_vote.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/images/blockchain_icons/queue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/border_screen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/border_screen2.png -------------------------------------------------------------------------------- /src/assets/images/border_screen4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/border_screen4.png -------------------------------------------------------------------------------- /src/assets/images/bottom_line_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/bottom_line_header.png -------------------------------------------------------------------------------- /src/assets/images/center_bottom_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/center_bottom_header.png -------------------------------------------------------------------------------- /src/assets/images/cover_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/cover_full.png -------------------------------------------------------------------------------- /src/assets/images/custom-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/custom-icon.png -------------------------------------------------------------------------------- /src/assets/images/evgene_lisovsky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/evgene_lisovsky.png -------------------------------------------------------------------------------- /src/assets/images/green_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/group_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2.png -------------------------------------------------------------------------------- /src/assets/images/group_2_buttom_center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2_buttom_center.png -------------------------------------------------------------------------------- /src/assets/images/group_2_buttom_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2_buttom_left.png -------------------------------------------------------------------------------- /src/assets/images/group_2_buttom_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2_buttom_right.png -------------------------------------------------------------------------------- /src/assets/images/group_2_middle_center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2_middle_center.png -------------------------------------------------------------------------------- /src/assets/images/group_2_middle_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2_middle_left.png -------------------------------------------------------------------------------- /src/assets/images/group_2_middle_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2_middle_right.png -------------------------------------------------------------------------------- /src/assets/images/group_2_top_center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2_top_center.png -------------------------------------------------------------------------------- /src/assets/images/group_2_top_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2_top_left.png -------------------------------------------------------------------------------- /src/assets/images/group_2_top_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/group_2_top_right.png -------------------------------------------------------------------------------- /src/assets/images/ic_block_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_block_normal.png -------------------------------------------------------------------------------- /src/assets/images/ic_block_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_block_selected.png -------------------------------------------------------------------------------- /src/assets/images/ic_object_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_object_normal.png -------------------------------------------------------------------------------- /src/assets/images/ic_object_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_object_selected.png -------------------------------------------------------------------------------- /src/assets/images/ic_permission_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_permission_normal.png -------------------------------------------------------------------------------- /src/assets/images/ic_permission_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_permission_selected.png -------------------------------------------------------------------------------- /src/assets/images/ic_queue_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_queue_normal.png -------------------------------------------------------------------------------- /src/assets/images/ic_queue_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_queue_selected.png -------------------------------------------------------------------------------- /src/assets/images/ic_user_info_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_user_info_normal.png -------------------------------------------------------------------------------- /src/assets/images/ic_user_info_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_user_info_selected.png -------------------------------------------------------------------------------- /src/assets/images/ic_user_login_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_user_login_normal.png -------------------------------------------------------------------------------- /src/assets/images/ic_user_login_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_user_login_selected.png -------------------------------------------------------------------------------- /src/assets/images/ic_user_signup_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_user_signup_normal.png -------------------------------------------------------------------------------- /src/assets/images/ic_validation_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_validation_normal.png -------------------------------------------------------------------------------- /src/assets/images/ic_validation_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ic_validation_selected.png -------------------------------------------------------------------------------- /src/assets/images/icon-blocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icon-blocks.png -------------------------------------------------------------------------------- /src/assets/images/icon-facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icon-facebook.png -------------------------------------------------------------------------------- /src/assets/images/icon-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icon-github.png -------------------------------------------------------------------------------- /src/assets/images/icon-google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icon-google.png -------------------------------------------------------------------------------- /src/assets/images/icon-menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/icon-nickname.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icon-nickname.png -------------------------------------------------------------------------------- /src/assets/images/icon-osm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icon-osm.png -------------------------------------------------------------------------------- /src/assets/images/icons/favicon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icons/favicon-144x144.png -------------------------------------------------------------------------------- /src/assets/images/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icons/favicon-16x16.png -------------------------------------------------------------------------------- /src/assets/images/icons/favicon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icons/favicon-180x180.png -------------------------------------------------------------------------------- /src/assets/images/icons/favicon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icons/favicon-192x192.png -------------------------------------------------------------------------------- /src/assets/images/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/icons/favicon-32x32.png -------------------------------------------------------------------------------- /src/assets/images/icons/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/assets/images/leader_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/leader_1.png -------------------------------------------------------------------------------- /src/assets/images/leader_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/leader_2.png -------------------------------------------------------------------------------- /src/assets/images/left_bottom_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/left_bottom_header.png -------------------------------------------------------------------------------- /src/assets/images/loader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/loader.png -------------------------------------------------------------------------------- /src/assets/images/logo_landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/logo_landing.png -------------------------------------------------------------------------------- /src/assets/images/map_icons/apartment.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/artwork.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/bar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/biergarten.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/cafe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/camp_pitch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/camp_site.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/caravan_site.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/fast_food.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/food_court.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/hotel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/ice_cream.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/locomotive.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/memorial.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/mine.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/monument.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/motel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/museum.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/picnic_site.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/poi_deleted_shield_map.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/poi_green_shield_map.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/poi_shield_map.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/poi_yellow_shield_map.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/pub.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/restaurant.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/ruins.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/ship.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/stone.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/technical_monument.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/map_icons/view_point.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/map_sources/ic_action_remove_shaped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/map_sources/ic_action_remove_shaped.png -------------------------------------------------------------------------------- /src/assets/images/map_sources/ic_colored_done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/map_sources/ic_colored_done.png -------------------------------------------------------------------------------- /src/assets/images/map_sources/ic_logo_wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/map_sources/ic_logo_wikipedia.png -------------------------------------------------------------------------------- /src/assets/images/map_sources/ic_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/map_sources/ic_warning.png -------------------------------------------------------------------------------- /src/assets/images/map_sources/openStreetMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/map_sources/openStreetMap.png -------------------------------------------------------------------------------- /src/assets/images/map_sources/trip-advisor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/map_sources/trip-advisor.png -------------------------------------------------------------------------------- /src/assets/images/monetization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/monetization.png -------------------------------------------------------------------------------- /src/assets/images/ogr_logo_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/ogr_logo_color.png -------------------------------------------------------------------------------- /src/assets/images/openness_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/openness_github.png -------------------------------------------------------------------------------- /src/assets/images/openness_opendb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/openness_opendb.png -------------------------------------------------------------------------------- /src/assets/images/operation-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/operation-database.png -------------------------------------------------------------------------------- /src/assets/images/operation-user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/operation-user.png -------------------------------------------------------------------------------- /src/assets/images/opr_logo_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/opr_logo_color.png -------------------------------------------------------------------------------- /src/assets/images/page404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/page404.png -------------------------------------------------------------------------------- /src/assets/images/red_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/right_bottom_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/right_bottom_header.png -------------------------------------------------------------------------------- /src/assets/images/screen_3_maps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/screen_3_maps.png -------------------------------------------------------------------------------- /src/assets/images/screen_5_graphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/screen_5_graphic.png -------------------------------------------------------------------------------- /src/assets/images/screen_6_graphic_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/screen_6_graphic_1.png -------------------------------------------------------------------------------- /src/assets/images/screen_6_graphic_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/screen_6_graphic_2.png -------------------------------------------------------------------------------- /src/assets/images/trust_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/trust_img.png -------------------------------------------------------------------------------- /src/assets/images/user_need_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/user_need_border.png -------------------------------------------------------------------------------- /src/assets/images/vertical_line_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/vertical_line_header.png -------------------------------------------------------------------------------- /src/assets/images/vertical_right_line_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/vertical_right_line_header.png -------------------------------------------------------------------------------- /src/assets/images/victor_shcherb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPlaceReviews/website/d029655789797e21495866dc0fb96b80a15d6ad5/src/assets/images/victor_shcherb.png -------------------------------------------------------------------------------- /src/assets/scss/app.scss: -------------------------------------------------------------------------------- 1 | @import "app/main"; 2 | @import "app/error"; 3 | @import "app/fonts"; 4 | @import "app/landing"; 5 | @import "app/map"; 6 | @import "app/auth"; 7 | -------------------------------------------------------------------------------- /src/assets/scss/app/auth.scss: -------------------------------------------------------------------------------- 1 | .auth-container { 2 | .oauth_avatar { 3 | position: absolute; 4 | margin-left: -70px; 5 | img{ 6 | width: 50px; 7 | height: 50px; 8 | border-radius: 50px; /* Радиус скругления */ 9 | //border: 3px solid green; /* Параметры рамки */ 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/assets/scss/app/error.scss: -------------------------------------------------------------------------------- 1 | .inner{ 2 | max-width: 1100px; 3 | padding: 0 20px; 4 | margin: auto; 5 | padding-top: 1px; 6 | min-height: calc(100vh - 217px); 7 | padding-bottom: 80px; 8 | h1{ 9 | margin-top: 40px; 10 | margin-bottom: 20px; 11 | line-height: 50px; 12 | font-size: 40px; 13 | letter-spacing: 0.01em; 14 | } 15 | .containter_flex{ 16 | display: flex; 17 | } 18 | 19 | .page-error{ 20 | margin: 0 auto; 21 | margin-top: 100px; 22 | max-width: 700px; 23 | flex-wrap: wrap; 24 | @media (max-width: 740px) { 25 | margin-top: 40px; 26 | } 27 | } 28 | .txt-page-error{ 29 | max-width: 470px; 30 | font-size: 16px; 31 | font-weight: 600; 32 | p{ 33 | margin-bottom: 8px; 34 | } 35 | h1{ 36 | margin-top: 0; 37 | line-height: 42px; 38 | } 39 | .error-description{ 40 | color: #6A7181; 41 | margin-bottom: 40px; 42 | } 43 | ul{ 44 | margin: 0; 45 | padding: 0; 46 | li{ 47 | list-style: none; 48 | line-height: 21px; 49 | margin-bottom: 5px; 50 | } 51 | } 52 | } 53 | .img-page-error{ 54 | background: url(../images/page404.png) no-repeat; 55 | width: 170px; 56 | height: 290px; 57 | background-size: contain; 58 | margin-right: 60px; 59 | @media (max-width: 740px) { 60 | margin-right: 20px; 61 | width: 85px; 62 | height: 145px; 63 | } 64 | @media (max-width: 615px) { 65 | display: none; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/assets/scss/app/map.scss: -------------------------------------------------------------------------------- 1 | .leaflet-container { 2 | position: fixed; 3 | top: 80px; 4 | left: 0; 5 | right: 0; 6 | bottom: 0; 7 | width: 100%; 8 | } 9 | 10 | .marker-cluster { 11 | width: 40px; 12 | height: 40px; 13 | border-radius: 30px; 14 | background: #FFFFFF; 15 | border: 1px solid rgba(0, 0, 0, 0.08); 16 | box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25), 0 2px 4px rgba(0, 0, 0, 0.25); 17 | } 18 | 19 | .leaflet-oldie .marker-cluster-large, 20 | .leaflet-oldie .marker-cluster-large div, 21 | .leaflet-oldie .marker-cluster-medium, 22 | .leaflet-oldie .marker-cluster-medium div, 23 | .leaflet-oldie .marker-cluster-small, 24 | .leaflet-oldie .marker-cluster-small div, 25 | .marker-cluster-large, 26 | .marker-cluster-medium, 27 | .marker-cluster-small, 28 | .marker-cluster-large div, 29 | .marker-cluster-medium div, 30 | .marker-cluster-small div { 31 | font-weight: bold; 32 | font-size: 16px; 33 | line-height: 21px; 34 | color: #2D69E0; 35 | margin-top: 10px; 36 | text-align: center; 37 | } 38 | -------------------------------------------------------------------------------- /src/components/Error.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function Error() { 4 | return
5 |
6 |
7 |
8 |
9 |

Something went wrong

10 |

Internal service error

11 |

Please contact us or try again later

12 | 17 |
18 |
19 |
20 |
; 21 | }; 22 | -------------------------------------------------------------------------------- /src/components/blocks/Header.js: -------------------------------------------------------------------------------- 1 | import React, {useContext} from 'react'; 2 | import {NavLink, useHistory} from "react-router-dom"; 3 | import AuthContext from "../main/auth/providers/AuthContext"; 4 | 5 | import openPlaceReviewLogo from "../../assets/images/OpenPlaceReview.svg"; 6 | import avatarDefault from "../../assets/images/avatar-default.png"; 7 | 8 | const UserMenuFragment = ({isLoggedIn, logOut}) => { 9 | const onclickLogout = (e) => { 10 | e.preventDefault(); 11 | logOut(); 12 | }; 13 | 14 | if(!isLoggedIn) { 15 | return <> 16 |
  • 17 | Login 18 |
  • 19 |
  • 20 | Sign Up 21 |
  • 22 |
    23 | ; 24 | } else { 25 | return <> 26 |
  • 27 | Logout 28 |
  • 29 |
  • 30 | default avatar 31 |
  • 32 | ; 33 | } 34 | }; 35 | 36 | export default function Header() { 37 | const {authData, logOut} = useContext(AuthContext); 38 | const history = useHistory(); 39 | 40 | const onLogOut = () => { 41 | logOut(); 42 | history.push('/'); 43 | }; 44 | 45 | return <> 46 |
    47 |
    48 |
    49 | 50 | OpenPlaceReviews.org logo 51 | 52 |
    53 | 54 | 57 | 65 |
    66 |
    67 | ; 68 | }; 69 | -------------------------------------------------------------------------------- /src/components/blocks/misc/Expand.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import {Button} from "@material-ui/core"; 3 | import PropTypes from "prop-types"; 4 | 5 | const Expand = (props) => { 6 | const [isExpand, setExpand] = useState(false); 7 | let className = 'expand-block'; 8 | if (props.className) { 9 | className += ` ${props.className}`; 10 | } 11 | 12 | return
    13 |
    14 | {props.children} 15 |
    16 | 17 |
    ; 18 | }; 19 | 20 | Expand.propTypes = { 21 | children: PropTypes.oneOfType([ 22 | PropTypes.element.isRequired, 23 | PropTypes.instanceOf(Array).isRequired 24 | ]), 25 | }; 26 | 27 | export default Expand; 28 | -------------------------------------------------------------------------------- /src/components/landing/DiscontinuedLayout.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Footer from "./Footer"; 3 | import Header from "../blocks/Header"; 4 | import DiscontinuedPage from "./DiscontinuedPage"; 5 | 6 | export default function DiscontinuedLayout() { 7 | return
    8 |
    9 | 10 |
    ; 12 | }; 13 | -------------------------------------------------------------------------------- /src/components/landing/Footer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Link} from "react-router-dom"; 3 | 4 | import openPlaceReviewLogo from "../../assets/images/OpenPlaceReview.svg"; 5 | 6 | export default function Footer() { 7 | return ; 36 | }; 37 | -------------------------------------------------------------------------------- /src/components/landing/LandingLayout.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Footer from "./Footer"; 3 | import Header from "../blocks/Header"; 4 | import LandingRouter from "./LandingRouter"; 5 | 6 | export default function LandingLayout() { 7 | return
    8 |
    9 | 10 |
    ; 12 | }; 13 | -------------------------------------------------------------------------------- /src/components/landing/LandingRouter.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Route, Switch, useRouteMatch} from "react-router-dom"; 3 | 4 | import LandingPage from "./LandingPage"; 5 | 6 | export default function LandingRouter () { 7 | let { path } = useRouteMatch(); 8 | 9 | return 10 | 11 | 12 | }; 13 | -------------------------------------------------------------------------------- /src/components/main/Error404.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Link} from "react-router-dom"; 3 | 4 | export default function Error404() { 5 | return
    6 |
    7 |
    8 |
    9 |
    10 |

    We can't find the page you are looking for.

    11 |

    Error code: 404

    12 |

    You can try one of this pages:

    13 |
      14 |
    • Database
    • 15 |
    • Account
    • 16 |
    17 |
    18 |
    19 |
    20 |
    ; 21 | }; 22 | -------------------------------------------------------------------------------- /src/components/main/ErrorBoundary.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Error from '../Error'; 3 | 4 | export default class ErrorBoundary extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = { hasError: false }; 8 | } 9 | 10 | componentDidCatch(error, info) { 11 | if (process.env.NODE_ENV === 'development') { 12 | console.log('Error', error.message); 13 | console.error(error); 14 | } 15 | 16 | this.setState({ hasError: true }); 17 | } 18 | 19 | render() { 20 | if (this.state.hasError) { 21 | return ; 22 | } 23 | 24 | return this.props.children; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/components/main/MainLayout.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Footer from "./blocks/Footer"; 3 | import Header from "../blocks/Header"; 4 | import MainRouter from "./MainRouter"; 5 | import {Container} from "@material-ui/core"; 6 | import {makeStyles} from "@material-ui/styles"; 7 | import ErrorBoundary from "./ErrorBoundary"; 8 | 9 | const useStyle = makeStyles({ 10 | column: { 11 | display: "flex", 12 | flexDirection: "column", 13 | flex: 1, 14 | } 15 | }); 16 | 17 | export default function MainLayout() { 18 | const classes = useStyle(); 19 | 20 | return
    21 |
    22 | 23 | 24 | 25 | 26 | 27 |
    28 |
    ; 29 | }; 30 | -------------------------------------------------------------------------------- /src/components/main/MainRouter.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Route, Switch, useRouteMatch} from "react-router-dom"; 3 | 4 | import AuthLayout from "./auth/AuthLayout"; 5 | import BlockchainLayout from "./blockchain/BlockchainLayout"; 6 | import Error404 from "./Error404"; 7 | 8 | export default function MainRouter() { 9 | let { path } = useRouteMatch(); 10 | 11 | let authRoutes = [ 12 | `${path}/auth`, 13 | `${path}/login`, 14 | `${path}/signup`, 15 | `${path}/profile`, 16 | `${path}/reset-password`, 17 | ] 18 | 19 | return 20 | 21 | 22 | 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/components/main/auth/AuthConfirmPage.js: -------------------------------------------------------------------------------- 1 | import React, {useContext} from "react"; 2 | import {Redirect} from "react-router-dom"; 3 | import qs from "qs"; 4 | 5 | import storage from "../../../libs/cookies"; 6 | 7 | import AuthContext from "./providers/AuthContext"; 8 | 9 | import EmailConfirmation from "./EmailConfirmation"; 10 | import ResetPwdConfirmation from "./ResetPwdConfirmation"; 11 | import OAuthConfirmation from "./OAuthConfirmation"; 12 | import useAuthCallback from "./hooks/useAuthCallback"; 13 | 14 | export default ({location}) => { 15 | const {authData, logIn, signUp} = useContext(AuthContext); 16 | const reqParams = qs.parse(location.search.substring(1)); 17 | const isConfirmation = (reqParams.name && reqParams.token && reqParams.op); 18 | const isOAuth = (reqParams.oauth_token || reqParams.oauth_verifier || reqParams.code); 19 | const {callback} = storage.get('opr-auth-callback') || {}; 20 | 21 | if (!!authData.token) { 22 | if (!!callback) { 23 | useAuthCallback(callback, authData); 24 | storage.remove('opr-auth-callback'); 25 | return null; 26 | } 27 | 28 | return 29 | } else if (isConfirmation) { 30 | const {op} = reqParams; 31 | if (op === 'signup_confirm') { 32 | return 33 | } else if (op === 'reset_pwd') { 34 | return 35 | } 36 | } else if (isOAuth) { 37 | if (!!authData.name) { 38 | if (!!callback) { 39 | useAuthCallback(callback, authData); 40 | storage.remove('opr-auth-callback'); 41 | return null; 42 | } 43 | 44 | return ; 45 | } 46 | 47 | return 48 | } 49 | 50 | return ; 51 | }; 52 | -------------------------------------------------------------------------------- /src/components/main/auth/AuthLayout.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | import AuthRouter from "./AuthRouter"; 4 | 5 | const useStyles = makeStyles({ 6 | authContainer: { 7 | minWidth: "280px", 8 | maxWidth: "540px", 9 | margin: "0 auto", 10 | color: "#212121", 11 | fontStyle: "normal", 12 | fontWeight: "normal", 13 | lineHeight: "26px", 14 | fontSize: "16px", 15 | letterSpacing: "0.02em", 16 | minHeight: "calc(100vh - 217px)", 17 | marginBottom: "40px", 18 | padding: "0 20px", 19 | } 20 | }); 21 | 22 | export default function AuthLayout() { 23 | const classes = useStyles(); 24 | return
    25 | 26 |
    ; 27 | } -------------------------------------------------------------------------------- /src/components/main/auth/AuthRouter.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Route, Switch} from "react-router-dom"; 3 | import Profile from "./Profile"; 4 | import ResetPwd from "./ResetPwd"; 5 | import AuthConfirmPage from "./AuthConfirmPage"; 6 | 7 | import LoginPage from "./LoginPage"; 8 | import SignUpPage from "./SignUpPage"; 9 | 10 | export default function AuthRouter() { 11 | return 12 | 13 | 14 | 15 | 16 | 17 | 18 | }; 19 | -------------------------------------------------------------------------------- /src/components/main/auth/LoginPage.js: -------------------------------------------------------------------------------- 1 | import React, {useContext} from 'react'; 2 | import {Link, Redirect} from "react-router-dom"; 3 | import qs from "qs"; 4 | 5 | import AuthContext from "./providers/AuthContext"; 6 | 7 | import LoginForm from "./blocks/forms/LoginForm"; 8 | import AuthSelector from "./blocks/AuthSelector"; 9 | import useAuthCallback from "./hooks/useAuthCallback"; 10 | 11 | export default function LoginPage() { 12 | const {authData, logIn} = useContext(AuthContext); 13 | const reqParams = qs.parse(location.search.substring(1)); 14 | const {callback, purpose} = reqParams; 15 | 16 | const onLogIn = (data) => { 17 | logIn(data); 18 | }; 19 | 20 | if (authData.token && (purpose === undefined || authData.provider === purpose)) { 21 | if (!!callback) { 22 | useAuthCallback(callback, authData); 23 | return null; 24 | } 25 | return ; 26 | } 27 | 28 | return
    29 |

    Login

    30 |

    Don't have an account? Create account

    31 | 32 |
    ; 33 | }; 34 | -------------------------------------------------------------------------------- /src/components/main/auth/Profile.js: -------------------------------------------------------------------------------- 1 | import React, {useContext, useEffect, useState} from 'react'; 2 | import {Redirect, Link} from "react-router-dom"; 3 | 4 | import AuthContext from "./providers/AuthContext"; 5 | import EmailConfirmation from "./EmailConfirmation"; 6 | import auth from "../../../api/auth"; 7 | 8 | export default () => { 9 | const {authData, logIn} = useContext(AuthContext); 10 | const [status, setStatus] = useState(null); 11 | 12 | useEffect(() => { 13 | const fetchData = async () => { 14 | const { data } = await auth.checkName(authData.name); 15 | if (!data) return; 16 | 17 | setStatus(data); 18 | }; 19 | 20 | fetchData(); 21 | }, [authData]); 22 | 23 | if (!authData.name) { 24 | return ; 25 | } 26 | 27 | if (!status) { 28 | return
    29 |
    Loading...
    30 |
    ; 31 | } 32 | 33 | const { 'db-name': name, 'email-expired': emailExpired, email, blockchain} = status; 34 | if (name !== 'ok') { 35 | if (blockchain !== 'ok') { 36 | return ; 37 | } else { 38 | return ; 39 | } 40 | } else { 41 | if (blockchain !== 'ok') { 42 | if (email === 'ok' && emailExpired !== "true") { 43 | return ; 44 | } else { 45 | return ; 46 | } 47 | } else { 48 | if (!authData.token) { 49 | return ; 50 | } 51 | } 52 | } 53 | 54 | return
    55 |

    56 |
    57 | Default avatar 58 |
    59 | Welcome, { authData.name }! 60 |

    61 | 62 |

    Start contributing to OpenPlaceReviews.

    63 |

    Please visit map to find places to contribute.

    64 |
    ; 65 | }; 66 | -------------------------------------------------------------------------------- /src/components/main/auth/ResetPwdConfirmation.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import {Link} from "react-router-dom"; 3 | import ResetPwdForm from "./ResetPwdForm"; 4 | 5 | export default ({params}) => { 6 | const [isSuccess, setSuccess] = useState(false); 7 | 8 | if (isSuccess) { 9 | return
    10 |

    Password reset

    11 |

    Password was reset successfully. Try to login with new password.

    12 |
    ; 13 | } 14 | 15 | return
    16 |

    Reset password

    17 | setSuccess(true)}/> 18 |
    ; 19 | } 20 | -------------------------------------------------------------------------------- /src/components/main/auth/SignUpPage.js: -------------------------------------------------------------------------------- 1 | import React, {useContext, useState} from 'react'; 2 | import {Link, Redirect} from "react-router-dom"; 3 | import qs from "qs"; 4 | 5 | import storage from "../../../libs/cookies"; 6 | import AuthContext from "./providers/AuthContext"; 7 | import useAuthCallback from "./hooks/useAuthCallback"; 8 | 9 | import SignUpForm from "./blocks/forms/SignUpForm"; 10 | import AuthSelector from "./blocks/AuthSelector"; 11 | 12 | export default function SignUpPage() { 13 | const {authData, signUp} = useContext(AuthContext); 14 | const [redirect, setRedirect] = useState(false); 15 | const reqParams = qs.parse(location.search.substring(1)); 16 | const {force_signup, callback} = reqParams; 17 | 18 | if (force_signup === 'true') { 19 | storage.setNonStrict('opr-force-signup', true); 20 | } else { 21 | storage.remove('opr-force-signup'); 22 | } 23 | 24 | const onSignUp = (data) => { 25 | signUp(data); 26 | setRedirect(true); 27 | }; 28 | 29 | if(authData.token || redirect) { 30 | if (!!callback) { 31 | useAuthCallback(callback, authData); 32 | return null; 33 | } 34 | 35 | return ; 36 | } 37 | 38 | return
    39 |

    Sign Up

    40 |

    41 | OpenPlaceReviews has a public database, so we do not store any private data. You can select a nickname and it will be visible to everyone. 42 |

    43 |

    Already have an account? Then please Login.

    44 | 45 |
    ; 46 | }; 47 | -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/blocks/Form.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {makeStyles} from "@material-ui/styles"; 3 | import {Backdrop} from "@material-ui/core"; 4 | import Loader from "../../../../blocks/Loader"; 5 | 6 | const useStyles = makeStyles({ 7 | fade: { 8 | position: "absolute", 9 | backgroundColor: "rgba(255, 255, 255, 0.5)", 10 | zIndex: "9000", 11 | }, 12 | form: { 13 | position: "relative", 14 | } 15 | }); 16 | 17 | export default function Form({onSubmit, submitted, children}){ 18 | const classes = useStyles(); 19 | return
    20 | {children} 21 | 22 | 23 | 24 |
    25 | }; -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/blocks/FormAlert.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Alert} from "@material-ui/lab"; 3 | import {makeStyles} from "@material-ui/styles"; 4 | 5 | const useStyles = makeStyles({ 6 | formAlert: { 7 | marginBottom: "20px", 8 | } 9 | }); 10 | 11 | export default function FormAlert({open, onClose, children}) { 12 | const classes = useStyles(); 13 | if (!open) { 14 | return null; 15 | } 16 | 17 | return 22 | {children} 23 | ; 24 | } -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/blocks/FormItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | import {FormControl} from "@material-ui/core"; 4 | 5 | const useStyles = makeStyles({ 6 | formItem: { 7 | marginBottom: "20px", 8 | display: "block", 9 | "& .input-description": { 10 | fontSize: "14px", 11 | letterSpacing: "0.01em", 12 | color: "rgba(49, 50, 51, 0.7)", 13 | } 14 | }, 15 | }) 16 | 17 | export default function FormItem({children}) { 18 | const classes = useStyles(); 19 | return 20 | {children} 21 | ; 22 | } -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/blocks/FormTextFiels.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {TextField} from "@material-ui/core"; 3 | 4 | export default function FormTextField(props) { 5 | return 12 | }; -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/blocks/SumbitButton.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Button} from "@material-ui/core"; 3 | 4 | export default function SubmitButton(props) { 5 | return 13 | } -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/hooks/useForm.js: -------------------------------------------------------------------------------- 1 | import {useState} from "react"; 2 | 3 | export default function useForm(data) { 4 | const [formData, setData] = useState(data); 5 | const [valid, setValid] = useState(false); 6 | 7 | const handler = (event) => { 8 | const { target } = event; 9 | const value = target.type === 'checkbox' ? target.checked : target.value; 10 | const { name } = target; 11 | 12 | let error = formData[name].error; 13 | if (target.required) { 14 | if (!value) { 15 | error = "This field is required"; 16 | } else { 17 | error = ''; 18 | } 19 | } 20 | 21 | setData( state => ({ 22 | ...state, 23 | [name]: { 24 | ...state[name], 25 | error, 26 | value 27 | } 28 | })); 29 | }; 30 | 31 | return { 32 | handler, 33 | formData, 34 | valid, 35 | setValid, 36 | setData, 37 | } 38 | } -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/hooks/useTypingTimeout.js: -------------------------------------------------------------------------------- 1 | import {useCallback} from "react"; 2 | import config from "../../../../../../config"; 3 | 4 | export default function useTypingTimeout(writeTimeout) { 5 | const TYPING_TIMEOUT = config.auth.typingTimeout; 6 | 7 | return useCallback((handler) => { 8 | clearTimeout(writeTimeout.current); 9 | writeTimeout.current = setTimeout(() => { 10 | handler(); 11 | }, TYPING_TIMEOUT); 12 | }, []); 13 | } -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/hooks/useValidate.js: -------------------------------------------------------------------------------- 1 | import {useCallback} from "react"; 2 | 3 | export default function useValidate() { 4 | return useCallback((formData) => { 5 | let errors = 0; 6 | let required = 0; 7 | for (let name in formData) { 8 | if (formData.hasOwnProperty(name)) { 9 | const field = formData[name]; 10 | if (field.error.length) { 11 | errors++; 12 | } 13 | if (field.required && !field.value) { 14 | required++; 15 | } 16 | } 17 | } 18 | 19 | return errors === 0 && required === 0; 20 | }, []); 21 | }; -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/hooks/useValidatePasswords.js: -------------------------------------------------------------------------------- 1 | import {useCallback} from "react"; 2 | import config from "../../../../../../config"; 3 | 4 | export default function useValidatePasswords() { 5 | const PASSWORD_MIN_LENGTH = config.auth.minPasswordLength; 6 | 7 | return useCallback((pwd, pwdRepeat) => { 8 | let pwdError = ''; 9 | let pwdRepeatError = ''; 10 | 11 | if (pwd.length > 0 && pwd.length < PASSWORD_MIN_LENGTH) { 12 | pwdError = `Password must be greater than ${PASSWORD_MIN_LENGTH} symbols`; 13 | } else if (pwdRepeat.length > 0 && pwd !== pwdRepeat) { 14 | pwdError = 'Passwords mismatch'; 15 | pwdRepeatError = 'Passwords mismatch'; 16 | } 17 | 18 | return { 19 | pwd: pwdError, 20 | pwdRepeat: pwdRepeatError, 21 | }; 22 | }, []); 23 | }; -------------------------------------------------------------------------------- /src/components/main/auth/blocks/forms/hooks/useValidateUsername.js: -------------------------------------------------------------------------------- 1 | import auth from "../../../../../../api/auth"; 2 | import {useCallback} from "react"; 3 | 4 | export default function useValidateUsername() { 5 | return useCallback(async (username, onCheck, onError) => { 6 | let error = ''; 7 | let result; 8 | try { 9 | result = await auth.checkName(username); 10 | } catch(error){ 11 | onError(error); 12 | return; 13 | } 14 | 15 | const { data } = result; 16 | if (data && data["db-name"] === "ok" && data["blockchain"] === 'ok') { 17 | error = 'The username already exists. Please use a different username'; 18 | } 19 | 20 | onCheck(error); 21 | }, []); 22 | }; -------------------------------------------------------------------------------- /src/components/main/auth/hooks/useAuthCallback.js: -------------------------------------------------------------------------------- 1 | export default function useAuthCallback(callback, authData) { 2 | window.location.href = `${callback}?opr-nickname=${encodeURIComponent(authData.name)}&opr-token=${encodeURIComponent(authData.token)}`; 3 | }; -------------------------------------------------------------------------------- /src/components/main/auth/providers/AuthContext.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const AuthContext = React.createContext({}); 4 | 5 | export default AuthContext; -------------------------------------------------------------------------------- /src/components/main/blockchain/BlockPage.js: -------------------------------------------------------------------------------- 1 | import React, {useEffect, useState} from 'react'; 2 | import {useParams} from "react-router"; 3 | 4 | import {getBlock} from "../../../api/data"; 5 | 6 | import Loader from "../blocks/Loader"; 7 | import BlockInfo from "./blocks/BlockInfo"; 8 | import BlocksHeader from "./blocks/BlocksHeader"; 9 | import Error404 from "../Error404"; 10 | import JSONViewer from "./blocks/JSONViewer/JSONViewer"; 11 | import {makeStyles} from "@material-ui/styles"; 12 | 13 | const useStyles = makeStyles({ 14 | jsonViewer: { 15 | marginBottom: "24px", 16 | }, 17 | }); 18 | 19 | export default function BlockPage() { 20 | const { param } = useParams(); 21 | 22 | const [state, setState] = useState({ 23 | loading: true, 24 | block: null, 25 | }); 26 | const [error, setError] = useState(null); 27 | const classes = useStyles(); 28 | 29 | useEffect(() => { 30 | const fetchData = async () => { 31 | try { 32 | let blockId = null; 33 | let hash = null; 34 | if (Number(param) > 0) { 35 | blockId = param; 36 | } else { 37 | hash = param; 38 | } 39 | 40 | const block = await getBlock({blockId, hash}); 41 | 42 | setState({ 43 | block, 44 | loading: false, 45 | }); 46 | } catch (error) { 47 | setError(error); 48 | } 49 | }; 50 | 51 | fetchData(); 52 | }, []); 53 | 54 | if (error) { 55 | if (error.code === 404) { 56 | return ; 57 | } 58 | 59 | throw error; 60 | } 61 | 62 | const {block, loading} = state; 63 | if (loading) { 64 | return ; 65 | } 66 | 67 | return
    68 | Block #{block.block_id} 69 | 70 | 71 |
    ; 72 | }; 73 | -------------------------------------------------------------------------------- /src/components/main/blockchain/BlockchainLayout.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Grid} from "@material-ui/core"; 3 | 4 | import Sidebar from "./blocks/sidebar/Sidebar"; 5 | import BlockchainRouter from "./BlockchainRouter"; 6 | import OperationsProvider from "./providers/OperationsProvider"; 7 | import {makeStyles} from "@material-ui/styles"; 8 | 9 | const useStyles = makeStyles({ 10 | mainColumn: { 11 | paddingBottom: "20px", 12 | } 13 | }) 14 | 15 | export default function BlockchainLayout() { 16 | const classes = useStyles(); 17 | return 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ; 27 | }; 28 | -------------------------------------------------------------------------------- /src/components/main/blockchain/BlockchainRouter.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Redirect, Route, Switch, useRouteMatch} from "react-router-dom"; 3 | 4 | import BlocksPage from "./BlocksPage"; 5 | import BlockPage from "./BlockPage"; 6 | import Transactions from "./TransactionsPage"; 7 | import Transaction from "./TransactionPage"; 8 | import QueuePage from "./QueuePage"; 9 | import ObjectsPage from "./ObjectsPage"; 10 | import Error404 from "../Error404"; 11 | 12 | export default function BlockChainRouter() { 13 | let {path, url} = useRouteMatch(); 14 | 15 | return 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ; 28 | }; 29 | -------------------------------------------------------------------------------- /src/components/main/blockchain/ObjectsPage.js: -------------------------------------------------------------------------------- 1 | import React, {useContext, useEffect, useState} from 'react'; 2 | 3 | import config from "../../../config"; 4 | import {getObjects, getObjectsById} from "../../../api/data"; 5 | import OperationsContext from "./providers/OperationsContext"; 6 | 7 | import {Box} from "@material-ui/core"; 8 | import Loader from "../blocks/Loader"; 9 | import BlocksList from "./blocks/BlocksList"; 10 | import BlocksHeader from "./blocks/BlocksHeader"; 11 | import ObjectItem from "./blocks/list-items/ObjectItem"; 12 | import Error404 from "../Error404"; 13 | import qs from "qs"; 14 | 15 | const BLOCKS_PER_PAGE = config.blockchain.blocksPageLimit; 16 | 17 | export default function ObjectsPage({match}) { 18 | const [state, setState] = useState({ 19 | objects: [], 20 | loading: true, 21 | }); 22 | const [error, setError] = useState(null); 23 | const {loading, objects} = state; 24 | const {params} = match; 25 | const type = params.type.replace('_', '.'); 26 | const {key} = qs.parse(location.search.substring(1)); 27 | const {types, loading: opsLoading} = useContext(OperationsContext); 28 | const typenames = Object.keys(types); 29 | 30 | useEffect(() => { 31 | const fetchData = async () => { 32 | let results; 33 | try { 34 | if (key) { 35 | results = await getObjectsById(type, key); 36 | } else { 37 | results = await getObjects({ 38 | limit: BLOCKS_PER_PAGE, 39 | type, 40 | }); 41 | } 42 | } catch (error) { 43 | setError(error) 44 | return; 45 | } 46 | 47 | const {objects: newObjects} = results; 48 | 49 | const newState = { ...state }; 50 | newState.objects = newObjects; 51 | newState.loading = false; 52 | 53 | setState(newState); 54 | }; 55 | 56 | if (!error) { 57 | fetchData(); 58 | } 59 | }, [type, key]); 60 | 61 | useEffect(() => { 62 | if (key) { 63 | window.scrollTo(0, 0); 64 | } 65 | }, [key]); 66 | 67 | if (error) { 68 | throw error; 69 | } 70 | 71 | let content 72 | if (!loading && !opsLoading) { 73 | if (!typenames.includes(type)) { 74 | return ; 75 | } else if (objects.length) { 76 | content = objects.map((ob) => ) 77 | } else { 78 | content = (

    No objects available

    ); 79 | } 80 | } else { 81 | return ; 82 | } 83 | 84 | return 85 | Objects {key && key.split(',').join(', ')} 86 | {content} 87 | ; 88 | }; 89 | -------------------------------------------------------------------------------- /src/components/main/blockchain/TransactionPage.js: -------------------------------------------------------------------------------- 1 | import React, {useEffect, useState} from 'react'; 2 | import {usePromiseTracker} from "react-promise-tracker"; 3 | 4 | import {getTransaction} from "../../../api/data"; 5 | import Loader from "../blocks/Loader"; 6 | import BlocksHeader from "./blocks/BlocksHeader"; 7 | import SummaryBlock from "./blocks/SummaryBlock"; 8 | import Value from "./blocks/Value"; 9 | import JSONViewer from "./blocks/JSONViewer/JSONViewer"; 10 | import ObjectsSummary from "./blocks/ObjectsSummary"; 11 | import {makeStyles} from "@material-ui/styles"; 12 | 13 | const useStyles = makeStyles({ 14 | jsonViewer: { 15 | marginBottom: "24px", 16 | }, 17 | }); 18 | 19 | export default function TransactionPage({match}) { 20 | const {promiseInProgress} = usePromiseTracker(); 21 | const [error, setError] = useState(null); 22 | const [state, setState] = useState({ 23 | block: null, 24 | loading: true, 25 | }); 26 | const classes = useStyles(); 27 | 28 | const {params: { hash }} = match; 29 | 30 | useEffect(() => { 31 | const fetchData = async () => { 32 | try { 33 | const block = await getTransaction(hash); 34 | setState({ 35 | block, 36 | loading: false, 37 | }); 38 | } catch (error) { 39 | setError(error); 40 | } 41 | }; 42 | 43 | fetchData(); 44 | }, [hash]); 45 | 46 | if (error) { 47 | if (error.code === 404) { 48 | return
    49 | Transaction 50 |

    Transaction deprecated or not found

    51 |
    ; 52 | } 53 | 54 | throw error; 55 | } 56 | 57 | const {loading, block} = state; 58 | if (loading || promiseInProgress) { 59 | return ; 60 | } 61 | 62 | const {signedByStr, shortHash} = block.clientData; 63 | return
    64 | Transaction {shortHash} 65 | 66 |

    Hash: {block.hash}

    67 | 68 |

    Signed by: #{signedByStr}

    69 |
    70 | 71 |
    ; 72 | }; 73 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/BlockIcon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Icon from "./Icon"; 4 | 5 | import blockIcon from "../../../../assets/images/blockchain_icons/blockchain.svg"; 6 | const reqSvgs = require.context("../../../../assets/images/blockchain_icons/operations/", true, /\.svg$/) 7 | const operationsIcons = reqSvgs 8 | .keys() 9 | .reduce((images, path) => { 10 | const name = path.replace(/^.*[\\\/]/, '').split('.').shift(); 11 | images[name] = reqSvgs(path).default; 12 | return images; 13 | }, {}); 14 | 15 | export default function BlockIcon({icon = ''}) { 16 | const [type, ic_name] = icon.split(':'); 17 | 18 | let url = blockIcon; 19 | if (type === 'opendb-icons' && ic_name && operationsIcons[ic_name]) { 20 | url = operationsIcons[ic_name]; 21 | } 22 | 23 | return ; 24 | } -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/BlockInfo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import SummaryBlock from "./SummaryBlock"; 3 | import Value from "./Value"; 4 | import Selection from "./Selection"; 5 | 6 | export default function BlockInfo({block}) { 7 | const {hash, block_id, operations_size} = block; 8 | const {signedByStr} = block.clientData; 9 | 10 | return 11 |

    Block id: #{block_id}

    12 |

    Hash: {hash}

    13 |

    Operations count: {operations_size}

    14 |

    Signed by: #{signedByStr}

    15 |
    ; 16 | }; 17 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/BlocksHeader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | header: { 6 | marginBottom: "20px", 7 | fontSize: "40px", 8 | letterSpacing: "0.01em", 9 | }, 10 | }); 11 | 12 | export default function BlocksHeader({children}) { 13 | const classes = useStyles(); 14 | return

    {children}

    ; 15 | } 16 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/BlocksList.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | list: { 6 | borderTop: "1px solid #E4E8F2", 7 | position: "relative", 8 | minHeight: "200px", 9 | paddingBottom: "20px", 10 | marginBottom: "20px", 11 | }, 12 | }); 13 | 14 | export default function BlocksList({children}) { 15 | const classes = useStyles(); 16 | return
    {children}
    ; 17 | } 18 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/FilterOperations.js: -------------------------------------------------------------------------------- 1 | import React, {useContext} from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | import Select from '@material-ui/core/Select'; 4 | import MenuItem from '@material-ui/core/MenuItem'; 5 | import OperationsContext from "../providers/OperationsContext"; 6 | import AllTypesIcon from "../../../../assets/images/blockchain_icons/all_types.svg"; 7 | import BlockIcon from "./BlockIcon"; 8 | 9 | const itemStyle = { 10 | display: "flex", 11 | alignItems: "center", 12 | height: "40px", 13 | minWidth: "200px", 14 | textAlign: "left", 15 | paddingTop: 0, 16 | paddingBottom: 0, 17 | }; 18 | 19 | const useStyles = makeStyles({ 20 | dropdown: { 21 | background: "#F1F4FC", 22 | border: "1px solid #C3CFE6", 23 | borderRadius: "5px", 24 | minWidth: "200px", 25 | height: "40px", 26 | "& .MuiSelect-root": itemStyle, 27 | }, 28 | item: itemStyle, 29 | title: { 30 | marginLeft: "8px", 31 | } 32 | }); 33 | 34 | export default function FilterOperations({onChange, value}) { 35 | const {operations, loading, types} = useContext(OperationsContext); 36 | const classes = useStyles(); 37 | 38 | const handleChange = (e) => { 39 | onChange(e.target.value); 40 | }; 41 | 42 | let options = []; 43 | if (!loading) { 44 | options = operations.map((op, i) => { 45 | const OpClass = types[op.id]; 46 | const baseName = OpClass.getName(0); 47 | 48 | return 49 | 50 |

    {baseName}

    51 |
    ; 52 | }); 53 | } 54 | 55 | return 70 | }; 71 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/Icon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function Icon({url}) { 4 | return icon 5 | } -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/JSONViewer/ExpandBtn.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {SvgIcon, Link} from "@material-ui/core"; 3 | import {makeStyles} from "@material-ui/styles"; 4 | 5 | const useStyles = makeStyles({ 6 | arrow: { 7 | width: "10px", 8 | height: "6px", 9 | verticalAlign: "middle", 10 | marginLeft: "10px", 11 | }, 12 | link: { 13 | color: "#2D69E0", 14 | textDecoration: "none", 15 | verticalAlign: "middle", 16 | "&:active": { 17 | color: "#2D69E0", 18 | textDecoration: "none", 19 | } 20 | }, 21 | }); 22 | 23 | export default function ExpandBtn({onClick}) { 24 | const classes = useStyles(); 25 | 26 | return 27 | Raw json 28 | 29 | 30 | 31 | ; 32 | } 33 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/JSONViewer/JSONViewer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactJson from 'react-json-view' 3 | 4 | import Collapse from '@material-ui/core/Collapse'; 5 | 6 | export default function JSONViewer({json, open = false, className}) { 7 | const src = { ...json }; 8 | delete src.clientData; 9 | 10 | const oprAdminTheme = { 11 | //Background 12 | base00: '#1c2833', 13 | base01: '#073642', 14 | //Borders 15 | base02: '#525252', 16 | base03: '#073642', 17 | base04: '#839496', 18 | base05: '#93a1a1', 19 | base06: '#eee8d5', 20 | //Properties 21 | base07: '#4fdee5', 22 | base08: '#ff8c00', 23 | //Strings 24 | base09: '#0ad161', 25 | base0A: '#b58900', 26 | base0B: '#859900', 27 | base0C: '#2aa198', 28 | //Open arrows 29 | base0D: '#fff', 30 | //Closed arrows 31 | base0E: '#fff', 32 | //Numbers 33 | base0F: '#ff8c00' 34 | }; 35 | 36 | return 37 | 56 | ; 57 | }; 58 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/JSONViewer/SumaryViewer.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import JSONViewer from "./JSONViewer"; 3 | import ExpandBtn from "./ExpandBtn"; 4 | 5 | export default function SummaryViewer({block}) { 6 | const [open, expand] = useState(true); 7 | 8 | const onExpandClick = (e) => { 9 | e.preventDefault(); 10 | expand(!open); 11 | }; 12 | 13 | return
    14 | 15 | 16 |
    ; 17 | }; 18 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/ObjectsSummary.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Value from "./Value"; 3 | 4 | export default function ObjectsSummary({op, listItem}) { 5 | return
    6 | {op.new &&

    Objects created: {op.new.length}

    } 7 | {op.old &&

    Objects deleted: {op.old.length}

    } 8 | {op.edit &&

    Objects edited: {op.edit.length}

    } 9 |
    ; 10 | }; -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/Selection.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | Selection: { 6 | color: "#2D69E0", 7 | } 8 | }) 9 | 10 | export default function Selection({children}) { 11 | const classes = useStyles(); 12 | return {children} 13 | }; 14 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/SpecChar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | root: { 6 | display: "inline-block", 7 | margin: "0 3px", 8 | } 9 | }) 10 | 11 | export default function SpecChar({code}) { 12 | const classes = useStyles(); 13 | return {code} 14 | }; -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/SummaryBlock.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | block: { 6 | background: "#F0F1F4", 7 | border: "1px solid #F0F1F4", 8 | borderRadius: "5px", 9 | padding: "15px", 10 | margin: "10px 0 25px 0", 11 | color: "#6A7181", 12 | fontSize: "15px", 13 | lineHeight: "1.5em", 14 | "& p": { 15 | margin: "5px", 16 | }, 17 | "& span": { 18 | color: "#000", 19 | }, 20 | }, 21 | 22 | }) 23 | 24 | export default function SummaryBlock({children}) { 25 | const classes = useStyles(); 26 | return
    27 | {children} 28 |
    ; 29 | }; 30 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/Value.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | value: { 6 | fontWeight: props => props.listItem ? "bold" : "normal", 7 | color: props => props.color ? props.color : "#000", 8 | fontSize: "15px", 9 | } 10 | }); 11 | 12 | export default function Value({children, listItem, color}) { 13 | const classes = useStyles({listItem, color}); 14 | return {children} 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/list-items/BlockItem.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import blockIcon from "../../../../../assets/images/blockchain_icons/blockchain.svg"; 4 | 5 | import DataListItem from "./DataListItem"; 6 | import Value from "../Value"; 7 | import Icon from "../Icon"; 8 | 9 | export default function BlockItem({block}) { 10 | const { 11 | block_id, 12 | operations_size, 13 | date, 14 | clientData: { 15 | shortHash, 16 | signedByStr, 17 | } 18 | } = block; 19 | 20 | const IconComponent = ; 21 | return 30 |

    Operations count: {operations_size}

    31 |

    Date: {date}

    32 |
    ; 33 | } 34 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/list-items/ObjectItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import DataListItem from "./DataListItem"; 3 | import BlockIcon from "../BlockIcon"; 4 | import useFormatting from "../../hooks/useFormatting"; 5 | 6 | export default function ObjectItem({object}) { 7 | const { 8 | clientData: { 9 | shortHash, 10 | parentHash, 11 | } 12 | } = object; 13 | 14 | const OpClass = useFormatting(object); 15 | 16 | const icon = ; 17 | const title = OpClass.getObjName(object); 18 | const type = object.clientData.type.replace('.', '_'); 19 | const objLink = `/data/objects/${type}?key=${object.clientData.id}`; 20 | const transLink = `/data/transaction/${parentHash}`; 21 | 22 | return 30 |

    Object type: {OpClass.getName()}

    31 | {object.comment &&

    Comment: {object.comment}

    } 32 |
    ; 33 | }; 34 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/list-items/OperationItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import DataListItem from "./DataListItem"; 3 | 4 | import useFormatting from "../../hooks/useFormatting"; 5 | import ObjectsSummary from "../ObjectsSummary"; 6 | import BlockIcon from "../BlockIcon"; 7 | import Value from "../Value"; 8 | 9 | export default function OperationItem({operation}) { 10 | const { 11 | clientData: { 12 | signedByStr, 13 | shortHash, 14 | rawHash, 15 | } 16 | } = operation; 17 | 18 | const OpClass = useFormatting(operation); 19 | 20 | const title = OpClass.getOpDescription(operation); 21 | const icon = ; 22 | const link = `/data/transaction/${rawHash}`; 23 | 24 | let content; 25 | let objects = []; 26 | if (Array.isArray(operation.new)) { 27 | objects = objects.concat(operation.new); 28 | } 29 | if (Array.isArray(operation.old)) { 30 | objects = objects.concat(operation.old); 31 | } 32 | if (Array.isArray(operation.edit)) { 33 | objects = objects.concat(operation.edit); 34 | } 35 | 36 | if (objects.length === 1) { 37 | const object = objects[0]; 38 | let desc = OpClass.getObjDescription(object); 39 | content = 40 |

    Object type: {OpClass.getName()}

    41 | {desc &&

    {desc}

    } 42 |
    ; 43 | } 44 | 45 | return 54 | {operation.comment &&

    Comment: {operation.comment}

    } 55 | {content} 56 | 57 |
    ; 58 | }; 59 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/sidebar/ListItemSidebar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | import ListItem from "@material-ui/core/ListItem"; 4 | 5 | const useStyles = makeStyles({ 6 | root: { 7 | padding: "5px 10px 5px 10px", 8 | }, 9 | }); 10 | 11 | export default function ListItemSidebar({children, ...bypass}) { 12 | const classes = useStyles(); 13 | 14 | return 15 | {children} 16 | ; 17 | } 18 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/sidebar/Objects.js: -------------------------------------------------------------------------------- 1 | import React, {useContext} from 'react'; 2 | import SidebarHeader from "./SidebarHeader"; 3 | import SidebarItem from "./SidebarItem"; 4 | 5 | import OperationsContext from "../../providers/OperationsContext"; 6 | import BlockIcon from "../BlockIcon"; 7 | 8 | export default function Objects(index) { 9 | const {operations, loading, types, count} = useContext(OperationsContext); 10 | 11 | let content = []; 12 | if (operations.length && !loading) { 13 | content = operations.map((o) => { 14 | const OpClass = types[o.id]; 15 | const baseName = OpClass.getName(index); 16 | const icon = ; 17 | 18 | return 25 | }) 26 | } 27 | 28 | return <> 29 | 30 | {content} 31 | ; 32 | }; 33 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/sidebar/Queue.js: -------------------------------------------------------------------------------- 1 | import React, {useEffect, useState} from 'react'; 2 | 3 | import {getQueue} from "../../../../../api/data"; 4 | 5 | import queueIcon from "../../../../../assets/images/blockchain_icons/queue.svg"; 6 | import SidebarItem from "./SidebarItem"; 7 | import Icon from "../Icon"; 8 | 9 | export default function Queue() { 10 | const [opsCount, setCount] = useState(0); 11 | 12 | useEffect(() => { 13 | const fetchData = async () => { 14 | try { 15 | const { count } = await getQueue(); 16 | setCount(count); 17 | } catch (e) { 18 | console.warn('Network request failed'); 19 | } 20 | } 21 | 22 | fetchData(); 23 | }, []); 24 | 25 | const itemIcon = ; 26 | return ; 27 | } 28 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/sidebar/Sidebar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | import List from '@material-ui/core/List'; 4 | import Divider from '@material-ui/core/Divider'; 5 | import SidebarHeader from "./SidebarHeader"; 6 | import Queue from "./Queue"; 7 | import BlocksFilter from "./BlocksFilter"; 8 | import Objects from "./Objects"; 9 | 10 | const MemoQueue = React.memo(Queue); 11 | const MemoBlocksFilter = React.memo(BlocksFilter); 12 | const MemoSidebarObjects = React.memo(Objects); 13 | 14 | const useStyles = makeStyles({ 15 | root: { 16 | marginTop: '114px', 17 | width: '100%', 18 | maxWidth: 360, 19 | border: "1px solid #CCD0D9", 20 | textAlign: "center", 21 | marginBottom: "20px", 22 | borderRadius: "5px", 23 | }, 24 | divider: { 25 | background: "#CCD0D9", 26 | } 27 | }); 28 | 29 | export default function Sidebar() { 30 | const classes = useStyles(); 31 | 32 | return ( 33 | 38 | } 39 | className={classes.root} 40 | > 41 | 42 | 43 | 44 | 45 | 46 | 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/sidebar/SidebarHeader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ListItem from "@material-ui/core/ListItem"; 3 | import ListItemText from "@material-ui/core/ListItemText"; 4 | import ValueSidebarItem from "./ValueSidebarItem"; 5 | import {makeStyles} from "@material-ui/styles"; 6 | 7 | const useStyles = makeStyles({ 8 | root: { 9 | font: "IBM Ples Sans", 10 | fontWeight: 600, 11 | color: "#56627A", 12 | "& span": { 13 | fontWeight: "bold", 14 | } 15 | }, 16 | }); 17 | 18 | export default function SidebarHeader({text, count}) { 19 | const classes = useStyles(); 20 | 21 | return 22 | 23 | {(count !== undefined) && } 24 | ; 25 | }; 26 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/sidebar/SidebarItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | import {NavLink} from "react-router-dom"; 5 | import ListItemIcon from "@material-ui/core/ListItemIcon"; 6 | import ListItemText from "@material-ui/core/ListItemText"; 7 | import ListItemSidebar from "./ListItemSidebar"; 8 | import ValueSidebarItem from "./ValueSidebarItem"; 9 | 10 | const useStyles = makeStyles({ 11 | icon: { 12 | minWidth: "20px", 13 | width: "20px", 14 | marginRight: "20px", 15 | }, 16 | activeLink: { 17 | color: "#140579", 18 | textDecorationColor: "#140579 !important", 19 | "& li, & > div": { 20 | background: "#FFC93A", 21 | color: "#140579", 22 | }, 23 | "& svg .fill": { 24 | fill: "#140579", 25 | }, 26 | "& svg .stroke": { 27 | stroke: "#140579", 28 | } 29 | }, 30 | }); 31 | 32 | export default function SidebarItem({text, count, icon, to, ...pass}) { 33 | const classes = useStyles(); 34 | 35 | return 36 | 37 | 38 | {icon} 39 | 40 | 41 | {(count !== undefined) && } 42 | 43 | ; 44 | }; 45 | -------------------------------------------------------------------------------- /src/components/main/blockchain/blocks/sidebar/ValueSidebarItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction"; 3 | import {makeStyles} from "@material-ui/styles"; 4 | 5 | const useStyles = makeStyles({ 6 | root: { 7 | color: "#ACB2BF", 8 | } 9 | }); 10 | 11 | export default function ValueSidebarItem({value}) { 12 | const classes = useStyles(); 13 | 14 | return {value} 15 | } 16 | -------------------------------------------------------------------------------- /src/components/main/blockchain/hooks/useFormatting.js: -------------------------------------------------------------------------------- 1 | import {useContext} from "react"; 2 | import OperationsContext from "../providers/OperationsContext"; 3 | 4 | export default function useFormatting(block) { 5 | const {types} = useContext(OperationsContext); 6 | if (!block) return {}; 7 | const blockType = block.clientData.type || block.type; 8 | 9 | return types[blockType]; 10 | }; -------------------------------------------------------------------------------- /src/components/main/blockchain/providers/OperationsContext.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const OperationsContext = React.createContext({}); 4 | 5 | export default OperationsContext; 6 | -------------------------------------------------------------------------------- /src/components/main/blockchain/providers/OperationsProvider.js: -------------------------------------------------------------------------------- 1 | import React, {useEffect, useState} from "react"; 2 | 3 | import config from '../../../../config'; 4 | 5 | import OperationsContext from './OperationsContext'; 6 | import {getOperations} from "../../../../api/data"; 7 | 8 | export default ({children}) => { 9 | const [state, setState] = useState({ 10 | loading: true, 11 | types: {} 12 | }); 13 | const [operations, setOperations] = useState({ 14 | operations: [], 15 | count: 0, 16 | }); 17 | const [error, setError] = useState(''); 18 | 19 | if (error) { 20 | throw new Error(error); 21 | } 22 | 23 | useEffect(() => { 24 | const script = document.createElement("script"); 25 | script.src = config.blockchain.opsTransformSrc; 26 | script.async = true; 27 | script.onload = () => { 28 | if (!Array.isArray(OP_SYS_TYPES)) { 29 | setError('Blockchain operation types not loaded!'); 30 | return; 31 | } 32 | 33 | const types = {}; 34 | OP_SYS_TYPES.forEach((Op) => { 35 | if (!Op.hasOwnProperty('key')) { 36 | return; 37 | } 38 | 39 | types[Op.key()] = new Op(); 40 | }); 41 | 42 | setState({ 43 | types, 44 | loading: false, 45 | }) 46 | } 47 | 48 | document.body.appendChild(script); 49 | }, []); 50 | 51 | useEffect(() => { 52 | const fetchData = async () => { 53 | const results = await getOperations(); 54 | setOperations(results); 55 | }; 56 | 57 | fetchData(); 58 | }, []); 59 | 60 | const contextValue = { 61 | ...state, 62 | ...operations, 63 | } 64 | 65 | return 66 | {children} 67 | ; 68 | }; 69 | 70 | -------------------------------------------------------------------------------- /src/components/main/blocks/Footer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | root: { 6 | backgroundColor: "#ebf2f5", 7 | color: "#596680", 8 | textAlign: "center", 9 | height: "50px", 10 | "& p": { 11 | margin: "0 auto", 12 | paddingTop: "10px", 13 | }, 14 | }, 15 | }); 16 | 17 | export default () => { 18 | const classes = useStyles(); 19 | 20 | return ; 23 | }; 24 | -------------------------------------------------------------------------------- /src/components/main/blocks/Loader.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {createUseStyles} from 'react-jss'; 3 | import loaderImg from "../../../assets/images/loader.png"; 4 | 5 | const useStyles = createUseStyles({ 6 | loader: (props) => { 7 | const style = { 8 | background: `url(${loaderImg}) no-repeat center center`, 9 | display: "block", 10 | width: "220px", 11 | height: "25px", 12 | position: "fixed", 13 | margin: "0 auto", 14 | }; 15 | 16 | if (props.position) { 17 | style.position = props.position; 18 | } 19 | 20 | if (props.position === 'relative') { 21 | style.margin = "20px auto"; 22 | } else { 23 | style.transform = "translateY(-50%)"; 24 | style.top = "50%"; 25 | style.left = 0; 26 | style.right = 0; 27 | } 28 | 29 | return style; 30 | } 31 | }); 32 | 33 | export default function Loader({position = ''}) { 34 | const classes = useStyles({position}); 35 | return ; 36 | } 37 | -------------------------------------------------------------------------------- /src/components/main/blocks/OPRLink.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Link} from "react-router-dom"; 3 | import {makeStyles} from "@material-ui/styles"; 4 | 5 | const useStyles = makeStyles({ 6 | link: { 7 | display: "inline !important", 8 | fontSize: "15px !important", 9 | color: "#2D69E0 !important", 10 | textDecoration: "none !important", 11 | verticalAlign: "middle !important", 12 | "&:active": { 13 | color: "#2D69E0 !important", 14 | textDecoration: "none !important", 15 | } 16 | }, 17 | }); 18 | 19 | export default function OPRLink({to, children}) { 20 | const classes = useStyles(); 21 | return {children}; 22 | } -------------------------------------------------------------------------------- /src/components/map/MapLayout.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ErrorBoundary from "../main/ErrorBoundary"; 3 | import Header from "../blocks/Header"; 4 | import Map from "./Map"; 5 | import {makeStyles} from "@material-ui/styles"; 6 | 7 | const useStyle = makeStyles({ 8 | column: { 9 | display: "flex", 10 | flexDirection: "column", 11 | flex: 1, 12 | } 13 | }); 14 | 15 | export default function MapLayout() { 16 | const classes = useStyle(); 17 | return
    18 |
    19 | 20 | 21 | 22 |
    23 | } -------------------------------------------------------------------------------- /src/components/map/MarkerEntity.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Marker} from "react-leaflet"; 3 | import MarkerIcon from './MarkerIcon'; 4 | 5 | export default function ({feature, onSelect}) { 6 | const {place_type} = feature.properties; 7 | const {place_deleted} = feature.properties.place_deleted; 8 | const {place_deleted_osm} = feature.properties.place_deleted_osm; 9 | const {deleted} = feature.properties.deleted; 10 | const lngLat = feature.geometry.coordinates; 11 | const latLng = [lngLat[1], lngLat[0]]; 12 | 13 | const icon = MarkerIcon(place_type, place_deleted, place_deleted_osm, deleted); 14 | 15 | const onClickHandler = () => { 16 | onSelect(feature); 17 | }; 18 | 19 | return 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/map/MergeList.js: -------------------------------------------------------------------------------- 1 | import MergeListDialog from "./blocks/dialogs/MergeListDialog"; 2 | import React, {useEffect, useState} from "react"; 3 | 4 | export default function MergeList({ 5 | mergeListDialogOpen, 6 | setMergeListDialogOpen, 7 | mergePlaces, 8 | placeTypes, 9 | setMergeListDialogWasClosed, 10 | alreadyReviewed 11 | }) { 12 | 13 | const [idsPlacesLocallyMerged, setIdsPlacesLocallyMerged] = useState([]); 14 | 15 | useEffect(() => { 16 | idsPlacesLocallyMerged.splice(0, idsPlacesLocallyMerged.length) 17 | setIdsPlacesLocallyMerged(idsPlacesLocallyMerged); 18 | }, [mergePlaces]); 19 | 20 | return mergeListDialogOpen && 21 | 27 | 28 | } -------------------------------------------------------------------------------- /src/components/map/ViewTracker.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {useMap, useMapEvent} from "react-leaflet"; 3 | import storage from "../../libs/storage"; 4 | 5 | export default function ViewTracker({ whenMoved }) { 6 | const map = useMap(); 7 | 8 | useMapEvent('moveend', () => { 9 | if (!!storage) { 10 | const view = { 11 | lat: map.getCenter().lat, 12 | lng: map.getCenter().lng, 13 | zoom: map.getZoom() 14 | }; 15 | storage.mapView = JSON.stringify(view); 16 | } 17 | whenMoved(); 18 | }); 19 | 20 | return null; 21 | } -------------------------------------------------------------------------------- /src/components/map/blocks/AttributesBarList.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import AttributesBar from "./AttributesBar"; 3 | 4 | export default function AttributesBarList({place, inactiveLinksVisible, isOpen}) { 5 | 6 | const attributesBarList = []; 7 | 8 | place && place.sources && Object.entries(place.sources).map(([type, sources], index) => { 9 | if (type === 'osm') { 10 | for (const source of sources) { 11 | if (inactiveLinksVisible || !source.deleted) { 12 | attributesBarList.push() 13 | } 14 | } 15 | } else { 16 | attributesBarList.push() 18 | } 19 | }) 20 | 21 | return attributesBarList; 22 | 23 | } -------------------------------------------------------------------------------- /src/components/map/blocks/BlockExpandable.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import {Accordion, AccordionSummary, AccordionDetails} from "@material-ui/core"; 3 | import ArrowDropDown from '@material-ui/icons/ArrowDropDown'; 4 | import {makeStyles} from "@material-ui/styles"; 5 | 6 | const useStyles = makeStyles({ 7 | root: { 8 | width: "100%", 9 | boxShadow: "none", 10 | margin: (props) => `${props.marginTop ? props.marginTop : 0} auto 0 auto !important`, 11 | }, 12 | summary: { 13 | fontWeight: 600, 14 | fontSize: "16px", 15 | padding: 0, 16 | minHeight: "32px !important", 17 | "& .MuiIconButton-root": { 18 | padding: "0 15px", 19 | }, 20 | "& .MuiAccordionSummary-content": { 21 | margin: "10px 0", 22 | }, 23 | "& .MuiSvgIcon-root": { 24 | color: "#2D69E0", 25 | } 26 | }, 27 | details: { 28 | position: "relative", 29 | display: "block", 30 | padding: 0, 31 | fontSize: "14px", 32 | } 33 | }); 34 | 35 | export default function BlockExpandable({header, children, open = false, marginTop}) { 36 | const [expanded, setExpanded] = useState(open); 37 | const classes = useStyles({marginTop}); 38 | 39 | const handleChange = () => { 40 | setExpanded(!expanded); 41 | }; 42 | 43 | return 44 | } className={classes.summary}> 45 | {header} 46 | 47 | 48 | {children} 49 | 50 | 51 | }; -------------------------------------------------------------------------------- /src/components/map/blocks/CategorySelector.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Box, Button, MenuItem, Select} from "@material-ui/core"; 3 | import {makeStyles} from "@material-ui/styles"; 4 | import Utils from "../../util/Utils"; 5 | 6 | const useStyles = makeStyles({ 7 | root: { 8 | margin: "10px 0", 9 | }, 10 | selector: { 11 | height: "35px", 12 | background: "#FFF", 13 | }, 14 | button: { 15 | height: "35px", 16 | }, 17 | }); 18 | 19 | export default function CategorySelector({value, categories, onChange, onSubmit, disabled}) { 20 | const classes = useStyles(); 21 | 22 | return 23 | 28 | 36 | ; 37 | } -------------------------------------------------------------------------------- /src/components/map/blocks/ImagesBlock.js: -------------------------------------------------------------------------------- 1 | import React, {useContext} from 'react'; 2 | import BlockExpandable from "./BlockExpandable"; 3 | import ReviewImagesBlock from "./ReviewImagesBlock"; 4 | import Utils from "../../util/Utils"; 5 | import AuthContext from "../../main/auth/providers/AuthContext"; 6 | 7 | export default function ImagesBlock({ 8 | place, 9 | isOriginalPlace, 10 | categories, 11 | showReviewBlock, 12 | setPlaces, 13 | mergeBlock 14 | }) { 15 | 16 | const {authData} = useContext(AuthContext); 17 | const isLoggedIn = () => !!authData.token; 18 | const isEditable = isLoggedIn() && isOriginalPlace && !mergeBlock; 19 | 20 | if (place && place.images && categories) { 21 | const {images} = place; 22 | let reviewImagesBlock; 23 | 24 | if (showReviewBlock) { 25 | reviewImagesBlock = images.review && images.review.length > 0 ? 26 | 27 | 29 | : '' 30 | } 31 | 32 | return 33 | {reviewImagesBlock} 34 | {Object.keys(categories).map((category, index) => images[category] && images[category].length > 0 ? 35 | 37 | 39 | : '')} 40 | } else { 41 | return "" 42 | } 43 | } -------------------------------------------------------------------------------- /src/components/map/blocks/MergePlacesCardList.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import MergeDialogPlaceCard from "./MergeDialogPlaceCard"; 3 | 4 | export default function MergePlacesCardList({ 5 | mergeTo, 6 | mergeFromList, 7 | mergeToInfo, 8 | mergeFromInfo, 9 | categories, 10 | createClosedPlace, 11 | setMergeFrom, 12 | allowToMerge 13 | }) { 14 | 15 | const mergeFromPlaceList = []; 16 | 17 | function getPlaceByInfo(i) { 18 | if (mergeFromList.filter(place => place.id === mergeFromInfo[i].oprId).length === 1) { 19 | return mergeFromList[0]; 20 | } else { 21 | return null; 22 | } 23 | } 24 | 25 | if (mergeTo) { 26 | mergeFromPlaceList.push() 31 | } 32 | 33 | if (mergeFromList) { 34 | for (let i = 0; i < mergeFromInfo.length; i++) { 35 | if (mergeFromInfo[i] && mergeFromInfo[i].latLon !== null) { 36 | mergeFromPlaceList.push() 43 | } 44 | } 45 | } 46 | return mergeFromPlaceList; 47 | } -------------------------------------------------------------------------------- /src/components/map/blocks/ModalLightbox.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { makeStyles } from '@material-ui/core/styles'; 3 | import Modal from '@material-ui/core/Modal'; 4 | import Backdrop from '@material-ui/core/Backdrop'; 5 | import Fade from '@material-ui/core/Fade'; 6 | 7 | const useStyles = makeStyles({ 8 | modal: { 9 | display: 'flex', 10 | alignItems: 'center', 11 | justifyContent: 'center', 12 | outline: 'none', 13 | }, 14 | image: { 15 | maxWidth: "95%", 16 | maxHeight: "95%", 17 | minWidth: "95%", 18 | minHeight: "95%", 19 | width: "auto", 20 | height: "auto", 21 | objectFit: "contain", 22 | outline: 'none', 23 | }, 24 | }); 25 | 26 | export default function ModalLightbox({ image, onClose }) { 27 | const classes = useStyles(); 28 | const open = !!image; 29 | 30 | return 40 | 41 | 42 | 43 | ; 44 | } -------------------------------------------------------------------------------- /src/components/map/blocks/OPRMessageOverlay.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | messageOverlay: { 6 | padding: "15px", 7 | background: "#FFFFFF", 8 | boxShadow: "0 4px 4px rgba(0, 0, 0, 0.25)", 9 | borderRadius: "12px", 10 | zIndex: 1100, 11 | position: "absolute", 12 | left: "50%", 13 | transform: "translateY(-50%)", 14 | top: "50px", 15 | }, 16 | }); 17 | 18 | export default function OPRMessageOverlay({children}) { 19 | const classes = useStyles(); 20 | 21 | return
    22 | {children} 23 |
    ; 24 | } -------------------------------------------------------------------------------- /src/components/map/blocks/StatusBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default ({status}) => { 4 | return

    {status}

    ; 5 | }; 6 | -------------------------------------------------------------------------------- /src/components/map/blocks/TagsTable.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | tags: { 6 | display: "grid", 7 | gridTemplateColumns: "1fr 2fr", 8 | border: "1px solid #ddd", 9 | "& dd, & dt": { padding: "0.5rem", margin: "0" }, 10 | "& dt": { backgroundColor: "#F6F6F6", color: "#2D69E0", borderTop: "1px solid #ddd" }, 11 | "& dd": { 12 | borderLeft: "1px solid #ddd", 13 | borderTop: "1px solid #ddd" 14 | }, 15 | "& dt:first-child": { borderTop: "none" } 16 | }, 17 | value: { 18 | wordBreak:"break-all" 19 | } 20 | 21 | }); 22 | 23 | export default function TagsTable({tags}) { 24 | const popupTags = []; 25 | for (let t in tags) { 26 | popupTags.push({ 27 | name: t, 28 | value: tags[t], 29 | }); 30 | } 31 | 32 | const classes = useStyles(); 33 | 34 | return
    35 | {popupTags.map((tag, i) => 36 |
    {tag.name}
    37 |
    -1) || tag.value.split('\s').find(word => word.length > 20) 38 | ? classes.value : null}>{tag.value}
    39 |
    )} 40 |
    41 | } -------------------------------------------------------------------------------- /src/components/map/blocks/carousels/ImagesCarousel.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Carousel from 'react-material-ui-carousel' 3 | import {makeStyles} from "@material-ui/styles"; 4 | 5 | const useStyles = makeStyles({ 6 | item: { 7 | height: "250px", 8 | "& img": { 9 | maxHeight: "250px", 10 | maxWidth: "350px", 11 | display: "block", 12 | margin: "0 auto", 13 | } 14 | }, 15 | }) 16 | 17 | const IMAGE_URL = '/api/ipfs/image?hash='; 18 | 19 | export default function ImagesCarousel({items, index, onChange = () => {}, onClick = () => {}}) { 20 | const classes = useStyles(); 21 | 22 | return 23 | { 24 | items.map( (item, i) =>
    photo onClick(`${IMAGE_URL}${item.hash}&cid=${item.cid}&ext=${item.extension}`)} 28 | />
    ) 29 | } 30 |
    ; 31 | } 32 | -------------------------------------------------------------------------------- /src/components/map/blocks/sidebar/MapSidebar.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useRef } from 'react'; 2 | import { makeStyles } from "@material-ui/styles"; 3 | import { useMap } from "react-leaflet"; 4 | import L from "leaflet"; 5 | 6 | const POSITION_CLASSES = { 7 | bottomleft: 'leaflet-bottom leaflet-left', 8 | bottomright: 'leaflet-bottom leaflet-right', 9 | topleft: 'leaflet-top leaflet-left', 10 | topright: 'leaflet-top leaflet-right', 11 | left: 'leaflet-top leaflet-bottom leaflet-left', 12 | right: 'leaflet-top leaflet-bottom leaflet-right', 13 | } 14 | 15 | const useStyles = makeStyles({ 16 | sidebar: { 17 | border: "none !important", 18 | display: "flex", 19 | flexDirection: "column", 20 | alignItems: (props) => { props.alignItems }, 21 | } 22 | }); 23 | 24 | export default ({ position, className, children }) => { 25 | const sidebarRef = useRef(); 26 | const map = useMap(); 27 | 28 | useEffect(() => { 29 | // Disable dragging when user's cursor enters the element 30 | L.DomEvent.addListener(sidebarRef.current, 'mouseover', () => { 31 | map._handlers.forEach(handler => handler.disable()); 32 | }); 33 | L.DomEvent.addListener(sidebarRef.current, 'mouseout', () => { 34 | map._handlers.forEach(handler => handler.enable()); 35 | }); 36 | }, []); 37 | 38 | let alignItems; 39 | if (position === 'topright' || position === 'bottomright' || position === 'right') { 40 | alignItems = 'flex-end'; 41 | } else { 42 | alignItems = 'flex-start'; 43 | } 44 | 45 | const classes = useStyles({ alignItems }); 46 | const positionClass = 47 | (position && POSITION_CLASSES[position]) || POSITION_CLASSES.topleft 48 | 49 | return
    50 |
    51 | {children} 52 |
    53 |
    ; 54 | } 55 | -------------------------------------------------------------------------------- /src/components/map/blocks/sidebar/MapSidebarBlock.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {makeStyles} from "@material-ui/styles"; 3 | 4 | const useStyles = makeStyles({ 5 | root: { 6 | fontFamily: "IBM Plex Sans", 7 | padding: "10px 15px", 8 | background: "#FFFFFF", 9 | boxShadow: "0 4px 4px rgba(0, 0, 0, 0.25)", 10 | borderRadius: "12px", 11 | marginBottom: "20px", 12 | width: (props) => props.width ? props.width : "300px", 13 | }, 14 | }); 15 | 16 | export default function MapSidebarBlock({children, width}) { 17 | const classes = useStyles({width}); 18 | 19 | return
    20 | {children} 21 |
    ; 22 | }; -------------------------------------------------------------------------------- /src/components/map/hooks/useBatchDiff.js: -------------------------------------------------------------------------------- 1 | import {useEffect} from "react"; 2 | import UtilsDiff from "../../util/UtilsDiff"; 3 | 4 | export default function useBatchDiff(current, newObject, categories, edited, deleted, setEdited, setDeleted) { 5 | useEffect(() => { 6 | const isEqual = JSON.stringify(current) === JSON.stringify(newObject); 7 | const isMerge = current && newObject && JSON.stringify(current.id) !== JSON.stringify(newObject.id); 8 | if (!isEqual && categories) { 9 | const diff = UtilsDiff.compareObjects(current, newObject, categories, isMerge); 10 | setEdited([...edited, 11 | { 12 | id: current.id, 13 | ...diff 14 | } 15 | ]) 16 | 17 | if (isMerge) { 18 | setDeleted([...deleted, 19 | newObject.id 20 | ]) 21 | } 22 | } 23 | 24 | }, [current, newObject, categories]); 25 | } -------------------------------------------------------------------------------- /src/components/map/hooks/useBatchOp.js: -------------------------------------------------------------------------------- 1 | import {useEffect} from "react"; 2 | 3 | export default function useBatchOp(forceCommit, setForceCommit, deleted, edited, onDiff, maxBatchSizeOp) { 4 | useEffect(() => { 5 | if (forceCommit || edited.length === maxBatchSizeOp) { 6 | const op = { 7 | delete: [], 8 | edit: [], 9 | type: 'opr.place', 10 | } 11 | 12 | deleted.forEach(del => { 13 | op.delete.push(del) 14 | }); 15 | edited.forEach(edit => { 16 | op.edit.push(edit) 17 | }); 18 | onDiff(op); 19 | 20 | edited.splice(0, edited.length); 21 | deleted.splice(0, deleted.length); 22 | 23 | setForceCommit(false); 24 | } 25 | }, [deleted, edited, forceCommit]); 26 | } -------------------------------------------------------------------------------- /src/components/map/hooks/useCommitOp.js: -------------------------------------------------------------------------------- 1 | import {useEffect, useState} from "react"; 2 | import {commitObject} from "../../../api/data"; 3 | 4 | export default function useCommitOp (op, authData, onUpdate) { 5 | const [error, setError] = useState(null); 6 | 7 | useEffect(() => { 8 | const sendData = async () => { 9 | try { 10 | const {data} = await commitObject(op, `${authData.name}:${authData.provider}`, authData.token); 11 | onUpdate(data); 12 | } catch (error) { 13 | setError(error); 14 | } 15 | }; 16 | 17 | if (op) { 18 | sendData(); 19 | } 20 | }, [op]); 21 | 22 | if(error) { 23 | throw error; 24 | } 25 | } -------------------------------------------------------------------------------- /src/components/map/hooks/useDiff.js: -------------------------------------------------------------------------------- 1 | import {useEffect} from "react"; 2 | import UtilsDiff from "../../util/UtilsDiff"; 3 | 4 | export default function useDiff(current, newObject, categories, onDiff) { 5 | useEffect(() => { 6 | const isEqual = JSON.stringify(current) === JSON.stringify(newObject); 7 | const isMerge = current && newObject && JSON.stringify(current.id) !== JSON.stringify(newObject.id); 8 | if (!isEqual && categories) { 9 | const diff = UtilsDiff.compareObjects(current, newObject, categories, isMerge); 10 | const op = { 11 | edit: [ 12 | { 13 | id: current.id, 14 | ...diff, 15 | } 16 | ], 17 | type: 'opr.place', 18 | }; 19 | if (isMerge) { 20 | op.delete = [ 21 | newObject.id, 22 | ]; 23 | } 24 | onDiff(op); 25 | } 26 | }, [current, newObject, categories]); 27 | } -------------------------------------------------------------------------------- /src/components/map/hooks/useExtractObject.js: -------------------------------------------------------------------------------- 1 | import {useEffect, useState} from "react"; 2 | import {getObjectsById} from "../../../api/data"; 3 | 4 | export default function useExtractObject(marker, version, onLoad) { 5 | const [error, setError] = useState(null); 6 | 7 | useEffect(() => { 8 | const fetchData = async () => { 9 | try { 10 | const data = await getObjectsById('opr.place', marker.properties.opr_id); 11 | const object = data.objects.shift(); 12 | 13 | if (object && object.clientData) { 14 | delete object.clientData; 15 | } 16 | 17 | let similarObject = null; 18 | if (marker.properties.similar_opr_id) { 19 | const data = await getObjectsById('opr.place', marker.properties.similar_opr_id); 20 | similarObject = data.objects.shift(); 21 | if (similarObject && similarObject.clientData) { 22 | delete similarObject.clientData; 23 | } 24 | } 25 | onLoad(object, similarObject); 26 | } catch (e) { 27 | console.log(e); 28 | setError(error); 29 | } 30 | }; 31 | 32 | if (marker && marker.properties.opr_id) { 33 | fetchData(); 34 | } else { 35 | onLoad(null); 36 | } 37 | }, [marker, version]); 38 | 39 | if (error) { 40 | throw error; 41 | } 42 | }; -------------------------------------------------------------------------------- /src/components/map/hooks/usePersistedState.js: -------------------------------------------------------------------------------- 1 | import {useEffect, useState} from "react"; 2 | import storage from "../../../libs/storage"; 3 | 4 | export default function usePersistedState(defaultValue, key) { 5 | const [value, setValue] = []; 6 | setValue(useState(() => { 7 | try { 8 | const storedValue = storage.getItem(key); 9 | return !!storedValue ? JSON.parse(storedValue) : defaultValue; 10 | } catch (e) { 11 | return defaultValue; 12 | } 13 | })); 14 | 15 | useEffect(() => { 16 | storage.setItem(key, JSON.stringify(value)); 17 | }, [key, value]); 18 | 19 | return [value, setValue]; 20 | } -------------------------------------------------------------------------------- /src/components/map/hooks/useTaskSelectionState.js: -------------------------------------------------------------------------------- 1 | import {useEffect, useState} from "react"; 2 | import storage from "../../../libs/storage"; 3 | 4 | export default function useTaskSelectionState(defaultValue) { 5 | const key = 'taskSelection'; 6 | const [value, setValue] = useState(() => { 7 | const storedValue = storage.getItem(key); 8 | if (!!storedValue) { 9 | try { 10 | let result = JSON.parse(storedValue); 11 | return { 12 | taskId: result.taskId, 13 | startDate: new Date(result.startDate), 14 | endDate: new Date(result.endDate), 15 | reviewedPlacesVisible: result.reviewedPlacesVisible, 16 | closedPlaces: false, 17 | potentiallyClosedPlaces: true, 18 | dateType: result.dateType 19 | } 20 | } catch (e) { 21 | return defaultValue 22 | } 23 | } else { 24 | return defaultValue 25 | } 26 | }); 27 | 28 | useEffect(() => { 29 | storage.setItem(key, JSON.stringify(value)); 30 | }, [key, value]); 31 | 32 | return [value, setValue]; 33 | } 34 | -------------------------------------------------------------------------------- /src/components/map/tasks/ReviewDuplicatePlacesTask.js: -------------------------------------------------------------------------------- 1 | import Task from './Task'; 2 | import { fetchHistoryData } from "../../../api/geo"; 3 | 4 | class ReviewDuplicatePlacesTask extends Task { 5 | constructor() { 6 | super('REVIEW_CLOSED_PLACES', 'Review closed places', false, 0); 7 | } 8 | 9 | fetchData({ startDate, endDate }) { 10 | return fetchHistoryData({ requestFilter: this.id, startDate, endDate }); 11 | } 12 | } 13 | 14 | export default ReviewDuplicatePlacesTask; -------------------------------------------------------------------------------- /src/components/map/tasks/ReviewImagesTask.js: -------------------------------------------------------------------------------- 1 | import Task from './Task'; 2 | import { fetchHistoryData } from "../../../api/geo"; 3 | 4 | class ReviewImagesTask extends Task { 5 | constructor() { 6 | super('REVIEW_IMAGES', 'Review new images', false, 0); 7 | } 8 | 9 | fetchData({ startDate, endDate }) { 10 | return fetchHistoryData({ requestFilter: this.id, startDate, endDate }); 11 | } 12 | } 13 | 14 | export default ReviewImagesTask; 15 | -------------------------------------------------------------------------------- /src/components/map/tasks/ReviewTripAdvisorTask.js: -------------------------------------------------------------------------------- 1 | import Task from './Task'; 2 | 3 | class ReviewTripAdvisorTask extends Task { 4 | constructor() { 5 | super('REVIEW_TRIPADVISOR', 'Review missing TripAdvisor', false, 0); 6 | } 7 | } 8 | 9 | export default ReviewTripAdvisorTask; -------------------------------------------------------------------------------- /src/components/map/tasks/Task.js: -------------------------------------------------------------------------------- 1 | 2 | class Task { 3 | constructor(id, name, tileBasedData, minZoom) { 4 | this.id = id; 5 | this.name = name; 6 | this.tileBasedData = tileBasedData; 7 | this.minZoom = minZoom; 8 | } 9 | } 10 | 11 | export default Task; -------------------------------------------------------------------------------- /src/components/map/tasks/Tasks.js: -------------------------------------------------------------------------------- 1 | import ReviewDuplicatePlacesTask from './ReviewDuplicatePlacesTask'; 2 | import ReviewImagesTask from './ReviewImagesTask'; 3 | import ReviewTripAdvisorTask from "./ReviewTripAdvisorTask"; 4 | 5 | const tasks = [new ReviewDuplicatePlacesTask(), new ReviewImagesTask(), new ReviewTripAdvisorTask()]; 6 | 7 | const getTasks = () => { 8 | return tasks; 9 | }; 10 | 11 | const getTaskById = (taskId) => { 12 | for (let i in tasks) { 13 | const task = tasks[i]; 14 | if (task.id === taskId) { 15 | return task; 16 | } 17 | } 18 | return null; 19 | }; 20 | 21 | export default { 22 | getTasks, 23 | getTaskById, 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/components/util/Utils.js: -------------------------------------------------------------------------------- 1 | import {useEffect, useRef} from "react"; 2 | 3 | const capitalize = (string) => { 4 | return string.charAt(0).toUpperCase() + string.slice(1); 5 | }; 6 | 7 | const formatDate = (date) => { 8 | var d = new Date(date), 9 | month = '' + (d.getMonth() + 1), 10 | day = '' + d.getDate(), 11 | year = d.getFullYear(); 12 | 13 | if (month.length < 2) 14 | month = '0' + month; 15 | if (day.length < 2) 16 | day = '0' + day; 17 | 18 | return [year, month, day].join('-'); 19 | }; 20 | 21 | /** 22 | * Gets distance in meters 23 | */ 24 | const getDistance = (lat1, lon1, lat2, lon2) => { 25 | const R = 6372.8; // for haversine use R = 6372.8 km instead of 6371 km 26 | const dLat = toRadians(lat2 - lat1); 27 | const dLon = toRadians(lon2 - lon1); 28 | const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + 29 | Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) * 30 | Math.sin(dLon / 2) * Math.sin(dLon / 2); 31 | //double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 32 | //return R * c * 1000; 33 | // simplyfy haversine: 34 | return (2 * R * 1000 * Math.asin(Math.sqrt(a))); 35 | } 36 | 37 | const toRadians = (angdeg) => { 38 | return angdeg / 180.0 * Math.PI; 39 | } 40 | 41 | function usePrevious(value) { 42 | const ref = useRef(); 43 | useEffect(() => { 44 | ref.current = value; 45 | }, [value]); 46 | return ref.current; 47 | } 48 | 49 | function contains(array, value) { 50 | let res = false; 51 | array.forEach(function (element) { 52 | if (element.toString() === value) { 53 | res = true; 54 | } 55 | }); 56 | return res; 57 | } 58 | 59 | export default { 60 | capitalize, 61 | formatDate, 62 | getDistance, 63 | usePrevious, 64 | contains 65 | } -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | auth: { 3 | typingTimeout: 1000, 4 | minPasswordLength: 10, 5 | }, 6 | blockchain: { 7 | blocksPageLimit: parseInt(process.env.BLOCK_LOAD_LIMIT) || 50, 8 | blocksSidebarLimit: parseInt(process.env.BLOCK_SIDEBAR_LIMIT) || 3, 9 | opsTransformSrc: process.env.OPS_TRANSFORM_SRC || '/api/ops.js', 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Open Place Reviews 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 36 | 37 | 38 |
    39 | 40 | 41 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import App from "./App.js"; 4 | import "./assets/scss/app.scss"; 5 | 6 | ReactDOM.render(, document.querySelector("#root")); 7 | -------------------------------------------------------------------------------- /src/libs/cookies.js: -------------------------------------------------------------------------------- 1 | import Cookie from "js-cookie"; 2 | 3 | const set = (name, data, expires = null) => { 4 | const options = { 5 | expires, 6 | sameSite: "strict", 7 | secure: true, 8 | }; 9 | 10 | Cookie.set(name, data, options); 11 | }; 12 | 13 | const setNonStrict = (name, data, expires = null) => { 14 | const options = { 15 | expires, 16 | sameSite: "Lax", 17 | secure: true, 18 | }; 19 | 20 | Cookie.set(name, data, options); 21 | }; 22 | 23 | const get = (name) => { 24 | try { 25 | return Cookie.getJSON(name); 26 | } catch (e) { 27 | return Cookie.get(name); 28 | } 29 | }; 30 | 31 | const has = (name) => { 32 | return Cookie.get(name) !== undefined; 33 | }; 34 | 35 | const remove = (name) => { 36 | Cookie.remove(name); 37 | }; 38 | 39 | const clear = () => { 40 | Object.keys(Cookie.get()).forEach((name) => { 41 | Cookie.remove(name); 42 | }); 43 | }; 44 | 45 | export default { 46 | set, 47 | setNonStrict, 48 | get, 49 | has, 50 | remove, 51 | clear, 52 | } 53 | -------------------------------------------------------------------------------- /src/libs/storage.js: -------------------------------------------------------------------------------- 1 | let storage = window.localStorage; 2 | try { 3 | const x = '__storage_test__'; 4 | storage.setItem(x, x); 5 | storage.removeItem(x); 6 | } 7 | catch(e) { 8 | console.warn("Your browser blocks access to localStorage"); 9 | storage = null; 10 | } 11 | 12 | export default storage; -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | export default { 2 | "a, a:active": { 3 | color: "#2D69E0", 4 | textDecoration: "none" }, 5 | "a:hover": { 6 | color: "#2D69E0", 7 | textDecoration: "underline", 8 | }, 9 | h1: { 10 | marginTop: "20px", 11 | marginBottom: "20px", 12 | lineHeight: "50px", 13 | fontSize: "40px", 14 | letterSpacing: "0.01em" 15 | } 16 | }; 17 | --------------------------------------------------------------------------------