Skip to content

Commit

Permalink
Admin can edit donations details imported from bank transfer (#1097)
Browse files Browse the repository at this point in the history
* added: admin can edit donor in donations grid

* fixed: edit donor cell visible only when edit mode is on

* added: update grid on edited person cell; add translations

* fixed: edit cell only if provider is bank

Co-authored-by: Margarita <[email protected]>
  • Loading branch information
2 people authored and slavcho committed Nov 13, 2022
1 parent 2fd05aa commit c62e098
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 24 deletions.
11 changes: 9 additions & 2 deletions public/locales/bg/donations.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
"createdAt": "Направено на",
"bankTransactionsFileId": "Номер на файла с банкови транзакции",
"addFiles": "Добави файлове",
"noOptions": "Няма резултати",
"alerts": {
"selectRow": "Моля изберете ред",
"create": "Дарението беше създадено успешно!",
"edit": "Дарението беше редактирано успешно!",
"delete": "Дарението беше изтрито успешно!",
"deleteAll": "Даренията бяха изтрити успешно!",
"error": "Възникна грешка! Моля опитайте отново по-късно."
"editDonor": "Дарителят беше редактиран успешно!",
"error": "Възникна грешка! Моля опитайте отново по-късно.",
"requiredError": "Полето е задължително."
},
"cta": {
"add": "Добави",
Expand All @@ -40,6 +43,10 @@
"deleteSelected": "Изтрий избраните редове",
"edit": "Редактирай",
"details": "Детайли за дарение",
"submit": "Изпрати"
"submit": "Изпрати",
"save": "Запиши",
"open": "Отвори",
"clear": "Изчисти",
"close": "Затвори"
}
}
11 changes: 9 additions & 2 deletions public/locales/en/donations.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
"addFiles": "Add files",
"actions": "Actions",
"createdAt": "Created at",
"noOptions": "No results",
"alerts": {
"selectRow": "Please choose a row",
"create": "Document has been created successfully!",
"edit": "Document has been edited successfully!",
"delete": "Document has been deleted successfully!",
"deleteAll": "Documents have been deleted successfully!",
"error": "An error has occured! Please try again later."
"editDonor": "Donation donor has been edited successfully!",
"error": "An error has occured! Please try again later.",
"requiredError": "Fields is required!"
},
"cta": {
"add": "Add",
Expand All @@ -40,6 +43,10 @@
"deleteSelected": "Delete selected rows",
"edit": "Edit",
"details": "Donation Details",
"submit": "Submit"
"submit": "Submit",
"save": "Save",
"open": "Open",
"clear": "Clear",
"close": "Close"
}
}
62 changes: 55 additions & 7 deletions src/components/donations/grid/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import React, { useState } from 'react'
import { UseQueryResult } from 'react-query'
import { useTranslation } from 'next-i18next'
import { Box } from '@mui/material'
import { DataGrid, GridColDef, GridColumns, GridRenderCellParams } from '@mui/x-data-grid'
import { Box, Tooltip } from '@mui/material'
import { Edit } from '@mui/icons-material'
import {
DataGrid,
GridCellModes,
GridColDef,
GridColumns,
GridRenderCellParams,
GridRenderEditCellParams,
} from '@mui/x-data-grid'
import { observer } from 'mobx-react'

import { routes } from 'common/routes'
import { useDonationsList } from 'common/hooks/donation'
import GridActions from 'components/admin/GridActions'

import DetailsModal from '../modals/DetailsModal'
import DeleteModal from '../modals/DeleteModal'
Expand All @@ -16,14 +22,25 @@ import { getExactDateTime } from 'common/util/date'
import { useRouter } from 'next/router'
import { money } from 'common/util/money'
import { CampaignDonationHistoryResponse } from 'gql/campaigns'
import { PersonResponse } from 'gql/person'
import { usePersonList } from 'common/hooks/person'
import RenderEditPersonCell from './RenderEditPersonCell'

interface RenderCellProps {
params: GridRenderCellParams
}

