diff --git a/.gitignore b/.gitignore
index 4d29575..f21726c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,7 @@
.env.development.local
.env.test.local
.env.production.local
+.env
npm-debug.log*
yarn-debug.log*
diff --git a/cypress.json b/cypress.json
index 399eea2..1ae86ea 100644
--- a/cypress.json
+++ b/cypress.json
@@ -1,3 +1,4 @@
{
- "baseUrl": "http://localhost:3001"
+ "baseUrl": "http://localhost:3001",
+ "chromeWebSecurity": false
}
diff --git a/cypress/integration/.keep b/cypress/integration/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/cypress/integration/usercanSeeWhatCountryTheyAreIn.feature.js b/cypress/integration/usercanSeeWhatCountryTheyAreIn.feature.js
new file mode 100644
index 0000000..fa0b832
--- /dev/null
+++ b/cypress/integration/usercanSeeWhatCountryTheyAreIn.feature.js
@@ -0,0 +1,11 @@
+const stubLocation = require('../support/stubLocation')
+
+describe('User can see current country', () => {
+ beforeEach(() => {
+ cy.visit("/", stubLocation({latitude: 28.9784, longitude: 41.0082 }))
+ })
+
+ it('that displays correctly', () => {
+ cy.get("[data-cy='current-location']").should("contain", "You are in Finland!")
+ });
+})
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index ca4d256..e69de29 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -1,25 +0,0 @@
-// ***********************************************
-// This example commands.js shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add("login", (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
diff --git a/cypress/support/stubLocation.js b/cypress/support/stubLocation.js
new file mode 100644
index 0000000..8d003e7
--- /dev/null
+++ b/cypress/support/stubLocation.js
@@ -0,0 +1,18 @@
+const stubLocation = (options) => ({
+ onBeforeLoad(win) {
+ const stubLocation = {
+ coords: {
+ latitidue: options.latitude,
+ longitude: options.longitude
+ },
+ };
+ debugger;
+ cy.stub(win.navigator.geolocation, "getCurrentPosition").callsFake(
+ (callback) => {
+ return callback(stubLocation);
+ }
+ );
+ },
+});
+
+export default stubLocation;
\ No newline at end of file
diff --git a/package.json b/package.json
index 1d86b88..5464e61 100644
--- a/package.json
+++ b/package.json
@@ -6,10 +6,13 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
+ "axios": "^0.20.0",
"cypress": "^4.8.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
+ "react-redux": "^7.2.1",
"react-scripts": "3.4.1",
+ "redux": "^4.0.5",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^0.88.2",
"start-server-and-test": "^1.11.0"
diff --git a/src/App.js b/src/App.js
deleted file mode 100644
index 7b753a6..0000000
--- a/src/App.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-import { Container, Header } from 'semantic-ui-react'
-
-const App = () => {
- return (
- <>
-
-
-
- >
- );
-}
-
-export default App;
\ No newline at end of file
diff --git a/src/App.jsx b/src/App.jsx
new file mode 100644
index 0000000..22eaa0b
--- /dev/null
+++ b/src/App.jsx
@@ -0,0 +1,25 @@
+import React, { useEffect } from 'react';
+import { Container, Header } from 'semantic-ui-react'
+import { useSelector, useDispatch } from 'react-redux'
+import { getCurrentPostion } from './modules/location'
+
+
+const App = () => {
+ let greeting = useSelector(state => state.greeting)
+ let country = useSelector(state => state.location.country)
+ const dispatch = useDispatch()
+
+ useEffect(() => {
+ getCurrentPostion(dispatch)
+ debugger
+ }, [])
+
+ return (
+
+ You are in {country}!
+
+
+ );
+}
+
+export default App;
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 232db01..16fbcef 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,6 +3,14 @@ import ReactDOM from 'react-dom';
import 'semantic-ui-css/semantic.min.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
+import { Provider } from 'react-redux'
+import configureStore from './state/store/configureStore'
-ReactDOM.render(, document.getElementById('root'));
+const store = configureStore()
+window.store = store
+ReactDOM.render(
+
+
+
+ , document.getElementById('root'));
serviceWorker.unregister();
\ No newline at end of file
diff --git a/src/modules/location.js b/src/modules/location.js
new file mode 100644
index 0000000..a4a9e49
--- /dev/null
+++ b/src/modules/location.js
@@ -0,0 +1,28 @@
+import axios from 'axios'
+
+const getCurrentPostion = async (dispatch) => {
+ navigator.geolocation.getCurrentPosition(async (pos) => {
+ debugger;
+ const country = await getCountry(pos.coords.longitude, pos.coords.latitude)
+ dispatch({
+ type: "SET_LOCATION",
+ payload: {
+ country: country,
+ longitude: pos.coords.longitude,
+ latitidue: pos.coords.latitude
+ }
+ })
+ })
+}
+
+const getCountry = async (long, lat) => {
+ const apiKey = process.env.REACT_APP_OPEN_CAGE_API_KEY
+debugger;
+ const results = await axios.get(
+ `https://api.opencagedata.com/geocode/v1/json?q=${lat}%2C${long}&language=en&key=${apiKey}`
+ )
+
+ return results.data.results[0].components.country
+}
+
+export { getCurrentPostion }
\ No newline at end of file
diff --git a/src/state/reducers/rootReducer.js b/src/state/reducers/rootReducer.js
new file mode 100644
index 0000000..cc70398
--- /dev/null
+++ b/src/state/reducers/rootReducer.js
@@ -0,0 +1,16 @@
+import initialState from '../store/initialState'
+
+const rootReducer = (state = initialState, action) => {
+ switch (action.type) {
+ case "SET_LOCATION":
+ return {
+ ...state,
+ location: action.payload
+ }
+
+ default:
+ return state
+ }
+}
+
+export default rootReducer
\ No newline at end of file
diff --git a/src/state/store/configureStore.js b/src/state/store/configureStore.js
new file mode 100644
index 0000000..fe19931
--- /dev/null
+++ b/src/state/store/configureStore.js
@@ -0,0 +1,8 @@
+import { createStore } from 'redux'
+import rootReducer from '../reducers/rootReducer'
+
+const configureStore = () => {
+ return createStore(rootReducer)
+}
+
+export default configureStore
\ No newline at end of file
diff --git a/src/state/store/initialState.js b/src/state/store/initialState.js
new file mode 100644
index 0000000..f89bfdb
--- /dev/null
+++ b/src/state/store/initialState.js
@@ -0,0 +1,8 @@
+const initialState = {
+ greeting: 'Hello it is time to use geolocation!',
+ location: {
+ country: ""
+ }
+}
+
+export default initialState
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 78708b8..a296dc1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1012,6 +1012,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.5.5":
+ version "7.11.2"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
+ integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
"@babel/template@^7.10.3":
version "7.10.3"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.3.tgz#4d13bc8e30bf95b0ce9d175d30306f42a2c9a7b8"
@@ -2349,6 +2356,13 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
+axios@^0.20.0:
+ version "0.20.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd"
+ integrity sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==
+ dependencies:
+ follow-redirects "^1.10.0"
+
axobject-query@^2.0.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799"
@@ -5045,6 +5059,11 @@ follow-redirects@^1.0.0:
dependencies:
debug "^3.0.0"
+follow-redirects@^1.10.0:
+ version "1.13.0"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
+ integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==
+
for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
@@ -5491,6 +5510,13 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
+hoist-non-react-statics@^3.3.0:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
+ integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
+ dependencies:
+ react-is "^16.7.0"
+
hosted-git-info@^2.1.4:
version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
@@ -9406,7 +9432,7 @@ react-error-overlay@^6.0.7:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108"
integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==
-react-is@^16.12.0, react-is@^16.6.3, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0:
+react-is@^16.12.0, react-is@^16.6.3, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -9424,6 +9450,17 @@ react-popper@^1.3.4:
typed-styles "^0.0.7"
warning "^4.0.2"
+react-redux@^7.2.1:
+ version "7.2.1"
+ resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.1.tgz#8dedf784901014db2feca1ab633864dee68ad985"
+ integrity sha512-T+VfD/bvgGTUA74iW9d2i5THrDQWbweXP0AVNI8tNd1Rk5ch1rnMiJkDD67ejw7YBKM4+REvcvqRuWJb7BLuEg==
+ dependencies:
+ "@babel/runtime" "^7.5.5"
+ hoist-non-react-statics "^3.3.0"
+ loose-envify "^1.4.0"
+ prop-types "^15.7.2"
+ react-is "^16.9.0"
+
react-scripts@3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.1.tgz#f551298b5c71985cc491b9acf3c8e8c0ae3ada0a"
@@ -9597,6 +9634,14 @@ redent@^3.0.0:
indent-string "^4.0.0"
strip-indent "^3.0.0"
+redux@^4.0.5:
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"
+ integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==
+ dependencies:
+ loose-envify "^1.4.0"
+ symbol-observable "^1.2.0"
+
reflect.ownkeys@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460"
@@ -10836,7 +10881,7 @@ svgo@^1.0.0, svgo@^1.2.2:
unquote "~1.1.1"
util.promisify "~1.0.0"
-symbol-observable@^1.1.0:
+symbol-observable@^1.1.0, symbol-observable@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==