api: Use semantic-ui-css for api-rendered views (account pages)

This commit is contained in:
Paul Bienkowski 2021-05-01 15:47:22 +02:00
parent 817de8fae5
commit 9a7043ea71
12 changed files with 100 additions and 11771 deletions

11641
api/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -55,6 +55,7 @@
"pug": "^3.0.0", "pug": "^3.0.0",
"request": "2.88.2", "request": "2.88.2",
"sanitize-filename": "^1.6.3", "sanitize-filename": "^1.6.3",
"semantic-ui-css": "^2.4.1",
"slug": "^3.5.2", "slug": "^3.5.2",
"turf": "^3.0.14", "turf": "^3.0.14",
"underscore": "^1.12.0" "underscore": "^1.12.0"

View file

@ -27,6 +27,7 @@ app.use(bodyParser.urlencoded({ limit: '50mb', extended: false }));
app.use(require('method-override')()); app.use(require('method-override')());
app.use(express.static(path.join(__dirname, 'public'))); app.use(express.static(path.join(__dirname, 'public')));
app.use('/semantic-ui', express.static(path.join(__dirname, '..', 'node_modules', 'semantic-ui-css')));
app.use(session({ secret: config.cookieSecret, cookie: { maxAge: 10 * 60 * 1000 }, resave: false, saveUninitialized: false })); app.use(session({ secret: config.cookieSecret, cookie: { maxAge: 10 * 60 * 1000 }, resave: false, saveUninitialized: false }));
app.use(passport.initialize()); app.use(passport.initialize());

View file

