feat: Add activity tracking toggle and customize status text
Some checks failed
Dev Deployment (Zero Downtime) / deploy-dev (push) Has been cancelled
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:
@@ -13,6 +13,8 @@ import {
|
||||
ChevronUp,
|
||||
Activity,
|
||||
X,
|
||||
Eye,
|
||||
EyeOff,
|
||||
} from "lucide-react";
|
||||
|
||||
// Types matching your n8n output
|
||||
@@ -54,6 +56,14 @@ export default function ActivityFeed() {
|
||||
const [isExpanded, setIsExpanded] = useState(true);
|
||||
const [isMinimized, setIsMinimized] = 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<{
|
||||
content: string;
|
||||
author: string;
|
||||
@@ -61,6 +71,11 @@ export default function ActivityFeed() {
|
||||
|
||||
// Fetch data every 30 seconds (optimized to match server cache)
|
||||
useEffect(() => {
|
||||
// Don't fetch if tracking is disabled
|
||||
if (!isTrackingEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// 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
|
||||
const interval = setInterval(fetchData, 30000);
|
||||
return () => clearInterval(interval);
|
||||
}, [isMinimized]);
|
||||
}, [isMinimized, isTrackingEnabled]);
|
||||
|
||||
// Fetch nerdy quote when idle
|
||||
useEffect(() => {
|
||||
@@ -1144,6 +1159,45 @@ export default function ActivityFeed() {
|
||||
}
|
||||
}, [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;
|
||||
|
||||
const activeCount = [
|
||||
@@ -1206,6 +1260,22 @@ export default function ActivityFeed() {
|
||||
</div>
|
||||
</div>
|
||||
<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
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
@@ -1487,7 +1557,13 @@ export default function ActivityFeed() {
|
||||
/>
|
||||
<span className="text-[11px] font-medium text-white/50 capitalize">
|
||||
{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}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user