Implement the following feature Progress tracking: User progress will be tracked and saved in the database. Authenticated Users will be able to see their progress in a list of unknown words, well-known words, and words that need to be learned inside wordSlice /* eslint-disable no-undef */
/* eslint-disable no-unused-vars */
import { createSlice } from '@reduxjs/toolkit';
import axios from '../api/api';

const initialState = {
  word: null,
  nounList: {
    masculine: [],
    feminine: [],
  },
  isCorrect: null,
  score: 0,
};

export const wordsSlice = createSlice({
  name: 'words',
  initialState,
  reducers: {
    setWord: (state, action) => {
      state.word = action.payload;
      state.isCorrect = null;
    },
    setNouns: (state, action) => {
      state.nounList = action.payload;
    },
    setCorrect: (state) => {
      state.isCorrect = true;
      state.score++;
    },
    setWrong: (state) => {
      state.isCorrect = false;
    },
    setExample: (state, action) => {
      state.example = action.payload.example;
    },
    setTranslation: (state, action) => {
      state.translation = action.payload.example;
    },
    setCorrectArticle: (state, action) => {
      state.correctArticle = action.payload.article;
      state.correctEnding = action.payload.ending;
    },
  },
});

export const {
  setWord,
  setNouns,
  setCorrect,
  setWrong,
  setTranslation,
  setCorrectArticle,
} = wordsSlice.actions;

export const selectWord = (state) => state.words.word;
export const selectNouns = (state) => state.words.nounList;
export const selectIsCorrect = (state) => state.words.isCorrect;
export const selectScore = (state) => state.words.score;
export const selectTranslation = (state) => state.words.translation;

const config = {
  headers: {
    Authorization: `Bearer ${
      JSON.parse(localStorage.getItem('userInfo')).accessToken
    }`,
  },
};

export const fetchWord = () => async (dispatch) => {
  try {
    const response = await axios.get('/words/random', config);
    dispatch(setWord(response.data));
  } catch (error) {
    console.error(error);
  }
};

export const fetchNouns = () => async (dispatch) => {
  try {
    const [masculineResponse, feminineResponse] = await Promise.all([
      axios.get('/words/masculine', config),
      axios.get('/words/feminine', config),
    ]);
    console.log(masculineResponse.data, feminineResponse.data);
    dispatch(
      setNouns({
        masculine: masculineResponse.data,
        feminine: feminineResponse.data,
      })
    );
  } catch (error) {
    console.error(error);
  }
};

export const fetchTranslation = (word) => async (dispatch) => {
  try {
    const response = await axios.get(`/words/example?word=${word}`, config);
    dispatch(setTranslation(response.data));
    console.log('Translation', dispatch(setTranslation(response.data)));
  } catch (error) {
    console.error(error);
  }
};

// export const submitAnswer = (selected) => (dispatch, getState) => {
//   const word = selectWord(getState());
//   const isCorrect = selected === (word.gender === 'm' ? 'UN/LE' : 'UNE/LA');
//   if (isCorrect) {
//     dispatch(setCorrect());
//   } else {
//     dispatch(setWrong());
//   }
// };
export const submitAnswer = (selected) => async (dispatch, getState) => {
  const { word, gender } = selectWord(getState());
  const isCorrect = selected === (word.gender === 'm' ? 'UN/LE' : 'UNE/LA');
  if (isCorrect) {
    dispatch(setCorrect());
    const translation = await dispatch(fetchTranslation(word));
    console.log('Submit Answer', translation);
  } else {
    if (!disableClicks) {
      dispatch(setWrong());
      let correctArticle = gender === 'masculine' ? 'LE' : 'LA';
      let correctEnding = '';
      for (let ending of gender === 'masculine'
        ? selectNouns(getState()).masculine
        : selectNouns(getState()).feminine) {
        if (word.word.endsWith(ending)) {
          correctEnding = ending;
          break;
        }
      }
      if (!correctEnding) {
        correctEnding = word.word;
      }
      dispatch(
        setCorrectArticle({ article: correctArticle, ending: correctEnding })
      );
    }
    dispatch(nextWord());
  }
};

export const nextWord = () => (dispatch) => {
  dispatch(fetchWord());
};

export default wordsSlice.reducer;
with backend code for the feature arleady implemented as import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common';
import { GameService } from './game.service';
import { AuthGuard } from '@nestjs/passport';
@UseGuards(AuthGuard('jwt'))
@Controller({
  path: 'game_progress',
  version: '1',
})
export class GameController {
  constructor(private readonly gameService: GameService) {}

  @Post('known')
  async markWordAsKnown(@Req() req, @Body() body) {
    const userId = req.user.id;
    const wordId = body.wordId;
    console.log(userId, wordId);

    return await this.gameService.markWordAsKnown(userId, wordId);
  }

  @Get('well_known')
  async getWellKnownWords(@Req() req) {
    const userId = req.user.id;
    return await this.gameService.getWellKnownWords(userId);
  }

  @Get('learned')
  async getLearnedWords(@Req() req) {
    const userId = req.user.id;
    return await this.gameService.getLearnedWords(userId);
  }
}