Recents in Beach

Analytics Dashboard | React-common-tracking


import React, { useState, useEffect } from 'react';

// Simple SVG Icons (replacing lucide-react)
const Icons = {
  Users: () => <svg className="w-6 h-6" fill="none"
stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round"
strokeLinejoin="round" strokeWidth={2}
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0
0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" /></svg>,
 
Eye: () => <svg className="w-6 h-6" fill="none"
stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round"
strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
<path strokeLinecap="round" strokeLinejoin="round"
strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5
12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064
7-9.542 7-4.477 0-8.268-2.943-9.542-7z" /></svg>,
 
Globe: () => <svg className="w-6 h-6" fill="none"
stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round"
strokeWidth={2} d="M3.055 11H5a2 2 0 012 2v1a2 2 0
002 2 2 2 0 012 2v2.945M8 3.935V5.5A2 2 0 009.5 8h2a2
2 0 002 2 2 2 0 002-2h1.064M15 20.488V18a2 2 0 013-1.736" />
<circle cx="12" cy="12" r="10" stroke="currentColor"
strokeWidth="2" fill="none"/></svg>,
 
Clock: () => <svg className="w-6 h-6" fill="none"
stroke="currentColor" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" strokeWidth={2}/>
<polyline points="12 6 12 12 16 14" strokeWidth={2}/></svg>,
 
TrendingUp: () => <svg className="w-6 h-6" fill="none"
stroke="currentColor" viewBox="0 0 24 24">
<polyline points="23 6 13.5 15.5 8.5 10.5 1 18"
strokeWidth={2}/><polyline points="17 6 23 12 23 6"
strokeWidth={2}/></svg>,
 
ExternalLink: () => <svg className="w-6 h-6" fill="none"
stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round"
strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0
002-2v-4M14 4h6m0 0v6m0-6L10 14" /></svg>,
 
Loader2: () => <svg className="w-16 h-16 animate-spin"
fill="none" viewBox="0 0 24 24"><circle cx="12" cy="12"
r="10" stroke="currentColor" strokeWidth="4" opacity="0.25"/>
<path d="M4 12a8 8 0 018-8" stroke="currentColor"
strokeWidth="4" strokeLinecap="round"/></svg>,
};

উপরের জিনিস গুলো হলো আইকন। SVG দিয়ে icon বানানো হয়েছে <Icons.Eye /> বা <Icons.Users /> এভাবে ব্যবহার

// Animated Counter
const AnimatedCounter = ({ value, suffix = '' }) => {
  const [count, setCount] = useState(0);
  useEffect(() => {
    let start = 0;
    const end = parseInt(value);
    const duration = 2000;
    const increment = end / (duration / 16);
    const timer = setInterval(() => {
      start += increment;
      if (start > end) {
        setCount(end);
        clearInterval(timer);
      } else setCount(Math.floor(start));
    }, 16);
    return () => clearInterval(timer);
  }, [value]);

  return <span className="text-4xl font-bold bg-gradient-to-r
from-blue-600 to-purple-600 bg-clip-text text-transparent">
{count.toLocaleString()}{suffix}</span>;
};

AnimatedCounter কী?

AnimatedCounter হলো একটি React component যা কোনো সংখ্যাকে ০ থেকে ধীরে ধীরে বাড়িয়ে নির্দিষ্ট মান পর্যন্ত এনিমেশনসহ দেখায়।

ধরো, value=1000 দিলে—এটা সরাসরি 1000 দেখাবে না, বরং 0 → 1 → 2 → … → 1000 এইভাবে বাড়তে থাকবে (animation effect)।

// Stats Card
const StatsCard = ({ title, value, Icon, trend, color = 'blue' })
 => {
  const bg = {
    blue: 'from-blue-500 to-blue-600',
    green: 'from-emerald-500 to-emerald-600',
    purple: 'from-purple-500 to-purple-600',
    orange: 'from-orange-500 to-orange-600',
  }[color];
Stats Card দিয়ে নিচে ব্যাবহার করা হয়েছে।
        <div className="grid grid-cols-1 sm:grid-cols-2
            lg:grid-cols-4 gap-8 mb-12">
          <StatsCard title="Total Visitors" value={125420}
            Icon={Icons.Users} trend={12} color="blue" />
          <StatsCard title="Unique Visitors" value={89234}
            Icon={Icons.Eye} trend={8} color="green" />
          <StatsCard title="New Visit" value={742105}
            Icon={Icons.TrendingUp} trend={18} color="purple" />
          <StatsCard title="Avg. Time (mins)" value={3}
            Icon={Icons.Clock} trend={-5} color="orange" />
        </div>

উপরের যে চারটি কার্ড সেগুলো কে কন্টল বানানোর জন্য এই কোডটি বানানো হয়।


চারটি গ্রিড এর জন্য বানানো হয়েছে। তাই এখানে flex justify-between items-start এটা ব্যবহার করা 
হয়েছে। এখন Icon className="text-white" এটা দিয়ে আইকন এর কালার বানানো হয়েছে। ${trend > 0 ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'} এটা দিয়ে শূন্য এর বেশি হলে bg-green-100 text-green-700 এটি কাজ করবে আর এর কম হলে অন্যটি যেমন bg-red-100 text-red-700 কাজ করবে।{trend !== undefined && ( আর বিশেষ করে যদি trend এর ভ্যালু থাকে তাহলে (undefined না হয়) তাহলেই <span> দেখাবে। {trend > 0 ? 'Up' : 'Down'} {Math.abs(trend)}% trend  


  return (
    <div className="bg-white rounded-2xl shadow-xl
    p-6 hover:shadow-2xl transition-all border
    border-gray-100 w-[100%]">
      <div className="flex justify-between items-start mb-4">
        <div className={`p-4 rounded-xl bg-gradient-to-br ${bg}`}>
          <Icon className="text-white" />
        </div>
        {trend !== undefined && (
          <span className={`px-3 py-1 rounded-full text-sm
                font-bold
          ${trend > 0 ? 'bg-green-100 text-green-700' :
          'bg-red-100 text-red-700'}`}>
            {trend > 0 ? 'Up' : 'Down'} {Math.abs(trend)}%
          </span>
        )}
      </div>
      <p className="text-gray-600 text-sm">{title}</p>
      <div className="mt-2"><AnimatedCounter
      value={value} suffix={title.includes('Time') ? 'm' : ''} />
      </div>
    </div>
  );
};

Post a Comment

0 Comments