From 65c092e4eede32e16ebd8fc8d65286b6bfd408d0 Mon Sep 17 00:00:00 2001 From: Daniel Mason Date: Wed, 31 Mar 2021 19:14:22 +1300 Subject: [PATCH] 0.0.7 - Switch redux -> Context - Remove excess packages --- .gitlab-ci.yml | 3 + docs/changelog.md | 4 +- internal/goscrobble/user.go | 2 - web/src/Api/index.js | 30 +-- web/src/Components/Navigation.js | 287 +++++++++++------------- web/src/Components/ScrobbleTable.js | 16 +- web/src/Contexts/AuthContextProvider.js | 10 +- web/src/Pages/About.js | 2 +- web/src/Pages/Dashboard.js | 74 +++--- web/src/Pages/Home.js | 6 +- web/src/Pages/Login.js | 8 +- web/src/Pages/Profile.js | 34 +-- web/src/Pages/Register.js | 183 +++++++-------- web/src/Pages/Settings.js | 31 +-- 14 files changed, 293 insertions(+), 397 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6f2b9a37..10d39ba9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,6 +8,7 @@ variables: build-go: image: golang:1.16.2 stage: build + only: master script: - go build -o goscrobble cmd/go-scrobble/*.go artifacts: @@ -21,6 +22,7 @@ build-go: build-react: image: node:15.12.0 stage: build + only: master script: - cd web - npm install @@ -33,6 +35,7 @@ build-react: bundle: image: bash:latest stage: bundle + only: master variables: GIT_STRATEGY: none before_script: diff --git a/docs/changelog.md b/docs/changelog.md index 07be997e..d92978d8 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,7 @@ # 0.0.7 --Switch redux -> context. +- Switch redux -> Context +- Remove excess packages + # 0.0.6 - Fix hitting dashboard when logged out diff --git a/internal/goscrobble/user.go b/internal/goscrobble/user.go index 2b3fff66..c1626325 100644 --- a/internal/goscrobble/user.go +++ b/internal/goscrobble/user.go @@ -61,10 +61,8 @@ func createUser(req *RegisterRequest, ip net.IP) error { // Check username is valid if !isUsernameValid(req.Username) { - log.Println("user is invalid") return errors.New("Username contains invalid characters") } - log.Println("user is valid") // If set an email.. validate it! if req.Email != "" { diff --git a/web/src/Api/index.js b/web/src/Api/index.js index 213e5c7e..ba263584 100644 --- a/web/src/Api/index.js +++ b/web/src/Api/index.js @@ -24,30 +24,26 @@ export const PostLogin = (formValues) => { jwt: response.data.token, uuid: expandedUser.sub, exp: expandedUser.exp, + username: expandedUser.username, } - // 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 } }) + .catch(() => { + return Promise.resolve(); + }); }; export const PostRegister = (formValues) => { - axios.post(process.env.REACT_APP_API_URL + "register", formValues) + return axios.post(process.env.REACT_APP_API_URL + "register", formValues) .then((response) => { - if (response.data.token) { - toast.success('Successfully registered. Please sign in'); + if (response.data.message) { + toast.success(response.data.message); return Promise.resolve(); } else { @@ -56,16 +52,8 @@ export const PostRegister = (formValues) => { 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(); + .catch(() => { + return Promise.resolve(); }); }; diff --git a/web/src/Components/Navigation.js b/web/src/Components/Navigation.js index b1dabd78..5c3ea871 100644 --- a/web/src/Components/Navigation.js +++ b/web/src/Components/Navigation.js @@ -1,10 +1,10 @@ -import { React, Component } from 'react'; +import { React, useState, useContext } from 'react'; import { Navbar, NavbarBrand, Collapse, Nav, NavbarToggler, NavItem } from 'reactstrap'; -import { Link } from 'react-router-dom'; +import { Link, useLocation } from 'react-router-dom'; import logo from '../logo.png'; import './Navigation.css'; -import logout from '../Contexts/AuthContextProvider'; +import AuthContext from '../Contexts/AuthContext'; const menuItems = [ 'Home', @@ -20,178 +20,141 @@ const isMobile = () => { return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) }; -class Navigation extends Component { - constructor(props) { - super(props); - this.toggleNavbar = this.toggleNavbar.bind(this); - this.handleLogout = this.handleLogout.bind(this); +const Navigation = () => { + const location = useLocation(); - // Yeah I know you might not hit home.. but I can't get the - // path based finder thing working on initial load :sweatsmile: - this.state = { active: "Home", collapsed: true }; + // Lovely hack to highlight the current page (: + let active = "Home" + if (location && location.pathname && location.pathname.length > 1) { + active = location.pathname.replace(/\//, ""); } - componentDidMount() { - const { isLoggedIn } = this.props; - if (isLoggedIn) { - this.setState({ - isLoggedIn: true, - }); - } + let activeStyle = { color: '#FFFFFF' }; + let { user, Logout } = useContext(AuthContext); + let [collapsed, setCollapsed] = useState(true); - } - - _handleClick(menuItem) { - this.setState({ active: menuItem, collapsed: !this.state.collapsed }); - } - - handleLogout() { - this.dispatch(logout()); - } - - toggleNavbar() { - this.setState({ collapsed: !this.state.collapsed }); - } - - // This is a real mess. TO CLEAN UP. - render() { - const activeStyle = { color: '#FFFFFF' }; - - const renderMobileNav = () => { - return - logo GoScrobble - - - {this.state.isLoggedIn ? - - : - } - - - } - - const renderDesktopNav = () => { - return - logo GoScrobble - {this.state.isLoggedIn ? -
- {loggedInMenuItems.map(menuItem => - - {menuItem} - - )} -
- :
- {menuItems.map(menuItem => - - {menuItem} - - )} -
- } - {this.state.isLoggedIn ? -
- Profile - Logout -
- : -
- Login - Register -
+ >{user.username} + Logout + + : +
+ Login + Register +
- } -
- } - - return ( -
- { - isMobile() - ? renderMobileNav() - : renderDesktopNav() - } -
- ); + } + } + + return ( +
+ { + isMobile() + ? renderMobileNav() + : renderDesktopNav() + } +
+ ); } export default Navigation; \ No newline at end of file diff --git a/web/src/Components/ScrobbleTable.js b/web/src/Components/ScrobbleTable.js index c15e6e93..57507072 100644 --- a/web/src/Components/ScrobbleTable.js +++ b/web/src/Components/ScrobbleTable.js @@ -1,15 +1,6 @@ import React from "react"; -class ScrobbleTable extends React.Component { - constructor(props) { - super(props); - - this.state = { - data: this.props.data, - }; - } - - render() { +const ScrobbleTable = (props) => { return (
@@ -23,8 +14,8 @@ class ScrobbleTable extends React.Component { { - this.state.data && this.state.data.items && - this.state.data.items.map(function (element) { + props.data && props.data.items && + props.data.items.map(function (element) { return @@ -37,7 +28,6 @@ class ScrobbleTable extends React.Component {
{element.time} {element.track}
); - } } export default ScrobbleTable; \ No newline at end of file diff --git a/web/src/Contexts/AuthContextProvider.js b/web/src/Contexts/AuthContextProvider.js index b94905df..0b0907b1 100644 --- a/web/src/Contexts/AuthContextProvider.js +++ b/web/src/Contexts/AuthContextProvider.js @@ -1,7 +1,6 @@ import React, { useState, useEffect } from 'react'; import { toast } from 'react-toastify'; import AuthContext from './AuthContext'; - import { PostLogin, PostRegister } from '../Api/index'; const AuthContextProvider = ({ children }) => { @@ -22,21 +21,16 @@ const AuthContextProvider = ({ children }) => { PostLogin(formValues).then(user => { if (user) { setUser(user); - const { history } = this.props; - history.push("/dashboard"); + localStorage.setItem('user', JSON.stringify(user)); } setLoading(false); }) } const Register = (formValues) => { - const { history } = this.props; - setLoading(true); return PostRegister(formValues).then(response => { - if (response) { - history.push("/login"); - } + // Do stuff here? setLoading(false); }); }; diff --git a/web/src/Pages/About.js b/web/src/Pages/About.js index cb9690ab..cfd74942 100644 --- a/web/src/Pages/About.js +++ b/web/src/Pages/About.js @@ -12,7 +12,7 @@ const About = () => { Used to track your listening history and build a profile to discover new music.

{ + const history = useHistory(); + let { user } = useContext(AuthContext); + let [isLoading, setIsLoading] = useState(true); + let [dashboardData, setDashboardData] = useState({}); + + if (!user) { + history.push("/login"); } - componentDidMount() { - const { history, uuid } = this.props; - const isLoggedIn = this.props.isLoggedIn; - - if (!isLoggedIn) { - history.push("/login") + useEffect(() => { + if (!user) { + return } + getRecentScrobbles(user.uuid) + .then(data => { + setDashboardData(data); + setIsLoading(false); + }) + }, [user]) - getRecentScrobbles(uuid) - .then((data) => { - this.setState({ - isLoading: false, - data: data - }); - }) - .catch(() => { - this.setState({ - isLoading: false - }); - }); - } - - render() { - return ( -
-

- Dashboard! -

- {this.state.isLoading - ? - : - } -
- ); - } + return ( +
+

+ Dashboard! +

+ {isLoading + ? + : + } +
+ ); } export default Dashboard; diff --git a/web/src/Pages/Home.js b/web/src/Pages/Home.js index 8bf4b070..574c57eb 100644 --- a/web/src/Pages/Home.js +++ b/web/src/Pages/Home.js @@ -4,16 +4,14 @@ import './Home.css'; import HomeBanner from '../Components/HomeBanner'; import React from 'react'; -class Home extends React.Component { - render() { - return ( +const Home = () => { + return (
logo

Go-Scrobble is an open source music scrobbling service written in Go and React.

); - } } export default Home; diff --git a/web/src/Pages/Login.js b/web/src/Pages/Login.js index 6c04dad7..ceb15dfb 100644 --- a/web/src/Pages/Login.js +++ b/web/src/Pages/Login.js @@ -5,10 +5,16 @@ import { Button } from 'reactstrap'; import { Formik, Form, Field } from 'formik'; import ScaleLoader from 'react-spinners/ScaleLoader'; import AuthContext from '../Contexts/AuthContext'; +import { useHistory } from "react-router"; const Login = () => { + const history = useHistory(); let boolTrue = true; - let { Login, loading } = useContext(AuthContext); + let { Login, loading, user } = useContext(AuthContext); + + if (user) { + history.push("/dashboard"); + } return (
diff --git a/web/src/Pages/Profile.js b/web/src/Pages/Profile.js index 2d9e11da..239f290d 100644 --- a/web/src/Pages/Profile.js +++ b/web/src/Pages/Profile.js @@ -1,25 +1,25 @@ -import React from 'react'; +import React, { useContext } from 'react'; import '../App.css'; import './Dashboard.css'; +import { useHistory } from "react-router"; +import AuthContext from '../Contexts/AuthContext'; -class Profile extends React.Component { - componentDidMount() { - const { history, isLoggedIn } = this.props; - - if (!isLoggedIn) { - history.push("/login") - } +const Profile = () => { + const history = useHistory(); + const { user } = useContext(AuthContext); + + if (!user) { + history.push("/login"); } - render() { - return ( -
-

- Hai User -

-
- ); - } + return ( +
+

+ Welcome {user.username}! +

+
+ ); + } export default Profile; \ No newline at end of file diff --git a/web/src/Pages/Register.js b/web/src/Pages/Register.js index 97aaa9a5..9787ebb6 100644 --- a/web/src/Pages/Register.js +++ b/web/src/Pages/Register.js @@ -1,117 +1,90 @@ -import React from 'react'; +import React, { useContext } from 'react'; import '../App.css'; import './Register.css'; import { Button } from 'reactstrap'; import ScaleLoader from "react-spinners/ScaleLoader"; -import register from '../Contexts/AuthContextProvider'; +import AuthContext from '../Contexts/AuthContext'; import { Formik, Field, Form } from 'formik'; +import { useHistory } from "react-router"; -class Register extends React.Component { - constructor(props) { - super(props); - this.state = {username: '', email: '', password: '', passwordconfirm: '', loading: false}; +const Register = () => { + const history = useHistory(); + let boolTrue = true; + let { Register, user, loading } = useContext(AuthContext); + + if (user) { + history.push("/dashboard"); } - componentDidMount() { - const { history, isLoggedIn } = this.props; - - if (isLoggedIn) { - history.push("/dashboard") - } - } - - handleRegister(values) { - console.log(values) - this.setState({loading: true}); - - const { dispatch, history } = this.props; - - dispatch(register(values.username, values.email, values.password)) - .then(() => { - this.setState({ - loading: false, - }); - history.push("/login"); - }) - .catch(() => { - this.setState({ - loading: false - }); - }); - } - - render() { - let trueBool = true; - return ( -
- { - // TODO: Move to DB:config REGISTRATION_DISABLED=1|0 - process.env.REACT_APP_REGISTRATION_DISABLED === "true" ? -

Registration is temporarily disabled. Please try again soon!

- : -
-

- Register -

-
- this.handleRegister(values)} - > -
- -
- -
- -
- -

- -
-
-
+ return ( +
+ { + // TODO: Move to DB:config REGISTRATION_DISABLED=1|0 :upsidedownsmile: + process.env.REACT_APP_REGISTRATION_DISABLED === "true" ? +

Registration is temporarily disabled. Please try again soon!

+ : +
+

+ Register +

+
+ Register(values)} + > +
+ +
+ +
+ +
+ +

+ +
+
- } -
- ); - } +
+ } +
+ ); } export default Register; diff --git a/web/src/Pages/Settings.js b/web/src/Pages/Settings.js index 1d0ca5e3..791009e2 100644 --- a/web/src/Pages/Settings.js +++ b/web/src/Pages/Settings.js @@ -2,26 +2,19 @@ import React from 'react'; import '../App.css'; import './Settings.css'; -class Settings extends React.Component { - constructor(props) { - super(props); - this.state = {username: '', password: '', loading: false}; - } - - render() { - return ( -
-

- Settings -

-
-

- All the settings -

-
+const Settings = () => { + return ( +
+

+ Settings +

+
+

+ All the settings +

- ); - } +
+ ); } export default Settings;