Skip to content

Commit f8c8b7f

Browse files
author
fangedShadow
committed
Merge remote-tracking branch 'origin/development' into bhavpreet_ep_down_upload
2 parents 002b426 + e58779a commit f8c8b7f

100 files changed

Lines changed: 33303 additions & 2926 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package-lock.json

Lines changed: 24856 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/index.css

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,6 @@ body.bm-dashboard-dark .nav-link {
242242
color: #ffffff !important;
243243
}
244244

245-
body.dark-mode .navbar,
246-
body.bm-dashboard-dark .navbar {
247-
background-color: #1b2a41 !important;
248-
}
249245

250246
body.dark-mode .navbar-brand,
251247
body.bm-dashboard-dark .navbar-brand {

src/actions/__tests__/userManagement.test.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const mockStore = configureMockStore(middlewares);
1414

1515
describe('User Management Actions', () => {
1616
let store;
17-
17+
1818
beforeEach(() => {
1919
store = mockStore({});
2020
vi.clearAllMocks();
@@ -46,7 +46,7 @@ describe('User Management Actions', () => {
4646

4747
it('should update user to active status', async () => {
4848
const reactivationDate = null;
49-
49+
5050
axios.patch.mockResolvedValueOnce({ data: {} });
5151

5252
await store.dispatch(actions.updateUserStatus(mockUser, UserStatus.Active, reactivationDate));
@@ -143,7 +143,7 @@ describe('User Management Actions', () => {
143143
);
144144
});
145145

146-
146+
147147
});
148148

149149
describe('updateUserFinalDayStatus', () => {
@@ -205,6 +205,7 @@ describe('User Management Actions', () => {
205205
{ id: 1, name: 'John Doe', email: 'john@example.com' },
206206
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
207207
];
208+
const mockSource = 'Report';
208209

209210
axios.get.mockResolvedValueOnce({ data: mockBasicInfo });
210211

@@ -213,20 +214,20 @@ describe('User Management Actions', () => {
213214
{ type: 'RECEIVE_USER_PROFILE_BASIC_INFO', payload: mockBasicInfo }
214215
];
215216

216-
await store.dispatch(actions.getUserProfileBasicInfo());
217+
await store.dispatch(actions.getUserProfileBasicInfo({source: mockSource}));
217218
expect(store.getActions()).toEqual(expectedActions);
218-
expect(axios.get).toHaveBeenCalledWith(ENDPOINTS.USER_PROFILE_BASIC_INFO);
219+
expect(axios.get).toHaveBeenCalledWith(ENDPOINTS.USER_PROFILE_BASIC_INFO(mockSource));
219220
});
220221

221222
it('should handle errors when fetching basic info', async () => {
222223
axios.get.mockRejectedValueOnce(new Error('Network error'));
223-
224+
const mockSource = '';
224225
const expectedActions = [
225226
{ type: 'FETCH_USER_PROFILE_BASIC_INFO' },
226227
{ type: 'FETCH_USER_PROFILE_BASIC_INFO_ERROR' }
227228
];
228229

229-
await store.dispatch(actions.getUserProfileBasicInfo());
230+
await store.dispatch(actions.getUserProfileBasicInfo({ source: mockSource }));
230231
expect(store.getActions()).toEqual(expectedActions);
231232
});
232233
});
@@ -276,4 +277,4 @@ describe('User Management Actions', () => {
276277
expect(store.getActions()).toContainEqual(expectedAction);
277278
});
278279
});
279-
});
280+
});
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import axios from 'axios';
2+
import {
3+
FETCH_LESSON_PLANS_REQUEST,
4+
FETCH_LESSON_PLANS_SUCCESS,
5+
FETCH_LESSON_PLANS_FAILURE,
6+
FETCH_LESSON_PLAN_DETAIL_REQUEST,
7+
FETCH_LESSON_PLAN_DETAIL_SUCCESS,
8+
FETCH_LESSON_PLAN_DETAIL_FAILURE,
9+
SAVE_LESSON_PLAN_REQUEST,
10+
SAVE_LESSON_PLAN_SUCCESS,
11+
SAVE_LESSON_PLAN_FAILURE,
12+
REMOVE_LESSON_PLAN_REQUEST,
13+
REMOVE_LESSON_PLAN_SUCCESS,
14+
REMOVE_LESSON_PLAN_FAILURE,
15+
FETCH_SAVED_LESSON_PLANS_REQUEST,
16+
FETCH_SAVED_LESSON_PLANS_SUCCESS,
17+
FETCH_SAVED_LESSON_PLANS_FAILURE,
18+
CHECK_IF_SAVED_REQUEST,
19+
CHECK_IF_SAVED_SUCCESS,
20+
CHECK_IF_SAVED_FAILURE,
21+
SET_FILTERS,
22+
CLEAR_FILTERS,
23+
SET_SEARCH_QUERY,
24+
SET_VIEW_MODE,
25+
} from '~/constants/educationPortal/browseLPConstant';
26+
import { ENDPOINTS } from '~/utils/URL';
27+
28+
const getAuthHeaders = () => {
29+
const token = localStorage.getItem('token');
30+
if (!token) {
31+
}
32+
return {
33+
'Content-Type': 'application/json',
34+
Accept: 'application/json',
35+
...(token ? { Authorization: token } : {}),
36+
};
37+
};
38+
39+
export const fetchLessonPlans = (params = {}) => async dispatch => {
40+
dispatch({ type: FETCH_LESSON_PLANS_REQUEST });
41+
try {
42+
const queryString = new URLSearchParams(params).toString();
43+
const url = `${ENDPOINTS.LESSON_PLANS}${queryString ? `?${queryString}` : ''}`;
44+
45+
const res = await axios.get(url, {
46+
headers: getAuthHeaders(),
47+
});
48+
49+
dispatch({
50+
type: FETCH_LESSON_PLANS_SUCCESS,
51+
payload: res.data.data,
52+
meta: res.data.meta,
53+
});
54+
} catch (error) {
55+
const errorMessage = error.response?.status === 401
56+
? 'Please log in to view lesson plans'
57+
: error.response?.data?.error || error.message;
58+
59+
dispatch({
60+
type: FETCH_LESSON_PLANS_FAILURE,
61+
error: errorMessage,
62+
});
63+
}
64+
};
65+
66+
export const fetchLessonPlanDetail = id => async dispatch => {
67+
dispatch({ type: FETCH_LESSON_PLAN_DETAIL_REQUEST });
68+
try {
69+
const res = await axios.get(`${ENDPOINTS.LESSON_PLANS}/${id}`, {
70+
headers: getAuthHeaders(),
71+
});
72+
dispatch({ type: FETCH_LESSON_PLAN_DETAIL_SUCCESS, payload: res.data.data });
73+
} catch (error) {
74+
const errorMessage = error.response?.status === 401
75+
? 'Please log in to view lesson plan details'
76+
: error.response?.data?.error || error.message;
77+
78+
dispatch({
79+
type: FETCH_LESSON_PLAN_DETAIL_FAILURE,
80+
error: errorMessage,
81+
});
82+
}
83+
};
84+
85+
export const saveLessonPlan = (studentId, lessonPlanId) => async dispatch => {
86+
dispatch({ type: SAVE_LESSON_PLAN_REQUEST });
87+
try {
88+
const res = await axios.post(
89+
ENDPOINTS.SAVE_INTEREST,
90+
{ studentId, lessonPlanId },
91+
{
92+
headers: getAuthHeaders(),
93+
}
94+
);
95+
dispatch({
96+
type: SAVE_LESSON_PLAN_SUCCESS,
97+
payload: res.data.data,
98+
lessonPlanId,
99+
});
100+
} catch (error) {
101+
const errorMessage = error.response?.status === 401
102+
? 'Please log in to save lesson plans'
103+
: error.response?.data?.error || error.message;
104+
105+
dispatch({
106+
type: SAVE_LESSON_PLAN_FAILURE,
107+
error: errorMessage,
108+
});
109+
}
110+
};
111+
112+
export const removeLessonPlan = (studentId, lessonPlanId) => async dispatch => {
113+
dispatch({ type: REMOVE_LESSON_PLAN_REQUEST });
114+
try {
115+
const res = await axios.delete(
116+
`${ENDPOINTS.REMOVE_INTEREST}/${lessonPlanId}?studentId=${studentId}`,
117+
{
118+
headers: getAuthHeaders(),
119+
}
120+
);
121+
dispatch({
122+
type: REMOVE_LESSON_PLAN_SUCCESS,
123+
payload: res.data.data,
124+
lessonPlanId,
125+
});
126+
} catch (error) {
127+
const errorMessage = error.response?.status === 401
128+
? 'Please log in to remove saved lesson plans'
129+
: error.response?.data?.error || error.message;
130+
131+
dispatch({
132+
type: REMOVE_LESSON_PLAN_FAILURE,
133+
error: errorMessage,
134+
});
135+
}
136+
};
137+
138+
export const fetchSavedLessonPlans = studentId => async dispatch => {
139+
dispatch({ type: FETCH_SAVED_LESSON_PLANS_REQUEST });
140+
try {
141+
const res = await axios.get(
142+
`${ENDPOINTS.GET_SAVED}?studentId=${encodeURIComponent(studentId)}`,
143+
{
144+
headers: getAuthHeaders(),
145+
}
146+
);
147+
dispatch({
148+
type: FETCH_SAVED_LESSON_PLANS_SUCCESS,
149+
payload: res.data.data,
150+
meta: res.data.meta,
151+
});
152+
} catch (error) {
153+
const errorMessage = error.response?.status === 401
154+
? 'Please log in to view saved lesson plans'
155+
: error.response?.data?.error || error.message;
156+
157+
dispatch({
158+
type: FETCH_SAVED_LESSON_PLANS_FAILURE,
159+
error: errorMessage,
160+
});
161+
}
162+
};
163+
164+
export const checkIfSaved = (studentId, lessonPlanId) => async dispatch => {
165+
dispatch({ type: CHECK_IF_SAVED_REQUEST });
166+
try {
167+
const res = await axios.get(
168+
`${ENDPOINTS.CHECK_IF_SAVED}?studentId=${studentId}&lessonPlanId=${lessonPlanId}`,
169+
{
170+
headers: getAuthHeaders(),
171+
}
172+
);
173+
dispatch({
174+
type: CHECK_IF_SAVED_SUCCESS,
175+
payload: res.data.isSaved,
176+
lessonPlanId,
177+
});
178+
} catch (error) {
179+
dispatch({
180+
type: CHECK_IF_SAVED_FAILURE,
181+
error: error.response?.data?.error || error.message,
182+
});
183+
}
184+
};
185+
186+
export const setFilters = filters => ({
187+
type: SET_FILTERS,
188+
payload: filters,
189+
});
190+
191+
export const clearFilters = () => ({
192+
type: CLEAR_FILTERS,
193+
});
194+
195+
export const setSearchQuery = query => ({
196+
type: SET_SEARCH_QUERY,
197+
payload: query,
198+
});
199+
200+
export const setViewMode = mode => ({
201+
type: SET_VIEW_MODE,
202+
payload: mode,
203+
});

