38980-vm/app-9w9pd00g5j41/PROVIDER_LEAD_VISIBILITY_FIX.md
2026-03-04 18:25:09 +00:00

6.0 KiB
Raw Permalink Blame History

Provider Lead Visibility Fix

Problem Summary

User temrentravel logged in as a provider but could not see any leads in the provider dashboard, despite:

  • Having the correct role (provider) in the database
  • Being listed as active in the admin providers page
  • Having proper provider service configuration with destinations and activity categories

Root Cause Analysis

Issue 1: Case-Sensitive Activity Category Matching (CRITICAL)

Location: src/db/api.ts - providerLeadsApi.getAvailable() function (lines 1145-1154)

Problem: The lead filtering logic was performing case-sensitive comparison between:

  • Provider's activity_categories: ["müze", "aktivite", "doğal alan", ...] (lowercase)
  • Lead's interests: ["Müze", "Aktivite", "Doğal Alan", ...] (Title Case)

Code Before:

filteredLeads = leads.filter(lead => {
  if (!lead.interests || lead.interests.length === 0) return false;
  return lead.interests.some((interest: string) => 
    providerService.activity_categories.includes(interest)  // ❌ Case-sensitive
  );
});

Result: All leads were filtered out because "Müze" !== "müze", causing the provider dashboard to show zero leads.

Issue 2: Empty Role Display in Admin Users Page (UI Issue)

Location: src/pages/admin/Users.tsx (line 191)

Problem: The SelectValue component was empty, not displaying the current role value properly in the admin users table.

Code Before:

<SelectTrigger className="w-32">
  <SelectValue />  {/* ❌ Empty, not showing current value */}
</SelectTrigger>

Solutions Implemented

Fix 1: Case-Insensitive Activity Category Matching

File: src/db/api.ts

Changes:

// Filter by activity categories (interests array overlap) - case insensitive
let filteredLeads = leads;
if (providerService.activity_categories && providerService.activity_categories.length > 0) {
  // Normalize provider categories to lowercase for comparison
  const normalizedCategories = providerService.activity_categories.map((cat: string) => 
    cat.toLowerCase().trim()
  );
  
  filteredLeads = leads.filter(lead => {
    if (!lead.interests || lead.interests.length === 0) return false;
    // Check if any lead interest matches any provider category (case insensitive)
    return lead.interests.some((interest: string) => 
      normalizedCategories.includes(interest.toLowerCase().trim())
    );
  });
}

Benefits:

  • Case-insensitive comparison
  • Trims whitespace for robust matching
  • Handles Turkish characters correctly
  • Provider now sees all matching leads

Fix 2: Proper Role Display in Admin Users Page

File: src/pages/admin/Users.tsx

Changes:

<SelectTrigger className="w-32">
  <SelectValue placeholder="Rol seçin">
    {user.role === 'admin' && (
      <div className="flex items-center gap-2">
        <Shield className="h-4 w-4" />
        <span>Admin</span>
      </div>
    )}
    {user.role === 'provider' && (
      <div className="flex items-center gap-2">
        <Briefcase className="h-4 w-4" />
        <span>Provider</span>
      </div>
    )}
    {(!user.role || user.role === 'user') && (
      <div className="flex items-center gap-2">
        <User className="h-4 w-4" />
        <span>Kullanıcı</span>
      </div>
    )}
  </SelectValue>
</SelectTrigger>

Benefits:

  • Displays current role with icon
  • Shows "Provider" for provider users
  • Shows "Admin" for admin users
  • Shows "Kullanıcı" for regular users
  • Handles null/undefined roles gracefully

Verification

Database Verification

-- Confirmed temrentravel has correct role
SELECT id, username, role FROM profiles WHERE username = 'temrentravel';
-- Result: role = 'provider' ✅

-- Confirmed provider service configuration exists
SELECT provider_id, business_name, destinations, activity_categories 
FROM provider_services 
WHERE provider_id = '43595be4-acce-4d42-bfbf-66cbf204457c';
-- Result: Temren Travel with destinations and categories ✅

-- Confirmed leads exist with matching criteria
SELECT id, destination, interests, status, consent_given 
FROM leads 
WHERE status = 'new' AND consent_given = true;
-- Result: 4 leads with "Kapadokya, Türkiye" destination ✅

Expected Behavior After Fix

  1. Provider Dashboard:

    • temrentravel can now see leads matching their destinations
    • Leads are filtered by activity categories (case-insensitive)
    • Available leads show in the "Available Leads" tab
    • Contact information is properly blurred until purchased
  2. Admin Users Page:

    • Role column displays "Provider" with briefcase icon for temrentravel
    • Role dropdown shows current selection
    • Admin can change roles if needed

Testing Recommendations

  1. Login as temrentravel:

    • Navigate to Provider Dashboard
    • Verify leads are visible in "Available Leads" tab
    • Check that leads match provider's destinations (Kapadokya, İstanbul, etc.)
    • Verify activity category filtering works
  2. Admin Panel Check:

    • Go to Admin → Users
    • Find temrentravel user
    • Verify "Provider" role is displayed correctly
    • Test role dropdown functionality
  3. Lead Filtering Test:

    • Create a test lead with destination "Kapadokya, Türkiye"
    • Add interests like "Müze", "Aktivite", "Doğal Alan"
    • Verify it appears in temrentravel's dashboard
  • src/db/api.ts - Lead filtering logic
  • src/pages/admin/Users.tsx - Admin users management
  • src/pages/ProviderDashboard.tsx - Provider dashboard UI
  • supabase/migrations/00013_add_provider_registration_function.sql - Provider registration
  • supabase/migrations/00017_add_provider_role.sql - Provider role constraint

Notes

  • The role was correctly set in the database from the beginning
  • The main issue was the case-sensitive comparison in lead filtering
  • Turkish character handling is important for this application
  • Always use case-insensitive comparisons for user-generated content matching