* fixing bugs due to eslint recommendation

feature: no-task
This commit is contained in:
2023-01-07 17:27:34 +01:00
parent 3b417c9ddd
commit 8463f87f9a
20 changed files with 1385 additions and 558 deletions

View File

@@ -5,5 +5,6 @@
"singleQuote": true, "singleQuote": true,
"arrowParens": "avoid", "arrowParens": "avoid",
"printWidth": 100, "printWidth": 100,
"bracketSameLine": true "bracketSameLine": true,
"endOfLine" : "auto"
} }

994
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,7 @@
"@fortawesome/free-regular-svg-icons": "^6.2.1", "@fortawesome/free-regular-svg-icons": "^6.2.1",
"@fortawesome/free-solid-svg-icons": "^6.2.1", "@fortawesome/free-solid-svg-icons": "^6.2.1",
"@fortawesome/vue-fontawesome": "^3.0.2", "@fortawesome/vue-fontawesome": "^3.0.2",
"@volar-plugins/vetur": "^0.1.0",
"@vuelidate/core": "^2.0.0", "@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0", "@vuelidate/validators": "^2.0.0",
"axios": "^1.2.2", "axios": "^1.2.2",

View File

@@ -74,7 +74,7 @@
<li v-if="isAnonym" class="block text-md py-4 text-white text-center"> <li v-if="isAnonym" class="block text-md py-4 text-white text-center">
<RouterLink to="/about">Über uns</RouterLink> <RouterLink to="/about">Über uns</RouterLink>
</li> </li>
<li v-if="isAnonym" class="block py-2 flex justify-center"> <li v-if="isAnonym" class="py-2 flex justify-center">
<button <button
class="bg-blue-600 hover:bg-blue-500 duration-300 text-white px-3 py-1 my-2 rounded" class="bg-blue-600 hover:bg-blue-500 duration-300 text-white px-3 py-1 my-2 rounded"
@click="login"> @click="login">

View File

@@ -1,42 +1,44 @@
<template> <template>
<div class="bg-zinc-50"> <div class="bg-zinc-50">
<div class="py-2"> <div class="py-2">
<table class="w-full table-auto"> <table class="w-full table-auto">
<tr class="border-b"> <tr class="border-b">
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Name:</td> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Name:</td>
<td class="w-full pl-3 text-lg max-sm:text-base py-2">{{ contract.client.name }}</td> <td class="w-full pl-3 text-lg max-sm:text-base py-2">{{ contract.client.name }}</td>
</tr> </tr>
<tr class="pt-5 border-b"> <tr class="pt-5 border-b">
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Address:</td> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Address:</td>
<td class="w-full pl-3 text-lg max-sm:text-base py-2">{{ contract.client.address }}</td> <td class="w-full pl-3 text-lg max-sm:text-base py-2">{{ contract.client.address }}</td>
</tr> </tr>
<tr class="border-b"> <tr class="border-b">
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Anschprechpartner:</td> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Anschprechpartner:</td>
<td class="w-full pl-3 text-lg max-sm:text-base py-2">{{ contract.client.contactPerson }}</td> <td class="w-full pl-3 text-lg max-sm:text-base py-2">
</tr> {{ contract.client.contactPerson }}
<tr class="border-b"> </td>
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Email:</td> </tr>
<td class="w-full pl-3 text-lg max-sm:text-base py-2"> <tr class="border-b">
<a v-bind:href="'mailto:' + contract.client.email"> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Email:</td>
<font-awesome-icon class="pl-1 h-5 mt-1" icon='fa-solid fa-envelope'/> <td class="w-full pl-3 text-lg max-sm:text-base py-2">
</a> <a :href="'mailto:' + contract.client.email">
</td> <font-awesome-icon class="pl-1 h-5 mt-1" icon="fa-solid fa-envelope" />
</tr> </a>
<tr class="border-b"> </td>
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Nummer:</td> </tr>
<td class="w-full pl-3 text-lg max-sm:text-base py-2">{{ contract.client.phone }}</td> <tr class="border-b">
</tr> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Nummer:</td>
</table> <td class="w-full pl-3 text-lg max-sm:text-base py-2">{{ contract.client.phone }}</td>
</div> </tr>
</div> </table>
</template> </div>
<script> </div>
</template>
export default { <script>
props: { export default {
contract: { props: {
type: Object contract: {
} type: Object,
} default: () => ({})
} }
</script> }
}
</script>

View File