src/actions/userManagement.js

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,7 @@ export const updateUserFinalDayStatusIsSet = (user, status, finalDayDate, isSet)
263263
// Prepare patch data
264264
const patchData = {
265265
status,
266-
endDate: finalDayDate
267-
? moment.utc(finalDayDate).format('YYYY-MM-DD')
268-
: undefined,
266+
endDate: finalDayDate ? new Date(finalDayDate) : undefined,
269267
isSet,
270268
};
271269

@@ -286,17 +284,43 @@ export const updateUserFinalDayStatusIsSet = (user, status, finalDayDate, isSet)
286284
};
287285
};
288286

287+
export const updateUserFinalDay = (user, finalDayDate, isSet) => {
288+
return async dispatch => {
289+
try {
290+
const patchData = {
291+
endDate: finalDayDate ? new Date(finalDayDate) : undefined,
292+
isSet,
293+
};
294+
const response = await axios.patch(ENDPOINTS.UPDATE_USER_FINAL_DAY(user._id), patchData);
295+
296+
const updatedUserProfile = {
297+
...user,
298+
...response.data,
299+
};
300+
301+
dispatch(userProfileUpdateAction(updatedUserProfile));
302+
} catch (error) {
303+
toast.error('Error updating user profile:', error);
304+
throw new Error('Failed to update user profile.');
305+
}
306+
};
307+
};
308+
309+
289310
/**
290311
* fetching all user profiles basic info
312+
* Added `source` parameter to identify the calling component.
291313
*/
292-
export const getUserProfileBasicInfo = (userId) => {
314+
export const getUserProfileBasicInfo = ({ userId, source }) => {
293315
// API request to fetch basic user profile information
294-
let userProfileBasicInfoPromise;
295-
if (userId)
316+
let userProfileBasicInfoPromise;
317+
if (userId)
296318
userProfileBasicInfoPromise = axios.get(`${ENDPOINTS.USER_PROFILE_BASIC_INFO}?userId=${userId}`);
297-
else
319+
else if (source)
320+
userProfileBasicInfoPromise = axios.get(ENDPOINTS.USER_PROFILE_BASIC_INFO(source));
321+
else
298322
userProfileBasicInfoPromise = axios.get(ENDPOINTS.USER_PROFILE_BASIC_INFO);
299-
323+
300324
return async dispatch => {
301325
// Dispatch action indicating the start of the fetch process
302326
await dispatch(userProfilesBasicInfoFetchStartAction());

src/components/BMDashboard/ItemList/SelectItem.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ export default function SelectItem({
7676
<option value="all" key="all-option">
7777
All
7878
</option>
79-
{itemSet.map(itemName => (
80-
<option key={`item-${itemName}`} value={itemName}>
81-
{itemName}
79+
{itemSet.map(item => (
80+
<option key={`item-${item}`} value={item}>
81+
{item}
8282
</option>
8383
))}
8484
</>

0 commit comments

Comments
 (0)