diff --git a/src/pages/team-page.ts b/src/pages/team-page.ts index 1fa54aecbf..aef07be00f 100644 --- a/src/pages/team-page.ts +++ b/src/pages/team-page.ts @@ -8,13 +8,12 @@ import 'plastic-image'; import '../elements/shared-styles'; import { ReduxMixin } from '../mixins/redux-mixin'; import { RootState, store } from '../store'; -import { fetchTeams } from '../store/teams/actions'; -import { initialTeamsState } from '../store/teams/state'; +import { fetchTeams, initialTeamsState } from '../store/teams'; @customElement('team-page') export class TeamPage extends ReduxMixin(PolymerElement) { @property({ type: Object }) - teams = initialTeamsState; + teams = initialTeamsState.value; @computed('teams') get pending() { @@ -199,7 +198,7 @@ export class TeamPage extends ReduxMixin(PolymerElement) { } override stateChanged(state: RootState) { - this.teams = state.teams; + this.teams = state.teams.value; } override connectedCallback() { diff --git a/src/store/index.ts b/src/store/index.ts index 43d1051236..78902fbfa9 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -14,7 +14,7 @@ import { scheduleReducer } from './schedule/reducers'; import { sessionsReducer } from './sessions/reducers'; import { speakersReducer } from './speakers/reducers'; import { subscribeReducer } from './subscribe/reducers'; -import { teamsReducer } from './teams/reducers'; +import teamsReducer from './teams'; import { ticketsReducer } from './tickets/reducers'; import { toastReducer } from './toast/reducers'; import { uiReducer } from './ui/reducers'; diff --git a/src/store/teams/actions.ts b/src/store/teams/actions.ts deleted file mode 100644 index 455533b7ab..0000000000 --- a/src/store/teams/actions.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { collection, getDocs, query } from 'firebase/firestore'; -import { Dispatch } from 'redux'; -import { db } from '../../firebase'; -import { Member } from '../../models/member'; -import { Team, TeamWithoutMembers } from '../../models/team'; -import { mergeDataAndId } from '../../utils/firestore'; -import { FETCH_TEAMS, FETCH_TEAMS_FAILURE, FETCH_TEAMS_SUCCESS, TeamsActions } from './types'; - -const getTeamIds = async (): Promise => { - const { docs } = await getDocs(query(collection(db, 'team'))); - - return docs.map(mergeDataAndId); -}; - -const getTeamMembers = async (team: TeamWithoutMembers): Promise => { - const { docs } = await getDocs(query(collection(db, 'team', team.id, 'members'))); - const members = docs.map(mergeDataAndId); - - return { - ...team, - members, - }; -}; - -const getTeams = async (): Promise => { - const teamIds = await getTeamIds(); - return Promise.all(teamIds.map(getTeamMembers)); -}; - -export const fetchTeams = async (dispatch: Dispatch) => { - dispatch({ - type: FETCH_TEAMS, - }); - - try { - dispatch({ - type: FETCH_TEAMS_SUCCESS, - payload: await getTeams(), - }); - } catch (error) { - dispatch({ - type: FETCH_TEAMS_FAILURE, - payload: error, - }); - } -}; diff --git a/src/store/teams/index.ts b/src/store/teams/index.ts new file mode 100644 index 0000000000..59400ca13c --- /dev/null +++ b/src/store/teams/index.ts @@ -0,0 +1,54 @@ +import { Failure, Initialized, Pending, RemoteData, Success } from '@abraham/remotedata'; +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import { collection, getDocs, query } from 'firebase/firestore'; +import { db } from '../../firebase'; +import { Member } from '../../models/member'; +import { Team, TeamWithoutMembers } from '../../models/team'; +import { mergeDataAndId } from '../../utils/firestore'; + +type TeamsState = { value: RemoteData }; + +export const initialTeamsState = { value: new Initialized() } as TeamsState; + +const getTeamIds = async (): Promise => { + const { docs } = await getDocs(query(collection(db, 'team'))); + + return docs.map(mergeDataAndId); +}; + +const getTeamMembers = async (team: TeamWithoutMembers): Promise => { + const { docs } = await getDocs(query(collection(db, 'team', team.id, 'members'))); + const members = docs.map(mergeDataAndId); + + return { + ...team, + members, + }; +}; + +const getTeams = async (): Promise => { + const teamIds = await getTeamIds(); + return Promise.all(teamIds.map(getTeamMembers)); +}; + +export const fetchTeams = createAsyncThunk('teams/fetch', async () => getTeams()); + +export const teamSlice = createSlice({ + name: 'teams', + initialState: initialTeamsState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchTeams.pending, (state) => { + state.value = new Pending(); + }) + .addCase(fetchTeams.rejected, (state, action) => { + state.value = new Failure(action.payload); + }) + .addCase(fetchTeams.fulfilled, (state, action) => { + state.value = new Success(action.payload); + }); + }, +}); + +export default teamSlice.reducer; diff --git a/src/store/teams/reducers.ts b/src/store/teams/reducers.ts deleted file mode 100644 index 30851edee1..0000000000 --- a/src/store/teams/reducers.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Failure, Pending, Success } from '@abraham/remotedata'; -import { initialTeamsState, TeamsState } from './state'; -import { FETCH_TEAMS, FETCH_TEAMS_FAILURE, FETCH_TEAMS_SUCCESS, TeamsActions } from './types'; - -export const teamsReducer = (state = initialTeamsState, action: TeamsActions): TeamsState => { - switch (action.type) { - case FETCH_TEAMS: - return new Pending(); - - case FETCH_TEAMS_FAILURE: - return new Failure(action.payload); - - case FETCH_TEAMS_SUCCESS: - return new Success(action.payload); - - default: - return state; - } -}; diff --git a/src/store/teams/state.ts b/src/store/teams/state.ts deleted file mode 100644 index e30146cf7f..0000000000 --- a/src/store/teams/state.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Initialized, RemoteData } from '@abraham/remotedata'; -import { Team } from '../../models/team'; - -export type TeamsState = RemoteData; -export const initialTeamsState: TeamsState = new Initialized(); diff --git a/src/store/teams/types.ts b/src/store/teams/types.ts deleted file mode 100644 index 16f71b5c8f..0000000000 --- a/src/store/teams/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Team } from '../../models/team'; - -export const FETCH_TEAMS = 'FETCH_TEAMS'; -export const FETCH_TEAMS_FAILURE = 'FETCH_TEAMS_FAILURE'; -export const FETCH_TEAMS_SUCCESS = 'FETCH_TEAMS_SUCCESS'; - -interface FetchTeamsAction { - type: typeof FETCH_TEAMS; -} - -interface FetchTeamsFailureAction { - type: typeof FETCH_TEAMS_FAILURE; - payload: Error; -} - -interface FetchTeamsSuccessAction { - type: typeof FETCH_TEAMS_SUCCESS; - payload: Team[]; -} - -export type TeamsActions = FetchTeamsAction | FetchTeamsFailureAction | FetchTeamsSuccessAction;