feat: Add activity tracking toggle and customize status text
Some checks failed
Dev Deployment (Zero Downtime) / deploy-dev (push) Has been cancelled

- Add toggle button to enable/disable activity tracking
- Store tracking preference in localStorage
- Change 'Do Not Disturb' to 'Nicht stören' (German)
- Add better status text translations (online, offline, away)
- Show disabled state when tracking is off
- Stop fetching activity data when tracking is disabled
This commit is contained in:
2026-01-09 17:25:57 +01:00
parent 60e69eb37b
commit 242a808590

View File

@@ -13,6 +13,8 @@ import {
ChevronUp, ChevronUp,
Activity, Activity,
X, X,
Eye,
EyeOff,
} from "lucide-react"; } from "lucide-react";
// Types matching your n8n output // Types matching your n8n output
@@ -54,6 +56,14 @@ export default function ActivityFeed() {
const [isExpanded, setIsExpanded] = useState(true); const [isExpanded, setIsExpanded] = useState(true);
const [isMinimized, setIsMinimized] = useState(false); const [isMinimized, setIsMinimized] = useState(false);
const [hasActivity, setHasActivity] = useState(false); const [hasActivity, setHasActivity] = useState(false);
const [isTrackingEnabled, setIsTrackingEnabled] = useState(() => {
// Check localStorage for tracking preference
if (typeof window !== 'undefined') {
const stored = localStorage.getItem('activityTrackingEnabled');
return stored !== 'false'; // Default to true if not set
}
return true;
});
const [quote, setQuote] = useState<{ const [quote, setQuote] = useState<{
content: string; content: string;
author: string; author: string;
@@ -61,6 +71,11 @@ export default function ActivityFeed() {
// Fetch data every 30 seconds (optimized to match server cache) // Fetch data every 30 seconds (optimized to match server cache)
useEffect(() => { useEffect(() => {
// Don't fetch if tracking is disabled
if (!isTrackingEnabled) {
return;
}
const fetchData = async () => { const fetchData = async () => {
try { try {
// Add timestamp to prevent aggressive caching but respect server cache // Add timestamp to prevent aggressive caching but respect server cache
@@ -109,7 +124,7 @@ export default function ActivityFeed() {
// The n8n API already has 30s cache, so faster polling doesn't help // The n8n API already has 30s cache, so faster polling doesn't help
const interval = setInterval(fetchData, 30000); const interval = setInterval(fetchData, 30000);
return () => clearInterval(interval); return () => clearInterval(interval);
}, [isMinimized]); }, [isMinimized, isTrackingEnabled]);
// Fetch nerdy quote when idle // Fetch nerdy quote when idle
useEffect(() => { useEffect(() => {
@@ -1144,6 +1159,45 @@ export default function ActivityFeed() {
} }
}, [hasActivity, quote]); }, [hasActivity, quote]);
// Toggle tracking on/off
const toggleTracking = () => {
const newValue = !isTrackingEnabled;
setIsTrackingEnabled(newValue);
if (typeof window !== 'undefined') {
localStorage.setItem('activityTrackingEnabled', String(newValue));
}
// Clear data when disabling
if (!newValue) {
setData(null);
setHasActivity(false);
}
};
// Don't render if tracking is disabled and no data
if (!isTrackingEnabled && !data) return null;
// If tracking disabled but we have data, show a disabled state
if (!isTrackingEnabled && data) {
return (
<div className="fixed bottom-4 right-4 md:bottom-6 md:right-6 z-40 pointer-events-auto">
<motion.div
initial={{ scale: 0, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
className="bg-black/80 backdrop-blur-xl border border-white/10 rounded-xl p-3 shadow-2xl"
>
<button
onClick={toggleTracking}
className="flex items-center gap-2 text-white/60 hover:text-white transition-colors"
title="Activity tracking is disabled. Click to enable."
>
<EyeOff size={16} />
<span className="text-xs">Tracking disabled</span>
</button>
</motion.div>
</div>
);
}
if (!data) return null; if (!data) return null;
const activeCount = [ const activeCount = [
@@ -1206,6 +1260,22 @@ export default function ActivityFeed() {
</div> </div>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
{/* Toggle Tracking Button */}
<button
onClick={(e) => {
e.stopPropagation();
toggleTracking();
}}
className="p-1.5 hover:bg-white/10 rounded-lg transition-colors"
title={isTrackingEnabled ? "Disable activity tracking" : "Enable activity tracking"}
aria-label={isTrackingEnabled ? "Disable tracking" : "Enable tracking"}
>
{isTrackingEnabled ? (
<Eye size={14} className="text-white/60 hover:text-white" />
) : (
<EyeOff size={14} className="text-white/60 hover:text-white" />
)}
</button>
<div <div
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
@@ -1487,7 +1557,13 @@ export default function ActivityFeed() {
/> />
<span className="text-[11px] font-medium text-white/50 capitalize"> <span className="text-[11px] font-medium text-white/50 capitalize">
{data.status.text === "dnd" {data.status.text === "dnd"
? "Do Not Disturb" ? "Nicht stören"
: data.status.text === "online"
? "Online"
: data.status.text === "offline"
? "Offline"
: data.status.text === "away"
? "Abwesend"
: data.status.text} : data.status.text}
</span> </span>
</div> </div>