@@ -5,15 +5,17 @@ import { RouterView } from 'vue-router'
|
|||||||
<template>
|
<template>
|
||||||
<RegisterModal v-if="modal === 'register'" />
|
<RegisterModal v-if="modal === 'register'" />
|
||||||
<DeregisterModal v-if="modal === 'deregister'" />
|
<DeregisterModal v-if="modal === 'deregister'" />
|
||||||
|
<CreateModal v-if="modal === 'createContract'" />
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex'
|
import { mapActions } from 'vuex'
|
||||||
|
import CreateModal from './components/modals/CreateModal.vue'
|
||||||
import DeregisterModal from './components/modals/DeregisterModal.vue'
|
import DeregisterModal from './components/modals/DeregisterModal.vue'
|
||||||
import RegisterModal from './components/modals/RegisterModal.vue'
|
import RegisterModal from './components/modals/RegisterModal.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { DeregisterModal, RegisterModal },
|
components: { DeregisterModal, RegisterModal, CreateModal },
|
||||||
computed: {
|
computed: {
|
||||||
modal() {
|
modal() {
|
||||||
return this.$store.state.modal.modal
|
return this.$store.state.modal.modal
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
export default axios.create({
|
export default axios.create({
|
||||||
baseURL: 'https://5f672efd-7bb4-4147-b5f7-64d3fa1a3873.mock.pstmn.io/',
|
baseURL: 'https://0100a919-8f1d-4f29-910c-a6955ea84e40.mock.pstmn.io/',
|
||||||
timeout: 4000
|
timeout: 4000
|
||||||
})
|
})
|
||||||
|
|||||||
132
src/components/modals/CreateModal.vue
Normal file
132
src/components/modals/CreateModal.vue
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
id="popup-modal"
|
||||||
|
tabindex="-1"
|
||||||
|
class="fixed top-0 left-0 right-0 z-50 flex justify-center text-center p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-modal md:h-full">
|
||||||
|
<div class="relative w-full h-full max-w-md md:h-auto">
|
||||||
|
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="absolute top-3 right-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-800 dark:hover:text-white"
|
||||||
|
data-modal-hide="popup-modal"
|
||||||
|
@click="closeModal()">
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="w-5 h-5"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
||||||
|
clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">Close modal</span>
|
||||||
|
</button>
|
||||||
|
<div class="p-6 text-center">
|
||||||
|
<p class="text-xl font-semibold font-sans">Create Auftrag</p>
|
||||||
|
<p v-for="error of v$.$errors" :key="error.$uid" class="text-red-900">
|
||||||
|
<strong>{{ error.$message }}</strong>
|
||||||
|
</p>
|
||||||
|
<div class="pt-3">
|
||||||
|
<label
|
||||||
|
for="base-input"
|
||||||
|
class="text-left block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||||
|
>Auftragsnummer</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="base-input"
|
||||||
|
v-model="id"
|
||||||
|
type="text"
|
||||||
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" />
|
||||||
|
</div>
|
||||||
|
<div class="pt-3">
|
||||||
|
<label
|
||||||
|
for="base-input"
|
||||||
|
class="text-left block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||||
|
>Name</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="base-input"
|
||||||
|
v-model="name"
|
||||||
|
type="text"
|
||||||
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" />
|
||||||
|
</div>
|
||||||
|
<div class="pt-3">
|
||||||
|
<label
|
||||||
|
for="base-input"
|
||||||
|
class="text-left block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||||
|
>Auftraggeber</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="base-input"
|
||||||
|
v-model="auftraggeber"
|
||||||
|
type="text"
|
||||||
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" />
|
||||||
|
</div>
|
||||||
|
<div class="pt-3">
|
||||||
|
<label
|
||||||
|
for="base-input"
|
||||||
|
class="text-left block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||||
|
>Passwort</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="base-input"
|
||||||
|
v-model="password"
|
||||||
|
type="password"
|
||||||
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" />
|
||||||
|
</div>
|
||||||
|
<div class="pt-3">
|
||||||
|
<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="createContract()">
|
||||||
|
Create Auftrag
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapActions } from 'vuex'
|
||||||
|
import { createContract as serviceCreateContract } from '../../service/ContractsService'
|
||||||
|
import { useVuelidate } from '@vuelidate/core'
|
||||||
|
import { required, minLength } from '../../main'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
v$: useVuelidate()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
auftraggeber: '',
|
||||||
|
password: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validations() {
|
||||||
|
return {
|
||||||
|
id: { required },
|
||||||
|
name: { required },
|
||||||
|
auftraggeber: { required },
|
||||||
|
password: { required, minLength: minLength(7) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
methods: {
|
||||||
|
...mapActions(['closeModal']),
|
||||||
|
async createContract() {
|
||||||
|
const isFormCorrect = await this.v$.$validate()
|
||||||
|
if (!isFormCorrect) return
|
||||||
|
|
||||||
|
serviceCreateContract(this.id, this.name, this.auftraggeber, this.password)
|
||||||
|
this.closeModal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -3,8 +3,10 @@ import en from './locales/en.json'
|
|||||||
import de from './locales/de.json'
|
import de from './locales/de.json'
|
||||||
export const SUPPORT_LOCALES = ['en', 'de']
|
export const SUPPORT_LOCALES = ['en', 'de']
|
||||||
|
|
||||||
|
export let instance = null
|
||||||
|
|
||||||
export function createI18n() {
|
export function createI18n() {
|
||||||
return _createI18n({
|
instance = _createI18n({
|
||||||
legacy: false,
|
legacy: false,
|
||||||
globalInjection: true,
|
globalInjection: true,
|
||||||
locale: 'de',
|
locale: 'de',
|
||||||
@@ -14,4 +16,5 @@ export function createI18n() {
|
|||||||
de
|
de
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
return instance
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,9 @@
|
|||||||
"hello": "Hallo i18n in SFC!",
|
"hello": "Hallo i18n in SFC!",
|
||||||
"welcome": "Willkommen!",
|
"welcome": "Willkommen!",
|
||||||
"yes-button": "Ja",
|
"yes-button": "Ja",
|
||||||
"no-button": "Nein!"
|
"no-button": "Nein!",
|
||||||
|
"validations": {
|
||||||
|
"required": "{property} ist erforerlig.",
|
||||||
|
"minLength": "Das Feld {property} muss eine Mindestlänge von {min} haben."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,5 +2,9 @@
|
|||||||
"hello": "Hello i18n in SFC!",
|
"hello": "Hello i18n in SFC!",
|
||||||
"welcome": "Welcome!",
|
"welcome": "Welcome!",
|
||||||
"yes-button": "Yes",
|
"yes-button": "Yes",
|
||||||
"no-button": "No!"
|
"no-button": "No!",
|
||||||
|
"validations": {
|
||||||
|
"required": "{property} is required.",
|
||||||
|
"minLength": "The {property} field has a value of '{model}', but it must have a min length of {min}."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
12
src/main.js
12
src/main.js
@@ -3,6 +3,7 @@ import App from './App.vue'
|
|||||||
import router from './router'
|
import router from './router'
|
||||||
import { createI18n } from './i18n'
|
import { createI18n } from './i18n'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
|
import * as validators from '@vuelidate/validators'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||||
import {
|
import {
|
||||||
@@ -30,6 +31,17 @@ library.add(faChalkboardUser)
|
|||||||
|
|
||||||
const i18n = createI18n()
|
const i18n = createI18n()
|
||||||
|
|
||||||
|
const { createI18nMessage } = validators
|
||||||
|
|
||||||
|
const withI18nMessage = createI18nMessage({ t: i18n.global.t.bind(i18n) })
|
||||||
|
|
||||||
|
// wrap each validator.
|
||||||
|
export const required = withI18nMessage(validators.required)
|
||||||
|
// validators that expect a parameter should have `{ withArguments: true }` passed as a second parameter, to annotate they should be wrapped
|
||||||
|
export const minLength = withI18nMessage(validators.minLength, { withArguments: true })
|
||||||
|
// or you can provide the param at definition, statically
|
||||||
|
export const maxLength = withI18nMessage(validators.maxLength(10))
|
||||||
|
|
||||||
let app = createApp(App)
|
let app = createApp(App)
|
||||||
|
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
|||||||
@@ -74,3 +74,20 @@ export async function misapply(contractID) {
|
|||||||
router.push('/error?message=' + error.message + '&code=' + error.code)
|
router.push('/error?message=' + error.message + '&code=' + error.code)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createContract(contractId, contractName, contractClient, contractPassword) {
|
||||||
|
return HttpClient.post('/contract/create', {
|
||||||
|
id: contractId,
|
||||||
|
name: contractName,
|
||||||
|
client: contractClient,
|
||||||
|
password: contractPassword
|
||||||
|
})
|
||||||
|
.then(resp => {
|
||||||
|
//TODO: send also auth token with request
|
||||||
|
return resp.data
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error)
|
||||||
|
router.push('/error?message=' + error.message + '&code=' + error.code)
|
||||||
|
})
|
||||||
|
}
|
||||||
19
src/views/ClientContractView.vue
Normal file
19
src/views/ClientContractView.vue
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<Navbar />
|
||||||
|
<div>
|
||||||
|
<h3 class="text-base font-semibold">Step 3: Fill in order details</h3>
|
||||||
|
<div class="flex space-x-3 justify-center pt-2">
|
||||||
|
<span class="w-12 h-2 rounded-sm bg-emerald-500"></span>
|
||||||
|
<span class="w-12 h-2 rounded-sm bg-emerald-500"></span>
|
||||||
|
<span class="w-12 h-2 rounded-sm bg-gray-400"></span>
|
||||||
|
<span class="w-12 h-2 rounded-sm bg-gray-700"></span>
|
||||||
|
<span class="w-12 h-2 rounded-sm bg-gray-700"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import Navbar from '../components/Navbar.vue'
|
||||||
|
export default {
|
||||||
|
components: { Navbar }
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -14,13 +14,12 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
|||||||
</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">
|
||||||
<RouterLink v-if="isVerwaltung" to="/contract/create">
|
<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"
|
||||||
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"
|
||||||
type="button">
|
@click="openModal('createContract')">
|
||||||
Create Auftrag
|
Create Auftrag
|
||||||
</button>
|
</button>
|
||||||
</RouterLink>
|
|
||||||
<RouterLink v-if="isEmployee" to="/contracts/open">
|
<RouterLink v-if="isEmployee" to="/contracts/open">
|
||||||
<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"
|
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"
|
||||||
@@ -103,7 +102,7 @@ export default {
|
|||||||
this.fetchContracts()
|
this.fetchContracts()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['fetchContracts']),
|
...mapActions(['fetchContracts', 'openModal']),
|
||||||
openDeleteDialog() {
|
openDeleteDialog() {
|
||||||
console.log('Prepare to delete')
|
console.log('Prepare to delete')
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user