feat: break visitor carousel into 5 separate slides with unique titles
This commit is contained in:
@@ -4,7 +4,7 @@ import { useState, useEffect, useCallback } from 'react'
|
||||
import Image from 'next/image'
|
||||
import { AnimatePresence, motion } from 'framer-motion'
|
||||
import { PulseMockup } from '@/components/marketing/mockups/pulse-mockup'
|
||||
import { PulseFeaturesCarousel } from '@/components/marketing/mockups/pulse-features-carousel'
|
||||
import { PagesCard, ReferrersCard, LocationsCard, TechnologyCard, PeakHoursCard } from '@/components/marketing/mockups/pulse-features-carousel'
|
||||
import { FunnelMockup } from '@/components/marketing/mockups/funnel-mockup'
|
||||
import { EmailReportMockup } from '@/components/marketing/mockups/email-report-mockup'
|
||||
|
||||
@@ -13,9 +13,21 @@ interface Slide {
|
||||
mockup: React.ReactNode
|
||||
}
|
||||
|
||||
function FeatureCard({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="rounded-xl border border-white/[0.08] bg-neutral-900/80 px-6 py-5 shadow-2xl">
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const slides: Slide[] = [
|
||||
{ headline: 'Your traffic, at a glance.', mockup: <PulseMockup /> },
|
||||
{ headline: 'Everything you need to know about your visitors.', mockup: <PulseFeaturesCarousel /> },
|
||||
{ headline: 'See which pages perform best.', mockup: <FeatureCard><PagesCard /></FeatureCard> },
|
||||
{ headline: 'Know where your visitors come from.', mockup: <FeatureCard><ReferrersCard /></FeatureCard> },
|
||||
{ headline: 'Visitors from around the world.', mockup: <FeatureCard><LocationsCard /></FeatureCard> },
|
||||
{ headline: 'Understand your audience's tech stack.', mockup: <FeatureCard><TechnologyCard /></FeatureCard> },
|
||||
{ headline: 'Find your peak traffic hours.', mockup: <FeatureCard><PeakHoursCard /></FeatureCard> },
|
||||
{ headline: 'See where visitors drop off.', mockup: <FunnelMockup /> },
|
||||
{ headline: 'Reports delivered to your inbox.', mockup: <EmailReportMockup /> },
|
||||
]
|
||||
|
||||
@@ -113,7 +113,7 @@ function BarRow({
|
||||
|
||||
// ─── Card 1: Pages ───────────────────────────────────────────────────────────
|
||||
|
||||
function PagesCard() {
|
||||
export function PagesCard() {
|
||||
const data = [
|
||||
{ label: '/', value: 142 },
|
||||
{ label: '/products/drop', value: 68 },
|
||||
@@ -169,7 +169,7 @@ function getReferrerIcon(name: string, favicon?: string) {
|
||||
|
||||
const FAVICON_URL = 'https://www.google.com/s2/favicons'
|
||||
|
||||
function ReferrersCard() {
|
||||
export function ReferrersCard() {
|
||||
const data = [
|
||||
{ label: 'Direct', value: 186 },
|
||||
{ label: 'Google', value: 94, domain: 'google.com' },
|
||||
@@ -206,7 +206,7 @@ function ReferrersCard() {
|
||||
|
||||
// ─── Card 3: Locations (Real Dotted Map) ─────────────────────────────────────
|
||||
|
||||
function LocationsCard() {
|
||||
export function LocationsCard() {
|
||||
const mockData = [
|
||||
{ country: 'CH', pageviews: 320 },
|
||||
{ country: 'US', pageviews: 186 },
|
||||
@@ -300,7 +300,7 @@ const BROWSER_ICONS: Record<string, string> = {
|
||||
Opera: '/icons/browsers/opera.svg',
|
||||
}
|
||||
|
||||
function TechnologyCard() {
|
||||
export function TechnologyCard() {
|
||||
const data = [
|
||||
{ label: 'Chrome', value: 412 },
|
||||
{ label: 'Safari', value: 189 },
|
||||
@@ -381,7 +381,7 @@ function getHighlightColor(value: number, max: number): string {
|
||||
return HIGHLIGHT_COLORS[4]
|
||||
}
|
||||
|
||||
function PeakHoursCard() {
|
||||
export function PeakHoursCard() {
|
||||
const max = Math.max(...MOCK_GRID.flat())
|
||||
|
||||
// Find best time
|
||||
|
||||
Reference in New Issue
Block a user