diff --git a/src/app/(app)/dashboard/page.tsx b/src/app/(app)/dashboard/page.tsx index 8cfef7c..cf330f9 100644 --- a/src/app/(app)/dashboard/page.tsx +++ b/src/app/(app)/dashboard/page.tsx @@ -218,12 +218,13 @@ export default function DashboardPage() { // Calculate real stats const totalScans = data.reduce((sum: number, qr: QRCodeData) => sum + (qr.scans || 0), 0); const activeQRCodes = data.filter((qr: QRCodeData) => qr.status === 'ACTIVE').length; - const conversionRate = activeQRCodes > 0 ? Math.round((totalScans / (activeQRCodes * 100)) * 100) : 0; + // Calculate "Unique Rate" (Conversion) + const conversionRate = totalScans > 0 ? Math.round((data.reduce((acc: number, qr: any) => acc + (qr.uniqueScans || 0), 0) / totalScans) * 100) : 0; setStats({ totalScans, activeQRCodes, - conversionRate: Math.min(conversionRate, 100), // Cap at 100% + conversionRate, }); } else { // If not logged in, show zeros diff --git a/src/app/(marketing)/blog/[slug]/page.tsx b/src/app/(marketing)/blog/[slug]/page.tsx index a0dfe09..06a8e77 100644 --- a/src/app/(marketing)/blog/[slug]/page.tsx +++ b/src/app/(marketing)/blog/[slug]/page.tsx @@ -2014,6 +2014,30 @@ export default function BlogPostPage({ params }: { params: { slug: string } }) { + + {/* Related Articles Section */} +
+

Related Articles

+
+ {Object.values(blogPosts) + .filter((p) => p.slug !== post.slug) + .slice(0, 3) + .map((relatedPost) => ( + + {relatedPost.category} +

+ {relatedPost.title} +

+

{relatedPost.excerpt}

+ Read more → + + ))} +
+
diff --git a/src/app/api/analytics/summary/route.ts b/src/app/api/analytics/summary/route.ts index 106d258..b41ba1c 100644 --- a/src/app/api/analytics/summary/route.ts +++ b/src/app/api/analytics/summary/route.ts @@ -140,8 +140,17 @@ export async function GET(request: NextRequest) { // Calculate trends const scansTrend = calculateTrend(totalScans, previousTotalScans); - const avgScansTrend = calculateTrend(avgScansPerQR, previousAvgScansPerQR); - + + // New Conversion Rate Logic: (Unique Scans / Total Scans) * 100 + // This represents "Engagement Efficiency" - how many scans are from fresh users + const currentConversion = totalScans > 0 ? Math.round((uniqueScans / totalScans) * 100) : 0; + + const previousConversion = previousTotalScans > 0 + ? Math.round((previousUniqueScans / previousTotalScans) * 100) + : 0; + + const avgScansTrend = calculateTrend(currentConversion, previousConversion); + // Device stats const deviceStats = qrCodes.flatMap(qr => qr.scans) .reduce((acc, scan) => { @@ -149,12 +158,12 @@ export async function GET(request: NextRequest) { acc[device] = (acc[device] || 0) + 1; return acc; }, {} as Record); - + const mobileScans = (deviceStats.mobile || 0) + (deviceStats.tablet || 0); - const mobilePercentage = totalScans > 0 - ? Math.round((mobileScans / totalScans) * 100) + const mobilePercentage = totalScans > 0 + ? Math.round((mobileScans / totalScans) * 100) : 0; - + // Country stats (current period) const countryStats = qrCodes.flatMap(qr => qr.scans) .reduce((acc, scan) => { @@ -172,8 +181,8 @@ export async function GET(request: NextRequest) { }, {} as Record); const topCountry = Object.entries(countryStats) - .sort(([,a], [,b]) => b - a)[0]; - + .sort(([, a], [, b]) => b - a)[0]; + // Daily scan counts for chart (current period) const dailyScans = qrCodes.flatMap(qr => qr.scans).reduce((acc, scan) => { const date = new Date(scan.ts).toISOString().split('T')[0]; @@ -215,7 +224,7 @@ export async function GET(request: NextRequest) { summary: { totalScans, uniqueScans, - avgScansPerQR, + avgScansPerQR: currentConversion, // Now sending Unique Rate instead of Avg per QR mobilePercentage, topCountry: topCountry ? topCountry[0] : 'N/A', topCountryPercentage: topCountry && totalScans > 0 @@ -228,7 +237,7 @@ export async function GET(request: NextRequest) { }, deviceStats, countryStats: Object.entries(countryStats) - .sort(([,a], [,b]) => b - a) + .sort(([, a], [, b]) => b - a) .slice(0, 10) .map(([country, count]) => { const previousCount = previousCountryStats[country] || 0; diff --git a/src/components/dashboard/StatsGrid.tsx b/src/components/dashboard/StatsGrid.tsx index 521e808..46f7dd8 100644 --- a/src/components/dashboard/StatsGrid.tsx +++ b/src/components/dashboard/StatsGrid.tsx @@ -67,9 +67,9 @@ export const StatsGrid: React.FC = ({ stats, trends }) => { ), }, { - title: t('dashboard.stats.conversion_rate'), + title: 'Unique Scan Rate', value: `${stats.conversionRate}%`, - change: stats.totalScans > 0 ? `${stats.conversionRate}% rate` : 'No scans yet', + change: stats.totalScans > 0 ? `${stats.conversionRate}% new users` : 'No scans yet', changeType: stats.conversionRate > 0 ? 'positive' : 'neutral' as 'positive' | 'negative' | 'neutral', icon: ( @@ -88,11 +88,10 @@ export const StatsGrid: React.FC = ({ stats, trends }) => {

{card.title}

{card.value}

-

+ 'text-gray-500' + }`}> {card.change}