Skip to content

Instantly share code, notes, and snippets.

@ideabrian
Created October 30, 2024 01:37
Show Gist options
  • Save ideabrian/0532b8d46d117113a2a97f39925906f3 to your computer and use it in GitHub Desktop.
Save ideabrian/0532b8d46d117113a2a97f39925906f3 to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from 'react';
import {
DollarSign,
Users,
Calculator,
Target,
ChevronRight,
Star,
TrendingUp,
Zap
} from 'lucide-react';
const Grid = () => {
const [selectedCells, setSelectedCells] = useState(0);
const [isAnimating, setIsAnimating] = useState(false);
const GRID_SIZE = 10;
const COMMISSION = 100;
const CELLS_TOTAL = GRID_SIZE * GRID_SIZE;
const TOTAL_POTENTIAL = COMMISSION * CELLS_TOTAL;
const calculateEarnings = (cells) => {
return cells * COMMISSION;
};
const getColorForCell = (index) => {
if (index < selectedCells) {
return 'bg-green-500';
}
return 'bg-gray-800';
};
const handleSliderChange = (e) => {
setSelectedCells(parseInt(e.target.value));
};
const animateToAmount = (amount) => {
setIsAnimating(true);
const targetCells = Math.floor(amount / COMMISSION);
let current = 0;
const interval = setInterval(() => {
current += Math.ceil(targetCells / 20);
if (current >= targetCells) {
setSelectedCells(targetCells);
clearInterval(interval);
setIsAnimating(false);
} else {
setSelectedCells(current);
}
}, 30);
};
// Create grid rows and cells
const renderGrid = () => {
const rows = [];
for (let i = 0; i < GRID_SIZE; i++) {
const cells = [];
for (let j = 0; j < GRID_SIZE; j++) {
const index = i * GRID_SIZE + j;
cells.push(
<div
key={`cell-${index}`}
className={`w-8 h-8 ${getColorForCell(index)} transition-colors duration-100`}
/>
);
}
rows.push(
<div key={`row-${i}`} className="flex gap-1">
{cells}
</div>
);
}
return rows;
};
return (
<div className="min-h-screen bg-gray-900 text-white py-12">
<div className="max-w-7xl mx-auto px-4">
{/* Updated Header */}
<div className="text-center mb-8">
<h1 className="text-4xl md:text-5xl font-bold mb-4">
Your Path to $10,000/month
</h1>
<p className="text-xl text-gray-300">
Each square represents $100 in earnings. Watch your monthly potential grow.
</p>
</div>
{/* Stats Bar */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8">
<div className="bg-white/5 rounded-xl p-4 backdrop-blur-lg border border-white/10">
<div className="text-sm text-gray-400 mb-1">Selected Customers</div>
<div className="text-2xl font-bold font-mono">
{selectedCells.toLocaleString()}
</div>
</div>
<div className="bg-white/5 rounded-xl p-4 backdrop-blur-lg border border-white/10">
<div className="text-sm text-gray-400 mb-1">Potential Earnings</div>
<div className="text-2xl font-bold font-mono text-green-500">
${calculateEarnings(selectedCells).toLocaleString()}
</div>
</div>
<div className="bg-white/5 rounded-xl p-4 backdrop-blur-lg border border-white/10">
<div className="text-sm text-gray-400 mb-1">Commission Per Sale</div>
<div className="text-2xl font-bold font-mono text-blue-500">
${COMMISSION}
</div>
</div>
<div className="bg-white/5 rounded-xl p-4 backdrop-blur-lg border border-white/10">
<div className="text-sm text-gray-400 mb-1">Progress to $10K</div>
<div className="text-2xl font-bold font-mono text-yellow-500">
{((calculateEarnings(selectedCells) / TOTAL_POTENTIAL) * 100).toFixed(1)}%
</div>
</div>
</div>
{/* Grid Container */}
<div className="mb-8 overflow-hidden rounded-xl border border-white/10 bg-gray-950 p-8">
<div className="mx-auto w-fit">
<div className="gap-1 flex flex-col">
{renderGrid()}
</div>
</div>
</div>
{/* Controls Below Grid */}
<div className="max-w-4xl mx-auto">
{/* Updated Quick Target Buttons */}
<div className="flex flex-wrap justify-center gap-3 mb-6">
{[1000, 2500, 5000, 7500, 10000].map((amount) => (
<button
key={amount}
onClick={() => animateToAmount(amount)}
disabled={isAnimating}
className="px-3 py-1.5 bg-white/5 rounded-lg hover:bg-white/10 border border-white/10 transition-all text-sm"
>
${amount.toLocaleString()}
</button>
))}
</div>
{/* Slider Control */}
<div className="mb-8">
<input
type="range"
min="0"
max={CELLS_TOTAL}
value={selectedCells}
onChange={handleSliderChange}
className="w-full h-2 bg-white/10 rounded-lg appearance-none cursor-pointer"
/>
</div>
{/* Updated Goal Cards */}
<div className="grid md:grid-cols-4 gap-4">
<div className="bg-white/5 rounded-xl p-4 backdrop-blur-lg border border-white/10">
<Target className="w-6 h-6 text-blue-500 mb-2" />
<h3 className="text-lg font-bold mb-1">Quick Start</h3>
<p className="text-gray-400 text-sm">10 sales = $1,000</p>
</div>
<div className="bg-white/5 rounded-xl p-4 backdrop-blur-lg border border-white/10">
<TrendingUp className="w-6 h-6 text-green-500 mb-2" />
<h3 className="text-lg font-bold mb-1">Growth Goal</h3>
<p className="text-gray-400 text-sm">25 sales = $2,500</p>
</div>
<div className="bg-white/5 rounded-xl p-4 backdrop-blur-lg border border-white/10">
<Star className="w-6 h-6 text-yellow-500 mb-2" />
<h3 className="text-lg font-bold mb-1">Scale Goal</h3>
<p className="text-gray-400 text-sm">50 sales = $5,000</p>
</div>
<div className="bg-white/5 rounded-xl p-4 backdrop-blur-lg border border-white/10">
<Zap className="w-6 h-6 text-purple-500 mb-2" />
<h3 className="text-lg font-bold mb-1">Freedom Goal</h3>
<p className="text-gray-400 text-sm">100 sales = $10,000</p>
</div>
</div>
</div>
</div>
</div>
);
};
export default Grid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment