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 Image from 'next/image'
|
||||||
import { AnimatePresence, motion } from 'framer-motion'
|
import { AnimatePresence, motion } from 'framer-motion'
|
||||||
import { PulseMockup } from '@/components/marketing/mockups/pulse-mockup'
|
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 { FunnelMockup } from '@/components/marketing/mockups/funnel-mockup'
|
||||||
import { EmailReportMockup } from '@/components/marketing/mockups/email-report-mockup'
|
import { EmailReportMockup } from '@/components/marketing/mockups/email-report-mockup'
|
||||||
|
|
||||||
@@ -13,9 +13,21 @@ interface Slide {
|
|||||||
mockup: React.ReactNode
|
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[] = [
|
const slides: Slide[] = [
|
||||||
{ headline: 'Your traffic, at a glance.', mockup: <PulseMockup /> },
|
{ 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: 'See where visitors drop off.', mockup: <FunnelMockup /> },
|
||||||
{ headline: 'Reports delivered to your inbox.', mockup: <EmailReportMockup /> },
|
{ headline: 'Reports delivered to your inbox.', mockup: <EmailReportMockup /> },
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ function BarRow({
|
|||||||
|
|
||||||
// ─── Card 1: Pages ───────────────────────────────────────────────────────────
|
// ─── Card 1: Pages ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
function PagesCard() {
|
export function PagesCard() {
|
||||||
const data = [
|
const data = [
|
||||||
{ label: '/', value: 142 },
|
{ label: '/', value: 142 },
|
||||||
{ label: '/products/drop', value: 68 },
|
{ label: '/products/drop', value: 68 },
|
||||||
@@ -169,7 +169,7 @@ function getReferrerIcon(name: string, favicon?: string) {
|
|||||||
|
|
||||||
const FAVICON_URL = 'https://www.google.com/s2/favicons'
|
const FAVICON_URL = 'https://www.google.com/s2/favicons'
|
||||||
|
|
||||||
function ReferrersCard() {
|
export function ReferrersCard() {
|
||||||
const data = [
|
const data = [
|
||||||
{ label: 'Direct', value: 186 },
|
{ label: 'Direct', value: 186 },
|
||||||
{ label: 'Google', value: 94, domain: 'google.com' },
|
{ label: 'Google', value: 94, domain: 'google.com' },
|
||||||
@@ -206,7 +206,7 @@ function ReferrersCard() {
|
|||||||
|
|
||||||
// ─── Card 3: Locations (Real Dotted Map) ─────────────────────────────────────
|
// ─── Card 3: Locations (Real Dotted Map) ─────────────────────────────────────
|
||||||
|
|
||||||
function LocationsCard() {
|
export function LocationsCard() {
|
||||||
const mockData = [
|
const mockData = [
|
||||||
{ country: 'CH', pageviews: 320 },
|
{ country: 'CH', pageviews: 320 },
|
||||||
{ country: 'US', pageviews: 186 },
|
{ country: 'US', pageviews: 186 },
|
||||||
@@ -300,7 +300,7 @@ const BROWSER_ICONS: Record<string, string> = {
|
|||||||
Opera: '/icons/browsers/opera.svg',
|
Opera: '/icons/browsers/opera.svg',
|
||||||
}
|
}
|
||||||
|
|
||||||
function TechnologyCard() {
|
export function TechnologyCard() {
|
||||||
const data = [
|
const data = [
|
||||||
{ label: 'Chrome', value: 412 },
|
{ label: 'Chrome', value: 412 },
|
||||||
{ label: 'Safari', value: 189 },
|
{ label: 'Safari', value: 189 },
|
||||||
@@ -381,7 +381,7 @@ function getHighlightColor(value: number, max: number): string {
|
|||||||
return HIGHLIGHT_COLORS[4]
|
return HIGHLIGHT_COLORS[4]
|
||||||
}
|
}
|
||||||
|
|
||||||
function PeakHoursCard() {
|
export function PeakHoursCard() {
|
||||||
const max = Math.max(...MOCK_GRID.flat())
|
const max = Math.max(...MOCK_GRID.flat())
|
||||||
|
|
||||||
// Find best time
|
// Find best time
|
||||||
|
|||||||
Reference in New Issue
Block a user