feat: Comprehensive contextual headers for all pages
Applied "bigger picture" thinking - added contextual headers to ALL submenu pages consistently. Problem: Only some pages had headers, creating inconsistent UX Issues Fixed: 1. Dashboard Submenu Pages - All Now Have Headers Before: Only Overview had header After: All 6 pages have headers (Revenue, Orders, Products, Customers, Coupons, Taxes) 2. Settings Pages Desktop - Show Headers (Except Payments) Before: PageHeader was md:hidden on all pages After: Shows on desktop for Settings pages, hidden only for Payments (special case) Implementation: - Added usePageHeader to 6 Dashboard submenu pages - Modified PageHeader to show on desktop by default - Auto-detect Payments page and hide header there Result: - ALL Dashboard pages have contextual headers - ALL Settings pages have contextual headers on desktop - Payments page special case handled - Consistent UX across entire app - No more bald pages! Files Modified: 6 Dashboard pages + PageHeader.tsx
This commit is contained in:
@@ -1,20 +1,26 @@
|
||||
import React from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { usePageHeader } from '@/contexts/PageHeaderContext';
|
||||
|
||||
interface PageHeaderProps {
|
||||
fullscreen?: boolean;
|
||||
hideOnDesktop?: boolean;
|
||||
}
|
||||
|
||||
export function PageHeader({ fullscreen = false }: PageHeaderProps) {
|
||||
export function PageHeader({ fullscreen = false, hideOnDesktop = false }: PageHeaderProps) {
|
||||
const { title, action } = usePageHeader();
|
||||
const location = useLocation();
|
||||
|
||||
if (!title) return null;
|
||||
|
||||
// Special case: Payments page should hide header on desktop (has its own layout)
|
||||
const isPaymentsPage = location.pathname.startsWith('/settings/payments');
|
||||
const shouldHideOnDesktop = hideOnDesktop || isPaymentsPage;
|
||||
|
||||
// PageHeader is now ABOVE submenu in DOM order
|
||||
// z-20 ensures it stays on top when both are sticky
|
||||
// Mobile-only: hidden on desktop (md:hidden)
|
||||
return (
|
||||
<div className="sticky top-0 z-20 border-b bg-background md:hidden">
|
||||
<div className={`sticky top-0 z-20 border-b bg-background ${shouldHideOnDesktop ? 'md:hidden' : ''}`}>
|
||||
<div className="w-full max-w-5xl mx-auto px-4 py-3 flex items-center justify-between min-w-0">
|
||||
<div className="min-w-0 flex-1">
|
||||
<h1 className="text-lg font-semibold truncate">{title}</h1>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import React, { useState, useMemo, useEffect } from 'react';
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts';
|
||||
import { Tag, DollarSign, TrendingUp, ShoppingCart } from 'lucide-react';
|
||||
import { __ } from '@/lib/i18n';
|
||||
@@ -12,11 +12,18 @@ import { ChartCard } from './components/ChartCard';
|
||||
import { DataTable, Column } from './components/DataTable';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { DUMMY_COUPONS_DATA, CouponsData, CouponPerformance } from './data/dummyCoupons';
|
||||
import { usePageHeader } from '@/contexts/PageHeaderContext';
|
||||
|
||||
export default function CouponsReport() {
|
||||
const { setPageHeader, clearPageHeader } = usePageHeader();
|
||||
const { period } = useDashboardPeriod();
|
||||
const store = getStoreCurrency();
|
||||
|
||||
useEffect(() => {
|
||||
setPageHeader(__('Coupons'));
|
||||
return () => clearPageHeader();
|
||||
}, [setPageHeader, clearPageHeader]);
|
||||
|
||||
// Fetch real data or use dummy data based on toggle
|
||||
const { data, isLoading, error, refetch } = useCouponsAnalytics(DUMMY_COUPONS_DATA);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import React, { useState, useMemo, useEffect } from 'react';
|
||||
import { BarChart, Bar, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts';
|
||||
import { Users, TrendingUp, DollarSign, ShoppingCart, UserPlus, UserCheck, Info } from 'lucide-react';
|
||||
import { __ } from '@/lib/i18n';
|
||||
@@ -12,11 +12,18 @@ import { ChartCard } from './components/ChartCard';
|
||||
import { DataTable, Column } from './components/DataTable';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { DUMMY_CUSTOMERS_DATA, CustomersData, TopCustomer } from './data/dummyCustomers';
|
||||
import { usePageHeader } from '@/contexts/PageHeaderContext';
|
||||
|
||||
export default function CustomersAnalytics() {
|
||||
const { setPageHeader, clearPageHeader } = usePageHeader();
|
||||
const { period } = useDashboardPeriod();
|
||||
const store = getStoreCurrency();
|
||||
|
||||
useEffect(() => {
|
||||
setPageHeader(__('Customers'));
|
||||
return () => clearPageHeader();
|
||||
}, [setPageHeader, clearPageHeader]);
|
||||
|
||||
// Fetch real data or use dummy data based on toggle
|
||||
const { data, isLoading, error, refetch } = useCustomersAnalytics(DUMMY_CUSTOMERS_DATA);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useMemo, useRef } from 'react';
|
||||
import React, { useState, useMemo, useRef, useEffect } from 'react';
|
||||
import { BarChart, Bar, LineChart, Line, AreaChart, Area, ComposedChart, PieChart, Pie, Cell, Label, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts';
|
||||
import { ShoppingCart, TrendingUp, Package, XCircle, DollarSign, CheckCircle, Clock } from 'lucide-react';
|
||||
import { __ } from '@/lib/i18n';
|
||||
@@ -12,13 +12,20 @@ import { ChartCard } from './components/ChartCard';
|
||||
import { DataTable, Column } from './components/DataTable';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { DUMMY_ORDERS_DATA, OrdersData } from './data/dummyOrders';
|
||||
import { usePageHeader } from '@/contexts/PageHeaderContext';
|
||||
|
||||
export default function OrdersAnalytics() {
|
||||
const { setPageHeader, clearPageHeader } = usePageHeader();
|
||||
const { period } = useDashboardPeriod();
|
||||
const store = getStoreCurrency();
|
||||
const [hoverIndex, setHoverIndex] = useState<number | undefined>(undefined);
|
||||
const chartRef = useRef<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setPageHeader(__('Orders'));
|
||||
return () => clearPageHeader();
|
||||
}, [setPageHeader, clearPageHeader]);
|
||||
|
||||
// Fetch real data or use dummy data based on toggle
|
||||
const { data, isLoading, error, refetch } = useOrdersAnalytics(DUMMY_ORDERS_DATA);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import React, { useState, useMemo, useEffect } from 'react';
|
||||
import { Package, TrendingUp, DollarSign, AlertTriangle, XCircle } from 'lucide-react';
|
||||
import { __ } from '@/lib/i18n';
|
||||
import { formatMoney, getStoreCurrency } from '@/lib/currency';
|
||||
@@ -12,11 +12,18 @@ import { DataTable, Column } from './components/DataTable';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { DUMMY_PRODUCTS_DATA, ProductsData, TopProduct, ProductByCategory, StockAnalysisProduct } from './data/dummyProducts';
|
||||
import { usePageHeader } from '@/contexts/PageHeaderContext';
|
||||
|
||||
export default function ProductsPerformance() {
|
||||
const { setPageHeader, clearPageHeader } = usePageHeader();
|
||||
const { period } = useDashboardPeriod();
|
||||
const store = getStoreCurrency();
|
||||
|
||||
useEffect(() => {
|
||||
setPageHeader(__('Products'));
|
||||
return () => clearPageHeader();
|
||||
}, [setPageHeader, clearPageHeader]);
|
||||
|
||||
// Fetch real data or use dummy data based on toggle
|
||||
const { data, isLoading, error, refetch } = useProductsAnalytics(DUMMY_PRODUCTS_DATA);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import React, { useState, useMemo, useEffect } from 'react';
|
||||
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts';
|
||||
import { DollarSign, TrendingUp, TrendingDown, CreditCard, Truck, RefreshCw } from 'lucide-react';
|
||||
import { __ } from '@/lib/i18n';
|
||||
@@ -13,12 +13,19 @@ import { DataTable, Column } from './components/DataTable';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { DUMMY_REVENUE_DATA, RevenueData, RevenueByProduct, RevenueByCategory, RevenueByPaymentMethod, RevenueByShippingMethod } from './data/dummyRevenue';
|
||||
import { usePageHeader } from '@/contexts/PageHeaderContext';
|
||||
|
||||
export default function RevenueAnalytics() {
|
||||
const { setPageHeader, clearPageHeader } = usePageHeader();
|
||||
const { period } = useDashboardPeriod();
|
||||
const [granularity, setGranularity] = useState<'day' | 'week' | 'month'>('day');
|
||||
const store = getStoreCurrency();
|
||||
|
||||
useEffect(() => {
|
||||
setPageHeader(__('Revenue'));
|
||||
return () => clearPageHeader();
|
||||
}, [setPageHeader, clearPageHeader]);
|
||||
|
||||
// Fetch real data or use dummy data based on toggle
|
||||
const { data, isLoading, error, refetch } = useRevenueAnalytics(DUMMY_REVENUE_DATA, granularity);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import React, { useState, useMemo, useEffect } from 'react';
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
||||
import { DollarSign, FileText, ShoppingCart, TrendingUp } from 'lucide-react';
|
||||
import { __ } from '@/lib/i18n';
|
||||
@@ -12,11 +12,18 @@ import { ChartCard } from './components/ChartCard';
|
||||
import { DataTable, Column } from './components/DataTable';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { DUMMY_TAXES_DATA, TaxesData, TaxByRate, TaxByLocation } from './data/dummyTaxes';
|
||||
import { usePageHeader } from '@/contexts/PageHeaderContext';
|
||||
|
||||
export default function TaxesReport() {
|
||||
const { setPageHeader, clearPageHeader } = usePageHeader();
|
||||
const { period } = useDashboardPeriod();
|
||||
const store = getStoreCurrency();
|
||||
|
||||
useEffect(() => {
|
||||
setPageHeader(__('Taxes'));
|
||||
return () => clearPageHeader();
|
||||
}, [setPageHeader, clearPageHeader]);
|
||||
|
||||
// Fetch real data or use dummy data based on toggle
|
||||
const { data, isLoading, error, refetch } = useTaxesAnalytics(DUMMY_TAXES_DATA);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user