Skip to content

Commit 1a02179

Browse files
Merge pull request #780 from Real-Dev-Squad/develop
Dev to Main Sync
2 parents a3bf062 + 4b62a55 commit 1a02179

File tree

8 files changed

+181
-45
lines changed

8 files changed

+181
-45
lines changed

applications/script.js

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
getIsSuperUser,
55
showToast,
66
updateApplication,
7+
getApplicationById,
78
} from './utils.js';
89
let nextLink;
910
let isDataLoading = false;
@@ -271,8 +272,33 @@ async function renderApplicationCards(next, status, isInitialRender) {
271272
});
272273
}
273274

275+
async function renderApplicationById(id) {
276+
noApplicationFoundText.classList.add('hidden');
277+
changeLoaderVisibility({ hide: false });
278+
isDataLoading = true;
279+
280+
try {
281+
const application = await getApplicationById(id);
282+
283+
if (!application) {
284+
return noApplicationFoundText.classList.remove('hidden');
285+
}
286+
287+
const applicationCard = createApplicationCard({ application });
288+
applicationContainer.appendChild(applicationCard);
289+
applicationContainer.classList.add('center');
290+
} catch (error) {
291+
console.error('Error fetching application by user ID:', error);
292+
noApplicationFoundText.classList.remove('hidden');
293+
} finally {
294+
isDataLoading = false;
295+
changeLoaderVisibility({ hide: true });
296+
}
297+
}
298+
274299
(async function renderCardsInitial() {
275300
changeLoaderVisibility({ hide: false });
301+
276302
const isSuperUser = await getIsSuperUser();
277303
if (!isSuperUser) {
278304
const unAuthorizedText = createElement({
@@ -284,8 +310,19 @@ async function renderApplicationCards(next, status, isInitialRender) {
284310
changeLoaderVisibility({ hide: true });
285311
return;
286312
}
287-
await renderApplicationCards('', status, true);
288-
addIntersectionObserver();
313+
314+
const queryString = window.location.search;
315+
const urlParams = new URLSearchParams(queryString);
316+
const applicationId = urlParams.get('id');
317+
318+
if (applicationId) {
319+
await renderApplicationById(applicationId);
320+
} else {
321+
await renderApplicationCards('', status, true);
322+
addIntersectionObserver();
323+
}
324+
325+
changeLoaderVisibility({ hide: true });
289326
})();
290327

291328
const intersectionObserver = new IntersectionObserver(async (entries) => {

applications/style.css

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ body {
4848
.container {
4949
max-width: 1100px;
5050
margin: 0 auto;
51-
padding: 2.5rem;
51+
padding: 2rem;
5252
overflow-y: auto;
5353
}
5454

@@ -144,13 +144,16 @@ body {
144144

145145
.application-container {
146146
display: flex;
147-
margin-top: 30px;
148147
flex-wrap: wrap;
149148
justify-content: space-between;
150149
padding-bottom: 10px;
151150
gap: 25px;
152151
}
153152

153+
.application-container.center {
154+
justify-content: center;
155+
}
156+
154157
.application-card {
155158
border-radius: 15px;
156159
box-shadow: var(--elevation-1);

applications/utils.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,28 @@ async function getApplications({ applicationStatus, size = 5, next = '' }) {
4040
}
4141
}
4242

43+
async function getApplicationById(applicationId) {
44+
try {
45+
const res = await fetch(`${BASE_URL}/applications/${applicationId}`, {
46+
method: 'GET',
47+
credentials: 'include',
48+
headers: {
49+
'Content-type': 'application/json',
50+
},
51+
});
52+
53+
if (!res.ok) {
54+
const error = await res.json();
55+
throw error;
56+
}
57+
58+
const data = await res.json();
59+
return data.application;
60+
} catch (error) {
61+
throw error;
62+
}
63+
}
64+
4365
async function getIsSuperUser() {
4466
try {
4567
const res = await fetch(`${BASE_URL}/users/self`, {
@@ -104,6 +126,7 @@ function showToast({ message, type }) {
104126
export {
105127
createElement,
106128
getApplications,
129+
getApplicationById,
107130
updateApplication,
108131
getIsSuperUser,
109132
showToast,

requests/constants.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ const Status = {
66
};
77

88
const OOO_REQUEST_TYPE = 'OOO';
9+
const EXTENSION_REQUEST_TYPE = 'EXTENSION';
910
const REQUEST_CONTAINER_ID = 'request_container';
1011
const OOO_TAB_ID = 'ooo_tab_link';
12+
const EXTENSION_TAB_ID = 'extension_tab_link';
1113

1214
const DEFAULT_DATE_FORMAT = 'DD MMM YYYY';
1315

@@ -19,8 +21,9 @@ const MessageStatus = {
1921
const ErrorMessages = {
2022
UNAUTHENTICATED:
2123
'You are unauthenticated to view this section, please login!',
22-
UNAUTHORIZED: 'You are unauthrozed to view this section',
24+
UNAUTHORIZED: 'You are unauthorized to view this section',
2325
OOO_NOT_FOUND: 'OOO Requests not found',
26+
EXTENSION_NOT_FOUND: 'Extension Requests not found',
2427
SERVER_ERROR: 'Unexpected error occurred',
2528
};
2629

requests/index.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<meta
88
name="description"
9-
content="This web page is for the requests managment functionality in real dev squad's dashboard website. admin can view and take action on the requests raised by the team members."
9+
content="This web page is for the requests management functionality in real dev squad's dashboard website. Admins can view and take action on the requests raised by the team members."
1010
/>
11-
<meta name="keywords" content="RDS, Request Managment" />
11+
<meta name="keywords" content="RDS, Request Management" />
1212
<meta name="author" content="Real Dev Squad" />
1313
<link rel="icon" href="/images/index.ico" type="image/x-icon" />
1414
<link rel="preconnect" href="https://fonts.googleapis.com" />
@@ -17,7 +17,6 @@
1717
href="https://fonts.googleapis.com/css2?family=Inter:wght@100;400;700;800&display=swap"
1818
rel="stylesheet"
1919
/>
20-
2120
<title>Requests | Real Dev Squad</title>
2221
<link rel="stylesheet" href="/global.css" />
2322
<link rel="stylesheet" href="/requests/style.css" />

requests/script.js

Lines changed: 85 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const loader = document.querySelector('.container__body__loader');
88
const startLoading = () => loader.classList.remove('hidden');
99
const stopLoading = () => loader.classList.add('hidden');
1010
let oooTabLink = document.getElementById(OOO_TAB_ID);
11+
let extensionTabLink = document.getElementById(EXTENSION_TAB_ID);
1112
let currentReqType = OOO_REQUEST_TYPE;
1213
let selected__tab__class = 'selected__tab';
1314
let statusValue = null;
@@ -25,7 +26,7 @@ const intersectionObserver = new IntersectionObserver(async (entries) => {
2526
return;
2627
}
2728
if (entries[0].isIntersecting && !isDataLoading) {
28-
await renderOooRequestCards({
29+
await renderRequestCards({
2930
state: statusValue,
3031
sort: sortByValue,
3132
next: nextLink,
@@ -42,18 +43,35 @@ const removeIntersectionObserver = () => {
4243

4344
oooTabLink.addEventListener('click', async function () {
4445
if (isDataLoading) return;
45-
oooTabLink.classList.add(selected__tab__class);
4646
currentReqType = OOO_REQUEST_TYPE;
47+
nextLink = '';
48+
oooTabLink.classList.add(selected__tab__class);
49+
extensionTabLink.classList.remove(selected__tab__class);
50+
changeFilter();
51+
updateUrlWithQuery(currentReqType);
52+
await renderRequestCards({ state: statusValue, sort: sortByValue });
53+
});
54+
55+
extensionTabLink.addEventListener('click', async function () {
56+
if (isDataLoading) return;
57+
currentReqType = EXTENSION_REQUEST_TYPE;
58+
nextLink = '';
59+
extensionTabLink.classList.add(selected__tab__class);
60+
oooTabLink.classList.remove(selected__tab__class);
4761
changeFilter();
48-
await renderOooRequestCards({ state: statusValue, sort: sortByValue });
62+
updateUrlWithQuery(currentReqType);
63+
await renderRequestCards({ state: statusValue, sort: sortByValue });
4964
});
5065

66+
function updateUrlWithQuery(type) {
67+
const url = new URL(window.location);
68+
url.searchParams.set('type', type.toLowerCase());
69+
window.history.pushState({ path: url.toString() }, '', url.toString());
70+
}
71+
5172
async function getOooRequests(query = {}) {
5273
let finalUrl =
5374
API_BASE_URL + (nextLink || '/requests' + getOooQueryParamsString(query));
54-
let windowUrl = `${window.location.origin}${window.location.pathname}`;
55-
56-
window.history.pushState({ path: windowUrl }, '', windowUrl);
5775

5876
try {
5977
const res = await fetch(finalUrl, {
@@ -88,6 +106,44 @@ async function getOooRequests(query = {}) {
88106
}
89107
}
90108

109+
async function getExtensionRequests(query = {}) {
110+
let finalUrl =
111+
API_BASE_URL +
112+
(nextLink || '/requests' + getExtensionQueryParamsString(query));
113+
114+
try {
115+
const res = await fetch(finalUrl, {
116+
credentials: 'include',
117+
});
118+
119+
const data = await res.json();
120+
if (res.ok) {
121+
return data;
122+
} else {
123+
switch (res.status) {
124+
case 401:
125+
showMessage('ERROR', ErrorMessages.UNAUTHENTICATED);
126+
return;
127+
case 403:
128+
showMessage('ERROR', ErrorMessages.UNAUTHORIZED);
129+
return;
130+
case 404:
131+
showMessage('ERROR', ErrorMessages.EXTENSION_NOT_FOUND);
132+
return;
133+
case 400:
134+
showMessage('ERROR', data.message);
135+
showToast(data.message, 'failure');
136+
return;
137+
default:
138+
break;
139+
}
140+
}
141+
showMessage('ERROR', ErrorMessages.SERVER_ERROR);
142+
} catch (e) {
143+
console.error(e);
144+
}
145+
}
146+
91147
function showMessage(type, message) {
92148
const p = document.createElement('p');
93149
const classes = ['request__message'];
@@ -106,11 +162,7 @@ const changeFilter = () => {
106162
requestContainer.innerHTML = '';
107163
};
108164

109-
function createOooRequestCard(
110-
oooRequest,
111-
superUserDetails,
112-
requesterUserDetails,
113-
) {
165+
function createRequestCard(request, superUserDetails, requesterUserDetails) {
114166
let {
115167
id,
116168
state,
@@ -121,7 +173,7 @@ function createOooRequestCard(
121173
lastModifiedBy,
122174
reason,
123175
updatedAt,
124-
} = oooRequest;
176+
} = request;
125177
let showSuperuserDetailsClass = 'notHidden';
126178
let showActionButtonClass = 'notHidden';
127179
if (
@@ -161,17 +213,17 @@ function createOooRequestCard(
161213
child: [
162214
generateRequesterInfo(),
163215
generateRequestContent(),
164-
addHotizontalBreakLine(),
216+
addHorizontalBreakLine(),
165217
generateSuperuserInfo(),
166218
generateActionButtonsContainer(),
167219
],
168220
});
169221
return card;
170222

171-
function addHotizontalBreakLine() {
223+
function addHorizontalBreakLine() {
172224
return createElementFromMap({
173225
tagName: 'hr',
174-
class: 'horizontal__line__saperator',
226+
class: 'horizontal__line__separator',
175227
});
176228
}
177229

@@ -378,28 +430,28 @@ function createOooRequestCard(
378430
}
379431
}
380432

381-
async function renderOooRequestCards(queries = {}) {
433+
async function renderRequestCards(queries = {}) {
382434
if (isDataLoading) return;
383-
let oooRequestResponse;
435+
let requestResponse;
384436
try {
385437
isDataLoading = true;
386438
startLoading();
387439
if (userDetails.length === 0) {
388440
userDetails = await getInDiscordUserList();
389441
}
390-
oooRequestResponse = await getOooRequests(queries);
391-
for (const oooRequest of oooRequestResponse?.data || []) {
442+
requestResponse =
443+
currentReqType === OOO_REQUEST_TYPE
444+
? await getOooRequests(queries)
445+
: await getExtensionRequests(queries);
446+
447+
for (const request of requestResponse?.data || []) {
392448
let superUserDetails;
393-
let requesterUserDetails = await getUserDetails(oooRequest.requestedBy);
394-
if (oooRequest.state !== 'PENDING') {
395-
superUserDetails = await getUserDetails(oooRequest.lastModifiedBy);
449+
let requesterUserDetails = await getUserDetails(request.requestedBy);
450+
if (request.state !== 'PENDING') {
451+
superUserDetails = await getUserDetails(request.lastModifiedBy);
396452
}
397453
requestContainer.appendChild(
398-
createOooRequestCard(
399-
oooRequest,
400-
superUserDetails,
401-
requesterUserDetails,
402-
),
454+
createRequestCard(request, superUserDetails, requesterUserDetails),
403455
);
404456
}
405457
} catch (error) {
@@ -410,15 +462,15 @@ async function renderOooRequestCards(queries = {}) {
410462
isDataLoading = false;
411463
if (
412464
requestContainer.innerHTML === '' ||
413-
oooRequestResponse === undefined ||
414-
oooRequestResponse?.data?.length === 0
465+
requestResponse === undefined ||
466+
requestResponse?.data?.length === 0
415467
) {
416-
showMessage('INFO', 'No OOO requests found!');
468+
showMessage('INFO', `No ${currentReqType.toLowerCase()} requests found!`);
417469
}
418470
}
419471

420472
addIntersectionObserver();
421-
nextLink = oooRequestResponse?.next;
473+
nextLink = requestResponse?.next;
422474
}
423475

424476
async function acceptRejectRequest(id, reqBody) {
@@ -497,7 +549,7 @@ async function performAcceptRejectAction(isAccepted, e) {
497549
updatedRequestDetails.requestedBy,
498550
);
499551

500-
const updatedCard = createOooRequestCard(
552+
const updatedCard = createRequestCard(
501553
updatedRequestDetails,
502554
superUserDetails,
503555
requesterUserDetails,
@@ -535,4 +587,4 @@ function showToast(message, type) {
535587
}, 5000);
536588
}
537589

538-
renderOooRequestCards({ state: statusValue, sort: sortByValue });
590+
renderRequestCards({ state: statusValue, sort: sortByValue });

0 commit comments

Comments
 (0)