Compare commits
2 commits
d47069cef2
...
31c578be30
Author | SHA1 | Date | |
---|---|---|---|
|
31c578be30 | ||
|
2c90b87818 |
6 changed files with 162 additions and 101 deletions
|
@ -4,8 +4,13 @@ volumes:
|
||||||
frontend_home:
|
frontend_home:
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
# Frontend
|
||||||
ui:
|
ui:
|
||||||
build: ui/docker
|
build:
|
||||||
|
context: ui/docker
|
||||||
|
args:
|
||||||
|
NONROOT_UID: 1000
|
||||||
|
NONROOT_GID: 1000
|
||||||
restart: 'unless-stopped'
|
restart: 'unless-stopped'
|
||||||
volumes:
|
volumes:
|
||||||
- "frontend_home:/home/node"
|
- "frontend_home:/home/node"
|
||||||
|
@ -13,10 +18,12 @@ services:
|
||||||
ports:
|
ports:
|
||||||
- 8000:8000
|
- 8000:8000
|
||||||
|
|
||||||
|
# Backend
|
||||||
api:
|
api:
|
||||||
build: api
|
build: api
|
||||||
restart: 'no'
|
restart: 'no'
|
||||||
|
|
||||||
|
# Common Proxy
|
||||||
dev-proxy:
|
dev-proxy:
|
||||||
build: dev-proxy
|
build: dev-proxy
|
||||||
restart: 'no'
|
restart: 'no'
|
||||||
|
|
|
@ -1,13 +1,28 @@
|
||||||
FROM node:lts-alpine
|
FROM node:lts-alpine
|
||||||
LABEL maintainer="joern-michael.miehe@lenaisten.de"
|
LABEL maintainer="joern-michael.miehe@lenaisten.de"
|
||||||
|
|
||||||
|
# vue services directory
|
||||||
WORKDIR /srv/vue
|
WORKDIR /srv/vue
|
||||||
|
|
||||||
|
# install vue cli
|
||||||
RUN set -ex; \
|
RUN set -ex; \
|
||||||
yarn global add @vue/cli
|
yarn global add @vue/cli
|
||||||
|
|
||||||
|
# user setup
|
||||||
|
ARG NONROOT_UID=1000
|
||||||
|
ARG NONROOT_GID=1000
|
||||||
|
|
||||||
|
# recycle node user
|
||||||
|
RUN set -ex; \
|
||||||
|
deluser --remove-home node; \
|
||||||
|
addgroup -g ${NONROOT_GID} node; \
|
||||||
|
adduser --disabled-password --gecos '' --uid "${NONROOT_UID}" --ingroup node node
|
||||||
|
|
||||||
|
# user change
|
||||||
USER node
|
USER node
|
||||||
|
|
||||||
|
# persistent home directory
|
||||||
VOLUME [ "/home/node" ]
|
VOLUME [ "/home/node" ]
|
||||||
|
|
||||||
|
# run vue ui
|
||||||
CMD [ "vue", "ui", "-H", "0.0.0.0" ]
|
CMD [ "vue", "ui", "-H", "0.0.0.0" ]
|
||||||
|
|
|
@ -2,121 +2,45 @@
|
||||||
<div class="admin">
|
<div class="admin">
|
||||||
<h1>Geburtstags-Tool</h1>
|
<h1>Geburtstags-Tool</h1>
|
||||||
|
|
||||||
<form v-if="!authenticated" @submit="login">
|
<Login v-if="step === 1" @success="step=2" />
|
||||||
<h2>Admin-Login für Geburtstagstool</h2>
|
<Input v-else-if="step === 2" @success="step=3" />
|
||||||
<input type="text" placeholder="Benutzername" v-model="apiCreds.name" required />
|
<Preview v-else @failure="step=2" />
|
||||||
<input type="password" placeholder="Passwort" v-model="apiCreds.pass" required />
|
|
||||||
|
|
||||||
<button>Einloggen</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form v-else-if="!reviewed" @submit="review">
|
|
||||||
<h2>Dateneingabe</h2>
|
|
||||||
|
|
||||||
<h3>Empfänger</h3>
|
|
||||||
|
|
||||||
<select v-model="recipient.title" required>
|
|
||||||
<option value selected>Geschlecht auswählen …</option>
|
|
||||||
<option value="m">männlich</option>
|
|
||||||
<option value="f">weiblich</option>
|
|
||||||
</select>
|
|
||||||
<input type="text" placeholder="Vorname" v-model="recipient.first" required />
|
|
||||||
<input type="text" placeholder="Nachname" v-model="recipient.last" required />
|
|
||||||
<input type="text" placeholder="E-Mail Adresse" v-model="recipient.email" required />
|
|
||||||
|
|
||||||
<h3>Mail</h3>
|
|
||||||
|
|
||||||
<input type="text" placeholder="Betreff" v-model="mail.subject" required />
|
|
||||||
<textarea v-model="mail.body" />
|
|
||||||
|
|
||||||
<button>Vorschau</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form v-else @submit="send" @reset="back">
|
|
||||||
<h2>Vorschau</h2>
|
|
||||||
|
|
||||||
<button>Sieht gesund aus. Absenden!</button>
|
|
||||||
<button type="reset" class="back">Da fehlt noch was. Zurück!</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Login from './admin/Login.vue'
|
||||||
|
import Input from './admin/Input.vue'
|
||||||
|
import Preview from './admin/Preview.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Admin",
|
name: "Admin",
|
||||||
|
|
||||||
data: () => ({
|
components: {
|
||||||
authenticated: false,
|
Login,
|
||||||
reviewed: false,
|
Input,
|
||||||
|
Preview,
|
||||||
apiCreds: {
|
|
||||||
name: "",
|
|
||||||
pass: "",
|
|
||||||
},
|
|
||||||
|
|
||||||
recipient: {
|
|
||||||
title: "",
|
|
||||||
first: "",
|
|
||||||
last: "",
|
|
||||||
email: "",
|
|
||||||
},
|
|
||||||
|
|
||||||
mail: {
|
|
||||||
subject: "Happy Birthday! Es gibt etwas zu feiern!",
|
|
||||||
body: `###ANREDE### ###VORNAME###,
|
|
||||||
heute übersenden wir Dir eine Email, weil es etwas zu feiern gibt.
|
|
||||||
Zum Geburtstag wünschen wir Dir alles Gute.
|
|
||||||
|
|
||||||
Deine Überraschungskarte kannst Du hier abrufen:
|
|
||||||
###PHOTO_LINK###
|
|
||||||
|
|
||||||
Vergiss aber nicht, Deine Lautsprecher einzuschalten, sonst verpasst Du etwas ;)
|
|
||||||
|
|
||||||
Lenaistische Grüße,
|
|
||||||
Deine Lenaisten`,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
login(event) {
|
|
||||||
this.authenticated = true;
|
|
||||||
event.preventDefault();
|
|
||||||
},
|
|
||||||
|
|
||||||
review(event) {
|
|
||||||
this.reviewed = true;
|
|
||||||
event.preventDefault();
|
|
||||||
},
|
|
||||||
|
|
||||||
send(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
},
|
|
||||||
|
|
||||||
back(event) {
|
|
||||||
if (this.reviewed) {
|
|
||||||
this.reviewed = false;
|
|
||||||
} else {
|
|
||||||
this.authenticated = false;
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
step: 1,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style>
|
||||||
div.admin {
|
div.admin {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-width: 1024px;
|
max-width: 1024px;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
div.admin label {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
div.admin input,
|
||||||
select,
|
div.admin select,
|
||||||
textarea {
|
div.admin textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 12px 20px;
|
padding: 12px 20px;
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
|
@ -124,13 +48,13 @@ textarea {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
div.admin textarea {
|
||||||
height: 250px;
|
height: 250px;
|
||||||
min-height: 250px;
|
min-height: 250px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
div.admin button {
|
||||||
background-color: #4caf50;
|
background-color: #4caf50;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 14px 20px;
|
padding: 14px 20px;
|
||||||
|
@ -140,11 +64,11 @@ button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.back {
|
div.admin button.back {
|
||||||
background-color: #f44336;
|
background-color: #f44336;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
div.admin button:hover {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
60
ui/src/components/admin/Input.vue
Normal file
60
ui/src/components/admin/Input.vue
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<template>
|
||||||
|
<form @submit="check">
|
||||||
|
<h2>Dateneingabe</h2>
|
||||||
|
|
||||||
|
<h3>Empfänger</h3>
|
||||||
|
|
||||||
|
<select v-model="recipient.title" required>
|
||||||
|
<option value selected>Geschlecht auswählen …</option>
|
||||||
|
<option value="m">männlich</option>
|
||||||
|
<option value="f">weiblich</option>
|
||||||
|
</select>
|
||||||
|
<input type="text" placeholder="Vorname" v-model="recipient.first" required />
|
||||||
|
<input type="text" placeholder="Nachname" v-model="recipient.last" required />
|
||||||
|
<input type="text" placeholder="E-Mail Adresse" v-model="recipient.email" required />
|
||||||
|
|
||||||
|
<h3>Mail</h3>
|
||||||
|
|
||||||
|
<input type="text" placeholder="Betreff" v-model="mail.subject" required />
|
||||||
|
<textarea v-model="mail.body" />
|
||||||
|
|
||||||
|
<button>Vorschau</button>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Input",
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
recipient: {
|
||||||
|
title: "",
|
||||||
|
first: "",
|
||||||
|
last: "",
|
||||||
|
email: "",
|
||||||
|
},
|
||||||
|
|
||||||
|
mail: {
|
||||||
|
subject: "Happy Birthday! Es gibt etwas zu feiern!",
|
||||||
|
body: `###ANREDE### ###VORNAME###,
|
||||||
|
heute übersenden wir Dir eine Email, weil es etwas zu feiern gibt.
|
||||||
|
Zum Geburtstag wünschen wir Dir alles Gute.
|
||||||
|
|
||||||
|
Deine Überraschungskarte kannst Du hier abrufen:
|
||||||
|
###PHOTO_LINK###
|
||||||
|
|
||||||
|
Vergiss aber nicht, Deine Lautsprecher einzuschalten, sonst verpasst Du etwas ;)
|
||||||
|
|
||||||
|
Lenaistische Grüße,
|
||||||
|
Deine Lenaisten`,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
check(event) {
|
||||||
|
this.$emit('success', this.recipient, this.mail);
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
30
ui/src/components/admin/Login.vue
Normal file
30
ui/src/components/admin/Login.vue
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<template>
|
||||||
|
<form @submit="check">
|
||||||
|
<h2>Admin-Login für Geburtstagstool</h2>
|
||||||
|
<input type="text" placeholder="Benutzername" v-model="apiCreds.name" required />
|
||||||
|
<input type="password" placeholder="Passwort" v-model="apiCreds.pass" required />
|
||||||
|
|
||||||
|
<button>Einloggen</button>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Login",
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
apiCreds: {
|
||||||
|
name: "",
|
||||||
|
pass: "",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
check(event) {
|
||||||
|
this.$emit('success', this.apiCreds)
|
||||||
|
// this.$emit('failure')
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
25
ui/src/components/admin/Preview.vue
Normal file
25
ui/src/components/admin/Preview.vue
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<template>
|
||||||
|
<form @submit="check">
|
||||||
|
<h2>Vorschau</h2>
|
||||||
|
|
||||||
|
<button value="good">Sieht gesund aus. Absenden!</button>
|
||||||
|
<button value="bad" class="back">Da fehlt noch was. Zurück!</button>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Preview",
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
check(event) {
|
||||||
|
if (event.submitter.value === "good") {
|
||||||
|
this.$emit("success");
|
||||||
|
} else {
|
||||||
|
this.$emit("failure");
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
Loading…
Reference in a new issue