From 301344303fa1af9c538ba90ef13d3e290090dd8a Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 21 Jan 2025 12:24:36 +0530 Subject: [PATCH 01/31] feat: add DonationReceipt page --- .../[slug]/[locale]/donation-receipt.tsx | 79 +++++++++++++++++++ .../user/TaxReceipt/DonationReceiptLayout.tsx | 9 +++ 2 files changed, 88 insertions(+) create mode 100644 pages/sites/[slug]/[locale]/donation-receipt.tsx create mode 100644 src/features/user/TaxReceipt/DonationReceiptLayout.tsx diff --git a/pages/sites/[slug]/[locale]/donation-receipt.tsx b/pages/sites/[slug]/[locale]/donation-receipt.tsx new file mode 100644 index 000000000..8ef1ca2fa --- /dev/null +++ b/pages/sites/[slug]/[locale]/donation-receipt.tsx @@ -0,0 +1,79 @@ +import type { + GetStaticPaths, + GetStaticProps, + GetStaticPropsContext, + GetStaticPropsResult, +} from 'next'; +import type { AbstractIntlMessages } from 'next-intl'; +import type { Tenant } from '@planet-sdk/common/build/types/tenant'; + +import { useEffect } from 'react'; +import { useRouter } from 'next/router'; +import { + constructPathsForTenantSlug, + getTenantConfig, +} from '../../../../src/utils/multiTenancy/helpers'; +import getMessagesForPage from '../../../../src/utils/language/getMessagesForPage'; +import { defaultTenant } from '../../../../tenant.config'; +import { useTenant } from '../../../../src/features/common/Layout/TenantContext'; +import DonationReceiptLayout from '../../../../src/features/user/TaxReceipt/DonationReceiptLayout'; + +interface PageProps { + messages: AbstractIntlMessages; + tenantConfig: Tenant; +} + +interface Props { + pageProps: PageProps; +} + +export default function DonationReceipt({ + pageProps: { tenantConfig }, +}: Props) { + const router = useRouter(); + const { setTenantConfig } = useTenant(); + + useEffect(() => { + if (router.isReady) setTenantConfig(tenantConfig); + }, [router.isReady]); + + return ; +} + +export const getStaticPaths: GetStaticPaths = async () => { + const subDomainPaths = await constructPathsForTenantSlug(); + + const paths = + subDomainPaths?.map((path) => { + return { + params: { + slug: path.params.slug, + locale: 'en', + }, + }; + }) ?? []; + + return { + paths, + fallback: 'blocking', + }; +}; + +export const getStaticProps: GetStaticProps = async ( + context: GetStaticPropsContext +): Promise> => { + const tenantConfig = + (await getTenantConfig(context.params?.slug as string)) ?? defaultTenant; + + const messages = await getMessagesForPage({ + locale: context.params?.locale as string, + filenames: ['common', 'me', 'country', 'donate'], + }); + + return { + props: { + messages, + tenantConfig, + }, + }; +}; diff --git a/src/features/user/TaxReceipt/DonationReceiptLayout.tsx b/src/features/user/TaxReceipt/DonationReceiptLayout.tsx new file mode 100644 index 000000000..b4c802835 --- /dev/null +++ b/src/features/user/TaxReceipt/DonationReceiptLayout.tsx @@ -0,0 +1,9 @@ +export const DonationReceiptLayout = () => { + return ( +
+
+
+ ); +}; + +export default DonationReceiptLayout; From e75accc108ca9faaf501a4a1aa267c444d8af072 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:28:17 +0530 Subject: [PATCH 02/31] feat(UI): add DonationReceiptLayout component with header, data, and footer sections for donation receipt page --- .../[slug]/[locale]/donation-receipt.tsx | 2 +- public/static/locales/en/donate.json | 7 ++- .../DonationReceipt/DonationReceiptLayout.tsx | 21 +++++++++ .../donationReceipt.module.scss | 43 +++++++++++++++++++ .../microComponents/ReceiptDataSection.tsx | 11 +++++ .../microComponents/ReceiptFooterSection.tsx | 9 ++++ .../ReceiptVerificationHeader.tsx | 24 +++++++++++ src/features/user/DonationReceipt/utils.ts | 31 +++++++++++++ .../user/TaxReceipt/DonationReceiptLayout.tsx | 9 ---- 9 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 src/features/user/DonationReceipt/DonationReceiptLayout.tsx create mode 100644 src/features/user/DonationReceipt/donationReceipt.module.scss create mode 100644 src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx create mode 100644 src/features/user/DonationReceipt/microComponents/ReceiptFooterSection.tsx create mode 100644 src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx create mode 100644 src/features/user/DonationReceipt/utils.ts delete mode 100644 src/features/user/TaxReceipt/DonationReceiptLayout.tsx diff --git a/pages/sites/[slug]/[locale]/donation-receipt.tsx b/pages/sites/[slug]/[locale]/donation-receipt.tsx index 8ef1ca2fa..941789b78 100644 --- a/pages/sites/[slug]/[locale]/donation-receipt.tsx +++ b/pages/sites/[slug]/[locale]/donation-receipt.tsx @@ -16,7 +16,7 @@ import { import getMessagesForPage from '../../../../src/utils/language/getMessagesForPage'; import { defaultTenant } from '../../../../tenant.config'; import { useTenant } from '../../../../src/features/common/Layout/TenantContext'; -import DonationReceiptLayout from '../../../../src/features/user/TaxReceipt/DonationReceiptLayout'; +import DonationReceiptLayout from '../../../../src/features/user/DonationReceipt/DonationReceiptLayout'; interface PageProps { messages: AbstractIntlMessages; diff --git a/public/static/locales/en/donate.json b/public/static/locales/en/donate.json index fed317502..3dc4f616e 100644 --- a/public/static/locales/en/donate.json +++ b/public/static/locales/en/donate.json @@ -110,6 +110,11 @@ "projectType": "Project Type", "restoration": "Restoration", "filters": "Filters", - "perM2": "per m²" + "perM2": "per m²", + "donationReceipt": { + "verifyTaxHeaderPrimary": "Verify your data to download tax receipt", + "verifyTaxHeaderSecondary": "once the data is verified, it can not be changed again for this receipt", + "downloadTaxReceipt": "Download tax receipt" + } } } diff --git a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx new file mode 100644 index 000000000..4b73e5e53 --- /dev/null +++ b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx @@ -0,0 +1,21 @@ +import styles from './donationReceipt.module.scss'; +import { donationData } from './utils'; +import ReceiptDataSection from './microComponents/ReceiptDataSection'; +import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; +import ReceiptFooterSection from './microComponents/ReceiptFooterSection'; + +export const DonationReceiptLayout = () => { + return ( +
+
+ + + +
+
+ ); +}; + +export default DonationReceiptLayout; diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss new file mode 100644 index 000000000..50bd0104e --- /dev/null +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -0,0 +1,43 @@ +@import '../../../theme/theme'; + +.donationReceiptLayout { + width: 100vw; + height: calc(100vh - 80px); + display: flex; + flex-direction: column; + align-items: center; + margin-top: 80px; + background: var(--background-base); +} + +.donationReceiptContainer { + display: flex; + gap: 20px; + flex-direction: column; + width: 100%; + max-width: 760px; + min-height: 60px; + margin-top: 60px; + flex-shrink: 0; +} + +.receiptVerificationHeader { + h2 { + font-size: 20px; + font-weight: 600; + } + + h3 { + font-size: 14px; + font-family: 400; + color: rgba(51, 51, 51, 1); + } +} + +.receiptDataSection { + width: 100%; + border-radius: 16px; + padding: 16px; + background: #fff; + height: 60px; +} diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx new file mode 100644 index 000000000..6a2142f49 --- /dev/null +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -0,0 +1,11 @@ +import styles from '../donationReceipt.module.scss'; + +const ReceiptDataSection = () => { + return ( +
+
+
+ ); +}; + +export default ReceiptDataSection; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptFooterSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptFooterSection.tsx new file mode 100644 index 000000000..bedcb8377 --- /dev/null +++ b/src/features/user/DonationReceipt/microComponents/ReceiptFooterSection.tsx @@ -0,0 +1,9 @@ +const ReceiptFooterSection = () => { + return ( +
+
+
+ ); +}; + +export default ReceiptFooterSection; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx new file mode 100644 index 000000000..6ef69b6dd --- /dev/null +++ b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx @@ -0,0 +1,24 @@ +import { useTranslations } from 'next-intl'; +import styles from '../donationReceipt.module.scss'; + +type Props = { + verificationDate: number | null; +}; + +const ReceiptVerificationHeader = ({ verificationDate }: Props) => { + const t = useTranslations('Donate.donationReceipt'); + return ( +
+ {verificationDate === null ? ( + <> +

{t('verifyTaxHeaderPrimary')}

+

{t('verifyTaxHeaderSecondary')}

+ + ) : ( +

{t('downloadTaxReceipt')}

+ )} +
+ ); +}; + +export default ReceiptVerificationHeader; diff --git a/src/features/user/DonationReceipt/utils.ts b/src/features/user/DonationReceipt/utils.ts new file mode 100644 index 000000000..00759789a --- /dev/null +++ b/src/features/user/DonationReceipt/utils.ts @@ -0,0 +1,31 @@ +export const donationData = { + dtn: 'H0GH9ADF', + challenge: 'T.HIL', + year: '2020', + verificationDate: null, + donor: { + tin: null, + city: 'Hamburg', + name: 'Pue GmbH', + type: 'organization', + email: 't.hicool.de', + country: 'DE', + zipCode: '22113', + address1: 'Springfield, 210', + address2: null, + reference: 't.coolmblue.ce', + }, + amount: 10.0, + donations: [ + { + reference: 'H01VDF', + amount: 10.0, + paymentDate: '2020-01-01', + }, + { + reference: '046S22', + amount: 50.0, + paymentDate: '2024-06-06T14:53:31+00:00', + }, + ], +}; diff --git a/src/features/user/TaxReceipt/DonationReceiptLayout.tsx b/src/features/user/TaxReceipt/DonationReceiptLayout.tsx deleted file mode 100644 index b4c802835..000000000 --- a/src/features/user/TaxReceipt/DonationReceiptLayout.tsx +++ /dev/null @@ -1,9 +0,0 @@ -export const DonationReceiptLayout = () => { - return ( -
-
-
- ); -}; - -export default DonationReceiptLayout; From 0d08f4eb998fbc3d6cc58553820ff3db459b9d7b Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Wed, 22 Jan 2025 10:50:37 +0530 Subject: [PATCH 03/31] feat: implement DonationData component for displaying donation records with translations --- public/static/locales/en/donate.json | 5 +- .../donationReceipt.module.scss | 50 ++++++++++++++++++- .../microComponents/DonationData.tsx | 42 ++++++++++++++++ .../microComponents/ReceiptDataSection.tsx | 6 ++- src/features/user/DonationReceipt/utils.ts | 12 ++--- 5 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 src/features/user/DonationReceipt/microComponents/DonationData.tsx diff --git a/public/static/locales/en/donate.json b/public/static/locales/en/donate.json index 3dc4f616e..198398976 100644 --- a/public/static/locales/en/donate.json +++ b/public/static/locales/en/donate.json @@ -114,7 +114,10 @@ "donationReceipt": { "verifyTaxHeaderPrimary": "Verify your data to download tax receipt", "verifyTaxHeaderSecondary": "once the data is verified, it can not be changed again for this receipt", - "downloadTaxReceipt": "Download tax receipt" + "downloadTaxReceipt": "Download tax receipt", + "referenceNumber": "Reference Number", + "amountDonated": "Amount Donated", + "paymentDate": "Payment Date" } } } diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index 50bd0104e..dc2932b5c 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -39,5 +39,53 @@ border-radius: 16px; padding: 16px; background: #fff; - height: 60px; +} + +.donationRecord { + display: flex; + flex-direction: column; + gap: 12px; + width: 100%; + padding: 6px 16px 16px 16px; + + .header { + display: flex; + justify-content: space-between; + font-weight: 600; + } +} + +.paymentDate { + text-align: right; +} + +.amountDonated { + text-align: center; +} + +.record { + display: flex; + justify-content: space-between; + align-items: center; + padding-top: 8px; + padding-bottom: 8px; + + .amount { + flex: 1; + text-align: center; + } + + .reference { + flex: 1; + text-align: left; + } + + .date { + flex: 1; + text-align: right; + } +} + +.record:not(:last-child) { + border-bottom: 1px solid #ccc; } diff --git a/src/features/user/DonationReceipt/microComponents/DonationData.tsx b/src/features/user/DonationReceipt/microComponents/DonationData.tsx new file mode 100644 index 000000000..82651d081 --- /dev/null +++ b/src/features/user/DonationReceipt/microComponents/DonationData.tsx @@ -0,0 +1,42 @@ +import { useTranslations } from 'next-intl'; +import styles from '../donationReceipt.module.scss'; + +type Donations = { + reference: string; + amount: string; + paymentDate: string; +}; + +type Props = { + donations: Donations[]; +}; + +const DonationData = ({ donations }: Props) => { + const t = useTranslations('Donate.donationReceipt'); + return ( +
+
+
+ {t('referenceNumber')} + {t('amountDonated')} + {t('paymentDate')} +
+
    + {donations.map((dtn) => { + return ( +
  • + {dtn.reference} + {dtn.amount} + +
  • + ); + })} +
