From 0ecb5a5963545bdb636a9d153b0e723fc8fd53ad Mon Sep 17 00:00:00 2001 From: Georgi Parlakov Date: Mon, 21 Oct 2024 10:09:42 +0300 Subject: [PATCH 01/14] Admin campaign applications e2e tests part 3 file download or delete (#1963) * chore: e2e test for organizer edit and delete a file * chore: add auth e2e test readme section * chore: linting --- README.md | 2 + e2e/README.md | 21 +++++ .../campaign-application-giver.spec.ts | 79 +++++++++++++++++-- e2e/utils/fixtures.ts | 4 + .../CampaignApplicationsGrid.tsx | 3 +- 5 files changed, 103 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 67bd26945..cd0668bdf 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,9 @@ Watch releases of this repository to be notified about future updates: ## Contributors ✨ + [![All Contributors](https://img.shields.io/badge/all_contributors-84-orange.svg?style=flat-square)](#contributors-) + Please check [contributors guide](https://github.com/podkrepi-bg/frontend/blob/master/CONTRIBUTING.md) for: diff --git a/e2e/README.md b/e2e/README.md index 0f3b4bde9..ba43be251 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -52,3 +52,24 @@ Options: ```shell yarn test:e2e --headed --debug -x -g support ``` + +### Tests with Authenticated user + +### Writing + +To auth a user we rely on the Storage where the session is stored. And the storage is filled in and accessed via a `test.extend` [fixture](https://playwright.dev/docs/auth#authenticate-with-api-request). It takes care to login and store the session and then use it in the tests. See the `e2e/utils/fixtures.ts` file + +This is the process for writing tests for auth user. + +- import the desired user `test` from the fixture + + `import { expect, giverTest as test } from '../../../utils/fixtures'` for the `giver` user + +- write your e2e tests ... + +> [Examples] `e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts` and `e2e/tests/regression/campaign-application/campaign-application-admin.spec.ts` + +### Running + +- [Locally] run the 'docker compose -d keycloak pg-db', the api (`yarn dev` in the api repo folder), the app (`yarn dev` in the frontend repo folder), +- in the `frontend/e2e` folder run `yarn e2e:tests --ui` to start the playwright visual testing tool diff --git a/e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts b/e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts index 1a916af60..d657221b6 100644 --- a/e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts +++ b/e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts @@ -1,8 +1,3 @@ -import { - CampaignApplicationResponse, - CampaignApplicationExisting, - CampaignApplicationAdminResponse, -} from '../../../../src/gql/campaign-applications' import { Page } from 'playwright/test' import { expect, giverTest as test } from '../../../utils/fixtures' import { textLocalized } from '../../../utils/texts-localized' @@ -169,6 +164,41 @@ test.describe('Campaign application giver', () => { await expect(page.getByText(t.steps.application['campaign-end'].options.funds)).toBeVisible() await expect(page.getByText('goal')).toBeVisible() }) + + test('should see the edit campaign application and be able to delete a selected file ', async ({ + page, + baseURL, + }) => { + // arrange + await setupMeAndCampaignTypes(page) + await setupCampaignApplicationForEdit(page) + await page.goto(`${baseURL}/campaigns/application/1234`) + const t = await textLocalized().campaign.bg() + await page.getByRole('button', { name: t.cta.next }).click() + await page.getByRole('button', { name: t.cta.next }).click() + + // expect to see 2 files + await expect(page.getByText('1234.txt')).toBeVisible() + await expect(page.getByText('document.pdf')).toBeVisible() + + // act + // hit the delete button ... + await page.locator('li').filter({ hasText: '1234.txt' }).getByLabel('delete').click() + const [editCamAppReq, fileDeleteReq] = await Promise.all([ + // the edit request to edit the CamApp entity + page.waitForRequest((r) => r.method() === 'PATCH'), + // the delete request to remove one of the files + page.waitForRequest((r) => r.method() === 'DELETE'), + // ... and when submit + page.getByRole('button', { name: t.cta.submit }).click(), + ]) + + await expect(editCamAppReq.postDataJSON()).toBeDefined() + + const fileDelRes = await fileDeleteReq.response() + + await expect(fileDelRes?.json()).resolves.toEqual({ id: 'ok' }) + }) }) function defaultCampaignApplication() { @@ -232,3 +262,42 @@ async function setupMeAndCampaignTypes(page: Page) { }), ) } + +async function setupCampaignApplicationForEdit( + page: Page, + application: Partial> = {}, +) { + await page.route('*/**/api/v1/campaign-application/byId/*', (req) => + req.fulfill({ + json: { + ...defaultCampaignApplication(), + id: 'forEdit', + documents: [ + { filename: '1234.txt', id: '1234' }, + { filename: 'document.pdf', id: 'doc-id-123123' }, + ], + ...application, + }, + }), + ) + + // on submit at the end of edit this patch request needs to be sent + await page.route('*/**/api/v1/campaign-application/forEdit', (req) => + req.fulfill({ + json: { + ...defaultCampaignApplication(), + id: 'forEdit', + ...application, + }, + }), + ) + + // delete file successful + await page.route('*/**/api/v1/campaign-application/fileById/*', (req) => + req.fulfill({ + json: { + id: 'ok', + }, + }), + ) +} diff --git a/e2e/utils/fixtures.ts b/e2e/utils/fixtures.ts index ea13fef30..a51ad18a1 100644 --- a/e2e/utils/fixtures.ts +++ b/e2e/utils/fixtures.ts @@ -1,3 +1,7 @@ +/** + * This is logic for authenticating and storing the session to be used in the tests. See the e2e/Readme.md - the section about Authenticated user + */ + import { test, test as base } from '@playwright/test' import dotenv from 'dotenv' import fs from 'fs' diff --git a/src/components/admin/campaign-applications/CampaignApplicationsGrid.tsx b/src/components/admin/campaign-applications/CampaignApplicationsGrid.tsx index 4d230a824..d6d3b3f78 100644 --- a/src/components/admin/campaign-applications/CampaignApplicationsGrid.tsx +++ b/src/components/admin/campaign-applications/CampaignApplicationsGrid.tsx @@ -115,7 +115,8 @@ export const useCampaignsList = () => { const { data, isLoading } = fetchMutation() return { - list: data?.sort((a, b) => b?.updatedAt?.localeCompare(a?.updatedAt ?? '') ?? 0), + // the data array is strict mode (sometimes) it throws a Readonly array error on the sort so create a shallow copy + list: [...(data ?? [])].sort((a, b) => b?.updatedAt?.localeCompare(a?.updatedAt ?? '') ?? 0), isLoading, } } From f3725c7b400028c767100b2573a696c4de837933 Mon Sep 17 00:00:00 2001 From: Nikolay Yankov <36303598+nikolay-yankov@users.noreply.github.com> Date: Tue, 29 Oct 2024 19:10:50 +0200 Subject: [PATCH 02/14] Bugfix/new donation flow issues (#1962) * Improve transaction popup message * Donation page fix card size * Do not disable the Amount form for Bank transaction * Validate the Amount field when card or bank is not selected * Fix Amount validation when transaction fees included * Fix wrong modal actions on close and continue * Add fullstop character in message * Remove duplicated Terms & GDPR fields * Fix route locale for Privacy Policy in Donation Component * Revert "Do not disable the Amount form for Bank transaction" This reverts commit 2ceeef55f2826e3ac9e43e81b25c8d28021b1d9e. * Revert Amount validation for bank payment --- public/locales/en/donation-flow.json | 4 ++-- src/components/client/donation-flow/DonationFlowForm.tsx | 6 +++--- .../client/donation-flow/DonationFlowStatusPage.tsx | 2 +- src/components/client/donation-flow/steps/Amount.tsx | 5 ++++- .../steps/authentication/InlineRegisterForm.tsx | 4 ---- src/components/common/form/AcceptPrivacyPolicyField.tsx | 7 ++++++- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/public/locales/en/donation-flow.json b/public/locales/en/donation-flow.json index b22973a45..1d888caf6 100644 --- a/public/locales/en/donation-flow.json +++ b/public/locales/en/donation-flow.json @@ -106,7 +106,7 @@ }, "noregister": { "label": "Continue without registration", - "description": "You will not be able to get a donation certificate or a list of your donations. If you still want to receive a receipt, please share your email - it will not be visible in the platform" + "description": "You will not be able to get a donation certificate or a list of your donations. If you still want to receive a receipt, please share your email - it will not be visible in the platform." }, "field": { "password": "Password", @@ -128,7 +128,7 @@ "donation": "Donation", "transaction": { "title": "Transaction", - "description": "The transaction is only to compensate the transfer and is calculated based on your method of payment. \"Podkrepi.bg\" works with 0% commission" + "description": "The transaction is only to compensate the transfer and is calculated based on your method of payment. \"Podkrepi.bg\" works with 0% commission." }, "total": "Total", "field": { diff --git a/src/components/client/donation-flow/DonationFlowForm.tsx b/src/components/client/donation-flow/DonationFlowForm.tsx index de6b63a4a..b4a14ee90 100644 --- a/src/components/client/donation-flow/DonationFlowForm.tsx +++ b/src/components/client/donation-flow/DonationFlowForm.tsx @@ -226,15 +226,15 @@ export function DonationFlowForm() { { - cancelSetupIntentMutation.mutate({ id: setupIntent.id }) - router.push(routes.campaigns.viewCampaignBySlug(campaign.slug)) + setShowCancelDialog(false) }} title={t('cancel-dialog.title')} content={t('cancel-dialog.content')} confirmButtonLabel={t('cancel-dialog.btn-continue')} cancelButtonLabel={t('cancel-dialog.btn-cancel')} handleConfirm={() => { - setShowCancelDialog(false) + cancelSetupIntentMutation.mutate({ id: setupIntent.id }) + router.push(routes.campaigns.viewCampaignBySlug(campaign.slug)) }} /> ) From 8076bca61a5f3ab3411ca03fbb6eed917e76938f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:40:21 +0200 Subject: [PATCH 05/14] add katina-anachkova as a contributor for code (#1973) * update README.md [skip ci] * update .all-contributorsrc [skip ci] --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8dcbda09a..8f241dcad 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -913,6 +913,15 @@ "contributions": [ "code" ] + }, + { + "login": "katina-anachkova", + "name": "Katina Anachkova", + "avatar_url": "https://avatars.githubusercontent.com/u/82702355?v=4", + "profile": "https://github.com/katina-anachkova", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 10, diff --git a/README.md b/README.md index 333133d46..872d6fb8c 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ Watch releases of this repository to be notified about future updates: ## Contributors ✨ -[![All Contributors](https://img.shields.io/badge/all_contributors-85-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-86-orange.svg?style=flat-square)](#contributors-) Please check [contributors guide](https://github.com/podkrepi-bg/frontend/blob/master/CONTRIBUTING.md) for: @@ -227,6 +227,7 @@ Thanks goes to these wonderful people: Viktor Stefanov
Viktor Stefanov

💻 velnachev
velnachev

💻 Nikolay Yankov
Nikolay Yankov

💻 + Katina Anachkova
Katina Anachkova

💻 From 98baadc45cd766f4f848f8370b31d8dcf108f3f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:28:50 +0200 Subject: [PATCH 06/14] build(deps): bump cross-spawn from 7.0.3 to 7.0.6 (#1977) Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6. - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 240a11f4e..820395f12 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6625,13 +6625,13 @@ __metadata: linkType: hard "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": - version: 7.0.3 - resolution: "cross-spawn@npm:7.0.3" + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" dependencies: path-key: ^3.1.0 shebang-command: ^2.0.0 which: ^2.0.1 - checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 + checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b languageName: node linkType: hard From 92721a7b1e64744c08dfa9e5ecb28fbfac1a5931 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:42:43 +0200 Subject: [PATCH 07/14] build(deps): bump cross-spawn from 7.0.3 to 7.0.6 in /e2e (#1978) Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6. - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- e2e/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/yarn.lock b/e2e/yarn.lock index d77e05353..626bd5bd9 100644 --- a/e2e/yarn.lock +++ b/e2e/yarn.lock @@ -235,13 +235,13 @@ __metadata: linkType: hard "cross-spawn@npm:^7.0.0": - version: 7.0.3 - resolution: "cross-spawn@npm:7.0.3" + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" dependencies: path-key: ^3.1.0 shebang-command: ^2.0.0 which: ^2.0.1 - checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 + checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b languageName: node linkType: hard From 4e2b1cbd042c463f8de204700bff584c8b2c9cca Mon Sep 17 00:00:00 2001 From: Katina Anachkova <82702355+katina-anachkova@users.noreply.github.com> Date: Wed, 20 Nov 2024 19:29:41 +0200 Subject: [PATCH 08/14] Card holder name restriction (#1975) * restrict input to letters and spaces * allow hyphens --------- Co-authored-by: Katina Anachkova --- .../steps/payment-method/PaymentDetailsStripeForm.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/client/donation-flow/steps/payment-method/PaymentDetailsStripeForm.tsx b/src/components/client/donation-flow/steps/payment-method/PaymentDetailsStripeForm.tsx index c7364f2f7..6e68dbd1e 100644 --- a/src/components/client/donation-flow/steps/payment-method/PaymentDetailsStripeForm.tsx +++ b/src/components/client/donation-flow/steps/payment-method/PaymentDetailsStripeForm.tsx @@ -79,6 +79,12 @@ export default function PaymentDetailsStripeForm({ id="billingName" variant="outlined" placeholder={t('donation-flow:step.payment-method.field.card-data.name-label')} + onInput={(e) => { + const input = e.target as HTMLInputElement + input.value = input.value + .replace(/[^a-zA-Z\s-]/g, '') + .replace(/[-\s]{2,}/g, (match) => match[0]) + }} /> Date: Thu, 21 Nov 2024 12:06:46 +0200 Subject: [PATCH 09/14] fix certificate date format (#1974) --- .../client/campaigns/CampaignPublicExpensesGrid.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/client/campaigns/CampaignPublicExpensesGrid.tsx b/src/components/client/campaigns/CampaignPublicExpensesGrid.tsx index 12f47fb26..058e5cdf1 100644 --- a/src/components/client/campaigns/CampaignPublicExpensesGrid.tsx +++ b/src/components/client/campaigns/CampaignPublicExpensesGrid.tsx @@ -12,6 +12,8 @@ import { Button, Grid, Tooltip } from '@mui/material' import FilePresentIcon from '@mui/icons-material/FilePresent' import Link from 'next/link' import { expenseFileUrl } from 'common/util/expenseFileUrls' +import { getExactDate } from 'common/util/date' +import { bg, enUS } from 'date-fns/locale' const PREFIX = 'Grid' @@ -43,12 +45,13 @@ const Root = styled(Grid)({ }) export default observer(function CampaignPublicExpensesGrid({ slug }: Props) { - const { t } = useTranslation('') + const { t, i18n } = useTranslation('') const { data: expensesList } = useCampaignApprovedExpensesList(slug) const [paginationModel, setPaginationModel] = useState({ pageSize: 20, page: 0, }) + const locale = i18n?.language == 'bg' ? bg : enUS const columns: GridColDef[] = [ { field: 'id', headerName: 'ID' }, @@ -96,8 +99,7 @@ export default observer(function CampaignPublicExpensesGrid({ slug }: Props) { if (!params.row.spentAt) { return '' } - - return new Date(params.row.spentAt).toLocaleDateString() + return getExactDate(params.row.spentAt, locale) }, }, { From 9dfbca6c8f0e5c33b8a2e8d76e55140077cf1729 Mon Sep 17 00:00:00 2001 From: Georgi Parlakov Date: Fri, 22 Nov 2024 14:54:23 +0200 Subject: [PATCH 10/14] fix: campaign application (#1976) - fix order of fields (make the goal the last field on the 3-rd step) - remove "Membership" from the list of campaign types (it's a system type) --- .../steps/CampaignApplicationBasic.tsx | 2 +- .../steps/CampaignApplicationDetails.tsx | 18 +++++++++--------- .../client/campaigns/CampaignTypeSelect.tsx | 16 ++++++++++------ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/components/client/campaign-application/steps/CampaignApplicationBasic.tsx b/src/components/client/campaign-application/steps/CampaignApplicationBasic.tsx index 864dcd8f9..807e746b2 100644 --- a/src/components/client/campaign-application/steps/CampaignApplicationBasic.tsx +++ b/src/components/client/campaign-application/steps/CampaignApplicationBasic.tsx @@ -58,7 +58,7 @@ export default function CampaignApplicationBasic() { /> - + {t('steps.details.title')} - - - + + + {t('campaigns:campaign.type')} - {data?.map((campaignType, index) => ( - - {campaignType.name} - - ))} + {data + ?.filter((campaignType) => !hideSystemTypes || !systemTypes.includes(campaignType?.name)) + ?.map((campaignType, index) => ( + + {campaignType.name} + + ))} {helperText && {helperText}} From c730414c1a33e208f6831e6c605ce955ddea2e35 Mon Sep 17 00:00:00 2001 From: Georgi Parlakov Date: Mon, 25 Nov 2024 21:22:49 +0200 Subject: [PATCH 11/14] fix: campaign application e2e test (#1985) --- README.md | 2 ++ .../campaign-application/campaign-application-giver.spec.ts | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 872d6fb8c..b49bfc908 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,9 @@ Watch releases of this repository to be notified about future updates: ## Contributors ✨ + [![All Contributors](https://img.shields.io/badge/all_contributors-86-orange.svg?style=flat-square)](#contributors-) + Please check [contributors guide](https://github.com/podkrepi-bg/frontend/blob/master/CONTRIBUTING.md) for: diff --git a/e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts b/e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts index d657221b6..942e7c5c8 100644 --- a/e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts +++ b/e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts @@ -252,9 +252,9 @@ async function setupMeAndCampaignTypes(page: Page) { }, { id: '34b501f0-b3c3-43d9-9be0-7f7258eeb247', - name: 'Membership', - slug: 'membership', - description: 'Membership Campaigns', + name: 'Elderly', + slug: 'elderly', + description: 'Help elderly people', parentId: null, category: 'others', }, From 953b21934f76aaa983a9f81ed255dca0be23ce79 Mon Sep 17 00:00:00 2001 From: Ivan Milchev Date: Sat, 30 Nov 2024 21:56:11 +0200 Subject: [PATCH 12/14] overwrite test artifacts Signed-off-by: Ivan Milchev --- .github/workflows/playwright.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index b80f5a889..c4b830882 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -120,6 +120,7 @@ jobs: name: playwright-report path: ./frontend/e2e/test-results/ retention-days: 14 + overwrite: true - uses: actions/upload-artifact@v4 if: always() From f4384d8309b4e38124abc5819ff227a1a55197cc Mon Sep 17 00:00:00 2001 From: Aleksandar Petkov Date: Wed, 4 Dec 2024 19:25:29 +0200 Subject: [PATCH 13/14] fix: Reported new donation flow issues (#1979) * fix: Reported new donation flow issues * fix: Non-anonymous donation being flagged as anonymous * fix: E2E test breakage * chore: Remove redundant console log --- e2e/pages/web-pages/donation/donation.page.ts | 2 +- .../client/donation-flow/DonationFlowForm.tsx | 28 ++++++++++--------- .../donation-flow/alerts/AlertsColumn.tsx | 1 + .../contexts/DonationFlowProvider.tsx | 2 +- src/service/stripeClient.ts | 2 +- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/e2e/pages/web-pages/donation/donation.page.ts b/e2e/pages/web-pages/donation/donation.page.ts index a5d58287d..df4a4e392 100644 --- a/e2e/pages/web-pages/donation/donation.page.ts +++ b/e2e/pages/web-pages/donation/donation.page.ts @@ -56,7 +56,7 @@ export class DonationPage extends CampaignsPage { bgLocalizationValidation['informed-agree-with'] + ' ' + bgLocalizationValidation.gdpr private readonly enPrivacyCheckboxText = enLocalizationValidation['informed-agree-with'] + ' ' + enLocalizationValidation.gdpr - private readonly bgStripeErrorNoBalanceText = 'Картата Ви не разполага с достатъчно средства.' + private readonly bgStripeErrorNoBalanceText = 'В картата ви няма достатъчно средства. Опитайте с друга.' async checkPageUrlByRegExp(urlRegExpAsString?: string, timeoutParam = 10000): Promise { await this.page.waitForTimeout(1000) diff --git a/src/components/client/donation-flow/DonationFlowForm.tsx b/src/components/client/donation-flow/DonationFlowForm.tsx index b4a14ee90..7ee93d06a 100644 --- a/src/components/client/donation-flow/DonationFlowForm.tsx +++ b/src/components/client/donation-flow/DonationFlowForm.tsx @@ -101,6 +101,18 @@ export const validationSchema: yup.SchemaOf = yup export function DonationFlowForm() { const formikRef = useRef | null>(null) const { t } = useTranslation('donation-flow') + const { campaign, setupIntent, paymentError, setPaymentError, idempotencyKey } = useDonationFlow() + const stripe = useStripe() + const elements = useElements() + const router = useRouter() + const updateSetupIntentMutation = useUpdateSetupIntent() + const cancelSetupIntentMutation = useCancelSetupIntent() + const paymentMethodSectionRef = React.useRef(null) + const authenticationSectionRef = React.useRef(null) + const stripeChargeRef = React.useRef(idempotencyKey) + const [showCancelDialog, setShowCancelDialog] = React.useState(false) + const [submitPaymentLoading, setSubmitPaymentLoading] = React.useState(false) + const { data: { user: person } = { user: null } } = useCurrentPerson() const { data: session } = useSession({ required: false, onUnauthenticated: () => { @@ -117,17 +129,6 @@ export function DonationFlowForm() { formikRef.current?.setFieldValue('email', '') formikRef.current?.setFieldValue('isAnonymous', true, false) }, [session]) - const { campaign, setupIntent, paymentError, setPaymentError, idempotencyKey } = useDonationFlow() - const stripe = useStripe() - const elements = useElements() - const router = useRouter() - const updateSetupIntentMutation = useUpdateSetupIntent() - const cancelSetupIntentMutation = useCancelSetupIntent() - const paymentMethodSectionRef = React.useRef(null) - const authenticationSectionRef = React.useRef(null) - const [showCancelDialog, setShowCancelDialog] = React.useState(false) - const [submitPaymentLoading, setSubmitPaymentLoading] = React.useState(false) - const { data: { user: person } = { user: null } } = useCurrentPerson() return ( {updatedRefArray.map((ref, index) => { const alert = alerts[ref.current?.id as keyof typeof alerts] + if (!alert) return null return })} diff --git a/src/components/client/donation-flow/contexts/DonationFlowProvider.tsx b/src/components/client/donation-flow/contexts/DonationFlowProvider.tsx index c8676bb1d..c1a8167be 100644 --- a/src/components/client/donation-flow/contexts/DonationFlowProvider.tsx +++ b/src/components/client/donation-flow/contexts/DonationFlowProvider.tsx @@ -10,7 +10,7 @@ type DonationContext = { paymentError: StripeError | null setPaymentError: React.Dispatch> campaign: CampaignResponse - stripe: StripeType | null + stripe: Promise idempotencyKey: string } diff --git a/src/service/stripeClient.ts b/src/service/stripeClient.ts index 8ba7c964c..adda96283 100644 --- a/src/service/stripeClient.ts +++ b/src/service/stripeClient.ts @@ -4,4 +4,4 @@ const { publicRuntimeConfig: { STRIPE_PUBLISHABLE_KEY }, } = getConfig() -export const stripe = await loadStripe(STRIPE_PUBLISHABLE_KEY) +export const stripe = loadStripe(STRIPE_PUBLISHABLE_KEY) From 62de3c5aa09a1628137809c2cf4e481fe7afab5b Mon Sep 17 00:00:00 2001 From: Aleksandar Petkov Date: Fri, 6 Dec 2024 20:32:09 +0200 Subject: [PATCH 14/14] fix: Donation flow more fixes (#1989) * chore: Fix inline registration * fix: Add minimum width to svgs for donation payment * chore: Add full stop at the end of the sentence * fix: Social links buttons not working * chore: Make amountChosen optional for now * fix: Typo in translation key * chore: Remove redundant log * chore: Remove redundant log * chore: Remove redundant logs --- public/locales/bg/donation-flow.json | 2 +- public/locales/en/donation-flow.json | 2 +- .../client/donation-flow/steps/Amount.tsx | 2 +- .../steps/authentication/InlineRegisterForm.tsx | 7 +++---- .../steps/payment-method/PaymentMethod.tsx | 4 ++-- src/components/common/SocialShareListButton.tsx | 14 +++++++------- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/public/locales/bg/donation-flow.json b/public/locales/bg/donation-flow.json index 8514038a1..e039106a0 100644 --- a/public/locales/bg/donation-flow.json +++ b/public/locales/bg/donation-flow.json @@ -102,7 +102,7 @@ }, "noregister": { "label": "Продължете без регистрация ", - "description": "Продължавайки без регистрация, нямате възможност да запазите дарението в историята на профила си както и да правите месечни дарения по избрана кампания" + "description": "Продължавайки без регистрация, нямате възможност да запазите дарението в историята на профила си както и да правите месечни дарения по избрана кампания." }, "field": { "password": "Парола", diff --git a/public/locales/en/donation-flow.json b/public/locales/en/donation-flow.json index 1d888caf6..2f6c0ca80 100644 --- a/public/locales/en/donation-flow.json +++ b/public/locales/en/donation-flow.json @@ -56,7 +56,7 @@ }, "card-data": { "name-label": "Cardholder name", - "error": { + "errors": { "email": "Please enter your email", "name": "Please enter your name" } diff --git a/src/components/client/donation-flow/steps/Amount.tsx b/src/components/client/donation-flow/steps/Amount.tsx index 303327984..986862668 100644 --- a/src/components/client/donation-flow/steps/Amount.tsx +++ b/src/components/client/donation-flow/steps/Amount.tsx @@ -27,7 +27,7 @@ export const initialAmountFormValues = { export const amountValidation = { amountChosen: yup.string().when('payment', { is: 'card', - then: yup.string().required(), + then: yup.string().optional(), }), finalAmount: yup.number().when('payment', { is: (payment: string | null) => ['card', null].includes(payment), diff --git a/src/components/client/donation-flow/steps/authentication/InlineRegisterForm.tsx b/src/components/client/donation-flow/steps/authentication/InlineRegisterForm.tsx index b0e3cdc90..3da6606db 100644 --- a/src/components/client/donation-flow/steps/authentication/InlineRegisterForm.tsx +++ b/src/components/client/donation-flow/steps/authentication/InlineRegisterForm.tsx @@ -83,7 +83,6 @@ export default function InlineRegisterForm() { try { setLoading(true) // Register in Keycloak - if (values.terms && values.gdpr && values.password === values.confirmPassword) { await register(values) } else if (!values.terms) { @@ -143,7 +142,7 @@ export default function InlineRegisterForm() { @@ -155,11 +154,11 @@ export default function InlineRegisterForm() { )} - + {!formik.values.registerTerms && formik.touched.registerTerms && ( {t('validation:terms-of-use')} )} - + {!formik.values.registerGdpr && formik.touched.registerGdpr && ( {t('validation:terms-of-service')} diff --git a/src/components/client/donation-flow/steps/payment-method/PaymentMethod.tsx b/src/components/client/donation-flow/steps/payment-method/PaymentMethod.tsx index 16769a641..a021bf558 100644 --- a/src/components/client/donation-flow/steps/payment-method/PaymentMethod.tsx +++ b/src/components/client/donation-flow/steps/payment-method/PaymentMethod.tsx @@ -35,13 +35,13 @@ export default function PaymentMethod({ { value: 'card', label: t('step.payment-method.field.method.card'), - icon: , + icon: , disabled: false, }, { value: 'bank', label: t('step.payment-method.field.method.bank'), - icon: , + icon: , disabled: mode.value === 'subscription', }, ] diff --git a/src/components/common/SocialShareListButton.tsx b/src/components/common/SocialShareListButton.tsx index ffe3bc4ab..b8fc77091 100644 --- a/src/components/common/SocialShareListButton.tsx +++ b/src/components/common/SocialShareListButton.tsx @@ -8,7 +8,7 @@ import { PopoverProps, ButtonProps, } from '@mui/material' -import { ContentCopy, Facebook, LinkedIn, Share, Twitter } from '@mui/icons-material' +import { ContentCopy, Facebook, LinkedIn, Share, Twitter, X } from '@mui/icons-material' import { AlertStore } from 'stores/AlertStore' import theme from 'common/theme' @@ -25,7 +25,7 @@ export default function SocialShareListButton({ }) { const { t } = useTranslation('common') const [anchorEl, setAnchorEl] = React.useState(null) - const serializedUrl = new URLSearchParams(url).toString() + const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget) } @@ -62,20 +62,20 @@ export default function SocialShareListButton({ {t('components.social-share.copy')} - + {t('components.social-share.share')} Facebook {t('components.social-share.share')} LinkedIn - - {t('components.social-share.share')} Twitter - + + {t('components.social-share.share')} X +