---
# System prepended metadata

title: Untitled

---

### API
```
export type LAYOUT_TYPE = 'user' | 'class' | 'category' | 'music' | 'hashtag';




export interface Classes {
  id: number;
  classCoverImage: string;
  classTitle: string;
  totalLearners: string;
  rating: number;
}
export interface User {
  id: number;
  name: string;
  username: string;
  coverUrl: string;
}

export interface Categories {
  id: number;
  categoryCover: string;
  name: string;
}
export interface Hashtag {
  id: number;
  coverUrl: string;
  name: string;
}
export interface Music {
  id: number;
  coverUrl: string;
  title: string;
  artist: string;
  file: {
    fileDuration: number;
    fileUrl: string;
  };
}
export interface ListResponse<T> {
  data: T[];
  pagination?: {
    page: number;
    pageCount: number;
    total: number;
  };
}
export interface SectionItem<T> {
  type: LAYOUT_TYPE;
  title: string;
  itemChild: ListResponse<T>;
}

export type ExploreRequestType = {
  keywords?: string;
  type: LAYOUT_TYPE;
  page?: number;
  per_page?: number;
  title?:string;
};

```

### Reducer

```
import {ProfileItemType} from '../userProfile/reducer';
import {RootState} from '../../index';
import {createSlice, createAction, PayloadAction} from '@reduxjs/toolkit';
import {
  Classes,
  ListResponse,
  Item,
  Categories,
  SectionItem,
  Music,
  Hashtag,
  ExploreRequestType,
  LAYOUT_TYPE,
  User,
} from './api';

export interface SliceState {
  section: {
    [key in string]: SectionItem<Classes|User | Categories | Music | Hashtag>;
  };
}
const initialState = {
  section: {},
} as SliceState;

export const Slice = createSlice({
  name: 'Section',
  initialState,
  reducers: {
    updateDataSection(
      state: SliceState,
      action: PayloadAction<
        SectionItem<Classes | Categories | User | Music | Hashtag>
      >,
    ) {
      let SectionId = action.payload.type;
      if (action.payload.itemChild.data) {
        if (action.payload.itemChild.pagination.page === 1) {
          state.section[SectionId] = action.payload;
        } else {
          // TODO: loadmore with pagination > 1
        }
      } else {
        state.section[SectionId] = action.payload;
      }
    },
  },
});

export const getDataSection = createAction('section/getDataHomePage');

export const getDataUsersAction = createAction<ExploreRequestType>(
  'section/getDataUsers',
);
export const getDataMusicsAction = createAction<ExploreRequestType>(
  'section/getDataMusics',
);
export const getDataHashtagsAction = createAction<ExploreRequestType>(
  'section/getDataHashtags',
);
export const getDataClassesAction = createAction('section/getDataClasses');

export const getDataCategoriesAction = createAction(
  'explore/getDataCategories',
);

export const {updateDataSection} = Slice.actions;

export const selectDataSection = (
  state: RootState,
  type: LAYOUT_TYPE,
  title?: string,
  keyWord?: string //update later
) => {
  // case 1 if this is load more list => update item of filter data

  let SectionId = type;

  // choose specially filteredData
  let list: SectionItem<Classes | User | Categories | Music | Hashtag> = {
    type,
    title: title ?? '',
    itemChild: {
      data: [],
    },
  };
    // if have a data in state, list equal data
  if (state.Section.section[SectionId]) {
    list = state.Section.section[SectionId];
  }

  return list;
};
export default Slice.reducer;

```

### Saga 
```
import {put, call, debounce, takeLatest} from 'redux-saga/effects';
import {setLoading} from '../application/reducer';
import {handleError} from '@utils/apiProxy';
import {
  getDataHashtagsAction,
  getDataMusicsAction,
  getDataUsersAction,
  updateDataSection,
} from './reducer';
import {getRandom} from '@utils/common';


export function* musicHandler(action) {
  try {
    yield put(setLoading(true));

    if (getDataMusicsAction.match(action)) {
        
      let fakeData: any = [];
      const randomUTitle = [
        'Eleanor Rigby',
        'Darling Nikki',
        'Fernando',
        'Gloria',
        'Jack and Diane',
        'Daniel',
        'Buddy Holly',
        'The Wind Cries Mary',
      ];
      const tenItems = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      fakeData = tenItems.map(id => ({
        id,
        coverUrl:
          'https://thumbs.dreamstime.com/b/music-notes-random-pattern-background-wallpapers-use-content-creation-design-layouts-189454693.jpg',
        title: getRandom(randomUTitle),
        artist: 'new',
        file: {
          fileDuration: 20,
          fileUrl: '',
        },
      }));
          console.log('fake data in redueraaaaaaaa',fakeData);
        yield put(
          updateDataSection({
            type: action.payload.type,
            title: action.payload.title ?? '',
            itemChild: {
              data: fakeData,
              pagination: {
                page: 1,
                pageCount: 20,
                total: 30
              },
            },
          }),
        );
      
    }
  } catch (error) {
    yield call(handleError, error, '');
  } finally {
    yield put(setLoading(false));
  }
}
export function* hashtagHandler(action) {
  try {
    yield put(setLoading(true));

    if (getDataHashtagsAction.match(action)) {
      let fakeData: any = [];
      const randomUTitle = [
        'Eleanor Rigby',
        'Darling Nikki',
        'Fernando',
        'Gloria',
        'Jack and Diane',
        'Daniel',
        'Buddy Holly',
        'The Wind Cries Mary',
      ];
      const tenItems = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      fakeData = tenItems.map(id => ({
        id,
        coverUrl:
         'https://media.istockphoto.com/photos/two-young-people-guy-and-girl-in-casual-clothes-dancing-contemporary-picture-id1334841020?k=20&m=1334841020&s=612x612&w=0&h=LsTymAEfSU6aBES-7IqaeXMnvmOqkcu7bcIggPCJBYM=',
        name: 'hashtags',
      }));
      console.log('hashtags reducer',fakeData)
      yield put(
        updateDataSection({
          type: action.payload.type,
          title: action.payload.title ?? '',
          itemChild: {
            data: fakeData,
            pagination: {
              page: 1,
              pageCount: 20,
              total: 30,
            },
          },
        }),
      );
    }
  } catch (error) {
    yield call(handleError, error, '');
  } finally {
    yield put(setLoading(false));
  }
}
export function* usersHandler(action) {
  try {
    yield put(setLoading(true));

    if (getDataUsersAction.match(action)) {
      let fakeData: any = [];
      const randomUTitle = [
        'Eleanor Rigby',
        'Darling Nikki',
        'Fernando',
        'Gloria',
        'Jack and Diane',
        'Daniel',
        'Buddy Holly',
        'The Wind Cries Mary',
      ];
      const tenItems = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      fakeData = tenItems.map(id => ({
        id,
        name: getRandom(randomUTitle),
        username: '',
        coverUrl:
          'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRLe5PABjXc17cjIMOibECLM7ppDwMmiDg6Dw&usqp=CAU',
      }));
      yield put(
        updateDataSection({
          type: action.payload.type,
          title: action.payload.title ?? '',
          itemChild: {
            data: fakeData,
            pagination: {
              page: 1,
              pageCount: 20,
              total: 30,
            },
          },
        }),
      );
    }
  } catch (error) {
    yield call(handleError, error, '');
  } finally {
    yield put(setLoading(false));
  }
}
export default function* () {
  yield takeLatest(getDataMusicsAction.type, musicHandler);
  yield takeLatest(getDataHashtagsAction.type, hashtagHandler);
  yield takeLatest(getDataUsersAction.type, usersHandler);
}
```