super-fit-web-app / src / components / programs / exercises-container.tsx
exercises-container.tsx
Raw
import NewExercise from '@components/programs/new-exercise';
import React, { Component } from 'react';
import { Button, Grid, Typography } from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
import ExerciseSelector from './exercise-selector';
import { toast } from 'react-toastify';
import { useState } from 'react';
import { ProgramDataProps } from '@/pages/dashboard/create-program';
import ExerciseRepsAndSets from './exercise-reps-sets';

interface ChildProps {
  key: number;
}

interface ParentState {
  children: JSX.Element[];
  nextKey: number;
}

interface ParentProps {
  setProgramData: React.Dispatch<React.SetStateAction<ProgramDataProps>>;
}

export class ExercisesContainer extends Component<ParentProps, ParentState> {
  constructor(props: ParentProps) {
    super(props);
    this.state = {
      children: [],
      nextKey: 0
    };
  }

  removeChild = (removeKey: number) => {
    this.setState(prevState => ({
      children: prevState.children.filter((child) => child.key !== removeKey.toString()),
    }))
  }

  addChild = () => {
    const { children, nextKey } = this.state;
    const { setProgramData } = this.props;
    this.setState({
      children: [
        ...children,
        <ProgramOption
          key={nextKey.toString()}
          positionId={nextKey}
          removeExercise={this.removeChild}
          setProgramData={setProgramData}
        />
      ],
      nextKey: nextKey + 1
    });
  };

  render() {
    const { children } = this.state;
    return (
      <>
        {children}
        <Button
          variant={'basic'}
          sx={{
            my: '25px',
            maxWidth: '200px',
            p: 0,
            color: 'white',
          }}
          onClick={this.addChild}
        >
          Add Exercise <AddIcon />
        </Button>
      </>
    )
  }
}

type NewExerciseProps = {
  positionId?: number;
  removeExercise?: (removeKey: number) => void;
  setProgramData: React.Dispatch<React.SetStateAction<ProgramDataProps>>;
}

const ProgramOption = ({ positionId, removeExercise, setProgramData }: NewExerciseProps) => {
  const [isNewExercise, setIsNewExercise] = useState<boolean>(false)
  const [dbExercise, setDbExercise] = useState<any>(null)

  const handleRemove = () => {
    if (removeExercise === undefined) return toast.error('Error removing exercise, please reload the page.')
    removeExercise(positionId as number)
  }

  if (dbExercise) {
    return (
      <ExerciseRepsAndSets
        id={dbExercise.id}
        name={dbExercise.name}
        setExerciseData={setProgramData}
      />
    )
  }

  if (isNewExercise) {
    return (
      <NewExercise
        positionId={positionId}
        removeExercise={removeExercise}
        cancel={() => setIsNewExercise(false)}
        onSave={setDbExercise}
      />
    )
  }

  return (
    <Grid container spacing={1} alignItems={'center'} justifyContent={'center'}>
      <Grid item xs={12} md={5.5}>
        <ExerciseSelector
          onSelect={setDbExercise}
        />
      </Grid>
      <Grid item xs={12} md={1}>
        <Typography variant='h6' sx={{ textAlign: 'center' }}>OR</Typography>
      </Grid>
      <Grid item xs={12} md={5.5}>
        <Button
          variant='contained'
          onClick={() => setIsNewExercise(true)}
        >
          Create new exercise
        </Button>
      </Grid>
      <Grid item xs={12}>
        <Button
          onClick={handleRemove}
        >
          Cancel
        </Button>
      </Grid>
    </Grid>
  )
}