Skip to content

Commit

Permalink
donations/grid: Allow admins to edit billingEmail (#1461)
Browse files Browse the repository at this point in the history
* donations/grid: Allow admins to edit billingEmail
Currently billingEmail is used to link all anonymous donations to a specific user profile. Unfortunately when user donates via bank transaction, and prefers the donation to be anonymous, there is no way to link that donation to user's profile.
This commits allows billingEmail to be either set or edited manually, thus linking anonymous donations to user's profile

* RendedEditBillingEmailCell.tsx: Rename the default function
  • Loading branch information
sashko9807 authored Jul 3, 2023
1 parent 30d7062 commit 62e12ce
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 2 deletions.
42 changes: 40 additions & 2 deletions src/components/admin/donations/grid/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { PersonResponse } from 'gql/person'
import { usePersonList } from 'common/hooks/person'
import RenderEditPersonCell from './RenderEditPersonCell'
import { useStores } from '../../../../common/hooks/useStores'
import RenderEditBillingEmailCell from './RenderEditBillingEmailCell'

interface RenderCellProps {
params: GridRenderCellParams
Expand Down Expand Up @@ -97,6 +98,34 @@ export default observer(function Grid() {
)
}

const RenderBillingEmaiCell = ({ params }: RenderCellProps) => {
return (
<>
<Box sx={{ display: 'flex', justifyContent: 'space-between', width: '100%' }}>
{params.row.billingEmail}
{params.isEditable ? (
<Tooltip title={t('donations:cta.edit')}>
<Edit
sx={addIconStyles}
color="action"
fontSize="medium"
onClick={() => {
if (focusedRowId) {
params.api.startCellEditMode({ id: params.row.id, field: params.field })
}
params.api.getCellMode(params.row.id, params.field)
setFocusedRowId(params.row.id)
}}
/>
</Tooltip>
) : (
<></>
)}
</Box>
</>
)
}

const RenderMoneyCell = ({ params }: RenderCellProps) => {
return <>{money(params.row.amount, params.row.currency)}</>
}
Expand Down Expand Up @@ -155,11 +184,20 @@ export default observer(function Grid() {
{
field: 'billingEmail',
headerName: 'Billing Email',
width: 250,
width: 300,
editable: true,
renderCell: (params: GridRenderCellParams) => {
return <RenderBillingEmaiCell params={params} />
},

renderEditCell: (params: GridRenderEditCellParams) => {
return <RenderEditBillingEmailCell params={params} personList={data} onUpdate={refetch} />
},
},
{
field: 'id',
headerName: 'ID',
width: 320,
},
{
field: 'type',
Expand All @@ -169,7 +207,7 @@ export default observer(function Grid() {
field: 'provider',
headerName: t('donations:provider'),
...commonProps,
width: 250,
width: 100,
},
{
field: 'targetVaultId',
Expand Down
111 changes: 111 additions & 0 deletions src/components/admin/donations/grid/RenderEditBillingEmailCell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React from 'react'
import { AxiosError, AxiosResponse } from 'axios'
import { useMutation } from '@tanstack/react-query'
import { useTranslation } from 'next-i18next'
import { GridRenderEditCellParams } from '@mui/x-data-grid'
import { TextField, Tooltip, Box } from '@mui/material'
import Autocomplete from '@mui/material/Autocomplete'
import { Save } from '@mui/icons-material'
import { PersonResponse } from 'gql/person'
import { DonationResponse, UserDonationInput } from 'gql/donations'
import { useEditDonation } from 'service/donation'
import { ApiErrors } from 'service/apiErrors'
import { AlertStore } from 'stores/AlertStore'

interface RenderEditCellProps {
params: GridRenderEditCellParams
personList?: PersonResponse[]
onUpdate(): void
}
const addIconStyles = {
background: '#4ac3ff',
borderRadius: '50%',
cursor: 'pointer',
padding: 0.7,
boxShadow: 3,
}

export default function RenderEditBillingEmailCell({
params,
personList,
onUpdate,
}: RenderEditCellProps) {
const { t } = useTranslation()

const initialPerson = {
firstName: params.row.billingEmail,
lastName: '',
email: params.row.email || params.row.billingEmail || null,
}
const [person, setPerson] = React.useState<PersonResponse | null>({
...initialPerson,
} as PersonResponse)
const mutationFn = useEditDonation(params.row.id)

const mutation = useMutation<
AxiosResponse<DonationResponse>,
AxiosError<ApiErrors>,
UserDonationInput
>({
mutationFn,
onError: () => AlertStore.show(t('donations:alerts.error'), 'error'),
onSuccess: () => {
AlertStore.show(t('donations:alerts.editDonor'), 'success')
onUpdate()
params.api.stopCellEditMode({ id: params.row.id, field: params.field })
},
})

const onClick = () => {
if (person) {
const donationData: UserDonationInput = params.row
donationData.billingEmail = person.email
mutation.mutate(donationData)
} else {
AlertStore.show(t('donations:alerts.requiredError'), 'error')
}
}

return (
<Box
sx={{ display: 'flex', alignItems: 'center', width: '100%', padding: 0.7, overflow: 'auto' }}>
<Autocomplete
id="edit-person-cell"
sx={{ width: 300 }}
value={person}
ListboxProps={{ style: { maxHeight: 300 } }}
onChange={(event, newValue: PersonResponse | null) => {
setPerson(newValue)
}}
options={personList || []}
getOptionLabel={(option: PersonResponse) => `${option.email}`}
renderInput={(params) => <TextField {...params} variant="standard" fullWidth />}
renderOption={(params, option: PersonResponse) => (
<Box component="li" {...params} key={option.id}>
{`${option.firstName} ${option.lastName} (${option.email ? option.email : ''})`}
</Box>
)}
isOptionEqualToValue={(option, value) => option.email === value.email}
filterOptions={(options, state) => {
const displayOptions = options.filter(
(option) =>
option.firstName
.toLowerCase()
.trim()
.includes(state.inputValue.toLowerCase().trim()) ||
option.email.toLowerCase().trim().includes(state.inputValue.toLowerCase().trim()),
)

return displayOptions
}}
clearText={t('donations:cta.clear')}
noOptionsText={t('donations:noOptions')}
openText={t('donations:cta.open')}
closeText={t('donations:cta.close')}
/>
<Tooltip title={t('donations:cta.save')}>
<Save sx={addIconStyles} color="action" fontSize="medium" onClick={onClick} />
</Tooltip>
</Box>
)
}
1 change: 1 addition & 0 deletions src/gql/donations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export type DonationInput = {
}
export type UserDonationInput = DonationInput & {
targetPersonId?: UUID
billingEmail?: string
}

export type DonationBankInput = {
Expand Down

0 comments on commit 62e12ce

Please sign in to comment.