From 39a213f245af50d4496b92b41b2fd90d4c1d2009 Mon Sep 17 00:00:00 2001 From: Aleksandar Petkov Date: Thu, 27 Jul 2023 18:20:01 +0300 Subject: [PATCH 1/2] Campaigns: Don't show successfull tag if campaign has not reached 100% (#1520) --- src/components/client/campaigns/CampaignCard.tsx | 8 +++++++- .../CompletedCampaignsSection.tsx | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/client/campaigns/CampaignCard.tsx b/src/components/client/campaigns/CampaignCard.tsx index fba1d18d5..c65edf8af 100644 --- a/src/components/client/campaigns/CampaignCard.tsx +++ b/src/components/client/campaigns/CampaignCard.tsx @@ -22,6 +22,7 @@ import Link from 'next/link' import CampaignProgress from './CampaignProgress' import SuccessfullCampaignTag from './SuccessfullCampaignTag' import { CampaignState } from './helpers/campaign.enums' +import { useMemo } from 'react' const PREFIX = 'CampaignCard' @@ -120,6 +121,7 @@ export default function CampaignCard({ campaign, index }: Props) { const pictureUrl = campaignListPictureUrl(campaign) const reached = summary ? summary.reachedAmount : 0 + const percentage = useMemo(() => (reached / target) * 100, [reached, target]) return ( @@ -131,7 +133,11 @@ export default function CampaignCard({ campaign, index }: Props) {
{title} - {campaignState === CampaignState.complete ? : ''} + {campaignState === CampaignState.complete && percentage >= 100 ? ( + + ) : ( + '' + )}
diff --git a/src/components/client/index/sections/CompletedCampaignsSection/CompletedCampaignsSection.tsx b/src/components/client/index/sections/CompletedCampaignsSection/CompletedCampaignsSection.tsx index 7d6951e06..be3077cef 100644 --- a/src/components/client/index/sections/CompletedCampaignsSection/CompletedCampaignsSection.tsx +++ b/src/components/client/index/sections/CompletedCampaignsSection/CompletedCampaignsSection.tsx @@ -31,7 +31,9 @@ export default function CompletedCampaignsSection() { const { data } = useCampaignList() const completedCampaigns = data?.filter( - (campaign: CampaignResponse) => campaign.state === CampaignState.complete, + (campaign: CampaignResponse) => + campaign.state === CampaignState.complete && + (campaign.summary.reachedAmount / campaign.targetAmount) * 100 >= 100, ) const onLinkMouseDown = (e: React.ChangeEvent) => { From f8d8df6beb441093f7ecf07f4bde34c309344d6e Mon Sep 17 00:00:00 2001 From: Aleksandar Petkov Date: Thu, 27 Jul 2023 18:20:32 +0300 Subject: [PATCH 2/2] [TEMP] Signout user on unauthorized response (#1516) * ProfilePage.tsx: Signout user on unauthorized response In some cases the keycloak session expires before the client session, which results in user not being able to see account's data such as donations and profile information. * useCurrentPerson: Don't retry query if response is 401 There is no need to retry on unauthorized response. * Run some linting * useCurrentPerson.ts: Signout user on useCurrentPerson() call --- src/common/util/useCurrentPerson.ts | 33 ++++++++++++++++--- .../client/auth/profile/ProfilePage.tsx | 12 +++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/common/util/useCurrentPerson.ts b/src/common/util/useCurrentPerson.ts index 691c8cab4..a68bb231c 100644 --- a/src/common/util/useCurrentPerson.ts +++ b/src/common/util/useCurrentPerson.ts @@ -1,6 +1,6 @@ -import { AxiosResponse } from 'axios' +import { AxiosError, AxiosResponse } from 'axios' import { useQuery } from '@tanstack/react-query' -import { useSession } from 'next-auth/react' +import { signOut, useSession } from 'next-auth/react' import { apiClient } from 'service/apiClient' import { endpoints } from 'service/apiEndpoints' @@ -15,20 +15,45 @@ type CurrentPerson = { status: 'unauthenticated' } +//Note: Used only for /profile page export function getCurrentPerson(isNew = false) { const { data: session } = useSession() - return useQuery( + const query = useQuery( [isNew ? endpoints.account.new.url : endpoints.account.me.url], authQueryFnFactory(session?.accessToken), + { + retry: (count, err) => { + if (err.isAxiosError && err.response?.status === 401) { + return false + } + return true + }, + }, ) + if (query.error && query.error.response?.status === 401) + signOut({ redirect: true, callbackUrl: '/login' }) + + return query } +//Note: Used for every other page export function useCurrentPerson() { const { data: session } = useSession() - return useQuery( + const query = useQuery( [endpoints.account.me.url], authQueryFnFactory(session?.accessToken), + { + retry: (count, err) => { + if (err.isAxiosError && err.response?.status === 401) { + return false + } + return true + }, + }, ) + if (query.error && query.error.response?.status === 401) signOut({ redirect: false }) + + return query } export function updateCurrentPerson() { diff --git a/src/components/client/auth/profile/ProfilePage.tsx b/src/components/client/auth/profile/ProfilePage.tsx index 264c0ce1e..a53bc3e28 100644 --- a/src/components/client/auth/profile/ProfilePage.tsx +++ b/src/components/client/auth/profile/ProfilePage.tsx @@ -19,6 +19,7 @@ import { routes } from 'common/routes' import Layout from 'components/client/layout/Layout' import { ProfileTabs, ProfileTab, tabs } from './tabs' +import { getCurrentPerson } from 'common/util/useCurrentPerson' const PREFIX = 'ProfilePage' @@ -50,6 +51,9 @@ export default function ProfilePage() { const router = useRouter() const matches = useMediaQuery(theme.breakpoints.down('sm')) const currentTab = router.query.slug ?? ProfileTabs.donations + + const { error: userError, isError } = getCurrentPerson(!!router.query?.register) + const tab = useMemo(() => { return tabs.find((tab) => tab.slug === currentTab) ?? tabs[0] }, [currentTab]) @@ -62,6 +66,14 @@ export default function ProfilePage() { return Not authenticated } + if (isError && userError.response && userError.response.status === 401) { + return ( + + The user session has expired. Redirecting to login page + + ) + } + const { Component: SelectedTab } = tab return (