All files / src/stores newsletterSubscriberStore.ts

100% Statements 18/18
100% Branches 0/0
100% Functions 14/14
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                                                                              2x             2x         2x         2x   2x       6x 6x                 6x 6x                 4x 4x                 8x 8x               3x 3x               2x 2x               22x                
/**
 * Newsletter Subscriber Store
 *
 * Zustand store for client-side state management of subscriber list filters,
 * pagination, and sort state.
 *
 * Story 10.28: Newsletter Subscriber Management Page
 */
 
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
 
export interface NewsletterSubscriberFilters {
  searchQuery?: string;
  status?: 'active' | 'unsubscribed' | 'suppressed' | 'all';
  sortBy?: string;
  sortDir?: 'asc' | 'desc';
}
 
interface NewsletterSubscriberPagination {
  page: number;
  limit: number;
}
 
interface NewsletterSubscriberState {
  // State
  filters: NewsletterSubscriberFilters;
  pagination: NewsletterSubscriberPagination;
 
  // Actions
  setFilters: (filters: NewsletterSubscriberFilters) => void;
  setSearchQuery: (query: string) => void;
  setSort: (field: string, dir: 'asc' | 'desc') => void;
  setPage: (page: number) => void;
  setLimit: (limit: number) => void;
  resetFilters: () => void;
  reset: () => void;
}
 
const DEFAULT_FILTERS: NewsletterSubscriberFilters = {
  searchQuery: '',
  status: 'all',
  sortBy: 'subscribedAt',
  sortDir: 'desc',
};
 
const DEFAULT_PAGINATION: NewsletterSubscriberPagination = {
  page: 1,
  limit: 20,
};
 
const initialState = {
  filters: DEFAULT_FILTERS,
  pagination: DEFAULT_PAGINATION,
};
 
export const useNewsletterSubscriberStore = create<NewsletterSubscriberState>()(
  devtools(
    (set) => ({
      ...initialState,
 
      setFilters: (filters: NewsletterSubscriberFilters) =>
        set(
          (state) => ({
            filters: { ...state.filters, ...filters },
            pagination: { ...state.pagination, page: 1 },
          }),
          false,
          'setFilters'
        ),
 
      setSearchQuery: (query: string) =>
        set(
          (state) => ({
            filters: { ...state.filters, searchQuery: query },
            pagination: { ...state.pagination, page: 1 },
          }),
          false,
          'setSearchQuery'
        ),
 
      setSort: (field: string, dir: 'asc' | 'desc') =>
        set(
          (state) => ({
            filters: { ...state.filters, sortBy: field, sortDir: dir },
            pagination: { ...state.pagination, page: 1 },
          }),
          false,
          'setSort'
        ),
 
      setPage: (page: number) =>
        set(
          (state) => ({
            pagination: { ...state.pagination, page },
          }),
          false,
          'setPage'
        ),
 
      setLimit: (limit: number) =>
        set(
          (state) => ({
            pagination: { ...state.pagination, limit, page: 1 },
          }),
          false,
          'setLimit'
        ),
 
      resetFilters: () =>
        set(
          () => ({
            filters: DEFAULT_FILTERS,
            pagination: DEFAULT_PAGINATION,
          }),
          false,
          'resetFilters'
        ),
 
      reset: () => set(initialState, false, 'reset'),
    }),
    {
      name: 'newsletter-subscriber-store',
      enabled: import.meta.env.DEV,
    }
  )
);