@@ -1,53 +1,67 @@
<template> <template>
<div class="bg-zinc-50"> <div class="bg-zinc-50">
<div class="flex flex-row justify-center py-5"> <div class="flex flex-row justify-center py-5">
<ul class="justify-around"> <ul class="justify-around">
<li v-for="comment in contract.comments" class="bg-white rounded-lg shadow-2xl mb-4"> <li
<div class="relative grid grid-cols-1 gap-4 p-4 mb-8 border rounded-lg bg-white shadow-lg"> v-for="comment in contract.comments"
<div class="relative flex gap-4"> :key="comment.id"
<font-awesome-icon icon="fa-solid fa-user-large" class="relative -mb-4 bg-white h-11 w-11" /> class="bg-white rounded-lg shadow-2xl mb-4">
<div class="flex flex-col w-full"> <div
<div class="flex flex-row justify-between"> class="relative grid grid-cols-1 gap-4 p-4 mb-8 border rounded-lg bg-white shadow-lg">
<p class="relative text-xl whitespace-nowrap truncate overflow-hidden">{{comment.name}}</p> <div class="relative flex gap-4">
<a class="text-gray-500 text-xl" href="#"><i class="fa-solid fa-trash"></i></a> <font-awesome-icon
</div> icon="fa-solid fa-user-large"
<p class="text-gray-400 text-sm">{{new Date(comment.date).toDateString() }}</p> class="relative -mb-4 bg-white h-11 w-11" />
</div> <div class="flex flex-col w-full">
</div> <div class="flex flex-row justify-between">
<p class="-mt-4 text-gray-500"> {{comment.message}} </p> <p class="relative text-xl whitespace-nowrap truncate overflow-hidden">
</div> {{ comment.name }}
</li> </p>
</ul> <a class="text-gray-500 text-xl" href="#"><i class="fa-solid fa-trash"></i></a>
</div> </div>
<p class="text-gray-400 text-sm">{{ new Date(comment.date).toDateString() }}</p>
<div class="flex justify-center"> </div>
</div>
<div class="py-4 mb-10 shadow-2xl"> <p class="-mt-4 text-gray-500">{{ comment.message }}</p>
<form class="w-full max-w-xl bg-white rounded-lg px-4 pt-2"> </div>
<div class="flex flex-wrap -mx-3 mb-6"> </li>
<h2 class="px-4 pt-3 pb-2 text-gray-800 text-lg">Add comment</h2> </ul>
<div class="w-full md:w-full px-3 mb-2 mt-2"> </div>
<textarea class="bg-gray-100 rounded border border-gray-400 leading-normal resize-none w-full h-20 py-2 px-3 font-medium placeholder-gray-700 focus:outline-none focus:bg-white" name="body" placeholder='Type Your Comment' required></textarea>
</div> <div class="flex justify-center">
<div class="w-full md:w-full flex items-start md:w-full px-3"> <div class="py-4 mb-10 shadow-2xl">
<div class="flex items-start w-1/2 text-gray-700 px-2 mr-auto"></div> <form class="w-full max-w-xl bg-white rounded-lg px-4 pt-2">
<div class="-mr-1"> <div class="flex flex-wrap -mx-3 mb-6">
<input type='submit' class="bg-white text-gray-700 font-medium py-1 px-4 border border-gray-400 rounded-lg tracking-wide mr-1 hover:bg-gray-100" value='Post Comment'> <h2 class="px-4 pt-3 pb-2 text-gray-800 text-lg">Add comment</h2>
</div> <div class="w-full md:w-full px-3 mb-2 mt-2">
</div> <textarea
</div> class="bg-gray-100 rounded border border-gray-400 leading-normal resize-none w-full h-20 py-2 px-3 font-medium placeholder-gray-700 focus:outline-none focus:bg-white"
</form> name="body"
</div> placeholder="Type Your Comment"
</div> required></textarea>
</div> </div>
</template> <div class="w-full md:w-full flex items-start px-3">
<script> <div class="flex items-start w-1/2 text-gray-700 px-2 mr-auto"></div>
<div class="-mr-1">
export default { <input
props: { type="submit"
contract: { class="bg-white text-gray-700 font-medium py-1 px-4 border border-gray-400 rounded-lg tracking-wide mr-1 hover:bg-gray-100"
type: Object value="Post Comment" />
} </div>
} </div>
} </div>
</script> </form>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
contract: {
type: Object,
default: () => ({})
}
}
}
</script>

View File

