feat: Implement stacked mobile layout for interest table
Mobile Table Redesign: - Redesigned mobile table layout with stacked status badges under contact info - Contact information takes 60% width with badges stacked below name/email - All status badges (Sales Process, EOI, Contract, Lead Category) now stack vertically - Eliminated horizontal scrolling issues and cramped mobile display Visual Improvements: - Optimized badge sizing (x-small) for mobile to fit more content - Enhanced spacing and alignment for better readability - Improved touch targets and visual hierarchy - Contact info and badges properly aligned for clean appearance Layout Structure: - Mobile: 3 columns (Contact+Badges 60%, Status 20%, Created 20%) - Desktop: Maintains original 6-column layout unchanged - Responsive breakpoint at 768px for optimal mobile experience User Experience Enhancements: - All status information visible without horizontal scrolling - Better content density and information accessibility - Maintained click functionality and hover effects - Consistent design language across mobile and desktop The mobile table now provides a much cleaner, more accessible experience with all status information clearly visible in a stacked format.
This commit is contained in:
parent
24dcee57d9
commit
79a706efe3
|
|
@ -136,9 +136,12 @@
|
||||||
>
|
>
|
||||||
<template #item="{ item }">
|
<template #item="{ item }">
|
||||||
<tr @click="handleRowClick(item)" class="table-row">
|
<tr @click="handleRowClick(item)" class="table-row">
|
||||||
<td class="contact-cell">
|
<!-- Mobile: Contact + Stacked Badges -->
|
||||||
<div class="d-flex align-center">
|
<td v-if="mobile" class="contact-cell mobile-contact-cell">
|
||||||
<v-avatar :size="mobile ? 28 : 32" color="primary" :class="mobile ? 'mr-2' : 'mr-3'">
|
<div class="mobile-contact-container">
|
||||||
|
<!-- Contact Info -->
|
||||||
|
<div class="d-flex align-center mb-2">
|
||||||
|
<v-avatar size="32" color="primary" class="mr-3">
|
||||||
<span class="text-white text-caption font-weight-bold">
|
<span class="text-white text-caption font-weight-bold">
|
||||||
{{ getInitials(item["Full Name"]) }}
|
{{ getInitials(item["Full Name"]) }}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -150,7 +153,80 @@
|
||||||
<template #activator="{ props }">
|
<template #activator="{ props }">
|
||||||
<v-icon
|
<v-icon
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
:size="mobile ? 'x-small' : 'small'"
|
size="x-small"
|
||||||
|
color="orange"
|
||||||
|
>
|
||||||
|
mdi-comment-text
|
||||||
|
</v-icon>
|
||||||
|
</template>
|
||||||
|
<span>{{ item["Extra Comments"] }}</span>
|
||||||
|
</v-tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="text-caption text-grey-darken-1 text-truncate">{{ item["Email Address"] }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Stacked Status Badges -->
|
||||||
|
<div class="mobile-badges-stack">
|
||||||
|
<div class="d-flex flex-wrap gap-1 mb-1">
|
||||||
|
<InterestSalesBadge
|
||||||
|
:salesProcessLevel="item['Sales Process Level']"
|
||||||
|
size="x-small"
|
||||||
|
/>
|
||||||
|
<LeadCategoryBadge
|
||||||
|
:leadCategory="item['Lead Category']"
|
||||||
|
size="x-small"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-wrap gap-1">
|
||||||
|
<EOIStatusBadge
|
||||||
|
v-if="item['EOI Status']"
|
||||||
|
:eoiStatus="item['EOI Status']"
|
||||||
|
size="x-small"
|
||||||
|
/>
|
||||||
|
<ContractStatusBadge
|
||||||
|
v-if="item['Contract Status']"
|
||||||
|
:contractStatus="item['Contract Status']"
|
||||||
|
size="x-small"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<!-- Mobile: Sales Status (simplified) -->
|
||||||
|
<td v-if="mobile" class="mobile-status-cell">
|
||||||
|
<InterestSalesBadge
|
||||||
|
:salesProcessLevel="item['Sales Process Level']"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<!-- Mobile: Created Date -->
|
||||||
|
<td v-if="mobile" class="mobile-date-cell">
|
||||||
|
<div class="text-caption text-center">
|
||||||
|
<div class="font-weight-medium">{{ formatDate(item["Created At"]) }}</div>
|
||||||
|
<div class="text-grey-darken-1">{{ getRelativeTime(item["Created At"]) }}</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<!-- Desktop: Full Layout -->
|
||||||
|
<template v-if="!mobile">
|
||||||
|
<td class="contact-cell">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<v-avatar size="32" color="primary" class="mr-3">
|
||||||
|
<span class="text-white text-caption font-weight-bold">
|
||||||
|
{{ getInitials(item["Full Name"]) }}
|
||||||
|
</span>
|
||||||
|
</v-avatar>
|
||||||
|
<div class="flex-grow-1 min-width-0">
|
||||||
|
<div class="d-flex align-center gap-1">
|
||||||
|
<span class="font-weight-medium text-truncate">{{ item["Full Name"] }}</span>
|
||||||
|
<v-tooltip v-if="item['Extra Comments']" location="bottom">
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<v-icon
|
||||||
|
v-bind="props"
|
||||||
|
size="small"
|
||||||
color="orange"
|
color="orange"
|
||||||
>
|
>
|
||||||
mdi-comment-text
|
mdi-comment-text
|
||||||
|
|
@ -189,6 +265,7 @@
|
||||||
<div class="text-grey-darken-1">{{ getRelativeTime(item["Created At"]) }}</div>
|
<div class="text-grey-darken-1">{{ getRelativeTime(item["Created At"]) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
</template>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -584,95 +661,91 @@ const getRelativeTime = (dateString: string) => {
|
||||||
|
|
||||||
/* Mobile-specific styles */
|
/* Mobile-specific styles */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
/* Mobile Contact Cell with Stacked Layout */
|
||||||
|
.mobile-contact-cell {
|
||||||
|
padding: 12px 8px !important;
|
||||||
|
vertical-align: top !important;
|
||||||
|
width: 60% !important;
|
||||||
|
min-width: 280px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-contact-container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-badges-stack {
|
||||||
|
margin-left: 44px; /* Align with contact info text */
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-badges-stack .v-chip {
|
||||||
|
height: 20px !important;
|
||||||
|
font-size: 0.65rem !important;
|
||||||
|
padding: 0 6px !important;
|
||||||
|
margin: 1px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile Status Cell */
|
||||||
|
.mobile-status-cell {
|
||||||
|
padding: 12px 4px !important;
|
||||||
|
text-align: center !important;
|
||||||
|
vertical-align: middle !important;
|
||||||
|
width: 20% !important;
|
||||||
|
min-width: 80px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile Date Cell */
|
||||||
|
.mobile-date-cell {
|
||||||
|
padding: 12px 8px !important;
|
||||||
|
text-align: center !important;
|
||||||
|
vertical-align: middle !important;
|
||||||
|
width: 20% !important;
|
||||||
|
min-width: 100px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-date-cell .text-caption {
|
||||||
|
font-size: 0.65rem !important;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table container improvements */
|
||||||
.table-container {
|
.table-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
margin: 0 -16px; /* Extend to screen edge */
|
margin: 0 -16px;
|
||||||
padding: 0 16px; /* Add padding back */
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add padding to the wrapper instead */
|
|
||||||
.modern-table :deep(.v-table__wrapper) {
|
.modern-table :deep(.v-table__wrapper) {
|
||||||
min-width: 400px; /* Reduced minimum width for mobile */
|
min-width: 460px; /* Minimum width to fit 3 columns properly */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Table headers for mobile */
|
||||||
.modern-table :deep(th) {
|
.modern-table :deep(th) {
|
||||||
padding: 8px 4px !important;
|
padding: 8px 4px !important;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modern-table :deep(td) {
|
.modern-table :deep(th:first-child) {
|
||||||
padding: 12px 4px !important;
|
text-align: left !important;
|
||||||
vertical-align: middle;
|
padding-left: 8px !important;
|
||||||
}
|
|
||||||
|
|
||||||
/* Optimize mobile column widths to fit better */
|
|
||||||
.modern-table :deep(th:nth-child(1)),
|
|
||||||
.modern-table :deep(td:nth-child(1)) {
|
|
||||||
min-width: 220px !important; /* Contact info needs more space */
|
|
||||||
max-width: 220px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modern-table :deep(th:nth-child(2)),
|
|
||||||
.modern-table :deep(td:nth-child(2)) {
|
|
||||||
min-width: 100px !important;
|
|
||||||
max-width: 100px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modern-table :deep(th:nth-child(3)),
|
|
||||||
.modern-table :deep(td:nth-child(3)) {
|
|
||||||
min-width: 80px !important;
|
|
||||||
max-width: 80px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Contact cell optimization */
|
|
||||||
.contact-cell {
|
|
||||||
max-width: 220px;
|
|
||||||
padding: 8px 4px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-cell .text-truncate {
|
|
||||||
max-width: 160px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-cell .v-avatar {
|
|
||||||
margin-right: 8px !important;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust table row height on mobile */
|
/* Adjust table row height on mobile */
|
||||||
.table-row td {
|
.table-row td {
|
||||||
padding: 8px 4px !important;
|
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
min-height: 60px;
|
min-height: 80px !important; /* Increased for stacked content */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure badges are sized appropriately */
|
/* Contact cell text improvements */
|
||||||
.modern-table :deep(.v-chip) {
|
.mobile-contact-cell .text-truncate {
|
||||||
height: 18px !important;
|
max-width: 200px;
|
||||||
font-size: 0.625rem !important;
|
|
||||||
padding: 0 6px !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style the date column to be more compact */
|
.mobile-contact-cell .v-avatar {
|
||||||
.modern-table :deep(td:nth-child(3) .text-caption) {
|
flex-shrink: 0;
|
||||||
font-size: 0.6rem !important;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add visual scroll indicators */
|
|
||||||
.table-container::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 16px;
|
|
||||||
bottom: 0;
|
|
||||||
width: 20px;
|
|
||||||
background: linear-gradient(to right, transparent, rgba(255,255,255,0.9));
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix container padding */
|
/* Fix container padding */
|
||||||
|
|
@ -690,6 +763,33 @@ const getRelativeTime = (dateString: string) => {
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add visual scroll indicators */
|
||||||
|
.table-container::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 16px;
|
||||||
|
bottom: 0;
|
||||||
|
width: 20px;
|
||||||
|
background: linear-gradient(to right, transparent, rgba(255,255,255,0.9));
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover effects for mobile */
|
||||||
|
.modern-table :deep(tbody tr:hover) {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optimize badge spacing in stacked layout */
|
||||||
|
.mobile-badges-stack .d-flex {
|
||||||
|
gap: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-badges-stack .gap-1 {
|
||||||
|
gap: 4px !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure proper text truncation */
|
/* Ensure proper text truncation */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue