Viewing profiles works, profiles not yet created

This commit is contained in:
2019-05-10 13:11:07 +10:00
parent 84ce324365
commit 31a59f56ba
8 changed files with 300 additions and 8 deletions
+8 -4
View File
@@ -110,8 +110,8 @@ footer {
/* custom styling */
/* Homepage structure */
.homePage {
/* SidePanelPage structure */
.sidePanelPage {
flex: 1;
display: flex;
flex-direction: row;
@@ -120,14 +120,14 @@ footer {
}
@media screen and (max-width: 480px) {
.homePage {
.sidePanelPage {
flex-direction: column;
}
}
/* left panel */
.sidePanel {
flex: 1;
flex: 0 1 auto;
display: flex;
flex-direction: column;
justify-content: flex-start;
@@ -173,6 +173,10 @@ footer {
/* New panel */
.newsPanel {
margin-left: 15px;
flex: 1;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
/* bits and pieces */
+4
View File
@@ -24,6 +24,10 @@ app.post('/passwordchange', accounts.passwordChange(connection));
app.post('/passwordrecover', accounts.passwordRecover(connection));
app.post('/passwordreset', accounts.passwordReset(connection));
//handle profiles
let profiles = require('./profiles.js');
app.post('/profilerequest', profiles.profileRequest(connection));
//static directories
app.use('/styles', express.static(path.resolve(__dirname + '/../public/styles')) );
+44
View File
@@ -0,0 +1,44 @@
//environment variables
require('dotenv').config();
//libraries
let formidable = require('formidable');
function profileRequest(connection) {
return (req, res) => {
//formidable handles forms
let form = formidable.IncomingForm();
//parse form
form.parse(req, (err, fields) => {
if (err) throw err;
//TODO: do something with the id and token provided
let query = 'SELECT * FROM profiles WHERE accountId IN (SELECT accounts.id FROM accounts WHERE username = ?);';
connection.query(query, [fields.username], (err, results) => {
if (err) throw err;
if (results.length !== 1) {
res.status(400).write(`Failed to find that profile: ${fields.username}`);
res.end();
return;
}
res.status(200).json({
username: fields.username,
gold: results[0].gold,
recruits: results[0].recruits,
soldiers: results[0].soldiers,
spies: results[0].spies,
scientists: results[0].scientists
});
res.end();
});
});
};
}
module.exports = {
profileRequest: profileRequest
}
+17
View File
@@ -1,3 +1,4 @@
# account system
CREATE TABLE IF NOT EXISTS signups (
email VARCHAR(320) UNIQUE,
username VARCHAR(100) UNIQUE,
@@ -34,5 +35,21 @@ CREATE TABLE IF NOT EXISTS passwordRecover (
accountId INTEGER UNSIGNED UNIQUE,
token INTEGER DEFAULT 0,
CONSTRAINT FOREIGN KEY fk_accountId(accountId) REFERENCES accounts(id) ON UPDATE CASCADE ON DELETE CASCADE
);
#profile system
CREATE TABLE IF NOT EXISTS profiles (
id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY UNIQUE,
td TIMESTAMP DEFAULT CURRENT_TIMESTAMP(),
accountId INTEGER UNSIGNED UNIQUE,
gold INTEGER DEFAULT 0,
recruits INTEGER DEFAULT 0,
soldiers INTEGER DEFAULT 0,
spies INTEGER DEFAULT 0,
scientists INTEGER DEFAULT 0,
CONSTRAINT FOREIGN KEY fk_accountId(accountId) REFERENCES accounts(id) ON UPDATE CASCADE ON DELETE CASCADE
);
+2 -1
View File
@@ -1,4 +1,5 @@
DROP TABLE signups;
DROP TABLE accounts;
DROP TABLE sessions;
#DROP TABLE profiles;
DROP TABLE passwordRecover;
DROP TABLE profiles;
+2
View File
@@ -3,6 +3,7 @@ import { BrowserRouter, Switch, Route } from 'react-router-dom';
//include pages
import Home from './pages/home.jsx';
import Profile from './pages/profile.jsx';
import PasswordReset from './pages/password_reset.jsx'
import PageNotFound from './pages/page_not_found.jsx';
@@ -21,6 +22,7 @@ export default class App extends React.Component {
<BrowserRouter>
<Switch>
<Route exact path='/' component={Home} />
<Route path='/profile' component={Profile} />
<Route path='/passwordreset' component={PasswordReset} />
<Route path='*' component={PageNotFound} />
</Switch>
+2 -3
View File
@@ -39,9 +39,8 @@ class Home extends React.Component {
return (
<div className='page'>
<h1 style={{textAlign: 'center', fontSize: '50px', margin: '30px'}}>KINGDOM BATTLES!</h1>
<div className='homePage'>
<div className='sidePanelPage'>
<SidePanel />
<br />
<div className='newsPanel'>
<h1 className='centered'>News</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
@@ -85,7 +84,7 @@ class Home extends React.Component {
//finally return the side panel
return (
<div className='sidePanel'>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Go to <Link to='/profile'>your profile</Link></p>
<PasswordChangePanel />
<Logout />
</div>
+221
View File
@@ -0,0 +1,221 @@
import React from 'react';
import { connect } from 'react-redux';
import { withRouter, Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import queryString from 'query-string';
//panels
import Logout from '../panels/logout.jsx';
import PasswordChange from '../panels/password_change.jsx';
class Profile extends React.Component {
constructor(props) {
super(props);
this.state = {
params: queryString.parse(props.location.search),
username: '',
gold: 0,
recruits: 0,
soldiers: 0,
spies: 0,
scientists: 0,
warning: ''
};
}
componentWillMount() {
this.requestProfileData(this.state.params.username ? this.state.params.username : this.props.username);
}
render() {
let warningStyle = {
display: this.state.warning.length > 0 ? 'flex' : 'none'
};
//side panel stuff
let SidePanel;
if (this.props.id) {
if (this.props.username === this.state.username) {
SidePanel = this.MyProfileSidePanel.bind(this);
} else {
SidePanel = this.NotMyProfileSidePanel.bind(this);
}
} else { //logged out
SidePanel = this.LoggedOutSidePanel.bind(this);
}
//main panel
let MainPanel;
if (this.state.username != '') {
MainPanel = () => {
return (
<div>
<p>Username: {this.state.username}</p>
<p>Gold: {this.state.gold}</p>
<p>Recruits: {this.state.recruits}</p>
<p>Soldiers: {this.state.soldiers}</p>
<p>Spies: {this.state.spies}</p>
<p>Scientists: {this.state.scientists}</p>
</div>
);
}
} else {
MainPanel = () => {
return (
<div>
<p>No profile found!</p>
</div>
);
}
}
return (
<div className='page'>
<h1 style={{textAlign: 'center', fontSize: '50px', margin: '30px'}}>KINGDOM BATTLES!</h1>
<div className='sidePanelPage'>
<SidePanel />
<div className='newsPanel'>
<div className='warning' style={warningStyle}>
<p>{this.state.warning}</p>
</div>
<MainPanel />
</div>
</div>
</div>
);
}
//gameplay functions
requestProfileData(username) {
if (username === undefined || username === '') {
return;
}
//request this profile's info, using my credentials
let formData = new FormData();
formData.append('id', this.props.id);
formData.append('token', this.props.token);
formData.append('username', username);
//build the XHR
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
let json = JSON.parse(xhr.responseText);
this.storeProfile(
json.username,
json.gold,
json.recruits,
json.soldiers,
json.spies,
json.scientists
);
}
else if (xhr.status === 400) {
this.setWarning(xhr.responseText);
}
else if (xhr.status === 404) {
this.props.history.push('/404');
}
}
}
//send
xhr.open('POST', '/profilerequest', true);
xhr.send(formData);
}
storeProfile(username, gold, recruits, soldiers, spies, scientists) {
this.setState({
username: username,
gold: gold,
recruits: recruits,
soldiers: soldiers,
spies: spies,
scientists: scientists
});
}
//panel functions
MyProfileSidePanel() {
//build the password change panel
let PasswordChangePanel;
if (!this.state.changedPassword) {
PasswordChangePanel = () => {
return (<PasswordChange onPasswordChange={() => { this.setState({changedPassword: true}) }} />);
}
} else {
PasswordChangePanel = () => {
return (<p>Password changed!</p>);
}
}
//finally return the side panel
return (
<div className='sidePanel'>
<p>Return <Link to='/'>home</Link></p>
<PasswordChangePanel />
<Logout />
</div>
);
}
NotMyProfileSidePanel() {
//finally return the side panel
return (
<div className='sidePanel'>
<p>Return <Link to='/'>home</Link></p>
<p>Go to <Link to='/profile' onClick={(e) => { e.preventDefault(); this.requestProfileData(this.props.username); }}>your profile</Link></p>
<Logout />
</div>
);
}
LoggedOutSidePanel() {
return (
<div className='sidePanel'>
<p>Return <Link to='/'>home</Link></p>
</div>
);
}
setWarning(s) {
this.setState({
warning: s
});
}
}
Profile.propTypes = {
id: PropTypes.number.isRequired,
email: PropTypes.string.isRequired,
username: PropTypes.string.isRequired,
token: PropTypes.number.isRequired
};
function mapStoreToProps(store) {
return {
id: store.account.id,
email: store.account.email,
username: store.account.username,
token: store.account.token
}
}
function mapDispatchToProps(dispatch) {
return {
//
}
}
Profile = connect(mapStoreToProps, mapDispatchToProps)(Profile);
export default withRouter(Profile);