All files / marketing-platform/presentation/hooks useGetPromotions.ts

100% Statements 63/63
60% Branches 6/10
100% Functions 9/9
100% Lines 63/63

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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173                1x 50x 50x 50x   50x 50x         50x 11x 11x 11x 11x 8x 8x     3x 3x 3x   11x               50x   3x 3x 3x 3x     2x 2x     1x     1x 1x   3x                 50x   5x 5x 5x 5x     4x 4x     1x     1x 1x   5x                 50x   4x 4x 4x 4x     3x 3x     1x     1x 1x   4x                 50x 1x           50x 1x           50x 1x 1x 1x       50x 21x 21x 3x       50x                                              
import { useState, useEffect, useCallback } from "react";
import { PromotionApplication, ApplicationStatus } from "../../domain";
import { ServiceContainer } from "../../infrastructure";
 
/**
 * Custom React hook for managing promotion applications
 * Provides methods to fetch and filter promotions with loading and error states
 */
export const useGetPromotions = (options?: { autoLoad?: boolean }) => {
  const [promotions, setPromotions] = useState<PromotionApplication[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
 
  const container = ServiceContainer.getInstance();
  const getAllPromotionsUseCase = container.getGetAllPromotionsUseCase();
 
  /**
   * Fetches all promotion applications
   */
  const fetchAllPromotions = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const allPromotions = await getAllPromotionsUseCase.execute();
      setPromotions(allPromotions);
      return allPromotions;
    } catch (err) {
      const errorMessage =
        err instanceof Error ? err.message : "Failed to fetch promotions";
      setError(errorMessage);
      throw err;
    } finally {
      setLoading(false);
    }
  }, [getAllPromotionsUseCase]);
 
  /**
   * Fetches only active promotion applications
   * Active = IN_SERVICE status and within promotion date range
   */
  const fetchActivePromotions = useCallback(
    async (currentDate?: Date) => {
      try {
        setLoading(true);
        setError(null);
        const activePromotions = await getAllPromotionsUseCase.getActivePromotions(
          currentDate
        );
        setPromotions(activePromotions);
        return activePromotions;
      } catch (err) {
        const errorMessage =
          err instanceof Error
            ? err.message
            : "Failed to fetch active promotions";
        setError(errorMessage);
        throw err;
      } finally {
        setLoading(false);
      }
    },
    [getAllPromotionsUseCase]
  );
 
  /**
   * Fetches promotions filtered by application status
   */
  const fetchByStatus = useCallback(
    async (status: ApplicationStatus) => {
      try {
        setLoading(true);
        setError(null);
        const filteredPromotions = await getAllPromotionsUseCase.getByStatus(
          status
        );
        setPromotions(filteredPromotions);
        return filteredPromotions;
      } catch (err) {
        const errorMessage =
          err instanceof Error
            ? err.message
            : `Failed to fetch promotions with status ${status}`;
        setError(errorMessage);
        throw err;
      } finally {
        setLoading(false);
      }
    },
    [getAllPromotionsUseCase]
  );
 
  /**
   * Fetches promotions for a specific merchant
   */
  const fetchByMerchant = useCallback(
    async (merchantId: string) => {
      try {
        setLoading(true);
        setError(null);
        const merchantPromotions = await getAllPromotionsUseCase.getByMerchant(
          merchantId
        );
        setPromotions(merchantPromotions);
        return merchantPromotions;
      } catch (err) {
        const errorMessage =
          err instanceof Error
            ? err.message
            : `Failed to fetch promotions for merchant ${merchantId}`;
        setError(errorMessage);
        throw err;
      } finally {
        setLoading(false);
      }
    },
    [getAllPromotionsUseCase]
  );
 
  /**
   * Refreshes the current promotions list
   */
  const refresh = useCallback(() => {
    return fetchAllPromotions();
  }, [fetchAllPromotions]);
 
  /**
   * Clears error state
   */
  const clearError = useCallback(() => {
    setError(null);
  }, []);
 
  /**
   * Resets hook state to initial values
   */
  const reset = useCallback(() => {
    setPromotions([]);
    setError(null);
    setLoading(false);
  }, []);
 
  // Auto-load promotions on mount if enabled (default: true)
  useEffect(() => {
    const shouldAutoLoad = options?.autoLoad !== false;
    if (shouldAutoLoad) {
      fetchAllPromotions();
    }
  }, [fetchAllPromotions, options?.autoLoad]);
 
  return {
    // State
    promotions,
    loading,
    error,
 
    // Fetch methods
    fetchAllPromotions,
    fetchActivePromotions,
    fetchByStatus,
    fetchByMerchant,
 
    // Utility methods
    refresh,
    clearError,
    reset,
  };
};
 
/**
 * Type definition for the return value of useGetPromotions
 */
export type UseGetPromotionsReturn = ReturnType<typeof useGetPromotions>;