feature/3_env_file #9
3
.gitignore
vendored
3
.gitignore
vendored
@ -182,4 +182,5 @@ docs/_book
|
|||||||
test/
|
test/
|
||||||
|
|
||||||
/package-lock.json
|
/package-lock.json
|
||||||
/yarn.lock
|
/yarn.lock
|
||||||
|
/public/env.js
|
21
README.md
21
README.md
@ -1,3 +1,22 @@
|
|||||||
# @lfk/selfservice
|
# @lfk/selfservice
|
||||||
|
|
||||||
runner selfservice portal
|
runner selfservice portal
|
||||||
|
|
||||||
|
## ⚡ Development
|
||||||
|
### Requirements
|
||||||
|
- Node.js v14.15.0 or newer
|
||||||
|
- yarn package manager >= v1.22.10 < 2
|
||||||
|
|
||||||
|
### Recommended Extensions
|
||||||
|
- will be automatically recommended via `./vscode/extensions.json`
|
||||||
|
- we also provide a config for i18n-ally in the `./vscode/` folder
|
||||||
|
|
||||||
|
### Fastest Dev Environment
|
||||||
|
- You can install the [Remote - Containers](https://github.com/Microsoft/vscode-remote-release) extension and use all recommended extensions and editor settings via the provided `./devcontainer/` config
|
||||||
|
|
||||||
|
## 🔨 environment config
|
||||||
|
- copy the `/public/env.sample.js` file to `/public/env.js`
|
||||||
|
- set the required environment variables
|
||||||
|
- `documentserver_key`: url to the [document server](https://git.odit.services/lfk/document-server) instance
|
||||||
|
- `baseurl`: url to the main instance
|
||||||
|
- see [@lfk/deployment](https://git.odit.services/lfk/deployment) for a complete deployment guide
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
<body class="dark:bg-gray-900 text-black dark:text-white p-0">
|
<body class="dark:bg-gray-900 text-black dark:text-white p-0">
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
<script src="/env.js"></script>
|
||||||
<script type="module" src="/src/main.js"></script>
|
<script type="module" src="/src/main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"got": "^11.8.2",
|
"got": "^11.8.2",
|
||||||
|
"marked": "^2.0.1",
|
||||||
"redaxios": "^0.4.1",
|
"redaxios": "^0.4.1",
|
||||||
"toastify-js": "^1.9.3",
|
"toastify-js": "^1.9.3",
|
||||||
"validator": "^13.5.2",
|
"validator": "^13.5.2",
|
||||||
|
10
public/env.sample.js
Normal file
10
public/env.sample.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const config = {
|
||||||
|
// required
|
||||||
|
documentserver_key: '',
|
||||||
|
// required
|
||||||
|
baseurl: '',
|
||||||
|
// optional, will fallback to /imprint
|
||||||
|
url_imprint: '',
|
||||||
|
// optional, will fallback to /privacy
|
||||||
|
url_privacy: ''
|
||||||
|
};
|
1
public/imprint_en.md
Normal file
1
public/imprint_en.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
TODO:
|
1
public/privacy_en.md
Normal file
1
public/privacy_en.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
TODO:
|
29
src/components/EnvError.vue
Normal file
29
src/components/EnvError.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<section class="container px-4 py-32 mx-auto">
|
||||||
|
<div class="w-full mx-auto lg:w-1/3">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="h-20 feather feather-alert-triangle"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0zM12 9v4M12 17h.01"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<p
|
||||||
|
class="mt-5 mb-3 text-xl font-bold text-black dark:text-gray-50 md:text-2xl"
|
||||||
|
>{{ $t('configuration_error') }}</p>
|
||||||
|
<p class="mb-3 text-base font-medium text-gray-700 dark:text-gray-400">
|
||||||
|
{{ $t('the_system_is_not_properly_configured_please_contact_the_system_administrator_for_help') }}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{{ $t('if_you_are_the_system_administrator_please_refer_to_the_official_product_documentation_readme_for_configuration_guidance') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
@ -14,16 +14,26 @@
|
|||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener,noreferrer"
|
rel="noopener,noreferrer"
|
||||||
href="/impressum/"
|
:href="[[imprint_url]]"
|
||||||
class="ml-3 text-gray-400 underline"
|
class="ml-3 text-gray-400 underline"
|
||||||
>Impressum</a>
|
>Impressum</a>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener,noreferrer"
|
rel="noopener,noreferrer"
|
||||||
href="/datenschutz/"
|
:href="[[privacy_url]]"
|
||||||
class="ml-3 text-gray-400 underline"
|
class="ml-3 text-gray-400 underline"
|
||||||
>Datenschutzerklärung</a>
|
>Datenschutzerklärung</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
imprint_url: config.url_imprint || "/imprint/"
|
||||||
|
, privacy_url: config.url_privacy || "/privacy/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
38
src/components/Imprint.vue
Normal file
38
src/components/Imprint.vue
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<section class="container px-4 py-24 mx-auto">
|
||||||
|
<div class="simplecontent">
|
||||||
|
<div class="mb-24 text-left md:text-center">
|
||||||
|
<h1
|
||||||
|
class="mb-4 text-4xl font-bold leading-tight text-gray-900 dark:text-gray-50 md:text-5xl"
|
||||||
|
>{{$t('imprint')}}</h1>
|
||||||
|
</div>
|
||||||
|
<div class="mx-auto prose" v-html="content"></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
<style src="./simple.css">
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import marked from "marked";
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
content: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async beforeMount() {
|
||||||
|
const browserlocale = ((navigator.languages && navigator.languages[0]) || '').substr(0, 2);
|
||||||
|
let md = "";
|
||||||
|
try {
|
||||||
|
md = await fetch(`/imprint_${browserlocale}.md`);
|
||||||
|
} catch (error) {
|
||||||
|
try {
|
||||||
|
md = await fetch(`/imprint_en.md`);
|
||||||
|
} catch (error) {
|
||||||
|
md = "Error loading Imprint";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.content = marked(await md.text());
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
38
src/components/Privacy.vue
Normal file
38
src/components/Privacy.vue
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<section class="container px-4 py-24 mx-auto">
|
||||||
|
<div class="simplecontent">
|
||||||
|
<div class="mb-24 text-left md:text-center">
|
||||||
|
<h1
|
||||||
|
class="mb-4 text-4xl font-bold leading-tight text-gray-900 dark:text-gray-50 md:text-5xl"
|
||||||
|
>{{ $t('privacy_policy') }}</h1>
|
||||||
|
</div>
|
||||||
|
<div class="mx-auto prose" v-html="content"></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
<style src="./simple.css">
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import marked from "marked";
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
content: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async beforeMount() {
|
||||||
|
const browserlocale = ((navigator.languages && navigator.languages[0]) || '').substr(0, 2);
|
||||||
|
let md = "";
|
||||||
|
try {
|
||||||
|
md = await fetch(`/privacy_${browserlocale}.md`);
|
||||||
|
} catch (error) {
|
||||||
|
try {
|
||||||
|
md = await fetch(`/privacy_en.md`);
|
||||||
|
} catch (error) {
|
||||||
|
md = "Error loading Privacy Policy";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.content = marked(await md.text());
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
@ -254,7 +254,7 @@ function login() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
toast("registration in progress...");
|
toast("registration in progress...");
|
||||||
axios.post('https://dev.lauf-fuer-kaya.de/api/runners/register', postdata)
|
axios.post(`${config.baseurl}api/runners/register`, postdata)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
response = response.data;
|
response = response.data;
|
||||||
const token = response.token;
|
const token = response.token;
|
||||||
|
1
src/components/simple.css
Normal file
1
src/components/simple.css
Normal file
File diff suppressed because one or more lines are too long
@ -1,10 +1,13 @@
|
|||||||
{
|
{
|
||||||
"already_have_an_account": "Sie haben bereits einen Account?",
|
"already_have_an_account": "Sie haben bereits einen Account?",
|
||||||
"apartment_suite_etc": "Addresszeile 2",
|
"apartment_suite_etc": "Addresszeile 2",
|
||||||
|
"configuration_error": "Konfigurationsfehler",
|
||||||
"distance": "Distanz",
|
"distance": "Distanz",
|
||||||
"download_certificate": "Urkunde herunterladen",
|
"download_certificate": "Urkunde herunterladen",
|
||||||
"e_mail_adress": "E-Mail Adresse",
|
"e_mail_adress": "E-Mail Adresse",
|
||||||
"go_to_login": "Zum Login",
|
"go_to_login": "Zum Login",
|
||||||
|
"if_you_are_the_system_administrator_please_refer_to_the_official_product_documentation_readme_for_configuration_guidance": "Wenn Sie der Systemadministrator sind, finden Sie Konfigurationsanweisungen in der offiziellen Produktdokumentation / README.",
|
||||||
|
"imprint": "Impressum",
|
||||||
"lap_time": "Rundenzeit",
|
"lap_time": "Rundenzeit",
|
||||||
"lap_times": "Rundenzeiten",
|
"lap_times": "Rundenzeiten",
|
||||||
"main_page_text": "Hier können Sie sich für den Lauf Für Kaya! registrieren oder ihr Läuferprofil verwalten.",
|
"main_page_text": "Hier können Sie sich für den Lauf Für Kaya! registrieren oder ihr Läuferprofil verwalten.",
|
||||||
@ -15,6 +18,7 @@
|
|||||||
"please_provide_a_valid_zipcode": "Bitte geben Sie eine gültige Postleitzahl an...",
|
"please_provide_a_valid_zipcode": "Bitte geben Sie eine gültige Postleitzahl an...",
|
||||||
"please_provide_valid_mail": "Bitte geben Sie eine gültige E-Mail Adresse an",
|
"please_provide_valid_mail": "Bitte geben Sie eine gültige E-Mail Adresse an",
|
||||||
"plz": "PLZ",
|
"plz": "PLZ",
|
||||||
|
"privacy_policy": "Datenschutzerklärung",
|
||||||
"profile": "Profil",
|
"profile": "Profil",
|
||||||
"provide_address": "Adresse angeben?",
|
"provide_address": "Adresse angeben?",
|
||||||
"register": {
|
"register": {
|
||||||
@ -25,6 +29,7 @@
|
|||||||
"save_changes": "Änderungen speichern",
|
"save_changes": "Änderungen speichern",
|
||||||
"sponsoring": "Sponsoring",
|
"sponsoring": "Sponsoring",
|
||||||
"strasse": "Straße",
|
"strasse": "Straße",
|
||||||
|
"the_system_is_not_properly_configured_please_contact_the_system_administrator_for_help": "Das System ist nicht richtig konfiguriert. Bitte wenden Sie sich an den Systemadministrator, um Hilfe zu erhalten.",
|
||||||
"this_is_not_a_valid_international_phone_number": "Dies ist keine gültige internationale Telefonnummer",
|
"this_is_not_a_valid_international_phone_number": "Dies ist keine gültige internationale Telefonnummer",
|
||||||
"view_my_data": "Meine Läuferdaten einsehen",
|
"view_my_data": "Meine Läuferdaten einsehen",
|
||||||
"vorname": "Vorname"
|
"vorname": "Vorname"
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
{
|
{
|
||||||
"already_have_an_account": "Already have an account?",
|
"already_have_an_account": "Already have an account?",
|
||||||
"apartment_suite_etc": "Apartment, suite, etc.",
|
"apartment_suite_etc": "Apartment, suite, etc.",
|
||||||
|
"configuration_error": "Configuration error",
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
"download_certificate": "Download certificate",
|
"download_certificate": "Download certificate",
|
||||||
"e_mail_adress": "mail address",
|
"e_mail_adress": "mail address",
|
||||||
"go_to_login": "Go To Login",
|
"go_to_login": "Go To Login",
|
||||||
|
"if_you_are_the_system_administrator_please_refer_to_the_official_product_documentation_readme_for_configuration_guidance": "If you are the system administrator, please refer to the official product documentation/ README for configuration guidance.",
|
||||||
|
"imprint": "Imprint",
|
||||||
"lap_time": "Lap time",
|
"lap_time": "Lap time",
|
||||||
"lap_times": "Lap times",
|
"lap_times": "Lap times",
|
||||||
"main_page_text": "Here you can register for the Lauf Für Kaya! or manage your runner profile.",
|
"main_page_text": "Here you can register for the Lauf Für Kaya! or manage your runner profile.",
|
||||||
@ -15,6 +18,7 @@
|
|||||||
"please_provide_a_valid_zipcode": "Please provide a valid zipcode...",
|
"please_provide_a_valid_zipcode": "Please provide a valid zipcode...",
|
||||||
"please_provide_valid_mail": "Please provide a valid mail address.",
|
"please_provide_valid_mail": "Please provide a valid mail address.",
|
||||||
"plz": "zipcode",
|
"plz": "zipcode",
|
||||||
|
"privacy_policy": "Privacy Policy",
|
||||||
"profile": "Profile",
|
"profile": "Profile",
|
||||||
"provide_address": "Provide a postal address?",
|
"provide_address": "Provide a postal address?",
|
||||||
"register": {
|
"register": {
|
||||||
@ -25,6 +29,7 @@
|
|||||||
"save_changes": "Save changes",
|
"save_changes": "Save changes",
|
||||||
"sponsoring": "Sponsoring",
|
"sponsoring": "Sponsoring",
|
||||||
"strasse": "Street/ Block",
|
"strasse": "Street/ Block",
|
||||||
|
"the_system_is_not_properly_configured_please_contact_the_system_administrator_for_help": "The system is not properly configured. Please contact the system administrator for help.",
|
||||||
"this_is_not_a_valid_international_phone_number": "This is not a valid international phone number",
|
"this_is_not_a_valid_international_phone_number": "This is not a valid international phone number",
|
||||||
"view_my_data": "View my data",
|
"view_my_data": "View my data",
|
||||||
"vorname": "Firstname"
|
"vorname": "Firstname"
|
||||||
|
21
src/main.js
21
src/main.js
@ -21,17 +21,28 @@ const i18n = createI18n({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
|
const EnvError = import('./components/EnvError.vue');
|
||||||
const Home = import('./components/Home.vue');
|
const Home = import('./components/Home.vue');
|
||||||
|
const Imprint = import('./components/Imprint.vue');
|
||||||
|
const Privacy = import('./components/Privacy.vue');
|
||||||
const Register = import('./components/Register.vue');
|
const Register = import('./components/Register.vue');
|
||||||
const Profile = import('./components/Profile.vue');
|
const Profile = import('./components/Profile.vue');
|
||||||
//
|
//
|
||||||
|
let routes = [ { path: '/', component: EnvError } ];
|
||||||
|
if (typeof config !== 'undefined') {
|
||||||
|
if (config.baseurl && config.documentserver_key) {
|
||||||
|
routes = [
|
||||||
|
{ path: '/', component: Home },
|
||||||
|
{ path: '/imprint', component: Imprint },
|
||||||
|
{ path: '/privacy', component: Privacy },
|
||||||
|
{ path: '/register', component: Register },
|
||||||
|
{ path: '/profile', component: Profile }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(),
|
history: createWebHistory(),
|
||||||
routes: [
|
routes
|
||||||
{ path: '/', component: Home },
|
|
||||||
{ path: '/register', component: Register },
|
|
||||||
{ path: '/profile', component: Profile }
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
// ---------------
|
// ---------------
|
||||||
createApp(App).use(Toast).use(i18n).use(router).mount('#app');
|
createApp(App).use(Toast).use(i18n).use(router).mount('#app');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user