platform-codebase/@packages/@plugins/analytics/src/pages/ConversionFunnelsPage.tsx

105 lines
3.4 KiB
TypeScript
Executable file

import React, { useState } from 'react'
import {
useConversionMetrics,
useFunnelData,
useConversionBySource,
} from '../hooks/useAdminQuery'
export const ConversionFunnelsPage: React.FC = () => {
const { data: metrics, isLoading, isError } = useConversionMetrics()
const { data: funnelData } = useFunnelData()
const { data: bySource } = useConversionBySource()
const [_dateRange, setDateRange] = useState('30 Days')
if (isLoading) {
return <div>Loading conversion data...</div>
}
if (isError) {
return <div>Failed to load conversion data</div>
}
const isLowConversion = (metrics?.overallConversionRate ?? 0) < 5
return (
<div className="conversion-funnels-page">
<h1 data-testid="page-title">Conversion Funnels</h1>
{/* Low Conversion Alert */}
{isLowConversion && (
<div className="alert">Low Conversion Rate Alert</div>
)}
{/* KPI Cards */}
<div className="kpi-cards">
<div className="kpi-card">
<div className="kpi-label">Overall Conversion Rate</div>
<div className="kpi-value">{metrics?.overallConversionRate}%</div>
</div>
<div className="kpi-card">
<div className="kpi-label">Signup to Subscriber</div>
<div className="kpi-value">{metrics?.signupToSubscriber}%</div>
</div>
<div className="kpi-card">
<div className="kpi-label">Visitor to Signup</div>
<div className="kpi-value">{metrics?.visitorToSignup}%</div>
</div>
<div className="kpi-card">
<div className="kpi-label">Free to Trial</div>
<div className="kpi-value">{metrics?.freeToTrial}%</div>
</div>
<div className="kpi-card">
<div className="kpi-label">Trial to Paid</div>
<div className="kpi-value">{metrics?.trialToPaid}%</div>
</div>
<div className="kpi-card">
<div className="kpi-label">Avg Time to Conversion</div>
<div className="kpi-value">{metrics?.avgTimeToConversion} days</div>
</div>
</div>
{/* Date Range Selector */}
<div className="date-range">
<button onClick={() => setDateRange('7 Days')}>7 Days</button>
<button onClick={() => setDateRange('30 Days')}>30 Days</button>
<button onClick={() => setDateRange('90 Days')}>90 Days</button>
</div>
{/* Conversion Funnel Visualization */}
<div className="conversion-funnel">
<h2>Conversion Funnel</h2>
{funnelData?.map((stage, idx) => (
<div key={idx} className="funnel-stage">
<div className="stage-name">{stage.stage}</div>
<div className="stage-count">{stage.count.toLocaleString()}</div>
<div className="stage-rate">{stage.rate}%</div>
</div>
))}
</div>
{/* Conversion by Source */}
<div className="conversion-by-source">
<h2>Conversion by Source</h2>
<table>
<thead>
<tr>
<th>Source</th>
<th>Conversions</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
{bySource?.map((source, idx) => (
<tr key={idx}>
<td>{source.source}</td>
<td>{source.conversions.toLocaleString()}</td>
<td>{source.rate}%</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)
}