Add roll-call Start/Stop UX to business and customer dashboards.
Owners/admins can run timed work days, manage tasks in a modal, and stop from the FAB or row control. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
ac287e02cc
commit
c4e846564e
@@ -6,6 +6,8 @@ export interface MultiSelectOption<T extends string | number = number> {
|
||||
value: T
|
||||
label: string
|
||||
depth?: number
|
||||
/** Extra text matched by search (e.g. EN+FA names, tags). */
|
||||
keywords?: string
|
||||
}
|
||||
|
||||
interface MultiSelectDropdownProps<T extends string | number = number> {
|
||||
@@ -43,7 +45,10 @@ export function MultiSelectDropdown<T extends string | number = number>({
|
||||
const filteredOptions = useMemo(() => {
|
||||
const query = searchQuery.trim().toLowerCase()
|
||||
if (!query) return options
|
||||
return options.filter((o) => o.label.toLowerCase().includes(query))
|
||||
return options.filter((o) => {
|
||||
const haystack = `${o.label} ${o.keywords ?? ''}`.toLowerCase()
|
||||
return haystack.includes(query)
|
||||
})
|
||||
}, [options, searchQuery])
|
||||
|
||||
const triggerLabel = useMemo(() => {
|
||||
|
||||
@@ -2,10 +2,12 @@ export interface BusinessCategory {
|
||||
id: number
|
||||
parentId: number | null
|
||||
name: string
|
||||
nameFa: string | null
|
||||
slug: string
|
||||
description: string | null
|
||||
icon: string | null
|
||||
sortOrder: number
|
||||
tags?: string[]
|
||||
}
|
||||
|
||||
export interface BusinessCategoriesResponse {
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
import type { BusinessCategory } from '../types/category'
|
||||
import type { MultiSelectOption } from '../components/MultiSelectDropdown'
|
||||
|
||||
/** Match IranBay: "English / فارسی" when both exist. */
|
||||
export function businessCategoryLabel(
|
||||
category: Pick<BusinessCategory, 'name' | 'nameFa'>,
|
||||
) {
|
||||
const nameFa = category.nameFa?.trim()
|
||||
if (nameFa && nameFa !== category.name) {
|
||||
return `${category.name} / ${nameFa}`
|
||||
}
|
||||
return category.name
|
||||
}
|
||||
|
||||
export function flattenBusinessCategories(
|
||||
categories: BusinessCategory[],
|
||||
): MultiSelectOption<number>[] {
|
||||
@@ -12,7 +23,15 @@ export function flattenBusinessCategories(
|
||||
.sort((a, b) => a.sortOrder - b.sortOrder || a.name.localeCompare(b.name))
|
||||
|
||||
for (const child of children) {
|
||||
result.push({ value: child.id, label: child.name, depth })
|
||||
const keywords = [child.name, child.nameFa ?? '', child.slug, ...(child.tags ?? [])]
|
||||
.join(' ')
|
||||
.trim()
|
||||
result.push({
|
||||
value: child.id,
|
||||
label: businessCategoryLabel(child),
|
||||
depth,
|
||||
keywords,
|
||||
})
|
||||
walk(child.id, depth + 1)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user