197 lines
9.2 KiB
TypeScript
197 lines
9.2 KiB
TypeScript
|
|
import React from 'react';
|
|
import { Eye, Star } from 'lucide-react';
|
|
import { Business } from '../../types';
|
|
|
|
import {
|
|
AreaChart,
|
|
Area,
|
|
XAxis,
|
|
YAxis,
|
|
CartesianGrid,
|
|
Tooltip,
|
|
ResponsiveContainer,
|
|
BarChart,
|
|
Bar
|
|
} from 'recharts';
|
|
|
|
const MousePointerClick = ({className}: {className?:string}) => (
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
|
|
<path d="M14 4.1 12 6" /><path d="m5.1 8-2.9-.8" /><path d="m6 12-1.9 2" /><path d="M7.2 2.2 8 5.1" /><path d="M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z" />
|
|
</svg>
|
|
);
|
|
|
|
interface DayStat {
|
|
date: string;
|
|
views: number;
|
|
clicks: number;
|
|
}
|
|
|
|
const CustomTooltip = ({ active, payload, label, color }: any) => {
|
|
if (active && payload && payload.length) {
|
|
return (
|
|
<div className="bg-white p-3 shadow-xl border border-gray-100 rounded-lg">
|
|
<p className="text-xs font-bold text-gray-400 uppercase tracking-widest mb-1">{label}</p>
|
|
<p className="text-lg font-bold" style={{ color }}>
|
|
{payload[0].value} {payload[0].name === 'views' ? 'Vues' : 'Clics'}
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const DashboardOverview = ({ business, stats }: {
|
|
business: Business,
|
|
stats: {
|
|
totalViews: number,
|
|
contactClicks: number,
|
|
dailyStats: DayStat[]
|
|
} | null
|
|
}) => (
|
|
<div className="space-y-6">
|
|
<h2 className="text-2xl font-bold font-serif text-gray-900">Tableau de bord</h2>
|
|
<div className="grid grid-cols-1 gap-5 sm:grid-cols-3">
|
|
<div className="bg-white overflow-hidden shadow-sm border border-gray-100 rounded-xl">
|
|
<div className="p-5">
|
|
<div className="flex items-center">
|
|
<div className="flex-shrink-0 bg-brand-50 rounded-lg p-3">
|
|
<Eye className="h-6 w-6 text-brand-600" />
|
|
</div>
|
|
<div className="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt className="text-sm font-medium text-gray-500 truncate">Vues de la fiche</dt>
|
|
<dd className="flex items-baseline">
|
|
<div className="text-2xl font-bold text-gray-900">{stats ? stats.totalViews : business.viewCount}</div>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="bg-white overflow-hidden shadow-sm border border-gray-100 rounded-xl">
|
|
<div className="p-5">
|
|
<div className="flex items-center">
|
|
<div className="flex-shrink-0 bg-blue-50 rounded-lg p-3">
|
|
<MousePointerClick className="h-6 w-6 text-blue-600" />
|
|
</div>
|
|
<div className="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt className="text-sm font-medium text-gray-500 truncate">Clics Contact</dt>
|
|
<dd className="flex items-baseline">
|
|
<div className="text-2xl font-bold text-gray-900">{stats ? stats.contactClicks : '...'}</div>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="bg-white overflow-hidden shadow-sm border border-gray-100 rounded-xl">
|
|
<div className="p-5">
|
|
<div className="flex items-center">
|
|
<div className="flex-shrink-0 bg-yellow-50 rounded-lg p-3">
|
|
<Star className="h-6 w-6 text-yellow-600" />
|
|
</div>
|
|
<div className="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt className="text-sm font-medium text-gray-500 truncate">Note moyenne</dt>
|
|
<dd className="flex items-baseline">
|
|
<div className="text-2xl font-bold text-gray-900">{business.rating}/5</div>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
<div className="bg-white shadow-sm border border-gray-100 rounded-xl p-6">
|
|
<div className="flex items-center justify-between mb-6">
|
|
<h3 className="text-lg font-bold text-gray-900">Historique des Visites</h3>
|
|
<div className="px-2 py-1 bg-brand-50 text-brand-700 text-[10px] font-bold uppercase rounded leading-none">30 derniers jours</div>
|
|
</div>
|
|
<div className="h-72 w-full">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<AreaChart data={stats?.dailyStats || []}>
|
|
<defs>
|
|
<linearGradient id="colorViews" x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="5%" stopColor="#d97706" stopOpacity={0.3}/>
|
|
<stop offset="95%" stopColor="#d97706" stopOpacity={0}/>
|
|
</linearGradient>
|
|
</defs>
|
|
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#f3f4f6" />
|
|
<XAxis
|
|
dataKey="date"
|
|
axisLine={false}
|
|
tickLine={false}
|
|
tick={{fill: '#9ca3af', fontSize: 10}}
|
|
interval={6}
|
|
/>
|
|
<YAxis
|
|
axisLine={false}
|
|
tickLine={false}
|
|
tick={{fill: '#9ca3af', fontSize: 10}}
|
|
/>
|
|
<Tooltip content={<CustomTooltip color="#d97706" />} />
|
|
<Area
|
|
type="monotone"
|
|
dataKey="views"
|
|
name="views"
|
|
stroke="#d97706"
|
|
strokeWidth={3}
|
|
fillOpacity={1}
|
|
fill="url(#colorViews)"
|
|
/>
|
|
</AreaChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="bg-white shadow-sm border border-gray-100 rounded-xl p-6">
|
|
<div className="flex items-center justify-between mb-6">
|
|
<h3 className="text-lg font-bold text-gray-900">Interactions Contact</h3>
|
|
<div className="px-2 py-1 bg-blue-50 text-blue-700 text-[10px] font-bold uppercase rounded leading-none">30 derniers jours</div>
|
|
</div>
|
|
<div className="h-72 w-full">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<AreaChart data={stats?.dailyStats || []}>
|
|
<defs>
|
|
<linearGradient id="colorClicks" x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="5%" stopColor="#2563eb" stopOpacity={0.3}/>
|
|
<stop offset="95%" stopColor="#2563eb" stopOpacity={0}/>
|
|
</linearGradient>
|
|
</defs>
|
|
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#f3f4f6" />
|
|
<XAxis
|
|
dataKey="date"
|
|
axisLine={false}
|
|
tickLine={false}
|
|
tick={{fill: '#9ca3af', fontSize: 10}}
|
|
interval={6}
|
|
/>
|
|
<YAxis
|
|
axisLine={false}
|
|
tickLine={false}
|
|
tick={{fill: '#9ca3af', fontSize: 10}}
|
|
/>
|
|
<Tooltip content={<CustomTooltip color="#2563eb" />} />
|
|
<Area
|
|
type="monotone"
|
|
dataKey="clicks"
|
|
name="clicks"
|
|
stroke="#2563eb"
|
|
strokeWidth={3}
|
|
fillOpacity={1}
|
|
fill="url(#colorClicks)"
|
|
/>
|
|
</AreaChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
export default DashboardOverview;
|