260 lines
5.8 KiB
Markdown
260 lines
5.8 KiB
Markdown
# New Client Detail Page - Modern Design
|
||
|
||
## Overview
|
||
A completely redesigned client detail page with modern UI/UX, inspired by the Settings page structure with tabs, client avatar/logo, and better ergonomics.
|
||
|
||
## Features
|
||
|
||
### 🎨 **Modern Layout**
|
||
- **Left Sidebar**: Sticky client card with navigation
|
||
- **Right Content Area**: Tabbed content with clean organization
|
||
|
||
### 👤 **Client Profile Card**
|
||
- **Avatar/Logo**:
|
||
- Shows client initials if no image
|
||
- Click edit button to upload logo
|
||
- Large, prominent display
|
||
- **Quick Stats**:
|
||
- Number of contacts
|
||
- Active/Inactive status
|
||
- **Client Info**: Name and type
|
||
|
||
### 📑 **5 Tab Sections**
|
||
|
||
#### 1. **Aperçu (Overview)**
|
||
Default view with key information:
|
||
- Contact info card (email, phone)
|
||
- Business info card (SIRET, VAT)
|
||
- Address card
|
||
- Recent contacts (first 3)
|
||
- Edit button to modify client
|
||
|
||
#### 2. **Informations (Information)**
|
||
Complete client details:
|
||
- Name, type
|
||
- SIRET, VAT number
|
||
- Email, phone
|
||
- Commercial
|
||
|
||
#### 3. **Contacts**
|
||
Full contact list with:
|
||
- Contact table with avatars
|
||
- Email, phone, position
|
||
- Primary contact badge
|
||
- "Add Contact" button
|
||
- Empty state if no contacts
|
||
|
||
#### 4. **Adresse (Address)**
|
||
Billing address details:
|
||
- Address line 1 & 2
|
||
- Postal code, city, country
|
||
|
||
#### 5. **Notes**
|
||
Client notes section
|
||
|
||
## File Location
|
||
```
|
||
src/views/pages/CRM/ClientDetailNew.vue
|
||
```
|
||
|
||
## Usage
|
||
|
||
### Update Router
|
||
Add the new route in your router configuration:
|
||
|
||
```javascript
|
||
// router/index.js
|
||
{
|
||
path: '/clients/:id/detail',
|
||
name: 'ClientDetailNew',
|
||
component: () => import('@/views/pages/CRM/ClientDetailNew.vue')
|
||
}
|
||
```
|
||
|
||
### Replace Old ClientDetail
|
||
To use this as the main client detail page:
|
||
|
||
```javascript
|
||
// Change existing route
|
||
{
|
||
path: '/clients/:id',
|
||
name: 'ClientDetail',
|
||
component: () => import('@/views/pages/CRM/ClientDetailNew.vue') // Changed from ClientDetails.vue
|
||
}
|
||
```
|
||
|
||
## Component Structure
|
||
|
||
### Template Sections
|
||
1. **Header** - Back button to clients list
|
||
2. **Loading State** - Spinner while fetching data
|
||
3. **Error State** - Alert for errors
|
||
4. **Main Content**
|
||
- Left: Client card + navigation
|
||
- Right: Tab content
|
||
|
||
### Script Features
|
||
```javascript
|
||
// Reactive data
|
||
const activeTab = ref('overview') // Current tab
|
||
const clientAvatar = ref(null) // Client logo/avatar
|
||
const contacts_client = ref([]) // Client contacts
|
||
|
||
// Methods
|
||
getInitials(name) // Generate initials from name
|
||
formatAddress(client) // Format full address string
|
||
triggerFileInput() // Open file selector
|
||
handleAvatarUpload() // Handle logo upload
|
||
```
|
||
|
||
### Styling Features
|
||
- **Sticky sidebar** - Stays visible when scrolling
|
||
- **Active tab highlighting** - Gradient background
|
||
- **Smooth transitions** - Hover effects
|
||
- **Responsive design** - Works on mobile
|
||
- **Clean cards** - Soft shadows and borders
|
||
|
||
## Design Principles
|
||
|
||
### Color Scheme
|
||
- **Primary Actions**: Gradient purple-pink (`#7928ca` to `#ff0080`)
|
||
- **Success**: Green for active status and badges
|
||
- **Info**: Blue for contact info
|
||
- **Warning**: Yellow for business info
|
||
- **Danger**: Red for inactive status
|
||
|
||
### Typography
|
||
- **Headers**: Bold, clear hierarchy
|
||
- **Body**: `text-sm` for readability
|
||
- **Labels**: Uppercase with spacing
|
||
|
||
### Icons
|
||
Using Font Awesome:
|
||
- 📊 `fa-eye` - Overview
|
||
- ℹ️ `fa-info-circle` - Information
|
||
- 👥 `fa-users` - Contacts
|
||
- 📍 `fa-map-marker-alt` - Address
|
||
- 📝 `fa-sticky-note` - Notes
|
||
|
||
## Avatar/Logo Upload
|
||
|
||
### Current Implementation
|
||
```javascript
|
||
handleAvatarUpload(event) {
|
||
const file = event.target.files[0];
|
||
if (file) {
|
||
const reader = new FileReader();
|
||
reader.onload = (e) => {
|
||
clientAvatar.value = e.target.result;
|
||
// TODO: Upload to server
|
||
};
|
||
reader.readAsDataURL(file);
|
||
}
|
||
}
|
||
```
|
||
|
||
### TODO: Connect to Backend
|
||
To implement server upload:
|
||
|
||
```javascript
|
||
const handleAvatarUpload = async (event) => {
|
||
const file = event.target.files[0];
|
||
if (!file) return;
|
||
|
||
const formData = new FormData();
|
||
formData.append('avatar', file);
|
||
formData.append('client_id', clientStore.currentClient.id);
|
||
|
||
try {
|
||
const response = await api.post('/clients/upload-avatar', formData, {
|
||
headers: { 'Content-Type': 'multipart/form-data' }
|
||
});
|
||
|
||
clientAvatar.value = response.data.avatar_url;
|
||
// Update store
|
||
await clientStore.fetchClient(client_id);
|
||
} catch (error) {
|
||
console.error('Upload failed:', error);
|
||
}
|
||
};
|
||
```
|
||
|
||
## Comparison: Old vs New
|
||
|
||
### Old Design
|
||
- Single page layout
|
||
- All info visible at once
|
||
- No image/avatar support
|
||
- Basic styling
|
||
- No tab organization
|
||
|
||
### New Design ✨
|
||
- Modern tabbed interface
|
||
- Client avatar/logo with upload
|
||
- Sticky sidebar navigation
|
||
- Card-based organization
|
||
- Better mobile responsive
|
||
- Visual hierarchy
|
||
- Quick stats
|
||
- Empty states
|
||
- Badge indicators
|
||
|
||
## Customization
|
||
|
||
### Change Tab Order
|
||
```vue
|
||
<!-- Reorder nav items in the sidebar -->
|
||
<ul class="nav nav-pills flex-column">
|
||
<li class="nav-item">
|
||
<a @click="activeTab = 'your-tab'">...</a>
|
||
</li>
|
||
</ul>
|
||
```
|
||
|
||
### Add New Tab
|
||
1. Add nav item in sidebar
|
||
2. Add content section with `v-show`
|
||
3. Update `activeTab` ref
|
||
|
||
```vue
|
||
<!-- Nav item -->
|
||
<li class="nav-item pt-2">
|
||
<a
|
||
class="nav-link"
|
||
:class="{ active: activeTab === 'documents' }"
|
||
@click="activeTab = 'documents'"
|
||
>
|
||
<i class="fas fa-file me-2"></i>
|
||
<span class="text-sm">Documents</span>
|
||
</a>
|
||
</li>
|
||
|
||
<!-- Content -->
|
||
<div v-show="activeTab === 'documents'" class="card">
|
||
<div class="card-header pb-0">
|
||
<h6 class="mb-0">Documents</h6>
|
||
</div>
|
||
<div class="card-body">
|
||
<!-- Your content -->
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
## Dependencies
|
||
- Vue 3 Composition API
|
||
- Vue Router
|
||
- Pinia stores (clientStore, contactStore)
|
||
- Font Awesome icons
|
||
- Bootstrap 5 classes
|
||
|
||
## Browser Support
|
||
- Chrome, Firefox, Safari (latest)
|
||
- Edge (latest)
|
||
- Mobile browsers
|
||
|
||
---
|
||
|
||
**Status**: ✅ Ready to use
|
||
**Created**: October 20, 2025
|
||
**File**: `src/views/pages/CRM/ClientDetailNew.vue`
|