Skip to content

Commit 4f46032

Browse files
authored
Use the typescript client for Core API (#273)
* Use the typescript client for Core API * fix build
1 parent e5a6707 commit 4f46032

File tree

12 files changed

+249
-323
lines changed

12 files changed

+249
-323
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@
1717
"prettier:write": "prettier --write ."
1818
},
1919
"dependencies": {
20+
"@acm-uiuc/core-client": "^4.1.9",
2021
"@acm-uiuc/js-shared": "^3.2.0",
2122
"@azure/msal-browser": "^4.15.0",
2223
"@azure/msal-react": "^3.0.15",
2324
"@heroui/react": "2.7.6",
2425
"@marsidev/react-turnstile": "^1.4.1",
25-
"axios": "^0.28.0",
2626
"framer-motion": "^10.17.9",
2727
"lottie-react": "^2.3.1",
2828
"moment": "^2.29.4",
2929
"moment-timezone": "^0.5.45",
3030
"next": "^14.2.25",
31+
"pluralize": "^8.0.0",
3132
"react": "^18.3.1",
3233
"react-big-calendar": "^1.13.1",
3334
"react-dom": "^18.3.1",
@@ -45,6 +46,7 @@
4546
"@testing-library/react": "^13.3.0",
4647
"@types/jest": "^27.5.2",
4748
"@types/node": "^20",
49+
"@types/pluralize": "^0.0.33",
4850
"@types/react": "^18",
4951
"@types/react-big-calendar": "^1.8.8",
5052
"@types/react-dom": "^18",

src/app/(main)/calendar/page.tsx

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import { Suspense, useEffect, useState } from 'react';
88
import CalendarControls from '@/components/CalendarControls';
99
import { View, Views } from 'react-big-calendar';
1010
import { transformApiDates } from '@/utils/dateutils';
11-
import { OrganizationName, Organizations } from '@acm-uiuc/js-shared';
11+
import { AllOrganizationNameList, OrganizationName, Organizations } from '@acm-uiuc/js-shared';
1212
import { useSearchParams } from 'next/navigation';
13+
import { eventsApiClient } from '@/utils/api';
1314

1415
const defaultEvent: CalendarEventDetailProps = {
1516
description: 'N/A',
@@ -30,35 +31,11 @@ const Calendar = () => {
3031
OrganizationList.includes(host as OrganizationName) ? host : '',
3132
);
3233
const [allEvents, setAllEvents] = useState<IEvent[] | null>(null);
33-
const [validOrganizations, setValidOrganizations] =
34-
useState<string[]>(OrganizationList);
3534
useEffect(() => {
36-
const baseurl = process.env.NEXT_PUBLIC_CORE_API_BASE_URL;
37-
if (!baseurl) {
38-
return setAllEvents([]);
39-
}
40-
async function fetcher() {
41-
const urls = [
42-
`${baseurl}/api/v1/events`,
43-
];
44-
45-
try {
46-
const [eventsResponse] =
47-
await Promise.allSettled(urls.map((url) => fetch(url)));
48-
if (eventsResponse.status === 'fulfilled') {
49-
const eventsData = await eventsResponse.value.json();
50-
setAllEvents(transformApiDates(eventsData as IEvent[]));
51-
} else {
52-
setAllEvents([]); // Handle error for events fetch
53-
}
54-
setValidOrganizations(OrganizationList);
55-
} catch (err) {
56-
console.error('Error in processing fetch results:', err);
57-
setAllEvents([]); // Fallback error handling for critical failure
58-
setValidOrganizations(OrganizationList);
59-
}
60-
}
61-
fetcher();
35+
(async () => {
36+
const allEvents = await eventsApiClient.apiV1EventsGet()
37+
setAllEvents(transformApiDates(allEvents));
38+
})();
6239
}, []);
6340

6441
// Function to handle filter changes, moved from Events.tsx
@@ -112,7 +89,7 @@ const Calendar = () => {
11289
className="px-2 border-2 border-gray-300 rounded-md w-full h-full" // Styling for the dropdown
11390
>
11491
<option value="">{filterLabel}</option>
115-
{validOrganizations.map((org) => (
92+
{AllOrganizationNameList.map((org) => (
11693
<option key={org} value={org}>
11794
{org}
11895
</option>

src/app/(membership)/admin/sync/page.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
import { Spinner } from '@heroui/spinner';
1818

1919
import Lottie from 'lottie-react';
20-
import axios from 'axios';
2120
import Layout from '../../MembershipLayout';
2221
import successAnimation from '../../success.json';
2322
import { useSearchParams } from 'next/navigation';

src/app/(membership)/check-membership/page.tsx

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,19 @@ import { Spinner } from '@heroui/spinner';
1818
// import Lottie from 'lottie-react';
1919
import dynamic from 'next/dynamic';
2020
const Lottie = dynamic(() => import('lottie-react'), { ssr: false });
21-
import axios from 'axios';
2221
import Layout from '../MembershipLayout';
2322
import successAnimation from '../success.json';
2423
import { getUserAccessToken, initMsalClient } from '@/utils/msal';
2524
import { MembershipPriceString } from "@acm-uiuc/js-shared"
2625
import { IPublicClientApplication } from '@azure/msal-browser';
27-
import { syncIdentity } from '@/utils/api';
26+
import { membershipApiClient, mobileWalletApiClient, syncIdentity } from '@/utils/api';
27+
import { Configuration, MembershipApi, MobileWalletApi, ResponseError } from '@acm-uiuc/core-client';
2828

2929
interface ErrorCode {
3030
code?: number | string;
3131
message: string;
3232
}
3333

34-
const baseUrl = process.env.NEXT_PUBLIC_CORE_API_BASE_URL;
35-
const walletApiBaseUrl = process.env.NEXT_PUBLIC_CORE_API_BASE_URL;
36-
3734
const Payment = () => {
3835
const [netId, setNetId] = useState('');
3936
const [fullName, setFullName] = useState<string | null>(null);
@@ -108,26 +105,31 @@ const Payment = () => {
108105
setNetId(netId);
109106
setIsLoading(true);
110107
await syncIdentity(accessToken)
111-
const url = `${baseUrl}/api/v1/membership`;
112-
axios
113-
.get(url, { headers: { "x-uiuc-token": accessToken } })
114-
.then((response) => {
115-
if (response.data.givenName && response.data.surname) {
116-
setFullName(`${response.data.givenName} ${response.data.surname}`)
117-
}
118-
setIsPaidMember(response.data.isPaidMember || false);
119-
setIsLoading(false);
120-
modalMembershipStatus.onOpen();
121-
})
122-
.catch((error) => {
123-
setIsLoading(false);
108+
try {
109+
const membershipResponse = await membershipApiClient.apiV1MembershipGet({ xUiucToken: accessToken });
110+
if (membershipResponse.givenName && membershipResponse.surname) {
111+
setFullName(`${membershipResponse.givenName} ${membershipResponse.surname}`)
112+
}
113+
setIsPaidMember(membershipResponse.isPaidMember);
114+
setIsLoading(false);
115+
modalMembershipStatus.onOpen();
116+
} catch (e) {
117+
console.error(e)
118+
if (e instanceof ResponseError) {
124119
setErrorMessage({
125-
code: error?.response?.status || 500,
126-
message: error?.message || 'An unknown error occurred',
120+
code: e?.response?.status || 500,
121+
message: (await e.response.json()).message || 'An unknown error occurred',
127122
});
128-
modalErrorMessage.onOpen();
129-
});
130-
};
123+
} else {
124+
setErrorMessage({
125+
code: 400,
126+
message: 'An unknown error occurred',
127+
});
128+
}
129+
modalErrorMessage.onOpen();
130+
131+
}
132+
}
131133

132134
const handleAddToWallet = async () => {
133135
setIsWalletLoading(true);
@@ -149,15 +151,9 @@ const Payment = () => {
149151
modalErrorMessage.onOpen();
150152
return;
151153
}
152-
let response;
154+
let response: Blob | undefined;
153155
try {
154-
response = await axios.get(
155-
`${walletApiBaseUrl}/api/v2/mobileWallet/membership`,
156-
{
157-
headers: { 'Content-Type': 'application/json', 'x-uiuc-token': accessToken },
158-
responseType: 'blob',
159-
},
160-
);
156+
response = await mobileWalletApiClient.apiV2MobileWalletMembershipGet({ xUiucToken: accessToken })
161157
setIsWalletLoading(false);
162158
} catch (error: any) {
163159
setIsWalletLoading(false);
@@ -173,8 +169,7 @@ const Payment = () => {
173169
if (!response) {
174170
return;
175171
}
176-
const pkpassBlob = response.data;
177-
const url = window.URL.createObjectURL(pkpassBlob);
172+
const url = window.URL.createObjectURL(response);
178173
const link = document.createElement('a');
179174
link.href = url;
180175
link.setAttribute('download', 'acm_uiuc_membership.pkpass');

src/app/(membership)/membership/page.tsx

Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ import {
1717
import { Spinner } from '@heroui/spinner';
1818

1919
import Lottie from 'lottie-react';
20-
import axios from 'axios';
2120
import Layout from '../MembershipLayout';
2221
import successAnimation from '../success.json';
2322
import { useSearchParams } from 'next/navigation';
24-
import config from '@/config.json';
2523
import { type IPublicClientApplication } from "@azure/msal-browser";
2624
import { getUserAccessToken, initMsalClient } from '@/utils/msal';
2725
import { MembershipPriceString } from '@acm-uiuc/js-shared';
26+
import { membershipApiClient } from '@/utils/api';
27+
import { ResponseError, ValidationError } from '@acm-uiuc/core-client';
2828

2929

3030
interface ErrorCode {
@@ -80,57 +80,37 @@ const Payment = () => {
8080
modalErrorMessage.onOpen();
8181
return;
8282
}
83-
const url = `${baseUrl}/api/v2/membership/checkout`;
84-
axios
85-
.get(url, {
86-
headers: { "Content-Type": "text/plain", 'x-uiuc-token': accessToken }
87-
})
88-
.then((response) => {
89-
window.location.replace(response.data);
90-
})
91-
.catch((error) => {
83+
try {
84+
const response = await membershipApiClient.apiV2MembershipCheckoutGet({
85+
xUiucToken: accessToken,
86+
});
87+
window.location.replace(response)
88+
} catch (e) {
89+
console.error("Error purchasing membership", e)
90+
if (e instanceof ResponseError) {
9291
setIsLoading(false);
93-
if (error.response) {
94-
if (error.response.status === 422) {
95-
const errorObj = error.response.data;
96-
setErrorMessage({
97-
code: errorObj.details[0].issue,
98-
message: errorObj.details[0].description,
99-
});
100-
modalErrorMessage.onOpen();
101-
}
102-
else if (error.response.status === 403) {
103-
setErrorMessage({
104-
code: 409,
105-
message: 'Could not verify NetID.',
106-
});
107-
modalAlreadyMember.onOpen();
108-
} else if (error.response.status === 400) {
109-
const errorObj = error.response.data;
110-
if ((errorObj.message as string).includes("is already a paid member")) {
111-
setErrorMessage({
112-
code: 409,
113-
message: 'The specified user is already a paid member.',
114-
});
115-
modalAlreadyMember.onOpen();
116-
} else {
117-
setErrorMessage({
118-
code: errorObj.id,
119-
message: errorObj.message,
120-
});
121-
modalErrorMessage.onOpen();
122-
}
123-
} else if (error.response.status === 409) {
124-
setErrorMessage({
125-
code: 500,
126-
message:
127-
'Internal server error: ' +
128-
(error.response.data.message || 'could not process request'),
129-
});
130-
modalErrorMessage.onOpen();
131-
}
92+
const responseJson = await e.response.json() as ValidationError;
93+
if (responseJson.message.includes("is already a paid member")) {
94+
modalErrorMessage.onClose();
95+
modalAlreadyMember.onOpen();
96+
return;
13297
}
133-
});
98+
setErrorMessage({
99+
code: responseJson.id ?? 400,
100+
message: responseJson.message ?? "An error occurred creating your checkout session."
101+
})
102+
} else {
103+
setErrorMessage({
104+
code: 400,
105+
message: "An error occurred creating your checkout session."
106+
})
107+
}
108+
modalErrorMessage.onOpen();
109+
}
110+
111+
112+
113+
134114
}, [modalAlreadyMember, modalErrorMessage]);
135115

136116
useEffect(() => {

0 commit comments

Comments
 (0)