/ src / components / AlertFilter.tsx
AlertFilter.tsx
  1  /**
  2   * Alert filter component for filtering notifications by type
  3   */
  4  import React from 'react';
  5  import {
  6    View,
  7    Text,
  8    StyleSheet,
  9    TouchableOpacity,
 10    ScrollView,
 11  } from 'react-native';
 12  import type { FilterType } from '../types/notifications';
 13  import {
 14    NOTIFICATION_TYPE_COLORS,
 15    NOTIFICATION_TYPE_LABELS,
 16  } from '../types/notifications';
 17  import { Colors } from '../theme/colors';
 18  
 19  interface AlertFilterProps {
 20    currentFilter: FilterType;
 21    onFilterChange: (filter: FilterType) => void;
 22    counts: Record<FilterType, number>;
 23  }
 24  
 25  interface FilterOption {
 26    value: FilterType;
 27    label: string;
 28    color?: string;
 29  }
 30  
 31  const FILTER_OPTIONS: FilterOption[] = [
 32    { value: 'all', label: 'All' },
 33    {
 34      value: 'governance',
 35      label: NOTIFICATION_TYPE_LABELS.governance,
 36      color: NOTIFICATION_TYPE_COLORS.governance,
 37    },
 38    {
 39      value: 'swap',
 40      label: NOTIFICATION_TYPE_LABELS.swap,
 41      color: NOTIFICATION_TYPE_COLORS.swap,
 42    },
 43    {
 44      value: 'price',
 45      label: NOTIFICATION_TYPE_LABELS.price,
 46      color: NOTIFICATION_TYPE_COLORS.price,
 47    },
 48    {
 49      value: 'system',
 50      label: NOTIFICATION_TYPE_LABELS.system,
 51      color: NOTIFICATION_TYPE_COLORS.system,
 52    },
 53  ];
 54  
 55  export function AlertFilter({
 56    currentFilter,
 57    onFilterChange,
 58    counts,
 59  }: AlertFilterProps) {
 60    return (
 61      <View style={styles.container}>
 62        <ScrollView
 63          horizontal
 64          showsHorizontalScrollIndicator={false}
 65          contentContainerStyle={styles.scrollContent}
 66        >
 67          {FILTER_OPTIONS.map((option) => {
 68            const isActive = currentFilter === option.value;
 69            const count = counts[option.value] || 0;
 70  
 71            return (
 72              <TouchableOpacity
 73                key={option.value}
 74                style={[
 75                  styles.filterButton,
 76                  isActive ? styles.activeButton : null,
 77                  isActive && option.color ? { borderColor: option.color } : null,
 78                ]}
 79                onPress={() => onFilterChange(option.value)}
 80                activeOpacity={0.7}
 81              >
 82                <Text
 83                  style={[
 84                    styles.filterText,
 85                    isActive ? styles.activeText : null,
 86                    isActive && option.color ? { color: option.color } : null,
 87                  ]}
 88                >
 89                  {option.label}
 90                </Text>
 91                {count > 0 && (
 92                  <View
 93                    style={[
 94                      styles.countBadge,
 95                      isActive && option.color
 96                        ? { backgroundColor: option.color }
 97                        : null,
 98                    ]}
 99                  >
100                    <Text style={styles.countText}>{count}</Text>
101                  </View>
102                )}
103              </TouchableOpacity>
104            );
105          })}
106        </ScrollView>
107      </View>
108    );
109  }
110  
111  const styles = StyleSheet.create({
112    container: {
113      paddingVertical: 12,
114      borderBottomWidth: 1,
115      borderBottomColor: Colors.border.default,
116    },
117    scrollContent: {
118      paddingHorizontal: 12,
119      gap: 8,
120    },
121    filterButton: {
122      flexDirection: 'row',
123      alignItems: 'center',
124      paddingHorizontal: 14,
125      paddingVertical: 8,
126      borderRadius: 20,
127      backgroundColor: Colors.background.secondary,
128      borderWidth: 1,
129      borderColor: Colors.border.strong,
130      marginHorizontal: 4,
131    },
132    activeButton: {
133      backgroundColor: Colors.background.tertiary,
134      borderColor: Colors.accent.alpha,
135    },
136    filterText: {
137      color: Colors.text.secondary,
138      fontSize: 14,
139      fontWeight: '500',
140    },
141    activeText: {
142      color: Colors.accent.alpha,
143    },
144    countBadge: {
145      marginLeft: 6,
146      backgroundColor: Colors.border.strong,
147      borderRadius: 10,
148      minWidth: 20,
149      height: 20,
150      justifyContent: 'center',
151      alignItems: 'center',
152      paddingHorizontal: 6,
153    },
154    countText: {
155      color: Colors.text.primary,
156      fontSize: 11,
157      fontWeight: 'bold',
158    },
159  });