@ -74,7 +74,7 @@ router.post(
description = 'Your account is not yet verified, please check your email or start the password recovery.'; description = 'Your account is not yet verified, please check your email or start the password recovery.';
} }
return res.render('message', { type: 'error', title: 'Login failed', description }); return res.render('message', { type: 'negative', title: 'Login failed', description });
}, },
wrapRoute((req, res, next) => { wrapRoute((req, res, next) => {
if (!req.user) { if (!req.user) {
@ -86,7 +86,7 @@ router.post(
req.session.next = null; req.session.next = null;
return; return;
} }
return res.render('message', { type: 'success', title: 'You are logged in.' }); return res.render('message', { type: 'positive', title: 'You are logged in.', showFrontendLink: true });
}), }),
); );
@ -94,7 +94,7 @@ router.get(
'/login', '/login',
wrapRoute(async (req, res) => { wrapRoute(async (req, res) => {
if (req.user) { if (req.user) {
return res.render('message', { type: 'success', title: 'You are already logged in.' }); return res.render('message', { type: 'positive', title: 'You are already logged in.' });
} }
return res.render('login'); return res.render('login');
@ -267,7 +267,7 @@ router.post(
if (expiresAt < new Date().getTime()) { if (expiresAt < new Date().getTime()) {
return res.status(400).render('message', { return res.status(400).render('message', {
type: 'error', type: 'negative',
title: 'Expired', title: 'Expired',
description: 'Your authorization has expired. Please go back and retry the process.', description: 'Your authorization has expired. Please go back and retry the process.',
}); });
@ -450,7 +450,7 @@ router
await accountService.register(req.body); await accountService.register(req.body);
return res.render('message', { return res.render('message', {
type: 'success', type: 'positive',
title: 'Registration successful', title: 'Registration successful',
description: 'Please check your email for verification instructions.', description: 'Please check your email for verification instructions.',
}); });
@ -469,7 +469,7 @@ router.get(
wrapRoute(async (req, res) => { wrapRoute(async (req, res) => {
await accountService.verifyEmail(req.query); await accountService.verifyEmail(req.query);
return res.render('message', { return res.render('message', {
type: 'success', type: 'positive',
title: 'Verification successful', title: 'Verification successful',
description: 'You can now log in.', description: 'You can now log in.',
showLoginButton: true, showLoginButton: true,
@ -488,7 +488,7 @@ router
wrapRoute(async (req, res) => { wrapRoute(async (req, res) => {
await accountService.forgotPassword(req.body); await accountService.forgotPassword(req.body);
res.render('message', { res.render('message', {
type: 'success', type: 'positive',
title: 'Recovery mail sent', title: 'Recovery mail sent',
description: 'Please check your inbox for password recovery instructions.', description: 'Please check your inbox for password recovery instructions.',
}); });
@ -509,7 +509,7 @@ router
wrapRoute(async (req, res) => { wrapRoute(async (req, res) => {
await accountService.resetPassword(req.body); await accountService.resetPassword(req.body);
return res.render('message', { return res.render('message', {
type: 'success', type: 'positive',
title: 'Password reset successful', title: 'Password reset successful',
description: 'You can now log in.', description: 'You can now log in.',
showLoginButton: true, showLoginButton: true,

View file

@ -8,10 +8,10 @@ block content
You are about to confirm a login to client #[b= clientTitle]. You have 2 You are about to confirm a login to client #[b= clientTitle]. You have 2
minutes time for your decision. minutes time for your decision.
.authorization .ui.grid.two.columns
form(method="post", action="authorize/decline") form.column(method="post", action="authorize/decline")
button(type="submit", class="red") Decline button.ui.button.fluid.red(type="submit", class="red") Decline
form(method="post", action="authorize/approve") form.column(method="post", action="authorize/approve")
button(type="submit", class="green") Approve button.ui.button.fluid.green(type="submit", class="green") Approve

View file

@ -4,9 +4,9 @@ block title
| Reset Password | Reset Password
block content block content
form(method="post") form.ui.form(method="post")
fieldset .field
label(for="email") E-Mail Address label(for="email") E-Mail Address
input(id="email", name="email") input(id="email", name="email")
button(type="submit") Send recovery mail button.ui.button.primary(type="submit") Send recovery mail

View file

@ -1,143 +1,32 @@
html html
head head
base(href=baseUrl) base(href=baseUrl)
title title block title
block title
| Authorization Server | Authorization Server
link(rel="stylesheet", href="/semantic-ui/semantic.min.css")
style. style.
html, body { body > main > header {
font-family: "Roboto"; margin: 16px 0;
font-size: 11pt;
background: #FAFAFE;
}
main {
max-width: 30rem;
margin: 2rem auto;
background: white;
border: 1px solid #DDD;
padding: 2rem;
border-radius: 6px;
}
h1 {
font-weight: 500;
text-align: center;
}
input, button {
font: inherit;
}
input {
background: white;
height: 2rem;
display: block;
width: 100%;
margin: 0.5rem 0;
padding: 0 0.5rem;
border: 1px solid #DDD;
}
input:focus {
border: 1px solid #000;
outline: none;
}
button {
padding: 0 1rem;
height: 2.5rem;
background: #dedede;
font-size: inherit;
border: 0;
border-radius: 6px;
color: black;
font-weight: 500;
cursor: pointer;
}
fieldset {
border: none;
padding: 0;
margin: 1rem 0;
}
.message.error {
color: red;
}
.authorization {
display: flex;
}
.authorization form {
flex: 1 1 0;
}
.authorization form:first-child {
margin-right: 2rem;
}
.authorization form button {
width: 100%;
}
button.red {
background: #b33f3f;
color: white;
}
button.red:hover {
background: #ff7878;
}
button.green {
background: #41b141;
color: white;
}
button.green:hover {
background: #83d283;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
align-items: center;
padding-bottom: 1rem;
margin-bottom: 1rem;
border-bottom: 1px solid #DDD;
}
nav ul li {
flex: 1 1 0;
text-align: center;
}
nav ul li a {
color: #999;
text-decoration: none;
}
nav ul li a:hover {
color: #444;
}
nav header {
text-align: center;
font-weight: 500;
margin-bottom: 1rem;
} }
body body
main main.ui.container
nav header
header OpenBikeSensor Account Pages nav.ui.menu
ul a.item(href=mainFrontendUrl, title="Back to Portal")
if mainFrontendUrl i.icon.arrow.left
li: a(href=mainFrontendUrl) Back to Portal .header.item OpenBikeSensor Account
if !user .right.menu
li: a(href="login") Login if mainFrontendUrl
li: a(href="register") Register if !user
if user a.item(href="login") Login
li: a(href="logout") Logout a.item(href="register") Register
header: h1 if user
block title a.item(href="logout") Logout
block content div.ui.grid.centered
div.eight.wide.column
h2.ui.header
block title
block content

View file

@ -4,17 +4,17 @@ block title
| Login | Login
block content block content
form(method="post") form.ui.form(method="post")
fieldset .field
label(for="email") E-Mail Address label(for="email") E-Mail Address
input(id="email", name="email") input(id="email", name="email")
fieldset .field
label(for="password") Password label(for="password") Password
input(name="password", type="password") input(name="password", type="password")
if badCredentials if badCredentials
p.message.error Invalid login credentials, please try again. p.ui.negative.message Invalid login credentials, please try again.
button(type="submit", style="margin-right: 2rem") Login button.ui.button.primary(type="submit", style="margin-right: 2rem") Login
a(href="forgot-password") I forgot my password a.ui(href="forgot-password") I forgot my password

View file

@ -5,4 +5,4 @@ block title
block content block content
form(method="post", action="logout") form(method="post", action="logout")
button(type="submit", class="red") Log out now button.ui.button(type="submit") Log out now

View file

@ -5,7 +5,10 @@ block title
block content block content
if description if description
div(class="message " + type)= description div(class="ui message " + type)= description
if showLoginButton if showLoginButton
p: a(href="login") Go to login p: a(href="login") Go to login
if showFrontendLink
p: a(href=mainFrontendUrl) Back to Portal

View file

@ -4,22 +4,22 @@ block title
| Register | Register
block content block content
form(method="post") form.ui.form(method="post")
fieldset .field
label(for="username") Username label(for="username") Username
input(id="username", name="username") input(id="username", name="username")
p.form-hint At least 3 characters, alphanumerical, must be unique p.form-hint At least 3 characters, alphanumerical, must be unique
fieldset .field
label(for="email") E-Mail Address label(for="email") E-Mail Address
input(id="email", name="email", type="email") input(id="email", name="email", type="email")
fieldset .field
label(for="password") Password label(for="password") Password
input(id="password", name="password", type="password") input(id="password", name="password", type="password")
fieldset .field
label(for="confirmPassword") Confirm Password label(for="confirmPassword") Confirm Password
input(id="confirmPassword", name="confirmPassword", type="password") input(id="confirmPassword", name="confirmPassword", type="password")
button(type="submit") Register button.ui.button.primary(type="submit") Register

View file

@ -4,15 +4,15 @@ block title
| Reset Password | Reset Password
block content block content
form(method="post") form.ui.form(method="post")
input(type="hidden", name="token", value=token) input(type="hidden", name="token", value=token)
fieldset .field
label(for="password") New Password label(for="password") New Password
input(id="password", name="password", type="password") input(id="password", name="password", type="password")
fieldset .field
label(for="confirmPassword") Confirm Password label(for="confirmPassword") Confirm Password
input(id="confirmPassword", name="confirmPassword", type="password") input(id="confirmPassword", name="confirmPassword", type="password")
button(type="submit") Set new password button.ui.button.primary(type="submit") Set new password