welcome to mnml
This commit is contained in:
parent
6ff292ff3c
commit
65514f576a
@ -74,6 +74,10 @@ figure {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#mnml {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(min-content, 1fr) 8fr 1fr;
|
||||
@ -189,11 +193,28 @@ button[disabled] {
|
||||
LOGIN
|
||||
*/
|
||||
|
||||
.login {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
margin-bottom: 2em;
|
||||
.welcome {
|
||||
.highlight {
|
||||
color: black;
|
||||
background: @white;
|
||||
border: 1px solid @white;
|
||||
}
|
||||
|
||||
.login {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.options {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
@ -53,10 +53,19 @@
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
|
||||
.login {
|
||||
.welcome .login {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.welcome .options {
|
||||
width: 100%;
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
|
||||
.welcome .options button {
|
||||
flex: 1 0 50%;
|
||||
}
|
||||
|
||||
.timer-container {
|
||||
margin: 0.5em 0 0 0;
|
||||
}
|
||||
|
||||
@ -16,7 +16,10 @@
|
||||
</head>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>js is required to run mnml</noscript>
|
||||
<noscript>
|
||||
<p>js is required to run mnml.</p>
|
||||
<p>this site has no trackers or ads.</p>
|
||||
</noscript>
|
||||
</body>
|
||||
<script src="https://js.stripe.com/v3/"></script>
|
||||
<script src="./index.js"></script>
|
||||
|
||||
@ -1,170 +0,0 @@
|
||||
// eslint-disable-next-line
|
||||
const preact = require('preact');
|
||||
const { Component } = require('preact')
|
||||
const { connect } = require('preact-redux');
|
||||
const linkState = require('linkstate').default;
|
||||
|
||||
const { postData, errorToast } = require('../utils');
|
||||
|
||||
const addState = connect(
|
||||
(state) => {
|
||||
const {
|
||||
ws
|
||||
} = state;
|
||||
function submitLogin(name, password) {
|
||||
postData('/account/login', { name, password })
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.error) return errorToast(data.error);
|
||||
console.log(data.response);
|
||||
ws.connect();
|
||||
})
|
||||
.catch(error => errorToast(error));
|
||||
}
|
||||
|
||||
function submitRegister(name, password, code) {
|
||||
postData('/account/register', { name, password, code })
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.error) return errorToast(data.error);
|
||||
console.log(data.response);
|
||||
ws.connect();
|
||||
})
|
||||
.catch(error => errorToast(error));
|
||||
}
|
||||
|
||||
return {
|
||||
submitLogin,
|
||||
submitRegister,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
class Login extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
login: { name: '', password: '', code: ''},
|
||||
register: { name: '', password: '', confirm: '', code: ''},
|
||||
};
|
||||
|
||||
this.loginSubmit = this.loginSubmit.bind(this);
|
||||
this.registerSubmit = this.registerSubmit.bind(this);
|
||||
}
|
||||
|
||||
loginSubmit(event) {
|
||||
event.preventDefault();
|
||||
console.log(this.state);
|
||||
this.props.submitLogin(this.state.login.name, this.state.login.password);
|
||||
this.setState({ login: { name: '', password: '' }});
|
||||
}
|
||||
|
||||
registerSubmit(event) {
|
||||
event.preventDefault();
|
||||
this.props.submitRegister(this.state.register.name, this.state.register.password, this.state.register.code);
|
||||
this.setState({ register: { name: '', password: '', confirm: '', code: ''}});
|
||||
}
|
||||
|
||||
render() {
|
||||
const registerConfirm = () =>
|
||||
this.state.register.password === this.state.register.confirm;
|
||||
|
||||
const loginDisabled = () => {
|
||||
const { password, name } = this.state.login;
|
||||
return !(password && name);
|
||||
}
|
||||
|
||||
const registerDisabled = () => {
|
||||
const { password, name, code } = this.state.register;
|
||||
return !(registerConfirm() && password && name && code);
|
||||
}
|
||||
|
||||
return (
|
||||
<main>
|
||||
<h1>mnml.gg</h1>
|
||||
<div class="login">
|
||||
<div>mnml is an abstract turn based strategy game</div>
|
||||
<div>free to play</div>
|
||||
<div>no email required</div>
|
||||
</div>
|
||||
<div class="login">
|
||||
<h2>Login</h2>
|
||||
<label for="username">Username</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="email"
|
||||
placeholder="username"
|
||||
tabIndex={1}
|
||||
value={this.state.login.name}
|
||||
onInput={linkState(this, 'login.name')}
|
||||
/>
|
||||
<label for="password">Password</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="password"
|
||||
placeholder="password"
|
||||
tabIndex={2}
|
||||
value={this.state.login.password}
|
||||
onInput={linkState(this, 'login.password')}
|
||||
/>
|
||||
<button
|
||||
class="login-btn"
|
||||
tabIndex={4}
|
||||
disabled={loginDisabled()}
|
||||
onClick={this.loginSubmit}>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
<div class="login">
|
||||
<h2>Register</h2>
|
||||
<label for="username">Username</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="email"
|
||||
placeholder="username"
|
||||
value={this.state.register.name}
|
||||
onInput={linkState(this, 'register.name')}
|
||||
/>
|
||||
<label for="password">Password - min 12 chars</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="password"
|
||||
placeholder="password"
|
||||
value={this.state.register.password}
|
||||
onInput={linkState(this, 'register.password')}
|
||||
/>
|
||||
<label for="confirm">Confirm Password</label>
|
||||
<input
|
||||
class={`${registerConfirm() ? '' : 'red'} login-input`}
|
||||
type="password"
|
||||
placeholder="confirm"
|
||||
value={this.state.register.confirm}
|
||||
onInput={linkState(this, 'register.confirm')}
|
||||
/>
|
||||
<label for="code">Access Code</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="text"
|
||||
placeholder="code"
|
||||
value={this.state.register.code}
|
||||
onInput={linkState(this, 'register.code')}
|
||||
/>
|
||||
<button
|
||||
class="login-btn"
|
||||
disabled={registerDisabled()}
|
||||
onClick={this.registerSubmit}>
|
||||
Register
|
||||
</button>
|
||||
<button
|
||||
class="login-btn"
|
||||
onClick={() => document.location.assign('https://discord.gg/YJJgurM')}>
|
||||
Discord + Codes
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = addState(Login);
|
||||
@ -2,7 +2,7 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
|
||||
const Login = require('./login');
|
||||
const Welcome = require('./welcome');
|
||||
const Game = require('./game');
|
||||
const Instance = require('./instance.component');
|
||||
const Team = require('./team');
|
||||
@ -25,7 +25,7 @@ function Main(props) {
|
||||
} = props;
|
||||
|
||||
if (!account) {
|
||||
return <Login />;
|
||||
return <Welcome />;
|
||||
}
|
||||
|
||||
if (game) {
|
||||
|
||||
69
client/src/components/welcome.about.jsx
Normal file
69
client/src/components/welcome.about.jsx
Normal file
@ -0,0 +1,69 @@
|
||||
// eslint-disable-next-line
|
||||
const preact = require('preact');
|
||||
const { Component } = require('preact')
|
||||
const { connect } = require('preact-redux');
|
||||
const linkState = require('linkstate').default;
|
||||
|
||||
const { postData, errorToast, infoToast } = require('../utils');
|
||||
|
||||
const addState = connect(
|
||||
(state) => {
|
||||
const {
|
||||
ws
|
||||
} = state;
|
||||
|
||||
function submitRegister(name, password, code) {
|
||||
postData('/account/register', { name, password, code })
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.error) return errorToast(data.error);
|
||||
infoToast(data.message);
|
||||
ws.connect();
|
||||
})
|
||||
.catch(error => errorToast(error));
|
||||
}
|
||||
|
||||
return {
|
||||
submitRegister,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function Register(args) {
|
||||
const {
|
||||
submitRegister,
|
||||
navRegister,
|
||||
} = args;
|
||||
|
||||
return (
|
||||
<div class="login">
|
||||
<p>
|
||||
mnml is made deep in the southern hemisphere by ntr & mashy.
|
||||
</p>
|
||||
<p>
|
||||
if you like this game please support the development by buying credits or subscribing.
|
||||
</p>
|
||||
<p>
|
||||
this site has no trackers or ads.
|
||||
</p>
|
||||
<p>
|
||||
you can reach us for feedback and support with the discord and email buttons below.
|
||||
</p>
|
||||
<p>
|
||||
the access code grep842 is currently active.
|
||||
</p>
|
||||
<button
|
||||
class="login-btn"
|
||||
onClick={() => document.location.assign('https://discord.gg/YJJgurM')}>
|
||||
Discord
|
||||
</button>
|
||||
<button
|
||||
class="login-btn"
|
||||
onClick={() => navRegister()}>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(Register);
|
||||
91
client/src/components/welcome.help.jsx
Normal file
91
client/src/components/welcome.help.jsx
Normal file
@ -0,0 +1,91 @@
|
||||
// eslint-disable-next-line
|
||||
const preact = require('preact');
|
||||
const { Component } = require('preact')
|
||||
const { connect } = require('preact-redux');
|
||||
const linkState = require('linkstate').default;
|
||||
|
||||
const { postData, errorToast, infoToast } = require('../utils');
|
||||
|
||||
const addState = connect(
|
||||
(state) => {
|
||||
const {
|
||||
ws
|
||||
} = state;
|
||||
|
||||
function submitRecover(email) {
|
||||
postData('/account/recover', { email })
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.error) return errorToast(data.error);
|
||||
infoToast(data.message);
|
||||
})
|
||||
.catch(error => errorToast(error));
|
||||
}
|
||||
|
||||
return {
|
||||
submitRecover,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const EMAIL_SUBJECT = name => `
|
||||
account support: ${name || 'CHANGEME'}
|
||||
`;
|
||||
|
||||
const EMAIL_BODY = `
|
||||
---
|
||||
include some details regarding your account. ie.
|
||||
- account name
|
||||
- construct names
|
||||
---
|
||||
`;
|
||||
|
||||
function Register(args) {
|
||||
const {
|
||||
submitRecover,
|
||||
} = args;
|
||||
|
||||
const { email } = this.state;
|
||||
|
||||
const buttonSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
submitRecover(email);
|
||||
// this.setState({ email: '' });
|
||||
};
|
||||
|
||||
const buttonDisabled = () => {
|
||||
return !email;
|
||||
};
|
||||
|
||||
const supportLink = encodeURI(`mailto:humans@mnml.gg?subject=${EMAIL_SUBJECT(email)}&body=${EMAIL_BODY}`);
|
||||
|
||||
return (
|
||||
<div class="login">
|
||||
<p>
|
||||
send a recovery email to your account's confirmed email address.
|
||||
</p>
|
||||
<p>
|
||||
if you have not set and confirmed an email address for your account
|
||||
please contact support.
|
||||
</p>
|
||||
<label for="username">Account Email</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="email"
|
||||
placeholder="player@mnml.gg"
|
||||
value={email}
|
||||
onInput={linkState(this, 'email')}
|
||||
/>
|
||||
<button
|
||||
class="login-btn"
|
||||
disabled={buttonDisabled()}
|
||||
onClick={buttonSubmit}> Send Recovery Email
|
||||
</button>
|
||||
<button>
|
||||
<a href={supportLink}>✉ support</a>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(Register);
|
||||
61
client/src/components/welcome.jsx
Normal file
61
client/src/components/welcome.jsx
Normal file
@ -0,0 +1,61 @@
|
||||
// eslint-disable-next-line
|
||||
const preact = require('preact');
|
||||
|
||||
const Login = require('./welcome.login');
|
||||
const Register = require('./welcome.register');
|
||||
const Help = require('./welcome.help');
|
||||
const About = require('./welcome.about');
|
||||
|
||||
function Welcome() {
|
||||
const page = this.state.page || 'login';
|
||||
|
||||
const navRegister = () => this.setState({ page: 'register' });
|
||||
const pageEl = () => {
|
||||
if (page === 'login') return <Login />;
|
||||
if (page === 'register') return <Register />;
|
||||
if (page === 'about') return <About navRegister={navRegister} />;
|
||||
if (page === 'help') return <Help />;
|
||||
return false;
|
||||
};
|
||||
|
||||
return (
|
||||
<main class="welcome">
|
||||
<h1>mnml.gg</h1>
|
||||
<div class="login">
|
||||
<div>mnml is an abstract turn based strategy game</div>
|
||||
<div>free to play</div>
|
||||
<div>no email required</div>
|
||||
<div>glhf</div>
|
||||
</div>
|
||||
<div class="options">
|
||||
<button
|
||||
class={`login-btn ${page === 'login' ? 'highlight' : ''}`}
|
||||
disabled={page === 'login'}
|
||||
onClick={() => this.setState({ page: 'login' })}>
|
||||
Login
|
||||
</button>
|
||||
<button
|
||||
class={`login-btn ${page === 'register' ? 'highlight' : ''}`}
|
||||
disabled={page === 'register'}
|
||||
onClick={() => this.setState({ page: 'register' })}>
|
||||
Register
|
||||
</button>
|
||||
<button
|
||||
class={`login-btn ${page === 'about' ? 'highlight' : ''}`}
|
||||
disabled={page === 'about'}
|
||||
onClick={() => this.setState({ page: 'about' })}>
|
||||
About
|
||||
</button>
|
||||
<button
|
||||
class={`login-btn ${page === 'help' ? 'highlight' : ''}`}
|
||||
disabled={page === 'help'}
|
||||
onClick={() => this.setState({ page: 'help' })}>
|
||||
Help
|
||||
</button>
|
||||
</div>
|
||||
{pageEl()}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = Welcome;
|
||||
80
client/src/components/welcome.login.jsx
Normal file
80
client/src/components/welcome.login.jsx
Normal file
@ -0,0 +1,80 @@
|
||||
// eslint-disable-next-line
|
||||
const preact = require('preact');
|
||||
const { Component } = require('preact')
|
||||
const { connect } = require('preact-redux');
|
||||
const linkState = require('linkstate').default;
|
||||
|
||||
const { postData, errorToast } = require('../utils');
|
||||
|
||||
const addState = connect(
|
||||
(state) => {
|
||||
const {
|
||||
ws
|
||||
} = state;
|
||||
function submitLogin(name, password) {
|
||||
postData('/account/login', { name, password })
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.error) return errorToast(data.error);
|
||||
console.log(data.message);
|
||||
ws.connect();
|
||||
})
|
||||
.catch(error => errorToast(error));
|
||||
}
|
||||
|
||||
return {
|
||||
submitLogin,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
function Login(args) {
|
||||
const {
|
||||
submitLogin,
|
||||
} = args;
|
||||
|
||||
const { password, name } = this.state;
|
||||
|
||||
const loginSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
submitLogin(name, password);
|
||||
this.setState({ name: '', password: '' });
|
||||
};
|
||||
|
||||
const loginDisabled = () => {
|
||||
return !(password && name);
|
||||
};
|
||||
|
||||
return (
|
||||
<div class="login">
|
||||
<label for="username">Username</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="email"
|
||||
placeholder="username"
|
||||
tabIndex={1}
|
||||
value={name}
|
||||
onInput={linkState(this, 'name')}
|
||||
/>
|
||||
<label for="password">Password</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="password"
|
||||
placeholder="password"
|
||||
tabIndex={2}
|
||||
value={password}
|
||||
onInput={linkState(this, 'password')}
|
||||
/>
|
||||
<button
|
||||
class="login-btn"
|
||||
tabIndex={4}
|
||||
disabled={loginDisabled()}
|
||||
onClick={loginSubmit}>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(Login);
|
||||
96
client/src/components/welcome.register.jsx
Normal file
96
client/src/components/welcome.register.jsx
Normal file
@ -0,0 +1,96 @@
|
||||
// eslint-disable-next-line
|
||||
const preact = require('preact');
|
||||
const { Component } = require('preact')
|
||||
const { connect } = require('preact-redux');
|
||||
const linkState = require('linkstate').default;
|
||||
|
||||
const { postData, errorToast, infoToast } = require('../utils');
|
||||
|
||||
const addState = connect(
|
||||
(state) => {
|
||||
const {
|
||||
ws
|
||||
} = state;
|
||||
|
||||
function submitRegister(name, password, code) {
|
||||
postData('/account/register', { name, password, code })
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.error) return errorToast(data.error);
|
||||
infoToast(data.message);
|
||||
ws.connect();
|
||||
})
|
||||
.catch(error => errorToast(error));
|
||||
}
|
||||
|
||||
return {
|
||||
submitRegister,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function Register(args) {
|
||||
const {
|
||||
submitRegister,
|
||||
} = args;
|
||||
|
||||
const { password, confirm, name, code } = this.state;
|
||||
|
||||
const registerSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
submitRegister(name, password, code);
|
||||
// this.setState({ name: '', password: '', confirm: '', code: ''});
|
||||
}
|
||||
|
||||
const registerConfirm = () =>
|
||||
password === confirm;
|
||||
|
||||
const registerDisabled = () => {
|
||||
return !(registerConfirm() && password && name && code);
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="login">
|
||||
<label for="username">Username</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="email"
|
||||
placeholder="username"
|
||||
value={this.state.name}
|
||||
onInput={linkState(this, 'name')}
|
||||
/>
|
||||
<label for="password">Password - min 12 chars</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="password"
|
||||
placeholder="password"
|
||||
value={this.state.password}
|
||||
onInput={linkState(this, 'password')}
|
||||
/>
|
||||
<label for="confirm">Confirm Password</label>
|
||||
<input
|
||||
class={`${registerConfirm() ? '' : 'red'} login-input`}
|
||||
type="password"
|
||||
placeholder="confirm"
|
||||
value={this.state.confirm}
|
||||
onInput={linkState(this, 'confirm')}
|
||||
/>
|
||||
<label for="code">Access Code</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="text"
|
||||
placeholder="code"
|
||||
value={this.state.code}
|
||||
onInput={linkState(this, 'code')}
|
||||
/>
|
||||
<button
|
||||
class="login-btn"
|
||||
disabled={registerDisabled()}
|
||||
onClick={registerSubmit}>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(Register);
|
||||
@ -9,6 +9,7 @@ exports.up = async knex => {
|
||||
table.string('token', 64)
|
||||
.notNullable()
|
||||
.index();
|
||||
|
||||
table.timestamp('token_expiry').notNullable();
|
||||
|
||||
table.bigInteger('balance')
|
||||
|
||||
@ -42,10 +42,13 @@ pub enum Mail {
|
||||
fn recover(email: &String, name: &String, token: &String) -> SendableEmail {
|
||||
let body = format!("{:},
|
||||
the link below will recover your account.
|
||||
please change your password immediately in the account page
|
||||
please change your password immediately in the account page.
|
||||
this link will expire in 48 hours or once used.
|
||||
|
||||
http://mnml.gg/api/account/recover?recover_token={:}
|
||||
|
||||
glhf", name, token);
|
||||
glhf
|
||||
--mnml", name, token);
|
||||
|
||||
Email::builder()
|
||||
.from("machines@mnml.gg")
|
||||
@ -62,7 +65,8 @@ fn confirm(email: &String, name: &String, token: &String) -> SendableEmail {
|
||||
please click the link below to confirm your email
|
||||
http://mnml.gg/api/account/email/confirm?confirm_token={:}
|
||||
|
||||
glhf", name, token);
|
||||
glhf
|
||||
--mnml", name, token);
|
||||
|
||||
Email::builder()
|
||||
.from("machines@mnml.gg")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user