diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0a6276eb..6f2b9a37 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,7 +3,7 @@ stages:
- bundle
variables:
- VERSION: 0.0.6
+ VERSION: 0.0.7
build-go:
image: golang:1.16.2
diff --git a/docs/changelog.md b/docs/changelog.md
index 19a35080..07be997e 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,3 +1,6 @@
+# 0.0.7
+-Switch redux -> context.
+
# 0.0.6
- Fix hitting dashboard when logged out
- Clean up app.js
diff --git a/web/package-lock.json b/web/package-lock.json
index a86fda08..de4226a5 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -19,21 +19,13 @@
"react": "^17.0.2",
"react-bootstrap": "^1.5.2",
"react-cookie": "^4.0.3",
- "react-data-grid": "*",
"react-dom": "^17.0.2",
"react-redux": "^7.2.3",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"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",
- "reactstrap": "^8.9.0",
- "redux": "^4.0.5",
- "redux-persist": "^6.0.0",
- "redux-thunk": "^2.3.0",
- "web-vitals": "^1.1.1"
+ "reactstrap": "^8.9.0"
},
"devDependencies": {
"redux-devtools-extension": "^2.13.9",
@@ -16328,18 +16320,6 @@
"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": {
"version": "11.0.4",
"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"
}
},
- "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": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-7.0.3.tgz",
@@ -17011,14 +16958,6 @@
"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": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
@@ -20691,11 +20630,6 @@
"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": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
@@ -35007,14 +34941,6 @@
"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": {
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
@@ -35331,27 +35257,6 @@
"@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": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-7.0.3.tgz",
@@ -35543,12 +35448,6 @@
"dev": true,
"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": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
@@ -38488,11 +38387,6 @@
"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": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
diff --git a/web/package.json b/web/package.json
index 745e2036..44605bb0 100644
--- a/web/package.json
+++ b/web/package.json
@@ -14,21 +14,13 @@
"react": "^17.0.2",
"react-bootstrap": "^1.5.2",
"react-cookie": "^4.0.3",
- "react-data-grid": "*",
"react-dom": "^17.0.2",
"react-redux": "^7.2.3",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"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",
- "reactstrap": "^8.9.0",
- "redux": "^4.0.5",
- "redux-persist": "^6.0.0",
- "redux-thunk": "^2.3.0",
- "web-vitals": "^1.1.1"
+ "reactstrap": "^8.9.0"
},
"scripts": {
"start": "react-scripts start",
diff --git a/web/src/Actions/api.js b/web/src/Actions/api.js
deleted file mode 100644
index 57e591d2..00000000
--- a/web/src/Actions/api.js
+++ /dev/null
@@ -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;
- }
- );
-};
-
diff --git a/web/src/Actions/auth.js b/web/src/Actions/auth.js
deleted file mode 100644
index 8f37d2f4..00000000
--- a/web/src/Actions/auth.js
+++ /dev/null
@@ -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);
- };
diff --git a/web/src/Actions/eventBus.js b/web/src/Actions/eventBus.js
deleted file mode 100644
index 17bfcd26..00000000
--- a/web/src/Actions/eventBus.js
+++ /dev/null
@@ -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
\ No newline at end of file
diff --git a/web/src/Actions/types.js b/web/src/Actions/types.js
deleted file mode 100644
index 98fda989..00000000
--- a/web/src/Actions/types.js
+++ /dev/null
@@ -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";
diff --git a/web/src/Api/index.js b/web/src/Api/index.js
new file mode 100644
index 00000000..213e5c7e
--- /dev/null
+++ b/web/src/Api/index.js
@@ -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;
+ });
+};
diff --git a/web/src/App.js b/web/src/App.js
index 02c1c903..7c440fec 100644
--- a/web/src/App.js
+++ b/web/src/App.js
@@ -3,47 +3,36 @@ import Home from './Pages/Home';
import About from './Pages/About';
import Dashboard from './Pages/Dashboard';
-import Admin from './Pages/Admin';
import Profile from './Pages/Profile';
import Login from './Pages/Login';
import Settings from './Pages/Settings';
import Register from './Pages/Register';
import Navigation from './Components/Navigation';
-// import { logout } from './Actions/auth';
import { Route, Switch, withRouter } from 'react-router-dom';
-import { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
-class App extends Component {
- constructor(props) {
- super(props);
- this.state = {
- true: true,
- };
- }
+const App = () => {
+ let boolTrue = true
- render() {
return (
-
+
-
-
);
- }
}
+
export default withRouter(App);
\ No newline at end of file
diff --git a/web/src/Components/HomeBanner.js b/web/src/Components/HomeBanner.js
index c4a4cdf4..66332e4a 100644
--- a/web/src/Components/HomeBanner.js
+++ b/web/src/Components/HomeBanner.js
@@ -1,65 +1,45 @@
-import React from 'react';
+import React, { useEffect, useState } from 'react';
import '../App.css';
import './HomeBanner.css';
-import { getStats } from '../Actions/api';
+import { getStats } from '../Api/index';
import ClipLoader from 'react-spinners/ClipLoader'
-class HomeBanner extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- isLoading: true,
- userCount: 0,
- scrobbleCount: 0,
- trackCount: 0,
- artistCount: 0,
- };
- }
+const HomeBanner = () => {
+ let [bannerData, setBannerData] = useState({});
+ let [isLoading, setIsLoading] = useState(true);
- componentDidMount() {
+ useEffect(() => {
getStats()
- .then((data) => {
- this.setState({
- isLoading: false,
- userCount: data.users,
- scrobbleCount: data.scrobbles,
- trackCount: data.tracks,
- artistCount: data.artists,
- });
- })
- .catch(() => {
- this.setState({
- isLoading: false
- });
- });
- }
+ .then(data => {
+ setBannerData(data);
+ setIsLoading(false);
+ })
+ }, [])
- render() {
- return (
-
-
- {this.state.isLoading
- ?
- : {this.state.scrobbleCount}}
Scrobbles
-
-
- {this.state.isLoading
- ?
- : {this.state.userCount}}
Users
-
-
- {this.state.isLoading
- ?
- : {this.state.trackCount}}
Tracks
-
-
- {this.state.isLoading
- ?
- : {this.state.artistCount}}
Artists
-
+ return (
+
+
+ {isLoading
+ ?
+ : {bannerData.scrobbles}}
Scrobbles
- );
- }
+
+ {isLoading
+ ?
+ : {bannerData.users}}
Users
+
+
+ {isLoading
+ ?
+ : {bannerData.tracks}}
Tracks
+
+
+ {isLoading
+ ?
+ : {bannerData.artists}}
Artists
+
+
+ );
}
export default HomeBanner;
diff --git a/web/src/Components/Navigation.js b/web/src/Components/Navigation.js
index f8f93239..b1dabd78 100644
--- a/web/src/Components/Navigation.js
+++ b/web/src/Components/Navigation.js
@@ -3,14 +3,8 @@ import { Navbar, NavbarBrand, Collapse, Nav, NavbarToggler, NavItem } from 'reac
import { Link } from 'react-router-dom';
import logo from '../logo.png';
import './Navigation.css';
-import { connect } from 'react-redux';
-import { logout } from '../Actions/auth';
-import eventBus from "../Actions/eventBus";
-import {
- LOGIN_SUCCESS,
- LOGOUT,
-} from "../Actions/types";
+import logout from '../Contexts/AuthContextProvider';
const menuItems = [
'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) {
@@ -211,12 +194,4 @@ class Navigation extends Component {
}
}
-function mapStateToProps(state) {
- const { isLoggedIn } = state.auth;
-
- return {
- isLoggedIn
- };
-}
-
-export default connect(mapStateToProps)(Navigation);
\ No newline at end of file
+export default Navigation;
\ No newline at end of file
diff --git a/web/src/Contexts/AuthContext.js b/web/src/Contexts/AuthContext.js
new file mode 100644
index 00000000..c5b074de
--- /dev/null
+++ b/web/src/Contexts/AuthContext.js
@@ -0,0 +1,5 @@
+import React from 'react';
+
+const AuthContext = React.createContext();
+
+export default AuthContext;
\ No newline at end of file
diff --git a/web/src/Contexts/AuthContextProvider.js b/web/src/Contexts/AuthContextProvider.js
new file mode 100644
index 00000000..b94905df
--- /dev/null
+++ b/web/src/Contexts/AuthContextProvider.js
@@ -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 (
+
+ {children}
+
+ );
+};
+
+export default AuthContextProvider;
\ No newline at end of file
diff --git a/web/src/Pages/About.js b/web/src/Pages/About.js
index 9e800c3a..cb9690ab 100644
--- a/web/src/Pages/About.js
+++ b/web/src/Pages/About.js
@@ -1,7 +1,7 @@
import '../App.css';
import './About.css';
-function About() {
+const About = () => {
return (
diff --git a/web/src/Pages/Admin.js b/web/src/Pages/Admin.js
deleted file mode 100644
index e2927dfb..00000000
--- a/web/src/Pages/Admin.js
+++ /dev/null
@@ -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 (
-
-
-
- );
- }
-}
-
-export default Admin;
\ No newline at end of file
diff --git a/web/src/Pages/Dashboard.js b/web/src/Pages/Dashboard.js
index 20c0a08a..11f18038 100644
--- a/web/src/Pages/Dashboard.js
+++ b/web/src/Pages/Dashboard.js
@@ -1,8 +1,8 @@
import React from 'react';
import '../App.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 ScrobbleTable from "../Components/ScrobbleTable";
@@ -53,17 +53,4 @@ class Dashboard extends React.Component {
}
}
-function mapStateToProps(state) {
- const { isLoggedIn } = state.auth;
- let uuid = null;
- if (isLoggedIn) {
- uuid = state.auth.user.uuid
- }
-
- return {
- isLoggedIn,
- uuid,
- };
-}
-
-export default connect(mapStateToProps)(Dashboard);
+export default Dashboard;
diff --git a/web/src/Pages/Login.js b/web/src/Pages/Login.js
index 34e17791..6c04dad7 100644
--- a/web/src/Pages/Login.js
+++ b/web/src/Pages/Login.js
@@ -1,102 +1,57 @@
-import React from 'react';
+import React, { useContext } from 'react';
import '../App.css';
import './Login.css';
import { Button } from 'reactstrap';
import { Formik, Form, Field } from 'formik';
import ScaleLoader from 'react-spinners/ScaleLoader';
-import { connect } from 'react-redux';
-import { login } from '../Actions/auth';
-import eventBus from "../Actions/eventBus";
-import { LOGIN_SUCCESS } from '../Actions/types';
+import AuthContext from '../Contexts/AuthContext';
-class Login extends React.Component {
- constructor(props) {
- super(props);
- this.state = {username: '', password: '', loading: false};
- }
+const Login = () => {
+ let boolTrue = true;
+ let { Login, loading } = useContext(AuthContext);
- 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 (
-
-
- Login
-
-
- this.handleLogin(values)}
- >
-
-
-
+ return (
+
+
+ Login
+
+
+ Login(values)}
+ >
+
+
- );
- }
+
+ );
}
-function mapStateToProps(state) {
- const { isLoggedIn } = state.auth;
- return {
- isLoggedIn
- };
-}
-
-export default connect(mapStateToProps)(Login);
+export default Login;
diff --git a/web/src/Pages/Profile.js b/web/src/Pages/Profile.js
index f87559b7..2d9e11da 100644
--- a/web/src/Pages/Profile.js
+++ b/web/src/Pages/Profile.js
@@ -1,7 +1,6 @@
import React from 'react';
import '../App.css';
import './Dashboard.css';
-import { connect } from 'react-redux';
class Profile extends React.Component {
componentDidMount() {
@@ -23,11 +22,4 @@ class Profile extends React.Component {
}
}
-function mapStateToProps(state) {
- const { isLoggedIn } = state.auth;
- return {
- isLoggedIn,
- };
-}
-
-export default connect(mapStateToProps)(Profile);
\ No newline at end of file
+export default Profile;
\ No newline at end of file
diff --git a/web/src/Pages/Register.js b/web/src/Pages/Register.js
index 2c1ed49c..97aaa9a5 100644
--- a/web/src/Pages/Register.js
+++ b/web/src/Pages/Register.js
@@ -3,9 +3,8 @@ import '../App.css';
import './Register.css';
import { Button } from 'reactstrap';
import ScaleLoader from "react-spinners/ScaleLoader";
-import { register } from '../Actions/auth';
+import register from '../Contexts/AuthContextProvider';
import { Formik, Field, Form } from 'formik';
-import { connect } from 'react-redux';
class Register extends React.Component {
constructor(props) {
@@ -115,11 +114,4 @@ class Register extends React.Component {
}
}
-function mapStateToProps(state) {
- const { isLoggedIn } = state.auth;
- return {
- isLoggedIn
- };
-}
-
-export default connect(mapStateToProps)(Register);
+export default Register;
diff --git a/web/src/Pages/Settings.js b/web/src/Pages/Settings.js
index e517b361..1d0ca5e3 100644
--- a/web/src/Pages/Settings.js
+++ b/web/src/Pages/Settings.js
@@ -2,15 +2,6 @@ import React from 'react';
import '../App.css';
import './Settings.css';
-import { useToasts } from 'react-toast-notifications';
-
-function withToast(Component) {
- return function WrappedComponent(props) {
- const toastFuncs = useToasts()
- return
;
- }
-}
-
class Settings extends React.Component {
constructor(props) {
super(props);
@@ -33,4 +24,4 @@ class Settings extends React.Component {
}
}
-export default withToast(Settings);
+export default Settings;
diff --git a/web/src/Reducers/auth.js b/web/src/Reducers/auth.js
deleted file mode 100644
index df75c1e6..00000000
--- a/web/src/Reducers/auth.js
+++ /dev/null
@@ -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;
- }
- }
diff --git a/web/src/Reducers/index.js b/web/src/Reducers/index.js
deleted file mode 100644
index 3df08848..00000000
--- a/web/src/Reducers/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import { combineReducers } from "redux";
-import auth from "./auth";
-
-export default combineReducers({
- auth,
-});
diff --git a/web/src/Services/Actions.js b/web/src/Services/Actions.js
deleted file mode 100644
index e69de29b..00000000
diff --git a/web/src/Services/api.service.js b/web/src/Services/api.service.js
deleted file mode 100644
index 0a202c5a..00000000
--- a/web/src/Services/api.service.js
+++ /dev/null
@@ -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();
\ No newline at end of file
diff --git a/web/src/Services/auth-header.js b/web/src/Services/auth-header.js
deleted file mode 100644
index 75454e14..00000000
--- a/web/src/Services/auth-header.js
+++ /dev/null
@@ -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 {};
- }
-}
diff --git a/web/src/Services/auth.service.js b/web/src/Services/auth.service.js
deleted file mode 100644
index 81ce31a6..00000000
--- a/web/src/Services/auth.service.js
+++ /dev/null
@@ -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();
diff --git a/web/src/Services/user.service.js b/web/src/Services/user.service.js
deleted file mode 100644
index 77b5391a..00000000
--- a/web/src/Services/user.service.js
+++ /dev/null
@@ -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();
diff --git a/web/src/index.js b/web/src/index.js
index 03553c32..15dbe6a0 100644
--- a/web/src/index.js
+++ b/web/src/index.js
@@ -3,13 +3,14 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { HashRouter } from 'react-router-dom';
+
import { ToastContainer } from 'react-toastify';
-import 'react-toastify/dist/ReactToastify.min.css'
-import { Provider } from 'react-redux';
-import store from "./store";
+import 'react-toastify/dist/ReactToastify.min.css';
+
+import AuthContextProvider from './Contexts/AuthContextProvider';
ReactDOM.render(
-
+
- ,
+ ,
document.getElementById('root')
);
diff --git a/web/src/store.js b/web/src/store.js
deleted file mode 100644
index 03eff2c9..00000000
--- a/web/src/store.js
+++ /dev/null
@@ -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;