fix: Contact page new design
This commit is contained in:
parent
fd23d66ccd
commit
759c301042
@ -8,165 +8,223 @@
|
|||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
</template>
|
</template>
|
||||||
</LayoutHeader>
|
</LayoutHeader>
|
||||||
<div v-if="contact.data" class="flex h-full flex-col overflow-hidden">
|
<div class="flex h-full">
|
||||||
<FileUploader @success="changeContactImage" :validateFile="validateFile">
|
<div
|
||||||
<template #default="{ openFileSelector, error }">
|
v-if="contact.data"
|
||||||
<div class="flex items-start justify-start gap-6 p-5 sm:items-center">
|
class="flex h-full flex-col overflow-hidden border-r min-w-[352px]"
|
||||||
<div class="group relative h-24 w-24">
|
>
|
||||||
<Avatar
|
<div class="border-b">
|
||||||
size="3xl"
|
<FileUploader
|
||||||
class="h-24 w-24"
|
@success="changeContactImage"
|
||||||
:label="contact.data.full_name"
|
:validateFile="validateFile"
|
||||||
:image="contact.data.image"
|
>
|
||||||
/>
|
<template #default="{ openFileSelector, error }">
|
||||||
<component
|
<div class="flex flex-col items-start justify-start gap-4 p-5">
|
||||||
:is="contact.data.image ? Dropdown : 'div'"
|
<div class="flex gap-4 items-center">
|
||||||
v-bind="
|
<div class="group relative h-15.5 w-15.5">
|
||||||
contact.data.image
|
<Avatar
|
||||||
? {
|
size="3xl"
|
||||||
options: [
|
class="h-15.5 w-15.5"
|
||||||
{
|
:label="contact.data.full_name"
|
||||||
icon: 'upload',
|
:image="contact.data.image"
|
||||||
label: contact.data.image
|
/>
|
||||||
? __('Change image')
|
<component
|
||||||
: __('Upload image'),
|
:is="contact.data.image ? Dropdown : 'div'"
|
||||||
onClick: openFileSelector,
|
v-bind="
|
||||||
},
|
contact.data.image
|
||||||
{
|
? {
|
||||||
icon: 'trash-2',
|
options: [
|
||||||
label: __('Remove image'),
|
{
|
||||||
onClick: () => changeContactImage(''),
|
icon: 'upload',
|
||||||
},
|
label: contact.data.image
|
||||||
],
|
? __('Change image')
|
||||||
}
|
: __('Upload image'),
|
||||||
: { onClick: openFileSelector }
|
onClick: openFileSelector,
|
||||||
"
|
},
|
||||||
class="!absolute bottom-0 left-0 right-0"
|
{
|
||||||
>
|
icon: 'trash-2',
|
||||||
<div
|
label: __('Remove image'),
|
||||||
class="z-1 absolute bottom-0 left-0 right-0 flex h-14 cursor-pointer items-center justify-center rounded-b-full bg-black bg-opacity-40 pt-3 opacity-0 duration-300 ease-in-out group-hover:opacity-100"
|
onClick: () => changeContactImage(''),
|
||||||
style="
|
},
|
||||||
-webkit-clip-path: inset(12px 0 0 0);
|
],
|
||||||
clip-path: inset(12px 0 0 0);
|
}
|
||||||
"
|
: { onClick: openFileSelector }
|
||||||
>
|
"
|
||||||
<CameraIcon class="h-6 w-6 cursor-pointer text-white" />
|
class="!absolute bottom-0 left-0 right-0"
|
||||||
</div>
|
>
|
||||||
</component>
|
<div
|
||||||
</div>
|
class="z-1 absolute bottom-0 left-0 right-0 flex h-14 cursor-pointer items-center justify-center rounded-b-full bg-black bg-opacity-40 pt-5 opacity-0 duration-300 ease-in-out group-hover:opacity-100"
|
||||||
<div class="flex flex-col gap-2 truncate sm:gap-0.5">
|
style="
|
||||||
<div class="truncate text-3xl font-semibold">
|
-webkit-clip-path: inset(22px 0 0 0);
|
||||||
<span v-if="contact.data.salutation">
|
clip-path: inset(22px 0 0 0);
|
||||||
{{ contact.data.salutation + '. ' }}
|
"
|
||||||
</span>
|
>
|
||||||
<span>{{ contact.data.full_name }}</span>
|
<CameraIcon class="h-6 w-6 cursor-pointer text-white" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
</component>
|
||||||
class="flex flex-col flex-wrap gap-3 text-base text-gray-700 sm:flex-row sm:items-center sm:gap-2"
|
</div>
|
||||||
>
|
<div class="flex flex-col gap-2 truncate">
|
||||||
<div
|
<div class="truncate text-2xl font-medium">
|
||||||
v-if="contact.data.email_id"
|
<span v-if="contact.data.salutation">
|
||||||
class="flex items-center gap-1.5"
|
{{ contact.data.salutation + '. ' }}
|
||||||
>
|
</span>
|
||||||
<Email2Icon class="h-4 w-4" />
|
<span>{{ contact.data.full_name }}</span>
|
||||||
<span class="">{{ contact.data.email_id }}</span>
|
</div>
|
||||||
</div>
|
<div
|
||||||
<span
|
v-if="contact.data.company_name"
|
||||||
v-if="contact.data.email_id"
|
class="flex items-center gap-1.5 text-base text-gray-800"
|
||||||
class="hidden text-3xl leading-[0] text-gray-600 sm:flex"
|
>
|
||||||
>
|
<Avatar
|
||||||
·
|
size="xs"
|
||||||
</span>
|
:label="contact.data.company_name"
|
||||||
<component
|
:image="
|
||||||
:is="callEnabled ? Tooltip : 'div'"
|
getOrganization(contact.data.company_name)
|
||||||
:text="__('Make Call')"
|
?.organization_logo
|
||||||
v-if="contact.data.actual_mobile_no"
|
"
|
||||||
|
/>
|
||||||
|
<span class="">{{ contact.data.company_name }}</span>
|
||||||
|
</div>
|
||||||
|
<!-- <div
|
||||||
|
class="flex flex-col flex-wrap gap-3 text-base text-gray-700 sm:flex-row sm:items-center sm:gap-2"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
v-if="contact.data.email_id"
|
||||||
class="flex items-center gap-1.5"
|
class="flex items-center gap-1.5"
|
||||||
:class="callEnabled ? 'cursor-pointer' : ''"
|
|
||||||
@click="
|
|
||||||
callEnabled && makeCall(contact.data.actual_mobile_no)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<PhoneIcon class="h-4 w-4" />
|
<Email2Icon class="h-4 w-4" />
|
||||||
<span class="">{{ contact.data.actual_mobile_no }}</span>
|
<span class="">{{ contact.data.email_id }}</span>
|
||||||
</div>
|
</div>
|
||||||
</component>
|
<span
|
||||||
<span
|
v-if="contact.data.email_id"
|
||||||
v-if="contact.data.actual_mobile_no"
|
class="hidden text-3xl leading-[0] text-gray-600 sm:flex"
|
||||||
class="hidden text-3xl leading-[0] text-gray-600 sm:flex"
|
>
|
||||||
>
|
·
|
||||||
·
|
</span>
|
||||||
</span>
|
<component
|
||||||
<div
|
:is="callEnabled ? Tooltip : 'div'"
|
||||||
v-if="contact.data.company_name"
|
:text="__('Make Call')"
|
||||||
class="flex items-center gap-1.5"
|
v-if="contact.data.actual_mobile_no"
|
||||||
>
|
>
|
||||||
<Avatar
|
<div
|
||||||
size="xs"
|
class="flex items-center gap-1.5"
|
||||||
:label="contact.data.company_name"
|
:class="callEnabled ? 'cursor-pointer' : ''"
|
||||||
:image="
|
@click="
|
||||||
getOrganization(contact.data.company_name)
|
callEnabled && makeCall(contact.data.actual_mobile_no)
|
||||||
?.organization_logo
|
"
|
||||||
|
>
|
||||||
|
<PhoneIcon class="h-4 w-4" />
|
||||||
|
<span class="">{{ contact.data.actual_mobile_no }}</span>
|
||||||
|
</div>
|
||||||
|
</component>
|
||||||
|
<span
|
||||||
|
v-if="contact.data.actual_mobile_no"
|
||||||
|
class="hidden text-3xl leading-[0] text-gray-600 sm:flex"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
v-if="contact.data.company_name"
|
||||||
|
class="flex items-center gap-1.5"
|
||||||
|
>
|
||||||
|
<Avatar
|
||||||
|
size="xs"
|
||||||
|
:label="contact.data.company_name"
|
||||||
|
:image="
|
||||||
|
getOrganization(contact.data.company_name)
|
||||||
|
?.organization_logo
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<span class="">{{ contact.data.company_name }}</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
v-if="contact.data.company_name"
|
||||||
|
class="hidden text-3xl leading-[0] text-gray-600 sm:flex"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
v-if="
|
||||||
|
contact.data.email_id ||
|
||||||
|
contact.data.mobile_no ||
|
||||||
|
contact.data.company_name
|
||||||
|
"
|
||||||
|
variant="ghost"
|
||||||
|
:label="__('More')"
|
||||||
|
class="w-fit cursor-pointer hover:text-gray-900 sm:-ml-1"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
detailMode = true
|
||||||
|
showContactModal = true
|
||||||
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<span class="">{{ contact.data.company_name }}</span>
|
</div> -->
|
||||||
|
<ErrorMessage :message="__(error)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-1.5">
|
||||||
|
<Button
|
||||||
|
:label="__('Make Call')"
|
||||||
|
size="sm"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
detailMode = false
|
||||||
|
showContactModal = true
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<PhoneIcon class="h-4 w-4" />
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
:label="__('Delete')"
|
||||||
|
theme="red"
|
||||||
|
size="sm"
|
||||||
|
@click="deleteContact"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<FeatherIcon name="trash-2" class="h-4 w-4" />
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<span
|
|
||||||
v-if="contact.data.company_name"
|
|
||||||
class="hidden text-3xl leading-[0] text-gray-600 sm:flex"
|
|
||||||
>
|
|
||||||
·
|
|
||||||
</span>
|
|
||||||
<Button
|
|
||||||
v-if="
|
|
||||||
contact.data.email_id ||
|
|
||||||
contact.data.mobile_no ||
|
|
||||||
contact.data.company_name
|
|
||||||
"
|
|
||||||
variant="ghost"
|
|
||||||
:label="__('More')"
|
|
||||||
class="w-fit cursor-pointer hover:text-gray-900 sm:-ml-1"
|
|
||||||
@click="
|
|
||||||
() => {
|
|
||||||
detailMode = true
|
|
||||||
showContactModal = true
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 flex gap-1.5">
|
</template>
|
||||||
<Button
|
</FileUploader>
|
||||||
:label="__('Edit')"
|
</div>
|
||||||
size="sm"
|
<div
|
||||||
@click="
|
v-if="fieldsLayout.data"
|
||||||
() => {
|
class="flex flex-1 flex-col justify-between overflow-hidden"
|
||||||
detailMode = false
|
>
|
||||||
showContactModal = true
|
<div class="flex flex-col overflow-y-auto">
|
||||||
}
|
<div
|
||||||
"
|
v-for="(section, i) in fieldsLayout.data"
|
||||||
>
|
:key="section.label"
|
||||||
<template #prefix>
|
class="flex flex-col p-3"
|
||||||
|
:class="{ 'border-b': i !== fieldsLayout.data.length - 1 }"
|
||||||
|
>
|
||||||
|
<Section :is-opened="section.opened" :label="section.label">
|
||||||
|
<template #actions>
|
||||||
|
<Button
|
||||||
|
v-if="i == 0 && isManager()"
|
||||||
|
variant="ghost"
|
||||||
|
class="w-7"
|
||||||
|
@click="showSidePanelModal = true"
|
||||||
|
>
|
||||||
<EditIcon class="h-4 w-4" />
|
<EditIcon class="h-4 w-4" />
|
||||||
</template>
|
</Button>
|
||||||
</Button>
|
</template>
|
||||||
<Button
|
<SectionFields
|
||||||
:label="__('Delete')"
|
v-if="section.fields"
|
||||||
theme="red"
|
:fields="section.fields"
|
||||||
size="sm"
|
v-model="contact.data"
|
||||||
@click="deleteContact"
|
@update="updateField"
|
||||||
>
|
/>
|
||||||
<template #prefix>
|
</Section>
|
||||||
<FeatherIcon name="trash-2" class="h-4 w-4" />
|
|
||||||
</template>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<ErrorMessage :message="__(error)" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
</FileUploader>
|
</div>
|
||||||
<Tabs class="overflow-hidden" v-model="tabIndex" :tabs="tabs">
|
<Tabs class="overflow-hidden" v-model="tabIndex" :tabs="tabs">
|
||||||
<template #tab="{ tab, selected }">
|
<template #tab="{ tab, selected }">
|
||||||
<button
|
<button
|
||||||
@ -221,6 +279,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import Icon from '@/components/Icon.vue'
|
import Icon from '@/components/Icon.vue'
|
||||||
|
import Section from '@/components/Section.vue'
|
||||||
|
import SectionFields from '@/components/SectionFields.vue'
|
||||||
import Dropdown from '@/components/frappe-ui/Dropdown.vue'
|
import Dropdown from '@/components/frappe-ui/Dropdown.vue'
|
||||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||||
import Email2Icon from '@/components/Icons/Email2Icon.vue'
|
import Email2Icon from '@/components/Icons/Email2Icon.vue'
|
||||||
@ -258,7 +318,7 @@ import { useRoute, useRouter } from 'vue-router'
|
|||||||
|
|
||||||
const { $dialog, makeCall } = globalStore()
|
const { $dialog, makeCall } = globalStore()
|
||||||
|
|
||||||
const { getUser } = usersStore()
|
const { getUser, isManager } = usersStore()
|
||||||
const { getOrganization } = organizationsStore()
|
const { getOrganization } = organizationsStore()
|
||||||
const { getDealStatus } = statusesStore()
|
const { getDealStatus } = statusesStore()
|
||||||
|
|
||||||
@ -386,6 +446,29 @@ const rows = computed(() => {
|
|||||||
return deals.data.map((row) => getDealRowObject(row))
|
return deals.data.map((row) => getDealRowObject(row))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// const fieldsLayout = ref({
|
||||||
|
// data: {},
|
||||||
|
// })
|
||||||
|
|
||||||
|
const fieldsLayout = createResource({
|
||||||
|
url: 'crm.api.doc.get_sidebar_fields',
|
||||||
|
cache: ['fieldsLayout', props.contactId],
|
||||||
|
params: { doctype: 'Contact', name: props.contactId },
|
||||||
|
auto: true,
|
||||||
|
// transform: (data) => getParsedFields(data),
|
||||||
|
})
|
||||||
|
|
||||||
|
function updateField(fieldname, value) {
|
||||||
|
call('frappe.client.set_value', {
|
||||||
|
doctype: 'Contact',
|
||||||
|
name: props.contactId,
|
||||||
|
fieldname,
|
||||||
|
value,
|
||||||
|
})
|
||||||
|
|
||||||
|
contact.reload()
|
||||||
|
}
|
||||||
|
|
||||||
const columns = computed(() => dealColumns)
|
const columns = computed(() => dealColumns)
|
||||||
|
|
||||||
function getDealRowObject(deal) {
|
function getDealRowObject(deal) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user