@@ -1,103 +1,122 @@
<template> <template>
<div class="bg-zinc-50"> <div class="bg-zinc-50">
<div class="px-4 pt-3"> <div class="px-4 pt-3">
<!-- Draw buttons by roles --> <!-- Draw buttons by roles -->
<button type="button" class="inline-block px-6 mr-3 py-2.5 bg-green-500 text-white font-medium text-xs rounded shadow-md">Nächstes Schritt</button> <button
<button type="button" class="inline-block max-sm:mt-3 px-6 mr-3 py-2.5 bg-blue-600 text-white font-medium text-xs rounded shadow-md">Status wächseln</button> type="button"
<button type="button" class="inline-block max-sm:mt-3 px-6 mr-3 py-2.5 bg-blue-600 text-white font-medium text-xs rounded shadow-md">Mitarbeitern wächseln</button> class="inline-block px-6 mr-3 py-2.5 bg-green-500 text-white font-medium text-xs rounded shadow-md">
<button type="button" class="inline-block max-md:mt-3 px-6 mr-3 py-2.5 bg-blue-600 text-white font-medium text-xs rounded shadow-md">Anmeldung anfangen</button> Nächstes Schritt
</div> </button>
<div class="py-2"> <button
<table class="w-full table-auto"> type="button"
<tr class="border-b"> class="inline-block max-sm:mt-3 px-6 mr-3 py-2.5 bg-blue-600 text-white font-medium text-xs rounded shadow-md">
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">ID:</td> Status wächseln
<td class="w-full pl-2 text-lg max-sm:text-base py-2">{{ contract.id }}</td> </button>
</tr> <button
<tr class="border-b"> type="button"
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Name:</td> class="inline-block max-sm:mt-3 px-6 mr-3 py-2.5 bg-blue-600 text-white font-medium text-xs rounded shadow-md">
<td class="w-full pl-2 text-lg max-sm:text-base py-2">{{ contract.name }}</td> Mitarbeitern wächseln
</tr> </button>
<tr class="pt-5 border-b"> <button
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Status:</td> type="button"
<td class="w-full pl-2 text-lg max-sm:text-base py-2"> class="inline-block max-md:mt-3 px-6 mr-3 py-2.5 bg-blue-600 text-white font-medium text-xs rounded shadow-md">
<span class="px-3 py-1 text-sm rounded-full bg-cyan-300 text-slate-800 bg-cyan-200 font-semibold"> Anmeldung anfangen
{{ contract.status }} </button>
</span> </div>
</td> <div class="py-2">
</tr> <table class="w-full table-auto">
<tr class="pt-5 border-b"> <tr class="border-b">
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Progress:</td> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">ID:</td>
<td class="w-full pl-2 text-lg max-sm:text-base py-2"> <td class="w-full pl-2 text-lg max-sm:text-base py-2">{{ contract.id }}</td>
<div class="mt-7 mb-"> </tr>
<div class="bg-slate-200 relative h-[10px] w-full rounded-2xl"> <tr class="border-b">
<div class="bg-blue-600 absolute top-0 left-0 h-full w-[75%] rounded-2xl"> <!-- todo: calculate in percents progress --> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Name:</td>
<span <td class="w-full pl-2 text-lg max-sm:text-base py-2">{{ contract.name }}</td>
class="bg-blue-600 absolute -right-4 bottom-full mb-2 rounded-sm py-1 px-2 text-xs font-semibold text-white" </tr>
> <tr class="pt-5 border-b">
<span <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Status:</td>
class="bg-blue-600 absolute bottom-[-2px] left-1/2 -z-10 h-2 w-2 -translate-x-1/2 rotate-45 rounded-sm" <td class="w-full pl-2 text-lg max-sm:text-base py-2">
></span> <span class="px-3 py-1 text-sm rounded-full text-slate-800 bg-cyan-200 font-semibold">
75% {{ contract.status }}
</span> </span>
</div> </td>
</div> </tr>
</div> <tr class="pt-5 border-b">
</td> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Progress:</td>
</tr> <td class="w-full pl-2 text-lg max-sm:text-base py-2">
<tr class="border-b"> <div class="mt-7 mb-">
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Mitarbeiter:</td> <div class="bg-slate-200 relative h-[10px] w-full rounded-2xl">
<td class="w-full pl-2 text-lg max-sm:text-base py-2"> <div class="bg-blue-600 absolute top-0 left-0 h-full w-[75%] rounded-2xl">
<ul class="list-disc pl-4"> <!-- TODO: calculate in percents progress -->
<li v-for="person in contract.mitarbeiter"> <span
{{ person.name }}({{ person.role }}) {{person.phone}} class="bg-blue-600 absolute -right-4 bottom-full mb-2 rounded-sm py-1 px-2 text-xs font-semibold text-white">
<a v-bind:href="'mailto:' + person.email"> <span
<font-awesome-icon class="pl-1 h-5 mt-1" icon='fa-solid fa-envelope'/> class="bg-blue-600 absolute bottom-[-2px] left-1/2 -z-10 h-2 w-2 -translate-x-1/2 rotate-45 rounded-sm"></span>
</a> 75%
</li> </span>
</ul> </div>
</td> </div>
</tr> </div>
<tr class="border-b"> </td>
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Unterlagen:</td> </tr>
<td class="w-full pl-2 text-lg max-sm:text-base py-2"> <tr class="border-b">
<ul class="list-disc pl-4"> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Mitarbeiter:</td>
<li v-for="document in contract.unterlagen"> <td class="w-full pl-2 text-lg max-sm:text-base py-2">
<a v-bind:href='document.url' class="underline"> <ul class="list-disc pl-4">
{{ document.name }} <li v-for="person in contract.mitarbeiter" :key="person.name">
<font-awesome-icon class="h-3 mb-0.5 pl-1" icon="fa-solid fa-arrow-up-right-from-square" /> {{ person.name }}({{ person.role }}) {{ person.phone }}
</a> <a :href="'mailto:' + person.email">
</li> <font-awesome-icon class="pl-1 h-5 mt-1" icon="fa-solid fa-envelope" />
</ul> </a>
</td> </li>
</tr> </ul>
<tr class="border-b"> </td>
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Beschreibung:</td> </tr>
<td class="w-full pl-2 text-lg max-sm:text-base py-2">{{ contract.beschreibung }}</td> <tr class="border-b">
</tr> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Unterlagen:</td>
<tr> <td class="w-full pl-2 text-lg max-sm:text-base py-2">
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Beispiele:</td> <ul class="list-disc pl-4">
<td class="w-full pl-2 text-lg py-2"> <li v-for="document in contract.unterlagen" :key="document.id">
<ul class="list-disc pl-4"> <a :href="document.url" class="underline">
<li v-for="(example, index) in contract.examples"> {{ document.name }}
<a v-bind:href='example' class="underline"> <font-awesome-icon
Link {{ index + 1 }} class="h-3 mb-0.5 pl-1"
<font-awesome-icon class="h-3 mb-0.5 pl-1" icon="fa-solid fa-arrow-up-right-from-square" /> icon="fa-solid fa-arrow-up-right-from-square" />
</a> </a>
</li> </li>
</ul> </ul>
</td> </td>
</tr> </tr>
</table> <tr class="border-b">
</div> <td class="text align-top text-xl pl-4 max-sm:text-base py-2">Beschreibung:</td>
</div> <td class="w-full pl-2 text-lg max-sm:text-base py-2">{{ contract.beschreibung }}</td>
</template> </tr>
<script> <tr>
<td class="text align-top text-xl pl-4 max-sm:text-base py-2">Beispiele:</td>
export default { <td class="w-full pl-2 text-lg py-2">
props: { <ul class="list-disc pl-4">
contract: { <li v-for="(example, index) in contract.examples" :key="index">
type: Object <a :href="example" class="underline">
} Link {{ index + 1 }}
} <font-awesome-icon
} class="h-3 mb-0.5 pl-1"
</script> icon="fa-solid fa-arrow-up-right-from-square" />
</a>
</li>
</ul>
</td>
</tr>
</table>
</div>
</div>
</template>
<script>
export default {
props: {
contract: {
type: Object,
default: () => ({})
}
}
}
</script>

