diff --git a/app/.env-example.env b/app/.env-example.env index 708ed73ef3..0f30d9ffe8 100644 --- a/app/.env-example.env +++ b/app/.env-example.env @@ -59,7 +59,8 @@ NEXT_PUBLIC_FF_TRUSTALABS_STAMPS=on NEXT_PUBLIC_FF_OUTDID_STAMP=on NEXT_PUBLIC_FF_ONCHAIN_ZKSYNC=off NEXT_PUBLIC_FF_ONCHAIN_SCROLL=off - +Should be set to whatever you have set for CERAMIC_CACHE_SCORER_ID=3 in the scorer API - Used for notifications +NEXT_PUBLIC_CERAMIC_CACHE_SCORER_ID=3 NEXT_PUBLIC_CERAMIC_CACHE_ENDPOINT=http://localhost:8002/ceramic-cache NEXT_PUBLIC_CERAMIC_CACHE_ENDPOINT_V2=http://localhost:8002/ceramic-cache/v2 @@ -86,4 +87,4 @@ NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=YOUR_WALLET_CONNECT_PROJECT_ID NEXT_PUBLIC_WEB3_ONBOARD_EXPLORE_URL=http://localhost:3000/ NEXT_PUBLIC_FF_CERAMIC_CLIENT=off NEXT_PUBLIC_ONBOARD_RESET_INDEX=1 -NEXT_PUBLIC_GA_ID=id \ No newline at end of file +NEXT_PUBLIC_GA_ID=id diff --git a/app/components/Notifications.tsx b/app/components/Notifications.tsx index 1d23d41de0..65d4aa96b0 100644 --- a/app/components/Notifications.tsx +++ b/app/components/Notifications.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, useContext, useMemo } from "react"; +import React, { Fragment, useCallback, useContext, useMemo, useState } from "react"; import { Popover, Transition } from "@headlessui/react"; import { useNotifications, useDismissNotification, Notification } from "../hooks/useNotifications"; import { StampClaimForPlatform, StampClaimingContext } from "../context/stampClaimingContext"; @@ -11,6 +11,13 @@ export type NotificationProps = { setShowSidebar: (show: boolean) => void; }; +enum ReverificationStatus { + INITIAL, + PENDING, + SUCCESSFUL, + REJECTED, +} + const ExpiryAction = ({ content, provider, @@ -20,30 +27,53 @@ const ExpiryAction = ({ provider: PROVIDER_ID; notification_id: string; }) => { + const [reverificationStatus, setReverificationStatus] = useState(ReverificationStatus.INITIAL); const { claimCredentials } = useContext(StampClaimingContext); const { expiredPlatforms } = useContext(CeramicContext); - - const platformId = Object.values(expiredPlatforms) - .filter((platform) => { - const providers = platform.platFormGroupSpec - .map((spec) => spec.providers.map((provider) => provider.name)) - .flat(); - - return providers.includes(provider); - }) - .map((platform) => platform.platform.platformId)[0]; - const deleteMutation = useDismissNotification(notification_id, "delete"); - const message = useMemo(() => { - const refreshStamp = async (stamp: StampClaimForPlatform) => { + const platformId = useMemo(() => { + return Object.values(expiredPlatforms) + .filter((platform) => { + const providers = platform.platFormGroupSpec + .map((spec) => spec.providers.map((provider) => provider.name)) + .flat(); + return providers.includes(provider); + }) + .map((platform) => platform.platform.platformId)[0]; + }, [expiredPlatforms, provider]); + + const refreshStamp = useCallback( + async (stamp: StampClaimForPlatform) => { + setReverificationStatus(ReverificationStatus.PENDING); await claimCredentials( async () => await Promise.resolve(), - () => {}, + () => { + setReverificationStatus(ReverificationStatus.REJECTED); + }, [stamp] ); + if (reverificationStatus === ReverificationStatus.REJECTED) { + return; + } + setReverificationStatus(ReverificationStatus.SUCCESSFUL); + await new Promise((resolve) => setTimeout(resolve, 5000)); deleteMutation.mutate(); - }; + }, + [claimCredentials, deleteMutation, reverificationStatus] + ); + + const message = useMemo(() => { + if (reverificationStatus === ReverificationStatus.PENDING) { + return
Your stamp is being reverified
; + } + if (reverificationStatus === ReverificationStatus.REJECTED) { + return
There was an error re-verifying the stamp. Please double check your eligibility.
; + } + if (reverificationStatus === ReverificationStatus.SUCCESSFUL) { + return
Your expired stamp has been reverified!
; + } + const claim: StampClaimForPlatform = { platformId: platformId as PLATFORM_ID, selectedProviders: [provider], @@ -59,7 +89,7 @@ const ExpiryAction = ({ part ) ); - }, [platformId, provider, content, claimCredentials, deleteMutation]); + }, [platformId, provider, reverificationStatus, content, refreshStamp]); return <>{message}; }; diff --git a/app/hooks/useNotifications.tsx b/app/hooks/useNotifications.tsx index 9df415355e..0173663239 100644 --- a/app/hooks/useNotifications.tsx +++ b/app/hooks/useNotifications.tsx @@ -6,6 +6,7 @@ import { useOnChainData } from "./useOnChainData"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { debug } from "console"; import { chains } from "../utils/chains"; +import { useCustomization } from "./useCustomization"; export type Notification = { notification_id: string; @@ -25,11 +26,12 @@ type ExpiredChain = { name: string; }; -const fetchNotifications = async (expiredChains?: ExpiredChain[], dbAccessToken?: string) => { +const fetchNotifications = async (expiredChains?: ExpiredChain[], dbAccessToken?: string, scorerId?: number) => { const res = await axios.post( `${process.env.NEXT_PUBLIC_SCORER_ENDPOINT}/passport-admin/notifications`, { expired_chain_ids: expiredChains || [], + scorer_id: scorerId || process.env.NEXT_PUBLIC_CERAMIC_CACHE_SCORER_ID, }, { headers: { @@ -81,6 +83,7 @@ export const useDismissNotification = (notification_id: string, dismissalType: " export const useNotifications = () => { const { dbAccessTokenStatus, dbAccessToken } = useDatastoreConnectionContext(); + const { scorer } = useCustomization(); const { data: onChainData } = useOnChainData(); const [expiredChains, setExpiredChains] = useState(); @@ -101,7 +104,7 @@ export const useNotifications = () => { const { data: notifications, error } = useQuery({ queryKey: ["notifications"], - queryFn: () => fetchNotifications(expiredChains, dbAccessToken), + queryFn: () => fetchNotifications(expiredChains, dbAccessToken, scorer?.id), enabled: !!dbAccessToken && dbAccessTokenStatus === "connected" && expiredChains !== undefined, });