updates on the active page and the profitability section
This commit is contained in:
@@ -9,8 +9,7 @@ import {
|
||||
MdRoute,
|
||||
MdLocationOn,
|
||||
MdBarChart,
|
||||
MdPeopleAlt,
|
||||
MdSearch
|
||||
MdPeopleAlt
|
||||
} from 'react-icons/md';
|
||||
import './ProfitabilitySection.css';
|
||||
|
||||
@@ -161,12 +160,12 @@ function OrdersBreakdownTable({ orders, getRevenue }) {
|
||||
const km = parseFloat(order.kms ?? order.actualkms ?? 0);
|
||||
const rev = getRevenue(order);
|
||||
return (
|
||||
<tr key={order.orderid ?? idx}>
|
||||
<tr key={`${order.orderid ?? 'order'}-${idx}`}>
|
||||
<td>
|
||||
<CustomerCell order={order} />
|
||||
</td>
|
||||
<td>
|
||||
<OrderStatusPill status={order.status} />
|
||||
<OrderStatusPill status={order.orderstatus ?? order.status} />
|
||||
</td>
|
||||
<td>
|
||||
<span className="distance-value">{km.toFixed(1)}</span>
|
||||
@@ -360,8 +359,6 @@ function RiderProfitabilityCard({ rider, metrics, isExpanded, isFocused, onToggl
|
||||
*/
|
||||
export default function ProfitabilitySection({ riders = [], totalDailyProfit = 0, focusedRider = null, handleRiderFocus }) {
|
||||
const [expanded, setExpanded] = useState({});
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [filterTab, setFilterTab] = useState('all'); // 'all', 'profitable', 'loss'
|
||||
const [sortMode, setSortMode] = useState('profit-asc'); // 'profit-asc', 'profit-desc', 'name-asc', 'orders-desc'
|
||||
|
||||
const toggleRider = useCallback((id) => {
|
||||
@@ -381,23 +378,8 @@ export default function ProfitabilitySection({ riders = [], totalDailyProfit = 0
|
||||
const dailyIsProfit = totalDailyProfit >= 0;
|
||||
const slotIsProfit = slotNet >= 0;
|
||||
|
||||
// Filter riders based on search query and filter tabs
|
||||
const filtered = useMemo(() => {
|
||||
return enriched.filter((r) => {
|
||||
const name = r.riderName ?? r.username ?? `Rider #${r.id}`;
|
||||
const matchesSearch = name.toLowerCase().includes(searchQuery.toLowerCase()) || String(r.id).includes(searchQuery);
|
||||
|
||||
const isProfitable = r._m.net >= 0;
|
||||
let matchesTab = true;
|
||||
if (filterTab === 'profitable') {
|
||||
matchesTab = isProfitable;
|
||||
} else if (filterTab === 'loss') {
|
||||
matchesTab = !isProfitable;
|
||||
}
|
||||
|
||||
return matchesSearch && matchesTab;
|
||||
});
|
||||
}, [enriched, searchQuery, filterTab]);
|
||||
// Filter riders (filtering by search and status tabs removed)
|
||||
const filtered = enriched;
|
||||
|
||||
// Sort riders based on selected sortMode
|
||||
const sortedAndFiltered = useMemo(() => {
|
||||
@@ -424,7 +406,7 @@ export default function ProfitabilitySection({ riders = [], totalDailyProfit = 0
|
||||
<header className="profitability-header">
|
||||
<div className="profitability-header-left">
|
||||
<div className="profitability-header-icon" aria-hidden="true">
|
||||
<MdBarChart size={24} />
|
||||
<MdBarChart size={18} />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="profitability-header-title">Profitability Overview</h2>
|
||||
@@ -496,58 +478,7 @@ export default function ProfitabilitySection({ riders = [], totalDailyProfit = 0
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Controls (Search, Filter, Sort) ── */}
|
||||
<div className="profitability-controls-bar">
|
||||
<div className="profitability-search-wrapper">
|
||||
<MdSearch className="profitability-search-icon" />
|
||||
<input
|
||||
type="text"
|
||||
className="profitability-search-input"
|
||||
placeholder="Search rider by name or ID..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="profitability-filter-tabs">
|
||||
<button
|
||||
type="button"
|
||||
className={`profitability-tab-btn ${filterTab === 'all' ? 'tab-active' : ''}`}
|
||||
onClick={() => setFilterTab('all')}
|
||||
>
|
||||
All <span className="profitability-tab-count">{enriched.length}</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`profitability-tab-btn ${filterTab === 'profitable' ? 'tab-active' : ''}`}
|
||||
onClick={() => setFilterTab('profitable')}
|
||||
>
|
||||
Profitable <span className="profitability-tab-count">{profitCount}</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`profitability-tab-btn ${filterTab === 'loss' ? 'tab-active' : ''}`}
|
||||
onClick={() => setFilterTab('loss')}
|
||||
>
|
||||
At Loss <span className="profitability-tab-count">{lossCount}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="profitability-sort-wrapper">
|
||||
<span className="profitability-sort-label">Sort:</span>
|
||||
<select
|
||||
className="profitability-sort-select"
|
||||
value={sortMode}
|
||||
onChange={(e) => setSortMode(e.target.value)}
|
||||
aria-label="Sort riders"
|
||||
>
|
||||
<option value="profit-asc">Lowest Profit First</option>
|
||||
<option value="profit-desc">Highest Profit First</option>
|
||||
<option value="name-asc">Rider Name (A-Z)</option>
|
||||
<option value="orders-desc">Orders Count (High-Low)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{/* ── Controls (Search) (removed) ── */}
|
||||
|
||||
{/* ── Rider feed ── */}
|
||||
<div className="rider-profitability-feed" role="list" aria-label="Rider cards">
|
||||
|
||||
Reference in New Issue
Block a user