mirror of
https://github.com/idanoo/GoScrobble.git
synced 2024-11-22 08:25:14 +00:00
Remove redux
This commit is contained in:
parent
0c56281bcd
commit
ebd88b3bb0
@ -3,7 +3,7 @@ stages:
|
|||||||
- bundle
|
- bundle
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
VERSION: 0.0.6
|
VERSION: 0.0.7
|
||||||
|
|
||||||
build-go:
|
build-go:
|
||||||
image: golang:1.16.2
|
image: golang:1.16.2
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# 0.0.7
|
||||||
|
-Switch redux -> context.
|
||||||
|
|
||||||
# 0.0.6
|
# 0.0.6
|
||||||
- Fix hitting dashboard when logged out
|
- Fix hitting dashboard when logged out
|
||||||
- Clean up app.js
|
- Clean up app.js
|
||||||
|
108
web/package-lock.json
generated
108
web/package-lock.json
generated
@ -19,21 +19,13 @@
|
|||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-bootstrap": "^1.5.2",
|
"react-bootstrap": "^1.5.2",
|
||||||
"react-cookie": "^4.0.3",
|
"react-cookie": "^4.0.3",
|
||||||
"react-data-grid": "*",
|
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-redux": "^7.2.3",
|
"react-redux": "^7.2.3",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "4.0.3",
|
"react-scripts": "4.0.3",
|
||||||
"react-spinners": "^0.10.6",
|
"react-spinners": "^0.10.6",
|
||||||
"react-table": "^7.6.3",
|
|
||||||
"react-toast": "^1.0.1",
|
|
||||||
"react-toast-notifications": "^2.4.3",
|
|
||||||
"react-toastify": "^7.0.3",
|
"react-toastify": "^7.0.3",
|
||||||
"reactstrap": "^8.9.0",
|
"reactstrap": "^8.9.0"
|
||||||
"redux": "^4.0.5",
|
|
||||||
"redux-persist": "^6.0.0",
|
|
||||||
"redux-thunk": "^2.3.0",
|
|
||||||
"web-vitals": "^1.1.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"redux-devtools-extension": "^2.13.9",
|
"redux-devtools-extension": "^2.13.9",
|
||||||
@ -16328,18 +16320,6 @@
|
|||||||
"react": ">= 16.3.0"
|
"react": ">= 16.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-data-grid": {
|
|
||||||
"version": "7.0.0-canary.38",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-data-grid/-/react-data-grid-7.0.0-canary.38.tgz",
|
|
||||||
"integrity": "sha512-JjMyChuh9KxOtYmpxrOuPBI6EYIbNLn/+pjwoQYeD7d5vkWMURWWhyLX1NJkT5bt5LF2qxOSQiFf3G6YndxlAg==",
|
|
||||||
"dependencies": {
|
|
||||||
"clsx": "^1.1.1"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^16.14 || ^17.0",
|
|
||||||
"react-dom": "^16.14 || ^17.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-dev-utils": {
|
"node_modules/react-dev-utils": {
|
||||||
"version": "11.0.4",
|
"version": "11.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
|
||||||
@ -16733,39 +16713,6 @@
|
|||||||
"react-dom": "^16.0.0 || ^17.0.0"
|
"react-dom": "^16.0.0 || ^17.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-table": {
|
|
||||||
"version": "7.6.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-table/-/react-table-7.6.3.tgz",
|
|
||||||
"integrity": "sha512-hfPF13zDLxPMpLKzIKCE8RZud9T/XrRTsaCIf8zXpWZIZ2juCl7qrGpo3AQw9eAetXV5DP7s2GDm+hht7qq5Dw==",
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/tannerlinsley"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^16.8.3 || ^17.0.0-0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-toast": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-toast/-/react-toast-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-xqkO5ZJiJDOLxycZts7xi729blKw4frhg2I4bcIjT7mVlshxu0AsaHlKAdPhVeACAnn8nnamxg6zoYoC9BEjjg==",
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=16"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-toast-notifications": {
|
|
||||||
"version": "2.4.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-toast-notifications/-/react-toast-notifications-2.4.3.tgz",
|
|
||||||
"integrity": "sha512-Ya/i2dCjN95Ytb/pwbAVmDMSKQwGeeGOhUThtjFQx2XAFKE+fQnodLlIylhgZfsInxdUXPFGFnzTdGS8JafuLA==",
|
|
||||||
"dependencies": {
|
|
||||||
"@emotion/core": "^10.0.14",
|
|
||||||
"react-transition-group": "^4.4.1"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^16.8.0 || ^17.0.0",
|
|
||||||
"react-dom": "^16.8.0 || ^17.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-toastify": {
|
"node_modules/react-toastify": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-7.0.3.tgz",
|
||||||
@ -17011,14 +16958,6 @@
|
|||||||
"redux": "^3.1.0 || ^4.0.0"
|
"redux": "^3.1.0 || ^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/redux-persist": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==",
|
|
||||||
"peerDependencies": {
|
|
||||||
"redux": ">4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/redux-thunk": {
|
"node_modules/redux-thunk": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
|
||||||
@ -20691,11 +20630,6 @@
|
|||||||
"minimalistic-assert": "^1.0.0"
|
"minimalistic-assert": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/web-vitals": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-jYOaqu01Ny1NvMwJ3dBJDUOJ2PGWknZWH4AUnvFOscvbdHMERIKT2TlgiAey5rVyfOePG7so2JcXXZdSnBvioQ=="
|
|
||||||
},
|
|
||||||
"node_modules/webidl-conversions": {
|
"node_modules/webidl-conversions": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
|
||||||
@ -35007,14 +34941,6 @@
|
|||||||
"universal-cookie": "^4.0.0"
|
"universal-cookie": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-data-grid": {
|
|
||||||
"version": "7.0.0-canary.38",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-data-grid/-/react-data-grid-7.0.0-canary.38.tgz",
|
|
||||||
"integrity": "sha512-JjMyChuh9KxOtYmpxrOuPBI6EYIbNLn/+pjwoQYeD7d5vkWMURWWhyLX1NJkT5bt5LF2qxOSQiFf3G6YndxlAg==",
|
|
||||||
"requires": {
|
|
||||||
"clsx": "^1.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"react-dev-utils": {
|
"react-dev-utils": {
|
||||||
"version": "11.0.4",
|
"version": "11.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
|
||||||
@ -35331,27 +35257,6 @@
|
|||||||
"@emotion/core": "^10.0.35"
|
"@emotion/core": "^10.0.35"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-table": {
|
|
||||||
"version": "7.6.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-table/-/react-table-7.6.3.tgz",
|
|
||||||
"integrity": "sha512-hfPF13zDLxPMpLKzIKCE8RZud9T/XrRTsaCIf8zXpWZIZ2juCl7qrGpo3AQw9eAetXV5DP7s2GDm+hht7qq5Dw==",
|
|
||||||
"requires": {}
|
|
||||||
},
|
|
||||||
"react-toast": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-toast/-/react-toast-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-xqkO5ZJiJDOLxycZts7xi729blKw4frhg2I4bcIjT7mVlshxu0AsaHlKAdPhVeACAnn8nnamxg6zoYoC9BEjjg==",
|
|
||||||
"requires": {}
|
|
||||||
},
|
|
||||||
"react-toast-notifications": {
|
|
||||||
"version": "2.4.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-toast-notifications/-/react-toast-notifications-2.4.3.tgz",
|
|
||||||
"integrity": "sha512-Ya/i2dCjN95Ytb/pwbAVmDMSKQwGeeGOhUThtjFQx2XAFKE+fQnodLlIylhgZfsInxdUXPFGFnzTdGS8JafuLA==",
|
|
||||||
"requires": {
|
|
||||||
"@emotion/core": "^10.0.14",
|
|
||||||
"react-transition-group": "^4.4.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"react-toastify": {
|
"react-toastify": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-7.0.3.tgz",
|
||||||
@ -35543,12 +35448,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"redux-persist": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==",
|
|
||||||
"requires": {}
|
|
||||||
},
|
|
||||||
"redux-thunk": {
|
"redux-thunk": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
|
||||||
@ -38488,11 +38387,6 @@
|
|||||||
"minimalistic-assert": "^1.0.0"
|
"minimalistic-assert": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web-vitals": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-jYOaqu01Ny1NvMwJ3dBJDUOJ2PGWknZWH4AUnvFOscvbdHMERIKT2TlgiAey5rVyfOePG7so2JcXXZdSnBvioQ=="
|
|
||||||
},
|
|
||||||
"webidl-conversions": {
|
"webidl-conversions": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
|
||||||
|
@ -14,21 +14,13 @@
|
|||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-bootstrap": "^1.5.2",
|
"react-bootstrap": "^1.5.2",
|
||||||
"react-cookie": "^4.0.3",
|
"react-cookie": "^4.0.3",
|
||||||
"react-data-grid": "*",
|
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-redux": "^7.2.3",
|
"react-redux": "^7.2.3",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "4.0.3",
|
"react-scripts": "4.0.3",
|
||||||
"react-spinners": "^0.10.6",
|
"react-spinners": "^0.10.6",
|
||||||
"react-table": "^7.6.3",
|
|
||||||
"react-toast": "^1.0.1",
|
|
||||||
"react-toast-notifications": "^2.4.3",
|
|
||||||
"react-toastify": "^7.0.3",
|
"react-toastify": "^7.0.3",
|
||||||
"reactstrap": "^8.9.0",
|
"reactstrap": "^8.9.0"
|
||||||
"redux": "^4.0.5",
|
|
||||||
"redux-persist": "^6.0.0",
|
|
||||||
"redux-thunk": "^2.3.0",
|
|
||||||
"web-vitals": "^1.1.1"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
import ApiService from "../Services/api.service";
|
|
||||||
|
|
||||||
export const getStats = () => {
|
|
||||||
return ApiService.getStats().then(
|
|
||||||
(data) => {
|
|
||||||
return data.data;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getRecentScrobbles = (id) => {
|
|
||||||
return ApiService.getRecentScrobbles(id).then(
|
|
||||||
(data) => {
|
|
||||||
return data.data;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
|||||||
import {
|
|
||||||
REGISTER_SUCCESS,
|
|
||||||
REGISTER_FAIL,
|
|
||||||
LOGIN_SUCCESS,
|
|
||||||
LOGIN_FAIL,
|
|
||||||
LOGOUT,
|
|
||||||
} from "./types";
|
|
||||||
|
|
||||||
import { toast } from 'react-toastify';
|
|
||||||
import jwt from 'jwt-decode'
|
|
||||||
import AuthService from "../Services/auth.service";
|
|
||||||
import eventBus from "./eventBus";
|
|
||||||
|
|
||||||
export const register = (username, email, password) => (dispatch) => {
|
|
||||||
return AuthService.register(username, email, password).then(
|
|
||||||
(data) => {
|
|
||||||
if (data.message) {
|
|
||||||
toast.success('Successfully registered. Please sign in');
|
|
||||||
dispatch({
|
|
||||||
type: REGISTER_SUCCESS,
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
toast.error(data.error ? data.error: 'An Unknown Error has occurred')
|
|
||||||
dispatch({
|
|
||||||
type: REGISTER_FAIL,
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise.reject();
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
const message =
|
|
||||||
(error.response &&
|
|
||||||
error.response.data &&
|
|
||||||
error.response.data.message) ||
|
|
||||||
error.message ||
|
|
||||||
error.toString();
|
|
||||||
|
|
||||||
toast.error(message);
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: REGISTER_FAIL,
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const login = (username, password) => (dispatch) => {
|
|
||||||
return AuthService.login(username, password).then(
|
|
||||||
(data) => {
|
|
||||||
if (data.token) {
|
|
||||||
toast.success('Login Success');
|
|
||||||
let user = jwt(data.token)
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: LOGIN_SUCCESS,
|
|
||||||
payload: { jwt: data.token, sub: user.sub, exp: user.exp },
|
|
||||||
});
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
toast.error(data.error ? data.error: 'An Unknown Error has occurred')
|
|
||||||
dispatch({
|
|
||||||
type: LOGIN_FAIL,
|
|
||||||
});
|
|
||||||
return Promise.reject();
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
const message =
|
|
||||||
(error.response &&
|
|
||||||
error.response.data &&
|
|
||||||
error.response.data.error) ||
|
|
||||||
error.message ||
|
|
||||||
error.toString();
|
|
||||||
|
|
||||||
toast.error('Error: ' + message)
|
|
||||||
dispatch({
|
|
||||||
type: LOGIN_FAIL,
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const logout = (dispatch) => {
|
|
||||||
// Clear local data
|
|
||||||
AuthService.logout()
|
|
||||||
|
|
||||||
// window.location.pathname("/")
|
|
||||||
window.location.reload()
|
|
||||||
|
|
||||||
// TODO; Clear Redux - ENABLE THIS WHEN I FIGURE OUT HOW 2 DISPATCH
|
|
||||||
// dispatch({
|
|
||||||
// type: LOGOUT,
|
|
||||||
// payload: {},
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // Issue to all listeners to reload
|
|
||||||
eventBus.dispatch(LOGOUT);
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
const eventBus = {
|
|
||||||
on(event, callback) {
|
|
||||||
document.addEventListener(event, (e) => callback(e.detail));
|
|
||||||
},
|
|
||||||
dispatch(event, data) {
|
|
||||||
document.dispatchEvent(new CustomEvent(event, { detail: data }));
|
|
||||||
},
|
|
||||||
remove(event, callback) {
|
|
||||||
document.removeEventListener(event, callback);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default eventBus
|
|
@ -1,5 +0,0 @@
|
|||||||
export const REGISTER_SUCCESS = "REGISTER_SUCCESS";
|
|
||||||
export const REGISTER_FAIL = "REGISTER_FAIL";
|
|
||||||
export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
|
|
||||||
export const LOGIN_FAIL = "LOGIN_FAIL";
|
|
||||||
export const LOGOUT = "LOGOUT";
|
|
86
web/src/Api/index.js
Normal file
86
web/src/Api/index.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import jwt from 'jwt-decode'
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
function getHeaders() {
|
||||||
|
// Todo: move this to use Context values instead.
|
||||||
|
const user = JSON.parse(localStorage.getItem('user'));
|
||||||
|
|
||||||
|
if (user && user.jwt) {
|
||||||
|
return { Authorization: 'Bearer ' + user.jwt };
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PostLogin = (formValues) => {
|
||||||
|
// const { setLoading, setUser } = useContext(AuthContext);
|
||||||
|
// setLoading(true)
|
||||||
|
return axios.post(process.env.REACT_APP_API_URL + "login", formValues)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.data.token) {
|
||||||
|
let expandedUser = jwt(response.data.token)
|
||||||
|
let user = {
|
||||||
|
jwt: response.data.token,
|
||||||
|
uuid: expandedUser.sub,
|
||||||
|
exp: expandedUser.exp,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set in local storage
|
||||||
|
localStorage.setItem('user', JSON.stringify(user));
|
||||||
|
|
||||||
|
// Set in context
|
||||||
|
// setUser(user)
|
||||||
|
|
||||||
|
toast.success('Successfully logged in.');
|
||||||
|
// setLoading(false)
|
||||||
|
return user;
|
||||||
|
} else {
|
||||||
|
toast.error(response.data.error ? response.data.error: 'An Unknown Error has occurred');
|
||||||
|
// setLoading(false)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PostRegister = (formValues) => {
|
||||||
|
axios.post(process.env.REACT_APP_API_URL + "register", formValues)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.data.token) {
|
||||||
|
toast.success('Successfully registered. Please sign in');
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
} else {
|
||||||
|
toast.error(response.data.error ? response.data.error: 'An Unknown Error has occurred');
|
||||||
|
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.error((error) => {
|
||||||
|
const message =
|
||||||
|
(error.response &&
|
||||||
|
error.response.data &&
|
||||||
|
error.response.data.message) ||
|
||||||
|
error.message ||
|
||||||
|
error.toString();
|
||||||
|
|
||||||
|
toast.error(message ? message : 'An Unknown Error has occurred')
|
||||||
|
return Promise.reject();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getStats = () => {
|
||||||
|
return axios.get(process.env.REACT_APP_API_URL + "stats").then(
|
||||||
|
(data) => {
|
||||||
|
data.isLoading = false;
|
||||||
|
return data.data;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getRecentScrobbles = (id) => {
|
||||||
|
return axios.get(process.env.REACT_APP_API_URL + "user/" + id + "/scrobbles", { headers: getHeaders() })
|
||||||
|
.then((data) => {
|
||||||
|
return data.data;
|
||||||
|
});
|
||||||
|
};
|
@ -3,47 +3,36 @@ import Home from './Pages/Home';
|
|||||||
import About from './Pages/About';
|
import About from './Pages/About';
|
||||||
|
|
||||||
import Dashboard from './Pages/Dashboard';
|
import Dashboard from './Pages/Dashboard';
|
||||||
import Admin from './Pages/Admin';
|
|
||||||
import Profile from './Pages/Profile';
|
import Profile from './Pages/Profile';
|
||||||
import Login from './Pages/Login';
|
import Login from './Pages/Login';
|
||||||
import Settings from './Pages/Settings';
|
import Settings from './Pages/Settings';
|
||||||
import Register from './Pages/Register';
|
import Register from './Pages/Register';
|
||||||
import Navigation from './Components/Navigation';
|
import Navigation from './Components/Navigation';
|
||||||
|
|
||||||
// import { logout } from './Actions/auth';
|
|
||||||
import { Route, Switch, withRouter } from 'react-router-dom';
|
import { Route, Switch, withRouter } from 'react-router-dom';
|
||||||
import { Component } from 'react';
|
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
class App extends Component {
|
const App = () => {
|
||||||
constructor(props) {
|
let boolTrue = true
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
true: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Navigation />
|
<Navigation />
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact={this.state.true} path={["/", "/home"]} component={Home} />
|
<Route exact={boolTrue} path={["/", "/home"]} component={Home} />
|
||||||
<Route path="/about" component={About} />
|
<Route path="/about" component={About} />
|
||||||
|
|
||||||
<Route path="/dashboard" component={Dashboard} />
|
<Route path="/dashboard" component={Dashboard} />
|
||||||
<Route path="/profile" component={Profile} />
|
<Route path="/profile" component={Profile} />
|
||||||
<Route path="/settings" component={Settings} />
|
<Route path="/settings" component={Settings} />
|
||||||
|
|
||||||
<Route path="/admin" component={Admin} />
|
|
||||||
|
|
||||||
<Route path="/login" component={Login} />
|
<Route path="/login" component={Login} />
|
||||||
<Route path="/register" component={Register} />
|
<Route path="/register" component={Register} />
|
||||||
|
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default withRouter(App);
|
export default withRouter(App);
|
@ -1,65 +1,45 @@
|
|||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import '../App.css';
|
import '../App.css';
|
||||||
import './HomeBanner.css';
|
import './HomeBanner.css';
|
||||||
import { getStats } from '../Actions/api';
|
import { getStats } from '../Api/index';
|
||||||
import ClipLoader from 'react-spinners/ClipLoader'
|
import ClipLoader from 'react-spinners/ClipLoader'
|
||||||
|
|
||||||
class HomeBanner extends React.Component {
|
const HomeBanner = () => {
|
||||||
constructor(props) {
|
let [bannerData, setBannerData] = useState({});
|
||||||
super(props);
|
let [isLoading, setIsLoading] = useState(true);
|
||||||
this.state = {
|
|
||||||
isLoading: true,
|
|
||||||
userCount: 0,
|
|
||||||
scrobbleCount: 0,
|
|
||||||
trackCount: 0,
|
|
||||||
artistCount: 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
useEffect(() => {
|
||||||
getStats()
|
getStats()
|
||||||
.then((data) => {
|
.then(data => {
|
||||||
this.setState({
|
setBannerData(data);
|
||||||
isLoading: false,
|
setIsLoading(false);
|
||||||
userCount: data.users,
|
|
||||||
scrobbleCount: data.scrobbles,
|
|
||||||
trackCount: data.tracks,
|
|
||||||
artistCount: data.artists,
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
}, [])
|
||||||
this.setState({
|
|
||||||
isLoading: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
return (
|
||||||
<div className="homeBanner">
|
<div className="homeBanner">
|
||||||
<div className="homeBannerItem">
|
<div className="homeBannerItem">
|
||||||
{this.state.isLoading
|
{isLoading
|
||||||
? <ClipLoader color="#6AD7E5" size={36} />
|
? <ClipLoader color="#6AD7E5" size={34} />
|
||||||
: <span className="homeBannerItemCount">{this.state.scrobbleCount}</span>}<br/>Scrobbles
|
: <span className="homeBannerItemCount">{bannerData.scrobbles}</span>}<br/>Scrobbles
|
||||||
</div>
|
</div>
|
||||||
<div className="homeBannerItem">
|
<div className="homeBannerItem">
|
||||||
{this.state.isLoading
|
{isLoading
|
||||||
? <ClipLoader color="#6AD7E5" size={36} />
|
? <ClipLoader color="#6AD7E5" size={34} />
|
||||||
: <span className="homeBannerItemCount">{this.state.userCount}</span>}<br/>Users
|
: <span className="homeBannerItemCount">{bannerData.users}</span>}<br/>Users
|
||||||
</div>
|
</div>
|
||||||
<div className="homeBannerItem">
|
<div className="homeBannerItem">
|
||||||
{this.state.isLoading
|
{isLoading
|
||||||
? <ClipLoader color="#6AD7E5" size={36} />
|
? <ClipLoader color="#6AD7E5" size={34} />
|
||||||
: <span className="homeBannerItemCount">{this.state.trackCount}</span>}<br/>Tracks
|
: <span className="homeBannerItemCount">{bannerData.tracks}</span>}<br/>Tracks
|
||||||
</div>
|
</div>
|
||||||
<div className="homeBannerItem">
|
<div className="homeBannerItem">
|
||||||
{this.state.isLoading
|
{isLoading
|
||||||
? <ClipLoader color="#6AD7E5" size={36} />
|
? <ClipLoader color="#6AD7E5" size={34} />
|
||||||
: <span className="homeBannerItemCount">{this.state.artistCount}</span>}<br/>Artists
|
: <span className="homeBannerItemCount">{bannerData.artists}</span>}<br/>Artists
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default HomeBanner;
|
export default HomeBanner;
|
||||||
|
@ -3,14 +3,8 @@ import { Navbar, NavbarBrand, Collapse, Nav, NavbarToggler, NavItem } from 'reac
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import logo from '../logo.png';
|
import logo from '../logo.png';
|
||||||
import './Navigation.css';
|
import './Navigation.css';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { logout } from '../Actions/auth';
|
|
||||||
import eventBus from "../Actions/eventBus";
|
|
||||||
|
|
||||||
import {
|
import logout from '../Contexts/AuthContextProvider';
|
||||||
LOGIN_SUCCESS,
|
|
||||||
LOGOUT,
|
|
||||||
} from "../Actions/types";
|
|
||||||
|
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
'Home',
|
'Home',
|
||||||
@ -45,17 +39,6 @@ class Navigation extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
eventBus.on(LOGIN_SUCCESS, () =>
|
|
||||||
this.setState({ isLoggedIn: true })
|
|
||||||
);
|
|
||||||
|
|
||||||
eventBus.on(LOGOUT, () =>
|
|
||||||
this.setState({ isLoggedIn: false })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
eventBus.remove(LOGIN_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleClick(menuItem) {
|
_handleClick(menuItem) {
|
||||||
@ -211,12 +194,4 @@ class Navigation extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
export default Navigation;
|
||||||
const { isLoggedIn } = state.auth;
|
|
||||||
|
|
||||||
return {
|
|
||||||
isLoggedIn
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(Navigation);
|
|
5
web/src/Contexts/AuthContext.js
Normal file
5
web/src/Contexts/AuthContext.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const AuthContext = React.createContext();
|
||||||
|
|
||||||
|
export default AuthContext;
|
65
web/src/Contexts/AuthContextProvider.js
Normal file
65
web/src/Contexts/AuthContextProvider.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import AuthContext from './AuthContext';
|
||||||
|
|
||||||
|
import { PostLogin, PostRegister } from '../Api/index';
|
||||||
|
|
||||||
|
const AuthContextProvider = ({ children }) => {
|
||||||
|
const [user, setUser] = useState();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLoading(true)
|
||||||
|
const user = JSON.parse(localStorage.getItem('user'));
|
||||||
|
if (user && user.jwt) {
|
||||||
|
setUser(user)
|
||||||
|
}
|
||||||
|
setLoading(false)
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const Login = (formValues) => {
|
||||||
|
setLoading(true);
|
||||||
|
PostLogin(formValues).then(user => {
|
||||||
|
if (user) {
|
||||||
|
setUser(user);
|
||||||
|
const { history } = this.props;
|
||||||
|
history.push("/dashboard");
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const Register = (formValues) => {
|
||||||
|
const { history } = this.props;
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
return PostRegister(formValues).then(response => {
|
||||||
|
if (response) {
|
||||||
|
history.push("/login");
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const Logout = () => {
|
||||||
|
localStorage.removeItem("user");
|
||||||
|
setUser(null)
|
||||||
|
toast.success('Successfully logged out.');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AuthContext.Provider
|
||||||
|
value={{
|
||||||
|
Logout,
|
||||||
|
Login,
|
||||||
|
Register,
|
||||||
|
loading,
|
||||||
|
user,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</AuthContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AuthContextProvider;
|
@ -1,7 +1,7 @@
|
|||||||
import '../App.css';
|
import '../App.css';
|
||||||
import './About.css';
|
import './About.css';
|
||||||
|
|
||||||
function About() {
|
const About = () => {
|
||||||
return (
|
return (
|
||||||
<div className="pageWrapper">
|
<div className="pageWrapper">
|
||||||
<h1>
|
<h1>
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
import React, { Component } from "react";
|
|
||||||
|
|
||||||
import UserService from "../Services/user.service";
|
|
||||||
|
|
||||||
class Admin extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
content: ""
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
UserService.getAdminBoard().then(
|
|
||||||
response => {
|
|
||||||
this.setState({
|
|
||||||
content: response.data
|
|
||||||
});
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
this.setState({
|
|
||||||
content:
|
|
||||||
(error.response &&
|
|
||||||
error.response.data &&
|
|
||||||
error.response.data.message) ||
|
|
||||||
error.message ||
|
|
||||||
error.toString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
<header className="jumbotron">
|
|
||||||
<h3>{this.state.content}</h3>
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Admin;
|
|
@ -1,8 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../App.css';
|
import '../App.css';
|
||||||
import './Dashboard.css';
|
import './Dashboard.css';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { getRecentScrobbles } from '../Actions/api';
|
import { getRecentScrobbles } from '../Api/index';
|
||||||
import ScaleLoader from 'react-spinners/ScaleLoader';
|
import ScaleLoader from 'react-spinners/ScaleLoader';
|
||||||
import ScrobbleTable from "../Components/ScrobbleTable";
|
import ScrobbleTable from "../Components/ScrobbleTable";
|
||||||
|
|
||||||
@ -53,17 +53,4 @@ class Dashboard extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
export default Dashboard;
|
||||||
const { isLoggedIn } = state.auth;
|
|
||||||
let uuid = null;
|
|
||||||
if (isLoggedIn) {
|
|
||||||
uuid = state.auth.user.uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
isLoggedIn,
|
|
||||||
uuid,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(Dashboard);
|
|
||||||
|
@ -1,52 +1,15 @@
|
|||||||
import React from 'react';
|
import React, { useContext } from 'react';
|
||||||
import '../App.css';
|
import '../App.css';
|
||||||
import './Login.css';
|
import './Login.css';
|
||||||
import { Button } from 'reactstrap';
|
import { Button } from 'reactstrap';
|
||||||
import { Formik, Form, Field } from 'formik';
|
import { Formik, Form, Field } from 'formik';
|
||||||
import ScaleLoader from 'react-spinners/ScaleLoader';
|
import ScaleLoader from 'react-spinners/ScaleLoader';
|
||||||
import { connect } from 'react-redux';
|
import AuthContext from '../Contexts/AuthContext';
|
||||||
import { login } from '../Actions/auth';
|
|
||||||
import eventBus from "../Actions/eventBus";
|
|
||||||
import { LOGIN_SUCCESS } from '../Actions/types';
|
|
||||||
|
|
||||||
class Login extends React.Component {
|
const Login = () => {
|
||||||
constructor(props) {
|
let boolTrue = true;
|
||||||
super(props);
|
let { Login, loading } = useContext(AuthContext);
|
||||||
this.state = {username: '', password: '', loading: false};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const { history, isLoggedIn } = this.props;
|
|
||||||
|
|
||||||
if (isLoggedIn) {
|
|
||||||
history.push("/dashboard")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleLogin(values) {
|
|
||||||
this.setState({loading: true});
|
|
||||||
|
|
||||||
const { dispatch, history } = this.props;
|
|
||||||
|
|
||||||
dispatch(login(values.username, values.password))
|
|
||||||
.then(() => {
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
isLoggedIn: true
|
|
||||||
});
|
|
||||||
|
|
||||||
eventBus.dispatch(LOGIN_SUCCESS, { isLoggedIn: true });
|
|
||||||
history.push("/dashboard");
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.setState({
|
|
||||||
loading: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let trueBool = true;
|
|
||||||
return (
|
return (
|
||||||
<div className="pageWrapper">
|
<div className="pageWrapper">
|
||||||
<h1>
|
<h1>
|
||||||
@ -55,7 +18,7 @@ class Login extends React.Component {
|
|||||||
<div className="loginBody">
|
<div className="loginBody">
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{ username: '', password: '' }}
|
initialValues={{ username: '', password: '' }}
|
||||||
onSubmit={async values => this.handleLogin(values)}
|
onSubmit={values => Login(values)}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
<label>
|
<label>
|
||||||
@ -63,7 +26,7 @@ class Login extends React.Component {
|
|||||||
<Field
|
<Field
|
||||||
name="username"
|
name="username"
|
||||||
type="text"
|
type="text"
|
||||||
required={trueBool}
|
required={boolTrue}
|
||||||
className="loginFields"
|
className="loginFields"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
@ -73,7 +36,7 @@ class Login extends React.Component {
|
|||||||
<Field
|
<Field
|
||||||
name="password"
|
name="password"
|
||||||
type="password"
|
type="password"
|
||||||
required={trueBool}
|
required={boolTrue}
|
||||||
className="loginFields"
|
className="loginFields"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
@ -82,21 +45,13 @@ class Login extends React.Component {
|
|||||||
color="primary"
|
color="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
className="loginButton"
|
className="loginButton"
|
||||||
disabled={this.state.loading}
|
disabled={loading}
|
||||||
>{this.state.loading ? <ScaleLoader color="#FFF" size={35} /> : "Login"}</Button>
|
>{loading ? <ScaleLoader color="#FFF" size={35} /> : "Login"}</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</Formik>
|
</Formik>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
export default Login;
|
||||||
const { isLoggedIn } = state.auth;
|
|
||||||
return {
|
|
||||||
isLoggedIn
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(Login);
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../App.css';
|
import '../App.css';
|
||||||
import './Dashboard.css';
|
import './Dashboard.css';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
class Profile extends React.Component {
|
class Profile extends React.Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -23,11 +22,4 @@ class Profile extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
export default Profile;
|
||||||
const { isLoggedIn } = state.auth;
|
|
||||||
return {
|
|
||||||
isLoggedIn,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(Profile);
|
|
@ -3,9 +3,8 @@ import '../App.css';
|
|||||||
import './Register.css';
|
import './Register.css';
|
||||||
import { Button } from 'reactstrap';
|
import { Button } from 'reactstrap';
|
||||||
import ScaleLoader from "react-spinners/ScaleLoader";
|
import ScaleLoader from "react-spinners/ScaleLoader";
|
||||||
import { register } from '../Actions/auth';
|
import register from '../Contexts/AuthContextProvider';
|
||||||
import { Formik, Field, Form } from 'formik';
|
import { Formik, Field, Form } from 'formik';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
class Register extends React.Component {
|
class Register extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -115,11 +114,4 @@ class Register extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
export default Register;
|
||||||
const { isLoggedIn } = state.auth;
|
|
||||||
return {
|
|
||||||
isLoggedIn
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(Register);
|
|
||||||
|
@ -2,15 +2,6 @@ import React from 'react';
|
|||||||
import '../App.css';
|
import '../App.css';
|
||||||
import './Settings.css';
|
import './Settings.css';
|
||||||
|
|
||||||
import { useToasts } from 'react-toast-notifications';
|
|
||||||
|
|
||||||
function withToast(Component) {
|
|
||||||
return function WrappedComponent(props) {
|
|
||||||
const toastFuncs = useToasts()
|
|
||||||
return <Component {...props} {...toastFuncs} />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Settings extends React.Component {
|
class Settings extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -33,4 +24,4 @@ class Settings extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withToast(Settings);
|
export default Settings;
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
import {
|
|
||||||
REGISTER_SUCCESS,
|
|
||||||
REGISTER_FAIL,
|
|
||||||
LOGIN_SUCCESS,
|
|
||||||
LOGIN_FAIL,
|
|
||||||
LOGOUT,
|
|
||||||
} from "../Actions/types";
|
|
||||||
|
|
||||||
const user = JSON.parse(localStorage.getItem('user'));
|
|
||||||
|
|
||||||
const initialState = user
|
|
||||||
? { isLoggedIn: true, user: user }
|
|
||||||
: { isLoggedIn: false, user: null };
|
|
||||||
|
|
||||||
export default function authReducer(state = initialState, action) {
|
|
||||||
const { type, payload } = action;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case REGISTER_SUCCESS:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isLoggedIn: false,
|
|
||||||
};
|
|
||||||
case REGISTER_FAIL:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isLoggedIn: false,
|
|
||||||
};
|
|
||||||
case LOGIN_SUCCESS:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isLoggedIn: true,
|
|
||||||
user: {
|
|
||||||
jwt: payload.jwt,
|
|
||||||
uuid: payload.sub,
|
|
||||||
exp: payload.exp,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
case LOGIN_FAIL:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isLoggedIn: false,
|
|
||||||
};
|
|
||||||
case LOGOUT:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isLoggedIn: false,
|
|
||||||
user: null,
|
|
||||||
};
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
import { combineReducers } from "redux";
|
|
||||||
import auth from "./auth";
|
|
||||||
|
|
||||||
export default combineReducers({
|
|
||||||
auth,
|
|
||||||
});
|
|
@ -1,14 +0,0 @@
|
|||||||
import axios from "axios";
|
|
||||||
import authHeader from '../Services/auth-header';
|
|
||||||
|
|
||||||
class ApiService {
|
|
||||||
async getStats() {
|
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "stats");
|
|
||||||
}
|
|
||||||
|
|
||||||
async getRecentScrobbles(id) {
|
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "user/" + id + "/scrobbles", { headers: authHeader() });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default new ApiService();
|
|
@ -1,9 +0,0 @@
|
|||||||
export default function authHeader() {
|
|
||||||
const user = JSON.parse(localStorage.getItem('user'));
|
|
||||||
|
|
||||||
if (user && user.jwt) {
|
|
||||||
return { Authorization: 'Bearer ' + user.jwt };
|
|
||||||
} else {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
import axios from "axios";
|
|
||||||
import jwt from 'jwt-decode' // import dependency
|
|
||||||
|
|
||||||
class AuthService {
|
|
||||||
async login(username, password) {
|
|
||||||
return axios
|
|
||||||
.post(process.env.REACT_APP_API_URL + "login", { username, password })
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.token) {
|
|
||||||
let expandedUser = jwt(response.data.token)
|
|
||||||
let user = {
|
|
||||||
jwt: response.data.token,
|
|
||||||
uuid: expandedUser.sub,
|
|
||||||
exp: expandedUser.exp,
|
|
||||||
}
|
|
||||||
localStorage.setItem('user', JSON.stringify(user))
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async logout() {
|
|
||||||
localStorage.removeItem("user");
|
|
||||||
}
|
|
||||||
|
|
||||||
async register(username, email, password) {
|
|
||||||
return axios
|
|
||||||
.post(process.env.REACT_APP_API_URL + "register", {
|
|
||||||
username,
|
|
||||||
email,
|
|
||||||
password,
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
console.log(response)
|
|
||||||
return response.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default new AuthService();
|
|
@ -1,18 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import authHeader from './auth-header';
|
|
||||||
|
|
||||||
class UserService {
|
|
||||||
getPublicContent() {
|
|
||||||
return axios.get(process.env.REACT_APP_API_URL + 'all');
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserBoard() {
|
|
||||||
return axios.get(process.env.REACT_APP_API_URL + 'user', { headers: authHeader() });
|
|
||||||
}
|
|
||||||
|
|
||||||
getAdminBoard() {
|
|
||||||
return axios.get(process.env.REACT_APP_API_URL + 'admin', { headers: authHeader() });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default new UserService();
|
|
@ -3,13 +3,14 @@ import ReactDOM from 'react-dom';
|
|||||||
import './index.css';
|
import './index.css';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import { HashRouter } from 'react-router-dom';
|
import { HashRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import { ToastContainer } from 'react-toastify';
|
import { ToastContainer } from 'react-toastify';
|
||||||
import 'react-toastify/dist/ReactToastify.min.css'
|
import 'react-toastify/dist/ReactToastify.min.css';
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
import store from "./store";
|
import AuthContextProvider from './Contexts/AuthContextProvider';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Provider store={store}>
|
<AuthContextProvider>
|
||||||
<HashRouter>
|
<HashRouter>
|
||||||
<ToastContainer
|
<ToastContainer
|
||||||
position="bottom-right"
|
position="bottom-right"
|
||||||
@ -24,6 +25,6 @@ ReactDOM.render(
|
|||||||
/>
|
/>
|
||||||
<App />
|
<App />
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
</Provider>,
|
</AuthContextProvider>,
|
||||||
document.getElementById('root')
|
document.getElementById('root')
|
||||||
);
|
);
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import { createStore, applyMiddleware } from "redux";
|
|
||||||
import { composeWithDevTools } from "redux-devtools-extension";
|
|
||||||
import thunk from "redux-thunk";
|
|
||||||
import rootReducer from "./Reducers";
|
|
||||||
|
|
||||||
const middleware = [thunk];
|
|
||||||
|
|
||||||
const store = createStore(
|
|
||||||
rootReducer,
|
|
||||||
composeWithDevTools(applyMiddleware(...middleware))
|
|
||||||
);
|
|
||||||
|
|
||||||
export default store;
|
|
Loading…
Reference in New Issue
Block a user