Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 32 additions & 21 deletions pages/profile/history.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,39 @@ import { ErrorHandlingContext } from '../../src/features/common/Layout/ErrorHand

const { useTranslation } = i18next;

interface Props { }
interface Props {}

function AccountHistory({ }: Props): ReactElement {
function AccountHistory({}: Props): ReactElement {
const { t } = useTranslation(['me']);
const { token, contextLoaded } = React.useContext(UserPropsContext);
const [progress, setProgress] = React.useState(0);
const [isDataLoading, setIsDataLoading] = React.useState(false);
const [filter, setFilter] = React.useState<string | null>(null);
const [paymentHistory, setpaymentHistory] = React.useState<Payments.PaymentHistory | null>(null);
const [accountingFilters, setaccountingFilters] = React.useState<Payments.Filters | null>(null);
const [paymentHistory, setpaymentHistory] =
React.useState<Payments.PaymentHistory | null>(null);
const [accountingFilters, setaccountingFilters] =
React.useState<Payments.Filters | null>(null);

const { handleError } = React.useContext(ErrorHandlingContext);

async function fetchPaymentHistory(next = false): Promise<void> {
setIsDataLoading(true);
setProgress(70);
if (next && paymentHistory?._links?.next) {
const newPaymentHistory: Payments.PaymentHistory = await getAuthenticatedRequest(
paymentHistory._links.next,
token,
{},
handleError,
'/profile'
);
const newPaymentHistory: Payments.PaymentHistory =
await getAuthenticatedRequest(
`${
filter && accountingFilters
? accountingFilters[filter] +
'&' +
paymentHistory?._links?.next.split('?').pop()
: paymentHistory?._links?.next
}`,
token,
{},
handleError,
'/profile'
);
setpaymentHistory({
...paymentHistory,
items: [...paymentHistory.items, ...newPaymentHistory.items],
Expand All @@ -45,23 +54,25 @@ function AccountHistory({ }: Props): ReactElement {
setTimeout(() => setProgress(0), 1000);
} else {
if (filter === null) {
const paymentHistory: Payments.PaymentHistory = await getAuthenticatedRequest(
'/app/paymentHistory?limit=15',
token,
{},
handleError,
'/profile'
);
const paymentHistory: Payments.PaymentHistory =
await getAuthenticatedRequest(
'/app/paymentHistory?limit=15',
token,
{},
handleError,
'/profile'
);
setpaymentHistory(paymentHistory);
setProgress(100);
setIsDataLoading(false);
setTimeout(() => setProgress(0), 1000);
setaccountingFilters(paymentHistory._filters);
} else {
const paymentHistory = await getAuthenticatedRequest(
`${filter && accountingFilters
? accountingFilters[filter] + '&limit=15'
: '/app/paymentHistory?limit=15'
`${
filter && accountingFilters
? accountingFilters[filter] + '&limit=15'
: '/app/paymentHistory?limit=15'
}`,
token,
{},
Expand Down
2 changes: 2 additions & 0 deletions public/static/locales/de/me.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"tree-donation": "Baumspende",
"tree-gift": "Baumgeschenk",
"tree-cash": "TreeCash",
"planet-cash": "PlanetCash",
"trees": "Bäume",
"amount": "Betrag",
"created": "Erstellungsdatum",
Expand Down Expand Up @@ -169,6 +170,7 @@
"unknown-method": "Unbekannt",
"stripe-sofort": "Sofort (Stripe)",
"tree-cash-tree-cash": "TreeCash",
"planet-cash-planet-cash": "PlanetCash",
"stripe-card": "Kreditkarte",
"stripe-giropay": "GiroPay (Stripe)",
"action-required": "Maßnahme erforderlich",
Expand Down
2 changes: 2 additions & 0 deletions public/static/locales/en/me.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"tree-donation": "Tree Donation",
"tree-gift": "Tree Gift",
"tree-cash": "TreeCash",
"planet-cash": "PlanetCash",
"trees": "Trees",
"amount": "Amount",
"created": "Date Created",
Expand Down Expand Up @@ -169,6 +170,7 @@
"unknown-method": "Unknown",
"stripe-sofort": "Sofort (Stripe)",
"tree-cash-tree-cash": "TreeCash",
"planet-cash-planet-cash": "PlanetCash",
"stripe-card": "Credit/Debit Card",
"stripe-giropay": "GiroPay (Stripe)",
"action-required": "Action Required",
Expand Down
6 changes: 3 additions & 3 deletions src/features/user/Account/History.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,9 @@ export default function History({
/>
)}
{showStatusNote(currentRecord, t)}
{(currentRecord.details.donorCertificate ||
currentRecord.details.taxDeductibleReceipt ||
currentRecord.details.giftCertificate) && (
{(currentRecord?.details?.donorCertificate ||
currentRecord?.details?.taxDeductibleReceipt ||
currentRecord?.details?.giftCertificate) && (
<>
<div className={styles.title}>{t('downloads')}</div>
<div className={styles.detailGrid}>
Expand Down
118 changes: 78 additions & 40 deletions src/features/user/Account/components/AccountRecord.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ export default function AccountRecord({
return (
<div
key={index}
className={`${styles.record} ${selectedRecord === index ? styles.selected : ''
}`}
className={`${styles.record} ${
selectedRecord === index ? styles.selected : ''
}`}
>
<RecordHeader record={record} handleRecordOpen={handleRecordOpen} index={index} />
<RecordHeader
record={record}
handleRecordOpen={handleRecordOpen}
index={index}
/>
{index !== paymentHistory?.items?.length - 1 && (
<div className={styles.divider} />
)}
Expand All @@ -51,16 +56,16 @@ export default function AccountRecord({
<TransferDetails account={record.details.account} />
)}
{showStatusNote(record, t)}
{(record.details.donorCertificate ||
record.details.taxDeductibleReceipt ||
record.details.giftCertificate) && (
<>
<div className={styles.title}>{t('downloads')}</div>
<div className={styles.detailGrid}>
<Certificates recordDetails={record.details} />
</div>
</>
)}
{(record?.details?.donorCertificate ||
record?.details?.taxDeductibleReceipt ||
record?.details?.giftCertificate) && (
<>
<div className={styles.title}>{t('downloads')}</div>
<div className={styles.detailGrid}>
<Certificates recordDetails={record.details} />
</div>
</>
)}
Comment on lines +59 to +68

@norbertschuler norbertschuler Apr 9, 2022

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this software with the production backend as I have a conversation donation done there. Unfortunately this of course can not solve the issue if the backend returns a link to a certificate, e.g. https://app.plant-for-the-planet.org/certificate/BYYRKSKQ4891 which then result into an error TCPDF ERROR: [Image] Unable to get the size of the image: /tmp/certyLJv9q.

Bildschirmfoto 2022-04-09 um 11 14 49

</div>
</div>
);
Expand All @@ -72,27 +77,48 @@ interface HeaderProps {
index?: number;
}

export function RecordHeader({ record, handleRecordOpen, index }: HeaderProps): ReactElement {
export function RecordHeader({
record,
handleRecordOpen,
index,
}: HeaderProps): ReactElement {
const { t, i18n } = useTranslation(['me']);
const getRecordTitle = (): ReactElement => {
switch (record.type) {
case 'tree-donation':
return <p className={styles.top}>{`${getFormattedNumber(i18n.language, record.quantity)} ${t(record.type)}`}</p>;
return (
<p className={styles.top}>{`${getFormattedNumber(
i18n.language,
record.quantity
)} ${t(record.type)}`}</p>
);
case 'tree-gift':
return <p className={styles.top}>{`${getFormattedNumber(i18n.language, record.quantity)} ${t(record.type)}`}</p>;
return (
<p className={styles.top}>{`${getFormattedNumber(
i18n.language,
record.quantity
)} ${t(record.type)}`}</p>
);
case 'funds-donation':
case 'bouquet-donation':
case 'conservation-donation':
if (record.details.project.length > 42)
return <p title={record.details.project} className={styles.top}>{`${record.details.project.substring(0, 42)}...`}</p>;
else
return <p className={styles.top}>{record.details.project}</p>;
return (
<p
title={record.details.project}
className={styles.top}
>{`${record.details.project.substring(0, 42)}...`}</p>
);
else return <p className={styles.top}>{record.details.project}</p>;
default:
return <p className={styles.top}>{`${t(record.type)}`}</p>;
}
};
return (
<div onClick={() => handleRecordOpen(index)} className={styles.recordHeader}>
<div
onClick={() => handleRecordOpen(index)}
className={styles.recordHeader}
>
<div className={styles.left}>
{getRecordTitle()}
<p>{formatDate(record.created)}</p>
Expand All @@ -105,9 +131,11 @@ export function RecordHeader({ record, handleRecordOpen, index }: HeaderProps):
record.netAmount / 100
)}
</p>
<p className={`${styles.recordStatus} ${styles[record.status]}`}>{t(record.status)}</p>
<p className={`${styles.recordStatus} ${styles[record.status]}`}>
{t(record.status)}
</p>
</div>
</div >
</div>
);
}

Expand Down Expand Up @@ -184,9 +212,17 @@ export function DetailsComponent({ record }: DetailProps): ReactElement {
<div className={styles.singleDetail}>
<p className={styles.title}>{t('project')}</p>
{record.projectGuid ? (
<a title={record.details.project} href={`/${record.projectGuid}`}>{record.details.project.length > 42 ? record.details.project.substring(0, 42) : record.details.project}</a>
<a title={record.details.project} href={`/${record.projectGuid}`}>
{record.details.project.length > 42
? record.details.project.substring(0, 42)
: record.details.project}
</a>
) : (
<p title={record.details.project}>{record.details.project.length > 42 ? record.details.project.substring(0, 42) + '...' : record.details.project}</p>
<p title={record.details.project}>
{record.details.project.length > 42
? record.details.project.substring(0, 42) + '...'
: record.details.project}
</p>
)}
</div>
)}
Expand All @@ -213,7 +249,9 @@ export function DetailsComponent({ record }: DetailProps): ReactElement {
)}
</p>
</div>
) : []}
) : (
[]
)}
{/* {record.projectGuid && (
<div className={styles.singleDetail}>
<p className={styles.title}>{t('projectGuid')}</p>
Expand Down Expand Up @@ -278,7 +316,10 @@ export function DetailsComponent({ record }: DetailProps): ReactElement {
);
}

export const showStatusNote = (record: Payments.PaymentHistoryRecord, t: TFunction): ReactElement => {
export const showStatusNote = (
record: Payments.PaymentHistoryRecord,
t: TFunction
): ReactElement => {
const showDonationNote = (): string => {
switch (record.details.method) {
case 'stripe-sofort':
Expand All @@ -288,20 +329,18 @@ export const showStatusNote = (record: Payments.PaymentHistoryRecord, t: TFuncti
default:
return '';
}
}
};
switch (record.status) {
case 'pending':
return (
<p className={styles.donationNote}>{showDonationNote()}</p>
);
return <p className={styles.donationNote}>{showDonationNote()}</p>;
case 'in-dispute':
return (
<p className={styles.donationNote}>{t('me:donationNote.in-dispute')}</p>
);
default:
return <></>;
}
}
};

interface BankDetailsProps {
recipientBank: Payments.RecipientBank;
Expand Down Expand Up @@ -350,11 +389,7 @@ export function BankDetails({ recipientBank }: BankDetailsProps): ReactElement {
{recipientBank?.isDefault && (
<div className={styles.singleDetail}>
<p className={styles.title}>{t('isDefault')}</p>
<p>
{Number(recipientBank.isDefault) === 0
? t('no')
: t('yes')}
</p>
<p>{Number(recipientBank.isDefault) === 0 ? t('no') : t('yes')}</p>
</div>
)}
{recipientBank?.created && (
Expand All @@ -373,12 +408,13 @@ export function BankDetails({ recipientBank }: BankDetailsProps): ReactElement {
);
}


interface TransferDetailsProps {
account: Payments.BankAccount;
}

export function TransferDetails({ account }: TransferDetailsProps): ReactElement {
export function TransferDetails({
account,
}: TransferDetailsProps): ReactElement {
const { t, i18n } = useTranslation(['me']);
return (
<>
Expand Down Expand Up @@ -423,14 +459,16 @@ interface CertificatesProps {
recordDetails: Payments.PaymentDetails;
}

export function Certificates({ recordDetails }: CertificatesProps): ReactElement {
export function Certificates({
recordDetails,
}: CertificatesProps): ReactElement {
const { t, i18n } = useTranslation(['me']);
return (
<>
{recordDetails?.donorCertificate && (
<div className={styles.singleDetail}>
<a
href={recordDetails.donorCertificate}
href={recordDetails?.donorCertificate}
target="_blank"
rel="noreferrer"
>
Expand Down