+
+
+ ); +}; + +export default DonationData; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index 6a2142f49..9945b65df 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -1,9 +1,13 @@ import styles from '../donationReceipt.module.scss'; +import { donationData } from '../utils'; +import DonationData from './DonationData'; const ReceiptDataSection = () => { return (
-
+ +
+
); }; diff --git a/src/features/user/DonationReceipt/utils.ts b/src/features/user/DonationReceipt/utils.ts index 00759789a..0694ab995 100644 --- a/src/features/user/DonationReceipt/utils.ts +++ b/src/features/user/DonationReceipt/utils.ts @@ -18,14 +18,14 @@ export const donationData = { amount: 10.0, donations: [ { - reference: 'H01VDF', - amount: 10.0, - paymentDate: '2020-01-01', + reference: 'H01VDFUJ', + amount: `$10.0`, + paymentDate: 'October 15, 2024', }, { - reference: '046S22', - amount: 50.0, - paymentDate: '2024-06-06T14:53:31+00:00', + reference: '046S2290', + amount: `$50.0`, + paymentDate: 'November 15, 2024', }, ], }; From 3329fc088dcb9160b066f41b7d8446a21175ab72 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:36:18 +0530 Subject: [PATCH 04/31] feat(UI): implement RecipientDetails component for displaying recipient details. --- public/static/locales/en/donate.json | 4 +- .../donationReceipt.module.scss | 39 ++++++++++ .../microComponents/ReceiptDataSection.tsx | 3 +- .../microComponents/RecipientDetails.tsx | 78 +++++++++++++++++++ src/features/user/DonationReceipt/utils.ts | 2 +- 5 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx diff --git a/public/static/locales/en/donate.json b/public/static/locales/en/donate.json index 198398976..14b1192d1 100644 --- a/public/static/locales/en/donate.json +++ b/public/static/locales/en/donate.json @@ -117,7 +117,9 @@ "downloadTaxReceipt": "Download tax receipt", "referenceNumber": "Reference Number", "amountDonated": "Amount Donated", - "paymentDate": "Payment Date" + "paymentDate": "Payment Date", + "recipientInfoHeader": "Receipt will be issued to", + "taxIdentificationNumber": "Tax Identification Number (TIN)" } } } diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index dc2932b5c..4289bb763 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -89,3 +89,42 @@ .record:not(:last-child) { border-bottom: 1px solid #ccc; } + +.recipientDetails { + display: flex; + flex-direction: column; + gap: 20px; + background: rgba(242, 242, 242, 0.5); + width: 100%; + border-radius: 9px; + margin-top: 25px; + padding: 10px 15px; + + .header { + font-weight: 600; + font-size: 14px; + } + + .details { + display: flex; + justify-content: space-between; + flex-direction: row; + flex-wrap: wrap; + gap: 28px; + } +} + +.address, +.firstName, +.lastName, +.companyName, +.tin { + display: flex; + flex-direction: column; + color: rgba(130, 130, 130, 1); + gap: 7px; + .header { + font-size: 12px; + font-weight: 700; + } +} diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index 9945b65df..fb5e78f79 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -1,12 +1,13 @@ import styles from '../donationReceipt.module.scss'; import { donationData } from '../utils'; import DonationData from './DonationData'; +import RecipientDetails from './RecipientDetails'; const ReceiptDataSection = () => { return (
-
+
); diff --git a/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx b/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx new file mode 100644 index 000000000..48caaecb7 --- /dev/null +++ b/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx @@ -0,0 +1,78 @@ +import type { CountryCode } from '@planet-sdk/common'; + +import { useTranslations } from 'next-intl'; +import styles from '../donationReceipt.module.scss'; +import { getFormattedAddress } from '../../../../utils/addressManagement'; +import { useMemo } from 'react'; + +type Donar = { + tin: string | null; + city: string; + name: string; + type: string; + email: string; + country: string; + zipCode: string; + address1: string; + address2: string | null; + reference: string; + companyName?: string; +}; + +interface Props { + donar: Donar; +} + +const RecipientDetails = ({ donar }: Props) => { + const t = useTranslations('Donate'); + const tCountry = useTranslations('Country'); + + const { zipCode, city, country, address1, address2 } = donar; + + const countryName = tCountry(country.toLowerCase() as Lowercase); + const cityStatePostalString = useMemo( + () => getFormattedAddress(zipCode, city, null, countryName), + [zipCode, city, countryName] + ); + + return ( +
+

+ {t('donationReceipt.recipientInfoHeader')} +

+
+
+ {t('firstName')} + John +
+
+ {t('lastName')} + Doe +
+
+ {t('companyName')} + {donar.companyName ? donar.companyName : '-'} +
+
+ + {t('donationReceipt.taxIdentificationNumber')} + + {donar.tin ? donar.tin : '-'} +
+
+ Address +
+ {address1},{cityStatePostalString} +
+ {address2 && ( +
+ {address2},{cityStatePostalString} +
+ )} +
+
+
+ ); +}; + +export default RecipientDetails; diff --git a/src/features/user/DonationReceipt/utils.ts b/src/features/user/DonationReceipt/utils.ts index 0694ab995..4393fbf5e 100644 --- a/src/features/user/DonationReceipt/utils.ts +++ b/src/features/user/DonationReceipt/utils.ts @@ -11,7 +11,7 @@ export const donationData = { email: 't.hicool.de', country: 'DE', zipCode: '22113', - address1: 'Springfield, 210', + address1: 'Springfield, 210, Springfield, 2100', address2: null, reference: 't.coolmblue.ce', }, From 784e637852b59371e9dc5d1a7f7ea3b4cc7284d6 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Wed, 22 Jan 2025 15:17:41 +0530 Subject: [PATCH 05/31] feat(UI) : add ReceiptActions(button's) component --- public/static/locales/en/donate.json | 4 ++- .../donationReceipt.module.scss | 9 +++++ .../microComponents/ReceiptActions.tsx | 34 +++++++++++++++++++ .../microComponents/ReceiptDataSection.tsx | 3 +- 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx diff --git a/public/static/locales/en/donate.json b/public/static/locales/en/donate.json index 14b1192d1..747e43828 100644 --- a/public/static/locales/en/donate.json +++ b/public/static/locales/en/donate.json @@ -119,7 +119,9 @@ "amountDonated": "Amount Donated", "paymentDate": "Payment Date", "recipientInfoHeader": "Receipt will be issued to", - "taxIdentificationNumber": "Tax Identification Number (TIN)" + "taxIdentificationNumber": "Tax Identification Number (TIN)", + "modifyContactInformation": "Modify Contact Information", + "confirm": "Confirm" } } } diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index 4289bb763..47dbabeac 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -128,3 +128,12 @@ font-weight: 700; } } + +.receiptActions { + margin-top: 40px; + display: flex; + justify-content: space-between; + svg { + width: 13px; + } +} diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx new file mode 100644 index 000000000..e60e21b90 --- /dev/null +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -0,0 +1,34 @@ +import { useRouter } from 'next/router'; +import EditIcon from '../../../../../public/assets/images/icons/EditIcon'; +import WebappButton from '../../../common/WebappButton'; +import styles from '../donationReceipt.module.scss'; +import { useTranslations } from 'next-intl'; + +const ReceiptActions = () => { + const t = useTranslations('Donate.donationReceipt'); + const router = useRouter(); + + // logic is pending + const confirmRecipientData = () => {}; + return ( +
+ } + onClick={() => + router.push(`/profile/tax-receipt/modify-recipient-data`) + } + /> + +
+ ); +}; + +export default ReceiptActions; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index fb5e78f79..eb6cdbed1 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -1,6 +1,7 @@ import styles from '../donationReceipt.module.scss'; import { donationData } from '../utils'; import DonationData from './DonationData'; +import ReceiptActions from './ReceiptActions'; import RecipientDetails from './RecipientDetails'; const ReceiptDataSection = () => { @@ -8,7 +9,7 @@ const ReceiptDataSection = () => {
-
+
); }; From e28cf6d60ef511d616e31774057486d6e0662ce5 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Wed, 22 Jan 2025 15:36:37 +0530 Subject: [PATCH 06/31] fix: minor ui adjustment for mobile view --- .../user/DonationReceipt/donationReceipt.module.scss | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index 47dbabeac..fb3934b04 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -8,6 +8,9 @@ align-items: center; margin-top: 80px; background: var(--background-base); + @include xsPhoneView { + padding: 0 2%; + } } .donationReceiptContainer { @@ -18,7 +21,9 @@ max-width: 760px; min-height: 60px; margin-top: 60px; - flex-shrink: 0; + @include xsPhoneView { + align-items: center; + } } .receiptVerificationHeader { From 4fd7bb5a27f7301af51c52673446dce7195f59b5 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:02:45 +0530 Subject: [PATCH 07/31] feat(UI) : Introduce conditional logic to display a download button when downloadUrl is available. --- ...eceipt.tsx => verify-donation-receipt.tsx} | 0 public/static/locales/en/donate.json | 3 +- .../DonationReceipt/DonationReceiptLayout.tsx | 4 +- .../donationReceipt.module.scss | 9 +++- .../microComponents/ReceiptActions.tsx | 50 +++++++++++++------ .../microComponents/ReceiptDataSection.tsx | 2 +- .../ReceiptVerificationHeader.tsx | 10 ++-- src/features/user/DonationReceipt/utils.ts | 1 + 8 files changed, 52 insertions(+), 27 deletions(-) rename pages/sites/[slug]/[locale]/{donation-receipt.tsx => verify-donation-receipt.tsx} (100%) diff --git a/pages/sites/[slug]/[locale]/donation-receipt.tsx b/pages/sites/[slug]/[locale]/verify-donation-receipt.tsx similarity index 100% rename from pages/sites/[slug]/[locale]/donation-receipt.tsx rename to pages/sites/[slug]/[locale]/verify-donation-receipt.tsx diff --git a/public/static/locales/en/donate.json b/public/static/locales/en/donate.json index 747e43828..84970a1dd 100644 --- a/public/static/locales/en/donate.json +++ b/public/static/locales/en/donate.json @@ -121,7 +121,8 @@ "recipientInfoHeader": "Receipt will be issued to", "taxIdentificationNumber": "Tax Identification Number (TIN)", "modifyContactInformation": "Modify Contact Information", - "confirm": "Confirm" + "confirm": "Confirm", + "download": "Download" } } } diff --git a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx index 4b73e5e53..223c9bbdc 100644 --- a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx +++ b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx @@ -8,9 +8,7 @@ export const DonationReceiptLayout = () => { return (
- +
diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index fb3934b04..94fd65100 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -137,7 +137,14 @@ .receiptActions { margin-top: 40px; display: flex; - justify-content: space-between; + gap: 12px; + padding: 0px 10px; + @include xsPhoneView { + flex-direction: column; + } + button { + flex: 1 1; + } svg { width: 13px; } diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx index e60e21b90..5ce795f67 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -3,30 +3,48 @@ import EditIcon from '../../../../../public/assets/images/icons/EditIcon'; import WebappButton from '../../../common/WebappButton'; import styles from '../donationReceipt.module.scss'; import { useTranslations } from 'next-intl'; +import DownloadIcon from '../../../../../public/assets/images/icons/projectV2/DownloadIcon'; -const ReceiptActions = () => { +type Props = { + downloadUrl: string | null; +}; + +const ReceiptActions = ({ downloadUrl }: Props) => { const t = useTranslations('Donate.donationReceipt'); const router = useRouter(); // logic is pending const confirmRecipientData = () => {}; + const handleDownload = () => {}; return (
- } - onClick={() => - router.push(`/profile/tax-receipt/modify-recipient-data`) - } - /> - + {downloadUrl ? ( + } + onClick={handleDownload} + /> + ) : ( + <> + } + onClick={() => + router.push(`/profile/tax-receipt/modify-recipient-data`) + } + /> + + + )}
); }; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index eb6cdbed1..20e2522f5 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -9,7 +9,7 @@ const ReceiptDataSection = () => {
- +
); }; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx index 6ef69b6dd..fb6ff1d04 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx @@ -2,20 +2,20 @@ import { useTranslations } from 'next-intl'; import styles from '../donationReceipt.module.scss'; type Props = { - verificationDate: number | null; + downloadUrl: number | null; }; -const ReceiptVerificationHeader = ({ verificationDate }: Props) => { +const ReceiptVerificationHeader = ({ downloadUrl }: Props) => { const t = useTranslations('Donate.donationReceipt'); return (
- {verificationDate === null ? ( + {downloadUrl ? ( +

{t('downloadTaxReceipt')}

+ ) : ( <>

{t('verifyTaxHeaderPrimary')}

{t('verifyTaxHeaderSecondary')}

- ) : ( -

{t('downloadTaxReceipt')}

)}
); diff --git a/src/features/user/DonationReceipt/utils.ts b/src/features/user/DonationReceipt/utils.ts index 4393fbf5e..b9473a591 100644 --- a/src/features/user/DonationReceipt/utils.ts +++ b/src/features/user/DonationReceipt/utils.ts @@ -28,4 +28,5 @@ export const donationData = { paymentDate: 'November 15, 2024', }, ], + downloadUrl: null, }; From c5fa70ca9f451b5ce0925f8cbc4dadbea7e654cd Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:15:40 +0530 Subject: [PATCH 08/31] refactor: rename component to ReceiptListRedirect --- src/features/user/DonationReceipt/DonationReceiptLayout.tsx | 4 ++-- .../{ReceiptFooterSection.tsx => ReceiptListRedirect.tsx} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename src/features/user/DonationReceipt/microComponents/{ReceiptFooterSection.tsx => ReceiptListRedirect.tsx} (100%) diff --git a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx index 223c9bbdc..82506b200 100644 --- a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx +++ b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx @@ -2,7 +2,7 @@ import styles from './donationReceipt.module.scss'; import { donationData } from './utils'; import ReceiptDataSection from './microComponents/ReceiptDataSection'; import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; -import ReceiptFooterSection from './microComponents/ReceiptFooterSection'; +import ReceiptListRedirect from './microComponents/ReceiptListRedirect'; export const DonationReceiptLayout = () => { return ( @@ -10,7 +10,7 @@ export const DonationReceiptLayout = () => {
- +
); diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptFooterSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptListRedirect.tsx similarity index 100% rename from src/features/user/DonationReceipt/microComponents/ReceiptFooterSection.tsx rename to src/features/user/DonationReceipt/microComponents/ReceiptListRedirect.tsx From 25dda11b9f26f1d3f524a2b433a7fef49ed0b618 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Thu, 23 Jan 2025 10:16:08 +0530 Subject: [PATCH 09/31] feat(context): Add DonationReceiptContext with provider and custom hook --- ...on-receipt.tsx => verify-receipt-data.tsx} | 0 .../common/Layout/DonationReceiptContext.tsx | 73 +++++++++++++++++++ 2 files changed, 73 insertions(+) rename pages/sites/[slug]/[locale]/{verify-donation-receipt.tsx => verify-receipt-data.tsx} (100%) create mode 100644 src/features/common/Layout/DonationReceiptContext.tsx diff --git a/pages/sites/[slug]/[locale]/verify-donation-receipt.tsx b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx similarity index 100% rename from pages/sites/[slug]/[locale]/verify-donation-receipt.tsx rename to pages/sites/[slug]/[locale]/verify-receipt-data.tsx diff --git a/src/features/common/Layout/DonationReceiptContext.tsx b/src/features/common/Layout/DonationReceiptContext.tsx new file mode 100644 index 000000000..72373021b --- /dev/null +++ b/src/features/common/Layout/DonationReceiptContext.tsx @@ -0,0 +1,73 @@ +import type { FC } from 'react'; +import type { Address, UserType } from '@planet-sdk/common'; +import type { SetState } from '../types/common'; + +import { useMemo, useState, createContext, useContext } from 'react'; + +interface Donor { + tin: string | null; + name: string; + type: UserType; +} + +interface DonationReceiptItemView { + amount: number; + currency: string | null; + paymentDate: string; + reference: string; +} + +interface DonationReceiptData { + dtn: string | null; + challenge: string | null; + year: string | null; + donor: Donor; + address: Address; + amount: number | null; + currency: string | null; + donations: DonationReceiptItemView[]; + operation?: string | null; + donationUids?: string[]; + tinIsRequired?: boolean; + mustAuthenticate?: boolean; + verificationDate: string; + isVerified?: boolean; + isDirty?: boolean; + downloadUrl?: string; +} + +interface DonationReceiptContextInterface { + donationReceiptData: DonationReceiptData | null; + setDonationReceiptData: SetState; +} + +const DonationReceiptContext = + createContext(null); + +export const DonationReceiptProvider: FC = ({ children }) => { + const [donationReceiptData, setDonationReceiptData] = + useState(null); + + const value: DonationReceiptContextInterface = useMemo( + () => ({ + setDonationReceiptData, + donationReceiptData, + }), + [setDonationReceiptData, donationReceiptData] + ); + + return ( + + {children} + + ); +}; + +export const useDonationReceipt = (): DonationReceiptContextInterface => { + const context = useContext(DonationReceiptContext); + if (!context) + throw new Error( + 'DonationReceiptContext must be used within AnalyticsProvider' + ); + return context; +}; From acd07add371f94cf6874dc0ed67da3cd903b8f09 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Thu, 23 Jan 2025 11:18:35 +0530 Subject: [PATCH 10/31] feat(API) : fetch and update donation receipt data based on query parameters (dtn, year, challenge) - Implemented logic to fetch donation receipt data when valid query parameters are present. - Added type checks for dtn, year, and challenge before making the API request. - Updated the donation receipt data upon successful fetch. - Handled errors in case of failed API request. --- .../[slug]/[locale]/verify-receipt-data.tsx | 7 ++- .../common/Layout/DonationReceiptContext.tsx | 23 +++++++--- .../microComponents/ReceiptDataSection.tsx | 44 +++++++++++++++++++ 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx index 941789b78..0d88e5e3a 100644 --- a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx +++ b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx @@ -17,6 +17,7 @@ import getMessagesForPage from '../../../../src/utils/language/getMessagesForPag import { defaultTenant } from '../../../../tenant.config'; import { useTenant } from '../../../../src/features/common/Layout/TenantContext'; import DonationReceiptLayout from '../../../../src/features/user/DonationReceipt/DonationReceiptLayout'; +import { DonationReceiptProvider } from '../../../../src/features/common/Layout/DonationReceiptContext'; interface PageProps { messages: AbstractIntlMessages; @@ -37,7 +38,11 @@ export default function DonationReceipt({ if (router.isReady) setTenantConfig(tenantConfig); }, [router.isReady]); - return ; + return ( + + + + ); } export const getStaticPaths: GetStaticPaths = async () => { diff --git a/src/features/common/Layout/DonationReceiptContext.tsx b/src/features/common/Layout/DonationReceiptContext.tsx index 72373021b..b3bf3e5b6 100644 --- a/src/features/common/Layout/DonationReceiptContext.tsx +++ b/src/features/common/Layout/DonationReceiptContext.tsx @@ -1,6 +1,5 @@ import type { FC } from 'react'; import type { Address, UserType } from '@planet-sdk/common'; -import type { SetState } from '../types/common'; import { useMemo, useState, createContext, useContext } from 'react'; @@ -17,7 +16,7 @@ interface DonationReceiptItemView { reference: string; } -interface DonationReceiptData { +export interface DonationReceiptData { dtn: string | null; challenge: string | null; year: string | null; @@ -38,7 +37,7 @@ interface DonationReceiptData { interface DonationReceiptContextInterface { donationReceiptData: DonationReceiptData | null; - setDonationReceiptData: SetState; + updateDonationReceiptData: (data: Partial) => void; } const DonationReceiptContext = @@ -48,12 +47,24 @@ export const DonationReceiptProvider: FC = ({ children }) => { const [donationReceiptData, setDonationReceiptData] = useState(null); + const updateDonationReceiptData = (data: Partial) => { + setDonationReceiptData((prevState) => { + if (!prevState) { + return { ...data } as DonationReceiptData; + } + return { + ...prevState, + ...data, + } as DonationReceiptData; + }); + }; + const value: DonationReceiptContextInterface = useMemo( () => ({ - setDonationReceiptData, donationReceiptData, + updateDonationReceiptData, }), - [setDonationReceiptData, donationReceiptData] + [updateDonationReceiptData, donationReceiptData] ); return ( @@ -67,7 +78,7 @@ export const useDonationReceipt = (): DonationReceiptContextInterface => { const context = useContext(DonationReceiptContext); if (!context) throw new Error( - 'DonationReceiptContext must be used within AnalyticsProvider' + 'DonationReceiptContext must be used within DonationReceiptProvider' ); return context; }; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index 20e2522f5..55cb9100c 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -1,10 +1,54 @@ +import type { DonationReceiptData } from '../../../common/Layout/DonationReceiptContext'; +import type { APIError } from '@planet-sdk/common'; + +import { useContext, useEffect } from 'react'; +import { useRouter } from 'next/router'; +import { handleError } from '@planet-sdk/common'; +import { useDonationReceipt } from '../../../common/Layout/DonationReceiptContext'; import styles from '../donationReceipt.module.scss'; import { donationData } from '../utils'; import DonationData from './DonationData'; import ReceiptActions from './ReceiptActions'; import RecipientDetails from './RecipientDetails'; +import { getRequest } from '../../../../utils/apiRequests/api'; +import { useTenant } from '../../../common/Layout/TenantContext'; +import { ErrorHandlingContext } from '../../../common/Layout/ErrorHandlingContext'; const ReceiptDataSection = () => { + const { setErrors } = useContext(ErrorHandlingContext); + const { updateDonationReceiptData } = useDonationReceipt(); + const { tenantConfig } = useTenant(); + const { query } = useRouter(); + const { dtn, year, challenge } = query; + + useEffect(() => { + if (!(dtn || year || challenge)) return; + const fetchReceiptData = async () => { + if ( + typeof dtn !== 'string' || + typeof year !== 'string' || + typeof challenge !== 'string' + ) + return; + try { + const data = await getRequest({ + tenant: tenantConfig.id, + url: '/app/donationReceipt', + queryParams: { + dtn, + year, + challenge, + }, + }); + if (data) updateDonationReceiptData(data); + } catch (err) { + setErrors(handleError(err as APIError)); + } + }; + + fetchReceiptData(); + }, [dtn, year, challenge]); + return (
From 3aba0e964930c61ebe5667b7ebfe04163daa9123 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Fri, 24 Jan 2025 11:18:06 +0530 Subject: [PATCH 11/31] refactor: refactor receipt verification page - added next-intl keys for "donationAmount" and "name" with currency and type-based rendering. - defined proper types for Donor, Donation, and ReceiptData for stricter TypeScript typing. - moved fetchReceiptData logic from ReceiptDataSection to DonationReceiptLayout for better separation of concerns. - simplified UI by removing firstName and lastName fields, displaying only Name. - added skeleton structure for the receipt verification page to enhance loading experience. --- public/static/locales/en/donate.json | 4 +- .../common/Layout/DonationReceiptContext.tsx | 64 +++++++++-------- .../DonationReceipt/DonationReceiptLayout.tsx | 72 +++++++++++++++++-- .../donationReceipt.module.scss | 9 ++- .../microComponents/DonationData.tsx | 22 +++--- .../microComponents/ReceiptDataSection.tsx | 60 ++++------------ .../ReceiptVerificationHeader.tsx | 2 +- .../microComponents/RecipientDetails.tsx | 49 +++++-------- 8 files changed, 154 insertions(+), 128 deletions(-) diff --git a/public/static/locales/en/donate.json b/public/static/locales/en/donate.json index 84970a1dd..95849b098 100644 --- a/public/static/locales/en/donate.json +++ b/public/static/locales/en/donate.json @@ -122,7 +122,9 @@ "taxIdentificationNumber": "Tax Identification Number (TIN)", "modifyContactInformation": "Modify Contact Information", "confirm": "Confirm", - "download": "Download" + "download": "Download", + "donationAmount": "{currency, select, EUR {€} USD {$} other {}} {amount}", + "name": "{type, select, individual {Name} organization {Company Name} other {}}" } } } diff --git a/src/features/common/Layout/DonationReceiptContext.tsx b/src/features/common/Layout/DonationReceiptContext.tsx index b3bf3e5b6..af218502a 100644 --- a/src/features/common/Layout/DonationReceiptContext.tsx +++ b/src/features/common/Layout/DonationReceiptContext.tsx @@ -1,43 +1,46 @@ import type { FC } from 'react'; -import type { Address, UserType } from '@planet-sdk/common'; import { useMemo, useState, createContext, useContext } from 'react'; -interface Donor { +export type Donor = { tin: string | null; + city: string; name: string; - type: UserType; -} + type: 'individual' | 'organization'; + email: string; + country: string; + zipCode: string; + address1: string; + address2: string | null; + reference: string; +}; -interface DonationReceiptItemView { +export type Donation = { amount: number; - currency: string | null; + currency: string; paymentDate: string; reference: string; -} +}; -export interface DonationReceiptData { - dtn: string | null; - challenge: string | null; - year: string | null; +export type ReceiptData = { + dtn: string; + challenge: string; + year: string; + country: string; + reference: string; + amount: number; + currency: string; + paymentDate: string; + verificationDate: string | null; donor: Donor; - address: Address; - amount: number | null; - currency: string | null; - donations: DonationReceiptItemView[]; - operation?: string | null; - donationUids?: string[]; - tinIsRequired?: boolean; - mustAuthenticate?: boolean; - verificationDate: string; - isVerified?: boolean; - isDirty?: boolean; - downloadUrl?: string; -} + downloadUrl: string; + donationCount: number; + donations: Donation[]; +}; interface DonationReceiptContextInterface { - donationReceiptData: DonationReceiptData | null; - updateDonationReceiptData: (data: Partial) => void; + donationReceiptData: ReceiptData | null; + updateDonationReceiptData: (data: Partial) => void; } const DonationReceiptContext = @@ -45,17 +48,16 @@ const DonationReceiptContext = export const DonationReceiptProvider: FC = ({ children }) => { const [donationReceiptData, setDonationReceiptData] = - useState(null); - - const updateDonationReceiptData = (data: Partial) => { + useState(null); + const updateDonationReceiptData = (data: Partial) => { setDonationReceiptData((prevState) => { if (!prevState) { - return { ...data } as DonationReceiptData; + return { ...data } as ReceiptData; } return { ...prevState, ...data, - } as DonationReceiptData; + } as ReceiptData; }); }; diff --git a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx index 82506b200..7a9edaf96 100644 --- a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx +++ b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx @@ -1,18 +1,82 @@ +import { + useDonationReceipt, + type ReceiptData, +} from '../../common/Layout/DonationReceiptContext'; +import type { APIError } from '@planet-sdk/common'; + +import { useContext, useEffect, useState } from 'react'; import styles from './donationReceipt.module.scss'; -import { donationData } from './utils'; import ReceiptDataSection from './microComponents/ReceiptDataSection'; import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; import ReceiptListRedirect from './microComponents/ReceiptListRedirect'; +import { useRouter } from 'next/router'; +import { useTenant } from '../../common/Layout/TenantContext'; +import { getRequest } from '../../../utils/apiRequests/api'; +import { ErrorHandlingContext } from '../../common/Layout/ErrorHandlingContext'; +import { handleError } from '@planet-sdk/common'; +import Skeleton from 'react-loading-skeleton'; +import 'react-loading-skeleton/dist/skeleton.css'; export const DonationReceiptLayout = () => { - return ( + const [isLoading, setIsLoading] = useState(false); + const { tenantConfig } = useTenant(); + const { setErrors, redirect } = useContext(ErrorHandlingContext); + const router = useRouter(); + const { dtn, year, challenge } = router.query; + const { updateDonationReceiptData, donationReceiptData } = + useDonationReceipt(); + const showReceipt = !isLoading && donationReceiptData !== null; + + useEffect(() => { + if (!(dtn || year || challenge || router.isReady)) return; + if ( + typeof dtn !== 'string' || + typeof year !== 'string' || + typeof challenge !== 'string' + ) + return; + const fetchReceiptData = async () => { + setIsLoading(true); + try { + const data = await getRequest({ + tenant: tenantConfig.id, + url: '/app/donationReceipt', + queryParams: { + dtn, + year, + challenge, + }, + }); + if (data) updateDonationReceiptData(data); + } catch (err) { + setErrors(handleError(err as APIError)); + redirect('/'); + } finally { + setIsLoading(false); + } + }; + + fetchReceiptData(); + }, [dtn, year, challenge, router.isReady]); + + return showReceipt ? (
- - + +
+ ) : ( +
+ +
); }; diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index 94fd65100..6af6668f4 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -1,5 +1,11 @@ @import '../../../theme/theme'; +.donationReceiptSkeleton { + display: flex; + justify-content: center; + margin-top: 110px; +} + .donationReceiptLayout { width: 100vw; height: calc(100vh - 80px); @@ -120,8 +126,7 @@ } .address, -.firstName, -.lastName, +.Name, .companyName, .tin { display: flex; diff --git a/src/features/user/DonationReceipt/microComponents/DonationData.tsx b/src/features/user/DonationReceipt/microComponents/DonationData.tsx index 82651d081..bd32184b5 100644 --- a/src/features/user/DonationReceipt/microComponents/DonationData.tsx +++ b/src/features/user/DonationReceipt/microComponents/DonationData.tsx @@ -1,14 +1,11 @@ +import type { Donation } from '../../../common/Layout/DonationReceiptContext'; + import { useTranslations } from 'next-intl'; import styles from '../donationReceipt.module.scss'; - -type Donations = { - reference: string; - amount: string; - paymentDate: string; -}; +import formatDate from '../../../../utils/countryCurrency/getFormattedDate'; type Props = { - donations: Donations[]; + donations: Donation[]; }; const DonationData = ({ donations }: Props) => { @@ -22,13 +19,18 @@ const DonationData = ({ donations }: Props) => { {t('paymentDate')}
    - {donations.map((dtn) => { + {donations?.map((dtn) => { return (
  • {dtn.reference} - {dtn.amount} + + {t('donationAmount', { + currency: dtn.currency, + amount: dtn.amount, + })} +
  • ); diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index 55cb9100c..15852b555 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -1,59 +1,25 @@ -import type { DonationReceiptData } from '../../../common/Layout/DonationReceiptContext'; -import type { APIError } from '@planet-sdk/common'; +import type { + Donation, + Donor, +} from '../../../common/Layout/DonationReceiptContext'; -import { useContext, useEffect } from 'react'; -import { useRouter } from 'next/router'; -import { handleError } from '@planet-sdk/common'; -import { useDonationReceipt } from '../../../common/Layout/DonationReceiptContext'; import styles from '../donationReceipt.module.scss'; -import { donationData } from '../utils'; import DonationData from './DonationData'; import ReceiptActions from './ReceiptActions'; import RecipientDetails from './RecipientDetails'; -import { getRequest } from '../../../../utils/apiRequests/api'; -import { useTenant } from '../../../common/Layout/TenantContext'; -import { ErrorHandlingContext } from '../../../common/Layout/ErrorHandlingContext'; -const ReceiptDataSection = () => { - const { setErrors } = useContext(ErrorHandlingContext); - const { updateDonationReceiptData } = useDonationReceipt(); - const { tenantConfig } = useTenant(); - const { query } = useRouter(); - const { dtn, year, challenge } = query; - - useEffect(() => { - if (!(dtn || year || challenge)) return; - const fetchReceiptData = async () => { - if ( - typeof dtn !== 'string' || - typeof year !== 'string' || - typeof challenge !== 'string' - ) - return; - try { - const data = await getRequest({ - tenant: tenantConfig.id, - url: '/app/donationReceipt', - queryParams: { - dtn, - year, - challenge, - }, - }); - if (data) updateDonationReceiptData(data); - } catch (err) { - setErrors(handleError(err as APIError)); - } - }; - - fetchReceiptData(); - }, [dtn, year, challenge]); +interface Prop { + donations: Donation[]; + donor: Donor; + downloadUrl: string | null; +} +const ReceiptDataSection = ({ donations, donor, downloadUrl }: Prop) => { return (
    - - - + + +
    ); }; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx index fb6ff1d04..0d27dd3c1 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx @@ -2,7 +2,7 @@ import { useTranslations } from 'next-intl'; import styles from '../donationReceipt.module.scss'; type Props = { - downloadUrl: number | null; + downloadUrl: string | null; }; const ReceiptVerificationHeader = ({ downloadUrl }: Props) => { diff --git a/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx b/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx index 48caaecb7..a383eda03 100644 --- a/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx +++ b/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx @@ -1,3 +1,4 @@ +import type { Donor } from '../../../../features/common/Layout/DonationReceiptContext'; import type { CountryCode } from '@planet-sdk/common'; import { useTranslations } from 'next-intl'; @@ -5,30 +6,16 @@ import styles from '../donationReceipt.module.scss'; import { getFormattedAddress } from '../../../../utils/addressManagement'; import { useMemo } from 'react'; -type Donar = { - tin: string | null; - city: string; - name: string; - type: string; - email: string; - country: string; - zipCode: string; - address1: string; - address2: string | null; - reference: string; - companyName?: string; -}; - interface Props { - donar: Donar; + donar: Donor | undefined; } const RecipientDetails = ({ donar }: Props) => { + if (!donar) return null; + const t = useTranslations('Donate'); const tCountry = useTranslations('Country'); - const { zipCode, city, country, address1, address2 } = donar; - const countryName = tCountry(country.toLowerCase() as Lowercase); const cityStatePostalString = useMemo( () => getFormattedAddress(zipCode, city, null, countryName), @@ -41,24 +28,22 @@ const RecipientDetails = ({ donar }: Props) => { {t('donationReceipt.recipientInfoHeader')}
    -
    - {t('firstName')} - John -
    -
    - {t('lastName')} - Doe -
    -
    - {t('companyName')} - {donar.companyName ? donar.companyName : '-'} -
    -
    +
    - {t('donationReceipt.taxIdentificationNumber')} + {t('donationReceipt.name', { + type: donar.type, + })} - {donar.tin ? donar.tin : '-'} + {donar.name}
    + {donar.tin && ( +
    + + {t('donationReceipt.taxIdentificationNumber')} + + {donar.tin} +
    + )}
    Address
    From 48cef1828e2c5be3f5689c8759198641eba9785c Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Fri, 24 Jan 2025 11:49:53 +0530 Subject: [PATCH 12/31] feat: change download button to link element with href for direct file download. --- .../user/DonationReceipt/donationReceipt.module.scss | 6 ++++++ .../DonationReceipt/microComponents/ReceiptActions.tsx | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index 6af6668f4..5998f7b36 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -133,6 +133,7 @@ flex-direction: column; color: rgba(130, 130, 130, 1); gap: 7px; + .header { font-size: 12px; font-weight: 700; @@ -144,12 +145,17 @@ display: flex; gap: 12px; padding: 0px 10px; + justify-content: flex-end; + @include xsPhoneView { flex-direction: column; + align-items: flex-end; } + button { flex: 1 1; } + svg { width: 13px; } diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx index 5ce795f67..6d1c68768 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -15,16 +15,17 @@ const ReceiptActions = ({ downloadUrl }: Props) => { // logic is pending const confirmRecipientData = () => {}; - const handleDownload = () => {}; + return (
    {downloadUrl ? ( } - onClick={handleDownload} + href={downloadUrl} + target={'_blank'} /> ) : ( <> From adc116bdf904ac0f638070ece19e4c14f65120b5 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Sat, 25 Jan 2025 20:50:27 +0530 Subject: [PATCH 13/31] refactor: use verificationDate condition to render download button --- .../DonationReceipt/DonationReceiptLayout.tsx | 3 ++- .../microComponents/ReceiptActions.tsx | 7 ++++--- .../microComponents/ReceiptDataSection.tsx | 13 +++++++++++-- .../ReceiptVerificationHeader.tsx | 6 +++--- .../microComponents/RecipientDetails.tsx | 18 +++++++++--------- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx index 7a9edaf96..fe0c79477 100644 --- a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx +++ b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx @@ -63,12 +63,13 @@ export const DonationReceiptLayout = () => {
    diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx index 6d1c68768..d3ce4a284 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -7,18 +7,19 @@ import DownloadIcon from '../../../../../public/assets/images/icons/projectV2/Do type Props = { downloadUrl: string | null; + verificationDate: string | null; }; -const ReceiptActions = ({ downloadUrl }: Props) => { +const ReceiptActions = ({ downloadUrl, verificationDate }: Props) => { const t = useTranslations('Donate.donationReceipt'); const router = useRouter(); // logic is pending const confirmRecipientData = () => {}; - + const isReceiptVerified = verificationDate !== null && downloadUrl !== null; return (
    - {downloadUrl ? ( + {isReceiptVerified ? ( { +const ReceiptDataSection = ({ + donations, + donor, + downloadUrl, + verificationDate, +}: Prop) => { return (
    - +
    ); }; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx index 0d27dd3c1..c741730af 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx @@ -2,14 +2,14 @@ import { useTranslations } from 'next-intl'; import styles from '../donationReceipt.module.scss'; type Props = { - downloadUrl: string | null; + verificationDate: string | null; }; -const ReceiptVerificationHeader = ({ downloadUrl }: Props) => { +const ReceiptVerificationHeader = ({ verificationDate }: Props) => { const t = useTranslations('Donate.donationReceipt'); return (
    - {downloadUrl ? ( + {verificationDate ? (

    {t('downloadTaxReceipt')}

    ) : ( <> diff --git a/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx b/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx index a383eda03..71edb7a7e 100644 --- a/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx +++ b/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx @@ -44,17 +44,17 @@ const RecipientDetails = ({ donar }: Props) => { {donar.tin}
    )} -
    - Address +
    +
    + Address +
    + {address1},{cityStatePostalString} +
    + {address2 && (
    - {address1},{cityStatePostalString} + {address2},{cityStatePostalString}
    - {address2 && ( -
    - {address2},{cityStatePostalString} -
    - )} -
    + )}
    ); From b39983b9d245d0b08ca47c9e6ac14f9e8653c7f2 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:01:00 +0530 Subject: [PATCH 14/31] feat: refactor ReceiptData handling and update DonationReceipt components - added `formatReceiptData` helper to transform `ReceiptDataAPI` into `ReceiptData` with strict type validation. - Updated `ReceiptData` to include `operation` and `issuedDonations` fields. - Improved type safety for `DonorView`, `AddressView`, and donation-related properties. - Refactored components to align with the updated ReceiptData structure and context logic. --- .../common/Layout/DonationReceiptContext.tsx | 67 +++++++++++------- .../DonationReceipt/DonationReceiptLayout.tsx | 23 +++---- .../microComponents/DonationData.tsx | 4 +- .../microComponents/ReceiptActions.tsx | 11 +-- .../microComponents/ReceiptDataSection.tsx | 29 +++----- .../microComponents/RecipientDetails.tsx | 24 ++++--- src/features/user/DonationReceipt/utils.ts | 69 +++++++++++-------- 7 files changed, 125 insertions(+), 102 deletions(-) diff --git a/src/features/common/Layout/DonationReceiptContext.tsx b/src/features/common/Layout/DonationReceiptContext.tsx index af218502a..eae87a915 100644 --- a/src/features/common/Layout/DonationReceiptContext.tsx +++ b/src/features/common/Layout/DonationReceiptContext.tsx @@ -1,8 +1,16 @@ import type { FC } from 'react'; import { useMemo, useState, createContext, useContext } from 'react'; +import { formatReceiptData } from '../../user/DonationReceipt/utils'; -export type Donor = { +export type IssuedDonationView = { + amount: number; + currency: string; + paymentDate: string; + reference: string; +}; + +export type DonorAPI = { tin: string | null; city: string; name: string; @@ -15,32 +23,48 @@ export type Donor = { reference: string; }; -export type Donation = { - amount: number; - currency: string; - paymentDate: string; - reference: string; +export type DonorView = { + tin: string | null; + name: string; + type: 'individual' | 'organization' | null; }; -export type ReceiptData = { +export type AddressView = { + city: string; + country: string; + zipCode: string; + address1: string; + address2: string | null; +}; + +type ReceiptDataBase = { dtn: string; - challenge: string; year: string; - country: string; - reference: string; + challenge: string; amount: number; currency: string; paymentDate: string; verificationDate: string | null; - donor: Donor; downloadUrl: string; donationCount: number; - donations: Donation[]; }; +export interface ReceiptDataAPI extends ReceiptDataBase { + country: string; + reference: string; + donor: DonorAPI; + donations: IssuedDonationView[]; +} +export interface ReceiptData extends ReceiptDataBase { + operation: 'verify' | 'download'; + donor: DonorView; + address: AddressView; + issuedDonations: IssuedDonationView[] | null; +} + interface DonationReceiptContextInterface { donationReceiptData: ReceiptData | null; - updateDonationReceiptData: (data: Partial) => void; + updateDonationReceiptData: (data: Partial) => void; } const DonationReceiptContext = @@ -49,16 +73,13 @@ const DonationReceiptContext = export const DonationReceiptProvider: FC = ({ children }) => { const [donationReceiptData, setDonationReceiptData] = useState(null); - const updateDonationReceiptData = (data: Partial) => { - setDonationReceiptData((prevState) => { - if (!prevState) { - return { ...data } as ReceiptData; - } - return { - ...prevState, - ...data, - } as ReceiptData; - }); + + const updateDonationReceiptData = (data: Partial) => { + const formattedData = formatReceiptData(data); + setDonationReceiptData((prevState) => ({ + ...prevState, + ...formattedData, + })); }; const value: DonationReceiptContextInterface = useMemo( diff --git a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx index fe0c79477..446b14de1 100644 --- a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx +++ b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx @@ -1,21 +1,19 @@ -import { - useDonationReceipt, - type ReceiptData, -} from '../../common/Layout/DonationReceiptContext'; +import type { ReceiptDataAPI } from '../../common/Layout/DonationReceiptContext'; import type { APIError } from '@planet-sdk/common'; import { useContext, useEffect, useState } from 'react'; +import { handleError } from '@planet-sdk/common'; +import Skeleton from 'react-loading-skeleton'; +import 'react-loading-skeleton/dist/skeleton.css'; +import { useRouter } from 'next/router'; +import { useDonationReceipt } from '../../common/Layout/DonationReceiptContext'; import styles from './donationReceipt.module.scss'; import ReceiptDataSection from './microComponents/ReceiptDataSection'; import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; import ReceiptListRedirect from './microComponents/ReceiptListRedirect'; -import { useRouter } from 'next/router'; import { useTenant } from '../../common/Layout/TenantContext'; import { getRequest } from '../../../utils/apiRequests/api'; import { ErrorHandlingContext } from '../../common/Layout/ErrorHandlingContext'; -import { handleError } from '@planet-sdk/common'; -import Skeleton from 'react-loading-skeleton'; -import 'react-loading-skeleton/dist/skeleton.css'; export const DonationReceiptLayout = () => { const [isLoading, setIsLoading] = useState(false); @@ -38,7 +36,7 @@ export const DonationReceiptLayout = () => { const fetchReceiptData = async () => { setIsLoading(true); try { - const data = await getRequest({ + const data = await getRequest({ tenant: tenantConfig.id, url: '/app/donationReceipt', queryParams: { @@ -65,12 +63,7 @@ export const DonationReceiptLayout = () => { - +
    diff --git a/src/features/user/DonationReceipt/microComponents/DonationData.tsx b/src/features/user/DonationReceipt/microComponents/DonationData.tsx index bd32184b5..80e430737 100644 --- a/src/features/user/DonationReceipt/microComponents/DonationData.tsx +++ b/src/features/user/DonationReceipt/microComponents/DonationData.tsx @@ -1,11 +1,11 @@ -import type { Donation } from '../../../common/Layout/DonationReceiptContext'; +import type { IssuedDonationView } from '../../../common/Layout/DonationReceiptContext'; import { useTranslations } from 'next-intl'; import styles from '../donationReceipt.module.scss'; import formatDate from '../../../../utils/countryCurrency/getFormattedDate'; type Props = { - donations: Donation[]; + donations: IssuedDonationView[] | null; }; const DonationData = ({ donations }: Props) => { diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx index d3ce4a284..84c0db006 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -1,3 +1,5 @@ +import { RECEIPT_STATUS } from '../utils'; + import { useRouter } from 'next/router'; import EditIcon from '../../../../../public/assets/images/icons/EditIcon'; import WebappButton from '../../../common/WebappButton'; @@ -7,19 +9,20 @@ import DownloadIcon from '../../../../../public/assets/images/icons/projectV2/Do type Props = { downloadUrl: string | null; - verificationDate: string | null; + operation: (typeof RECEIPT_STATUS)[keyof typeof RECEIPT_STATUS]; }; -const ReceiptActions = ({ downloadUrl, verificationDate }: Props) => { +const ReceiptActions = ({ downloadUrl, operation }: Props) => { const t = useTranslations('Donate.donationReceipt'); const router = useRouter(); // logic is pending const confirmRecipientData = () => {}; - const isReceiptVerified = verificationDate !== null && downloadUrl !== null; + const showDowloadButton = + operation === RECEIPT_STATUS.DOWNLOAD && downloadUrl !== null; return (
    - {isReceiptVerified ? ( + {showDowloadButton ? ( { +const ReceiptDataSection = ({ donationReceiptData }: Prop) => { + if (!donationReceiptData) return null; + const { issuedDonations, downloadUrl, operation, donor, address } = + donationReceiptData; return (
    - - - + + +
    ); }; diff --git a/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx b/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx index 71edb7a7e..f81ffa9fd 100644 --- a/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx +++ b/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx @@ -1,4 +1,7 @@ -import type { Donor } from '../../../../features/common/Layout/DonationReceiptContext'; +import type { + AddressView, + DonorView, +} from '../../../../features/common/Layout/DonationReceiptContext'; import type { CountryCode } from '@planet-sdk/common'; import { useTranslations } from 'next-intl'; @@ -7,16 +10,19 @@ import { getFormattedAddress } from '../../../../utils/addressManagement'; import { useMemo } from 'react'; interface Props { - donar: Donor | undefined; + donor: DonorView | undefined; + address: AddressView | undefined; } -const RecipientDetails = ({ donar }: Props) => { - if (!donar) return null; +const RecipientDetails = ({ donor, address }: Props) => { + if (address === undefined || donor === undefined) return null; const t = useTranslations('Donate'); const tCountry = useTranslations('Country'); - const { zipCode, city, country, address1, address2 } = donar; + const { country, zipCode, city, address1, address2 } = address; + const { type, name, tin } = donor; const countryName = tCountry(country.toLowerCase() as Lowercase); + const cityStatePostalString = useMemo( () => getFormattedAddress(zipCode, city, null, countryName), [zipCode, city, countryName] @@ -31,17 +37,17 @@ const RecipientDetails = ({ donar }: Props) => {
    {t('donationReceipt.name', { - type: donar.type, + type, })} - {donar.name} + {name}
    - {donar.tin && ( + {tin && (
    {t('donationReceipt.taxIdentificationNumber')} - {donar.tin} + {tin}
    )}
    diff --git a/src/features/user/DonationReceipt/utils.ts b/src/features/user/DonationReceipt/utils.ts index b9473a591..9afe67e99 100644 --- a/src/features/user/DonationReceipt/utils.ts +++ b/src/features/user/DonationReceipt/utils.ts @@ -1,32 +1,43 @@ -export const donationData = { - dtn: 'H0GH9ADF', - challenge: 'T.HIL', - year: '2020', - verificationDate: null, - donor: { - tin: null, - city: 'Hamburg', - name: 'Pue GmbH', - type: 'organization', - email: 't.hicool.de', - country: 'DE', - zipCode: '22113', - address1: 'Springfield, 210, Springfield, 2100', - address2: null, - reference: 't.coolmblue.ce', - }, - amount: 10.0, - donations: [ - { - reference: 'H01VDFUJ', - amount: `$10.0`, - paymentDate: 'October 15, 2024', +import type { + ReceiptDataAPI, + ReceiptData, +} from '../../common/Layout/DonationReceiptContext'; + +export const RECEIPT_STATUS = { + VERIFY: 'verify', + DOWNLOAD: 'download', + ISSUE: 'issue', +} as const; + +export const formatReceiptData = ( + data: Partial +): ReceiptData => { + return { + dtn: data.dtn || '', + year: data.year || '', + challenge: data.challenge || '', + amount: data.amount || 0, + currency: data.currency || '', + paymentDate: data.paymentDate || '', + verificationDate: data.verificationDate || null, + downloadUrl: data.downloadUrl || '', + donationCount: data.donationCount || 0, + operation: + data.verificationDate === null + ? RECEIPT_STATUS.VERIFY + : RECEIPT_STATUS.DOWNLOAD, + donor: { + tin: data.donor?.tin || null, + name: data.donor?.name || '', + type: data.donor?.type || null, }, - { - reference: '046S2290', - amount: `$50.0`, - paymentDate: 'November 15, 2024', + address: { + city: data.donor?.city || '', + country: data.donor?.country || '', + zipCode: data.donor?.zipCode || '', + address1: data.donor?.address1 || '', + address2: data.donor?.address2 || null, }, - ], - downloadUrl: null, + issuedDonations: data.donations || null, + }; }; From b5ef8b2bf4ac6750e56d273494eb9d4719273eaa Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Mon, 27 Jan 2025 12:52:59 +0530 Subject: [PATCH 15/31] feat: Implement `putRequest` function - Rename hasUserDataChanged to hasDonorDataChanged --- .../common/Layout/DonationReceiptContext.tsx | 1 + .../DonationReceipt/DonationReceiptLayout.tsx | 2 +- .../donationReceipt.module.scss | 1 - .../microComponents/ReceiptActions.tsx | 52 +++++++++++++++++-- .../microComponents/ReceiptDataSection.tsx | 29 +++++++++-- src/features/user/DonationReceipt/utils.ts | 1 + src/utils/apiRequests/api.ts | 34 ++++++++++++ 7 files changed, 110 insertions(+), 10 deletions(-) diff --git a/src/features/common/Layout/DonationReceiptContext.tsx b/src/features/common/Layout/DonationReceiptContext.tsx index eae87a915..088426394 100644 --- a/src/features/common/Layout/DonationReceiptContext.tsx +++ b/src/features/common/Layout/DonationReceiptContext.tsx @@ -60,6 +60,7 @@ export interface ReceiptData extends ReceiptDataBase { donor: DonorView; address: AddressView; issuedDonations: IssuedDonationView[] | null; + hasDonorDataChanged: boolean; // Set it to true if the user modifies the data during the receipt verification process } interface DonationReceiptContextInterface { diff --git a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx index 446b14de1..6274d505c 100644 --- a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx +++ b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx @@ -5,8 +5,8 @@ import { useContext, useEffect, useState } from 'react'; import { handleError } from '@planet-sdk/common'; import Skeleton from 'react-loading-skeleton'; import 'react-loading-skeleton/dist/skeleton.css'; -import { useRouter } from 'next/router'; import { useDonationReceipt } from '../../common/Layout/DonationReceiptContext'; +import { useRouter } from 'next/router'; import styles from './donationReceipt.module.scss'; import ReceiptDataSection from './microComponents/ReceiptDataSection'; import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index 5998f7b36..42767b1cb 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -149,7 +149,6 @@ @include xsPhoneView { flex-direction: column; - align-items: flex-end; } button { diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx index 84c0db006..1f9d19427 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -1,23 +1,67 @@ import { RECEIPT_STATUS } from '../utils'; +import type { APIError } from '@planet-sdk/common'; +import type { ReceiptDataAPI } from '../../../common/Layout/DonationReceiptContext'; +import { useContext } from 'react'; import { useRouter } from 'next/router'; +import { useTranslations } from 'next-intl'; +import { handleError } from '@planet-sdk/common'; import EditIcon from '../../../../../public/assets/images/icons/EditIcon'; import WebappButton from '../../../common/WebappButton'; import styles from '../donationReceipt.module.scss'; -import { useTranslations } from 'next-intl'; import DownloadIcon from '../../../../../public/assets/images/icons/projectV2/DownloadIcon'; +import { putRequest } from '../../../../utils/apiRequests/api'; +import { useTenant } from '../../../common/Layout/TenantContext'; +import { ErrorHandlingContext } from '../../../common/Layout/ErrorHandlingContext'; type Props = { downloadUrl: string | null; operation: (typeof RECEIPT_STATUS)[keyof typeof RECEIPT_STATUS]; + hasDonorDataChanged: boolean; + dtn: string; + challenge: string; + year: string; + updateDonationReceiptData: (data: Partial) => void; }; -const ReceiptActions = ({ downloadUrl, operation }: Props) => { +const ReceiptActions = ({ + downloadUrl, + operation, + hasDonorDataChanged, + dtn, + challenge, + year, + updateDonationReceiptData, +}: Props) => { const t = useTranslations('Donate.donationReceipt'); const router = useRouter(); + const { tenantConfig } = useTenant(); + const { setErrors } = useContext(ErrorHandlingContext); + + const confirmRecipientData = async () => { + if (operation !== RECEIPT_STATUS.VERIFY) return; + const verificationDate = new Date().toISOString(); + + if (hasDonorDataChanged) { + //TODO: PUT Authentication request logic + } - // logic is pending - const confirmRecipientData = () => {}; + try { + const data = await putRequest({ + tenant: tenantConfig.id, + url: `/app/donationReceipt/verify`, + data: { + dtn, + challenge, + year, + verificationDate, + }, + }); + if (data) updateDonationReceiptData(data); + } catch (error) { + setErrors(handleError(error as APIError)); + } + }; const showDowloadButton = operation === RECEIPT_STATUS.DOWNLOAD && downloadUrl !== null; return ( diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index a63a13420..9ebe5b193 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -1,4 +1,7 @@ -import type { ReceiptData } from '../../../common/Layout/DonationReceiptContext'; +import { + useDonationReceipt, + type ReceiptData, +} from '../../../common/Layout/DonationReceiptContext'; import styles from '../donationReceipt.module.scss'; import DonationData from './DonationData'; @@ -11,13 +14,31 @@ interface Prop { const ReceiptDataSection = ({ donationReceiptData }: Prop) => { if (!donationReceiptData) return null; - const { issuedDonations, downloadUrl, operation, donor, address } = - donationReceiptData; + const { updateDonationReceiptData } = useDonationReceipt(); + const { + issuedDonations, + downloadUrl, + operation, + donor, + address, + hasDonorDataChanged, + dtn, + challenge, + year, + } = donationReceiptData; return (
    - +
    ); }; diff --git a/src/features/user/DonationReceipt/utils.ts b/src/features/user/DonationReceipt/utils.ts index 9afe67e99..6009223ba 100644 --- a/src/features/user/DonationReceipt/utils.ts +++ b/src/features/user/DonationReceipt/utils.ts @@ -39,5 +39,6 @@ export const formatReceiptData = ( address2: data.donor?.address2 || null, }, issuedDonations: data.donations || null, + hasDonorDataChanged: false, }; }; diff --git a/src/utils/apiRequests/api.ts b/src/utils/apiRequests/api.ts index 8dba539ab..9fee567f6 100644 --- a/src/utils/apiRequests/api.ts +++ b/src/utils/apiRequests/api.ts @@ -48,6 +48,10 @@ interface GetRequestOptions extends BaseRequestOptions { queryParams?: { [key: string]: string }; version?: string; } + +interface PutRequestOptions extends BaseRequestOptions { + data: any; +} // API call to private /profile endpoint export async function getAccountInfo({ tenant, @@ -252,7 +256,37 @@ export function postRequest({ tenant, url, data }: PostRequestOptions) { })(); }); } +export function putRequest({ tenant, url, data }: PutRequestOptions) { + const lang = localStorage.getItem('language') || 'en'; + return new Promise((resolve, reject) => { + (async () => { + try { + const res = await fetch(process.env.API_ENDPOINT + url, { + method: 'PUT', + body: JSON.stringify(data), + headers: { + 'Content-Type': 'application/json', + 'tenant-key': `${tenant}`, + 'X-SESSION-ID': await getsessionId(), + 'x-locale': lang, + }, + }); + if (!res.ok) { + throw new APIError(res.status, await res.json()); + } + + if (res.status === 204) { + resolve(true as T); + } else { + resolve(await res.json()); + } + } catch (error) { + reject(error); + } + })(); + }); +} export function deleteAuthenticatedRequest({ tenant, url, From 21360ae3f17bea7f7d2e03a23e23201050653621 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:22:41 +0530 Subject: [PATCH 16/31] refactor: move confirmDonorData logic from ReceiptActions to ReceiptDataSection - Relocated the `confirmDonorData` logic to improve component structure and ensure relevant logic resides within `ReceiptDataSection`. -Introduce spinner for loading state. --- .../DonationReceipt/DonationReceiptLayout.tsx | 6 +- .../donationReceipt.module.scss | 8 ++- .../microComponents/ReceiptActions.tsx | 52 ++------------ .../microComponents/ReceiptDataSection.tsx | 67 ++++++++++++++++--- .../ReceiptVerificationHeader.tsx | 9 ++- src/features/user/DonationReceipt/utils.ts | 6 ++ 6 files changed, 85 insertions(+), 63 deletions(-) diff --git a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx index 6274d505c..beb89e26b 100644 --- a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx +++ b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx @@ -5,8 +5,8 @@ import { useContext, useEffect, useState } from 'react'; import { handleError } from '@planet-sdk/common'; import Skeleton from 'react-loading-skeleton'; import 'react-loading-skeleton/dist/skeleton.css'; -import { useDonationReceipt } from '../../common/Layout/DonationReceiptContext'; import { useRouter } from 'next/router'; +import { useDonationReceipt } from '../../common/Layout/DonationReceiptContext'; import styles from './donationReceipt.module.scss'; import ReceiptDataSection from './microComponents/ReceiptDataSection'; import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; @@ -60,9 +60,7 @@ export const DonationReceiptLayout = () => { return showReceipt ? (
    - +
    diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index 42767b1cb..05f72a29d 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -107,8 +107,8 @@ gap: 20px; background: rgba(242, 242, 242, 0.5); width: 100%; + margin-top: 20px; border-radius: 9px; - margin-top: 25px; padding: 10px 15px; .header { @@ -159,3 +159,9 @@ width: 13px; } } + +.receiptVerificationSpinner { + display: flex; + justify-content: center; + margin-top: 40px; +} diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx index 1f9d19427..01efe3793 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -1,67 +1,27 @@ import { RECEIPT_STATUS } from '../utils'; -import type { APIError } from '@planet-sdk/common'; -import type { ReceiptDataAPI } from '../../../common/Layout/DonationReceiptContext'; - -import { useContext } from 'react'; import { useRouter } from 'next/router'; import { useTranslations } from 'next-intl'; -import { handleError } from '@planet-sdk/common'; import EditIcon from '../../../../../public/assets/images/icons/EditIcon'; import WebappButton from '../../../common/WebappButton'; import styles from '../donationReceipt.module.scss'; import DownloadIcon from '../../../../../public/assets/images/icons/projectV2/DownloadIcon'; -import { putRequest } from '../../../../utils/apiRequests/api'; -import { useTenant } from '../../../common/Layout/TenantContext'; -import { ErrorHandlingContext } from '../../../common/Layout/ErrorHandlingContext'; + +export type Operation = (typeof RECEIPT_STATUS)[keyof typeof RECEIPT_STATUS]; type Props = { downloadUrl: string | null; - operation: (typeof RECEIPT_STATUS)[keyof typeof RECEIPT_STATUS]; - hasDonorDataChanged: boolean; - dtn: string; - challenge: string; - year: string; - updateDonationReceiptData: (data: Partial) => void; + operation: Operation; + confirmDonorData: () => Promise; }; const ReceiptActions = ({ downloadUrl, operation, - hasDonorDataChanged, - dtn, - challenge, - year, - updateDonationReceiptData, + confirmDonorData, }: Props) => { const t = useTranslations('Donate.donationReceipt'); const router = useRouter(); - const { tenantConfig } = useTenant(); - const { setErrors } = useContext(ErrorHandlingContext); - - const confirmRecipientData = async () => { - if (operation !== RECEIPT_STATUS.VERIFY) return; - const verificationDate = new Date().toISOString(); - - if (hasDonorDataChanged) { - //TODO: PUT Authentication request logic - } - try { - const data = await putRequest({ - tenant: tenantConfig.id, - url: `/app/donationReceipt/verify`, - data: { - dtn, - challenge, - year, - verificationDate, - }, - }); - if (data) updateDonationReceiptData(data); - } catch (error) { - setErrors(handleError(error as APIError)); - } - }; const showDowloadButton = operation === RECEIPT_STATUS.DOWNLOAD && downloadUrl !== null; return ( @@ -90,7 +50,7 @@ const ReceiptActions = ({ variant="primary" text={t('confirm')} elementType="button" - onClick={confirmRecipientData} + onClick={confirmDonorData} /> )} diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index 9ebe5b193..91b85b100 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -1,12 +1,20 @@ +import { useCallback, useContext, useState } from 'react'; import { useDonationReceipt, type ReceiptData, } from '../../../common/Layout/DonationReceiptContext'; +import type { APIError } from '@planet-sdk/common'; +import { handleError } from '@planet-sdk/common'; import styles from '../donationReceipt.module.scss'; import DonationData from './DonationData'; import ReceiptActions from './ReceiptActions'; import RecipientDetails from './RecipientDetails'; +import { getVerificationDate, RECEIPT_STATUS } from '../utils'; +import { useTenant } from '../../../common/Layout/TenantContext'; +import { putRequest } from '../../../../utils/apiRequests/api'; +import { ErrorHandlingContext } from '../../../common/Layout/ErrorHandlingContext'; +import { CircularProgress } from '@mui/material'; interface Prop { donationReceiptData: ReceiptData | null; @@ -15,6 +23,9 @@ interface Prop { const ReceiptDataSection = ({ donationReceiptData }: Prop) => { if (!donationReceiptData) return null; const { updateDonationReceiptData } = useDonationReceipt(); + const { tenantConfig } = useTenant(); + const { setErrors } = useContext(ErrorHandlingContext); + const [isLoading, setIsLoading] = useState(false); const { issuedDonations, downloadUrl, @@ -26,19 +37,57 @@ const ReceiptDataSection = ({ donationReceiptData }: Prop) => { challenge, year, } = donationReceiptData; + + const confirmDonorData = useCallback(async () => { + if (operation !== RECEIPT_STATUS.VERIFY) return; + + if (hasDonorDataChanged) { + //TODO: PUT Authentication request logic + } + + try { + setIsLoading(true); + const data = await putRequest({ + tenant: tenantConfig.id, + url: `/app/donationReceipt/verify`, + data: { + dtn, + challenge, + year, + verificationDate: getVerificationDate(), + }, + }); + if (data) updateDonationReceiptData(data); + } catch (error) { + setErrors(handleError(error as APIError)); + } finally { + setIsLoading(false); + } + }, [ + operation, + hasDonorDataChanged, + tenantConfig.id, + dtn, + challenge, + year, + updateDonationReceiptData, + ]); + return (
    - + {!isLoading ? ( + + ) : ( +
    + +
    + )}
    ); }; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx index c741730af..b68d0c9fb 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx @@ -1,15 +1,18 @@ +import type { Operation } from './ReceiptActions'; + import { useTranslations } from 'next-intl'; import styles from '../donationReceipt.module.scss'; +import { RECEIPT_STATUS } from '../utils'; type Props = { - verificationDate: string | null; + operation: Operation; }; -const ReceiptVerificationHeader = ({ verificationDate }: Props) => { +const ReceiptVerificationHeader = ({ operation }: Props) => { const t = useTranslations('Donate.donationReceipt'); return (
    - {verificationDate ? ( + {operation === RECEIPT_STATUS.DOWNLOAD ? (

    {t('downloadTaxReceipt')}

    ) : ( <> diff --git a/src/features/user/DonationReceipt/utils.ts b/src/features/user/DonationReceipt/utils.ts index 6009223ba..9145e9f44 100644 --- a/src/features/user/DonationReceipt/utils.ts +++ b/src/features/user/DonationReceipt/utils.ts @@ -42,3 +42,9 @@ export const formatReceiptData = ( hasDonorDataChanged: false, }; }; + +export const getVerificationDate = () => { + const isoDate = new Date().toISOString(); + const verificationDate = isoDate.replace('T', ' ').split('.')[0]; + return verificationDate; +}; From 51bc65b7ad84c3abb64fbac22998a723c012ee51 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:32:18 +0530 Subject: [PATCH 17/31] refactor: rename recipientDetails to donorDetails --- .../user/DonationReceipt/donationReceipt.module.scss | 2 +- .../{RecipientDetails.tsx => DonorDetails.tsx} | 6 +++--- .../DonationReceipt/microComponents/ReceiptDataSection.tsx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/features/user/DonationReceipt/microComponents/{RecipientDetails.tsx => DonorDetails.tsx} (93%) diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index 05f72a29d..3d51bdb2e 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -101,7 +101,7 @@ border-bottom: 1px solid #ccc; } -.recipientDetails { +.donorDetails { display: flex; flex-direction: column; gap: 20px; diff --git a/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx similarity index 93% rename from src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx rename to src/features/user/DonationReceipt/microComponents/DonorDetails.tsx index f81ffa9fd..9691fa5b4 100644 --- a/src/features/user/DonationReceipt/microComponents/RecipientDetails.tsx +++ b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx @@ -14,7 +14,7 @@ interface Props { address: AddressView | undefined; } -const RecipientDetails = ({ donor, address }: Props) => { +const DonorDetails = ({ donor, address }: Props) => { if (address === undefined || donor === undefined) return null; const t = useTranslations('Donate'); @@ -29,7 +29,7 @@ const RecipientDetails = ({ donor, address }: Props) => { ); return ( -
    +

    {t('donationReceipt.recipientInfoHeader')}

    @@ -66,4 +66,4 @@ const RecipientDetails = ({ donor, address }: Props) => { ); }; -export default RecipientDetails; +export default DonorDetails; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index 91b85b100..eb7b85389 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -9,7 +9,7 @@ import { handleError } from '@planet-sdk/common'; import styles from '../donationReceipt.module.scss'; import DonationData from './DonationData'; import ReceiptActions from './ReceiptActions'; -import RecipientDetails from './RecipientDetails'; +import DonorDetails from './DonorDetails'; import { getVerificationDate, RECEIPT_STATUS } from '../utils'; import { useTenant } from '../../../common/Layout/TenantContext'; import { putRequest } from '../../../../utils/apiRequests/api'; @@ -76,7 +76,7 @@ const ReceiptDataSection = ({ donationReceiptData }: Prop) => { return (
    - + {!isLoading ? ( Date: Tue, 28 Jan 2025 10:08:06 +0530 Subject: [PATCH 18/31] feat: add reusable SCSS mixin for flexible layout management --- .../donationReceipt.module.scss | 84 ++++++++++--------- .../microComponents/DonorDetails.tsx | 2 +- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index 3d51bdb2e..a4f429cee 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -1,17 +1,40 @@ @import '../../../theme/theme'; +@mixin flex-layout( + $display: flex, + $flex-direction: null, + $justify-content: null, + $align-items: null, + $gap: null +) { + display: $display; + + @if $justify-content { + justify-content: $justify-content; + } + + @if $align-items { + align-items: $align-items; + } + + @if $gap { + gap: $gap; + } + + @if $flex-direction { + flex-direction: $flex-direction; + } +} + .donationReceiptSkeleton { - display: flex; - justify-content: center; + @include flex-layout(flex, null, center); margin-top: 110px; } .donationReceiptLayout { + @include flex-layout(flex, column, null, center); width: 100vw; height: calc(100vh - 80px); - display: flex; - flex-direction: column; - align-items: center; margin-top: 80px; background: var(--background-base); @include xsPhoneView { @@ -20,27 +43,25 @@ } .donationReceiptContainer { - display: flex; - gap: 20px; - flex-direction: column; + @include flex-layout(flex, column, null, null, 20px); width: 100%; max-width: 760px; min-height: 60px; margin-top: 60px; @include xsPhoneView { - align-items: center; + @include flex-layout(flex, null, null, center); } } .receiptVerificationHeader { h2 { - font-size: 20px; + font-size: $fontLarge; font-weight: 600; } h3 { - font-size: 14px; - font-family: 400; + font-size: $fontSmall; + font-weight: 400; color: rgba(51, 51, 51, 1); } } @@ -53,15 +74,12 @@ } .donationRecord { - display: flex; - flex-direction: column; - gap: 12px; + @include flex-layout(flex, column, null, null, 12px); width: 100%; padding: 6px 16px 16px 16px; .header { - display: flex; - justify-content: space-between; + @include flex-layout(flex, null, space-between); font-weight: 600; } } @@ -75,9 +93,7 @@ } .record { - display: flex; - justify-content: space-between; - align-items: center; + @include flex-layout(flex, null, space-between, center); padding-top: 8px; padding-bottom: 8px; @@ -102,9 +118,7 @@ } .donorDetails { - display: flex; - flex-direction: column; - gap: 20px; + @include flex-layout(flex, column, null, null, 20px); background: rgba(242, 242, 242, 0.5); width: 100%; margin-top: 20px; @@ -113,42 +127,35 @@ .header { font-weight: 600; - font-size: 14px; + font-size: $fontSmall; } .details { - display: flex; - justify-content: space-between; - flex-direction: row; + @include flex-layout(flex, row, space-between, null, 28px); flex-wrap: wrap; - gap: 28px; } } .address, -.Name, +.donorName, .companyName, .tin { - display: flex; - flex-direction: column; + @include flex-layout(flex, column, null, null, 7px); color: rgba(130, 130, 130, 1); - gap: 7px; .header { - font-size: 12px; + font-size: $fontXSmall; font-weight: 700; } } .receiptActions { + @include flex-layout(flex, null, flex-end, null, 12px); margin-top: 40px; - display: flex; - gap: 12px; padding: 0px 10px; - justify-content: flex-end; @include xsPhoneView { - flex-direction: column; + @include flex-layout(flex, column); } button { @@ -161,7 +168,6 @@ } .receiptVerificationSpinner { - display: flex; - justify-content: center; + @include flex-layout(flex, null, center); margin-top: 40px; } diff --git a/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx index 9691fa5b4..dfb7eb13b 100644 --- a/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx +++ b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx @@ -34,7 +34,7 @@ const DonorDetails = ({ donor, address }: Props) => { {t('donationReceipt.recipientInfoHeader')}
    -
    +
    {t('donationReceipt.name', { type, From fc5d5d45f154c86ef3d163c5c3d693a348002ec1 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:43:09 +0530 Subject: [PATCH 19/31] refactor: replace donation term with donor --- .../[slug]/[locale]/verify-receipt-data.tsx | 10 ++--- ...iptContext.tsx => DonorReceiptContext.tsx} | 40 ++++++++++--------- ...ceiptLayout.tsx => DonorReceiptLayout.tsx} | 21 +++++----- .../donationReceipt.module.scss | 6 +-- .../microComponents/DonationData.tsx | 2 +- .../microComponents/DonorDetails.tsx | 4 +- .../microComponents/ReceiptActions.tsx | 2 +- .../microComponents/ReceiptDataSection.tsx | 24 +++++------ src/features/user/DonationReceipt/utils.ts | 2 +- 9 files changed, 55 insertions(+), 56 deletions(-) rename src/features/common/Layout/{DonationReceiptContext.tsx => DonorReceiptContext.tsx} (63%) rename src/features/user/DonationReceipt/{DonationReceiptLayout.tsx => DonorReceiptLayout.tsx} (75%) diff --git a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx index 0d88e5e3a..e40996dbc 100644 --- a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx +++ b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx @@ -16,8 +16,8 @@ import { import getMessagesForPage from '../../../../src/utils/language/getMessagesForPage'; import { defaultTenant } from '../../../../tenant.config'; import { useTenant } from '../../../../src/features/common/Layout/TenantContext'; -import DonationReceiptLayout from '../../../../src/features/user/DonationReceipt/DonationReceiptLayout'; -import { DonationReceiptProvider } from '../../../../src/features/common/Layout/DonationReceiptContext'; +import DonorReceiptLayout from '../../../../src/features/user/DonationReceipt/DonorReceiptLayout'; +import { DonorReceiptProvider } from '../../../../src/features/common/Layout/DonorReceiptContext'; interface PageProps { messages: AbstractIntlMessages; @@ -39,9 +39,9 @@ export default function DonationReceipt({ }, [router.isReady]); return ( - - - + + + ); } diff --git a/src/features/common/Layout/DonationReceiptContext.tsx b/src/features/common/Layout/DonorReceiptContext.tsx similarity index 63% rename from src/features/common/Layout/DonationReceiptContext.tsx rename to src/features/common/Layout/DonorReceiptContext.tsx index 088426394..65b7b763a 100644 --- a/src/features/common/Layout/DonationReceiptContext.tsx +++ b/src/features/common/Layout/DonorReceiptContext.tsx @@ -63,46 +63,48 @@ export interface ReceiptData extends ReceiptDataBase { hasDonorDataChanged: boolean; // Set it to true if the user modifies the data during the receipt verification process } -interface DonationReceiptContextInterface { - donationReceiptData: ReceiptData | null; - updateDonationReceiptData: (data: Partial) => void; +interface DonorReceiptContextInterface { + donorReceiptData: ReceiptData | null; + updateDonorReceiptData: (data: Partial) => void; } -const DonationReceiptContext = - createContext(null); +const DonorReceiptContext = createContext( + null +); -export const DonationReceiptProvider: FC = ({ children }) => { - const [donationReceiptData, setDonationReceiptData] = - useState(null); +export const DonorReceiptProvider: FC = ({ children }) => { + const [donorReceiptData, setDonorReceiptData] = useState( + null + ); - const updateDonationReceiptData = (data: Partial) => { + const updateDonorReceiptData = (data: Partial) => { const formattedData = formatReceiptData(data); - setDonationReceiptData((prevState) => ({ + setDonorReceiptData((prevState) => ({ ...prevState, ...formattedData, })); }; - const value: DonationReceiptContextInterface = useMemo( + const value: DonorReceiptContextInterface = useMemo( () => ({ - donationReceiptData, - updateDonationReceiptData, + donorReceiptData, + updateDonorReceiptData, }), - [updateDonationReceiptData, donationReceiptData] + [updateDonorReceiptData, donorReceiptData] ); return ( - + {children} - + ); }; -export const useDonationReceipt = (): DonationReceiptContextInterface => { - const context = useContext(DonationReceiptContext); +export const useDonorReceipt = (): DonorReceiptContextInterface => { + const context = useContext(DonorReceiptContext); if (!context) throw new Error( - 'DonationReceiptContext must be used within DonationReceiptProvider' + 'DonorReceiptContext must be used within DonorReceiptProvider' ); return context; }; diff --git a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonorReceiptLayout.tsx similarity index 75% rename from src/features/user/DonationReceipt/DonationReceiptLayout.tsx rename to src/features/user/DonationReceipt/DonorReceiptLayout.tsx index beb89e26b..0aeeb0198 100644 --- a/src/features/user/DonationReceipt/DonationReceiptLayout.tsx +++ b/src/features/user/DonationReceipt/DonorReceiptLayout.tsx @@ -1,4 +1,4 @@ -import type { ReceiptDataAPI } from '../../common/Layout/DonationReceiptContext'; +import type { ReceiptDataAPI } from '../../common/Layout/DonorReceiptContext'; import type { APIError } from '@planet-sdk/common'; import { useContext, useEffect, useState } from 'react'; @@ -6,7 +6,7 @@ import { handleError } from '@planet-sdk/common'; import Skeleton from 'react-loading-skeleton'; import 'react-loading-skeleton/dist/skeleton.css'; import { useRouter } from 'next/router'; -import { useDonationReceipt } from '../../common/Layout/DonationReceiptContext'; +import { useDonorReceipt } from '../../common/Layout/DonorReceiptContext'; import styles from './donationReceipt.module.scss'; import ReceiptDataSection from './microComponents/ReceiptDataSection'; import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; @@ -15,15 +15,14 @@ import { useTenant } from '../../common/Layout/TenantContext'; import { getRequest } from '../../../utils/apiRequests/api'; import { ErrorHandlingContext } from '../../common/Layout/ErrorHandlingContext'; -export const DonationReceiptLayout = () => { +export const DonorReceiptLayout = () => { const [isLoading, setIsLoading] = useState(false); const { tenantConfig } = useTenant(); const { setErrors, redirect } = useContext(ErrorHandlingContext); const router = useRouter(); const { dtn, year, challenge } = router.query; - const { updateDonationReceiptData, donationReceiptData } = - useDonationReceipt(); - const showReceipt = !isLoading && donationReceiptData !== null; + const { updateDonorReceiptData, donorReceiptData } = useDonorReceipt(); + const showReceipt = !isLoading && donorReceiptData !== null; useEffect(() => { if (!(dtn || year || challenge || router.isReady)) return; @@ -45,7 +44,7 @@ export const DonationReceiptLayout = () => { challenge, }, }); - if (data) updateDonationReceiptData(data); + if (data) updateDonorReceiptData(data); } catch (err) { setErrors(handleError(err as APIError)); redirect('/'); @@ -58,10 +57,10 @@ export const DonationReceiptLayout = () => { }, [dtn, year, challenge, router.isReady]); return showReceipt ? ( -
    +
    - - + +
    @@ -72,4 +71,4 @@ export const DonationReceiptLayout = () => { ); }; -export default DonationReceiptLayout; +export default DonorReceiptLayout; diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/donationReceipt.module.scss index a4f429cee..2cce63ccf 100644 --- a/src/features/user/DonationReceipt/donationReceipt.module.scss +++ b/src/features/user/DonationReceipt/donationReceipt.module.scss @@ -31,7 +31,7 @@ margin-top: 110px; } -.donationReceiptLayout { +.donorReceiptLayout { @include flex-layout(flex, column, null, center); width: 100vw; height: calc(100vh - 80px); @@ -80,7 +80,7 @@ .header { @include flex-layout(flex, null, space-between); - font-weight: 600; + font-weight: 700; } } @@ -126,7 +126,7 @@ padding: 10px 15px; .header { - font-weight: 600; + font-weight: 700; font-size: $fontSmall; } diff --git a/src/features/user/DonationReceipt/microComponents/DonationData.tsx b/src/features/user/DonationReceipt/microComponents/DonationData.tsx index 80e430737..16d77e1fc 100644 --- a/src/features/user/DonationReceipt/microComponents/DonationData.tsx +++ b/src/features/user/DonationReceipt/microComponents/DonationData.tsx @@ -1,4 +1,4 @@ -import type { IssuedDonationView } from '../../../common/Layout/DonationReceiptContext'; +import type { IssuedDonationView } from '../../../common/Layout/DonorReceiptContext'; import { useTranslations } from 'next-intl'; import styles from '../donationReceipt.module.scss'; diff --git a/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx index dfb7eb13b..ca8e428e6 100644 --- a/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx +++ b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx @@ -1,13 +1,13 @@ import type { AddressView, DonorView, -} from '../../../../features/common/Layout/DonationReceiptContext'; +} from '../../../common/Layout/DonorReceiptContext'; import type { CountryCode } from '@planet-sdk/common'; +import { useMemo } from 'react'; import { useTranslations } from 'next-intl'; import styles from '../donationReceipt.module.scss'; import { getFormattedAddress } from '../../../../utils/addressManagement'; -import { useMemo } from 'react'; interface Props { donor: DonorView | undefined; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx index 01efe3793..fcc250841 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -1,6 +1,6 @@ -import { RECEIPT_STATUS } from '../utils'; import { useRouter } from 'next/router'; import { useTranslations } from 'next-intl'; +import { RECEIPT_STATUS } from '../utils'; import EditIcon from '../../../../../public/assets/images/icons/EditIcon'; import WebappButton from '../../../common/WebappButton'; import styles from '../donationReceipt.module.scss'; diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index eb7b85389..bfcf99a83 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -1,11 +1,10 @@ -import { useCallback, useContext, useState } from 'react'; -import { - useDonationReceipt, - type ReceiptData, -} from '../../../common/Layout/DonationReceiptContext'; +import type { ReceiptData } from '../../../common/Layout/DonorReceiptContext'; import type { APIError } from '@planet-sdk/common'; +import { useCallback, useContext, useState } from 'react'; import { handleError } from '@planet-sdk/common'; +import { CircularProgress } from '@mui/material'; +import { useDonorReceipt } from '../../../common/Layout/DonorReceiptContext'; import styles from '../donationReceipt.module.scss'; import DonationData from './DonationData'; import ReceiptActions from './ReceiptActions'; @@ -14,15 +13,14 @@ import { getVerificationDate, RECEIPT_STATUS } from '../utils'; import { useTenant } from '../../../common/Layout/TenantContext'; import { putRequest } from '../../../../utils/apiRequests/api'; import { ErrorHandlingContext } from '../../../common/Layout/ErrorHandlingContext'; -import { CircularProgress } from '@mui/material'; interface Prop { - donationReceiptData: ReceiptData | null; + donorReceiptData: ReceiptData | null; } -const ReceiptDataSection = ({ donationReceiptData }: Prop) => { - if (!donationReceiptData) return null; - const { updateDonationReceiptData } = useDonationReceipt(); +const ReceiptDataSection = ({ donorReceiptData }: Prop) => { + if (!donorReceiptData) return null; + const { updateDonorReceiptData } = useDonorReceipt(); const { tenantConfig } = useTenant(); const { setErrors } = useContext(ErrorHandlingContext); const [isLoading, setIsLoading] = useState(false); @@ -36,7 +34,7 @@ const ReceiptDataSection = ({ donationReceiptData }: Prop) => { dtn, challenge, year, - } = donationReceiptData; + } = donorReceiptData; const confirmDonorData = useCallback(async () => { if (operation !== RECEIPT_STATUS.VERIFY) return; @@ -57,7 +55,7 @@ const ReceiptDataSection = ({ donationReceiptData }: Prop) => { verificationDate: getVerificationDate(), }, }); - if (data) updateDonationReceiptData(data); + if (data) updateDonorReceiptData(data); } catch (error) { setErrors(handleError(error as APIError)); } finally { @@ -70,7 +68,7 @@ const ReceiptDataSection = ({ donationReceiptData }: Prop) => { dtn, challenge, year, - updateDonationReceiptData, + updateDonorReceiptData, ]); return ( diff --git a/src/features/user/DonationReceipt/utils.ts b/src/features/user/DonationReceipt/utils.ts index 9145e9f44..b0664755c 100644 --- a/src/features/user/DonationReceipt/utils.ts +++ b/src/features/user/DonationReceipt/utils.ts @@ -1,7 +1,7 @@ import type { ReceiptDataAPI, ReceiptData, -} from '../../common/Layout/DonationReceiptContext'; +} from '../../common/Layout/DonorReceiptContext'; export const RECEIPT_STATUS = { VERIFY: 'verify', From 9c6b64e1bed3c6afaf475a17153640ac1a924e96 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:50:11 +0530 Subject: [PATCH 20/31] refactor : change the folder name to donor receipt --- pages/sites/[slug]/[locale]/verify-receipt-data.tsx | 2 +- src/features/common/Layout/DonorReceiptContext.tsx | 2 +- .../{DonationReceipt => DonorReceipt}/DonorReceiptLayout.tsx | 0 .../donationReceipt.module.scss | 0 .../microComponents/DonationData.tsx | 0 .../microComponents/DonorDetails.tsx | 0 .../microComponents/ReceiptActions.tsx | 0 .../microComponents/ReceiptDataSection.tsx | 0 .../microComponents/ReceiptListRedirect.tsx | 0 .../microComponents/ReceiptVerificationHeader.tsx | 0 src/features/user/{DonationReceipt => DonorReceipt}/utils.ts | 0 11 files changed, 2 insertions(+), 2 deletions(-) rename src/features/user/{DonationReceipt => DonorReceipt}/DonorReceiptLayout.tsx (100%) rename src/features/user/{DonationReceipt => DonorReceipt}/donationReceipt.module.scss (100%) rename src/features/user/{DonationReceipt => DonorReceipt}/microComponents/DonationData.tsx (100%) rename src/features/user/{DonationReceipt => DonorReceipt}/microComponents/DonorDetails.tsx (100%) rename src/features/user/{DonationReceipt => DonorReceipt}/microComponents/ReceiptActions.tsx (100%) rename src/features/user/{DonationReceipt => DonorReceipt}/microComponents/ReceiptDataSection.tsx (100%) rename src/features/user/{DonationReceipt => DonorReceipt}/microComponents/ReceiptListRedirect.tsx (100%) rename src/features/user/{DonationReceipt => DonorReceipt}/microComponents/ReceiptVerificationHeader.tsx (100%) rename src/features/user/{DonationReceipt => DonorReceipt}/utils.ts (100%) diff --git a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx index e40996dbc..691833b7b 100644 --- a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx +++ b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx @@ -16,7 +16,7 @@ import { import getMessagesForPage from '../../../../src/utils/language/getMessagesForPage'; import { defaultTenant } from '../../../../tenant.config'; import { useTenant } from '../../../../src/features/common/Layout/TenantContext'; -import DonorReceiptLayout from '../../../../src/features/user/DonationReceipt/DonorReceiptLayout'; +import DonorReceiptLayout from '../../../../src/features/user/DonorReceipt/DonorReceiptLayout'; import { DonorReceiptProvider } from '../../../../src/features/common/Layout/DonorReceiptContext'; interface PageProps { diff --git a/src/features/common/Layout/DonorReceiptContext.tsx b/src/features/common/Layout/DonorReceiptContext.tsx index 65b7b763a..1af873337 100644 --- a/src/features/common/Layout/DonorReceiptContext.tsx +++ b/src/features/common/Layout/DonorReceiptContext.tsx @@ -1,7 +1,7 @@ import type { FC } from 'react'; import { useMemo, useState, createContext, useContext } from 'react'; -import { formatReceiptData } from '../../user/DonationReceipt/utils'; +import { formatReceiptData } from '../../user/DonorReceipt/utils'; export type IssuedDonationView = { amount: number; diff --git a/src/features/user/DonationReceipt/DonorReceiptLayout.tsx b/src/features/user/DonorReceipt/DonorReceiptLayout.tsx similarity index 100% rename from src/features/user/DonationReceipt/DonorReceiptLayout.tsx rename to src/features/user/DonorReceipt/DonorReceiptLayout.tsx diff --git a/src/features/user/DonationReceipt/donationReceipt.module.scss b/src/features/user/DonorReceipt/donationReceipt.module.scss similarity index 100% rename from src/features/user/DonationReceipt/donationReceipt.module.scss rename to src/features/user/DonorReceipt/donationReceipt.module.scss diff --git a/src/features/user/DonationReceipt/microComponents/DonationData.tsx b/src/features/user/DonorReceipt/microComponents/DonationData.tsx similarity index 100% rename from src/features/user/DonationReceipt/microComponents/DonationData.tsx rename to src/features/user/DonorReceipt/microComponents/DonationData.tsx diff --git a/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx b/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx similarity index 100% rename from src/features/user/DonationReceipt/microComponents/DonorDetails.tsx rename to src/features/user/DonorReceipt/microComponents/DonorDetails.tsx diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx similarity index 100% rename from src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx rename to src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx similarity index 100% rename from src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx rename to src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptListRedirect.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptListRedirect.tsx similarity index 100% rename from src/features/user/DonationReceipt/microComponents/ReceiptListRedirect.tsx rename to src/features/user/DonorReceipt/microComponents/ReceiptListRedirect.tsx diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptVerificationHeader.tsx similarity index 100% rename from src/features/user/DonationReceipt/microComponents/ReceiptVerificationHeader.tsx rename to src/features/user/DonorReceipt/microComponents/ReceiptVerificationHeader.tsx diff --git a/src/features/user/DonationReceipt/utils.ts b/src/features/user/DonorReceipt/utils.ts similarity index 100% rename from src/features/user/DonationReceipt/utils.ts rename to src/features/user/DonorReceipt/utils.ts From 188dcf971c38a2e904f30b6949e7635395395d45 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 28 Jan 2025 11:22:57 +0530 Subject: [PATCH 21/31] feat(ui): right-align download button for mobile version --- .../DonorReceipt/donationReceipt.module.scss | 4 ++++ .../microComponents/ReceiptActions.tsx | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/features/user/DonorReceipt/donationReceipt.module.scss b/src/features/user/DonorReceipt/donationReceipt.module.scss index 2cce63ccf..1843d0f16 100644 --- a/src/features/user/DonorReceipt/donationReceipt.module.scss +++ b/src/features/user/DonorReceipt/donationReceipt.module.scss @@ -167,6 +167,10 @@ } } +.downloadButtonContainer { + @include flex-layout(flex, null, flex-end); +} + .receiptVerificationSpinner { @include flex-layout(flex, null, center); margin-top: 40px; diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx index fcc250841..09fc2f6b7 100644 --- a/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx @@ -27,14 +27,16 @@ const ReceiptActions = ({ return (
    {showDowloadButton ? ( - } - href={downloadUrl} - target={'_blank'} - /> +
    + } + href={downloadUrl} + target={'_blank'} + /> +
    ) : ( <> Date: Tue, 28 Jan 2025 11:54:24 +0530 Subject: [PATCH 22/31] refactor: create a file to store donor receipt type --- .../common/Layout/DonorReceiptContext.tsx | 64 ++----------------- .../user/DonorReceipt/DonorReceiptLayout.tsx | 2 +- .../user/DonorReceipt/donorReceipt.d.ts | 59 +++++++++++++++++ .../microComponents/DonationData.tsx | 2 +- .../microComponents/DonorDetails.tsx | 5 +- .../microComponents/ReceiptDataSection.tsx | 2 +- src/features/user/DonorReceipt/utils.ts | 5 +- 7 files changed, 68 insertions(+), 71 deletions(-) create mode 100644 src/features/user/DonorReceipt/donorReceipt.d.ts diff --git a/src/features/common/Layout/DonorReceiptContext.tsx b/src/features/common/Layout/DonorReceiptContext.tsx index 1af873337..7b894967e 100644 --- a/src/features/common/Layout/DonorReceiptContext.tsx +++ b/src/features/common/Layout/DonorReceiptContext.tsx @@ -1,68 +1,12 @@ import type { FC } from 'react'; +import type { + ReceiptData, + ReceiptDataAPI, +} from '../../user/DonorReceipt/donorReceipt'; import { useMemo, useState, createContext, useContext } from 'react'; import { formatReceiptData } from '../../user/DonorReceipt/utils'; -export type IssuedDonationView = { - amount: number; - currency: string; - paymentDate: string; - reference: string; -}; - -export type DonorAPI = { - tin: string | null; - city: string; - name: string; - type: 'individual' | 'organization'; - email: string; - country: string; - zipCode: string; - address1: string; - address2: string | null; - reference: string; -}; - -export type DonorView = { - tin: string | null; - name: string; - type: 'individual' | 'organization' | null; -}; - -export type AddressView = { - city: string; - country: string; - zipCode: string; - address1: string; - address2: string | null; -}; - -type ReceiptDataBase = { - dtn: string; - year: string; - challenge: string; - amount: number; - currency: string; - paymentDate: string; - verificationDate: string | null; - downloadUrl: string; - donationCount: number; -}; - -export interface ReceiptDataAPI extends ReceiptDataBase { - country: string; - reference: string; - donor: DonorAPI; - donations: IssuedDonationView[]; -} -export interface ReceiptData extends ReceiptDataBase { - operation: 'verify' | 'download'; - donor: DonorView; - address: AddressView; - issuedDonations: IssuedDonationView[] | null; - hasDonorDataChanged: boolean; // Set it to true if the user modifies the data during the receipt verification process -} - interface DonorReceiptContextInterface { donorReceiptData: ReceiptData | null; updateDonorReceiptData: (data: Partial) => void; diff --git a/src/features/user/DonorReceipt/DonorReceiptLayout.tsx b/src/features/user/DonorReceipt/DonorReceiptLayout.tsx index 0aeeb0198..a25a33be2 100644 --- a/src/features/user/DonorReceipt/DonorReceiptLayout.tsx +++ b/src/features/user/DonorReceipt/DonorReceiptLayout.tsx @@ -1,4 +1,4 @@ -import type { ReceiptDataAPI } from '../../common/Layout/DonorReceiptContext'; +import type { ReceiptDataAPI } from './donorReceipt'; import type { APIError } from '@planet-sdk/common'; import { useContext, useEffect, useState } from 'react'; diff --git a/src/features/user/DonorReceipt/donorReceipt.d.ts b/src/features/user/DonorReceipt/donorReceipt.d.ts new file mode 100644 index 000000000..c2ce6e7f8 --- /dev/null +++ b/src/features/user/DonorReceipt/donorReceipt.d.ts @@ -0,0 +1,59 @@ +export type IssuedDonationView = { + amount: number; + currency: string; + paymentDate: string; + reference: string; +}; + +export type DonorAPI = { + tin: string | null; + city: string; + name: string; + type: 'individual' | 'organization'; + email: string; + country: string; + zipCode: string; + address1: string; + address2: string | null; + reference: string; +}; + +export type DonorView = { + tin: string | null; + name: string; + type: 'individual' | 'organization' | null; +}; + +export type AddressView = { + city: string; + country: string; + zipCode: string; + address1: string; + address2: string | null; +}; + +type ReceiptDataBase = { + dtn: string; + year: string; + challenge: string; + amount: number; + currency: string; + paymentDate: string; + verificationDate: string | null; + downloadUrl: string; + donationCount: number; +}; + +export interface ReceiptDataAPI extends ReceiptDataBase { + country: string; + reference: string; + donor: DonorAPI; + donations: IssuedDonationView[]; +} +export interface ReceiptData extends ReceiptDataBase { + operation: 'verify' | 'download'; + donor: DonorView; + address: AddressView; + issuedDonations: IssuedDonationView[] | null; + hasDonorDataChanged: boolean; // Set it to true if the user modifies the data during the receipt verification process +} diff --git a/src/features/user/DonorReceipt/microComponents/DonationData.tsx b/src/features/user/DonorReceipt/microComponents/DonationData.tsx index 16d77e1fc..f1981be9f 100644 --- a/src/features/user/DonorReceipt/microComponents/DonationData.tsx +++ b/src/features/user/DonorReceipt/microComponents/DonationData.tsx @@ -1,4 +1,4 @@ -import type { IssuedDonationView } from '../../../common/Layout/DonorReceiptContext'; +import type { IssuedDonationView } from '../donorReceipt'; import { useTranslations } from 'next-intl'; import styles from '../donationReceipt.module.scss'; diff --git a/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx b/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx index ca8e428e6..e7ce3258b 100644 --- a/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx +++ b/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx @@ -1,7 +1,4 @@ -import type { - AddressView, - DonorView, -} from '../../../common/Layout/DonorReceiptContext'; +import type { AddressView, DonorView } from '../donorReceipt'; import type { CountryCode } from '@planet-sdk/common'; import { useMemo } from 'react'; diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx index bfcf99a83..7abb15fdd 100644 --- a/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx @@ -1,4 +1,4 @@ -import type { ReceiptData } from '../../../common/Layout/DonorReceiptContext'; +import type { ReceiptData } from '../donorReceipt'; import type { APIError } from '@planet-sdk/common'; import { useCallback, useContext, useState } from 'react'; diff --git a/src/features/user/DonorReceipt/utils.ts b/src/features/user/DonorReceipt/utils.ts index b0664755c..20260f76f 100644 --- a/src/features/user/DonorReceipt/utils.ts +++ b/src/features/user/DonorReceipt/utils.ts @@ -1,7 +1,4 @@ -import type { - ReceiptDataAPI, - ReceiptData, -} from '../../common/Layout/DonorReceiptContext'; +import type { ReceiptDataAPI, ReceiptData } from './donorReceipt'; export const RECEIPT_STATUS = { VERIFY: 'verify', From 4b7ba7db39c690bdebd6bce2578e9f9a2ca71e6a Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 28 Jan 2025 12:42:57 +0530 Subject: [PATCH 23/31] feat(ui): minor padding adjustment for mobile view --- src/features/user/DonorReceipt/DonorReceiptLayout.tsx | 4 ++-- .../user/DonorReceipt/donationReceipt.module.scss | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/features/user/DonorReceipt/DonorReceiptLayout.tsx b/src/features/user/DonorReceipt/DonorReceiptLayout.tsx index a25a33be2..306bc13d3 100644 --- a/src/features/user/DonorReceipt/DonorReceiptLayout.tsx +++ b/src/features/user/DonorReceipt/DonorReceiptLayout.tsx @@ -58,14 +58,14 @@ export const DonorReceiptLayout = () => { return showReceipt ? (
    -
    +
    ) : ( -
    +
    ); diff --git a/src/features/user/DonorReceipt/donationReceipt.module.scss b/src/features/user/DonorReceipt/donationReceipt.module.scss index 1843d0f16..026cefa08 100644 --- a/src/features/user/DonorReceipt/donationReceipt.module.scss +++ b/src/features/user/DonorReceipt/donationReceipt.module.scss @@ -26,7 +26,7 @@ } } -.donationReceiptSkeleton { +.donorReceiptSkeleton { @include flex-layout(flex, null, center); margin-top: 110px; } @@ -42,7 +42,7 @@ } } -.donationReceiptContainer { +.donorReceiptContainer { @include flex-layout(flex, column, null, null, 20px); width: 100%; max-width: 760px; @@ -78,6 +78,10 @@ width: 100%; padding: 6px 16px 16px 16px; + @include xsPhoneView { + padding: 6px 6px 16px 6px; + } + .header { @include flex-layout(flex, null, space-between); font-weight: 700; From 63bea5a915850b8ad35d0b2275d5a3bf6e1be1fd Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 4 Feb 2025 12:30:28 +0530 Subject: [PATCH 24/31] refactor(feedback) : correct import path case for DonationReceipt.module.scss to match file name convention. --- src/features/user/DonorReceipt/DonorReceiptLayout.tsx | 2 +- src/features/user/DonorReceipt/microComponents/DonationData.tsx | 2 +- src/features/user/DonorReceipt/microComponents/DonorDetails.tsx | 2 +- .../user/DonorReceipt/microComponents/ReceiptActions.tsx | 2 +- .../user/DonorReceipt/microComponents/ReceiptDataSection.tsx | 2 +- .../DonorReceipt/microComponents/ReceiptVerificationHeader.tsx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/features/user/DonorReceipt/DonorReceiptLayout.tsx b/src/features/user/DonorReceipt/DonorReceiptLayout.tsx index 306bc13d3..3091c339d 100644 --- a/src/features/user/DonorReceipt/DonorReceiptLayout.tsx +++ b/src/features/user/DonorReceipt/DonorReceiptLayout.tsx @@ -7,7 +7,7 @@ import Skeleton from 'react-loading-skeleton'; import 'react-loading-skeleton/dist/skeleton.css'; import { useRouter } from 'next/router'; import { useDonorReceipt } from '../../common/Layout/DonorReceiptContext'; -import styles from './donationReceipt.module.scss'; +import styles from './DonationReceipt.module.scss'; import ReceiptDataSection from './microComponents/ReceiptDataSection'; import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; import ReceiptListRedirect from './microComponents/ReceiptListRedirect'; diff --git a/src/features/user/DonorReceipt/microComponents/DonationData.tsx b/src/features/user/DonorReceipt/microComponents/DonationData.tsx index f1981be9f..4e7f65d78 100644 --- a/src/features/user/DonorReceipt/microComponents/DonationData.tsx +++ b/src/features/user/DonorReceipt/microComponents/DonationData.tsx @@ -1,7 +1,7 @@ import type { IssuedDonationView } from '../donorReceipt'; import { useTranslations } from 'next-intl'; -import styles from '../donationReceipt.module.scss'; +import styles from '../DonationReceipt.module.scss'; import formatDate from '../../../../utils/countryCurrency/getFormattedDate'; type Props = { diff --git a/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx b/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx index e7ce3258b..3fd3a2077 100644 --- a/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx +++ b/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx @@ -3,7 +3,7 @@ import type { CountryCode } from '@planet-sdk/common'; import { useMemo } from 'react'; import { useTranslations } from 'next-intl'; -import styles from '../donationReceipt.module.scss'; +import styles from '../DonationReceipt.module.scss'; import { getFormattedAddress } from '../../../../utils/addressManagement'; interface Props { diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx index 09fc2f6b7..94fa18c7e 100644 --- a/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx @@ -3,7 +3,7 @@ import { useTranslations } from 'next-intl'; import { RECEIPT_STATUS } from '../utils'; import EditIcon from '../../../../../public/assets/images/icons/EditIcon'; import WebappButton from '../../../common/WebappButton'; -import styles from '../donationReceipt.module.scss'; +import styles from '../DonationReceipt.module.scss'; import DownloadIcon from '../../../../../public/assets/images/icons/projectV2/DownloadIcon'; export type Operation = (typeof RECEIPT_STATUS)[keyof typeof RECEIPT_STATUS]; diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx index 7abb15fdd..a37313d51 100644 --- a/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx @@ -5,7 +5,7 @@ import { useCallback, useContext, useState } from 'react'; import { handleError } from '@planet-sdk/common'; import { CircularProgress } from '@mui/material'; import { useDonorReceipt } from '../../../common/Layout/DonorReceiptContext'; -import styles from '../donationReceipt.module.scss'; +import styles from '../DonationReceipt.module.scss'; import DonationData from './DonationData'; import ReceiptActions from './ReceiptActions'; import DonorDetails from './DonorDetails'; diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptVerificationHeader.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptVerificationHeader.tsx index b68d0c9fb..48685c98d 100644 --- a/src/features/user/DonorReceipt/microComponents/ReceiptVerificationHeader.tsx +++ b/src/features/user/DonorReceipt/microComponents/ReceiptVerificationHeader.tsx @@ -1,7 +1,7 @@ import type { Operation } from './ReceiptActions'; import { useTranslations } from 'next-intl'; -import styles from '../donationReceipt.module.scss'; +import styles from '../DonationReceipt.module.scss'; import { RECEIPT_STATUS } from '../utils'; type Props = { From 175593027e3d0891a478261e180c7db1132ff39c Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:02:09 +0530 Subject: [PATCH 25/31] refactor: use the term "donation" instead of "donor." --- .../[slug]/[locale]/verify-receipt-data.tsx | 10 ++-- .../common/Layout/DonationReceiptContext.tsx | 52 ++++++++++++++++++ .../common/Layout/DonorReceiptContext.tsx | 54 ------------------- ...ptLayout.tsx => DonationReceiptLayout.tsx} | 25 ++++----- .../DonorReceipt/donationReceipt.module.scss | 6 +-- .../{donorReceipt.d.ts => donationReceipt.ts} | 0 .../microComponents/DonationData.tsx | 2 +- .../microComponents/DonorDetails.tsx | 2 +- .../microComponents/ReceiptActions.tsx | 6 +-- .../microComponents/ReceiptDataSection.tsx | 22 ++++---- src/features/user/DonorReceipt/utils.ts | 2 +- 11 files changed, 90 insertions(+), 91 deletions(-) create mode 100644 src/features/common/Layout/DonationReceiptContext.tsx delete mode 100644 src/features/common/Layout/DonorReceiptContext.tsx rename src/features/user/DonorReceipt/{DonorReceiptLayout.tsx => DonationReceiptLayout.tsx} (72%) rename src/features/user/DonorReceipt/{donorReceipt.d.ts => donationReceipt.ts} (100%) diff --git a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx index 691833b7b..1520e2be6 100644 --- a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx +++ b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx @@ -16,8 +16,8 @@ import { import getMessagesForPage from '../../../../src/utils/language/getMessagesForPage'; import { defaultTenant } from '../../../../tenant.config'; import { useTenant } from '../../../../src/features/common/Layout/TenantContext'; -import DonorReceiptLayout from '../../../../src/features/user/DonorReceipt/DonorReceiptLayout'; -import { DonorReceiptProvider } from '../../../../src/features/common/Layout/DonorReceiptContext'; +import DonationReceiptLayout from '../../../../src/features/user/DonorReceipt/DonationReceiptLayout'; +import { DonationReceiptProvider } from '../../../../src/features/common/Layout/DonationReceiptContext'; interface PageProps { messages: AbstractIntlMessages; @@ -39,9 +39,9 @@ export default function DonationReceipt({ }, [router.isReady]); return ( - - - + + + ); } diff --git a/src/features/common/Layout/DonationReceiptContext.tsx b/src/features/common/Layout/DonationReceiptContext.tsx new file mode 100644 index 000000000..4ce7d06f5 --- /dev/null +++ b/src/features/common/Layout/DonationReceiptContext.tsx @@ -0,0 +1,52 @@ +import type { FC } from 'react'; +import type { + ReceiptData, + ReceiptDataAPI, +} from '../../user/DonorReceipt/donationReceipt'; + +import { useMemo, useState, createContext, useContext } from 'react'; +import { formatReceiptData } from '../../user/DonorReceipt/utils'; + +interface DonationReceiptContextInterface { + donationReceiptData: ReceiptData | null; + updateDonationReceiptData: (data: Partial) => void; +} + +const DonationReceiptContext = + createContext(null); + +export const DonationReceiptProvider: FC = ({ children }) => { + const [donationReceiptData, setDonationReceiptData] = + useState(null); + + const updateDonationReceiptData = (data: Partial) => { + const formattedData = formatReceiptData(data); + setDonationReceiptData((prevState) => ({ + ...prevState, + ...formattedData, + })); + }; + + const value: DonationReceiptContextInterface = useMemo( + () => ({ + donationReceiptData, + updateDonationReceiptData, + }), + [updateDonationReceiptData, donationReceiptData] + ); + + return ( + + {children} + + ); +}; + +export const useDonationReceipt = (): DonationReceiptContextInterface => { + const context = useContext(DonationReceiptContext); + if (!context) + throw new Error( + 'DonationReceiptContext must be used within DonationReceiptProvider' + ); + return context; +}; diff --git a/src/features/common/Layout/DonorReceiptContext.tsx b/src/features/common/Layout/DonorReceiptContext.tsx deleted file mode 100644 index 7b894967e..000000000 --- a/src/features/common/Layout/DonorReceiptContext.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import type { FC } from 'react'; -import type { - ReceiptData, - ReceiptDataAPI, -} from '../../user/DonorReceipt/donorReceipt'; - -import { useMemo, useState, createContext, useContext } from 'react'; -import { formatReceiptData } from '../../user/DonorReceipt/utils'; - -interface DonorReceiptContextInterface { - donorReceiptData: ReceiptData | null; - updateDonorReceiptData: (data: Partial) => void; -} - -const DonorReceiptContext = createContext( - null -); - -export const DonorReceiptProvider: FC = ({ children }) => { - const [donorReceiptData, setDonorReceiptData] = useState( - null - ); - - const updateDonorReceiptData = (data: Partial) => { - const formattedData = formatReceiptData(data); - setDonorReceiptData((prevState) => ({ - ...prevState, - ...formattedData, - })); - }; - - const value: DonorReceiptContextInterface = useMemo( - () => ({ - donorReceiptData, - updateDonorReceiptData, - }), - [updateDonorReceiptData, donorReceiptData] - ); - - return ( - - {children} - - ); -}; - -export const useDonorReceipt = (): DonorReceiptContextInterface => { - const context = useContext(DonorReceiptContext); - if (!context) - throw new Error( - 'DonorReceiptContext must be used within DonorReceiptProvider' - ); - return context; -}; diff --git a/src/features/user/DonorReceipt/DonorReceiptLayout.tsx b/src/features/user/DonorReceipt/DonationReceiptLayout.tsx similarity index 72% rename from src/features/user/DonorReceipt/DonorReceiptLayout.tsx rename to src/features/user/DonorReceipt/DonationReceiptLayout.tsx index 3091c339d..bf519821d 100644 --- a/src/features/user/DonorReceipt/DonorReceiptLayout.tsx +++ b/src/features/user/DonorReceipt/DonationReceiptLayout.tsx @@ -1,4 +1,4 @@ -import type { ReceiptDataAPI } from './donorReceipt'; +import type { ReceiptDataAPI } from './donationReceipt'; import type { APIError } from '@planet-sdk/common'; import { useContext, useEffect, useState } from 'react'; @@ -6,7 +6,7 @@ import { handleError } from '@planet-sdk/common'; import Skeleton from 'react-loading-skeleton'; import 'react-loading-skeleton/dist/skeleton.css'; import { useRouter } from 'next/router'; -import { useDonorReceipt } from '../../common/Layout/DonorReceiptContext'; +import { useDonationReceipt } from '../../common/Layout/DonationReceiptContext'; import styles from './DonationReceipt.module.scss'; import ReceiptDataSection from './microComponents/ReceiptDataSection'; import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; @@ -15,14 +15,15 @@ import { useTenant } from '../../common/Layout/TenantContext'; import { getRequest } from '../../../utils/apiRequests/api'; import { ErrorHandlingContext } from '../../common/Layout/ErrorHandlingContext'; -export const DonorReceiptLayout = () => { +const DonationReceiptLayout = () => { const [isLoading, setIsLoading] = useState(false); const { tenantConfig } = useTenant(); const { setErrors, redirect } = useContext(ErrorHandlingContext); const router = useRouter(); const { dtn, year, challenge } = router.query; - const { updateDonorReceiptData, donorReceiptData } = useDonorReceipt(); - const showReceipt = !isLoading && donorReceiptData !== null; + const { updateDonationReceiptData, donationReceiptData } = + useDonationReceipt(); + const showReceipt = !isLoading && donationReceiptData !== null; useEffect(() => { if (!(dtn || year || challenge || router.isReady)) return; @@ -44,7 +45,7 @@ export const DonorReceiptLayout = () => { challenge, }, }); - if (data) updateDonorReceiptData(data); + if (data) updateDonationReceiptData(data); } catch (err) { setErrors(handleError(err as APIError)); redirect('/'); @@ -57,18 +58,18 @@ export const DonorReceiptLayout = () => { }, [dtn, year, challenge, router.isReady]); return showReceipt ? ( -
    -
    - - +
    +
    + +
    ) : ( -
    +
    ); }; -export default DonorReceiptLayout; +export default DonationReceiptLayout; diff --git a/src/features/user/DonorReceipt/donationReceipt.module.scss b/src/features/user/DonorReceipt/donationReceipt.module.scss index 026cefa08..f5918c67e 100644 --- a/src/features/user/DonorReceipt/donationReceipt.module.scss +++ b/src/features/user/DonorReceipt/donationReceipt.module.scss @@ -26,12 +26,12 @@ } } -.donorReceiptSkeleton { +.donationReceiptSkeleton { @include flex-layout(flex, null, center); margin-top: 110px; } -.donorReceiptLayout { +.donationReceiptLayout { @include flex-layout(flex, column, null, center); width: 100vw; height: calc(100vh - 80px); @@ -42,7 +42,7 @@ } } -.donorReceiptContainer { +.donationReceiptContainer { @include flex-layout(flex, column, null, null, 20px); width: 100%; max-width: 760px; diff --git a/src/features/user/DonorReceipt/donorReceipt.d.ts b/src/features/user/DonorReceipt/donationReceipt.ts similarity index 100% rename from src/features/user/DonorReceipt/donorReceipt.d.ts rename to src/features/user/DonorReceipt/donationReceipt.ts diff --git a/src/features/user/DonorReceipt/microComponents/DonationData.tsx b/src/features/user/DonorReceipt/microComponents/DonationData.tsx index 4e7f65d78..9ea22efb5 100644 --- a/src/features/user/DonorReceipt/microComponents/DonationData.tsx +++ b/src/features/user/DonorReceipt/microComponents/DonationData.tsx @@ -1,4 +1,4 @@ -import type { IssuedDonationView } from '../donorReceipt'; +import type { IssuedDonationView } from '../donationReceipt'; import { useTranslations } from 'next-intl'; import styles from '../DonationReceipt.module.scss'; diff --git a/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx b/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx index 3fd3a2077..941ec2d2e 100644 --- a/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx +++ b/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx @@ -1,4 +1,4 @@ -import type { AddressView, DonorView } from '../donorReceipt'; +import type { AddressView, DonorView } from '../donationReceipt'; import type { CountryCode } from '@planet-sdk/common'; import { useMemo } from 'react'; diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx index 94fa18c7e..327d40cf4 100644 --- a/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx @@ -11,13 +11,13 @@ export type Operation = (typeof RECEIPT_STATUS)[keyof typeof RECEIPT_STATUS]; type Props = { downloadUrl: string | null; operation: Operation; - confirmDonorData: () => Promise; + confirmReceiptData: () => Promise; }; const ReceiptActions = ({ downloadUrl, operation, - confirmDonorData, + confirmReceiptData, }: Props) => { const t = useTranslations('Donate.donationReceipt'); const router = useRouter(); @@ -52,7 +52,7 @@ const ReceiptActions = ({ variant="primary" text={t('confirm')} elementType="button" - onClick={confirmDonorData} + onClick={confirmReceiptData} /> )} diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx index a37313d51..0f6e56a4f 100644 --- a/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx @@ -1,10 +1,10 @@ -import type { ReceiptData } from '../donorReceipt'; +import type { ReceiptData } from '../donationReceipt'; import type { APIError } from '@planet-sdk/common'; import { useCallback, useContext, useState } from 'react'; import { handleError } from '@planet-sdk/common'; import { CircularProgress } from '@mui/material'; -import { useDonorReceipt } from '../../../common/Layout/DonorReceiptContext'; +import { useDonationReceipt } from '../../../common/Layout/DonationReceiptContext'; import styles from '../DonationReceipt.module.scss'; import DonationData from './DonationData'; import ReceiptActions from './ReceiptActions'; @@ -15,12 +15,12 @@ import { putRequest } from '../../../../utils/apiRequests/api'; import { ErrorHandlingContext } from '../../../common/Layout/ErrorHandlingContext'; interface Prop { - donorReceiptData: ReceiptData | null; + donationReceiptData: ReceiptData | null; } -const ReceiptDataSection = ({ donorReceiptData }: Prop) => { - if (!donorReceiptData) return null; - const { updateDonorReceiptData } = useDonorReceipt(); +const ReceiptDataSection = ({ donationReceiptData }: Prop) => { + if (!donationReceiptData) return null; + const { updateDonationReceiptData } = useDonationReceipt(); const { tenantConfig } = useTenant(); const { setErrors } = useContext(ErrorHandlingContext); const [isLoading, setIsLoading] = useState(false); @@ -34,9 +34,9 @@ const ReceiptDataSection = ({ donorReceiptData }: Prop) => { dtn, challenge, year, - } = donorReceiptData; + } = donationReceiptData; - const confirmDonorData = useCallback(async () => { + const confirmReceiptData = useCallback(async () => { if (operation !== RECEIPT_STATUS.VERIFY) return; if (hasDonorDataChanged) { @@ -55,7 +55,7 @@ const ReceiptDataSection = ({ donorReceiptData }: Prop) => { verificationDate: getVerificationDate(), }, }); - if (data) updateDonorReceiptData(data); + if (data) updateDonationReceiptData(data); } catch (error) { setErrors(handleError(error as APIError)); } finally { @@ -68,7 +68,7 @@ const ReceiptDataSection = ({ donorReceiptData }: Prop) => { dtn, challenge, year, - updateDonorReceiptData, + updateDonationReceiptData, ]); return ( @@ -79,7 +79,7 @@ const ReceiptDataSection = ({ donorReceiptData }: Prop) => { ) : (
    diff --git a/src/features/user/DonorReceipt/utils.ts b/src/features/user/DonorReceipt/utils.ts index 20260f76f..d23b2d1da 100644 --- a/src/features/user/DonorReceipt/utils.ts +++ b/src/features/user/DonorReceipt/utils.ts @@ -1,4 +1,4 @@ -import type { ReceiptDataAPI, ReceiptData } from './donorReceipt'; +import type { ReceiptDataAPI, ReceiptData } from './donationReceipt'; export const RECEIPT_STATUS = { VERIFY: 'verify', From 63891068698490de06ac9ea532fa9bda56f9367b Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:21:22 +0530 Subject: [PATCH 26/31] refactor : rename receiptVerificationHeader to verifyReceiptHeader - rename ReceiptListRedirect to ReceiptFooterSection --- src/features/user/DonorReceipt/DonationReceiptLayout.tsx | 8 ++++---- .../user/DonorReceipt/donationReceipt.module.scss | 2 +- .../DonorReceipt/microComponents/ReceiptListRedirect.tsx | 9 --------- .../microComponents/VerifyReceiptFooter .tsx | 9 +++++++++ ...iptVerificationHeader.tsx => VerifyReceiptHeader.tsx} | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 src/features/user/DonorReceipt/microComponents/ReceiptListRedirect.tsx create mode 100644 src/features/user/DonorReceipt/microComponents/VerifyReceiptFooter .tsx rename src/features/user/DonorReceipt/microComponents/{ReceiptVerificationHeader.tsx => VerifyReceiptHeader.tsx} (77%) diff --git a/src/features/user/DonorReceipt/DonationReceiptLayout.tsx b/src/features/user/DonorReceipt/DonationReceiptLayout.tsx index bf519821d..50a6938f6 100644 --- a/src/features/user/DonorReceipt/DonationReceiptLayout.tsx +++ b/src/features/user/DonorReceipt/DonationReceiptLayout.tsx @@ -9,11 +9,11 @@ import { useRouter } from 'next/router'; import { useDonationReceipt } from '../../common/Layout/DonationReceiptContext'; import styles from './DonationReceipt.module.scss'; import ReceiptDataSection from './microComponents/ReceiptDataSection'; -import ReceiptVerificationHeader from './microComponents/ReceiptVerificationHeader'; -import ReceiptListRedirect from './microComponents/ReceiptListRedirect'; +import VerifyReceiptHeader from './microComponents/VerifyReceiptHeader'; import { useTenant } from '../../common/Layout/TenantContext'; import { getRequest } from '../../../utils/apiRequests/api'; import { ErrorHandlingContext } from '../../common/Layout/ErrorHandlingContext'; +import VerifyReceiptFooter from './microComponents/VerifyReceiptFooter '; const DonationReceiptLayout = () => { const [isLoading, setIsLoading] = useState(false); @@ -60,9 +60,9 @@ const DonationReceiptLayout = () => { return showReceipt ? (
    - + - +
    ) : ( diff --git a/src/features/user/DonorReceipt/donationReceipt.module.scss b/src/features/user/DonorReceipt/donationReceipt.module.scss index f5918c67e..2717dc2d8 100644 --- a/src/features/user/DonorReceipt/donationReceipt.module.scss +++ b/src/features/user/DonorReceipt/donationReceipt.module.scss @@ -53,7 +53,7 @@ } } -.receiptVerificationHeader { +.verifyReceiptHeader { h2 { font-size: $fontLarge; font-weight: 600; diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptListRedirect.tsx b/src/features/user/DonorReceipt/microComponents/ReceiptListRedirect.tsx deleted file mode 100644 index bedcb8377..000000000 --- a/src/features/user/DonorReceipt/microComponents/ReceiptListRedirect.tsx +++ /dev/null @@ -1,9 +0,0 @@ -const ReceiptFooterSection = () => { - return ( -
    -
    -
    - ); -}; - -export default ReceiptFooterSection; diff --git a/src/features/user/DonorReceipt/microComponents/VerifyReceiptFooter .tsx b/src/features/user/DonorReceipt/microComponents/VerifyReceiptFooter .tsx new file mode 100644 index 000000000..8ad26167f --- /dev/null +++ b/src/features/user/DonorReceipt/microComponents/VerifyReceiptFooter .tsx @@ -0,0 +1,9 @@ +const VerifyReceiptFooter = () => { + return ( +
    +
    +
    + ); +}; + +export default VerifyReceiptFooter; diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptVerificationHeader.tsx b/src/features/user/DonorReceipt/microComponents/VerifyReceiptHeader.tsx similarity index 77% rename from src/features/user/DonorReceipt/microComponents/ReceiptVerificationHeader.tsx rename to src/features/user/DonorReceipt/microComponents/VerifyReceiptHeader.tsx index 48685c98d..3e545f608 100644 --- a/src/features/user/DonorReceipt/microComponents/ReceiptVerificationHeader.tsx +++ b/src/features/user/DonorReceipt/microComponents/VerifyReceiptHeader.tsx @@ -8,10 +8,10 @@ type Props = { operation: Operation; }; -const ReceiptVerificationHeader = ({ operation }: Props) => { +const VerifyReceiptHeader = ({ operation }: Props) => { const t = useTranslations('Donate.donationReceipt'); return ( -
    +
    {operation === RECEIPT_STATUS.DOWNLOAD ? (

    {t('downloadTaxReceipt')}

    ) : ( @@ -24,4 +24,4 @@ const ReceiptVerificationHeader = ({ operation }: Props) => { ); }; -export default ReceiptVerificationHeader; +export default VerifyReceiptHeader; From 06a320afeb0ebef7e3171db1fa91b2e32027c711 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:43:56 +0530 Subject: [PATCH 27/31] refactor : change the folder name from DonorReceipt to DonationReceipt --- pages/sites/[slug]/[locale]/verify-receipt-data.tsx | 2 +- src/features/common/Layout/DonationReceiptContext.tsx | 4 ++-- .../DonationReceipt.module.scss} | 0 .../DonationReceiptLayout.tsx | 0 .../user/{DonorReceipt => DonationReceipt}/donationReceipt.ts | 0 .../microComponents/DonationData.tsx | 0 .../microComponents/DonorDetails.tsx | 0 .../microComponents/ReceiptActions.tsx | 0 .../microComponents/ReceiptDataSection.tsx | 0 .../microComponents/VerifyReceiptFooter .tsx | 0 .../microComponents/VerifyReceiptHeader.tsx | 0 src/features/user/{DonorReceipt => DonationReceipt}/utils.ts | 0 12 files changed, 3 insertions(+), 3 deletions(-) rename src/features/user/{DonorReceipt/donationReceipt.module.scss => DonationReceipt/DonationReceipt.module.scss} (100%) rename src/features/user/{DonorReceipt => DonationReceipt}/DonationReceiptLayout.tsx (100%) rename src/features/user/{DonorReceipt => DonationReceipt}/donationReceipt.ts (100%) rename src/features/user/{DonorReceipt => DonationReceipt}/microComponents/DonationData.tsx (100%) rename src/features/user/{DonorReceipt => DonationReceipt}/microComponents/DonorDetails.tsx (100%) rename src/features/user/{DonorReceipt => DonationReceipt}/microComponents/ReceiptActions.tsx (100%) rename src/features/user/{DonorReceipt => DonationReceipt}/microComponents/ReceiptDataSection.tsx (100%) rename src/features/user/{DonorReceipt => DonationReceipt}/microComponents/VerifyReceiptFooter .tsx (100%) rename src/features/user/{DonorReceipt => DonationReceipt}/microComponents/VerifyReceiptHeader.tsx (100%) rename src/features/user/{DonorReceipt => DonationReceipt}/utils.ts (100%) diff --git a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx index 1520e2be6..0d88e5e3a 100644 --- a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx +++ b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx @@ -16,7 +16,7 @@ import { import getMessagesForPage from '../../../../src/utils/language/getMessagesForPage'; import { defaultTenant } from '../../../../tenant.config'; import { useTenant } from '../../../../src/features/common/Layout/TenantContext'; -import DonationReceiptLayout from '../../../../src/features/user/DonorReceipt/DonationReceiptLayout'; +import DonationReceiptLayout from '../../../../src/features/user/DonationReceipt/DonationReceiptLayout'; import { DonationReceiptProvider } from '../../../../src/features/common/Layout/DonationReceiptContext'; interface PageProps { diff --git a/src/features/common/Layout/DonationReceiptContext.tsx b/src/features/common/Layout/DonationReceiptContext.tsx index 4ce7d06f5..dc3b14423 100644 --- a/src/features/common/Layout/DonationReceiptContext.tsx +++ b/src/features/common/Layout/DonationReceiptContext.tsx @@ -2,10 +2,10 @@ import type { FC } from 'react'; import type { ReceiptData, ReceiptDataAPI, -} from '../../user/DonorReceipt/donationReceipt'; +} from '../../user/DonationReceipt/donationReceipt'; import { useMemo, useState, createContext, useContext } from 'react'; -import { formatReceiptData } from '../../user/DonorReceipt/utils'; +import { formatReceiptData } from '../../user/DonationReceipt/utils'; interface DonationReceiptContextInterface { donationReceiptData: ReceiptData | null; diff --git a/src/features/user/DonorReceipt/donationReceipt.module.scss b/src/features/user/DonationReceipt/DonationReceipt.module.scss similarity index 100% rename from src/features/user/DonorReceipt/donationReceipt.module.scss rename to src/features/user/DonationReceipt/DonationReceipt.module.scss diff --git a/src/features/user/DonorReceipt/DonationReceiptLayout.tsx b/src/features/user/DonationReceipt/DonationReceiptLayout.tsx similarity index 100% rename from src/features/user/DonorReceipt/DonationReceiptLayout.tsx rename to src/features/user/DonationReceipt/DonationReceiptLayout.tsx diff --git a/src/features/user/DonorReceipt/donationReceipt.ts b/src/features/user/DonationReceipt/donationReceipt.ts similarity index 100% rename from src/features/user/DonorReceipt/donationReceipt.ts rename to src/features/user/DonationReceipt/donationReceipt.ts diff --git a/src/features/user/DonorReceipt/microComponents/DonationData.tsx b/src/features/user/DonationReceipt/microComponents/DonationData.tsx similarity index 100% rename from src/features/user/DonorReceipt/microComponents/DonationData.tsx rename to src/features/user/DonationReceipt/microComponents/DonationData.tsx diff --git a/src/features/user/DonorReceipt/microComponents/DonorDetails.tsx b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx similarity index 100% rename from src/features/user/DonorReceipt/microComponents/DonorDetails.tsx rename to src/features/user/DonationReceipt/microComponents/DonorDetails.tsx diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx similarity index 100% rename from src/features/user/DonorReceipt/microComponents/ReceiptActions.tsx rename to src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx diff --git a/src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx similarity index 100% rename from src/features/user/DonorReceipt/microComponents/ReceiptDataSection.tsx rename to src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx diff --git a/src/features/user/DonorReceipt/microComponents/VerifyReceiptFooter .tsx b/src/features/user/DonationReceipt/microComponents/VerifyReceiptFooter .tsx similarity index 100% rename from src/features/user/DonorReceipt/microComponents/VerifyReceiptFooter .tsx rename to src/features/user/DonationReceipt/microComponents/VerifyReceiptFooter .tsx diff --git a/src/features/user/DonorReceipt/microComponents/VerifyReceiptHeader.tsx b/src/features/user/DonationReceipt/microComponents/VerifyReceiptHeader.tsx similarity index 100% rename from src/features/user/DonorReceipt/microComponents/VerifyReceiptHeader.tsx rename to src/features/user/DonationReceipt/microComponents/VerifyReceiptHeader.tsx diff --git a/src/features/user/DonorReceipt/utils.ts b/src/features/user/DonationReceipt/utils.ts similarity index 100% rename from src/features/user/DonorReceipt/utils.ts rename to src/features/user/DonationReceipt/utils.ts From e77466919d2c27902894117dd788741e56457e5b Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:43:31 +0530 Subject: [PATCH 28/31] refactor: create a new file for donation receipt translation resources --- global.d.ts | 5 ++++- i18n.ts | 4 ++++ .../[slug]/[locale]/verify-receipt-data.tsx | 2 +- public/static/locales/en/donationReceipt.json | 21 +++++++++++++++++++ .../microComponents/DonationData.tsx | 14 ++++++++----- .../microComponents/DonorDetails.tsx | 10 ++++----- .../microComponents/ReceiptActions.tsx | 8 +++---- .../microComponents/VerifyReceiptHeader.tsx | 8 +++---- src/utils/language/getMessagesForPage.ts | 3 ++- 9 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 public/static/locales/en/donationReceipt.json diff --git a/global.d.ts b/global.d.ts index d04e133c4..3a9324dfb 100644 --- a/global.d.ts +++ b/global.d.ts @@ -35,6 +35,8 @@ type MessagesTreemapper = typeof import('./public/static/locales/en/treemapper.json'); type MessagesTreemapperAnalytics = typeof import('./public/static/locales/en/treemapperAnalytics.json'); +type MessagesDonationReceipt = + typeof import('./public/static/locales/en/donationReceipt.json'); type Messages = MessagesAllProjects & MessagesBulkCodes & @@ -58,6 +60,7 @@ type Messages = MessagesAllProjects & MessagesRegisterTrees & MessagesTenants & MessagesTreemapper & - MessagesTreemapperAnalytics; + MessagesTreemapperAnalytics & + MessagesDonationReceipt; declare interface IntlMessages extends Messages {} diff --git a/i18n.ts b/i18n.ts index d9b5dc1c0..9956a54c5 100644 --- a/i18n.ts +++ b/i18n.ts @@ -41,6 +41,8 @@ export default getRequestConfig(async ({ locale }) => { ...( await import(`./public/static/locales/${locale}/treemapperAnalytics.json`) ).default, + ...(await import(`./public/static/locales/${locale}/donationReceipt.json`)) + .default, }; const defaultMessages = { @@ -68,6 +70,8 @@ export default getRequestConfig(async ({ locale }) => { ...(await import(`./public/static/locales/en/treemapper.json`)).default, ...(await import(`./public/static/locales/en/treemapperAnalytics.json`)) .default, + ...(await import(`./public/static/locales/en/donationReceipt.json`)) + .default, }; const messages: IntlMessages = deepmerge(defaultMessages, userMessages); diff --git a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx index 0d88e5e3a..f05b92266 100644 --- a/pages/sites/[slug]/[locale]/verify-receipt-data.tsx +++ b/pages/sites/[slug]/[locale]/verify-receipt-data.tsx @@ -72,7 +72,7 @@ export const getStaticProps: GetStaticProps = async ( const messages = await getMessagesForPage({ locale: context.params?.locale as string, - filenames: ['common', 'me', 'country', 'donate'], + filenames: ['common', 'me', 'country', 'donationReceipt'], }); return { diff --git a/public/static/locales/en/donationReceipt.json b/public/static/locales/en/donationReceipt.json new file mode 100644 index 000000000..02341de08 --- /dev/null +++ b/public/static/locales/en/donationReceipt.json @@ -0,0 +1,21 @@ +{ + "DonationReceipt": { + "donorInfo": { + "name": "{type, select, individual {Name} organization {Company Name} other {}}" + }, + "donationDetails": { + "referenceNumber": "Reference Number", + "amountDonated": "Amount Donated", + "paymentDate": "Payment Date", + "donationAmount": "{currency, select, EUR {€} USD {$} other {}} {amount}", + "taxIdentificationNumber": "Tax Identification Number (TIN)" + }, + "verifyTaxHeaderPrimary": "Verify your data to download tax receipt", + "verifyTaxHeaderSecondary": "once the data is verified, it can not be changed again for this receipt", + "downloadTaxReceipt": "Download tax receipt", + "recipientInfoHeader": "Receipt will be issued to", + "modifyContactInformation": "Modify Contact Information", + "confirm": "Confirm", + "download": "Download" + } +} diff --git a/src/features/user/DonationReceipt/microComponents/DonationData.tsx b/src/features/user/DonationReceipt/microComponents/DonationData.tsx index 9ea22efb5..66a023581 100644 --- a/src/features/user/DonationReceipt/microComponents/DonationData.tsx +++ b/src/features/user/DonationReceipt/microComponents/DonationData.tsx @@ -9,14 +9,18 @@ type Props = { }; const DonationData = ({ donations }: Props) => { - const t = useTranslations('Donate.donationReceipt'); + const tReceipt = useTranslations('DonationReceipt'); return (
    - {t('referenceNumber')} - {t('amountDonated')} - {t('paymentDate')} + {tReceipt('donationDetails.referenceNumber')} + + {tReceipt('donationDetails.amountDonated')} + + + {tReceipt('donationDetails.paymentDate')} +
      {donations?.map((dtn) => { @@ -24,7 +28,7 @@ const DonationData = ({ donations }: Props) => {
    • {dtn.reference} - {t('donationAmount', { + {tReceipt('donationDetails.donationAmount', { currency: dtn.currency, amount: dtn.amount, })} diff --git a/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx index 941ec2d2e..8c32d4973 100644 --- a/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx +++ b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx @@ -14,7 +14,7 @@ interface Props { const DonorDetails = ({ donor, address }: Props) => { if (address === undefined || donor === undefined) return null; - const t = useTranslations('Donate'); + const tReceipt = useTranslations('DonationReceipt'); const tCountry = useTranslations('Country'); const { country, zipCode, city, address1, address2 } = address; const { type, name, tin } = donor; @@ -27,13 +27,11 @@ const DonorDetails = ({ donor, address }: Props) => { return (
      -

      - {t('donationReceipt.recipientInfoHeader')} -

      +

      {tReceipt('recipientInfoHeader')}

      - {t('donationReceipt.name', { + {tReceipt('donorInfo.name', { type, })} @@ -42,7 +40,7 @@ const DonorDetails = ({ donor, address }: Props) => { {tin && (
      - {t('donationReceipt.taxIdentificationNumber')} + {tReceipt('donationDetails.taxIdentificationNumber')} {tin}
      diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx index 327d40cf4..9a0b04a1c 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -19,7 +19,7 @@ const ReceiptActions = ({ operation, confirmReceiptData, }: Props) => { - const t = useTranslations('Donate.donationReceipt'); + const tReceipt = useTranslations('DonationReceipt'); const router = useRouter(); const showDowloadButton = @@ -30,7 +30,7 @@ const ReceiptActions = ({
      } href={downloadUrl} @@ -41,7 +41,7 @@ const ReceiptActions = ({ <> } onClick={() => @@ -50,7 +50,7 @@ const ReceiptActions = ({ /> diff --git a/src/features/user/DonationReceipt/microComponents/VerifyReceiptHeader.tsx b/src/features/user/DonationReceipt/microComponents/VerifyReceiptHeader.tsx index 3e545f608..4ebf72c38 100644 --- a/src/features/user/DonationReceipt/microComponents/VerifyReceiptHeader.tsx +++ b/src/features/user/DonationReceipt/microComponents/VerifyReceiptHeader.tsx @@ -9,15 +9,15 @@ type Props = { }; const VerifyReceiptHeader = ({ operation }: Props) => { - const t = useTranslations('Donate.donationReceipt'); + const tReceipt = useTranslations('DonationReceipt'); return (
      {operation === RECEIPT_STATUS.DOWNLOAD ? ( -

      {t('downloadTaxReceipt')}

      +

      {tReceipt('downloadTaxReceipt')}

      ) : ( <> -

      {t('verifyTaxHeaderPrimary')}

      -

      {t('verifyTaxHeaderSecondary')}

      +

      {tReceipt('verifyTaxHeaderPrimary')}

      +

      {tReceipt('verifyTaxHeaderSecondary')}

      )}
      diff --git a/src/utils/language/getMessagesForPage.ts b/src/utils/language/getMessagesForPage.ts index e3b0d6ed1..eb751cfac 100644 --- a/src/utils/language/getMessagesForPage.ts +++ b/src/utils/language/getMessagesForPage.ts @@ -26,7 +26,8 @@ type TRANSLATION_FILE_NAMES = | 'registerTrees' | 'tenants' | 'treemapper' - | 'treemapperAnalytics'; + | 'treemapperAnalytics' + | 'donationReceipt'; interface MessageConfig { /** From 8143bba545a1cbe83f66110973c229964b197220 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:57:29 +0530 Subject: [PATCH 29/31] feat : add receipt verification check for download button --- .../DonationReceipt/microComponents/ReceiptActions.tsx | 10 +++++++--- .../microComponents/ReceiptDataSection.tsx | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx index 9a0b04a1c..9f1cc2077 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptActions.tsx @@ -12,21 +12,25 @@ type Props = { downloadUrl: string | null; operation: Operation; confirmReceiptData: () => Promise; + isReceiptVerified: boolean; }; const ReceiptActions = ({ downloadUrl, operation, confirmReceiptData, + isReceiptVerified, }: Props) => { const tReceipt = useTranslations('DonationReceipt'); const router = useRouter(); - const showDowloadButton = - operation === RECEIPT_STATUS.DOWNLOAD && downloadUrl !== null; + const showDownloadButton = + operation === RECEIPT_STATUS.DOWNLOAD && + downloadUrl !== null && + isReceiptVerified; return (
      - {showDowloadButton ? ( + {showDownloadButton ? (
      { downloadUrl={downloadUrl} operation={operation} confirmReceiptData={confirmReceiptData} + isReceiptVerified={donationReceiptData.verificationDate !== null} /> ) : (
      From 2bc8d2b1d78ff8176412f44026c9ddf169043f2a Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:18:33 +0530 Subject: [PATCH 30/31] refactor : remove mixin --- .../DonationReceipt.module.scss | 75 +++++++++---------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/src/features/user/DonationReceipt/DonationReceipt.module.scss b/src/features/user/DonationReceipt/DonationReceipt.module.scss index 2717dc2d8..cb0fb644f 100644 --- a/src/features/user/DonationReceipt/DonationReceipt.module.scss +++ b/src/features/user/DonationReceipt/DonationReceipt.module.scss @@ -1,38 +1,15 @@ @import '../../../theme/theme'; -@mixin flex-layout( - $display: flex, - $flex-direction: null, - $justify-content: null, - $align-items: null, - $gap: null -) { - display: $display; - - @if $justify-content { - justify-content: $justify-content; - } - - @if $align-items { - align-items: $align-items; - } - - @if $gap { - gap: $gap; - } - - @if $flex-direction { - flex-direction: $flex-direction; - } -} - .donationReceiptSkeleton { - @include flex-layout(flex, null, center); + display: flex; + justify-content: center; margin-top: 110px; } .donationReceiptLayout { - @include flex-layout(flex, column, null, center); + display: flex; + flex-direction: column; + align-items: center; width: 100vw; height: calc(100vh - 80px); margin-top: 80px; @@ -43,13 +20,15 @@ } .donationReceiptContainer { - @include flex-layout(flex, column, null, null, 20px); + display: flex; + flex-direction: column; + gap: 20px; width: 100%; max-width: 760px; min-height: 60px; margin-top: 60px; @include xsPhoneView { - @include flex-layout(flex, null, null, center); + align-items: center; } } @@ -74,7 +53,9 @@ } .donationRecord { - @include flex-layout(flex, column, null, null, 12px); + display: flex; + flex-direction: column; + gap: 12px; width: 100%; padding: 6px 16px 16px 16px; @@ -83,7 +64,8 @@ } .header { - @include flex-layout(flex, null, space-between); + display: flex; + justify-content: space-between; font-weight: 700; } } @@ -97,7 +79,9 @@ } .record { - @include flex-layout(flex, null, space-between, center); + display: flex; + justify-content: space-between; + align-items: center; padding-top: 8px; padding-bottom: 8px; @@ -122,7 +106,9 @@ } .donorDetails { - @include flex-layout(flex, column, null, null, 20px); + display: flex; + flex-direction: column; + gap: 20px; background: rgba(242, 242, 242, 0.5); width: 100%; margin-top: 20px; @@ -135,7 +121,10 @@ } .details { - @include flex-layout(flex, row, space-between, null, 28px); + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 28px; flex-wrap: wrap; } } @@ -144,7 +133,9 @@ .donorName, .companyName, .tin { - @include flex-layout(flex, column, null, null, 7px); + display: flex; + flex-direction: column; + gap: 7px; color: rgba(130, 130, 130, 1); .header { @@ -154,12 +145,14 @@ } .receiptActions { - @include flex-layout(flex, null, flex-end, null, 12px); + display: flex; + justify-content: flex-end; + gap: 12px; margin-top: 40px; padding: 0px 10px; @include xsPhoneView { - @include flex-layout(flex, column); + flex-direction: column; } button { @@ -172,10 +165,12 @@ } .downloadButtonContainer { - @include flex-layout(flex, null, flex-end); + display: flex; + justify-content: flex-end; } .receiptVerificationSpinner { - @include flex-layout(flex, null, center); + display: flex; + justify-content: center; margin-top: 40px; } From 00886ee3468fe5c1a2cc716a433f0a10775975a0 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Tue, 4 Feb 2025 17:27:42 +0530 Subject: [PATCH 31/31] fix: address feedbacks --- .../DonationReceipt.module.scss | 6 +-- .../user/DonationReceipt/donationReceipt.ts | 10 ++-- .../microComponents/DonationData.tsx | 48 ----------------- .../microComponents/DonationsTable.tsx | 54 +++++++++++++++++++ .../microComponents/DonorDetails.tsx | 13 +++-- .../microComponents/ReceiptDataSection.tsx | 4 +- 6 files changed, 70 insertions(+), 65 deletions(-) delete mode 100644 src/features/user/DonationReceipt/microComponents/DonationData.tsx create mode 100644 src/features/user/DonationReceipt/microComponents/DonationsTable.tsx diff --git a/src/features/user/DonationReceipt/DonationReceipt.module.scss b/src/features/user/DonationReceipt/DonationReceipt.module.scss index cb0fb644f..67cb0f64c 100644 --- a/src/features/user/DonationReceipt/DonationReceipt.module.scss +++ b/src/features/user/DonationReceipt/DonationReceipt.module.scss @@ -52,7 +52,7 @@ background: #fff; } -.donationRecord { +.donationsTable { display: flex; flex-direction: column; gap: 12px; @@ -120,7 +120,7 @@ font-size: $fontSmall; } - .details { + .donorInfo { display: flex; flex-direction: row; justify-content: space-between; @@ -129,7 +129,7 @@ } } -.address, +.addressInfo, .donorName, .companyName, .tin { diff --git a/src/features/user/DonationReceipt/donationReceipt.ts b/src/features/user/DonationReceipt/donationReceipt.ts index c2ce6e7f8..c01904c49 100644 --- a/src/features/user/DonationReceipt/donationReceipt.ts +++ b/src/features/user/DonationReceipt/donationReceipt.ts @@ -6,16 +6,16 @@ export type IssuedDonationView = { }; export type DonorAPI = { + reference: string; tin: string | null; - city: string; - name: string; type: 'individual' | 'organization'; + name: string; email: string; - country: string; - zipCode: string; address1: string; address2: string | null; - reference: string; + city: string; + zipCode: string; + country: string; }; export type DonorView = { diff --git a/src/features/user/DonationReceipt/microComponents/DonationData.tsx b/src/features/user/DonationReceipt/microComponents/DonationData.tsx deleted file mode 100644 index 66a023581..000000000 --- a/src/features/user/DonationReceipt/microComponents/DonationData.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import type { IssuedDonationView } from '../donationReceipt'; - -import { useTranslations } from 'next-intl'; -import styles from '../DonationReceipt.module.scss'; -import formatDate from '../../../../utils/countryCurrency/getFormattedDate'; - -type Props = { - donations: IssuedDonationView[] | null; -}; - -const DonationData = ({ donations }: Props) => { - const tReceipt = useTranslations('DonationReceipt'); - return ( -
      -
      -
      - {tReceipt('donationDetails.referenceNumber')} - - {tReceipt('donationDetails.amountDonated')} - - - {tReceipt('donationDetails.paymentDate')} - -
      -
        - {donations?.map((dtn) => { - return ( -
      • - {dtn.reference} - - {tReceipt('donationDetails.donationAmount', { - currency: dtn.currency, - amount: dtn.amount, - })} - - -
      • - ); - })} -
      -
      -
      - ); -}; - -export default DonationData; diff --git a/src/features/user/DonationReceipt/microComponents/DonationsTable.tsx b/src/features/user/DonationReceipt/microComponents/DonationsTable.tsx new file mode 100644 index 000000000..f93d8ba83 --- /dev/null +++ b/src/features/user/DonationReceipt/microComponents/DonationsTable.tsx @@ -0,0 +1,54 @@ +import type { IssuedDonationView } from '../donationReceipt'; + +import { useTranslations } from 'next-intl'; +import styles from '../DonationReceipt.module.scss'; +import formatDate from '../../../../utils/countryCurrency/getFormattedDate'; + +type Props = { + donations: IssuedDonationView[] | null; +}; + +const DonationsTable = ({ donations }: Props) => { + const tReceipt = useTranslations('DonationReceipt'); + return ( +
      +
      + + {tReceipt('donationDetails.referenceNumber')} + + + {tReceipt('donationDetails.amountDonated')} + + + {tReceipt('donationDetails.paymentDate')} + +
      +
        + {donations?.map((dtn) => { + return ( +
      • + + {dtn.reference} + + + {tReceipt('donationDetails.donationAmount', { + currency: dtn.currency, + amount: dtn.amount, + })} + + +
      • + ); + })} +
      +
      + ); +}; + +export default DonationsTable; diff --git a/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx index 8c32d4973..77b3128ff 100644 --- a/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx +++ b/src/features/user/DonationReceipt/microComponents/DonorDetails.tsx @@ -17,7 +17,6 @@ const DonorDetails = ({ donor, address }: Props) => { const tReceipt = useTranslations('DonationReceipt'); const tCountry = useTranslations('Country'); const { country, zipCode, city, address1, address2 } = address; - const { type, name, tin } = donor; const countryName = tCountry(country.toLowerCase() as Lowercase); const cityStatePostalString = useMemo( @@ -28,25 +27,25 @@ const DonorDetails = ({ donor, address }: Props) => { return (

      {tReceipt('recipientInfoHeader')}

      -
      +
      {tReceipt('donorInfo.name', { - type, + type: donor.type, })} - {name} + {donor.name}
      - {tin && ( + {donor.tin !== null && (
      {tReceipt('donationDetails.taxIdentificationNumber')} - {tin} + {donor.tin}
      )}
      -
      +
      Address
      {address1},{cityStatePostalString} diff --git a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx index c53bfb8fc..ab7c5d286 100644 --- a/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx +++ b/src/features/user/DonationReceipt/microComponents/ReceiptDataSection.tsx @@ -6,7 +6,7 @@ import { handleError } from '@planet-sdk/common'; import { CircularProgress } from '@mui/material'; import { useDonationReceipt } from '../../../common/Layout/DonationReceiptContext'; import styles from '../DonationReceipt.module.scss'; -import DonationData from './DonationData'; +import DonationsTable from './DonationsTable'; import ReceiptActions from './ReceiptActions'; import DonorDetails from './DonorDetails'; import { getVerificationDate, RECEIPT_STATUS } from '../utils'; @@ -73,7 +73,7 @@ const ReceiptDataSection = ({ donationReceiptData }: Prop) => { return (
      - + {!isLoading ? (