AdminPanel erste Funktionen hinzugefügt (Formulare)
This commit is contained in:
@@ -8,4 +8,5 @@ Bei der Migration beachten:
|
||||
- addhit URL in der index.html anpassen
|
||||
- Event-Datenbank anpassen
|
||||
- Neue Formulartabelle
|
||||
- ritzenbergenlib.ts anpassen
|
||||
- .env.production anpassen
|
||||
- Salt ändern (secret.php in der API)
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import RitzenbergenLib from "./ritzenbergenlib";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
|
||||
class AdminPanelLib {
|
||||
router=useRouter();
|
||||
|
||||
static async getUserInfo(token:string){
|
||||
const url=new URL(RitzenbergenLib.RitzenbergenLib.api("/admin/userinfo.php"));
|
||||
return fetch(url.toString(), {
|
||||
@@ -7,7 +12,15 @@ class AdminPanelLib {
|
||||
"Authorization": "Bearer "+token
|
||||
},
|
||||
})
|
||||
.then((response)=>response.json());
|
||||
.then((response)=>response.json())
|
||||
.then((response)=>{
|
||||
if(response.error){
|
||||
window.alert(response.error);
|
||||
return false;
|
||||
}else{
|
||||
return response;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
36
src/components/admin/AdminNavbar.vue
Normal file
36
src/components/admin/AdminNavbar.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ref } from "vue";
|
||||
import AdminPanelLib from "../../adminpanellib.ts";
|
||||
import Navbar from "../Navbar.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const token=ref(route.params.token);
|
||||
const userinfo=ref({})
|
||||
|
||||
AdminPanelLib.AdminPanelLib.getUserInfo(token.value)
|
||||
.then((result)=>{
|
||||
if(result) return result;
|
||||
else router.push({"path":"/adminpanel/login"});
|
||||
})
|
||||
.then((result)=>userinfo.value=result);
|
||||
|
||||
const links=[
|
||||
{ "title":"Startseite", "link":"/adminpanel/"+token.value },
|
||||
{ "title":"Formulare", "link":"/adminpanel/"+token.value+"/formulare" },
|
||||
{ "title":"Events", "link":"/adminpanel/"+token.value+"/events" }
|
||||
]
|
||||
|
||||
function logout(){
|
||||
router.push({"path":"/adminpanel/login"});
|
||||
}
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<Navbar :links="links" buttontext="Abmelden" @clickbtn="logout"/>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
64
src/components/admin/InputP.vue
Normal file
64
src/components/admin/InputP.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, defineProps, computed } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: [String,Boolean,Number],
|
||||
default: null,
|
||||
},
|
||||
nullable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
inputtype: {
|
||||
type: String,
|
||||
default: "text",
|
||||
required: false
|
||||
}
|
||||
});
|
||||
|
||||
const firstValue = props.modelValue;
|
||||
|
||||
const isNull = ref(firstValue == null);
|
||||
|
||||
const emit = defineEmits(["update:modelValue", "isNull"]);
|
||||
|
||||
const value = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (v) => {
|
||||
emit("update:modelValue", v);
|
||||
},
|
||||
});
|
||||
|
||||
if(value.value==null && props.nullable==false){
|
||||
isNull.value=false;
|
||||
value.value="";
|
||||
}
|
||||
|
||||
const editing = ref(false);
|
||||
</script>
|
||||
<template>
|
||||
<form v-if="editing" @submit.prevent="editing = false">
|
||||
<input
|
||||
:type="props.inputtype"
|
||||
:placeholder="firstValue"
|
||||
v-model="value"
|
||||
v-if="!isNull"
|
||||
/>
|
||||
<label for="nullCheckbox" v-if="nullable">Null: </label>
|
||||
<input
|
||||
id="nullCheckbox"
|
||||
type="checkbox"
|
||||
v-if="nullable"
|
||||
@change="value=isNull?null:value"
|
||||
v-model="isNull"
|
||||
/>
|
||||
<input type="submit" value="Speichern" />
|
||||
</form>
|
||||
<i v-else-if="value=='' && !isNull && props.inputtype!='checkbox'" @dblclick="editing=true">EMPTY</i>
|
||||
<p v-else-if="!isNull" @dblclick="editing = true">{{ value }}</p>
|
||||
<i v-else @dblclick="editing = true">NULL</i>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@@ -185,8 +185,8 @@ class Formular {
|
||||
el.id,
|
||||
el.name,
|
||||
el.minitext,
|
||||
el.public,
|
||||
el.multiple
|
||||
el.public==null?null:(el.public==1?true:false),
|
||||
el.multiple==null?null:(el.multiple==1?true:false)
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -212,12 +212,12 @@ class Formular {
|
||||
displayvalue: el.displayvalue,
|
||||
placeholder: el.placeholder,
|
||||
title: el.title,
|
||||
required: el.required == 1,
|
||||
required: el.required==null?null:(el.required==1?true:false),
|
||||
maxlength: el.maxlength,
|
||||
min: el.min,
|
||||
max: el.max,
|
||||
multiple: el.multiple == 1,
|
||||
checked: el.checked == 1,
|
||||
multiple: el.multiple==null?null:(el.multiple==1?true:false),
|
||||
checked: el.checked==null?null:(el.checked==1?true:false),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
@@ -16,6 +16,8 @@ const routes = [
|
||||
{ path: "/bulitipp/tippen", component: () => import("../views/Bulitipp.vue") },
|
||||
{ path: "/adminpanel/login", component: () => import("../views/adminpanel/AdminPanelLogin.vue") },
|
||||
{ path: "/adminpanel/:token", component: () => import("../views/adminpanel/Main.vue"), name: "adminpanel-main" },
|
||||
{ path: "/adminpanel/:token/events", component: () => import("../views/adminpanel/Events.vue"), name: "adminpanel-events" },
|
||||
{ path: "/adminpanel/:token/formulare", component: () => import("../views/adminpanel/Formulare.vue"), name: "adminpanel-formulare" },
|
||||
{ path: "/adminpanel", component: () => import("../views/adminpanel/Main.vue") },
|
||||
|
||||
]
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
const username=ref("");
|
||||
const password=ref("");
|
||||
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<br>
|
||||
@@ -32,7 +33,7 @@
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h1>Test</h1>
|
||||
<h1>Admin Panel</h1>
|
||||
<Navbar/>
|
||||
<form @submit.prevent="login()">
|
||||
<input type="text" placeholder="Benutzername" v-model="username"/>
|
||||
|
||||
12
src/views/adminpanel/Events.vue
Normal file
12
src/views/adminpanel/Events.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<script lang="ts" setup>
|
||||
import AdminNavbar from "../../components/admin/AdminNavbar.vue";
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<AdminNavbar/>
|
||||
<h1>Events</h1>
|
||||
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
208
src/views/adminpanel/Formulare.vue
Normal file
208
src/views/adminpanel/Formulare.vue
Normal file
@@ -0,0 +1,208 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from "vue-router";
|
||||
import { ref } from "vue";
|
||||
import AdminNavbar from "../../components/admin/AdminNavbar.vue";
|
||||
import RitzenbergenLib from "../../ritzenbergenlib.ts";
|
||||
import InputP from "../../components/admin/InputP.vue";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const token = ref(route.params.token);
|
||||
|
||||
const formulare: RitzenbergenLib.Formular[] = ref([]);
|
||||
RitzenbergenLib.Formular.getForms().then(
|
||||
(result) => (formulare.value = result)
|
||||
);
|
||||
|
||||
function saveForm(form) {
|
||||
console.log(form);
|
||||
}
|
||||
function filterType(type: string) {
|
||||
if (type in ["radio", "checkbox"]) return "text";
|
||||
return type;
|
||||
}
|
||||
async function newForm() {
|
||||
return fetch(RitzenbergenLib.RitzenbergenLib.api("/admin/formulare/newForm.php"),{
|
||||
headers: {
|
||||
"Authorization":"Bearer "+token.value
|
||||
}
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.ok)
|
||||
RitzenbergenLib.Formular.getForms().then(
|
||||
(result) => (formulare.value = result)
|
||||
);
|
||||
return response;
|
||||
})
|
||||
.then((response) => response.json());
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<AdminNavbar />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h1>Formulare</h1>
|
||||
<div>
|
||||
<form
|
||||
@submit.prevent="saveForm(form)"
|
||||
v-for="(form, i) in formulare"
|
||||
:key="i"
|
||||
>
|
||||
<input type="text" placeholder="Name" v-model="form.name"/><br>
|
||||
<input type="text" placeholder="Minitext (Ergebnisse anzeigen-Button)" v-model="form.minitext"/><br>
|
||||
<label for="publicCheckbox">Ergebnisse veröffentlichen</label>
|
||||
<input type="checkbox" id="publicCheckbox" v-model="form.ispublic"/><br>
|
||||
<label for="multipleCheckbox">Mehrfacheinträge zulassen</label>
|
||||
<input type="checkbox" id="multipleCheckbox" v-model="form.multiple"/><br>
|
||||
*: Muss gesetzt werden
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td>Name *</td>
|
||||
<td>Display-Name</td>
|
||||
<td>Value *</td>
|
||||
<td>Display-Value</td>
|
||||
<td>Placeholder</td>
|
||||
<td>Type *</td>
|
||||
<td>Title (Hover)</td>
|
||||
<td>Required *</td>
|
||||
<td>Max. Länge</td>
|
||||
<td>Minimum</td>
|
||||
<td>Maximum</td>
|
||||
<td>Checked (für Checkbox und Radio)</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(field, j) in form.fields" :key="j">
|
||||
<td>{{ field.id }}</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="text"
|
||||
:nullable="false"
|
||||
v-model="field.name"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="text"
|
||||
:nullable="true"
|
||||
v-model="field.displayname"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
:inputtype="filterType(field.type)"
|
||||
:nullable="false"
|
||||
v-model="field.value"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="text"
|
||||
:nullable="true"
|
||||
v-model="field.displayvalue"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="text"
|
||||
:nullable="true"
|
||||
v-model="field.placeholder"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<select v-model="field.type">
|
||||
<option value="text">Text</option>
|
||||
<option value="number">Zahl</option>
|
||||
<option value="range">Schieberegler</option>
|
||||
<option value="date">Datum</option>
|
||||
<option value="time">Zeit</option>
|
||||
<option value="checkbox">Checkbox</option>
|
||||
<option value="radio">Radio Button</option>
|
||||
<option value="color">Farbe</option>
|
||||
<option value="textarea">
|
||||
Mehrzeiliger Text
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="text"
|
||||
:nullable="true"
|
||||
v-model="field.title"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="checkbox"
|
||||
:nullable="false"
|
||||
v-model="field.required"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="number"
|
||||
:nullable="true"
|
||||
v-model="field.maxlength"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="number"
|
||||
:nullable="true"
|
||||
v-model="field.min"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="number"
|
||||
:nullable="true"
|
||||
v-model="field.max"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<InputP
|
||||
inputtype="checkbox"
|
||||
:nullable="true"
|
||||
v-model="field.checked"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button
|
||||
@click="
|
||||
form.fields.push(
|
||||
new RitzenbergenLib.Field()
|
||||
)
|
||||
"
|
||||
>
|
||||
Neu
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<input class="saveBtn" type="submit" value="Speichern" />
|
||||
<br />
|
||||
<br />
|
||||
</form>
|
||||
<button class="saveBtn" @click="newForm">Neues Formular</button>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
@import "../../assets/css/bulitipp2.css";
|
||||
thead tr td {
|
||||
background-color: #efefef;
|
||||
}
|
||||
.saveBtn {
|
||||
margin-left: 20%;
|
||||
margin-right: 20%;
|
||||
}
|
||||
label, p, i {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -2,6 +2,7 @@
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ref } from "vue";
|
||||
import AdminPanelLib from "../../adminpanellib.ts";
|
||||
import AdminNavbar from "../../components/admin/AdminNavbar.vue";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
@@ -9,8 +10,11 @@
|
||||
const userinfo=ref({})
|
||||
|
||||
AdminPanelLib.AdminPanelLib.getUserInfo(token.value).then((result)=>userinfo.value=result);
|
||||
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<AdminNavbar/>
|
||||
<h1>Admin Panel</h1>
|
||||
<h2>Moin {{ userinfo.username }}!</h2>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user