All files / src/hooks/use-auth/use-auth-availabilityCheck index.ts

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

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                                                                                                                                         
'use client';

import { useCallback, useMemo, useState } from 'react';

import { Availability } from '@/types/service/user';

type AvailabilityState =
  | { status: 'idle' }
  | { status: 'checking' }
  | { status: 'available'; message: string }
  | { status: 'unavailable'; message: string }
  | { status: 'error'; message: string };

type Messages = {
  available: string;
  unavailable: string;
  error: string;
  checking: string;
};

export const useAvailabilityCheck = <TQuery>(
  request: (query: TQuery) => Promise<Availability>,
  buildQuery: (value: string) => TQuery,
  messages: Messages,
) => {
  const [state, setState] = useState<AvailabilityState>({ status: 'idle' });

  const hint = useMemo(() => {
    if (state.status === 'checking') return messages.checking;
    if (state.status === 'available') return state.message;
    if (state.status === 'unavailable') return state.message;
    if (state.status === 'error') return state.message;
    return undefined;
  }, [messages.checking, state]);

  const isChecking = state.status === 'checking';
  const isAvailable = state.status === 'available';

  const reset = useCallback(() => {
    setState({ status: 'idle' });
  }, []);

  const check = useCallback(
    async (value: string) => {
      const trimmed = value.trim();
      if (!trimmed) return;
      if (isChecking) return;

      try {
        setState({ status: 'checking' });

        const data = await request(buildQuery(trimmed));
        const available = Boolean(data.available);

        if (available) {
          setState({ status: 'available', message: messages.available });
        } else {
          setState({ status: 'unavailable', message: messages.unavailable });
        }
      } catch {
        setState({ status: 'error', message: messages.error });
      }
    },
    [buildQuery, isChecking, messages, request],
  );

  return { state, hint, isChecking, isAvailable, reset, check };
};