aramej

Claude AI Performance Heatmap

Nov 10th, 2024
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.32 KB | None | 0 0
  1. import React, { useState, useEffect } from 'react';
  2. import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
  3.  
  4. // Constants
  5. const CONFIG = {
  6. CENTER: { X: 250, Y: 250 },
  7. RADIUS: { OUTER: 180, INNER: 80 },
  8. HOURS: Array.from({ length: 24 }, (_, i) => i),
  9. REGIONS: ['Europe', 'North America', 'Asia', 'Australia'],
  10. TASK_TYPES: {
  11. 'general': 'General Use',
  12. 'coding': 'Programming & Development',
  13. 'writing': 'Content Writing',
  14. 'translation': 'Translation Tasks',
  15. 'analysis': 'Data Analysis'
  16. }
  17. };
  18.  
  19. // Performance calculation utilities
  20. const getPerformanceScore = (hour, region, taskType = 'general') => {
  21. let adjustedHour = hour;
  22. const offsets = { 'North America': -5, 'Europe': 1, 'Asia': 8, 'Australia': 10 };
  23. adjustedHour = (hour + (offsets[region] || 0) + 24) % 24;
  24.  
  25. let baseScore = 0.7;
  26. // Upravené časové pásma na základe diskusie
  27. const timeRanges = {
  28. 'deep_night': { hours: [1, 5], score: 0.98 }, // Najlepší výkon (2am PST)
  29. 'early_morning': { hours: [5, 8], score: 0.85 }, // Stále dobrý výkon
  30. 'morning_peak': { hours: [8, 12], score: 0.3 }, // Najhoršia špička (8am US)
  31. 'afternoon': { hours: [12, 17], score: 0.35 }, // Vysoká záťaž
  32. 'evening': { hours: [17, 20], score: 0.65 }, // Zlepšenie po práci
  33. 'night': { hours: [20, 24], score: 0.8 }, // Postupné zlepšovanie
  34. 'midnight': { hours: [0, 1], score: 0.9 } // Prechod do najlepšieho výkonu
  35. };
  36.  
  37. Object.values(timeRanges).forEach(({ hours, score }) => {
  38. if (adjustedHour >= hours[0] && adjustedHour < hours[1]) {
  39. baseScore = score;
  40. }
  41. });
  42.  
  43. // Vylepšené modifikátory na základe používateľských skúseností
  44. const taskModifiers = {
  45. 'coding': adjustedHour >= 1 && adjustedHour < 5 ? 0.1 :
  46. adjustedHour >= 8 && adjustedHour < 17 ? -0.15 : -0.05, // Výrazný rozdiel v noci
  47. 'writing': adjustedHour >= 9 && adjustedHour < 17 ? -0.1 :
  48. adjustedHour >= 0 && adjustedHour < 5 ? 0.05 : 0, // Lepšie v noci
  49. 'translation': adjustedHour >= 0 && adjustedHour < 5 ? 0.02 : 0, // Mierne lepšie v noci
  50. 'analysis': adjustedHour >= 0 && adjustedHour < 5 ? 0.08 :
  51. adjustedHour >= 8 && adjustedHour < 17 ? -0.08 : 0, // Analytické úlohy
  52. 'general': 0
  53. };
  54.  
  55. return Math.min(1, Math.max(0, baseScore + (taskModifiers[taskType] || 0)));
  56. };
  57.  
  58. const ClaudePerformanceHeatmap = () => {
  59. // Add custom animation styles
  60. useEffect(() => {
  61. const style = document.createElement('style');
  62. style.textContent = `
  63. @keyframes peak-performance {
  64. 0% { opacity: 0.05; transform: scale(1); }
  65. 50% { opacity: 0.2; transform: scale(1.02); }
  66. 100% { opacity: 0.05; transform: scale(1); }
  67. }
  68. .animate-peak-performance {
  69. animation: peak-performance 4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
  70. }
  71. @keyframes pulse-slow {
  72. 0% { opacity: 0; transform: scale(1); }
  73. 50% { opacity: 0.3; transform: scale(1.02); }
  74. 100% { opacity: 0; transform: scale(1); }
  75. }
  76. @keyframes pulse-glow {
  77. 0% { filter: brightness(1); }
  78. 50% { filter: brightness(1.3); }
  79. 100% { filter: brightness(1); }
  80. }
  81. @keyframes status-pulse {
  82. 0% { transform: scale(0.95); opacity: 0.8; }
  83. 50% { transform: scale(1.05); opacity: 1; }
  84. 100% { transform: scale(0.95); opacity: 0.8; }
  85. }
  86. .animate-pulse-slow {
  87. animation: pulse-slow 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
  88. }
  89. .animate-pulse-glow {
  90. animation: pulse-glow 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
  91. }
  92. .animate-status {
  93. animation: status-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
  94. }
  95. `;
  96. document.head.appendChild(style);
  97. return () => document.head.removeChild(style);
  98. }, []);
  99. const [selectedRegion, setSelectedRegion] = useState('Europe');
  100. const [selectedTask, setSelectedTask] = useState('general');
  101. const [hoveredSegment, setHoveredSegment] = useState(null);
  102. const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 });
  103. const [showTooltip, setShowTooltip] = useState(false);
  104. const [currentTime, setCurrentTime] = useState(new Date());
  105. const [userTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone);
  106.  
  107. useEffect(() => {
  108. const timer = setInterval(() => setCurrentTime(new Date()), 60000);
  109. return () => clearInterval(timer);
  110. }, []);
  111.  
  112. const getCurrentLoadStatus = (region) => {
  113. const hour = currentTime.getHours();
  114. const performance = getPerformanceScore(hour, region);
  115.  
  116. if (performance >= 0.8) return {
  117. status: 'Low Load',
  118. color: '#22c55e',
  119. message: 'Optimal time for complex tasks'
  120. };
  121. if (performance >= 0.6) return {
  122. status: 'Moderate',
  123. color: '#eab308',
  124. message: 'Good for most tasks'
  125. };
  126. return {
  127. status: 'High Load',
  128. color: '#ef4444',
  129. message: 'Peak Hours - Expect Delays'
  130. };
  131. };
  132.  
  133. const generateSegments = () => {
  134. const currentHour = currentTime.getHours();
  135.  
  136. return CONFIG.HOURS.map(hour => {
  137. const startAngle = (hour * 15 - 90) * (Math.PI / 180);
  138. const endAngle = ((hour + 1) * 15 - 90) * (Math.PI / 180);
  139. const performance = getPerformanceScore(hour, selectedRegion, selectedTask);
  140.  
  141. const getPoint = (radius, angle) => ({
  142. x: CONFIG.CENTER.X + radius * Math.cos(angle),
  143. y: CONFIG.CENTER.Y + radius * Math.sin(angle)
  144. });
  145.  
  146. const start = getPoint(CONFIG.RADIUS.INNER, startAngle);
  147. const end = getPoint(CONFIG.RADIUS.INNER, endAngle);
  148. const outerStart = getPoint(CONFIG.RADIUS.OUTER, startAngle);
  149. const outerEnd = getPoint(CONFIG.RADIUS.OUTER, endAngle);
  150.  
  151. const path = [
  152. `M ${start.x} ${start.y}`,
  153. `L ${outerStart.x} ${outerStart.y}`,
  154. `A ${CONFIG.RADIUS.OUTER} ${CONFIG.RADIUS.OUTER} 0 0 1 ${outerEnd.x} ${outerEnd.y}`,
  155. `L ${end.x} ${end.y}`,
  156. `A ${CONFIG.RADIUS.INNER} ${CONFIG.RADIUS.INNER} 0 0 0 ${start.x} ${start.y}`,
  157. 'Z'
  158. ].join(' ');
  159.  
  160. return (
  161. <g key={hour}>
  162. {/* Peak Performance Marker */}
  163. {currentHour === hour && (
  164. <path
  165. d={path}
  166. fill="white"
  167. opacity="0.2"
  168. className="animate-pulse-slow"
  169. />
  170. )}
  171. {getPerformanceScore(hour, selectedRegion, selectedTask) > 0.95 && (
  172. <path
  173. d={path}
  174. fill="white"
  175. opacity="0.1"
  176. className="animate-peak-performance"
  177. />
  178. )}
  179. <path
  180. d={path}
  181. fill={performance >= 0.8 ? '#22c55e' : performance >= 0.6 ? '#eab308' : '#ef4444'}
  182. opacity={hoveredSegment === hour ? 1 : currentHour === hour ? 0.9 : 0.7}
  183. className={currentHour === hour ? 'animate-pulse-glow' : ''}
  184. onMouseEnter={(e) => {
  185. setHoveredSegment(hour);
  186. setShowTooltip(true);
  187. const rect = e.currentTarget.getBoundingClientRect();
  188. setTooltipPosition({
  189. x: rect.left + (rect.width / 2),
  190. y: rect.top - 10
  191. });
  192. }}
  193. onMouseLeave={() => {
  194. setHoveredSegment(null);
  195. setShowTooltip(false);
  196. }}
  197. />
  198. <text
  199. x={CONFIG.CENTER.X + (CONFIG.RADIUS.OUTER + 30) * Math.cos((hour * 15 - 90) * (Math.PI / 180))}
  200. y={CONFIG.CENTER.Y + (CONFIG.RADIUS.OUTER + 30) * Math.sin((hour * 15 - 90) * (Math.PI / 180))}
  201. fill="#9ca3af"
  202. textAnchor="middle"
  203. dominantBaseline="middle"
  204. fontSize="12"
  205. >
  206. {`${hour}:00`}
  207. </text>
  208. </g>
  209. );
  210. });
  211. };
  212.  
  213. const loadStatus = getCurrentLoadStatus(selectedRegion);
  214.  
  215. return (
  216. <div className="min-h-screen bg-gray-950 p-4">
  217. <Card className="w-full max-w-3xl mx-auto bg-gray-900 border-gray-800">
  218. <CardHeader>
  219. <CardTitle className="text-gray-100">Claude AI Performance Heatmap</CardTitle>
  220. </CardHeader>
  221. <CardContent>
  222. <div className="flex flex-col items-center gap-4 mb-6">
  223. <div className="flex items-center gap-4">
  224. <select
  225. value={selectedRegion}
  226. onChange={(e) => setSelectedRegion(e.target.value)}
  227. className="bg-gray-800 text-gray-100 p-2 rounded border border-gray-700"
  228. >
  229. {CONFIG.REGIONS.map(region => (
  230. <option key={region} value={region}>{region}</option>
  231. ))}
  232. </select>
  233.  
  234. <select
  235. value={selectedTask}
  236. onChange={(e) => setSelectedTask(e.target.value)}
  237. className="bg-gray-800 text-gray-100 p-2 rounded border border-gray-700"
  238. >
  239. {Object.entries(CONFIG.TASK_TYPES).map(([key, label]) => (
  240. <option key={key} value={key}>{label}</option>
  241. ))}
  242. </select>
  243.  
  244. <div
  245. className="flex items-center gap-2 px-3 py-1.5 rounded-full transition-all duration-700"
  246. style={{
  247. backgroundColor: `${loadStatus.color}15`,
  248. border: `1px solid ${loadStatus.color}`,
  249. boxShadow: `0 0 10px ${loadStatus.color}25`
  250. }}
  251. >
  252. <div
  253. className="relative"
  254. >
  255. <div
  256. className="w-2 h-2 rounded-full transition-colors duration-700"
  257. style={{ backgroundColor: loadStatus.color }}
  258. />
  259. <div
  260. className="absolute top-0 left-0 w-2 h-2 rounded-full animate-status"
  261. style={{
  262. backgroundColor: loadStatus.color,
  263. }}
  264. />
  265. </div>
  266. <span
  267. className="text-sm font-medium transition-colors duration-700"
  268. style={{ color: loadStatus.color }}
  269. >
  270. {loadStatus.status}
  271. </span>
  272. </div>
  273. </div>
  274.  
  275. <p className="text-gray-400 text-sm">{loadStatus.message}</p>
  276. <p className="text-gray-500 text-xs">Your timezone: {userTimezone}</p>
  277.  
  278. <button
  279. onClick={() => {
  280. const bestHour = CONFIG.HOURS.reduce((best, hour) => {
  281. return getPerformanceScore(hour, selectedRegion, selectedTask) >
  282. getPerformanceScore(best, selectedRegion, selectedTask) ? hour : best;
  283. }, 0);
  284. setHoveredSegment(bestHour);
  285. setShowTooltip(true);
  286. }}
  287. className="px-4 py-2 bg-gray-800 hover:bg-gray-700 text-gray-200 rounded-full transition-colors text-sm"
  288. >
  289. Find Best Time
  290. </button>
  291. </div>
  292.  
  293. <div className="relative w-full flex justify-center">
  294. <svg viewBox="-50 -50 600 600" className="w-full max-w-2xl">
  295. <g>
  296. {generateSegments()}
  297. <circle
  298. cx={CONFIG.CENTER.X}
  299. cy={CONFIG.CENTER.Y}
  300. r={CONFIG.RADIUS.INNER - 10}
  301. className="fill-gray-950"
  302. />
  303. <text
  304. x={CONFIG.CENTER.X}
  305. y={CONFIG.CENTER.Y - 10}
  306. textAnchor="middle"
  307. className="fill-gray-300 text-xl"
  308. >
  309. {currentTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
  310. </text>
  311. <text
  312. x={CONFIG.CENTER.X}
  313. y={CONFIG.CENTER.Y + 15}
  314. textAnchor="middle"
  315. className="fill-gray-500 text-sm"
  316. >
  317. {userTimezone}
  318. </text>
  319. </g>
  320. </svg>
  321.  
  322. {showTooltip && hoveredSegment !== null && (
  323. <div
  324. className="absolute bg-gray-800 text-gray-100 p-2 rounded shadow-lg border border-gray-700 text-sm"
  325. style={{
  326. left: tooltipPosition.x,
  327. top: tooltipPosition.y,
  328. transform: 'translate(-50%, -100%)'
  329. }}
  330. >
  331. <div>Time: {hoveredSegment}:00</div>
  332. <div>Performance: {Math.round(getPerformanceScore(hoveredSegment, selectedRegion, selectedTask) * 100)}%</div>
  333. </div>
  334. )}
  335. </div>
  336.  
  337. <div className="mt-6 flex items-center justify-center gap-4 text-sm">
  338. <span className="text-red-500">Lower Performance</span>
  339. <div className="w-32 h-2 bg-gradient-to-r from-red-500 via-yellow-500 to-green-500 rounded" />
  340. <span className="text-green-500">Higher Performance</span>
  341. </div>
  342. </CardContent>
  343. </Card>
  344. </div>
  345. );
  346. };
  347.  
  348. export default ClaudePerformanceHeatmap;
Advertisement
Add Comment
Please, Sign In to add comment