Skip to content

Commit

Permalink
Merge pull request #71 from sparcs-kaist/migration@setup-react-query
Browse files Browse the repository at this point in the history
Refactor Account related components with function component, react-query, and ts
  • Loading branch information
sboh1214 authored Jun 1, 2024
2 parents de39597 + aea8afd commit 6076b84
Show file tree
Hide file tree
Showing 18 changed files with 369 additions and 347 deletions.
3 changes: 3 additions & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import '@testing-library/jest-dom';
import axios from 'axios';

// eslint-disable-next-line no-undef
jest.mock('react-i18next', () => ({
Expand All @@ -17,3 +18,5 @@ jest.mock('react-i18next', () => ({
return Component;
},
}));

axios.defaults.baseURL = 'http://localhost';
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"prepare": "husky install"
},
"dependencies": {
"@tanstack/react-query": "^5.36.2",
"@tanstack/react-query-devtools": "^5.36.2",
"axios": "^0.21.2",
"classnames": "^2.2.6",
"framer-motion": "^10.15.0",
Expand All @@ -25,6 +27,7 @@
"i18next-xhr-backend": "^3.2.2",
"lodash": "^4.17.21",
"moment": "^2.29.2",
"nock": "^13.5.4",
"prop-types": "^15.7.2",
"qs": "^6.9.4",
"react": "^18.2.0",
Expand Down
56 changes: 0 additions & 56 deletions src/components/sections/account/AcademicInfoSubSection.jsx

This file was deleted.

44 changes: 44 additions & 0 deletions src/components/sections/account/AcademicInfoSubSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useTranslation } from 'react-i18next';

import { appBoundClassNames as classNames } from '@/common/boundClassNames';
import { CONTACT } from '@/common/constants';
import Attributes from '@/components/Attributes';
import { useSessionInfo } from '@/queries/account';
import { useTranslatedString } from '@/hooks/useTranslatedString';

const AcademicInfoSubSection = () => {
const { t } = useTranslation();
const translate = useTranslatedString();
const { data: user } = useSessionInfo();

if (!user) {
return null;
}

return (
<div className={classNames('subsection', 'subsection--academic-info')}>
<div className={classNames('title')}>{t('ui.title.academicInformation')}</div>
<Attributes
entries={[
{ name: t('ui.attribute.studentId'), info: user.student_id },
{
name: t('ui.attribute.major'),
info: user.majors.map((d) => translate(d, 'name')).join(', '),
},
]}
/>
<div className={classNames('caption')}>
{t('ui.message.academicInfoCaptionHead')}
<a
href={`mailto:${CONTACT}`}
className={classNames('text-button')}
data-testid="contact-mail">
{CONTACT}
</a>
{t('ui.message.academicInfoCaptionTail')}
</div>
</div>
);
};

export default AcademicInfoSubSection;
174 changes: 0 additions & 174 deletions src/components/sections/account/FavoriteDepartmentsSubSection.jsx

This file was deleted.

77 changes: 77 additions & 0 deletions src/components/sections/account/FavoriteDepartmentsSubSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { FormEventHandler, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { appBoundClassNames as classNames } from '@/common/boundClassNames';
import SearchFilter from '@/components/SearchFilter';
import {
useDepartmentOptions,
useSessionInfo,
useUpdateFavoriteDepartments,
} from '@/queries/account';
import { useTranslatedString } from '@/hooks/useTranslatedString';

const FavoriteDepartmentsSubSection = () => {
const [selectedDepartments, setSelectedDepartments] = useState<Set<string>>(new Set([]));

const { t } = useTranslation();
const translate = useTranslatedString();
const { data: user } = useSessionInfo();
const { data: departmentOptions } = useDepartmentOptions();
const { mutate: updateFavoriteDepartments } = useUpdateFavoriteDepartments();

useEffect(() => {
if (user) {
setSelectedDepartments(new Set(user.favorite_departments.map((d) => String(d.id))));
}
}, [user]);

const handleSubmit: FormEventHandler = (e) => {
e.preventDefault();
e.stopPropagation();

updateFavoriteDepartments({ selectedDepartments });
};

if (!user) {
return null;
}

// TODO: Change comparison logic
const hasChange =
user.favorite_departments.length !== selectedDepartments.size ||
user.favorite_departments.some(({ id }) => !selectedDepartments.has(id.toString()));

return (
<div className={classNames('subsection', 'subsection--favorite-department')}>
<div className={classNames('title')}>{t('ui.title.settings')}</div>
{departmentOptions ? (
<form onSubmit={handleSubmit}>
<SearchFilter
updateCheckedValues={(checkedValues: Set<string>) =>
setSelectedDepartments(checkedValues)
}
inputName="department"
titleName={t('ui.search.favoriteDepartment')}
options={departmentOptions.map((d) => [
String(d.id),
`${translate(d, 'name')} (${d.code})`,
])}
checkedValues={selectedDepartments}
/>
<div className={classNames('buttons')}>
<button
type="submit"
className={classNames('text-button', { 'text-button--disabled': !hasChange })}
disabled={!hasChange}>
{t('ui.button.save')}
</button>
</div>
</form>
) : (
<span>{t('ui.placeholder.loading')}</span>
)}
</div>
);
};

export default FavoriteDepartmentsSubSection;
Loading

0 comments on commit 6076b84

Please sign in to comment.