Skip to content

Commit

Permalink
[Release] Version 0.3.5 (#384)
Browse files Browse the repository at this point in the history
* [enhancement] Track application status to return to original tab in admin view (#372)

* Track application status to return to correct tab

* fixup! Track application status to return to correct tab

* [Fix] Unsaved Doctor's Information (#374)

* used values.doctorInformation instead of doctorInformation

* using validated values for doctor's info

* [Improvement] Add pagination controls to top of requests/permit holders tables (#376)

* Add pagination to top of requests table

* Add pagination to top of permit holders table

* Add Vihaan to employees.ts (#379)

* Add Braydent to employee.ts (#380)

* broyston: updated stamp png to contain new address (#382)

* Add phone number and addresses to request report (#383)

* Remove applicant deletion (#377)

---------

Co-authored-by: Jennifer Chen <[email protected]>
Co-authored-by: Keane Moraes <[email protected]>
Co-authored-by: Chinemerem <[email protected]>
Co-authored-by: Brayden Royston <[email protected]>
  • Loading branch information
5 people authored Nov 18, 2024
1 parent a645238 commit 92a56e3
Show file tree
Hide file tree
Showing 13 changed files with 223 additions and 86 deletions.
20 changes: 12 additions & 8 deletions components/admin/permit-holders/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { ChevronDownIcon, ChevronLeftIcon } from '@chakra-ui/icons'; // Chakra UI icon
import Link from 'next/link'; // Link
import { ApplicantStatus } from '@lib/graphql/types';
import { CurrentApplication } from '@tools/admin/permit-holders/current-application';
import PermitHolderStatusBadge from '@components/admin/PermitHolderStatusBadge';
import ConfirmDeleteApplicantModal from '@components/admin/permit-holders/table/ConfirmDeleteApplicantModal';
import SetPermitHolderToInactiveModal from '@components/admin/permit-holders/table/ConfirmSetInactiveModal';
Expand All @@ -31,12 +32,13 @@ type PermitHolderHeaderProps = {
status: ApplicantStatus;
inactiveReason?: string;
notes: string;
mostRecentApplication: CurrentApplication | null;
};
readonly refetch: () => void;
};

export default function PermitHolderHeader({
applicant: { id, name, status, inactiveReason, notes },
applicant: { id, name, status, inactiveReason, notes, mostRecentApplication },
refetch,
}: PermitHolderHeaderProps) {
const router = useRouter();
Expand Down Expand Up @@ -108,13 +110,15 @@ export default function PermitHolderHeader({
>
{`Set as ${status === 'ACTIVE' ? 'Inactive' : 'Active'}`}
</MenuItem>
<MenuItem
color="text.critical"
textStyle="button-regular"
onClick={onOpenDeleteApplicantModal}
>
{'Delete Permit Holder'}
</MenuItem>
{mostRecentApplication?.processing?.status == 'COMPLETED' ? null : (
<MenuItem
color="text.critical"
textStyle="button-regular"
onClick={onOpenDeleteApplicantModal}
>
{'Delete Permit Holder'}
</MenuItem>
)}
</MenuList>
</Menu>
</Box>
Expand Down
20 changes: 19 additions & 1 deletion components/admin/requests/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ApplicationStatus, ApplicationType, PermitType } from '@lib/graphql/typ
import { titlecase } from '@tools/string';
import { formatDateYYYYMMDD, formatDateYYYYMMDDLocal } from '@lib/utils/date';
import { getPermanentPermitExpiryDate } from '@lib/utils/permit-expiry';
import { useEffect, useState } from 'react'; // React

type RequestHeaderProps = {
readonly id: number;
Expand Down Expand Up @@ -87,6 +88,22 @@ export default function RequestHeader({

const router = useRouter();

const [backLink, setBackLink] = useState('/admin');
const generateBackLink = () => {
let status;
const routerQuery = router.query;
if (routerQuery === undefined || routerQuery.origin === undefined) {
status = applicationStatus;
} else {
status = routerQuery.origin;
}
setBackLink(`/admin?tab=${status}`);
};

useEffect(() => {
generateBackLink();
}, []);

// Delete application modal state
const {
isOpen: isDeleteApplicationModalOpen,
Expand All @@ -96,12 +113,13 @@ export default function RequestHeader({

return (
<Box textAlign="left">
<NextLink href="/admin" passHref>
<NextLink href={backLink} passHref>
<Text textStyle="button-semibold" textColor="primary" as="a">
<ChevronLeftIcon />
All requests
</Text>
</NextLink>

<VStack alignItems="stretch">
<Flex marginTop={5} alignItems="baseline" justifyContent="space-between">
<Box>
Expand Down
2 changes: 2 additions & 0 deletions lib/graphql/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ export type ApplicationsReportColumn =
| 'APPLICANT_NAME'
| 'APPLICANT_DATE_OF_BIRTH'
| 'APP_NUMBER'
| 'PHONE_NUMBER'
| 'HOME_ADDRESS'
| 'APPLICATION_DATE'
| 'PAYMENT_METHOD'
| 'FEE_AMOUNT'
Expand Down
27 changes: 24 additions & 3 deletions lib/reports/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ export const generateApplicationsReport: Resolver<
firstName: true,
middleName: true,
lastName: true,
addressLine1: true,
addressLine2: true,
city: true,
province: true,
postalCode: true,
phone: true,
type: true,
createdAt: true,
paymentMethod: true,
Expand Down Expand Up @@ -262,6 +268,10 @@ export const generateApplicationsReport: Resolver<
firstName,
middleName,
lastName,
phone,
addressLine1,
addressLine2,
postalCode,
type,
createdAt,
processingFee,
Expand Down Expand Up @@ -292,6 +302,9 @@ export const generateApplicationsReport: Resolver<
id: applicant?.id,
applicantName: formatFullName(firstName, middleName, lastName),
dateOfBirth: dateOfBirth && formatDateYYYYMMDD(dateOfBirth),
address: formatStreetAddress(addressLine1, addressLine2),
postalCode: formatPostalCode(postalCode),
phone: formatPhoneNumber(phone),
rcdPermitId: permit?.rcdPermitId ? `#${permit.rcdPermitId}` : null,
applicationDate: createdAt ? formatDateYYYYMMDDLocal(createdAt, true) : null,
processingFee: `$${processingFee}`,
Expand All @@ -314,9 +327,17 @@ export const generateApplicationsReport: Resolver<
}
);

const csvHeaders = APPLICATIONS_COLUMNS.filter(({ value }) => columnsSet.has(value)).map(
({ name, reportColumnId }) => ({ id: reportColumnId, title: name })
);
const filteredColumns = APPLICATIONS_COLUMNS.filter(({ value }) => columnsSet.has(value));
const csvHeaders: Array<{ id: string; title: string }> = [];
for (const { name, reportColumnId } of filteredColumns) {
if (typeof reportColumnId === 'string') {
csvHeaders.push({ id: reportColumnId, title: name });
} else {
for (const [columnLabel, columnId] of reportColumnId) {
csvHeaders.push({ id: columnId, title: columnLabel });
}
}
}

// Generate CSV string from csv object.
const csvStringifier = createObjectCsvStringifier({
Expand Down
2 changes: 2 additions & 0 deletions lib/reports/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export default gql`
APPLICANT_NAME
APPLICANT_DATE_OF_BIRTH
APP_NUMBER
PHONE_NUMBER
HOME_ADDRESS
APPLICATION_DATE
PAYMENT_METHOD
FEE_AMOUNT
Expand Down
125 changes: 82 additions & 43 deletions pages/admin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,39 @@ import { formatFullName } from '@lib/utils/format'; // String formatter util
import { formatDateYYYYMMDDLocal } from '@lib/utils/date'; // Date Formatter Util
import EmptyMessage from '@components/EmptyMessage';

interface RouterQuery {
tab?: string;
}

export const getTabIndex = (routerQuery: RouterQuery): number => {
if (routerQuery === undefined || routerQuery.tab === undefined) {
return 1;
}
const tabName = routerQuery.tab;
switch (tabName) {
case 'ALL':
return 0;
case 'PENDING':
return 1;
case 'IN_PROGRESS':
return 2;
case 'COMPLETED':
return 3;
case 'REJECTED':
return 4;
default:
return 1;
}
};

const tabIndexToStatus: { [key: number]: ApplicationStatus | 'ALL' } = {
0: 'ALL',
1: 'PENDING',
2: 'IN_PROGRESS',
3: 'COMPLETED',
4: 'REJECTED',
};

// Placeholder columns
const COLUMNS: Column<ApplicationRow>[] = [
{
Expand Down Expand Up @@ -126,6 +159,7 @@ const PAGE_SIZE = 20;
const Requests: NextPage = () => {
// Router
const router = useRouter();
const routerQuery: RouterQuery = router.query;

// Filters
const [statusFilter, setStatusFilter] = useState<ApplicationStatus | null>('PENDING');
Expand All @@ -145,6 +179,20 @@ const Requests: NextPage = () => {
const [pageNumber, setPageNumber] = useState(0);
const [recordsCount, setRecordsCount] = useState(0);

// Tabs
const [tabIndex, setTabIndex] = useState(0);
const getTabFromRoute = (): number => {
const index = getTabIndex(routerQuery);
setTabIndex(index);
return index;
};

const handleTabChange = () => {
const status = tabIndexToStatus[tabIndex];
setStatusFilter(status === 'ALL' ? null : status);
router.push({ query: { tab: status } });
};

// Make query to applications resolver
const { refetch, loading } = useQuery<GetApplicationsResponse, GetApplicationsRequest>(
GET_APPLICATIONS_QUERY,
Expand Down Expand Up @@ -191,6 +239,16 @@ const Requests: NextPage = () => {
}
);

// Determine the active tab on page load based on the route
useEffect(() => {
getTabFromRoute();
}, []);

useEffect(() => {
if (tabIndex === null) return;
handleTabChange();
}, [tabIndex]);

// Set page number to 0 after every filter or sort change
useEffect(() => {
setPageNumber(0);
Expand Down Expand Up @@ -228,48 +286,19 @@ const Requests: NextPage = () => {
</HStack>
</Flex>
<Box border="1px solid" borderColor="border.secondary" borderRadius="12px" bgColor="white">
<Tabs marginBottom="20px" defaultIndex={1}>
<TabList paddingX="24px">
<Tab
height="64px"
onClick={() => {
setStatusFilter(null);
}}
>
All
</Tab>
<Tab
height="64px"
onClick={() => {
setStatusFilter('PENDING');
}}
>
Pending
</Tab>
<Tab
height="64px"
onClick={() => {
setStatusFilter('IN_PROGRESS');
}}
>
In Progress
</Tab>
<Tab
height="64px"
onClick={() => {
setStatusFilter('COMPLETED');
}}
>
Completed
</Tab>
<Tab
height="64px"
onClick={() => {
setStatusFilter('REJECTED');
}}
>
Rejected
</Tab>
<Tabs
marginBottom="20px"
index={tabIndex}
onChange={index => {
setTabIndex(index);
}}
>
<TabList paddingX="24px" defaultIndex={1}>
<Tab height="64px">All</Tab>
<Tab height="64px">Pending</Tab>
<Tab height="64px">In Progress</Tab>
<Tab height="64px">Completed</Tab>
<Tab height="64px">Rejected</Tab>
</TabList>
</Tabs>
<Box padding="0 24px">
Expand Down Expand Up @@ -379,13 +408,23 @@ const Requests: NextPage = () => {
</Flex>
{requestsData.length > 0 ? (
<>
<Flex justifyContent="flex-end">
<Pagination
pageNumber={pageNumber}
pageSize={PAGE_SIZE}
totalCount={recordsCount}
onPageChange={setPageNumber}
/>
</Flex>
<Table
columns={COLUMNS}
data={requestsData}
loading={loading}
initialSort={sortOrder}
onChangeSortOrder={setSortOrder}
onRowClick={({ id }) => router.push(`/admin/request/${id}`)}
onRowClick={({ id }) =>
router.push(`/admin/request/${id}?origin=${tabIndexToStatus[tabIndex]}`)
}
/>
<Flex justifyContent="flex-end">
<Pagination
Expand Down
1 change: 1 addition & 0 deletions pages/admin/permit-holder/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export default function PermitHolder({ id: idString }: Props) {
status,
inactiveReason: inactiveReason || undefined,
notes: notes || '',
mostRecentApplication: currentApplication,
}}
refetch={refetch}
/>
Expand Down
Loading

0 comments on commit 92a56e3

Please sign in to comment.