From 0a0b6c7a55f04cd643850edca8d005a60582af7d Mon Sep 17 00:00:00 2001 From: Janus Chung Date: Thu, 19 Dec 2024 22:07:28 -0800 Subject: [PATCH] better offerlist UX --- src/components/AppHeader.jsx | 1 + src/components/MobileMenu.jsx | 4 +- src/components/OfferListDialog.jsx | 104 +++++++++-------------- src/components/common/SortableTable.jsx | 58 +++++++++++++ src/components/hooks/useSortableTable.js | 40 +++++++++ src/util/sortUtil.js | 18 ++++ 6 files changed, 161 insertions(+), 64 deletions(-) create mode 100644 src/components/common/SortableTable.jsx create mode 100644 src/components/hooks/useSortableTable.js create mode 100644 src/util/sortUtil.js diff --git a/src/components/AppHeader.jsx b/src/components/AppHeader.jsx index 3e134b8..c954218 100644 --- a/src/components/AppHeader.jsx +++ b/src/components/AppHeader.jsx @@ -168,6 +168,7 @@ export default function AppHeader() { handleMobileMenuClose={handleMobileMenuClose} handleProfileMenuOpen={handleProfileMenuOpen} handleJobApplicationOpen={handleOpen} + handleOfferListDialogOpen={handleOfferListDialogOpen} interviewCount={interviewCount} offerCount={offerCount} /> diff --git a/src/components/MobileMenu.jsx b/src/components/MobileMenu.jsx index deb5447..ebd89b3 100644 --- a/src/components/MobileMenu.jsx +++ b/src/components/MobileMenu.jsx @@ -8,7 +8,7 @@ import EventAvailableIcon from '@mui/icons-material/EventAvailable'; import NotificationsIcon from '@mui/icons-material/Notifications'; import AccountCircle from '@mui/icons-material/AccountCircle'; -export default function MobileMenu({ mobileMoreAnchorEl, isMobileMenuOpen, handleMobileMenuClose, handleProfileMenuOpen, handleJobApplicationOpen, interviewCount, offerCount }) { +export default function MobileMenu({ mobileMoreAnchorEl, isMobileMenuOpen, handleMobileMenuClose, handleProfileMenuOpen, handleJobApplicationOpen, handleOfferListDialogOpen, interviewCount, offerCount }) { const mobileMenuId = 'primary-search-account-menu-mobile'; return (

Interviews

- + diff --git a/src/components/OfferListDialog.jsx b/src/components/OfferListDialog.jsx index 7a07626..ebead83 100644 --- a/src/components/OfferListDialog.jsx +++ b/src/components/OfferListDialog.jsx @@ -7,25 +7,22 @@ import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import CircularProgress from '@mui/material/CircularProgress'; import Box from '@mui/material/Box'; -import Table from '@mui/material/Table'; -import TableBody from '@mui/material/TableBody'; -import TableCell from '@mui/material/TableCell'; -import TableContainer from '@mui/material/TableContainer'; -import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; -import Paper from '@mui/material/Paper'; import { GET_ALL_OFFERS } from '../graphql/query'; import useJobApplicationDialog from './hooks/useJobApplicationDialog'; import JobApplicationDialog from './JobApplicationDialog'; import DialogTitleBar from './DialogTitleBar'; +import useSortableTable from './hooks/useSortableTable'; +import SortableTable from './common/SortableTable'; export default function OfferListDialog({ handleClose, open }) { const [offers, setOffers] = useState([]); + const { loading, error, data, refetch } = useQuery(GET_ALL_OFFERS, { fetchPolicy: 'network-only', onCompleted: (data) => setOffers(data.allOffer), }); + const { open: jobDialogOpen, jobApplication, @@ -35,6 +32,35 @@ export default function OfferListDialog({ handleClose, open }) { refetch().then(({ data }) => setOffers(data.allOffer)); }); + const columns = [ + { + key: 'jobApplication.companyName', // Nested property example + label: 'Company Name', + sortable: true, + render: (value, row) => value || row.jobApplication?.companyName || 'N/A', // Fallback for nested value + }, + { key: 'offerDate', label: 'Offer Date', sortable: true }, + { key: 'salaryOffered', label: 'Salary Offered', sortable: true }, + { key: 'description', label: 'Note' }, + { + key: 'actions', + label: 'Job Application', + render: (value, row) => ( + + ), + align: 'center', + }, + ]; + + const { sortedData, handleSort, getSortIndicator } = useSortableTable(offers, columns); + useEffect(() => { if (open) { refetch() @@ -49,8 +75,6 @@ export default function OfferListDialog({ handleClose, open }) { - - {loading && ( + {loading ? ( - )} - - {error && ( + ) : error ? ( Something went wrong. Please try again later. - )} - - {!loading && !error && offers.length === 0 && ( - - - No offers available yet! - - - - )} - - {!loading && !error && offers.length > 0 && ( - - - - - Company - Offer Date - Salary Offered - Note - Job Application - - - - {offers.map((offer, index) => ( - - {offer.jobApplication.companyName} - {offer.offerDate} - {offer.salaryOffered} - {offer.description} - - - - - ))} - -
-
+ ) : ( + )}
-