View File

@@ -26,7 +26,6 @@ const router = createRouter({
{ {
path: '/support', path: '/support',
name: 'support', name: 'support',
// this page is lazy-loaded when the route is visited.
component: () => import('../views/SupportView.vue'), component: () => import('../views/SupportView.vue'),
meta: { meta: {
requiresAuth: true requiresAuth: true
@@ -35,7 +34,6 @@ const router = createRouter({
{ {
path: '/administration', path: '/administration',
name: 'administration', name: 'administration',
// this page is lazy-loaded when the route is visited.
component: () => import('../views/AdministrationView.vue'), component: () => import('../views/AdministrationView.vue'),
meta: { meta: {
requiresAuth: true, requiresAuth: true,
@@ -45,7 +43,6 @@ const router = createRouter({
{ {
path: '/arbeiten', path: '/arbeiten',
name: 'arbeiten', name: 'arbeiten',
// this page is lazy-loaded when the route is visited.
component: () => import('../views/ArbeitenView.vue'), component: () => import('../views/ArbeitenView.vue'),
meta: { meta: {
requiresAuth: false requiresAuth: false
@@ -54,7 +51,6 @@ const router = createRouter({
{ {
path: '/contact', path: '/contact',
name: 'contact', name: 'contact',
// this page is lazy-loaded when the route is visited.
component: () => import('../views/ContactView.vue'), component: () => import('../views/ContactView.vue'),
meta: { meta: {
requiresAuth: false requiresAuth: false
@@ -63,7 +59,6 @@ const router = createRouter({
{ {
path: '/about', path: '/about',
name: 'about', name: 'about',
// this page is lazy-loaded when the route is visited.
component: () => import('../views/AboutView.vue'), component: () => import('../views/AboutView.vue'),
meta: { meta: {
requiresAuth: false requiresAuth: false
@@ -72,7 +67,6 @@ const router = createRouter({
{ {
path: '/contract', path: '/contract',
name: 'contract', name: 'contract',
// this page is lazy-loaded when the route is visited.
component: () => import('../views/ContractView.vue'), component: () => import('../views/ContractView.vue'),
meta: { meta: {
requiresAuth: true requiresAuth: true
@@ -81,7 +75,6 @@ const router = createRouter({
{ {
path: '/contracts/register', path: '/contracts/register',
name: 'contractRegistration', name: 'contractRegistration',
// this page is lazy-loaded when the route is visited.
component: () => import('../views/OpenContractsView.vue'), component: () => import('../views/OpenContractsView.vue'),
meta: { meta: {
requiresAuth: true requiresAuth: true

View File

@@ -7,7 +7,7 @@ import router from '../router'
//Auth: provide auth token in request //Auth: provide auth token in request
//OnError: redirect to page /error?message=somemessage&code=404 //OnError: redirect to page /error?message=somemessage&code=404
export async function getContracts() { export async function getContracts() {
return HttpClient.get('contracts') //todo: provide here auth header return HttpClient.get('contracts') //TODO: provide here auth header
.then(resp => { .then(resp => {
return resp.data.contracts return resp.data.contracts
}) })
@@ -20,7 +20,7 @@ export async function getContracts() {
//Auth: provide auth token in request //Auth: provide auth token in request
//OnError: redirect to page /error?message=somemessage&code=404 //OnError: redirect to page /error?message=somemessage&code=404
export async function getOpenContracts() { export async function getOpenContracts() {
return HttpClient.get('contracts/register') //todo: provide here auth header return HttpClient.get('contracts/register') //TODO: provide here auth header
.then(resp => { .then(resp => {
return resp.data.openContracts return resp.data.openContracts
}) })
@@ -37,7 +37,7 @@ export async function getOpenContracts() {
export async function getContractById(identifier) { export async function getContractById(identifier) {
return HttpClient.get('/contract', { params: { id: identifier } }) return HttpClient.get('/contract', { params: { id: identifier } })
.then(resp => { .then(resp => {
//todo: send also auth token with request //TODO: send also auth token with request
return resp.data return resp.data
}) })
.catch(error => { .catch(error => {

View File

@@ -7,7 +7,7 @@ export default {
} }
</script> </script>
<template> <template>
<Navbar /><!-- Causes rendering each time todo: possible use in App.vue--> <Navbar /><!-- Causes rendering each time TODO: possible use in App.vue-->
<div class="about"> <div class="about">
<h1>This is a About page</h1> <h1>This is a About page</h1>
</div> </div>

View File

@@ -7,7 +7,7 @@ export default {
} }
</script> </script>
<template> <template>
<Navbar /><!-- Causes rerendering each time todo: possible use in App.vue--> <Navbar /><!-- Causes rerendering each time TODO: possible use in App.vue-->
<div class="about"> <div class="about">
<h1>This is an Administration page</h1> <h1>This is an Administration page</h1>
</div> </div>

View File

@@ -7,7 +7,7 @@ export default {
} }
</script> </script>
<template> <template>
<Navbar /><!-- Causes rerendering each time todo: possible use in App.vue--> <Navbar /><!-- Causes rerendering each time TODO: possible use in App.vue-->
<div class="about"> <div class="about">
<h1>This is an Arbeiten page</h1> <h1>This is an Arbeiten page</h1>
</div> </div>

View File

@@ -7,7 +7,7 @@ export default {
} }
</script> </script>
<template> <template>
<Navbar /><!-- Causes rerendering each time todo: possible use in App.vue--> <Navbar /><!-- Causes rerendering each time TODO: possible use in App.vue-->
<div class="about"> <div class="about">
<h1>This is an Contact page</h1> <h1>This is an Contact page</h1>
</div> </div>

View File

@@ -1,90 +1,93 @@
<template> <template>
<Navbar /> <Navbar />
<div class="flex justify-center py-5"> <div class="flex justify-center py-5">
<p class="text-3xl" v-if="currentContract"> {{ currentContract.name }} </p> <p v-if="currentContract" class="text-3xl">{{ currentContract.name }}</p>
</div> </div>
<div class="flex justify-center text-center pt-5"> <div class="flex justify-center text-center pt-5">
<ul class="flex border-b border-gray-200 text-center max-sm:overflow-x-scroll max-sm:overflow-y-hidden sm:w-2/3 "> <ul
<li class="flex-1 cursor-pointer" @click="changeTab('contract')"> class="flex border-b border-gray-200 text-center max-sm:overflow-x-scroll max-sm:overflow-y-hidden sm:w-2/3">
<p <li class="flex-1 cursor-pointer" @click="changeTab('contract')">
v-bind:class="{ <p
'block bg-gray-100 p-4 text-sm font-medium text-gray-500 ring-1 ring-inset ring-white': currentTab !== 'contract', :class="{
'relative block border-t border-l border-r border-gray-200 bg-white p-4 text-sm font-medium': currentTab === 'contract' 'block bg-gray-100 p-4 text-sm font-medium text-gray-500 ring-1 ring-inset ring-white':
}" currentTab !== 'contract',
> 'relative block border-t border-l border-r border-gray-200 bg-white p-4 text-sm font-medium':
<span class="absolute inset-x-0 -bottom-px h-px w-full bg-white" v-if="currentTab === 'contract'"></span> currentTab === 'contract'
Auftrag }">
</p> <span
</li> v-if="currentTab === 'contract'"
class="absolute inset-x-0 -bottom-px h-px w-full bg-white"></span>
<li class="flex-1 pl-px cursor-pointer" @click="changeTab('client')"> Auftrag
<p </p>
v-bind:class="{ </li>
'block bg-gray-100 p-4 text-sm font-medium text-gray-500 ring-1 ring-inset ring-white': currentTab !== 'client',
'relative block border-t border-l border-r border-gray-200 bg-white p-4 text-sm font-medium': currentTab === 'client' <li class="flex-1 pl-px cursor-pointer" @click="changeTab('client')">
}" <p
> :class="{
Auftraggeber 'block bg-gray-100 p-4 text-sm font-medium text-gray-500 ring-1 ring-inset ring-white':
</p> currentTab !== 'client',
</li> 'relative block border-t border-l border-r border-gray-200 bg-white p-4 text-sm font-medium':
currentTab === 'client'
<li class="flex-1 cursor-pointer" @click="changeTab('comments')"> }">
<p Auftraggeber
v-bind:class="{ </p>
'block bg-gray-100 p-4 text-sm font-medium text-gray-500 ring-1 ring-inset ring-white': currentTab !== 'comments', </li>
'relative block border-t border-l border-r border-gray-200 bg-white p-4 text-sm font-medium': currentTab === 'comments'
}" <li class="flex-1 cursor-pointer" @click="changeTab('comments')">
> <p
Comments :class="{
</p> 'block bg-gray-100 p-4 text-sm font-medium text-gray-500 ring-1 ring-inset ring-white':
</li> currentTab !== 'comments',
'relative block border-t border-l border-r border-gray-200 bg-white p-4 text-sm font-medium':
</ul> currentTab === 'comments'
</div> }">
<div class="flex justify-center text-left"> Comments
<div class="sm:w-2/3" v-if="currentContract"> </p>
<ContractTab v-bind:contract="currentContract" v-if="currentTab === 'contract'"/> </li>
<ClientTab v-bind:contract="currentContract" v-if="currentTab === 'client'"/> </ul>
<CommentsTab v-bind:contract="currentContract" v-if="currentTab === 'comments'"/> </div>
</div> <div class="flex justify-center text-left">
</div> <div v-if="currentContract" class="sm:w-2/3">
</template> <ContractTab v-if="currentTab === 'contract'" :contract="currentContract" />
<script> <ClientTab v-if="currentTab === 'client'" :contract="currentContract" />
import Navbar from "../components/Navbar.vue"; <CommentsTab v-if="currentTab === 'comments'" :contract="currentContract" />
import { mapActions, mapGetters } from "vuex"; </div>
import ClientTab from "../components/tabs/ClientTab.vue"; </div>
import ContractTab from "../components/tabs/ContractTab.vue"; </template>
import CommentsTab from "../components/tabs/CommentsTab.vue"; <script>
import Navbar from '../components/Navbar.vue'
export default { import { mapActions, mapGetters } from 'vuex'
components: { import ClientTab from '../components/tabs/ClientTab.vue'
CommentsTab, import ContractTab from '../components/tabs/ContractTab.vue'
ContractTab, import CommentsTab from '../components/tabs/CommentsTab.vue'
ClientTab,
Navbar export default {
}, components: {
data() { CommentsTab,
return { ContractTab,
currentTab: 'contract' ClientTab,
} Navbar
}, },
mounted() { data() {
const id = this.$route.query.id return {
if (id === null) { currentTab: 'contract'
this.$router.push('/error?message=' + 'Bad id' + '&code=404') //todo: check if works }
} },
this.fetchContractById(id) computed: {
}, ...mapGetters(['currentContract'])
methods: { },
...mapActions(['fetchContractById']), mounted() {
changeTab(tabName) { const id = this.$route.query.id
this.currentTab = tabName if (id === null) {
} this.$router.push('/error?message=' + 'Bad id' + '&code=404') //TODO: check if works
}, }
computed: { this.fetchContractById(id)
...mapGetters([ },
'currentContract', methods: {
]), ...mapActions(['fetchContractById']),
} changeTab(tabName) {
} this.currentTab = tabName
</script> }
}
}
</script>

View File

@@ -1,6 +1,6 @@
<script setup> <script setup>
import Navbar from '../components/Navbar.vue' import Navbar from '../components/Navbar.vue'
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
</script> </script>
<template> <template>
<Navbar /><!-- Causes rerendering each time todo: possible use in App.vue--> <Navbar /><!-- Causes rerendering each time todo: possible use in App.vue-->
@@ -15,50 +15,65 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
<div class="flex justify-center pb-6"> <div class="flex justify-center pb-6">
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<RouterLink v-if="isVerwaltung" to="/contract/create"> <RouterLink v-if="isVerwaltung" to="/contract/create">
<button class="bg-sky-500 text-white active:bg-sky-600 font-bold uppercase text-xs px-4 py-2 mb-3 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150" type="button" <button
> class="bg-sky-500 text-white active:bg-sky-600 font-bold uppercase text-xs px-4 py-2 mb-3 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 ease-linear transition-all duration-150"
type="button">
Create Auftrag Create Auftrag
</button> </button>
</RouterLink> </RouterLink>
<RouterLink v-if="isEmployee" to="/contracts/register"> <RouterLink v-if="isEmployee" to="/contracts/register">
<button class="bg-emerald-500 text-white active:bg-emerald-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150" type="button" <button
> class="bg-emerald-500 text-white active:bg-emerald-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
<font-awesome-icon icon="fa-solid fa-pen-to-square" class="pr-1 h-3.5"/> Für Auftrag anmelden type="button">
<font-awesome-icon icon="fa-solid fa-pen-to-square" class="pr-1 h-3.5" /> Für Auftrag
anmelden
</button> </button>
</RouterLink> </RouterLink>
<table class="min-w-full border-collapse bg-white border border-gray-600"> <table class="min-w-full border-collapse bg-white border border-gray-600">
<thead class="bg-gray-800 text-white"> <thead class="bg-gray-800 text-white">
<tr> <tr>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Id</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Id</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Name</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Name</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Status</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Status</th>
<th class="w-1/3 text-left py-3 px-4 uppercase font-semibold text-sm text-center">Mitarbeiter</th> <th class="w-1/3 py-3 px-4 uppercase font-semibold text-sm text-center">Mitarbeiter</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Updated</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Updated</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Aktion</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Aktion</th>
</tr> </tr>
</thead> </thead>
<tbody class="text-gray-700"> <tbody class="text-gray-700">
<tr v-for="(contract, index) in contracts" :key="contract.id" :class="{ 'bg-gray-100': index % 2 !== 0 }"> <tr
<td class="text-left py-3 px-4 text-center">{{ contract.id }}</td> v-for="(contract, index) in contracts"
<td class="text-left py-3 px-4 text-center">{{ contract.name }}</td> :key="contract.id"
<td class="text-left py-3 px-4 text-center"> :class="{ 'bg-gray-100': index % 2 !== 0 }">
<!-- todo: set color specific from status. for colors use https://www.creative-tim.com/learning-lab/tailwind-starter-kit/documentation/css/labels --> <td class="py-3 px-4 text-center">{{ contract.id }}</td>
<span class="text-emerald-600 bg-emerald-200 rounded-full py-1 px-2">{{ contract.status }}</span> <td class="py-3 px-4 text-center">{{ contract.name }}</td>
<td class="py-3 px-4 text-center">
<!-- TODO: set color specific from status. for colors use https://www.creative-tim.com/learning-lab/tailwind-starter-kit/documentation/css/labels -->
<span class="text-emerald-600 bg-emerald-200 rounded-full py-1 px-2">{{
contract.status
}}</span>
</td>
<td class="py-3 px-4 text-center">{{ contract.mitarbeiter.join(', ') }}</td>
<td class="py-3 px-4 text-center">
{{ new Date(contract.updatedAt).toDateString() }}
</td> </td>
<td class="text-left py-3 px-4 text-center">{{ contract.mitarbeiter.join(', ') }}</td>
<td class="text-left py-3 px-4 text-center">{{ new Date(contract.updatedAt).toDateString() }}</td>
<td class="text-left py-2"> <td class="text-left py-2">
<button v-if="isVerwaltung" @click="openDeleteDialog()" class="bg-red-500 text-white active:bg-red-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150" type="button" <button
> v-if="isVerwaltung"
class="bg-red-500 text-white active:bg-red-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
type="button"
@click="openDeleteDialog()">
Delete Delete
</button> </button>
<button class="bg-amber-500 text-white active:bg-amber-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150" type="button" <button
> class="bg-amber-500 text-white active:bg-amber-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
type="button">
Update Update
</button> </button>
<RouterLink to="/contract?id=TESTID"> <RouterLink to="/contract?id=TESTID">
<button class="bg-emerald-500 text-white active:bg-emerald-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150" type="button" <button
> class="bg-emerald-500 text-white active:bg-emerald-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
type="button">
View View
</button> </button>
</RouterLink> </RouterLink>
@@ -70,20 +85,9 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
</div> </div>
</template> </template>
<script> <script>
import { mapActions } from "vuex"; import { mapActions } from 'vuex'
export default { export default {
mounted() {
this.fetchContracts()
},
methods: {
...mapActions([
'fetchContracts'
]),
openDeleteDialog() {
console.log("Prepare to delete")
}
},
computed: { computed: {
contracts() { contracts() {
return this.$store.state.contracts.contracts return this.$store.state.contracts.contracts
@@ -91,9 +95,18 @@ export default {
isVerwaltung() { isVerwaltung() {
return this.$store.state.keycloak.keycloak.realmAccess.roles.includes('verwaltung') return this.$store.state.keycloak.keycloak.realmAccess.roles.includes('verwaltung')
}, },
isEmployee(){ isEmployee() {
return this.$store.state.keycloak.keycloak.realmAccess.roles.includes('employee') return this.$store.state.keycloak.keycloak.realmAccess.roles.includes('employee')
} }
},
mounted() {
this.fetchContracts()
},
methods: {
...mapActions(['fetchContracts']),
openDeleteDialog() {
console.log('Prepare to delete')
}
} }
} }
</script> </script>

View File

@@ -1,55 +1,47 @@
<script setup> <script setup>
import Navbar from '../components/Navbar.vue' import Navbar from '../components/Navbar.vue'
</script> </script>
<template> <template>
<Navbar/> <Navbar />
<div <div class="flex items-center justify-center bg-gradient-to-r from-indigo-600 to-blue-400 py-10">
class=" <div class="md:px-40 md:py-20 bg-white rounded-md shadow-xl">
flex <div class="flex flex-col items-center">
items-center <h1 class="font-bold text-blue-600 text-3xl">{{ code }}</h1>
justify-center
bg-gradient-to-r <h6 class="mb-2 text-2xl font-bold text-center text-gray-800 md:text-3xl">
from-indigo-600 <span class="text-red-500">Oops!</span> Error happend
to-blue-400 </h6>
py-10
" <p class="mb-8 text-center text-gray-500 md:text-lg">
> {{ message }}
<div class="md:px-40 md:py-20 bg-white rounded-md shadow-xl"> </p>
<div class="flex flex-col items-center">
<h1 class="font-bold text-blue-600 text-3xl">{{code}}</h1> <div class="pb-10">
<a
<h6 class="mb-2 text-2xl font-bold text-center text-gray-800 md:text-3xl"> class="px-6 py-2 mr-4 text-sm font-semibold text-blue-800 bg-blue-100"
<span class="text-red-500">Oops!</span> Error happend @click="navigateToPrevious()">
</h6> Zurück
</a>
<p class="mb-8 text-center text-gray-500 md:text-lg"> <RouterLink to="/" class="px-6 py-2 text-sm font-semibold text-blue-800 bg-blue-100">
{{ message }} Go Home
</p> </RouterLink>
</div>
<div class="pb-10"> </div>
<a @click="navigateToPrevious()" class="px-6 py-2 mr-4 text-sm font-semibold text-blue-800 bg-blue-100"> </div>
Zurück </div>
</a> </template>
<RouterLink to="/" class="px-6 py-2 text-sm font-semibold text-blue-800 bg-blue-100"> <script>
Go Home export default {
</RouterLink> data() {
</div> return {
</div> message: this.$route.query.message,
</div> code: this.$route.query.code
</div> }
</template> },
<script> methods: {
export default { navigateToPrevious() {
data(){ this.$router.back()
return { }
message: this.$route.query.message, }
code: this.$route.query.code }
} </script>
},
methods:{
navigateToPrevious() {
this.$router.back()
}
}
}
</script>

View File

@@ -7,7 +7,7 @@ export default {
} }
</script> </script>
<template> <template>
<Navbar /><!-- Causes rerendering each time todo: possible use in App.vue--> <Navbar /><!-- Causes rerendering each time TODO: possible use in App.vue-->
<div class="about"> <div class="about">
<h1>This is a Home page</h1> <h1>This is a Home page</h1>
</div> </div>

View File

@@ -2,7 +2,7 @@
import Navbar from '../components/Navbar.vue' import Navbar from '../components/Navbar.vue'
</script> </script>
<template> <template>
<Navbar /><!-- Causes rerendering each time todo: possible use in App.vue--> <Navbar /><!-- Causes rerendering each time TODO: possible use in App.vue-->
<div class="flex justify-center pt-8 pb-8"> <div class="flex justify-center pt-8 pb-8">
<p <p
class="text-2xl md:text-2xl lg:text-3xl xl:text-4xl 2xl:text-5xl font-serif font-medium tracking-wide flex justify-center items-center"> class="text-2xl md:text-2xl lg:text-3xl xl:text-4xl 2xl:text-5xl font-serif font-medium tracking-wide flex justify-center items-center">
@@ -13,51 +13,65 @@ import Navbar from '../components/Navbar.vue'
</div> </div>
<div class="flex justify-center pb-6"> <div class="flex justify-center pb-6">
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<table v-if="openContracts" class="min-w-full border-collapse bg-white border border-gray-600"> <table
v-if="openContracts"
class="min-w-full border-collapse bg-white border border-gray-600">
<thead class="bg-gray-800 text-white"> <thead class="bg-gray-800 text-white">
<tr> <tr>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Id</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Id</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Name</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Name</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Status</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Status</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Planed Date</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Planed Date</th>
<th class="w-1/3 text-left py-3 px-4 uppercase font-semibold text-sm text-center">Notes</th> <th class="w-1/3 py-3 px-4 uppercase font-semibold text-sm text-center">Notes</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm text-center">Aktion</th> <th class="py-3 px-4 uppercase font-semibold text-sm text-center">Aktion</th>
</tr> </tr>
</thead> </thead>
<tbody class="text-gray-700"> <tbody class="text-gray-700">
<tr v-for="(contract, index) in openContracts" :key="contract.id" :class="{ 'bg-gray-100': index % 2 !== 0 }"> <tr
<td class="text-left py-3 px-4 text-center">{{ contract.id }}</td> v-for="(contract, index) in openContracts"
<td class="text-left py-3 px-4 text-center">{{ contract.name }}</td> :key="contract.id"
<td class="text-left py-3 px-4 text-center"> :class="{ 'bg-gray-100': index % 2 !== 0 }">
<!-- todo: set color specific from status. for colors use https://www.creative-tim.com/learning-lab/tailwind-starter-kit/documentation/css/labels --> <td class="py-3 px-4 text-center">{{ contract.id }}</td>
<span class="text-emerald-600 bg-emerald-200 rounded-full py-1 px-2">{{ contract.status }}</span> <td class="py-3 px-4 text-center">{{ contract.name }}</td>
</td> <td class="py-3 px-4 text-center">
<td class="text-left py-3 px-4 text-center">{{ new Date(contract.appointment).toDateString() }}</td> <!-- TODO: set color specific from status. for colors use https://www.creative-tim.com/learning-lab/tailwind-starter-kit/documentation/css/labels -->
<td class="text-left py-3 px-4 text-center">{{ contract.notes }}</td> <span class="text-emerald-600 bg-emerald-200 rounded-full py-1 px-2">{{
<td class="text-left py-2"> contract.status
<RouterLink to="/contract?id=TESTID"> }}</span>
<button class="bg-blue-500 text-white active:bg-emerald-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150" type="button" </td>
> <td class="py-3 px-4 text-center">
View {{ new Date(contract.appointment).toDateString() }}
</td>
<td class="py-3 px-4 text-center">{{ contract.notes }}</td>
<td class="text-left py-2">
<RouterLink to="/contract?id=TESTID">
<button
class="bg-blue-500 text-white active:bg-emerald-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
type="button">
View
</button>
</RouterLink>
<button
class="bg-emerald-500 text-white active:bg-emerald-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
type="button"
@click="openDialog('register')">
Anmelden
</button> </button>
</RouterLink> <button
<button @click="openDialog('register')" class="bg-emerald-500 text-white active:bg-emerald-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150" type="button" class="bg-red-500 text-white active:bg-red-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
> type="button"
Anmelden @click="openDialog('deregister')">
</button> Abmelden
<button @click="openDialog('deregister')" class="bg-red-500 text-white active:bg-red-600 font-bold uppercase text-xs px-4 py-2 rounded shadow hover:shadow-md outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150" type="button" </button>
> </td>
Abmelden </tr>
</button>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapActions } from "vuex"; import { mapActions } from 'vuex'
export default { export default {
data() { data() {
@@ -65,21 +79,19 @@ export default {
dialog: null dialog: null
} }
}, },
mounted() {
this.fetchOpenContracts()
},
methods: {
...mapActions([
'fetchOpenContracts'
]),
openDialog(name) {
this.dialog = name
}
},
computed: { computed: {
openContracts() { openContracts() {
return this.$store.state.contracts.openContracts return this.$store.state.contracts.openContracts
} }
},
mounted() {
this.fetchOpenContracts()
},
methods: {
...mapActions(['fetchOpenContracts']),
openDialog(name) {
this.dialog = name
}
} }
} }
</script> </script>

View File

@@ -7,7 +7,7 @@ export default {
} }
</script> </script>
<template> <template>
<Navbar /><!-- Causes rerendering each time todo: possible use in App.vue--> <Navbar /><!-- Causes rerendering each time TODO: possible use in App.vue-->
<div class="about"> <div class="about">
<h1>This is an Support page</h1> <h1>This is an Support page</h1>
</div> </div>

5
volar.config.js Normal file
View File

@@ -0,0 +1,5 @@
const vetur = require('@volar-plugins/vetur');
module.exports = {
plugins: [vetur()]
}