File size: 2,085 Bytes
98fcc8e
 
 
 
 
 
 
 
 
 
 
fbae805
98fcc8e
 
 
 
3857bd9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fbae805
 
 
 
 
 
 
 
 
 
 
3857bd9
 
 
 
 
 
 
98fcc8e
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// Shared color utilities for consistent heatmap theming

// Use exact same colors for both daily and weekly views
const EMPTY_DOT_DARK = "#374151";   // gray-600 equivalent
const EMPTY_DOT_LIGHT = "#d1d5db";  // gray-300 equivalent

export const getHeatmapTheme = (primaryColor: string) => ({
  dark: [EMPTY_DOT_DARK, primaryColor],
  light: [EMPTY_DOT_LIGHT, primaryColor],
});

export const getHeatmapColorIntensity = (level: number, primaryColor: string, isDarkMode: boolean = false) => {
  if (level === 0) {
    return null; // Will use CSS classes for theme-aware empty state
  }
  
  // Create different intensities of the primary color
  const hexToRgb = (hex: string) => {
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
      r: parseInt(result[1], 16),
      g: parseInt(result[2], 16),
      b: parseInt(result[3], 16)
    } : null;
  };
  
  const rgbToHex = (r: number, g: number, b: number) => {
    return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
  };
  
  const rgb = hexToRgb(primaryColor);
  if (!rgb) {
    // Fallback to green scale if color parsing fails
    const greenIntensities = ['#0e4429', '#006d32', '#26a641', '#39d353'];
    return greenIntensities[Math.min(level - 1, 3)];
  }
  
  // Create intensity levels based on theme
  let intensityMultipliers: number[];
  
  if (isDarkMode) {
    // Dark mode: Start darker, get brighter (40% → 100%)
    intensityMultipliers = [0.4, 0.6, 0.8, 1.0];
  } else {
    // Light mode: Start brighter, get darker (100% → 40%)
    intensityMultipliers = [1.0, 0.8, 0.6, 0.4];
  }
  
  const multiplier = intensityMultipliers[Math.min(level - 1, 3)];
  
  const adjustedR = Math.round(rgb.r * multiplier);
  const adjustedG = Math.round(rgb.g * multiplier);
  const adjustedB = Math.round(rgb.b * multiplier);
  
  return rgbToHex(adjustedR, adjustedG, adjustedB);
};

export const getEmptyDotColors = () => ({
  dark: EMPTY_DOT_DARK,
  light: EMPTY_DOT_LIGHT,
});

export const getEmptyDotClasses = () => "bg-[#d1d5db] dark:bg-[#374151]";