useI18n

'use client';
 
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
 
import { useI18nState } from '@/i18n/I18nProvider';
import { TranslationVariables } from '@/i18n/I18nProvider/typing';
import { I18nNamespaces } from '@/i18n/settings';
 
type CamelCase<S extends string> = S extends `${infer Head}-${infer Tail}`
  ? `${Head}${Capitalize<CamelCase<Tail>>}`
  : S;
 
type AppendT<S extends string> = `${S}T`;
 
type ConvertArrayToCamelCaseWithT<T extends readonly string[]> = {
  [K in keyof T]: AppendT<CamelCase<T[K]>>;
}[number];
 
export const useI18n = <T extends I18nNamespaces>(ns: T[]) => {
  const { lng } = useI18nState();
 
  const { t } = useTranslation();
 
  const translator = useMemo(() => {
    return ns.reduce(
      (acc, cur) => {
        acc[`${convertKebabCaseToCamelCase(cur)}T` as keyof typeof acc] = (
          key: string,
          variables?: TranslationVariables,
        ) => t(key, { ns: cur, lng, ...(typeof variables !== 'undefined' ? variables : {}) });
        return acc;
      },
      {} as Record<ConvertArrayToCamelCaseWithT<typeof ns>, (key: string, variables?: TranslationVariables) => string>,
    );
  }, [lng, ns, t]);
 
  return translator;
};
 
function convertKebabCaseToCamelCase(input: string) {
  return input
    .split('-')
    .map((word, index) => {
      if (index === 0) {
        return word;
      }
      return word.charAt(0).toUpperCase() + word.slice(1);
    })
    .join('') as CamelCase<string>;
}