mirror of
https://github.com/idanoo/GoScrobble.git
synced 2024-12-25 16:19:00 +00:00
Update readme, add stack+support. Add redis env vars. Add disable registration flag
This commit is contained in:
parent
dc1a2df968
commit
feb2ac37da
@ -3,6 +3,11 @@ MYSQL_USER=
|
||||
MYSQL_PASS=
|
||||
MYSQL_DB=
|
||||
|
||||
REDIS_URL=
|
||||
REDIS_DB=
|
||||
REDIS_PREFIX="gs:"
|
||||
REDIS_AUTH=""
|
||||
|
||||
JWT_SECRET=
|
||||
JWT_EXPIRY=86400
|
||||
|
||||
|
@ -30,7 +30,6 @@ build-react:
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- web/build
|
||||
- web/public
|
||||
- .env.example
|
||||
|
||||
bundle:
|
||||
@ -41,8 +40,8 @@ bundle:
|
||||
before_script:
|
||||
- apk add --no-cache zip tar
|
||||
script:
|
||||
- zip -r goscrobble.zip web goscrobble migrations init .env.example
|
||||
- tar -czf goscrobble.tar.gz web goscrobble migrations init .env.example
|
||||
- zip -r goscrobble.zip web/build goscrobble migrations init .env.example
|
||||
- tar -czf goscrobble.tar.gz web/build goscrobble migrations init .env.example
|
||||
artifacts:
|
||||
expire_in: 6 months
|
||||
paths:
|
||||
|
14
README.md
14
README.md
@ -1,14 +1,14 @@
|
||||
# go-scrobble
|
||||
|
||||
Golang based music scrobbler. MySQL 8.0+
|
||||
Golang based music scrobbler.
|
||||
|
||||
Currently building on Node V15.X & Go V1.16.X
|
||||
Stack: Go 1.16+, Node 15+, React 17+, MySQL 8.0+, Redis
|
||||
|
||||
There are prebuilt binaries/packages available.
|
||||
|
||||
With a prebuilt binary - you will still need the migrations folder + web/build folder on prod.
|
||||
|
||||
Copy .env.example to .env and set variables. You can use https://www.grc.com/passwords.htm to generate a JWT_SECRET.
|
||||
|
||||
|
||||
## Setup MySQL
|
||||
create user 'goscrobble'@'%' identified by 'supersecurepass';
|
||||
create database goscrobble;
|
||||
@ -31,4 +31,8 @@ We need to build NPM package, and then ship web/build with the binary.
|
||||
cp .env.example .env # Fill in the blanks
|
||||
cd web npm install --production && REACT_APP_API_URL=https://goscrobble.com npm run build
|
||||
go build -o goscrobble cmd/go-scrobble/*.go
|
||||
./goscrobble
|
||||
./goscrobble
|
||||
|
||||
|
||||
## Support Development!
|
||||
Feel free to support hosting and my coffee addiction https://liberapay.com/idanoo
|
21
docs/config.md
Normal file
21
docs/config.md
Normal file
@ -0,0 +1,21 @@
|
||||
## FRONTEND VARS
|
||||
REACT_APP_REGISTRATION_DISABLED=true // Disables registration
|
||||
REACT_APP_API_URL=https://goscrobble.com // Sets API URL
|
||||
|
||||
|
||||
## BACKEND VARS
|
||||
MYSQL_HOST= // MySQL Server
|
||||
MYSQL_USER= // MySQL User
|
||||
MYSQL_PASS= // MySQL Password
|
||||
MYSQL_DB= // MySQL Database
|
||||
|
||||
REDIS_URL= // Redis host
|
||||
REDIS_DB=4 // Redis DB
|
||||
REDIS_PREFIX="gs:" // Redis key prefix
|
||||
REDIS_AUTH="" // Redis password
|
||||
|
||||
JWT_SECRET= // 32+ Char JWT secret
|
||||
JWT_EXPIRY=86400 // JWT expiry
|
||||
|
||||
REVERSE_PROXIES=127.0.0.1 // Comma separated list of servers to ignore for IP logs
|
||||
PORT=42069 // Server port
|
140
web/package-lock.json
generated
140
web/package-lock.json
generated
@ -13,8 +13,10 @@
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"bootstrap": "^4.6.0",
|
||||
"formik": "^2.2.6",
|
||||
"react": "^17.0.2",
|
||||
"react-bootstrap": "^1.5.2",
|
||||
"react-cookie": "^4.0.3",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-redux": "^7.2.3",
|
||||
"react-router-dom": "^5.2.0",
|
||||
@ -22,6 +24,7 @@
|
||||
"react-toast": "^1.0.1",
|
||||
"react-toast-notifications": "^2.4.3",
|
||||
"reactstrap": "^8.9.0",
|
||||
"redux-persist": "^6.0.0",
|
||||
"web-vitals": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -3095,6 +3098,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.11.tgz",
|
||||
"integrity": "sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw=="
|
||||
},
|
||||
"node_modules/@types/cookie": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
||||
"integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow=="
|
||||
},
|
||||
"node_modules/@types/eslint": {
|
||||
"version": "7.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.7.tgz",
|
||||
@ -8961,6 +8969,42 @@
|
||||
"node": ">= 0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/formik": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/formik/-/formik-2.2.6.tgz",
|
||||
"integrity": "sha512-Kxk2zQRafy56zhLmrzcbryUpMBvT0tal5IvcifK5+4YNGelKsnrODFJ0sZQRMQboblWNym4lAW3bt+tf2vApSA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://opencollective.com/formik"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"deepmerge": "^2.1.1",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"lodash": "^4.17.14",
|
||||
"lodash-es": "^4.17.14",
|
||||
"react-fast-compare": "^2.0.1",
|
||||
"tiny-warning": "^1.0.2",
|
||||
"tslib": "^1.10.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/formik/node_modules/deepmerge": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
|
||||
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/formik/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
@ -16241,6 +16285,19 @@
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
},
|
||||
"node_modules/react-cookie": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.0.3.tgz",
|
||||
"integrity": "sha512-cmi6IpdVgTSvjqssqIEvo779Gfqc4uPGHRrKMEdHcqkmGtPmxolGfsyKj95bhdLEKqMdbX8MLBCwezlnhkHK0g==",
|
||||
"dependencies": {
|
||||
"@types/hoist-non-react-statics": "^3.0.1",
|
||||
"hoist-non-react-statics": "^3.0.0",
|
||||
"universal-cookie": "^4.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">= 16.3.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",
|
||||
@ -16357,6 +16414,11 @@
|
||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
|
||||
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
|
||||
},
|
||||
"node_modules/react-fast-compare": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
|
||||
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
@ -16862,6 +16924,14 @@
|
||||
"symbol-observable": "^1.2.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",
|
||||
@ -19892,6 +19962,15 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/universal-cookie": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.4.tgz",
|
||||
"integrity": "sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==",
|
||||
"dependencies": {
|
||||
"@types/cookie": "^0.3.3",
|
||||
"cookie": "^0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
@ -24453,6 +24532,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.11.tgz",
|
||||
"integrity": "sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw=="
|
||||
},
|
||||
"@types/cookie": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
||||
"integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow=="
|
||||
},
|
||||
"@types/eslint": {
|
||||
"version": "7.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.7.tgz",
|
||||
@ -29137,6 +29221,32 @@
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"formik": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/formik/-/formik-2.2.6.tgz",
|
||||
"integrity": "sha512-Kxk2zQRafy56zhLmrzcbryUpMBvT0tal5IvcifK5+4YNGelKsnrODFJ0sZQRMQboblWNym4lAW3bt+tf2vApSA==",
|
||||
"requires": {
|
||||
"deepmerge": "^2.1.1",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"lodash": "^4.17.14",
|
||||
"lodash-es": "^4.17.14",
|
||||
"react-fast-compare": "^2.0.1",
|
||||
"tiny-warning": "^1.0.2",
|
||||
"tslib": "^1.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"deepmerge": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
|
||||
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
@ -34782,6 +34892,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-cookie": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.0.3.tgz",
|
||||
"integrity": "sha512-cmi6IpdVgTSvjqssqIEvo779Gfqc4uPGHRrKMEdHcqkmGtPmxolGfsyKj95bhdLEKqMdbX8MLBCwezlnhkHK0g==",
|
||||
"requires": {
|
||||
"@types/hoist-non-react-statics": "^3.0.1",
|
||||
"hoist-non-react-statics": "^3.0.0",
|
||||
"universal-cookie": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"react-dev-utils": {
|
||||
"version": "11.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
|
||||
@ -34872,6 +34992,11 @@
|
||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
|
||||
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
|
||||
},
|
||||
"react-fast-compare": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
|
||||
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
|
||||
},
|
||||
"react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
@ -35276,6 +35401,12 @@
|
||||
"symbol-observable": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
@ -37681,6 +37812,15 @@
|
||||
"crypto-random-string": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"universal-cookie": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.4.tgz",
|
||||
"integrity": "sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.3.3",
|
||||
"cookie": "^0.4.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
|
@ -8,8 +8,10 @@
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"bootstrap": "^4.6.0",
|
||||
"formik": "^2.2.6",
|
||||
"react": "^17.0.2",
|
||||
"react-bootstrap": "^1.5.2",
|
||||
"react-cookie": "^4.0.3",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-redux": "^7.2.3",
|
||||
"react-router-dom": "^5.2.0",
|
||||
@ -17,6 +19,7 @@
|
||||
"react-toast": "^1.0.1",
|
||||
"react-toast-notifications": "^2.4.3",
|
||||
"reactstrap": "^8.9.0",
|
||||
"redux-persist": "^6.0.0",
|
||||
"web-vitals": "^1.1.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -2,14 +2,12 @@ import './App.css';
|
||||
import Home from './Components/Pages/Home';
|
||||
import About from './Components/Pages/About';
|
||||
import Login from './Components/Pages/Login';
|
||||
import Settings from './Components/Pages/Settings';
|
||||
import Register from './Components/Pages/Register';
|
||||
import Navigation from './Components/Navigation';
|
||||
|
||||
import { Route, Switch, HashRouter } from 'react-router-dom';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { ToastProvider } from 'react-toast-notifications';
|
||||
|
||||
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
@ -28,17 +26,16 @@ function mapDispatchToProps(dispatch) {
|
||||
const App = () => {
|
||||
let exact = true
|
||||
return (
|
||||
<HashRouter>
|
||||
<ToastProvider autoDismiss="true" autoDismissTimeout="5000" placement="bottom-right">
|
||||
<Navigation />
|
||||
<Switch>
|
||||
<Route exact={exact} path="/" component={Home} />
|
||||
<Route path="/about" component={About} />
|
||||
<Route path="/login" component={Login} />
|
||||
<Route path="/register" component={Register} />
|
||||
</Switch>
|
||||
</ToastProvider>
|
||||
</HashRouter>
|
||||
<div>
|
||||
<Navigation />
|
||||
<Switch>
|
||||
<Route exact={exact} path="/" component={Home} />
|
||||
<Route path="/about" component={About} />
|
||||
<Route path="/settings" component={Settings} />
|
||||
<Route path="/login" component={Login} />
|
||||
<Route path="/register" component={Register} />
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
1
web/src/Components/Api.js
Normal file
1
web/src/Components/Api.js
Normal file
@ -0,0 +1 @@
|
||||
// https://stackoverflow.com/questions/38397653/redux-what-is-the-correct-place-to-save-cookie-after-login-request
|
45
web/src/Components/AppProvider.js
Normal file
45
web/src/Components/AppProvider.js
Normal file
@ -0,0 +1,45 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { persistStore } from 'redux-persist';
|
||||
|
||||
class AppProvider extends Component {
|
||||
static propTypes = {
|
||||
store: PropTypes.object.isRequired,
|
||||
children: PropTypes.node
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = { rehydrated: false };
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const opts = {
|
||||
whitelist: ['user'] // <-- Your auth/user reducer storing the cookie
|
||||
};
|
||||
|
||||
persistStore(this.props.store, opts, () => {
|
||||
this.setState({ rehydrated: true });
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.state.rehydrated) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Provider store={this.props.store}>
|
||||
{this.props.children}
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AppProvider.propTypes = {
|
||||
store: PropTypes.object.isRequired,
|
||||
children: PropTypes.node
|
||||
}
|
||||
|
||||
export default AppProvider;
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import '../../App.css';
|
||||
import './Login.css';
|
||||
import { Button } from 'reactstrap';
|
||||
|
||||
import { Formik, Form, Field } from 'formik';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
|
||||
function withToast(Component) {
|
||||
@ -29,16 +29,15 @@ class Login extends React.Component {
|
||||
this.setState({password: event.target.value});
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
handleSubmit(values) {
|
||||
this.setState({loading: true});
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
timeout: 5000,
|
||||
body: JSON.stringify({
|
||||
username: this.state.username,
|
||||
password: this.state.password,
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
})
|
||||
};
|
||||
const apiUrl = process.env.REACT_APP_API_URL + '/api/v1/login';
|
||||
@ -47,7 +46,7 @@ class Login extends React.Component {
|
||||
.then((function(data) {
|
||||
if (data.error) {
|
||||
this.props.addToast(data.error, { appearance: 'error' });
|
||||
} else {
|
||||
} else if (data.token) {
|
||||
this.props.addToast(data.token, { appearance: 'success' });
|
||||
}
|
||||
this.setState({loading: false});
|
||||
@ -59,30 +58,35 @@ class Login extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let trueBool = true;
|
||||
return (
|
||||
<div className="pageWrapper">
|
||||
<h1>
|
||||
Login
|
||||
</h1>
|
||||
<div className="loginBody">
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<Formik
|
||||
initialValues={{ username: '', password: '' }}
|
||||
onSubmit={async values => this.handleSubmit(values)}
|
||||
>
|
||||
<Form>
|
||||
<label>
|
||||
Email / Username<br/>
|
||||
<input
|
||||
<Field
|
||||
name="username"
|
||||
type="text"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
value={this.state.username}
|
||||
onChange={this.handleUsernameChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Password<br/>
|
||||
<input
|
||||
<Field
|
||||
name="password"
|
||||
type="password"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
value={this.state.password}
|
||||
onChange={this.handlePasswordChange}
|
||||
/>
|
||||
</label>
|
||||
<br/><br/>
|
||||
@ -92,7 +96,8 @@ class Login extends React.Component {
|
||||
className="loginButton"
|
||||
disabled={this.state.loading}
|
||||
>Login</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||
import '../../App.css';
|
||||
import './Login.css';
|
||||
import { Button } from 'reactstrap';
|
||||
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
|
||||
function withToast(Component) {
|
||||
@ -84,64 +83,73 @@ class Register extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let trueBool = true;
|
||||
return (
|
||||
<div className="pageWrapper">
|
||||
<h1>
|
||||
Register
|
||||
</h1>
|
||||
<div className="loginBody">
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<label>
|
||||
Username*<br/>
|
||||
<input
|
||||
type="text"
|
||||
required="true"
|
||||
className="loginFields"
|
||||
value={this.state.username}
|
||||
onChange={this.handleUsernameChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Email<br/>
|
||||
<input
|
||||
type="email"
|
||||
className="loginFields"
|
||||
value={this.state.email}
|
||||
onChange={this.handleEmailChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Password<br/>
|
||||
<input
|
||||
type="password"
|
||||
required="true"
|
||||
className="loginFields"
|
||||
value={this.state.password}
|
||||
onChange={this.handlePasswordChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Password<br/>
|
||||
<input
|
||||
type="password"
|
||||
required="true"
|
||||
className="loginFields"
|
||||
value={this.state.passwordconfirm}
|
||||
onChange={this.handlePasswordConfirmChange}
|
||||
/>
|
||||
</label>
|
||||
<br/><br/>
|
||||
<Button
|
||||
color="primary"
|
||||
type="submit"
|
||||
className="loginButton"
|
||||
disabled={this.state.loading}
|
||||
>Login</Button>
|
||||
</form>
|
||||
</div>
|
||||
{
|
||||
// TODO: Move to DB:config REGISTRATION_DISABLED=1|0
|
||||
process.env.REACT_APP_REGISTRATION_DISABLED === "true" ?
|
||||
<p>Registration is temporarily disabled. Please try again soon!</p>
|
||||
:
|
||||
<div>
|
||||
<h1>
|
||||
Register
|
||||
</h1>
|
||||
<div className="loginBody">
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<label>
|
||||
Username*<br/>
|
||||
<input
|
||||
type="text"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
value={this.state.username}
|
||||
onChange={this.handleUsernameChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Email<br/>
|
||||
<input
|
||||
type="email"
|
||||
className="loginFields"
|
||||
value={this.state.email}
|
||||
onChange={this.handleEmailChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Password<br/>
|
||||
<input
|
||||
type="password"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
value={this.state.password}
|
||||
onChange={this.handlePasswordChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Password<br/>
|
||||
<input
|
||||
type="password"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
value={this.state.passwordconfirm}
|
||||
onChange={this.handlePasswordConfirmChange}
|
||||
/>
|
||||
</label>
|
||||
<br/><br/>
|
||||
<Button
|
||||
color="primary"
|
||||
type="submit"
|
||||
className="loginButton"
|
||||
disabled={this.state.loading}
|
||||
>Login</Button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
0
web/src/Components/Pages/Settings.css
Normal file
0
web/src/Components/Pages/Settings.css
Normal file
36
web/src/Components/Pages/Settings.js
Normal file
36
web/src/Components/Pages/Settings.js
Normal file
@ -0,0 +1,36 @@
|
||||
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 <Component {...props} {...toastFuncs} />;
|
||||
}
|
||||
}
|
||||
|
||||
class Settings extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {username: '', password: '', loading: false};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="pageWrapper">
|
||||
<h1>
|
||||
Settings
|
||||
</h1>
|
||||
<div className="loginBody">
|
||||
<p>
|
||||
All the settings
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withToast(Settings);
|
@ -2,7 +2,8 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import { HashRouter } from 'react-router-dom'
|
||||
import { ToastProvider } from 'react-toast-notifications';
|
||||
|
||||
import { Provider } from 'react-redux'
|
||||
import { createStore } from 'redux'
|
||||
@ -14,10 +15,12 @@ const goScorbbleStore = (state = false, logIn) => {
|
||||
const store = createStore(goScorbbleStore);
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</Provider>,
|
||||
<HashRouter>
|
||||
<ToastProvider autoDismiss="true" autoDismissTimeout="5000" placement="bottom-right">
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>
|
||||
</ToastProvider>
|
||||
</HashRouter>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user