From ef2e23f91489efd3414d8d8f13a15e0ced126319 Mon Sep 17 00:00:00 2001 From: sunilsabatp <101264823+sunilsabatp@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:43:56 +0530 Subject: [PATCH] refactor(types): replace 'any' with generic types in POST authenticated requests --- .../[slug]/[locale]/claim/[type]/[code].tsx | 11 ++++-- .../[slug]/[locale]/profile/redeem/[code].tsx | 8 +++-- .../user/BulkCodes/forms/IssueCodesForm.tsx | 5 ++- .../ManagePayouts/screens/AddBankAccount.tsx | 19 ++++++++-- .../components/BasicDetails.tsx | 35 +++++++++++++++++-- .../components/ProjectCertificates.tsx | 10 ++++-- .../components/ProjectMedia.tsx | 10 ++++-- .../components/ProjectSites.tsx | 16 +++++++-- .../components/ProjectSpending.tsx | 10 ++++-- .../components/CreateAccountForm.tsx | 23 ++++++++++-- .../Profile/ProfileCard/RedeemModal/index.tsx | 10 ++++-- .../RegisterTrees/UploadImages.tsx | 9 +++-- .../RegisterTrees/RegisterTreesWidget.tsx | 15 ++++++-- .../AddressManagement/AddAddress.tsx | 14 ++++++-- .../Import/components/PlantingLocation.tsx | 22 ++++++++++-- src/utils/apiRequests/api.ts | 8 ++--- 16 files changed, 188 insertions(+), 37 deletions(-) diff --git a/pages/sites/[slug]/[locale]/claim/[type]/[code].tsx b/pages/sites/[slug]/[locale]/claim/[type]/[code].tsx index d03d2f96c..30c2deb72 100644 --- a/pages/sites/[slug]/[locale]/claim/[type]/[code].tsx +++ b/pages/sites/[slug]/[locale]/claim/[type]/[code].tsx @@ -35,6 +35,10 @@ interface Props { pageProps: PageProps; } +export type RedeemCodeSubmitData = { + code: string; +}; + function ClaimDonation({ pageProps }: Props): ReactElement { const t = useTranslations('Redeem'); const router = useRouter(); @@ -79,12 +83,15 @@ function ClaimDonation({ pageProps }: Props): ReactElement { }; async function redeemingCode(code: string): Promise { - const submitData = { + const submitData: RedeemCodeSubmitData = { code: code, }; if (contextLoaded && user) { try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest< + RedeemedCodeData, + RedeemCodeSubmitData + >({ tenant: pageProps.tenantConfig.id, url: `/app/redeem`, data: submitData, diff --git a/pages/sites/[slug]/[locale]/profile/redeem/[code].tsx b/pages/sites/[slug]/[locale]/profile/redeem/[code].tsx index 2f3303cc2..347a66268 100644 --- a/pages/sites/[slug]/[locale]/profile/redeem/[code].tsx +++ b/pages/sites/[slug]/[locale]/profile/redeem/[code].tsx @@ -8,6 +8,7 @@ import type { AbstractIntlMessages } from 'next-intl'; import type { APIError, SerializedError } from '@planet-sdk/common'; import type { Tenant } from '@planet-sdk/common/build/types/tenant'; import type { RedeemedCodeData } from '../../../../../../src/features/common/types/redeem'; +import type { RedeemCodeSubmitData } from '../../claim/[type]/[code]'; import { useRouter } from 'next/router'; import { useState, useEffect, useContext } from 'react'; @@ -73,13 +74,16 @@ const RedeemCode = ({ pageProps: { tenantConfig } }: Props) => { async function redeemingCode(data: string): Promise { setIsLoading(true); - const submitData = { + const submitData: RedeemCodeSubmitData = { code: data, }; if (contextLoaded && user) { try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest< + RedeemedCodeData, + RedeemCodeSubmitData + >({ tenant: tenantConfig?.id, url: `/app/redeem`, data: submitData, diff --git a/src/features/user/BulkCodes/forms/IssueCodesForm.tsx b/src/features/user/BulkCodes/forms/IssueCodesForm.tsx index 9641007ec..8146efa63 100644 --- a/src/features/user/BulkCodes/forms/IssueCodesForm.tsx +++ b/src/features/user/BulkCodes/forms/IssueCodesForm.tsx @@ -152,7 +152,10 @@ const IssueCodesForm = (): ReactElement | null => { const cleanedData = cleanObject(donationData); try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest< + Donation, + PrepaidDonationRequest + >({ tenant: tenantConfig?.id, url: `/app/donations`, data: cleanedData, diff --git a/src/features/user/ManagePayouts/screens/AddBankAccount.tsx b/src/features/user/ManagePayouts/screens/AddBankAccount.tsx index 93c52aa13..e2993e674 100644 --- a/src/features/user/ManagePayouts/screens/AddBankAccount.tsx +++ b/src/features/user/ManagePayouts/screens/AddBankAccount.tsx @@ -17,6 +17,21 @@ import { PayoutCurrency } from '../../../../utils/constants/payoutConstants'; import { handleError } from '@planet-sdk/common'; import { useTenant } from '../../../common/Layout/TenantContext'; +interface AccountData { + currency: string; + payoutMinAmount: string | undefined; + bankName: string; + bankCountry: string; + bankAddress: string; + holderName: string; + holderAddress: string; + accountNumber: string; + routingNumber: string; + bic: string; + branchCode: string; + remarks: string; +} + const AddBankAccount = (): ReactElement | null => { const t = useTranslations('ManagePayouts'); const { payoutMinAmounts, setAccounts, accounts } = usePayouts(); @@ -32,14 +47,14 @@ const AddBankAccount = (): ReactElement | null => { const handleSaveAccount = async (data: FormData) => { setIsProcessing(true); - const accountData = { + const accountData: AccountData = { ...data, currency: data.currency === PayoutCurrency.DEFAULT ? '' : data.currency, payoutMinAmount: data.currency === PayoutCurrency.DEFAULT ? '' : data.payoutMinAmount, }; try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest({ tenant: tenantConfig?.id, url: '/app/accounts', data: accountData, diff --git a/src/features/user/ManageProjects/components/BasicDetails.tsx b/src/features/user/ManageProjects/components/BasicDetails.tsx index b8dc673ed..79c3cadb8 100644 --- a/src/features/user/ManageProjects/components/BasicDetails.tsx +++ b/src/features/user/ManageProjects/components/BasicDetails.tsx @@ -66,6 +66,36 @@ type TreeFormData = FormData & { type ConservationFormData = FormData; +interface SubmitDataBase { + name: string; + slug: string; + website: string; + description: string; + acceptDonations: boolean; + unitCost: number | undefined; + currency: 'EUR'; // Fixed currency + metadata: { + ecosystem: string; + visitorAssistance: boolean; + }; + geometry: { + type: 'Point'; + coordinates: [number, number]; + }; +} + +interface SubmitDataTrees extends SubmitDataBase { + unitType: 'tree' | 'm2'; + classification: string; + countTarget: number; +} + +interface SubmitDataConservation extends SubmitDataBase { + purpose: 'conservation'; +} + +type SubmitData = SubmitDataTrees | SubmitDataConservation; + export default function BasicDetails({ handleNext, token, @@ -306,7 +336,7 @@ export default function BasicDetails({ const onSubmit = async (data: TreeFormData | ConservationFormData) => { setIsUploadingData(true); - const submitData = + const submitData: SubmitData = purpose === 'trees' ? { name: data.name, @@ -379,7 +409,8 @@ export default function BasicDetails({ } else { try { const res = await postAuthenticatedRequest< - ProfileProjectTrees | ProfileProjectConservation + ProfileProjectTrees | ProfileProjectConservation, + SubmitData >({ tenant: tenantConfig?.id, url: `/app/projects`, diff --git a/src/features/user/ManageProjects/components/ProjectCertificates.tsx b/src/features/user/ManageProjects/components/ProjectCertificates.tsx index ae3e5bb8c..0a323e94a 100644 --- a/src/features/user/ManageProjects/components/ProjectCertificates.tsx +++ b/src/features/user/ManageProjects/components/ProjectCertificates.tsx @@ -48,6 +48,12 @@ const dialogSx: SxProps = { }, }; +type SubmitData = { + issueDate: string; + certifierName: string; + pdfFile: string; +}; + function ProjectCertificates({ projectGUID, token, @@ -78,14 +84,14 @@ function ProjectCertificates({ const onSubmit = async (pdf: string) => { const { issueDate, certifierName } = getValues(); setIsUploadingData(true); - const submitData = { + const submitData: SubmitData = { issueDate: issueDate.getFullYear(), certifierName: certifierName, pdfFile: pdf, }; try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest({ tenant: tenantConfig?.id, url: `/app/projects/${projectGUID}/certificates`, data: submitData, diff --git a/src/features/user/ManageProjects/components/ProjectMedia.tsx b/src/features/user/ManageProjects/components/ProjectMedia.tsx index 72aeb0fb4..3eef0ae10 100644 --- a/src/features/user/ManageProjects/components/ProjectMedia.tsx +++ b/src/features/user/ManageProjects/components/ProjectMedia.tsx @@ -33,6 +33,12 @@ import { useUserProps } from '../../../common/Layout/UserPropsContext'; import { ProjectCreationTabs } from '..'; import { useTenant } from '../../../common/Layout/TenantContext'; +type SubmitData = { + imageFile: string; + description: string | null; + isDefault: boolean; +}; + export default function ProjectMedia({ handleBack, token, @@ -84,14 +90,14 @@ export default function ProjectMedia({ const uploadPhotos = async (image: string) => { setIsUploadingData(true); - const submitData = { + const submitData: SubmitData = { imageFile: image, description: null, isDefault: false, }; try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest({ tenant: tenantConfig?.id, url: `/app/projects/${projectGUID}/images`, data: submitData, diff --git a/src/features/user/ManageProjects/components/ProjectSites.tsx b/src/features/user/ManageProjects/components/ProjectSites.tsx index c0d36d2b8..f80644eb8 100644 --- a/src/features/user/ManageProjects/components/ProjectSites.tsx +++ b/src/features/user/ManageProjects/components/ProjectSites.tsx @@ -8,7 +8,11 @@ import type { Site, SitesScopeProjects, } from '../../../common/types/project'; -import type { FeatureCollection as GeoJson } from 'geojson'; +import type { + FeatureCollection as GeoJson, + GeoJsonProperties, + Geometry, +} from 'geojson'; import React from 'react'; import styles from './../StepForm.module.scss'; @@ -258,6 +262,12 @@ interface ProjectSitesFormData { status: string; } +type SubmitData = { + name: string; + geometry: GeoJson; + status: string; +}; + export default function ProjectSites({ handleBack, token, @@ -369,14 +379,14 @@ export default function ProjectSites({ if (!data.name) return; setIsUploadingData(true); - const submitData = { + const submitData: SubmitData = { name: siteDetails.name, geometry: geoJson, status: data.status, }; try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest({ tenant: tenantConfig?.id, url: `/app/projects/${projectGUID}/sites`, data: submitData, diff --git a/src/features/user/ManageProjects/components/ProjectSpending.tsx b/src/features/user/ManageProjects/components/ProjectSpending.tsx index 89e81c419..f7ff6beb8 100644 --- a/src/features/user/ManageProjects/components/ProjectSpending.tsx +++ b/src/features/user/ManageProjects/components/ProjectSpending.tsx @@ -56,7 +56,11 @@ type FormData = { year: Date; amount: number; }; - +type SubmitData = { + year: number; + amount: number; + pdfFile: string | ArrayBuffer | null | undefined; +}; export default function ProjectSpending({ handleBack, token, @@ -88,14 +92,14 @@ export default function ProjectSpending({ const updatedAmount = getValues('amount'); const year = getValues('year'); - const submitData = { + const submitData: SubmitData = { year: year.getFullYear(), amount: updatedAmount, pdfFile: pdf, }; try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest({ tenant: tenantConfig?.id, url: `/app/projects/${projectGUID}/expenses`, data: submitData, diff --git a/src/features/user/PlanetCash/components/CreateAccountForm.tsx b/src/features/user/PlanetCash/components/CreateAccountForm.tsx index a4181247c..fc0b70b53 100644 --- a/src/features/user/PlanetCash/components/CreateAccountForm.tsx +++ b/src/features/user/PlanetCash/components/CreateAccountForm.tsx @@ -25,6 +25,25 @@ interface Props { allowedCountries: CountryType[]; } +type SubmitData = { + country: ExtendedCountryCode | string; + activate: boolean; +}; + +type PlanetCash = { + id: string; + isActive: boolean; + ownerName: string; + balance: number; + debit: number; + fee: number; + creditLimit: number; + currency: 'EUR' | 'USD'; + country: 'DE' | 'ES' | 'US'; + topUpThreshold: number; + topUpAmount: number; +}; + const CreateAccountForm = ({ allowedCountries, isPlanetCashActive, @@ -42,11 +61,11 @@ const CreateAccountForm = ({ const onSubmit = async (event: FormEvent) => { event.preventDefault(); - const data = { country: country, activate: !isPlanetCashActive }; + const data: Data = { country: country, activate: !isPlanetCashActive }; setIsProcessing(true); try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest({ tenant: tenantConfig?.id, url: '/app/planetCash', data, diff --git a/src/features/user/Profile/ProfileCard/RedeemModal/index.tsx b/src/features/user/Profile/ProfileCard/RedeemModal/index.tsx index 7c3cc94d2..8f50e3160 100644 --- a/src/features/user/Profile/ProfileCard/RedeemModal/index.tsx +++ b/src/features/user/Profile/ProfileCard/RedeemModal/index.tsx @@ -1,6 +1,7 @@ import type { ReactElement } from 'react'; import type { APIError, SerializedError } from '@planet-sdk/common'; import type { RedeemedCodeData } from '../../../../common/types/redeem'; +import type { RedeemCodeSubmitData } from '../../../../../../pages/sites/[slug]/[locale]/claim/[type]/[code]'; import Modal from '@mui/material/Modal'; import Fade from '@mui/material/Fade'; @@ -43,14 +44,17 @@ export default function RedeemModal({ RedeemedCodeData | undefined >(undefined); const [isLoading, setIsLoading] = React.useState(false); - async function redeemingCode(data: string | undefined): Promise { + async function redeemingCode(data: string): Promise { setIsLoading(true); - const submitData = { + const submitData: RedeemCodeSubmitData = { code: data, }; if (contextLoaded && user) { try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest< + RedeemedCodeData, + RedeemCodeSubmitData + >({ tenant: tenantConfig?.id, url: `/app/redeem`, data: submitData, diff --git a/src/features/user/RegisterTrees/RegisterTrees/UploadImages.tsx b/src/features/user/RegisterTrees/RegisterTrees/UploadImages.tsx index 7f91ebfd6..d4979ca37 100644 --- a/src/features/user/RegisterTrees/RegisterTrees/UploadImages.tsx +++ b/src/features/user/RegisterTrees/RegisterTrees/UploadImages.tsx @@ -23,6 +23,11 @@ interface Props { token: string | null; } +type SubmitData = { + imageFile: string; + description: string; +}; + export default function UploadImages({ contributionGUID, token, @@ -36,13 +41,13 @@ export default function UploadImages({ const uploadPhotos = async (image: string) => { setIsUploadingData(true); - const submitData = { + const submitData: SubmitData = { imageFile: image, description: '', }; try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest({ tenant: tenantConfig?.id, url: `/app/contributions/${contributionGUID}/images`, data: submitData, diff --git a/src/features/user/RegisterTrees/RegisterTreesWidget.tsx b/src/features/user/RegisterTrees/RegisterTreesWidget.tsx index 519d449ef..63de1fc30 100644 --- a/src/features/user/RegisterTrees/RegisterTreesWidget.tsx +++ b/src/features/user/RegisterTrees/RegisterTreesWidget.tsx @@ -61,6 +61,14 @@ const dialogSx: SxProps = { }, }; +type SubmitData = { + treeCount: string; + treeSpecies: string; + plantProject: string | null; + plantDate: Date; + geometry: RegisterTreeGeometry; +}; + function RegisterTreesForm({ setContributionGUID, setContributionDetails, @@ -183,7 +191,7 @@ function RegisterTreesForm({ geometry.features?.length >= 1)) ) { setIsUploadingData(true); - const submitData = { + const submitData: SubmitData = { treeCount: data.treeCount, treeSpecies: data.species, plantProject: data.plantProject, @@ -191,7 +199,10 @@ function RegisterTreesForm({ geometry: geometry, }; try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest< + ContributionProperties, + SubmitData + >({ tenant: tenantConfig?.id, url: `/app/contributions`, data: submitData, diff --git a/src/features/user/Settings/EditProfile/AddressManagement/AddAddress.tsx b/src/features/user/Settings/EditProfile/AddressManagement/AddAddress.tsx index e9981098b..f729c8b4f 100644 --- a/src/features/user/Settings/EditProfile/AddressManagement/AddAddress.tsx +++ b/src/features/user/Settings/EditProfile/AddressManagement/AddAddress.tsx @@ -29,6 +29,16 @@ interface Props { setAddressAction: SetState; } +type SubmitData = { + country: '' | ExtendedCountryCode; + type: 'other'; + address: string | undefined; + address2: string | null; + city: string | undefined; + zipCode: string | undefined; + state: string | null; +}; + const defaultAddressDetail = { address: '', address2: '', @@ -57,13 +67,13 @@ const AddAddress = ({ async (data: FormData) => { if (!contextLoaded || !user || !token) return; setIsLoading(true); - const bodyToSend = { + const bodyToSend: SubmitData = { ...data, country, type: ADDRESS_TYPE.OTHER, }; try { - const res = await postAuthenticatedRequest
({ + const res = await postAuthenticatedRequest({ tenant: tenantConfig.id, url: '/app/addresses', data: bodyToSend, diff --git a/src/features/user/TreeMapper/Import/components/PlantingLocation.tsx b/src/features/user/TreeMapper/Import/components/PlantingLocation.tsx index fb3a9debc..8807491ac 100644 --- a/src/features/user/TreeMapper/Import/components/PlantingLocation.tsx +++ b/src/features/user/TreeMapper/Import/components/PlantingLocation.tsx @@ -10,7 +10,10 @@ import type { Species, PlantLocation as PlantLocationType, } from '../../../../common/types/plantLocation'; -import type { PlantingLocationFormData } from '../../Treemapper'; +import type { + PlantingLocationFormData, + SpeciesFormData, +} from '../../Treemapper'; import type { MapProject } from '../../../../common/types/ProjectPropsContextInterface'; import type { SetState } from '../../../../common/types/common'; import type { SxProps } from '@mui/material'; @@ -165,6 +168,16 @@ interface Props { setActiveMethod: Function; } +type SubmitData = { + type: 'multi-tree-registration'; + captureMode: 'external'; + geometry: Geometry; + plantedSpecies: SpeciesFormData[]; + plantDate: string; + registrationDate: string; + plantProject: string; +}; + export default function PlantingLocation({ handleNext, userLang, @@ -329,7 +342,7 @@ export default function PlantingLocation({ const onSubmit = async (data: PlantingLocationFormData) => { if (geoJson) { setIsUploadingData(true); - const submitData = { + const submitData: SubmitData = { type: 'multi-tree-registration', captureMode: 'external', geometry: geoJson, @@ -340,7 +353,10 @@ export default function PlantingLocation({ }; try { - const res = await postAuthenticatedRequest({ + const res = await postAuthenticatedRequest< + PlantLocationType, + SubmitData + >({ tenant: tenantConfig?.id, url: `/treemapper/interventions`, data: submitData, diff --git a/src/utils/apiRequests/api.ts b/src/utils/apiRequests/api.ts index 8dba539ab..68f5a9e4f 100644 --- a/src/utils/apiRequests/api.ts +++ b/src/utils/apiRequests/api.ts @@ -26,9 +26,9 @@ interface GetAuthRequestOptions extends BaseRequestOptions { queryParams?: { [key: string]: string }; version?: string; } -interface PostAuthRequestOptions extends BaseRequestOptions { +interface PostAuthRequestOptions extends BaseRequestOptions { token: string | null; - data: any; + data: D; logoutUser: (value?: string | undefined) => void; headers?: Record; } @@ -171,14 +171,14 @@ export function getAuthenticatedRequest({ }); } -export function postAuthenticatedRequest({ +export function postAuthenticatedRequest({ tenant, url, data, token, logoutUser, headers, -}: PostAuthRequestOptions) { +}: PostAuthRequestOptions) { const lang = localStorage.getItem('language') || 'en'; return new Promise((resolve, reject) => { (async () => {