Skip to content

Commit

Permalink
enhance(app): improve display of application details with modal (#6)
Browse files Browse the repository at this point in the history
Co-authored-by: Roland Schlaefli <[email protected]>
  • Loading branch information
mxmlnwbr and rschlaefli authored Nov 7, 2023
1 parent 5ee2cbc commit e897848
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 70 deletions.
24 changes: 14 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@trpc/next": "10.37.1",
"@trpc/react-query": "10.37.1",
"@trpc/server": "10.37.1",
"@uzh-bf/design-system": "2.0.12",
"@uzh-bf/design-system": "2.4.3",
"axios": "1.5.1",
"cross-fetch": "3.1.5",
"date-fns": "2.30.0",
Expand Down
82 changes: 82 additions & 0 deletions src/components/ApplicationDetailsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { IconDefinition, faFilePdf } from '@fortawesome/free-regular-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { Button, Modal, Prose } from '@uzh-bf/design-system'
import { add, format, parseISO } from 'date-fns'
import { useState } from 'react'
import { ApplicationDetails } from 'src/types/app'

function ApplicationDetailsModal({ row }: { row: ApplicationDetails }) {
const FileTypeIconMap: Record<string, IconDefinition> = {
'application/pdf': faFilePdf,
}
const [isOpen, setIsOpen] = useState(false)

return (
<Modal
title={`Application by ${row?.fullName}`}
open={isOpen}
trigger={
<Button
onClick={() => {
setIsOpen(true)
}}
>
More
</Button>
}
onClose={() => {
setIsOpen(false)
}}
>
<div className="md:grid md:grid-cols-2">
<div>
<h1 className="text-base font-bold">Full Name:</h1>
<p className="pb-2 text-base">{row?.fullName}</p>
<h1 className="text-base font-bold">Email:</h1>
<p className="pb-2 text-base">{row?.email}</p>
<h1 className="text-base font-bold">Matriculation Number:</h1>
<p className="pb-2 text-base">{row?.matriculationNumber}</p>
</div>
<div>
<h1 className="text-base font-bold">Status:</h1>
<p className="pb-2 text-base">{row?.statusKey}</p>
<h1 className="text-base font-bold">Working Period:</h1>
<p className="pb-2 text-base">
{format(parseISO(row.plannedStartAt), 'dd.MM.Y')} -{' '}
{format(
add(parseISO(row.plannedStartAt), {
months: 6,
}),
'dd.MM.Y'
)}
</p>

<h1 className="text-base font-bold">Attachments:</h1>
<div className="grid grid-cols-1 pb-2 text-base">
{row?.attachments?.map((attachment: any) => (
<div key={attachment.id}>
<a
href={attachment.href}
target="_blank"
className="hover:text-orange-700"
rel="noreferrer"
>
<div className="flex flex-row items-center gap-2">
<FontAwesomeIcon icon={FileTypeIconMap[attachment.type]} />
{attachment.name}
</div>
</a>
</div>
))}
</div>
</div>
</div>
<div>
<h1 className="text-base font-bold">Motivation:</h1>
<Prose className={{ root: 'max-w-none' }}>{row?.motivation}</Prose>
</div>
</Modal>
)
}

export default ApplicationDetailsModal
69 changes: 10 additions & 59 deletions src/components/ProposalApplication.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import {
IconDefinition,
faFilePdf,
faMessage,
} from '@fortawesome/free-regular-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { H2, Table } from '@uzh-bf/design-system'
import { add, format, parseISO } from 'date-fns'
import { ProposalDetails } from 'src/types/app'
import { IterableElement } from 'type-fest'
import { ApplicationDetails, ProposalDetails } from 'src/types/app'
import ApplicationDetailsModal from './ApplicationDetailsModal'
import ApplicationForm from './ApplicationForm'

interface ProposalApplicationProps {
Expand All @@ -21,9 +15,6 @@ export default function ProposalApplication({
isStudent,
isSupervisor,
}: ProposalApplicationProps) {
const FileTypeIconMap: Record<string, IconDefinition> = {
'application/pdf': faFilePdf,
}
if (proposalDetails?.typeKey === 'SUPERVISOR') {
return (
<div className="p-4">
Expand All @@ -40,7 +31,7 @@ export default function ProposalApplication({
{proposalDetails?.applications?.length === 0 &&
'No applications for this proposal...'}
{proposalDetails?.applications?.length > 0 && (
<Table<IterableElement<(typeof proposalDetails)['applications']>>
<Table<ApplicationDetails>
className={{
root: 'text-xs',
tableHeader: 'text-sm',
Expand All @@ -49,14 +40,14 @@ export default function ProposalApplication({
{
label: 'Date',
accessor: 'createdAt',
sortable: true,
transformer: ({ row }) =>
format(parseISO(row.createdAt), 'dd.MM.Y'),
format(parseISO(row.createdAt), 'dd.MM.yyyy'),
},
{
label: 'Status',
accessor: 'status',
label: 'Email',
accessor: 'email',
sortable: true,
transformer: ({ row }) => <div>{row.statusKey}</div>,
},
{
label: 'Working Period',
Expand All @@ -72,50 +63,10 @@ export default function ProposalApplication({
)}`,
},
{
label: 'Name',
accessor: 'fullName',
sortable: true,
transformer: ({ row }) => (
<a
href={`mailto:${row.email}`}
target="_blank"
className="flex flex-row items-center gap-2 hover:text-orange-700"
rel="noreferrer"
>
<FontAwesomeIcon icon={faMessage} />
{row.fullName}
</a>
),
},
{
label: 'Motivation',
accessor: 'motivation',
transformer: ({ row }) => (
<div className="text-xs break-all">{row.motivation}</div>
),
},
{
label: 'Attachments',
accessor: 'attachments',
label: 'Details',
accessor: 'details',
transformer: ({ row }) => (
<div>
{row.attachments?.map((attachment: any) => (
<a
href={attachment.href}
target="_blank"
key={attachment.id}
className="hover:text-orange-700"
rel="noreferrer"
>
<div className="flex flex-row items-center gap-2">
<FontAwesomeIcon
icon={FileTypeIconMap[attachment.type]}
/>
{attachment.name}
</div>
</a>
))}
</div>
<ApplicationDetailsModal row={row} />
),
},
]}
Expand Down
1 change: 1 addition & 0 deletions src/types/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ type RouterOutput = inferRouterOutputs<AppRouter>

type ProposalsOutput = RouterOutput['proposals']
type ProposalDetails = IterableElement<ProposalsOutput>
type ApplicationDetails = IterableElement<ProposalDetails['applications']>

0 comments on commit e897848

Please sign in to comment.