mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 18:28:15 +00:00
feat: Lead Master — column show/hide toggle, resizable table, remove dead filter/sort buttons
- ColumnToggle component with checkbox dropdown for column visibility - useColumnVisibility hook for state management - Campaign/Ad/FirstContact/Spam/Dups hidden by default (mostly empty) - ResizableTableContainer wrapping Table for column resize support - Column defaultWidth/minWidth props - Removed non-functional Filter and Sort buttons Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,19 +2,18 @@ import type { FC } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faArrowLeft, faArrowDownToLine, faFilterList, faMagnifyingGlass, faArrowUpArrowDown } from '@fortawesome/pro-duotone-svg-icons';
|
||||
import { faArrowLeft, faArrowDownToLine, faMagnifyingGlass } from '@fortawesome/pro-duotone-svg-icons';
|
||||
|
||||
const ArrowLeft: FC<{ className?: string }> = ({ className }) => <FontAwesomeIcon icon={faArrowLeft} className={className} />;
|
||||
const Download01: FC<{ className?: string }> = ({ className }) => <FontAwesomeIcon icon={faArrowDownToLine} className={className} />;
|
||||
const FilterLines: FC<{ className?: string }> = ({ className }) => <FontAwesomeIcon icon={faFilterList} className={className} />;
|
||||
const SearchLg: FC<{ className?: string }> = ({ className }) => <FontAwesomeIcon icon={faMagnifyingGlass} className={className} />;
|
||||
const SwitchVertical01: FC<{ className?: string }> = ({ className }) => <FontAwesomeIcon icon={faArrowUpArrowDown} className={className} />;
|
||||
import { Button } from '@/components/base/buttons/button';
|
||||
import { Input } from '@/components/base/input/input';
|
||||
import { Tabs, TabList, Tab } from '@/components/application/tabs/tabs';
|
||||
import { PaginationPageDefault } from '@/components/application/pagination/pagination';
|
||||
import { TopBar } from '@/components/layout/top-bar';
|
||||
import { LeadTable } from '@/components/leads/lead-table';
|
||||
import { ColumnToggle, useColumnVisibility } from '@/components/application/table/column-toggle';
|
||||
import { BulkActionBar } from '@/components/leads/bulk-action-bar';
|
||||
import { FilterPills } from '@/components/leads/filter-pills';
|
||||
import { AssignModal } from '@/components/modals/assign-modal';
|
||||
@@ -61,6 +60,22 @@ export const AllLeadsPage = () => {
|
||||
const { agents, templates, leadActivities, campaigns } = useData();
|
||||
const [campaignFilter, setCampaignFilter] = useState<string | null>(null);
|
||||
|
||||
const columnDefs = [
|
||||
{ id: 'phone', label: 'Phone', defaultVisible: true },
|
||||
{ id: 'name', label: 'Name', defaultVisible: true },
|
||||
{ id: 'email', label: 'Email', defaultVisible: true },
|
||||
{ id: 'campaign', label: 'Campaign', defaultVisible: false },
|
||||
{ id: 'ad', label: 'Ad', defaultVisible: false },
|
||||
{ id: 'source', label: 'Source', defaultVisible: true },
|
||||
{ id: 'firstContactedAt', label: 'First Contact', defaultVisible: false },
|
||||
{ id: 'lastContactedAt', label: 'Last Contact', defaultVisible: true },
|
||||
{ id: 'status', label: 'Status', defaultVisible: true },
|
||||
{ id: 'createdAt', label: 'Age', defaultVisible: true },
|
||||
{ id: 'spamScore', label: 'Spam', defaultVisible: false },
|
||||
{ id: 'dups', label: 'Dups', defaultVisible: false },
|
||||
];
|
||||
const { visibleColumns, toggle: toggleColumn } = useColumnVisibility(columnDefs);
|
||||
|
||||
// Client-side sorting
|
||||
const sortedLeads = useMemo(() => {
|
||||
const sorted = [...filteredLeads];
|
||||
@@ -233,20 +248,6 @@ export const AllLeadsPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
size="sm"
|
||||
color="secondary"
|
||||
iconLeading={FilterLines}
|
||||
>
|
||||
Filter
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
color="secondary"
|
||||
iconLeading={SwitchVertical01}
|
||||
>
|
||||
Sort
|
||||
</Button>
|
||||
<div className="w-56">
|
||||
<Input
|
||||
placeholder="Search leads..."
|
||||
@@ -260,6 +261,7 @@ export const AllLeadsPage = () => {
|
||||
aria-label="Search leads"
|
||||
/>
|
||||
</div>
|
||||
<ColumnToggle columns={columnDefs} visibleColumns={visibleColumns} onToggle={toggleColumn} />
|
||||
<Button
|
||||
size="sm"
|
||||
color="secondary"
|
||||
@@ -350,6 +352,7 @@ export const AllLeadsPage = () => {
|
||||
sortDirection={sortDirection}
|
||||
onSort={handleSort}
|
||||
onViewActivity={handleViewActivity}
|
||||
visibleColumns={visibleColumns}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user