* Page with open contracts

feature: #8
This commit is contained in:
2023-01-07 00:34:41 +01:00
parent aff1564b64
commit 3b417c9ddd
6 changed files with 152 additions and 18 deletions

View File

@@ -39,13 +39,9 @@
"raw": ""
},
"url": {
"raw": "https://88c09a70-ab85-412a-9bd3-407afe8986a1.mock.pstmn.io/contracts",
"protocol": "https",
"raw": "{{url}}/contracts",
"host": [
"88c09a70-ab85-412a-9bd3-407afe8986a1",
"mock",
"pstmn",
"io"
"{{url}}"
],
"path": [
"contracts"
@@ -90,13 +86,9 @@
"raw": ""
},
"url": {
"raw": "https://88c09a70-ab85-412a-9bd3-407afe8986a1.mock.pstmn.io/contracts",
"protocol": "https",
"raw": "{{url}}/contracts",
"host": [
"88c09a70-ab85-412a-9bd3-407afe8986a1",
"mock",
"pstmn",
"io"
"{{url}}"
],
"path": [
"contracts"
@@ -161,6 +153,36 @@
"body": " {\r\n \"id\" : \"DZ2022\",\r\n \"name\" : \"Jugendamt Title\",\r\n \"status\" : \"eingelegt\",\r\n \"mitarbeiter\" : [\r\n {\r\n \"name\" : \"Max Musterman\",\r\n \"role\" : \"Leiter\",\r\n \"phone\" : \"+4915254444444\",\r\n \"email\" : \"max.musterman@gmail.com\"\r\n },\r\n {\r\n \"name\" : \"John Doe\",\r\n \"role\" : \"Producer\",\r\n \"phone\" : null,\r\n \"email\" : \"john.doe@gmail.com\"\r\n }\r\n ],\r\n \"unterlagen\" : [\r\n {\r\n \"name\" : \"Name1.pdf\",\r\n \"url\" : \"https://denysoft.de/\"\r\n },\r\n {\r\n \"name\" : \"Name2.pdf\",\r\n \"url\" : \"https://denysoft.de/\"\r\n }\r\n ],\r\n \"beschreibung\" : \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas tempus justo quis magna rutrum, quis feugiat velit commodo. Vivamus semper massa auctor, rutrum nisl eget, faucibus massa. Vivamus ac ex tellus. Nullam a venenatis odio. Aenean sed tincidunt erat. In id elementum justo. Nullam pulvinar non leo non congue. Quisque eget orci id nulla tristique imperdiet.\\nCras sed orci eget mauris fermentum mattis at et magna. Integer vel purus ut nulla dignissim suscipit at sit amet neque. Proin lectus arcu, pretium ac molestie vitae, mollis nec lectus. Aliquam posuere lectus at purus porttitor dignissim. Sed et mi ultrices nisi bibendum laoreet faucibus nec arcu. Duis imperdiet eleifend tellus vel suscipit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec molestie leo eleifend ex ultricies viverra. Praesent blandit, purus in dictum hendrerit, sapien risus ultricies lorem, at condimentum ex urna sit amet dolor. Morbi sed felis vestibulum, consequat nibh vel, faucibus eros.\\nAenean venenatis nibh non nisl ornare, sit amet eleifend ipsum tincidunt. Phasell\",\r\n \"address\" : \"Gottfried-Kiesow-Platz 2, 02826 Goerlitz\",\r\n \"examples\" : [\r\n \"https://www.youtube.com/watch?v=AED0kfEdwk8\",\r\n \"https://www.youtube.com/watch?v=AED0kfEdwk8\",\r\n \"https://www.youtube.com/watch?v=AED0kfEdwk8\"\r\n ],\r\n \"client\" : {\r\n \"name\" : \"Jugendamt Cloppenburg\",\r\n \"contactPerson\" : \"John Doe\",\r\n \"address\" : \"Gottfried-Kiesow-Platz 2, 02826 Goerlitz\",\r\n \"email\" : \"john.doe@jugendamt.cloppenburg\",\r\n \"phone\" : \"+4915253333333\"\r\n },\r\n \"comments\" : [\r\n {\r\n \"name\" : \"John Doe\",\r\n \"message\" : \"Lorem ipsum dolor sit amet, consectetur adipiscing elit.\",\r\n \"date\" : \"2020-01-01T12:00:00Z\"\r\n },\r\n {\r\n \"name\" : \"Max Musterman\",\r\n \"message\" : \"Vivamus semper massa auctor, rutrum nisl eget, faucibus massa.\",\r\n \"date\" : \"2021-01-01T12:00:00Z\"\r\n },\r\n {\r\n \"name\" : \"Andre Doe\",\r\n \"message\" : \"Lorem ipsum dolor sit amet, consectetur adipiscing elit.\",\r\n \"date\" : \"2021-01-01T18:00:00Z\"\r\n }\r\n ]\r\n }"
}
]
},
{
"name": "Get Open Contracts",
"request": {
"method": "GET",
"header": []
},
"response": [
{
"name": "Get Open Contracts",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{url}}/contracts/register",
"host": [
"{{url}}"
],
"path": [
"contracts",
"register"
]
}
},
"_postman_previewlanguage": null,
"header": null,
"cookie": [],
"body": "{\r\n \"openContracts\": [\r\n {\r\n \"id\" : \"DZ22\",\r\n \"name\" : \"Name1\",\r\n \"status\" : \"open\",\r\n \"appointment\" : \"2020-01-01T12:00:00Z\",\r\n \"notes\" : \"From Feb 2023 To March 2023\"\r\n },\r\n {\r\n \"id\" : \"PC22\",\r\n \"name\" : \"Name2\",\r\n \"status\" : \"open\",\r\n \"appointment\" : \"2020-01-12T12:00:00Z\",\r\n \"notes\" : \"From Feb 2023 To March 2023\"\r\n }\r\n ]\r\n}"
}
]
}
],
"variable": [

View File

@@ -75,7 +75,16 @@ const router = createRouter({
// this page is lazy-loaded when the route is visited.
component: () => import('../views/ContractView.vue'),
meta: {
requiresAuth: false
requiresAuth: true
}
},
{
path: '/contracts/register',
name: 'contractRegistration',
// this page is lazy-loaded when the route is visited.
component: () => import('../views/OpenContractsView.vue'),
meta: {
requiresAuth: true
}
},
{

View File

@@ -16,6 +16,19 @@ export async function getContracts() {
})
}
//REST: GET /contracts
//Auth: provide auth token in request
//OnError: redirect to page /error?message=somemessage&code=404
export async function getOpenContracts() {
return HttpClient.get('contracts/register') //todo: provide here auth header
.then(resp => {
return resp.data.openContracts
})
.catch(error => {
router.push('/error?message=' + error.message + '&code=' + error.code)
})
}
//Request in order to retrieve specific contract using ID
//Backend: extra roles check. Allow admin, verwaltung, employee.
//REST: GET /contract?id=someId

View File

@@ -1,14 +1,18 @@
import { getContracts, getContractById } from '../service/ContractsService'
import { getContracts, getContractById, getOpenContracts } from '../service/ContractsService'
export default {
state: () => ({
contracts: [],
currentContract: null
currentContract: null,
openContracts: []
}),
mutations: {
initContracts(state, data) {
state.contracts = data
},
initOpenContracts(state, data) {
state.openContracts = data
},
setCurrentContract(state, data) {
state.currentContract = data
}
@@ -22,6 +26,10 @@ export default {
const contract = await getContractById(id)
commit('setCurrentContract', contract)
return state.currentContract
},
async fetchOpenContracts({ commit }) {
const openContracts = await getOpenContracts()
commit('initOpenContracts', openContracts)
}
},
getters: {

View File

@@ -82,9 +82,6 @@ export default {
}
},
computed: {
currentContract() {
return this.$store.state.contracts.currentContract
},
...mapGetters([
'currentContract',
]),

View File

@@ -0,0 +1,85 @@
<script setup>
import Navbar from '../components/Navbar.vue'
</script>
<template>
<Navbar /><!-- Causes rerendering each time todo: possible use in App.vue-->
<div class="flex justify-center pt-8 pb-8">
<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">
<span class="inline-block w-5 h-1 mr-4 bg-gray-900 ::before"></span>
Offene Aufträge
<span class="inline-block w-5 h-1 ml-4 bg-gray-900 ::after"></span>
</p>
</div>
<div class="flex justify-center pb-6">
<div class="overflow-x-auto">
<table v-if="openContracts" class="min-w-full border-collapse bg-white border border-gray-600">
<thead class="bg-gray-800 text-white">
<tr>
<th class="text-left 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="text-left 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="w-1/3 text-left 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>
</tr>
</thead>
<tbody class="text-gray-700">
<tr v-for="(contract, index) in openContracts" :key="contract.id" :class="{ 'bg-gray-100': index % 2 !== 0 }">
<td class="text-left py-3 px-4 text-center">{{ contract.id }}</td>
<td class="text-left py-3 px-4 text-center">{{ contract.name }}</td>
<td class="text-left 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="text-left py-3 px-4 text-center">{{ new Date(contract.appointment).toDateString() }}</td>
<td class="text-left 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 @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"
>
Anmelden
</button>
<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"
>
Abmelden
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
import { mapActions } from "vuex";
export default {
data() {
return {
dialog: null
}
},
mounted() {
this.fetchOpenContracts()
},
methods: {
...mapActions([
'fetchOpenContracts'
]),
openDialog(name) {
this.dialog = name
}
},
computed: {
openContracts() {
return this.$store.state.contracts.openContracts
}
}
}
</script>