added Maintenance to frontend and backend

This commit is contained in:
2025-01-18 20:59:35 +01:00
parent fb7e3967ae
commit b27d511e13
16 changed files with 981 additions and 14 deletions
+89
View File
@@ -0,0 +1,89 @@
<template>
<div class="character-details">
Maintenance
<div class="character-header">
<h2>{{ $t('maintenance') }}</h2>
</div>
<!-- Submenu Content -->
<component :is="currentView" :mdata="mdata"/>
<!-- Submenu -->
<div class="submenu">
<button
v-for="menu in menus"
:key="menu.id"
:class="{ active: currentView === menu.component }"
@click="changeView(menu.component)"
>
{{ $t( 'maintmenu.'+ menu.name ) }}
</button>
</div>
</div>
</template>
<style>
</style>
<script>
import API from '../utils/api'
import SkillView from "./maintenance/SkillView.vue"; // Component for character history
/*import WeaponSkillView from "./maintenance/WeaponSkillView.vue"; // Component for character equipment
import SpellView from "./maintenance/SpellView.vue"; // Component for character history
import EquipmentView from "./maintenance/EquipmentView.vue"; // Component for character equipment
import WeaponView from "./maintenance/WeaponView.vue"; // Component for character history
*/
export default {
name: "Maintenance",
//props: ["id"], // Receive the route parameter as a prop
components: {
SkillView,
/*WeaponSkillView,
SpellView,
WeaponView,
EquipmentView,*/
},
data() {
return {
mdata: {},
/*
skills: {},
weaponskills: {},
spells: {},
equipment: {},
weapons: {},*/
currentView: "SkillView", // Default view
lastView: "SkillView",
menus: [
{ id: 0, name: "skill", component: "SkillView" },
/*{ id: 1, name: "weaponskill", component: "WeaponSkillView" },
{ id: 2, name: "spell", component: "SpellView" },
{ id: 3, name: "equipment", component: "EquipmentView" },
{ id: 1, name: "weapon", component: "WeaponView" },
*/
],
};
},
async created() {
const token = localStorage.getItem('token')
const response = await API.get(`/api/maintenance`, {
headers: { Authorization: `Bearer ${token}` },
})
this.mdata= response.data
/*
this.skills = response.data['skills']
this.weaponskills = response.data["weaponskills"]
this.spells = response.data["spells"]
this.equipment = response.data["equipment"]
this.weapons = response.data["weapons"]
*/
},
methods: {
changeView(view) {
this.lastView = this.currentView;
this.currentView = view;
},
},
};
</script>
+3
View File
@@ -13,6 +13,9 @@
<li v-if="!isLoggedIn">
<router-link to="/register" active-class="active">Register</router-link>
</li>
<li v-if="isLoggedIn">
<router-link to="/maintenance" active-class="active">Maintenance</router-link>
</li>
</ul>
<LanguageSwitcher />
</nav>
@@ -0,0 +1,86 @@
<template>
<div class="cd-view">
<div class="cd-list">
<div class="tables-container">
<h2 style="line-height: 1.5; margin-top: 5px;"><!-- {{ character.name }}'s -->Fertigkeiten</h2>
<table class="cd-table">
<thead>
<tr>
<th class="cd-table-header" width="60%">{{ $t('skill.name') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.value') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.bonus') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.pp') }}</th>
<!-- <th class="cd-table-header">{{ $t('skill.description') }}</th>-->
<th class="cd-table-header" width="30%">{{ $t('skill.note') }}</th>
</tr>
</thead>
<tbody>
<template v-for="skills,categorie in character.categorizedskills">
<tr>
<td colspan="6">{{ categorie || '-' }}</td>
</tr>
<template v-for="skill in skills">
<tr>
<td>{{ skill.name || '-' }}</td>
<td>{{ skill.fertigkeitswert || '-' }}</td>
<td>{{ skill.bonus || '0' }}</td>
<td>{{ skill.pp || '0' }}</td>
<!-- <td>{{ skill.beschreibung || '-' }}</td>-->
<td>{{ skill.bemerkung || '-' }}</td>
</tr>
</template>
</template>
<template v-for="skill in character.waffenfertigkeiten">
<tr>
<td>{{ skill.name || '-' }}</td>
<td>{{ skill.fertigkeitswert || '-' }}</td>
<td>{{ skill.bonus || '0' }}</td>
<td>{{ skill.pp || '0' }}</td>
<!-- <td>{{ skill.beschreibung || '-' }}</td> -->
<td>{{ skill.bemerkung || '-' }}</td>
</tr>
</template>
</tbody>
</table>
</div>
</div> <!--- end cd-list-->
</div> <!--- end character -datasheet-->
</template>
<style>
.tables-container {
display: flex;
gap: 1rem;
width: 100%;
}
.table-wrapper-left {
flex: 6;
min-width: 0; /* Prevent table from overflowing */
}
.table-wrapper-right {
flex: 4;
min-width: 0; /* Prevent table from overflowing */
}
.cd-table {
width: 100%;
}
.cd-table-header {
background-color: #1da766;
font-weight: bold;
}
</style>
<script>
export default {
name: "EquipmentView",
props: {
character: {
type: Object,
required: true
}
}
};
</script>
@@ -0,0 +1,125 @@
<template>
<div class="cd-view">
<div class="cd-list">
<div class="tables-container">
<table class="cd-table">
<thead>
<tr>
<th class="cd-table-header">{{ $t('skill.id') }}</th>
<th class="cd-table-header">{{ $t('skill.category') }}</th>
<th class="cd-table-header">{{ $t('skill.name') }}</th>
<th class="cd-table-header">{{ $t('skill.initialwert') }}</th>
<th class="cd-table-header">{{ $t('skill.improvable') }}</th>
<th class="cd-table-header">{{ $t('skill.innateskill') }}</th>
<th class="cd-table-header">{{ $t('skill.description') }}</th>
<th class="cd-table-header">{{ $t('skill.bonusskill') }}</th>
<th class="cd-table-header">{{ $t('skill.quelle') }}</th>
<th class="cd-table-header">{{ $t('skill.system') }}</th>
<th class="cd-table-header"> </th>
</tr>
</thead>
<tbody>
<template v-for="(dtaItem, index) in mdata['skills']" :key="index">
<tr v-if="editingIndex !== index">
<td>{{ dtaItem.id || '' }}</td>
<td>{{ dtaItem.category|| '-' }}</td>
<td>{{ dtaItem.name || '-' }}</td>
<td>{{ dtaItem.initialwert || '0' }}</td>
<td>{{ dtaItem.improvable || '0' }}</td>
<td>{{ dtaItem.innateskill || '0' }}</td>
<td>{{ dtaItem.beschreibung || '-' }}</td>
<td>{{ dtaItem.bonuseigenschaft || '-' }}</td>
<td>{{ dtaItem.quelle || '-' }}</td>
<td>{{ dtaItem.system || 'midgard' }}</td>
<td>
<button @click="startEdit(index)">Edit</button>
</td>
</tr>
<tr v-else>
<td><input v-model="editedItem.id" style="width:20px;"/></td>
<td><select v-model="editedItem.category" style="width:80px;">
<option v-for="category in mdata['skillcategories']"
:key="category"
:value="category">
{{ category }}
</option>
</select></td>
<td><input v-model="editedItem.name"/></td>
<td><input v-model.number="editedItem.initialwert" type="number" style="width:40px;"/></td>
<td><input v-model.boolean="editedItem.improvable" style="width:50px;"/></td>
<td><input v-model.boolean="editedItem.innateskill" style="width:50px;"/></td>
<td><input v-model="editedItem.beschreibung" /></td>
<td><input v-model="editedItem.bonuseigenschaft" style="width:80px;" ></td>
<td><input v-model="editedItem.quelle" style="width:80px;"/></td>
<td><input v-model="editedItem.system" style="width:80px;"/></td>
<td>
<button @click="saveEdit(index)">Save</button>
<button @click="cancelEdit">Cancel</button>
</td>
</tr>
</template>
</tbody>
</table>
</div>
</div> <!--- end cd-list-->
</div> <!--- end character -datasheet-->
</template>
<style>
.tables-container {
display: flex;
gap: 1rem;
width: 100%;
}
.table-wrapper-left {
flex: 6;
min-width: 0; /* Prevent table from overflowing */
}
.table-wrapper-right {
flex: 4;
min-width: 0; /* Prevent table from overflowing */
}
.cd-table {
width: 100%;
}
.cd-table-header {
background-color: #1da766;
font-weight: bold;
}
</style>
<script>
export default {
name: "SkillView",
props: {
mdata: {
type: Object,
required: true
}
},
data() {
return {
editingIndex: -1,
editedItem: null
}
},
methods: {
startEdit(index) {
this.editingIndex = index;
this.editedItem = { ...this.mdata['skills'][index] };
},
saveEdit(index) {
this.$emit('update-skill', { index, skill: this.editedItem });
this.editingIndex = -1;
this.editedItem = null;
},
cancelEdit() {
this.editingIndex = -1;
this.editedItem = null;
}
}
};
</script>
@@ -0,0 +1,86 @@
<template>
<div class="cd-view">
<div class="cd-list">
<div class="tables-container">
<h2 style="line-height: 1.5; margin-top: 5px;"><!-- {{ character.name }}'s -->Fertigkeiten</h2>
<table class="cd-table">
<thead>
<tr>
<th class="cd-table-header" width="60%">{{ $t('skill.name') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.value') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.bonus') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.pp') }}</th>
<!-- <th class="cd-table-header">{{ $t('skill.description') }}</th>-->
<th class="cd-table-header" width="30%">{{ $t('skill.note') }}</th>
</tr>
</thead>
<tbody>
<template v-for="skills,categorie in character.categorizedskills">
<tr>
<td colspan="6">{{ categorie || '-' }}</td>
</tr>
<template v-for="skill in skills">
<tr>
<td>{{ skill.name || '-' }}</td>
<td>{{ skill.fertigkeitswert || '-' }}</td>
<td>{{ skill.bonus || '0' }}</td>
<td>{{ skill.pp || '0' }}</td>
<!-- <td>{{ skill.beschreibung || '-' }}</td>-->
<td>{{ skill.bemerkung || '-' }}</td>
</tr>
</template>
</template>
<template v-for="skill in character.waffenfertigkeiten">
<tr>
<td>{{ skill.name || '-' }}</td>
<td>{{ skill.fertigkeitswert || '-' }}</td>
<td>{{ skill.bonus || '0' }}</td>
<td>{{ skill.pp || '0' }}</td>
<!-- <td>{{ skill.beschreibung || '-' }}</td> -->
<td>{{ skill.bemerkung || '-' }}</td>
</tr>
</template>
</tbody>
</table>
</div>
</div> <!--- end cd-list-->
</div> <!--- end character -datasheet-->
</template>
<style>
.tables-container {
display: flex;
gap: 1rem;
width: 100%;
}
.table-wrapper-left {
flex: 6;
min-width: 0; /* Prevent table from overflowing */
}
.table-wrapper-right {
flex: 4;
min-width: 0; /* Prevent table from overflowing */
}
.cd-table {
width: 100%;
}
.cd-table-header {
background-color: #1da766;
font-weight: bold;
}
</style>
<script>
export default {
name: "SpellView",
props: {
character: {
type: Object,
required: true
}
}
};
</script>
@@ -0,0 +1,86 @@
<template>
<div class="cd-view">
<div class="cd-list">
<div class="tables-container">
<h2 style="line-height: 1.5; margin-top: 5px;"><!-- {{ character.name }}'s -->Fertigkeiten</h2>
<table class="cd-table">
<thead>
<tr>
<th class="cd-table-header" width="60%">{{ $t('skill.name') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.value') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.bonus') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.pp') }}</th>
<!-- <th class="cd-table-header">{{ $t('skill.description') }}</th>-->
<th class="cd-table-header" width="30%">{{ $t('skill.note') }}</th>
</tr>
</thead>
<tbody>
<template v-for="skills,categorie in character.categorizedskills">
<tr>
<td colspan="6">{{ categorie || '-' }}</td>
</tr>
<template v-for="skill in skills">
<tr>
<td>{{ skill.name || '-' }}</td>
<td>{{ skill.fertigkeitswert || '-' }}</td>
<td>{{ skill.bonus || '0' }}</td>
<td>{{ skill.pp || '0' }}</td>
<!-- <td>{{ skill.beschreibung || '-' }}</td>-->
<td>{{ skill.bemerkung || '-' }}</td>
</tr>
</template>
</template>
<template v-for="skill in character.waffenfertigkeiten">
<tr>
<td>{{ skill.name || '-' }}</td>
<td>{{ skill.fertigkeitswert || '-' }}</td>
<td>{{ skill.bonus || '0' }}</td>
<td>{{ skill.pp || '0' }}</td>
<!-- <td>{{ skill.beschreibung || '-' }}</td> -->
<td>{{ skill.bemerkung || '-' }}</td>
</tr>
</template>
</tbody>
</table>
</div>
</div> <!--- end cd-list-->
</div> <!--- end character -datasheet-->
</template>
<style>
.tables-container {
display: flex;
gap: 1rem;
width: 100%;
}
.table-wrapper-left {
flex: 6;
min-width: 0; /* Prevent table from overflowing */
}
.table-wrapper-right {
flex: 4;
min-width: 0; /* Prevent table from overflowing */
}
.cd-table {
width: 100%;
}
.cd-table-header {
background-color: #1da766;
font-weight: bold;
}
</style>
<script>
export default {
name: "WeaponSkillView",
props: {
character: {
type: Object,
required: true
}
}
};
</script>
@@ -0,0 +1,86 @@
<template>
<div class="cd-view">
<div class="cd-list">
<div class="tables-container">
<h2 style="line-height: 1.5; margin-top: 5px;"><!-- {{ character.name }}'s -->Fertigkeiten</h2>
<table class="cd-table">
<thead>
<tr>
<th class="cd-table-header" width="60%">{{ $t('skill.name') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.value') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.bonus') }}</th>
<th class="cd-table-header" width="35">{{ $t('skill.pp') }}</th>
<!-- <th class="cd-table-header">{{ $t('skill.description') }}</th>-->
<th class="cd-table-header" width="30%">{{ $t('skill.note') }}</th>
</tr>
</thead>
<tbody>
<template v-for="skills,categorie in character.categorizedskills">
<tr>
<td colspan="6">{{ categorie || '-' }}</td>
</tr>
<template v-for="skill in skills">
<tr>
<td>{{ skill.name || '-' }}</td>
<td>{{ skill.fertigkeitswert || '-' }}</td>
<td>{{ skill.bonus || '0' }}</td>
<td>{{ skill.pp || '0' }}</td>
<!-- <td>{{ skill.beschreibung || '-' }}</td>-->
<td>{{ skill.bemerkung || '-' }}</td>
</tr>
</template>
</template>
<template v-for="skill in character.waffenfertigkeiten">
<tr>
<td>{{ skill.name || '-' }}</td>
<td>{{ skill.fertigkeitswert || '-' }}</td>
<td>{{ skill.bonus || '0' }}</td>
<td>{{ skill.pp || '0' }}</td>
<!-- <td>{{ skill.beschreibung || '-' }}</td> -->
<td>{{ skill.bemerkung || '-' }}</td>
</tr>
</template>
</tbody>
</table>
</div>
</div> <!--- end cd-list-->
</div> <!--- end character -datasheet-->
</template>
<style>
.tables-container {
display: flex;
gap: 1rem;
width: 100%;
}
.table-wrapper-left {
flex: 6;
min-width: 0; /* Prevent table from overflowing */
}
.table-wrapper-right {
flex: 4;
min-width: 0; /* Prevent table from overflowing */
}
.cd-table {
width: 100%;
}
.cd-table-header {
background-color: #1da766;
font-weight: bold;
}
</style>
<script>
export default {
name: "WeaponView",
props: {
character: {
type: Object,
required: true
}
}
};
</script>
+16
View File
@@ -42,12 +42,20 @@ export default {
contained_in:'Enthalten in',
},
skill:{
id:'ID',
name:'Name',
description:'Beschreibung',
value:'EW',
note:'Bemerkung',
bonus:'Bonus',
pp:'PP',
quelle:'Quelle',
system:'System',
bonusskill:'Bonuseigenschaft',
innateskill:'angeboren',
improvable:'verbesserbar',
category:'Kategorie',
initialwert:'Startwert',
},
spell:{
name:'Name',
@@ -65,4 +73,12 @@ export default {
bonus:'Bonus',
contained_in:'Enthalten in',
},
maintenance:'Wartung',
maintmenu:{
skill:'Fertigkeiten',
weaponskill:'Waffenfertigkeiten',
spell:'Zauber',
equipment:'Ausrüstung',
weapon:'Waffen',
},
}
+2
View File
@@ -4,6 +4,7 @@ import LoginView from "../views/LoginView.vue";
import RegisterView from "../views/RegisterView.vue";
import DashboardView from "../views/DashboardView.vue";
import AusruestungView from "../views/AusruestungView.vue";
import MaintenanceView from "../views/MaintenanceView.vue";
import FileUploadPage from "../views/FileUploadPage.vue";
import CharacterDetails from "@/components/CharacterDetails.vue";
@@ -16,6 +17,7 @@ const routes = [
{ path: "/register", name: "Register", component: RegisterView },
{ path: "/dashboard", name: "Dashboard", component: DashboardView, meta: { requiresAuth: true } },
{ path: "/ausruestung/:characterId", name: "Ausruestung", component: AusruestungView, meta: { requiresAuth: true } },
{ path: "/maintenance", name: "Maintenance", component: MaintenanceView, meta: { requiresAuth: true } },
{ path: "/upload", name: "FileUpload", component: FileUploadPage },
// Route for character details // Pass route params as props to the component
{ path: "/character/:id", name: "CharacterDetails", component: CharacterDetails, props: true, meta: { requiresAuth: true } },
+11
View File
@@ -0,0 +1,11 @@
<template>
<Maintenance/>
</template>
<script>
import Maintenance from '../components/Maintenance.vue'
export default {
components: { Maintenance },
}
</script>