Kundenliste: Schalter Kundenart fehlt

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-16 13:32:04 +00:00
1 parent 58bb956645
commit 5e59ad44bd
3 files changed
+58 -11

No files matched your search

+19 -6
View File
@@ -1,5 +1,7 @@
// Reine Funktionen der Kundenliste und der Kundenseite: Stufe, Filter, Zähler und Abzeichen.
// Ohne Importe, damit Liste, Zähler und Tests dieselbe Logik benutzen.
// Frei von React und Appwrite (nur der Kundenart-Kern), damit Liste, Zähler und Tests dieselbe Logik benutzen.
import { kundenartGesetzt } from './kundenFelder'
export function customerStage(c) {
const s = (c?.customerStatus || '').toLowerCase()
@@ -22,11 +24,21 @@ export const CUSTOMER_TABS = [
{ id: 'all', label: 'Alle' },
]
/** Fehlt die Kundenart? Alles außer genau 'unternehmen' oder 'privat' gilt als nicht gesetzt (V4). */
export function kundenartFehlt(customer) {
return !kundenartGesetzt(customer?.kundenart)
}
/** Zahl für den Schalter „Kundenart fehlt“: nicht archivierte Leads und feste Kunden ohne Kundenart (Abgesagte zählen nicht). */
export function kundenartFehltAnzahl(customers) {
return (customers || []).filter((c) => !isArchived(c) && customerStage(c) !== 'lost' && kundenartFehlt(c)).length
}
/**
* Filtert die Kundenliste nach Reiter und Suchtext. Die Reihenfolge der Eingabe bleibt.
* Archivierte erscheinen nur im Reiter `archived`.
* Archivierte erscheinen nur im Reiter `archived`. Mit `nurKundenartFehlt` bleiben nur Einträge ohne Kundenart.
*/
export function filterCustomers(customers, { stage = 'customer', search = '' } = {}) {
export function filterCustomers(customers, { stage = 'customer', search = '', nurKundenartFehlt = false } = {}) {
const s = String(search || '').toLowerCase()
const matchesStage = (c) => {
const archived = isArchived(c)
@@ -38,15 +50,16 @@ export function filterCustomers(customers, { stage = 'customer', search = '' } =
}
return (customers || []).filter((c) => {
if (!matchesStage(c)) return false
if (nurKundenartFehlt && !kundenartFehlt(c)) return false
if (!s) return true
return `${c.name || ''} ${c.code || ''} ${c.location || ''} ${c.email || ''} ${c.contactName || ''} ${c.phone || ''}`.toLowerCase().includes(s)
})
}
/** Zähler je Reiter, berechnet mit derselben Filterfunktion wie die Liste (beachtet den Suchtext). */
export function stageCounts(customers, search = '') {
/** Zähler je Reiter, berechnet mit derselben Filterfunktion wie die Liste (beachtet Suchtext und Schalter „Kundenart fehlt“). */
export function stageCounts(customers, search = '', { nurKundenartFehlt = false } = {}) {
const counts = {}
for (const tab of CUSTOMER_TABS) counts[tab.id] = filterCustomers(customers, { stage: tab.id, search }).length
for (const tab of CUSTOMER_TABS) counts[tab.id] = filterCustomers(customers, { stage: tab.id, search, nurKundenartFehlt }).length
return counts
}
+9 -4
View File
@@ -3,7 +3,7 @@ import { Link, useNavigate } from 'react-router-dom'
import { useCustomers } from '../hooks/useCustomers'
import { useAuth } from '../context/AuthContext'
import { createLead } from '../lib/leads'
import { CUSTOMER_TABS, customerBadges, customerTitle, filterCustomers, stageCounts } from '../lib/customerList'
import { CUSTOMER_TABS, customerBadges, customerTitle, filterCustomers, kundenartFehltAnzahl, stageCounts } from '../lib/customerList'
import { isRowActivation } from '../lib/rowClick'
import { findDuplicates } from '../lib/leadDuplicates'
import DuplicateWarning from '../components/customer/DuplicateWarning'
@@ -19,10 +19,11 @@ export default function CustomersPage() {
// 105 von 110 Eintraegen sind Leads der Lead-Automatik, deshalb startet die Liste bei den festen Kunden
const [stage, setStage] = useState('customer') // customer | lead | lost | archived | all
const [showCreate, setShowCreate] = useState(null) // null | 'lead' | 'customer'
const [nurFehlt, setNurFehlt] = useState(false) // Schalter „Kundenart fehlt“
const filtered = useMemo(() => filterCustomers(customers, { stage, search }), [customers, stage, search])
// Zähler mit derselben Funktion wie die Liste (beachten den Suchtext); bis zum Laden ohne Zahl
const counts = useMemo(() => stageCounts(customers, search), [customers, search])
const filtered = useMemo(() => filterCustomers(customers, { stage, search, nurKundenartFehlt: nurFehlt }), [customers, stage, search, nurFehlt])
// Zähler mit derselben Funktion wie die Liste (beachten Suchtext und Schalter); bis zum Laden ohne Zahl
const counts = useMemo(() => stageCounts(customers, search, { nurKundenartFehlt: nurFehlt }), [customers, search, nurFehlt])
const tabs = CUSTOMER_TABS.map((tab) => ({ id: tab.id, label: tab.label, count: loading ? undefined : counts[tab.id] }))
let content
@@ -100,6 +101,10 @@ export default function CustomersPage() {
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
<label className="check">
<input type="checkbox" checked={nurFehlt} onChange={(e) => setNurFehlt(e.target.checked)} />
Kundenart fehlt{loading ? '' : ` (${kundenartFehltAnzahl(customers)})`}
</label>
</div>
{content}