const addIconStyles = {
background: '#4ac3ff',
borderRadius: '50%',
cursor: 'pointer',
padding: 0.7,
boxShadow: 3,
}
export default observer(function Grid() {
const [pageSize, setPageSize] = useState(5)
const [page, setPage] = useState<number>(0)
const [focusedRowId, setFocusedRowId] = useState(null as string | null)

const { t } = useTranslation()
const router = useRouter()
const { isDetailsOpen } = ModalStore
Expand All @@ -32,16 +49,42 @@ export default observer(function Grid() {
data: { items: donations, total: all_rows } = { items: [], total: 0 },
error: donationHistoryError,
isLoading: isDonationHistoryLoading,
refetch,
}: UseQueryResult<CampaignDonationHistoryResponse> = useDonationsList(campaignId, page, pageSize)

const { data }: UseQueryResult<PersonResponse[]> = usePersonList()
const RenderVaultCell = ({ params }: RenderCellProps) => {
return <>{params.row.targetVault.name}</>
}
const RenderPersonCell = ({ params }: RenderCellProps) => {
const { firstName, lastName } = params.row.person
? params.row.person
: { firstName: 'Anonymous', lastName: 'Donor' }
return <>{firstName + ' ' + lastName}</>
return (
<>
<Box sx={{ display: 'flex', justifyContent: 'space-between', width: '100%' }}>
{firstName + ' ' + lastName}
{params.isEditable ? (
<Tooltip title={t('donations:cta.edit')}>
<Edit
sx={addIconStyles}
color="action"
fontSize="medium"
onClick={() => {
if (focusedRowId) {
params.api.setCellMode(focusedRowId, params.field, GridCellModes.View)
}
params.api.setCellMode(params.row.id, params.field, GridCellModes.Edit)
setFocusedRowId(params.row.id)
}}
/>
</Tooltip>
) : (
<></>
)}
</Box>
</>
)
}

const RenderMoneyCell = ({ params }: RenderCellProps) => {
Expand Down Expand Up @@ -85,10 +128,14 @@ export default observer(function Grid() {
field: 'person',
headerName: t('donations:person'),
...commonProps,
width: 250,
editable: true,
width: 280,
renderCell: (params: GridRenderCellParams) => {
return <RenderPersonCell params={params} />
},
renderEditCell: (params: GridRenderEditCellParams) => {
return <RenderEditPersonCell params={params} personList={data} onUpdate={refetch} />
},
},
{
field: 'billingName',
Expand Down Expand Up @@ -155,6 +202,7 @@ export default observer(function Grid() {
paginationMode="server"
rowCount={all_rows}
disableSelectionOnClick
isCellEditable={(params) => params.row.provider.includes('bank')}
/>
</Box>

Expand Down
105 changes: 105 additions & 0 deletions src/components/donations/grid/RenderEditPersonCell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React from 'react'
import { AxiosError, AxiosResponse } from 'axios'
import { useMutation } from 'react-query'
import { useTranslation } from 'next-i18next'
import { GridRenderEditCellParams, GridCellModes } from '@mui/x-data-grid'
import { Autocomplete, createFilterOptions, TextField, Tooltip, Box } from '@mui/material'
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 RenderEditPersonCell({
params,
personList,
onUpdate,
}: RenderEditCellProps) {
const { t } = useTranslation()

const initialPerson = {
firstName:
params.row.person && params.row.person.firstName ? params.row.person.firstName : 'Anonymous',
lastName:
params.row.person && params.row.person.lastName ? params.row.person.lastName : 'Donor',
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.setCellMode(params.row.id, params.field, GridCellModes.View)
},
})

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

return (
<Box sx={{ display: 'flex', alignItems: 'center', width: '100%', padding: 0.7 }}>
<Autocomplete
id="edit-person-cell"
sx={{ width: 300 }}
value={person}
onChange={(event, newValue: PersonResponse | null) => {
setPerson(newValue)
}}
options={personList || []}
getOptionLabel={(option: PersonResponse) => `${option.firstName} ${option.lastName}`}
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.firstName === value.firstName}
filterOptions={createFilterOptions<PersonResponse>({
matchFrom: 'any',
limit: 5,
ignoreCase: true,
trim: true,
})}
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>
)
}
4 changes: 4 additions & 0 deletions src/gql/donations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ export type DonationInput = {
extPaymentMethodId: string
// personId: UUID
}
export type UserDonationInput = DonationInput & {
targetPersonId?: UUID
}

export type DonationBankInput = {
currency: string
amount: number
Expand Down
3 changes: 2 additions & 1 deletion src/service/donation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
DonationBankInput,
DonationInput,
DonationResponse,
UserDonationInput,
} from 'gql/donations'
import { apiClient } from 'service/apiClient'
import { endpoints } from 'service/apiEndpoints'
Expand Down Expand Up @@ -44,7 +45,7 @@ export function useCreateBankDonation() {

export function useEditDonation(id: string) {
const { data: session } = useSession()
return async (data: DonationInput) => {
return async (data: UserDonationInput) => {
return await apiClient.patch<DonationResponse, AxiosResponse<DonationResponse>>(
endpoints.donation.editDonation(id).url,
data,
Expand Down
12 changes: 0 additions & 12 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6266,11 +6266,6 @@ pegjs@^0.10.0:
resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd"
integrity sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=

performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=

picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
Expand Down Expand Up @@ -6595,13 +6590,6 @@ quill@^1.3.7, quill@^1.x:
parchment "^1.1.4"
quill-delta "^3.6.2"

raf@^3.4.0:
version "3.4.1"
resolved "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz"
integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
dependencies:
performance-now "^2.1.0"

ramda@^0.26.1:
version "0.26.1"
resolved "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz"
Expand Down

0 comments on commit c62e098

Please sign in to comment.