feat(ui): complete ProCanvas role-based overhaul and fix Recharts crash

- Implement unified Neomorphic tactical layout for ProCanvas across Agent, Admin, and Owner roles.

- Add Quick Operations Log widget for immediate action logging.

- Integrate discrete Checkpoint/Stages progression system to replace static prize tracks.

- Build custom AnimatedCounter for GSAP-style numerical state changes.

- Fix Recharts ResponsiveContainer loading crash in OwnerSnapshot.jsx.
This commit is contained in:
Satyam
2026-02-21 21:23:37 +05:30
parent 7e166726da
commit 058b5bb217
8 changed files with 741 additions and 28 deletions
+39
View File
@@ -0,0 +1,39 @@
import React, { useEffect, useState, useRef } from 'react';
import { useInView } from 'framer-motion';
export const AnimatedCounter = ({ from = 0, to, duration = 1.5, className = "" }) => {
const [value, setValue] = useState(from);
const ref = useRef(null);
const isInView = useInView(ref, { once: true, margin: "-20px" });
useEffect(() => {
if (!isInView) return;
let startTime;
let animationFrame;
const animate = (timestamp) => {
if (!startTime) startTime = timestamp;
const progress = (timestamp - startTime) / (duration * 1000);
if (progress < 1) {
// Easing function: easeOutQuart
const easeOut = 1 - Math.pow(1 - progress, 4);
setValue(Math.floor(from + (to - from) * easeOut));
animationFrame = requestAnimationFrame(animate);
} else {
setValue(to);
}
};
animationFrame = requestAnimationFrame(animate);
return () => cancelAnimationFrame(animationFrame);
}, [from, to, duration, isInView]);
return (
<span ref={ref} className={className}>
{value.toLocaleString()}
</span>
);
};
+10
View File
@@ -154,6 +154,11 @@ const Layout = () => {
{ to: "/admin/schedule", icon: Calendar, label: "Schedule" },
{ to: "/admin/leaderboard", icon: Trophy, label: "Leaderboard" },
{ to: "/admin/maps", icon: Map, label: "Territory Map" },
{
to: "/admin/pro-canvas",
icon: LayoutDashboard,
label: <span><span className="text-[#fda913]">Pro</span>Canvas</span>
},
...commonItems,
];
case 'CONTRACTOR':
@@ -173,6 +178,11 @@ const Layout = () => {
return [
{ to: "/emp/fa/dashboard", icon: LayoutDashboard, label: "Dashboard" },
{ to: "/emp/fa/maps", icon: Map, label: "My Map" },
{
to: "/emp/fa/pro-canvas",
icon: LayoutDashboard,
label: <span><span className="text-[#fda913]">Pro</span>Canvas</span>
},
...commonItems,
];
default: // Customer or Fallback