New-Thanasoft/thanasoft-front/CLIENT_DETAIL_NEW.md
2025-10-20 15:58:25 +03:00

5.8 KiB
Raw Blame History

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:

// 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:

// 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

// 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

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:

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

<!-- 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
<!-- 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