Viewing profiles works, profiles not yet created
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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')) );
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
@@ -1,4 +1,5 @@
|
||||
DROP TABLE signups;
|
||||
DROP TABLE accounts;
|
||||
DROP TABLE sessions;
|
||||
#DROP TABLE profiles;
|
||||
DROP TABLE passwordRecover;
|
||||
DROP TABLE profiles;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user