All files / src/hooks useCareers.ts

100% Statements 49/49
100% Branches 8/8
100% Functions 10/10
100% Lines 45/45

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 1085x   5x 5x 5x                                         5x 2x 2x           1x 1x 1x 1x 1x 1x 1x 1x 1x   1x 1x 1x 1x 1x 1x   1x 1x 1x   1x   2x                         1x 7x 4x   3x           4x   10x 4x         1x     5x 4x   4x 4x 2x 2x 2x 1x   1x         4x    
import React from 'react';
 
import { endpoints } from '@/constants';
import { getApiClient, GoogleSheetsApiResponse } from '@/lib';
import { handleError } from '@/utils/errors';
 
export type CareerDetailData = {
  rowNo: number;
  'subject_ja-JP': string;
  'subject_en-US': string;
  skills: { key: string; icon: string }[];
};
 
export type CareerData = {
  id: number;
  date: string;
  place: string;
  'title_ja-JP': string;
  'title_en-US': string;
  favicon: string;
  url: string;
  visible: boolean;
  details: CareerDetailData[];
};
 
const fetchData = async () => {
  const client = getApiClient();
  const [careersResponse, careerDetailsResponse, iconsResponse] = await Promise.all([
    client.get<GoogleSheetsApiResponse>(endpoints.getCareers),
    client.get<GoogleSheetsApiResponse>(endpoints.getCareerDetails),
    client.get<GoogleSheetsApiResponse>(endpoints.getIcons),
  ]);
 
  const career = careersResponse.data.values[0];
  const career_id = career.indexOf('id');
  const career_date = career.indexOf('date');
  const career_place = career.indexOf('place');
  const career_titleJaJp = career.indexOf('title_ja-JP');
  const career_titleEnUs = career.indexOf('title_en-US');
  const career_favicon = career.indexOf('favicon');
  const career_url = career.indexOf('url');
  const career_visible = career.indexOf('visible');
 
  const careerDetail = careerDetailsResponse.data.values[0];
  const careerDetail_careerId = careerDetail.indexOf('career_id');
  const careerDetail_rowNo = careerDetail.indexOf('row_no');
  const careerDetail_subjectJaJp = careerDetail.indexOf('subject_ja-JP');
  const careerDetail_subjectEnUs = careerDetail.indexOf('subject_en-US');
  const careerDetail_skills = careerDetail.indexOf('skills');
 
  const icon = iconsResponse.data.values[0];
  const icon_id = icon.indexOf('id');
  const icon_data = icon.indexOf('data');
 
  const buffer = careersResponse.data.values.slice(1, careersResponse.data.values.length).map(
    (row) =>
      ({
        id: Number(row[career_id]),
        date: row[career_date],
        place: row[career_place],
        'title_ja-JP': row[career_titleJaJp],
        'title_en-US': row[career_titleEnUs],
        favicon: row[career_favicon],
        url: row[career_url],
        visible: row[career_visible]?.toLowerCase() === 'true' ? true : false,
        details: [],
      } as CareerData)
  );
 
  careerDetailsResponse.data.values.slice(1, careerDetailsResponse.data.values.length).forEach((row) => {
    const career = buffer.find((c) => c.id === Number(row[careerDetail_careerId]));
    if (!career) return;
 
    career.details[career.details.length] = {
      rowNo: Number(row[careerDetail_rowNo]),
      'subject_ja-JP': row[careerDetail_subjectJaJp],
      'subject_en-US': row[careerDetail_subjectEnUs],
      skills: row[careerDetail_skills]
        .split(',')
        .map((s) => s.trim())
        .map((s) => {
          const icon = iconsResponse.data.values.find((row) => row[icon_id] === s);
          return { key: s, icon: icon ? icon[icon_data] : '' };
        }),
    };
  });
 
  return buffer;
};
 
export const useCareers = (ready: boolean) => {
  const [cache, setCache] = React.useState<CareerData[]>();
 
  React.useEffect(() => {
    if (ready && !cache)
      (async () => {
        try {
          const data = await fetchData();
          setCache(data);
        } catch (e) {
          handleError(e);
        }
      })();
  }, [ready, cache]);
 
  return cache;
};