운동기록 항목 Form 기능 구현

곽재훈·2024년 7월 30일
2

// store.ts
import { CardioInput, Value, WeightInput } from '@/types/exercises';
import { create } from 'zustand';

interface ExerciseTabStoreTypes {
  exerciseType: Value;
  setExerciseType: (value: Value) => void;
}

export const useExerciseTabStore = create<ExerciseTabStoreTypes>((set) => ({
  exerciseType: 'weight',
  setExerciseType: (value) => set(() => ({ exerciseType: value })),
}));

interface CardioInputStoreTypes {
  cardioInputs: CardioInput[];
  setCardioInputs: (value: CardioInput[]) => void;
  addInput: () => void;
  deleteInput: (index: number) => void;
}

export const useCardioInputStore = create<CardioInputStoreTypes>((set) => ({
  cardioInputs: [
    {
      hours: 0,
      minutes: 0,
    },
  ],
  addInput: () => set((state) => ({ cardioInputs: [...state.cardioInputs, { hours: 0, minutes: 0 }] })),
  setCardioInputs: (value) => set(() => ({ cardioInputs: value })),
  deleteInput: (index) =>
    set((state) => {
      if (state.cardioInputs.length <= 1) {
        alert('You need to have at least one input');
        return { cardioInputs: state.cardioInputs };
      }
      return { cardioInputs: state.cardioInputs.filter((_, i) => i !== index) };
    }),
}));

interface WeightInputStoreTypes {
  weightInputs: WeightInput[];
  setWeightInputs: (value: WeightInput[]) => void;
  addInput: () => void;
  deleteInput: (index: number) => void;
}

export const useWeightInputStore = create<WeightInputStoreTypes>((set) => ({
  weightInputs: [
    {
      weight: 0,
      reps: 0,
    },
  ],
  setWeightInputs: (value) => set(() => ({ weightInputs: value })),
  addInput: () => set((state) => ({ weightInputs: [...state.weightInputs, { weight: 0, reps: 0 }] })),
  deleteInput: (index) =>
    set((state) => {
      if (state.weightInputs.length <= 1) {
        alert('You need to have at least one input');
        return { weightInputs: state.weightInputs };
      }
      return { weightInputs: state.weightInputs.filter((_, i) => i !== index) };
    }),
}));
import { useCardioInputStore, useWeightInputStore } from '@/stores/useExerciseStore';

interface FormItemProps {
  index: number;
  firstProp: number;
  secondProp: number;
  type: 'cardio' | 'weight';
  onChange: (e: React.ChangeEvent<HTMLInputElement>, index: number) => void;
}

const FormItem = ({ onChange, type, index, firstProp, secondProp }: FormItemProps) => {
  const deleteCardio = useCardioInputStore((state) => state.deleteInput);
  const deleteWeight = useWeightInputStore((state) => state.deleteInput);
  const deleteInput = () => {
    if (type === 'cardio') {
      deleteCardio(index);
    } else {
      deleteWeight(index);
    }
  };
  return (
    <div className="grid grid-cols-4 justify-items-center">
      <div className="flex justify-center items-center w-12 h-10 border-2 border-black">{index + 1}</div>
      <input
        onChange={(e) => onChange(e, index)}
        className="flex justify-center items-center w-12 h-10 border-2 border-black exerciseInput"
        name={type === 'cardio' ? 'hours' : 'weight'}
        type="number"
        value={firstProp}
      />
      <input
        onChange={(e) => onChange(e, index)}
        className="flex justify-center items-center w-12 h-10 border-2 border-black exerciseInput"
        name={type === 'cardio' ? 'minutes' : 'reps'}
        type="number"
        value={secondProp}
      />
      <button
        type="button"
        className="flex justify-center items-center w-12 h-10 border-2 border-black"
        onClick={deleteInput}
      >
        삭제
      </button>
    </div>
  );
};

export default FormItem;
profile
개발하고 싶은 국문과 머시기

2개의 댓글

comment-user-thumbnail
2024년 7월 30일

우아아 고생하셨어여 !

답글 달기
comment-user-thumbnail
2024년 8월 3일

훈재햄 폼 미쳤당

답글 달기

관련 채용 정보