Edit client detail

This commit is contained in:
Peter Papp
2021-04-29 10:54:10 +02:00
parent 19bce195b4
commit 834b0ba5e0
11 changed files with 597 additions and 47 deletions
@@ -0,0 +1,162 @@
<template>
<div id="single-page">
<div id="page-content" v-if="! isLoading">
<MobileHeader :title="$router.currentRoute.meta.title" />
<PageHeader :can-back="true" :title="$router.currentRoute.meta.title" />
<div class="content-page">
<!--Client thumbnail-->
<div class="user-thumbnail">
<div class="avatar">
<img :src="client.avatar" :alt="client.name">
</div>
<div class="info">
<b class="name">{{ client.name }}</b>
<span class="email">{{ client.email }}</span>
</div>
</div>
<!--Page Tab links-->
<div class="menu-list-wrapper horizontal">
<router-link replace :to="{name: 'ClientDetail'}" class="menu-list-item link border-bottom-theme">
<div class="icon text-theme">
<user-icon size="17" />
</div>
<div class="label text-theme">
{{ $t('admin_page_user.tabs.detail') }}
</div>
</router-link>
<router-link replace :to="{name: 'UserInvoices'}" class="menu-list-item link border-bottom-theme">
<div class="icon text-theme">
<file-text-icon size="17" />
</div>
<div class="label text-theme">
{{ $t('admin_page_user.tabs.invoices') }}
</div>
</router-link>
<router-link replace :to="{name: 'UserDelete'}" class="menu-list-item link border-bottom-theme">
<div class="icon text-theme">
<trash2-icon size="17" />
</div>
<div class="label text-theme">
Delete Client
</div>
</router-link>
</div>
<!--Router Content-->
<router-view :client="client" @reload-user="fetchUser" />
</div>
</div>
<div id="loader" v-if="isLoading">
<Spinner />
</div>
</div>
</template>
<script>
import {UserIcon, Trash2Icon, FileTextIcon} from 'vue-feather-icons'
import MobileHeader from '@/components/Mobile/MobileHeader'
import SectionTitle from '@/components/Others/SectionTitle'
import PageHeader from '@/components/Others/PageHeader'
import Spinner from '@/components/FilesView/Spinner'
import axios from 'axios'
export default {
name: 'Client',
components: {
SectionTitle,
FileTextIcon,
MobileHeader,
PageHeader,
Trash2Icon,
UserIcon,
Spinner,
},
data() {
return {
isLoading: true,
client: undefined,
}
},
methods: {
fetchUser() {
axios.get(`/api/oasis/clients/${this.$route.params.id}`)
.then(response => {
this.client = response.data
})
.finally(() => {
this.isLoading = false
})
}
},
created() {
this.fetchUser()
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.user-thumbnail {
display: flex;
align-items: center;
cursor: pointer;
padding-bottom: 10px;
padding-top: 15px;
.avatar {
margin-right: 20px;
position: relative;
img {
line-height: 0;
width: 62px;
height: 62px;
border-radius: 12px;
z-index: 1;
position: relative;
&.blurred {
@include blurred-image;
top: 0;
}
}
}
.info {
.name {
display: block;
@include font-size(17);
line-height: 1;
}
.email {
color: $text-muted;
@include font-size(14);
}
}
}
@media only screen and (max-width: 960px) {
}
@media (prefers-color-scheme: dark) {
.user-thumbnail {
.info {
.email {
color: $dark_mode_text_secondary;
}
}
}
}
</style>
@@ -0,0 +1,152 @@
<template>
<PageTab class="form-fixed-width">
<PageTabGroup class="form block-form">
<FormLabel>Company & Logo</FormLabel>
<div class="block-wrapper">
<label>Logo (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="avatar" v-slot="{ errors }">
<ImageInput @input="$updateImage(`/oasis/clients/${client.id}`, 'avatar', client.avatar)" v-model="client.avatar" :image="client.avatar" :error="errors[0]" />
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Company name:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="name" rules="required" v-slot="{ errors }">
<input @input="$updateText(`/oasis/clients/${client.id}`, 'name', client.name)" v-model="client.name" placeholder="" type="text" :class="{'is-error': errors[0]}" class="focus-border-theme" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
</PageTabGroup>
<PageTabGroup class="form block-form">
<FormLabel>Company Details</FormLabel>
<div class="block-wrapper">
<label>ICO:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="ico" rules="required" v-slot="{ errors }">
<input @input="$updateText(`/oasis/clients/${client.id}`, 'ico', client.ico)" v-model="client.ico" placeholder="" type="text" :class="{'is-error': errors[0]}" class="focus-border-theme" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>DIC (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="dic" v-slot="{ errors }">
<input @input="$updateText(`/oasis/clients/${client.id}`, 'dic', client.dic)" v-model="client.dic" placeholder="" type="text" :class="{'is-error': errors[0]}" class="focus-border-theme" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>IC DPH (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="ic_dph" v-slot="{ errors }">
<input @input="$updateText(`/oasis/clients/${client.id}`, 'ic_dph', client.ic_dph)" v-model="client.ic_dph" placeholder="" type="text" :class="{'is-error': errors[0]}" class="focus-border-theme" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
</PageTabGroup>
<PageTabGroup class="form block-form">
<FormLabel>Company Address</FormLabel>
<div class="block-wrapper">
<label>Address:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="address" rules="required" v-slot="{ errors }">
<input @input="$updateText(`/oasis/clients/${client.id}`, 'address', client.address)" v-model="client.address" placeholder="" type="text" :class="{'is-error': errors[0]}" class="focus-border-theme" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>City:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="city" rules="required" v-slot="{ errors }">
<input @input="$updateText(`/oasis/clients/${client.id}`, 'city', client.city)" v-model="client.city" placeholder="" type="text" :class="{'is-error': errors[0]}" class="focus-border-theme" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Postal Code:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="postal_code" rules="required" v-slot="{ errors }">
<input @input="$updateText(`/oasis/clients/${client.id}`, 'postal_code', client.postal_code)" v-model="client.postal_code" placeholder="" type="text" :class="{'is-error': errors[0]}" class="focus-border-theme" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Country:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="country" rules="required" v-slot="{ errors }">
<SelectInput @input="$updateText(`/oasis/clients/${client.id}`, 'country', client.country)" v-model="client.country" :default="client.country" :options="countries" placeholder="" :isError="errors[0]" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
</PageTabGroup>
<PageTabGroup class="form block-form">
<FormLabel>Contact Informations</FormLabel>
<div class="block-wrapper">
<label>Phone (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="phone_number" v-slot="{ errors }">
<input @input="$updateText(`/oasis/clients/${client.id}`, 'phone_number', client.phone_number)" v-model="client.phone_number" placeholder="" type="text" :class="{'is-error': errors[0]}" class="focus-border-theme" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Email (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="email" v-slot="{ errors }">
<input @input="$updateText(`/oasis/clients/${client.id}`, 'email', client.email)" v-model="client.email" placeholder="" type="email" :class="{'is-error': errors[0]}" class="focus-border-theme" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
</PageTabGroup>
</PageTab>
</template>
<script>
import ImageInput from '@/components/Others/Forms/ImageInput'
import InfoBox from '@/components/Others/Forms/InfoBox'
import PageTabGroup from '@/components/Others/Layout/PageTabGroup'
import PageTab from '@/components/Others/Layout/PageTab'
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '@/components/Others/StorageItemDetail'
import SelectInput from '@/components/Others/Forms/SelectInput'
import FormLabel from '@/components/Others/Forms/FormLabel'
import ButtonBase from '@/components/FilesView/ButtonBase'
import SetupBox from '@/components/Others/Forms/SetupBox'
import {required} from 'vee-validate/dist/rules'
import {mapGetters} from "vuex";
export default {
name: 'UserDetail',
props: [
'client'
],
computed: {
...mapGetters([
'countries'
]),
},
components: {
ImageInput,
PageTabGroup,
PageTab,
InfoBox,
FormLabel,
ValidationProvider,
ValidationObserver,
StorageItemDetail,
SelectInput,
ButtonBase,
SetupBox,
required,
},
data() {
return {
isLoading: false,
}
},
methods: {
},
}
</script>
<style lang="scss" scoped>
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
@import '@assets/vuefilemanager/_forms';
.block-form {
max-width: 100%;
}
</style>
@@ -1,5 +1,5 @@
<template>
<div class="file-wrapper" @mouseup.stop="clickedItem" @dblclick="showInvoice">
<div class="file-wrapper" @mouseup.stop="clickedItem" @dblclick="showClient">
<div class="file-item" :class="{'is-clicked': isClicked , 'no-clicked': !isClicked && $isMobile()}">
<!-- MultiSelecting for the mobile version -->
@@ -135,8 +135,8 @@ export default {
}
}
},
showInvoice() {
events.$emit('file-preview:show')
showClient() {
this.$router.push({name: 'ClientDetail', params: {id: this.item.id}})
},
},
created() {
@@ -6,7 +6,7 @@
<OptionGroup class="menu-option-group">
<Option @click.native="" title="Edit Invoice" icon="rename" />
<Option @click.native="" title="Send Invoice" icon="send" />
<Option @click.native="" title="Go to Company" icon="user" />
<Option @click.native="goToCompany" title="Go to Company" icon="user" />
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash" />
</OptionGroup>
@@ -74,6 +74,9 @@ export default {
}
},
methods: {
goToCompany() {
this.$router.push({name: 'ClientDetail', params: {id: this.item.id}})
},
downloadItem() {
if (this.clipboard.length > 1)
this.$store.dispatch('downloadFiles')
+23 -1
View File
@@ -106,11 +106,33 @@ const routesOasis = [
name: 'CreateClient',
path: '/invoice/create-client',
component: () =>
import(/* webpackChunkName: "chunks/oasis/invoices/create-client" */ './Oasis/Invoices/CreateClient'),
import(/* webpackChunkName: "chunks/oasis/invoices/create-client" */ './Oasis/Invoices/Clients/CreateClient'),
meta: {
requiresAuth: true,
title: 'Create Client'
},
},
{
name: 'Client',
path: '/invoice/client/:id',
component: () =>
import(/* webpackChunkName: "chunks/oasis/invoices/client" */ './Oasis/Invoices/Clients/Client'),
meta: {
requiresAuth: true,
title: 'Client'
},
children: [
{
name: 'ClientDetail',
path: '/invoice/client/:id/detail',
component: () =>
import(/* webpackChunkName: "chunks/oasis/invoices/client-detail" */ './Oasis/Invoices/Clients/Tabs/ClientDetail'),
meta: {
requiresAuth: true,
title: 'Client Detail'
},
}
]
}
]
},