"feat: update data APIs to fetch orders and events via fetch instead of axios, add Order and Event models, update selectors and reducers, add EventDetail page with joined members display"
This commit is contained in:
@@ -4,6 +4,8 @@ import { Speaker } from '../models/Speaker';
|
||||
import { Location } from '../models/Location';
|
||||
import axios from 'axios';
|
||||
import constants from '../constants';
|
||||
import { IOrderItem } from '../models/Order';
|
||||
import { Event } from '../models/Event';
|
||||
|
||||
const dataUrl = '/assets/data/data.json';
|
||||
const locationsUrl = '/assets/data/locations.json';
|
||||
@@ -16,11 +18,13 @@ export const getConfData = async () => {
|
||||
const response = await Promise.all([
|
||||
fetch(dataUrl),
|
||||
fetch(locationsUrl),
|
||||
axios.get(`${constants.API_ENDPOINT}/api/order/list`),
|
||||
fetch(`${constants.API_ENDPOINT}/api/order/list`),
|
||||
fetch(`${constants.API_ENDPOINT}/api/event/list`),
|
||||
// axios.get(`${constants.API_ENDPOINT}/v1/events`),
|
||||
// axios.get(`${constants.API_ENDPOINT}/v1/members`),
|
||||
//
|
||||
]);
|
||||
|
||||
const responseData = await response[0].json();
|
||||
const schedule = responseData.schedule[0] as Schedule;
|
||||
const sessions = parseSessions(schedule);
|
||||
@@ -33,9 +37,29 @@ export const getConfData = async () => {
|
||||
|
||||
// const events = response[2].data;
|
||||
// const nearByMembers = response[3].data;
|
||||
const orders = response[2].data.orders;
|
||||
|
||||
const events = [];
|
||||
// TODO: update this due to not use axios anymore
|
||||
// the data object is not available
|
||||
// const orders = response[2].data.orders as IOrderItem[];
|
||||
// const events = response[3].data.events as Event[];
|
||||
const orderResponse = response[2];
|
||||
let orders = {
|
||||
result: { status: orderResponse.status, ok: orderResponse.ok },
|
||||
data: [],
|
||||
};
|
||||
if (orderResponse.status == 200) {
|
||||
orders = { ...orders, data: await orderResponse.json() };
|
||||
}
|
||||
|
||||
const eventResponse = response[3];
|
||||
let events = {
|
||||
result: { status: eventResponse.status, ok: eventResponse.ok },
|
||||
data: [],
|
||||
};
|
||||
if (eventResponse.status == 200) {
|
||||
events = { ...events, data: await eventResponse.json() };
|
||||
}
|
||||
|
||||
const nearByMembers = [];
|
||||
|
||||
const data = {
|
||||
@@ -47,15 +71,21 @@ export const getConfData = async () => {
|
||||
filteredTracks: [...allTracks],
|
||||
//
|
||||
events,
|
||||
nearByMembers,
|
||||
// nearByMembers,
|
||||
orders,
|
||||
hello: 'world',
|
||||
//
|
||||
};
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getUserData = async () => {
|
||||
const response = await Promise.all([Storage.get({ key: HAS_LOGGED_IN }), Storage.get({ key: HAS_SEEN_TUTORIAL }), Storage.get({ key: USERNAME })]);
|
||||
const response = await Promise.all([
|
||||
Storage.get({ key: HAS_LOGGED_IN }),
|
||||
Storage.get({ key: HAS_SEEN_TUTORIAL }),
|
||||
Storage.get({ key: USERNAME }),
|
||||
]);
|
||||
const isLoggedin = (await response[0].value) === 'true';
|
||||
const hasSeenTutorial = (await response[1].value) === 'true';
|
||||
const username = (await response[2].value) || undefined;
|
||||
|
@@ -2,9 +2,10 @@ import { createSelector } from 'reselect';
|
||||
import { Schedule, Session, ScheduleGroup } from '../models/Schedule';
|
||||
import { Speaker } from '../models/Speaker';
|
||||
import { Location } from '../models/Location';
|
||||
import { Event } from '../models/Event';
|
||||
|
||||
import { AppState } from './state';
|
||||
import { IOrderItem } from '../models/Order';
|
||||
import { Event } from '../models/Event';
|
||||
|
||||
const getSchedule = (state: AppState) => {
|
||||
return state.data.schedule;
|
||||
@@ -17,106 +18,126 @@ const getFilteredTracks = (state: AppState) => state.data.filteredTracks;
|
||||
const getFavoriteIds = (state: AppState) => state.data.favorites;
|
||||
const getSearchText = (state: AppState) => state.data.searchText;
|
||||
|
||||
export const getEvents = (state: AppState) => state.data.events;
|
||||
export const getEvents = (state: AppState) => {
|
||||
return state.data.events;
|
||||
};
|
||||
|
||||
export const getNearbyMembers = (state: AppState) => state.data.nearByMembers;
|
||||
export const getOrders = (state: AppState) => state.data.orders;
|
||||
|
||||
export const getFilteredSchedule = createSelector(getSchedule, getFilteredTracks, (schedule, filteredTracks) => {
|
||||
const groups: ScheduleGroup[] = [];
|
||||
export const getOrders = (state: AppState) => {
|
||||
return state.data.orders;
|
||||
};
|
||||
|
||||
// Helper function to convert 12-hour time to 24-hour time for proper sorting
|
||||
const convertTo24Hour = (timeStr: string) => {
|
||||
const [time, period] = timeStr.toLowerCase().split(' ');
|
||||
let [hours, minutes] = time.split(':').map(Number);
|
||||
export const getFilteredSchedule = createSelector(
|
||||
getSchedule,
|
||||
getFilteredTracks,
|
||||
(schedule, filteredTracks) => {
|
||||
const groups: ScheduleGroup[] = [];
|
||||
|
||||
if (period === 'pm' && hours !== 12) {
|
||||
hours += 12;
|
||||
} else if (period === 'am' && hours === 12) {
|
||||
hours = 0;
|
||||
}
|
||||
// Helper function to convert 12-hour time to 24-hour time for proper sorting
|
||||
const convertTo24Hour = (timeStr: string) => {
|
||||
const [time, period] = timeStr.toLowerCase().split(' ');
|
||||
let [hours, minutes] = time.split(':').map(Number);
|
||||
|
||||
return `${hours.toString().padStart(2, '0')}:${minutes || '00'}`;
|
||||
};
|
||||
if (period === 'pm' && hours !== 12) {
|
||||
hours += 12;
|
||||
} else if (period === 'am' && hours === 12) {
|
||||
hours = 0;
|
||||
}
|
||||
|
||||
// Sort the groups by time
|
||||
const sortedGroups = [...schedule.groups].sort((a, b) => {
|
||||
const timeA = convertTo24Hour(a.time);
|
||||
const timeB = convertTo24Hour(b.time);
|
||||
return timeA.localeCompare(timeB);
|
||||
});
|
||||
return `${hours.toString().padStart(2, '0')}:${minutes || '00'}`;
|
||||
};
|
||||
|
||||
sortedGroups.forEach((group: ScheduleGroup) => {
|
||||
const sessions: Session[] = [];
|
||||
group.sessions.forEach((session) => {
|
||||
session.tracks.forEach((track) => {
|
||||
if (filteredTracks.indexOf(track) > -1) {
|
||||
sessions.push(session);
|
||||
}
|
||||
});
|
||||
// Sort the groups by time
|
||||
const sortedGroups = [...schedule.groups].sort((a, b) => {
|
||||
const timeA = convertTo24Hour(a.time);
|
||||
const timeB = convertTo24Hour(b.time);
|
||||
return timeA.localeCompare(timeB);
|
||||
});
|
||||
|
||||
if (sessions.length) {
|
||||
// Sort sessions within each group by start time
|
||||
const sortedSessions = sessions.sort((a, b) => {
|
||||
const timeA = convertTo24Hour(a.timeStart);
|
||||
const timeB = convertTo24Hour(b.timeStart);
|
||||
return timeA.localeCompare(timeB);
|
||||
sortedGroups.forEach((group: ScheduleGroup) => {
|
||||
const sessions: Session[] = [];
|
||||
group.sessions.forEach((session) => {
|
||||
session.tracks.forEach((track) => {
|
||||
if (filteredTracks.indexOf(track) > -1) {
|
||||
sessions.push(session);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const groupToAdd: ScheduleGroup = {
|
||||
time: group.time,
|
||||
sessions: sortedSessions,
|
||||
};
|
||||
groups.push(groupToAdd);
|
||||
}
|
||||
});
|
||||
if (sessions.length) {
|
||||
// Sort sessions within each group by start time
|
||||
const sortedSessions = sessions.sort((a, b) => {
|
||||
const timeA = convertTo24Hour(a.timeStart);
|
||||
const timeB = convertTo24Hour(b.timeStart);
|
||||
return timeA.localeCompare(timeB);
|
||||
});
|
||||
|
||||
return {
|
||||
date: schedule.date,
|
||||
groups,
|
||||
} as Schedule;
|
||||
});
|
||||
const groupToAdd: ScheduleGroup = {
|
||||
time: group.time,
|
||||
sessions: sortedSessions,
|
||||
};
|
||||
groups.push(groupToAdd);
|
||||
}
|
||||
});
|
||||
|
||||
export const getSearchedSchedule = createSelector(getFilteredSchedule, getSearchText, (schedule, searchText) => {
|
||||
if (!searchText) {
|
||||
return schedule;
|
||||
return {
|
||||
date: schedule.date,
|
||||
groups,
|
||||
} as Schedule;
|
||||
}
|
||||
const groups: ScheduleGroup[] = [];
|
||||
schedule.groups.forEach((group) => {
|
||||
const sessions = group.sessions.filter((s) => s.name.toLowerCase().indexOf(searchText.toLowerCase()) > -1);
|
||||
if (sessions.length) {
|
||||
const groupToAdd: ScheduleGroup = {
|
||||
time: group.time,
|
||||
sessions,
|
||||
};
|
||||
groups.push(groupToAdd);
|
||||
);
|
||||
|
||||
export const getSearchedSchedule = createSelector(
|
||||
getFilteredSchedule,
|
||||
getSearchText,
|
||||
(schedule, searchText) => {
|
||||
if (!searchText) {
|
||||
return schedule;
|
||||
}
|
||||
});
|
||||
return {
|
||||
date: schedule.date,
|
||||
groups,
|
||||
} as Schedule;
|
||||
});
|
||||
const groups: ScheduleGroup[] = [];
|
||||
schedule.groups.forEach((group) => {
|
||||
const sessions = group.sessions.filter(
|
||||
(s) => s.name.toLowerCase().indexOf(searchText.toLowerCase()) > -1
|
||||
);
|
||||
if (sessions.length) {
|
||||
const groupToAdd: ScheduleGroup = {
|
||||
time: group.time,
|
||||
sessions,
|
||||
};
|
||||
groups.push(groupToAdd);
|
||||
}
|
||||
});
|
||||
return {
|
||||
date: schedule.date,
|
||||
groups,
|
||||
} as Schedule;
|
||||
}
|
||||
);
|
||||
|
||||
export const getScheduleList = createSelector(getSearchedSchedule, (schedule) => schedule);
|
||||
|
||||
export const getGroupedFavorites = createSelector(getScheduleList, getFavoriteIds, (schedule, favoriteIds) => {
|
||||
const groups: ScheduleGroup[] = [];
|
||||
schedule.groups.forEach((group) => {
|
||||
const sessions = group.sessions.filter((s) => favoriteIds.indexOf(s.id) > -1);
|
||||
if (sessions.length) {
|
||||
const groupToAdd: ScheduleGroup = {
|
||||
time: group.time,
|
||||
sessions,
|
||||
};
|
||||
groups.push(groupToAdd);
|
||||
}
|
||||
});
|
||||
return {
|
||||
date: schedule.date,
|
||||
groups,
|
||||
} as Schedule;
|
||||
});
|
||||
export const getGroupedFavorites = createSelector(
|
||||
getScheduleList,
|
||||
getFavoriteIds,
|
||||
(schedule, favoriteIds) => {
|
||||
const groups: ScheduleGroup[] = [];
|
||||
schedule.groups.forEach((group) => {
|
||||
const sessions = group.sessions.filter((s) => favoriteIds.indexOf(s.id) > -1);
|
||||
if (sessions.length) {
|
||||
const groupToAdd: ScheduleGroup = {
|
||||
time: group.time,
|
||||
sessions,
|
||||
};
|
||||
groups.push(groupToAdd);
|
||||
}
|
||||
});
|
||||
return {
|
||||
date: schedule.date,
|
||||
groups,
|
||||
} as Schedule;
|
||||
}
|
||||
);
|
||||
|
||||
const getIdParam = (_state: AppState, props: any) => {
|
||||
return props.match.params['id'];
|
||||
@@ -126,9 +147,25 @@ export const getSession = createSelector(getSessions, getIdParam, (sessions, id)
|
||||
return sessions.find((s: Session) => s.id === id);
|
||||
});
|
||||
|
||||
export const getSpeaker = createSelector(getSpeakers, getIdParam, (speakers, id) => speakers.find((x: Speaker) => x.id === id));
|
||||
export const getSpeaker = createSelector(getSpeakers, getIdParam, (speakers, id) =>
|
||||
speakers.find((x: Speaker) => x.id === id)
|
||||
);
|
||||
|
||||
export const getEvent = createSelector(getEvents, getIdParam, (events, id) => events.find((x: Event) => x.id === id));
|
||||
export const getEvent = createSelector(getEvents, getIdParam, (data_events, id) => {
|
||||
const {
|
||||
data: { events },
|
||||
} = data_events;
|
||||
|
||||
return events.find((x: Event) => x.id === id);
|
||||
});
|
||||
|
||||
export const getOrder = createSelector(getOrders, getIdParam, (data_orders, id) => {
|
||||
const {
|
||||
data: { orders },
|
||||
} = data_orders;
|
||||
|
||||
return orders.find((x: IOrderItem) => x.id === id);
|
||||
});
|
||||
|
||||
export const getSpeakerSessions = createSelector(getSessions, (sessions) => {
|
||||
const speakerSessions: { [key: string]: Session[] } = {};
|
||||
|
@@ -3,6 +3,7 @@ import { Speaker } from '../../models/Speaker';
|
||||
import { Schedule, Session } from '../../models/Schedule';
|
||||
//
|
||||
import { Event } from '../../models/Event';
|
||||
import { IOrderItem } from '../../models/Order';
|
||||
|
||||
export interface ConfState {
|
||||
schedule: Schedule;
|
||||
@@ -18,4 +19,5 @@ export interface ConfState {
|
||||
menuEnabled: boolean;
|
||||
//
|
||||
events: Event[];
|
||||
orders: IOrderItem[];
|
||||
}
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import { SessionsActions } from './sessions.actions';
|
||||
import { ConfState } from './conf.state';
|
||||
|
||||
export const sessionsReducer = (
|
||||
state: ConfState,
|
||||
action: SessionsActions
|
||||
): ConfState => {
|
||||
export const sessionsReducer = (state: ConfState, action: SessionsActions): ConfState => {
|
||||
switch (action.type) {
|
||||
case 'set-conf-loading': {
|
||||
return { ...state, loading: action.isLoading };
|
||||
|
@@ -31,23 +31,21 @@ export const logoutUser = () => async (dispatch: React.Dispatch<any>) => {
|
||||
dispatch(setUsername());
|
||||
};
|
||||
|
||||
export const setIsLoggedIn =
|
||||
(loggedIn: boolean) => async (dispatch: React.Dispatch<any>) => {
|
||||
await setIsLoggedInData(loggedIn);
|
||||
return {
|
||||
type: 'set-is-loggedin',
|
||||
loggedIn,
|
||||
} as const;
|
||||
};
|
||||
export const setIsLoggedIn = (loggedIn: boolean) => async (dispatch: React.Dispatch<any>) => {
|
||||
await setIsLoggedInData(loggedIn);
|
||||
return {
|
||||
type: 'set-is-loggedin',
|
||||
loggedIn,
|
||||
} as const;
|
||||
};
|
||||
|
||||
export const setUsername =
|
||||
(username?: string) => async (dispatch: React.Dispatch<any>) => {
|
||||
await setUsernameData(username);
|
||||
return {
|
||||
type: 'set-username',
|
||||
username,
|
||||
} as const;
|
||||
};
|
||||
export const setUsername = (username?: string) => async (dispatch: React.Dispatch<any>) => {
|
||||
await setUsernameData(username);
|
||||
return {
|
||||
type: 'set-username',
|
||||
username,
|
||||
} as const;
|
||||
};
|
||||
|
||||
export const setHasSeenTutorial =
|
||||
(hasSeenTutorial: boolean) => async (dispatch: React.Dispatch<any>) => {
|
||||
|
Reference in New Issue
Block a user