All files / libs/payout-definition/challenges/state/src/lib challenges.queries.ts

0% Statements 0/92
0% Branches 0/1
0% Functions 0/1
0% Lines 0/92

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                                                                                                                                                                                         
import { useQueries, useQuery, useQueryClient, type UseQueryResult } from '@tanstack/react-query';
import { useCallback } from 'react';
import { useIntl } from 'react-intl';

import { useMutation } from '@amalia/ext/react-query';
import { toError } from '@amalia/ext/typescript';
import { type Period } from '@amalia/payout-definition/periods/types';
import {
  ChallengeLaunchNotificationStatus,
  type Challenge,
  type Rule,
  type RuleConfiguration,
} from '@amalia/payout-definition/plans/types';
import { type UserContract } from '@amalia/tenants/users/types';

import { ChallengeApiClient } from './api-client/challenges.api-client';
import { challengesMutationKeys, challengesQueryKeys } from './queries.keys';

export const useChallengeByRulePeriod = (ruleId?: Rule['id'], periodId?: Period['id']) =>
  useQuery({
    queryKey: challengesQueryKeys.detailsByRulePeriod(ruleId!, periodId!),
    queryFn: () => ChallengeApiClient.getChallengeByRulePeriod({ ruleId: ruleId!, periodId: periodId! }),
    enabled: !!ruleId && !!periodId,
  });

export const useChallengesByRulePeriod = (
  args: { ruleId?: Rule['id']; periodId?: Period['id'] }[],
  { enabled = true } = {},
) =>
  useQueries({
    queries: args.map(({ ruleId, periodId }) => ({
      queryKey: challengesQueryKeys.detailsByRulePeriod(ruleId!, periodId!),
      queryFn: () => ChallengeApiClient.getChallengeByRulePeriod({ ruleId: ruleId!, periodId: periodId! }),
      enabled: enabled && !!ruleId && !!periodId,
    })),
    combine: useCallback(
      (results: UseQueryResult<Challenge | null, Error>[]) => ({
        data: results.map((result) => result.data).filter(Boolean),
        isPending: results.some((result) => result.isPending),
      }),
      [],
    ),
  });

export const useChallengePayments = (challengeId?: Challenge['id'], periodId?: Period['id']) =>
  useQuery({
    queryKey: challengesQueryKeys.paymentsOfChallenge(challengeId!, periodId!),
    queryFn: () => ChallengeApiClient.getChallengePayments({ challengeId: challengeId!, periodId: periodId! }),
    enabled: !!challengeId && !!periodId,
  });

export const useUsersToNotify = ({
  planId,
  challengeStartDate,
}: {
  planId?: string;
  challengeStartDate: RuleConfiguration['challengeStartDate'];
}) =>
  useQuery({
    queryKey: challengesQueryKeys.usersToNotify(planId!, challengeStartDate),
    queryFn: () => ChallengeApiClient.getUsersToNotify({ planId: planId!, challengeStartDate }),
    enabled: !!planId,
    placeholderData: [],
  });

export const useLaunchChallengeNotificationStatus = (ruleId: string) =>
  useQuery({
    queryKey: challengesQueryKeys.launchNotificationStatus(ruleId),
    queryFn: () => ChallengeApiClient.getLaunchChallengeNotificationsStatus({ ruleId }),
    enabled: !!ruleId,
    refetchInterval: (query) => (query.state.data === ChallengeLaunchNotificationStatus.SENDING ? 2000 : false),
  });

export const useLaunchChallengeNotification = (ruleId: string) => {
  const queryClient = useQueryClient();
  const { formatMessage } = useIntl();
  return useMutation({
    mutationKey: challengesMutationKeys.sendLaunchNotification(),

    mutationFn: (userIds: UserContract['id'][]) =>
      ChallengeApiClient.sendChallengeLaunchNotification({ challengeRuleId: ruleId, userIds }),

    onSettled: async () => {
      await queryClient.invalidateQueries({ queryKey: challengesQueryKeys.launchNotificationStatus(ruleId) });
    },

    meta: {
      successMessage: formatMessage({ defaultMessage: 'Participants will receive notifications.' }),
      errorMessage: (error) => toError(error).message,
    },
  });
};