From 6c03b38fb86a2be15e2db2d2c86112ca4ae108e4 Mon Sep 17 00:00:00 2001 From: Johnny D Date: Sun, 11 Aug 2024 09:26:01 +1000 Subject: [PATCH 01/46] V4 project page: volume charts [1/n] (#4420) --- .../VolumeChart/hooks/useProjectTimeline.ts | 30 ++-- .../v4/graphql/queries/projectTL.graphql | 130 ++++++++++++++++++ src/packages/v4/graphql/useSubgraphQuery.ts | 12 +- .../V4ActivityPanel/V4ActivityList.tsx | 15 +- .../V4ActivityPanel/V4ActivityPanel.tsx | 12 +- .../hooks/useDownloadPayments.ts | 15 +- .../hooks/useV4ProjectHeader.ts | 11 +- 7 files changed, 190 insertions(+), 35 deletions(-) create mode 100644 src/packages/v4/graphql/queries/projectTL.graphql diff --git a/src/components/VolumeChart/hooks/useProjectTimeline.ts b/src/components/VolumeChart/hooks/useProjectTimeline.ts index 835bd277ed..55520a1c32 100644 --- a/src/components/VolumeChart/hooks/useProjectTimeline.ts +++ b/src/components/VolumeChart/hooks/useProjectTimeline.ts @@ -1,9 +1,12 @@ import { useQuery } from '@tanstack/react-query' +import { PV_V4 } from 'constants/pv' import { readProvider } from 'constants/readProvider' import EthDater from 'ethereum-block-by-date' -import { useProjectTlQuery } from 'generated/graphql' +import { ProjectTlQuery, useProjectTlQuery } from 'generated/graphql' import { client } from 'lib/apollo/client' import { PV } from 'models/pv' +import { ProjectTlDocument } from 'packages/v4/graphql/client/graphql' +import { useSubgraphQuery } from 'packages/v4/graphql/useSubgraphQuery' import { useMemo } from 'react' import { wadToFloat } from 'utils/format/formatNumber' import { getSubgraphIdForProject } from 'utils/graph' @@ -73,23 +76,26 @@ export function useProjectTimeline({ id: blocks ? getSubgraphIdForProject(pv, projectId) : '', ...blocks, }, + skip: pv === PV_V4 + }) + + const { data: v4QueryResult } = useSubgraphQuery({ + document: ProjectTlDocument, + variables: { + id: blocks ? projectId.toString() : '', + ...blocks, + }, + enabled: pv === PV_V4 }) - // TODO: const { data: v4QueryResult } = useSubgraphQuery(ProjectTlDocument, { - // where: { - // projectId, - // }, - // }) const points = useMemo(() => { - // TODO: if (!(v1v2v3QueryResult || v4QueryResult) || !timestamps) return - if (!v1v2v3QueryResult || !timestamps) return - // TODO: const queryResult = pv === PV_V4 ? v4QueryResult : v1v2v3QueryResult - const queryResult = v1v2v3QueryResult + const queryResult = pv === PV_V4 ? v4QueryResult : v1v2v3QueryResult + if (!queryResult || !timestamps) return const points: ProjectTimelinePoint[] = [] for (let i = 0; i < COUNT; i++) { - const point = queryResult[`p${i}` as keyof typeof queryResult] + const point = (queryResult as ProjectTlQuery)[`p${i}` as keyof typeof queryResult] if (!point) continue @@ -102,7 +108,7 @@ export function useProjectTimeline({ } return points - }, [timestamps, v1v2v3QueryResult]) + }, [timestamps, v1v2v3QueryResult, v4QueryResult, pv]) return { points, diff --git a/src/packages/v4/graphql/queries/projectTL.graphql b/src/packages/v4/graphql/queries/projectTL.graphql new file mode 100644 index 0000000000..fc3c500295 --- /dev/null +++ b/src/packages/v4/graphql/queries/projectTL.graphql @@ -0,0 +1,130 @@ +fragment ProjectTLParts on Project { + currentBalance + volume + trendingScore +} + +query ProjectTL( + $id: ID! + $block0: Int + $block1: Int + $block2: Int + $block3: Int + $block4: Int + $block5: Int + $block6: Int + $block7: Int + $block8: Int + $block9: Int + $block10: Int + $block11: Int + $block12: Int + $block13: Int + $block14: Int + $block15: Int + $block16: Int + $block17: Int + $block18: Int + $block19: Int + $block20: Int + $block21: Int + $block22: Int + $block23: Int + $block24: Int + $block25: Int + $block26: Int + $block27: Int + $block28: Int + $block29: Int +) { + p0: project(id: $id, block: { number: $block0 }) { + ...ProjectTLParts + } + p1: project(id: $id, block: { number: $block1 }) { + ...ProjectTLParts + } + p2: project(id: $id, block: { number: $block2 }) { + ...ProjectTLParts + } + p3: project(id: $id, block: { number: $block3 }) { + ...ProjectTLParts + } + p4: project(id: $id, block: { number: $block4 }) { + ...ProjectTLParts + } + p5: project(id: $id, block: { number: $block5 }) { + ...ProjectTLParts + } + p6: project(id: $id, block: { number: $block6 }) { + ...ProjectTLParts + } + p7: project(id: $id, block: { number: $block7 }) { + ...ProjectTLParts + } + p8: project(id: $id, block: { number: $block8 }) { + ...ProjectTLParts + } + p9: project(id: $id, block: { number: $block9 }) { + ...ProjectTLParts + } + p10: project(id: $id, block: { number: $block10 }) { + ...ProjectTLParts + } + p11: project(id: $id, block: { number: $block11 }) { + ...ProjectTLParts + } + p12: project(id: $id, block: { number: $block12 }) { + ...ProjectTLParts + } + p13: project(id: $id, block: { number: $block13 }) { + ...ProjectTLParts + } + p14: project(id: $id, block: { number: $block14 }) { + ...ProjectTLParts + } + p15: project(id: $id, block: { number: $block15 }) { + ...ProjectTLParts + } + p16: project(id: $id, block: { number: $block16 }) { + ...ProjectTLParts + } + p17: project(id: $id, block: { number: $block17 }) { + ...ProjectTLParts + } + p18: project(id: $id, block: { number: $block18 }) { + ...ProjectTLParts + } + p19: project(id: $id, block: { number: $block19 }) { + ...ProjectTLParts + } + p20: project(id: $id, block: { number: $block20 }) { + ...ProjectTLParts + } + p21: project(id: $id, block: { number: $block21 }) { + ...ProjectTLParts + } + p22: project(id: $id, block: { number: $block22 }) { + ...ProjectTLParts + } + p23: project(id: $id, block: { number: $block23 }) { + ...ProjectTLParts + } + p24: project(id: $id, block: { number: $block24 }) { + ...ProjectTLParts + } + p25: project(id: $id, block: { number: $block25 }) { + ...ProjectTLParts + } + p26: project(id: $id, block: { number: $block26 }) { + ...ProjectTLParts + } + p27: project(id: $id, block: { number: $block27 }) { + ...ProjectTLParts + } + p28: project(id: $id, block: { number: $block28 }) { + ...ProjectTLParts + } + p29: project(id: $id, block: { number: $block29 }) { + ...ProjectTLParts + } +} diff --git a/src/packages/v4/graphql/useSubgraphQuery.ts b/src/packages/v4/graphql/useSubgraphQuery.ts index 251912e9e4..e8c6a7586c 100644 --- a/src/packages/v4/graphql/useSubgraphQuery.ts +++ b/src/packages/v4/graphql/useSubgraphQuery.ts @@ -8,10 +8,15 @@ BigInt.prototype.toJSON = function () { return { $bigint: this.toString() } } -export function useSubgraphQuery( +export function useSubgraphQuery({ + document, + enabled = true, + variables +}: { document: TypedDocumentNode, - ...[variables]: TVariables extends Record ? [] : [TVariables] -): UseQueryResult { + enabled?: boolean, + variables?: TVariables +}): UseQueryResult { return useQuery({ // eslint-disable-next-line @typescript-eslint/no-explicit-any queryKey: [(document.definitions[0] as any).name.value, variables], @@ -26,5 +31,6 @@ export function useSubgraphQuery( queryKey[1] ? queryKey[1] : undefined, ) }, + enabled }) } diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx index b12f0ea608..2e97805109 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx @@ -18,12 +18,15 @@ export function V4ActivityList() { const { projectId } = useJBContractContext() // TODO: pageSize (pagination) - const { data: payEventsData, isLoading } = useSubgraphQuery(PayEventsDocument, { - orderBy: PayEvent_OrderBy.timestamp, - orderDirection: OrderDirection.desc, - where: { - projectId: Number(projectId), - }, + const { data: payEventsData, isLoading } = useSubgraphQuery({ + document: PayEventsDocument, + variables: { + orderBy: PayEvent_OrderBy.timestamp, + orderDirection: OrderDirection.desc, + where: { + projectId: Number(projectId), + }, + } }) const payEvents = transformPayEventsRes(payEventsData) ?? [] diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx index 311748a86c..1db9dacbc6 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx @@ -12,11 +12,15 @@ import { V4ActivityList } from './V4ActivityList' export function V4ActivityPanel() { const { projectId } = useJBContractContext() - const { data } = useSubgraphQuery(ProjectsDocument, { - where: { - projectId: Number(projectId), - }, + const { data } = useSubgraphQuery({ + document: ProjectsDocument, + variables: { + where: { + projectId: Number(projectId), + }, + } }) + const createdAt = data?.projects?.[0].createdAt return ( diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/hooks/useDownloadPayments.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/hooks/useDownloadPayments.ts index 0ef53cd166..8e60233c93 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/hooks/useDownloadPayments.ts +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/hooks/useDownloadPayments.ts @@ -10,12 +10,15 @@ import { transformPayEventsRes } from "../utils/transformEventsData"; export const useDownloadPayments = (blockNumber: number, projectId: number) => { const [isLoading, setIsLoading] = useState(false); - const { data: payEventsData } = useSubgraphQuery(PayEventsDocument, { - orderBy: PayEvent_OrderBy.timestamp, - orderDirection: OrderDirection.desc, - where: { - projectId: Number(projectId), - }, + const { data: payEventsData } = useSubgraphQuery({ + document: PayEventsDocument, + variables: { + orderBy: PayEvent_OrderBy.timestamp, + orderDirection: OrderDirection.desc, + where: { + projectId: Number(projectId), + }, + } }); const downloadPayments = useCallback(async () => { diff --git a/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts b/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts index a09560f02b..b43598df3c 100644 --- a/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts +++ b/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts @@ -35,10 +35,13 @@ export const useV4ProjectHeader = (): ProjectHeaderData => { const projectIdNum = parseInt(projectId.toString()) - const { data } = useSubgraphQuery(ProjectsDocument, { - where: { - projectId: projectIdNum, - }, + const { data } = useSubgraphQuery({ + document: ProjectsDocument, + variables: { + where: { + projectId: projectIdNum, + }, + } }) const projectStatsData = data?.projects?.[0] From 979af117530fbee0a814a1e8af213ac3ce90664d Mon Sep 17 00:00:00 2001 From: Johnny D Date: Sun, 11 Aug 2024 15:38:13 +1000 Subject: [PATCH 02/46] feat: hide launch project payer for projects with OFAC (#4425) --- .../V2V3ProjectToolsDrawer.tsx | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer/V2V3ProjectToolsDrawer.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer/V2V3ProjectToolsDrawer.tsx index 1b728af9f6..972f5ac768 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer/V2V3ProjectToolsDrawer.tsx +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer/V2V3ProjectToolsDrawer.tsx @@ -25,10 +25,12 @@ export function V2V3ProjectToolsDrawer({ open?: boolean onClose?: VoidFunction }) { - const { projectId } = useContext(ProjectMetadataContext) + const { projectId, projectMetadata } = useContext(ProjectMetadataContext) const { payoutSplits, reservedTokensSplits, handle } = useContext(V2V3ProjectContext) + const hasOFAC = projectMetadata?.projectRequiredOFACCheck + const isMobile = useMobile() return ( @@ -48,18 +50,21 @@ export function V2V3ProjectToolsDrawer({ + + {hasOFAC ? null : ( + <> +
+

+ Project payer addresses +

-
-

- Project payer addresses -

- - -
- - + +
+ + + )} Date: Mon, 12 Aug 2024 15:44:46 +1000 Subject: [PATCH 03/46] feat: hide add to balance for ofac projects --- .../V2V3ProjectToolsDrawer/V2V3ProjectToolsDrawer.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer/V2V3ProjectToolsDrawer.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer/V2V3ProjectToolsDrawer.tsx index 972f5ac768..b15a7ae86c 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer/V2V3ProjectToolsDrawer.tsx +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer/V2V3ProjectToolsDrawer.tsx @@ -45,14 +45,14 @@ export function V2V3ProjectToolsDrawer({
-
- -
- - {hasOFAC ? null : ( <> +
+ +
+ +

Project payer addresses From 6ef3d1acf3461e2ccfa202fec2e30ff0262de2c6 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Mon, 12 Aug 2024 20:08:19 +1000 Subject: [PATCH 04/46] V4 Pay (#4427) --- .../components/CartItemBadge.tsx | 0 .../NftRewards}/SmallNftSquare.tsx | 0 src/locales/messages.pot | 6 - .../ProjectDashboard/ProjectDashboard.tsx | 2 +- .../components/PayInput.test.tsx | 39 --- .../PayProjectCard/components/PayInput.tsx | 73 ----- .../components/TokensPerEth.test.tsx | 54 ---- .../components/TokensPerEth.tsx | 33 --- .../components/__mocks__/PayInput.tsx | 22 -- .../__snapshots__/PayInput.test.tsx.snap | 173 ------------ .../__snapshots__/TokensPerEth.test.tsx.snap | 7 - .../PayProjectCard/hooks/usePayInput.test.ts | 39 --- .../PayProjectCard/hooks/usePayInput.ts | 41 --- .../PayProjectModal/PayProjectModal.tsx | 8 +- .../components/EditRewardBeneficiary.test.tsx | 0 .../components/EditRewardBeneficiary.tsx | 0 .../components/MessageInput.test.tsx | 0 .../components/MessageInput.tsx | 0 .../components/MessageSection.tsx | 2 +- .../components/ReceiveNftItem.test.tsx | 2 +- .../components/ReceiveNftItem.tsx | 6 +- .../components/ReceiveSection.test.tsx | 12 +- .../components/ReceiveSection.tsx | 4 +- .../components/ReceiveTokensItem.test.tsx | 6 +- .../components/ReceiveTokensItem.tsx | 4 +- .../EditRewardBeneficiary.test.tsx.snap | 0 .../editRewardBeneficiaryReducer.test.ts | 0 .../editRewardBeneficiaryReducer.ts | 0 .../useEditRewardBeneficiary.test.ts | 0 .../useEditRewardBeneficiary.ts | 0 .../payProjectModalReducer.test.ts | 0 .../payProjectModalReducer.ts | 0 .../usePayProjectModal/usePayProjectModal.ts | 13 +- .../usePayProjectModal/usePayProjectTx.ts | 4 +- .../usePrepareDelegatePayMetadata.ts | 4 +- .../hooks/useProjectPaymentTokens.ts | 2 +- .../{ => PayRedeemCard}/PayRedeemCard.tsx | 59 ++-- .../SuccessPayView/SuccessPayView.tsx | 2 +- .../components/SuccessNftItem.tsx | 4 +- .../components/SuccessTokensItem.tsx | 2 +- .../hooks/useSuccessPayView.ts | 2 +- .../hooks/usePayProjectCard.ts | 58 ---- .../PayoutsTable/ConvertAmountsModal.tsx | 5 - .../components/PayoutsTable/PayoutTitle.tsx | 5 - .../ReduxProjectCartProvider.tsx | 47 ++++ .../V4PayRedeemCard/EthereumLogo.tsx | 9 + .../V4PayRedeemCard/NftReward.tsx | 93 +++++++ .../V4PayRedeemCard/PayConfiguration.tsx | 176 ++++++++++++ .../PayProjectModal/PayProjectModal.tsx | 174 ++++++++++++ .../components/EditRewardBeneficiary.tsx | 95 +++++++ .../components/MessageInput.tsx | 134 +++++++++ .../components/MessageSection.tsx | 46 ++++ .../components/ReceiveNftItem.tsx | 37 +++ .../components/ReceiveSection.tsx | 49 ++++ .../components/ReceiveTokensItem.tsx | 55 ++++ .../editRewardBeneficiaryReducer.ts | 69 +++++ .../useEditRewardBeneficiary.ts | 70 +++++ .../payProjectModalReducer.ts | 48 ++++ .../usePayProjectModal/usePayProjectModal.ts | 142 ++++++++++ .../usePayProjectModal/usePayProjectTx.ts | 167 ++++++++++++ .../hooks/useProjectPaymentTokens.ts | 52 ++++ .../V4PayRedeemCard/PayRedeemInput.tsx | 210 +++++++++++++++ .../V4PayRedeemCard/RedeemConfiguration.tsx | 225 ++++++++++++++++ .../V4PayRedeemCard/V4PayRedeemCard.tsx | 160 +++++++++++ .../SuccessPayView/SuccessPayView.tsx | 96 +++++++ .../components/SuccessNftItem.tsx | 48 ++++ .../components/SuccessPayCard.tsx | 89 ++++++ .../components/SuccessTokensItem.tsx | 32 +++ .../SuccessPayView/hooks/useSuccessPayView.ts | 35 +++ .../ProjectDashboard/redux/hooks.ts | 9 + .../ProjectDashboard/redux/payRedeemSlice.ts | 29 ++ .../redux/projectCartSlice.ts | 254 ++++++++++++++++++ .../ProjectDashboard/redux/store.ts | 15 ++ .../SplitItem/JuiceboxProjectBeneficiary.tsx | 5 - .../v4/components/V4ProjectHandleLink.tsx | 23 +- src/packages/v4/utils/networks.ts | 18 ++ src/packages/v4/utils/routes.ts | 12 + .../V4PayRedeemCard/V4PayRedeemCard.tsx | 53 ---- .../V4ProjectDashboard/V4ProjectDashboard.tsx | 33 ++- .../V4ProjectDashboard/V4ProjectHeader.tsx | 11 +- .../V4ProjectAllocationRow.tsx | 4 - .../hooks/useV4ProjectHeader.ts | 6 - .../v4/[chainName]/p/[projectId]/index.tsx | 21 +- src/utils/routes.ts | 10 - 84 files changed, 2823 insertions(+), 731 deletions(-) rename src/{packages/v2v3/components/V2V3Project/ProjectDashboard => }/components/CartItemBadge.tsx (100%) rename src/{packages/v2v3/components/V2V3Project/ProjectDashboard/components => components/NftRewards}/SmallNftSquare.tsx (100%) delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/PayInput.test.tsx delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/PayInput.tsx delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/TokensPerEth.test.tsx delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/TokensPerEth.tsx delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__mocks__/PayInput.tsx delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__snapshots__/PayInput.test.tsx.snap delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__snapshots__/TokensPerEth.test.tsx.snap delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/hooks/usePayInput.test.ts delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/hooks/usePayInput.ts rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/PayProjectModal.tsx (98%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/EditRewardBeneficiary.test.tsx (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/EditRewardBeneficiary.tsx (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/MessageInput.test.tsx (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/MessageInput.tsx (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/MessageSection.tsx (93%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/ReceiveNftItem.test.tsx (95%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/ReceiveNftItem.tsx (82%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/ReceiveSection.test.tsx (84%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/ReceiveSection.tsx (86%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/ReceiveTokensItem.test.tsx (80%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/ReceiveTokensItem.tsx (91%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/components/__snapshots__/EditRewardBeneficiary.test.tsx.snap (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.test.ts (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.ts (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.test.ts (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.ts (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/{ => components/PayRedeemCard/PayProjectModal}/hooks/usePayProjectModal/payProjectModalReducer.test.ts (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/{ => components/PayRedeemCard/PayProjectModal}/hooks/usePayProjectModal/payProjectModalReducer.ts (100%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/{ => components/PayRedeemCard/PayProjectModal}/hooks/usePayProjectModal/usePayProjectModal.ts (91%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/{ => components/PayRedeemCard/PayProjectModal}/hooks/usePayProjectModal/usePayProjectTx.ts (95%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/{ => components/PayRedeemCard/PayProjectModal}/hooks/usePayProjectModal/usePrepareDelegatePayMetadata.ts (95%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/{ => components/PayRedeemCard/PayProjectModal}/hooks/useProjectPaymentTokens.ts (82%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/{ => PayRedeemCard}/PayRedeemCard.tsx (95%) rename src/packages/v2v3/components/V2V3Project/ProjectDashboard/{ => components/SuccessPayView}/hooks/useSuccessPayView.ts (93%) delete mode 100644 src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectCard.ts create mode 100644 src/packages/v4/components/ProjectDashboard/ReduxProjectCartProvider.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/EthereumLogo.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/NftReward.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayConfiguration.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/PayProjectModal.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/EditRewardBeneficiary.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/MessageInput.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/MessageSection.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.ts create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.ts create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/payProjectModalReducer.ts create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useProjectPaymentTokens.ts create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayRedeemInput.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/RedeemConfiguration.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessPayCard.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx create mode 100644 src/packages/v4/components/ProjectDashboard/components/SuccessPayView/hooks/useSuccessPayView.ts create mode 100644 src/packages/v4/components/ProjectDashboard/redux/hooks.ts create mode 100644 src/packages/v4/components/ProjectDashboard/redux/payRedeemSlice.ts create mode 100644 src/packages/v4/components/ProjectDashboard/redux/projectCartSlice.ts create mode 100644 src/packages/v4/components/ProjectDashboard/redux/store.ts create mode 100644 src/packages/v4/utils/networks.ts create mode 100644 src/packages/v4/utils/routes.ts delete mode 100644 src/packages/v4/views/V4ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard.tsx diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/CartItemBadge.tsx b/src/components/CartItemBadge.tsx similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/CartItemBadge.tsx rename to src/components/CartItemBadge.tsx diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SmallNftSquare.tsx b/src/components/NftRewards/SmallNftSquare.tsx similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SmallNftSquare.tsx rename to src/components/NftRewards/SmallNftSquare.tsx diff --git a/src/locales/messages.pot b/src/locales/messages.pot index 31ad4d646e..482c1f426e 100644 --- a/src/locales/messages.pot +++ b/src/locales/messages.pot @@ -74,9 +74,6 @@ msgstr "" msgid "Contract address: {0}" msgstr "" -msgid "per {currencyText} paid" -msgstr "" - msgid "No surplus" msgstr "" @@ -479,9 +476,6 @@ msgstr "" msgid "Claiming {tokenSymbol} tokens will convert your {tokenSymbol} balance to ERC-20 tokens and mint them to your wallet." msgstr "" -msgid "Receive {receivedTickets} {receivedTokenSymbolText} {suffix}" -msgstr "" - msgid "Amount to pay out" msgstr "" diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/ProjectDashboard.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/ProjectDashboard.tsx index 253ec92dd7..6c6adb4f77 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/ProjectDashboard.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/ProjectDashboard.tsx @@ -6,7 +6,7 @@ import { Provider } from 'react-redux' import { twMerge } from 'tailwind-merge' import { BlockedProjectBanner } from './components/BlockedProjectBanner' import { FundingCycleCountdownProvider } from './components/FundingCycleCountdown/FundingCycleCountdownProvider' -import { PayRedeemCard } from './components/PayRedeemCard' +import { PayRedeemCard } from './components/PayRedeemCard/PayRedeemCard' import { ProjectHeaderCountdown } from './components/ProjectHeaderCountdown' import { V2V3ProjectTabs } from './components/ProjectTabs/V2V3ProjectTabs' import { ReduxProjectCartProvider } from './components/ReduxProjectCartProvider' diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/PayInput.test.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/PayInput.test.tsx deleted file mode 100644 index 10ebae724f..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/PayInput.test.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @jest-environment jsdom - */ -import { fireEvent, render, screen } from '@testing-library/react' -import { V2V3_CURRENCY_ETH } from 'packages/v2v3/utils/currency' -import { PayInput } from './PayInput' - -describe('PayInput', () => { - it('renders', () => { - const { container } = render() - expect(container).toMatchSnapshot() - }) - - it('renders with placeholder', () => { - const { container } = render() - expect(container).toMatchSnapshot() - }) - - it('renders with value', () => { - const { container } = render( - , - ) - expect(container).toMatchSnapshot() - }) - - test('clicking currency button changes currency', () => { - render() - const button = screen.getByTestId('pay-input-currency-button') - const icon = screen.getByTestId('pay-input-currency-icon') - expect(button).toHaveTextContent('ETH') - expect(icon).toHaveClass('bg-bluebs-50 text-bluebs-500') - fireEvent.click(button) - expect(button).toHaveTextContent('USD') - expect(icon).toHaveClass('bg-melon-50 text-melon-600') - fireEvent.click(button) - expect(button).toHaveTextContent('ETH') - expect(icon).toHaveClass('bg-bluebs-50 text-bluebs-500') - }) -}) diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/PayInput.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/PayInput.tsx deleted file mode 100644 index d6a15e396b..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/PayInput.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { ChevronDownIcon } from '@heroicons/react/24/outline' -import { V2V3CurrencyOption } from 'packages/v2v3/models/currencyOption' -import { - V2V3CurrencyName, - V2V3_CURRENCY_ETH, -} from 'packages/v2v3/utils/currency' -import { FocusEventHandler } from 'react' -import { twMerge } from 'tailwind-merge' -import { CurrencyIcon } from '../../ui/CurrencyIcon' -import { usePayInput } from '../hooks/usePayInput' - -export type PayInputValue = { - amount: string - currency: V2V3CurrencyOption -} - -type Props = { - className?: string - placeholder?: string - value?: PayInputValue - onChange?: (value: PayInputValue) => void - onBlur?: FocusEventHandler - name?: string -} - -export const PayInput = ({ - className, - placeholder, - value, - name, - onChange, - onBlur, -}: Props) => { - const { - value: { amount, currency }, - onInputChange, - onCurrencyChange, - } = usePayInput(value, onChange) - - return ( -
- - -
- - {V2V3CurrencyName(currency)} -
-
- ) -} diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/TokensPerEth.test.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/TokensPerEth.test.tsx deleted file mode 100644 index 58542081b4..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/TokensPerEth.test.tsx +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @jest-environment jsdom - */ -import { render, screen } from '@testing-library/react' -import { useTokensPerEth } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useTokensPerEth' -import { V2V3_CURRENCY_ETH } from 'packages/v2v3/utils/currency' -import { TokensPerEth } from './TokensPerEth' - -jest.mock( - 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useTokensPerEth', - () => ({ - useTokensPerEth: jest.fn(), - }), -) - -describe('TokensPerEth', () => { - const mockedTokensPerEth = { - receivedTickets: '100', - currencyText: 'ETH', - receivedTokenSymbolText: 'TKN', - } - - beforeEach(() => { - ;(useTokensPerEth as jest.Mock).mockReturnValue(mockedTokensPerEth) - }) - - it('renders when `currencyAmount` is 1', () => { - const { container } = render( - , - ) - expect(container).toMatchSnapshot() - expect(screen.getByText('Receive 100 TKN')).toBeInTheDocument() - }) - - it('calls useTokensPerEth with correct arguments', () => { - render( - , - ) - expect(useTokensPerEth).toHaveBeenCalledWith({ - amount: 1, - currency: V2V3_CURRENCY_ETH, - }) - }) -}) diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/TokensPerEth.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/TokensPerEth.tsx deleted file mode 100644 index 0809a86434..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/TokensPerEth.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Trans } from '@lingui/macro' -import { V2V3CurrencyOption } from 'packages/v2v3/models/currencyOption' -import { V2V3_CURRENCY_ETH } from 'packages/v2v3/utils/currency' -import { useTokensPerEth } from '../../../hooks/useTokensPerEth' - -export const TokensPerEth = ({ - currencyAmount, -}: { - currencyAmount: - | { - amount: number // NOTE this is actually a `string | undefined` from what I can tell. Too scared to change it atm. - currency: V2V3CurrencyOption - } - | undefined -}) => { - const { currencyText, receivedTickets, receivedTokenSymbolText } = - useTokensPerEth({ - amount: parseFloat(currencyAmount?.amount?.toString() || '1'), - currency: currencyAmount?.currency || V2V3_CURRENCY_ETH, - }) - - const suffix = - !currencyAmount || !currencyAmount.amount ? ( - per {currencyText} paid - ) : ( - '' - ) - return ( - - Receive {receivedTickets} {receivedTokenSymbolText} {suffix} - - ) -} diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__mocks__/PayInput.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__mocks__/PayInput.tsx deleted file mode 100644 index 7b4c60ab2e..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__mocks__/PayInput.tsx +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -export const PayInput = ({ - className, - placeholder, - value, - onChange, - onBlur, - name, -}: any) => ( - - onChange({ amount: Number(e.target.value), currency: value.currency }) - } - onBlur={onBlur} - /> -) diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__snapshots__/PayInput.test.tsx.snap b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__snapshots__/PayInput.test.tsx.snap deleted file mode 100644 index 5fe6777837..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__snapshots__/PayInput.test.tsx.snap +++ /dev/null @@ -1,173 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PayInput renders 1`] = ` -
-
-
- - - -
- -
- - ETH -
-
-
-`; - -exports[`PayInput renders with placeholder 1`] = ` -
-
-
- - - -
- -
- - ETH -
-
-
-`; - -exports[`PayInput renders with value 1`] = ` -
-
-
- - - -
- -
- - ETH -
-
-
-`; diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__snapshots__/TokensPerEth.test.tsx.snap b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__snapshots__/TokensPerEth.test.tsx.snap deleted file mode 100644 index 13a9818e5a..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/components/__snapshots__/TokensPerEth.test.tsx.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TokensPerEth renders when \`currencyAmount\` is 1 1`] = ` -
- Receive 100 TKN -
-`; diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/hooks/usePayInput.test.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/hooks/usePayInput.test.ts deleted file mode 100644 index 5dccef3cdc..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/hooks/usePayInput.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { act, renderHook } from '@testing-library/react-hooks' -import { - V2V3_CURRENCY_ETH, - V2V3_CURRENCY_USD, -} from 'packages/v2v3/utils/currency' -import { usePayInput } from './usePayInput' - -describe('usePayInput', () => { - it('should show amount value updates onInputChange', () => { - const { result } = renderHook(usePayInput) - expect(result.current.value).toEqual({ - amount: '', - currency: V2V3_CURRENCY_ETH, - }) - act(() => { - result.current.onInputChange({ target: { value: '1' } } as any) - }) - expect(result.current.value).toEqual({ - amount: '1', - currency: V2V3_CURRENCY_ETH, - }) - }) - - it('should show currency value updates onCurrencyChange', () => { - const { result } = renderHook(usePayInput) - expect(result.current.value).toEqual({ - amount: '', - currency: V2V3_CURRENCY_ETH, - }) - act(() => { - result.current.onCurrencyChange() - }) - expect(result.current.value).toEqual({ - amount: '', - currency: V2V3_CURRENCY_USD, - }) - }) -}) diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/hooks/usePayInput.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/hooks/usePayInput.ts deleted file mode 100644 index ccea0ed59c..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectCard/hooks/usePayInput.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - V2V3_CURRENCY_ETH, - V2V3_CURRENCY_USD, -} from 'packages/v2v3/utils/currency' -import { useState } from 'react' -import { PayInputValue } from '../components/PayInput' - -export const usePayInput = ( - v?: PayInputValue, - oc?: (value: PayInputValue) => void, -) => { - const [_value, _setValue] = useState({ - amount: '', - currency: V2V3_CURRENCY_ETH, - }) - const value = v ?? _value - const onChange = oc ?? _setValue - - const onInputChange = (e: React.ChangeEvent) => { - const v = e.target.value - onChange({ - ...value, - amount: v, - }) - } - const onCurrencyChange = () => { - onChange({ - ...value, - currency: - value.currency === V2V3_CURRENCY_ETH - ? V2V3_CURRENCY_USD - : V2V3_CURRENCY_ETH, - }) - } - - return { - value, - onInputChange, - onCurrencyChange, - } -} diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/PayProjectModal.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/PayProjectModal.tsx similarity index 98% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/PayProjectModal.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/PayProjectModal.tsx index 3b5ebef433..40725f1c79 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/PayProjectModal.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/PayProjectModal.tsx @@ -4,14 +4,14 @@ import ExternalLink from 'components/ExternalLink' import { JuiceModal } from 'components/modals/JuiceModal' import { Formik } from 'formik' import Image from 'next/image' -import { - PayProjectModalFormValues, - usePayProjectModal, -} from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectModal' import { twMerge } from 'tailwind-merge' import { helpPagePath } from 'utils/routes' import { MessageSection } from './components/MessageSection' import { ReceiveSection } from './components/ReceiveSection' +import { + PayProjectModalFormValues, + usePayProjectModal, +} from './hooks/usePayProjectModal/usePayProjectModal' export const PayProjectModal: React.FC = () => { const { diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/EditRewardBeneficiary.test.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/EditRewardBeneficiary.test.tsx similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/EditRewardBeneficiary.test.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/EditRewardBeneficiary.test.tsx diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/EditRewardBeneficiary.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/EditRewardBeneficiary.tsx similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/EditRewardBeneficiary.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/EditRewardBeneficiary.tsx diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/MessageInput.test.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/MessageInput.test.tsx similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/MessageInput.test.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/MessageInput.test.tsx diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/MessageInput.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/MessageInput.tsx similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/MessageInput.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/MessageInput.tsx diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/MessageSection.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/MessageSection.tsx similarity index 93% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/MessageSection.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/MessageSection.tsx index 0255ebcff1..e0fd91d638 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/MessageSection.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/MessageSection.tsx @@ -5,7 +5,7 @@ import { useFormikContext } from 'formik' import { PayProjectModalFormValues, usePayProjectModal, -} from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectModal' +} from '../hooks/usePayProjectModal/usePayProjectModal' import { MessageInput } from './MessageInput' export const MessageSection = () => { diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveNftItem.test.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveNftItem.test.tsx similarity index 95% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveNftItem.test.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveNftItem.test.tsx index 2fb802db38..5135522007 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveNftItem.test.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveNftItem.test.tsx @@ -9,7 +9,7 @@ jest.mock( 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useNftCartItem', ) -jest.mock('../../SmallNftSquare', () => ({ +jest.mock('components/NftRewards/SmallNftSquare', () => ({ // eslint-disable-next-line @typescript-eslint/no-explicit-any SmallNftSquare: ({ nftReward: { fileUrl } }: any) => , })) diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveNftItem.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx similarity index 82% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveNftItem.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx index 455cd72437..5209e95a42 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveNftItem.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx @@ -1,9 +1,9 @@ import { Trans } from '@lingui/macro' +import { CartItemBadge } from 'components/CartItemBadge' +import { SmallNftSquare } from 'components/NftRewards/SmallNftSquare' import { useNftCartItem } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useNftCartItem' import { twMerge } from 'tailwind-merge' -import { CartItemBadge } from '../../CartItemBadge' -import { ProjectCartNftReward } from '../../ReduxProjectCartProvider' -import { SmallNftSquare } from '../../SmallNftSquare' +import { ProjectCartNftReward } from '../../../ReduxProjectCartProvider' export const ReceiveNftItem = ({ className, diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveSection.test.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveSection.test.tsx similarity index 84% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveSection.test.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveSection.test.tsx index 8be30f5058..0a8c5f1be0 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveSection.test.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveSection.test.tsx @@ -5,16 +5,12 @@ /* eslint-disable @typescript-eslint/no-empty-function */ import { render, screen } from '@testing-library/react' import { Formik } from 'formik' -import { usePayProjectModal } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectModal' -import { useProjectPaymentTokens } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPaymentTokens' +import { usePayProjectModal } from '../hooks/usePayProjectModal/usePayProjectModal' +import { useProjectPaymentTokens } from '../hooks/useProjectPaymentTokens' import { ReceiveSection } from './ReceiveSection' -jest.mock( - 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectModal', -) -jest.mock( - 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPaymentTokens', -) +jest.mock('../hooks/usePayProjectModal/usePayProjectModal') +jest.mock('../hooks/useProjectPaymentTokens') jest.mock('./ReceiveNftItem', () => ({ ReceiveNftItem: jest.fn().mockImplementation(() =>
NFT
), diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveSection.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx similarity index 86% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveSection.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx index 7671fdb56f..fdb45559e5 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveSection.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx @@ -3,8 +3,8 @@ import { useFormikContext } from 'formik' import { PayProjectModalFormValues, usePayProjectModal, -} from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectModal' -import { useProjectPaymentTokens } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPaymentTokens' +} from '../hooks/usePayProjectModal/usePayProjectModal' +import { useProjectPaymentTokens } from '../hooks/useProjectPaymentTokens' import { EditRewardBeneficiary } from './EditRewardBeneficiary' import { ReceiveNftItem } from './ReceiveNftItem' import { ReceiveTokensItem } from './ReceiveTokensItem' diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveTokensItem.test.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.test.tsx similarity index 80% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveTokensItem.test.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.test.tsx index 242b0b652b..86f7dedb5f 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveTokensItem.test.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.test.tsx @@ -3,12 +3,10 @@ */ import { render, screen } from '@testing-library/react' -import { useProjectPaymentTokens } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPaymentTokens' +import { useProjectPaymentTokens } from '../hooks/useProjectPaymentTokens' import { ReceiveTokensItem } from './ReceiveTokensItem' -jest.mock( - 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPaymentTokens', -) +jest.mock('../hooks/useProjectPaymentTokens') describe('ReceiveTokensItem', () => { const DefaultUseProjectPaymentTokens = { diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveTokensItem.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx similarity index 91% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveTokensItem.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx index c729250791..9b986bac6d 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/ReceiveTokensItem.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx @@ -1,13 +1,13 @@ import { Trans, t } from '@lingui/macro' +import { CartItemBadge } from 'components/CartItemBadge' import { ProjectHeaderLogo } from 'components/Project/ProjectHeader/ProjectHeaderLogo' import TooltipIcon from 'components/TooltipIcon' import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' import { useProjectHasErc20Token } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectHasErc20Token' -import { useProjectPaymentTokens } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPaymentTokens' import { BUYBACK_DELEGATE_ENABLED_PROJECT_IDS } from 'packages/v2v3/constants/buybackDelegateEnabledProjectIds' import { useContext } from 'react' import { twMerge } from 'tailwind-merge' -import { CartItemBadge } from '../../CartItemBadge' +import { useProjectPaymentTokens } from '../hooks/useProjectPaymentTokens' export const ReceiveTokensItem = ({ className }: { className?: string }) => { const { projectId } = useContext(ProjectMetadataContext) diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/__snapshots__/EditRewardBeneficiary.test.tsx.snap b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/__snapshots__/EditRewardBeneficiary.test.tsx.snap similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/components/__snapshots__/EditRewardBeneficiary.test.tsx.snap rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/components/__snapshots__/EditRewardBeneficiary.test.tsx.snap diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.test.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.test.ts similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.test.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.test.ts diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.ts similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.ts diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.test.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.test.ts similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.test.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.test.ts diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.ts similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.ts diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/payProjectModalReducer.test.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/payProjectModalReducer.test.ts similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/payProjectModalReducer.test.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/payProjectModalReducer.test.ts diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/payProjectModalReducer.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/payProjectModalReducer.ts similarity index 100% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/payProjectModalReducer.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/payProjectModalReducer.ts diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectModal.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts similarity index 91% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectModal.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts index 75b9648046..21a3ede3b4 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectModal.ts +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts @@ -3,18 +3,21 @@ import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' import { useWallet } from 'hooks/Wallet' import { useCurrencyConverter } from 'hooks/useCurrencyConverter' import { TxStatus } from 'models/transaction' +import { useProjectPageQueries } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPageQueries' import { - V2V3_CURRENCY_ETH, - V2V3_CURRENCY_USD, + useProjectDispatch, + useProjectSelector, +} from 'packages/v2v3/components/V2V3Project/ProjectDashboard/redux/hooks' +import { projectCartActions } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/redux/projectCartSlice' +import { + V2V3_CURRENCY_ETH, + V2V3_CURRENCY_USD, } from 'packages/v2v3/utils/currency' import { formatCurrencyAmount } from 'packages/v2v3/utils/formatCurrencyAmount' import { useCallback, useContext, useMemo, useReducer } from 'react' import { fromWad, parseWad } from 'utils/format/formatNumber' import { emitErrorNotification } from 'utils/notifications' import * as Yup from 'yup' -import { useProjectDispatch, useProjectSelector } from '../../redux/hooks' -import { projectCartActions } from '../../redux/projectCartSlice' -import { useProjectPageQueries } from '../useProjectPageQueries' import { payProjectModalReducer } from './payProjectModalReducer' import { usePayProjectTx } from './usePayProjectTx' diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectTx.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts similarity index 95% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectTx.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts index 9ad08d5eb2..f40a154bb2 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePayProjectTx.ts +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts @@ -2,6 +2,8 @@ import { Transaction } from 'ethers' import { FormikHelpers } from 'formik' import { useWallet } from 'hooks/Wallet' import { useCurrencyConverter } from 'hooks/useCurrencyConverter' +import { ProjectPayReceipt } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPageQueries' +import { useProjectSelector } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/redux/hooks' import { NftRewardsContext } from 'packages/v2v3/contexts/NftRewards/NftRewardsContext' import { usePayETHPaymentTerminalTx } from 'packages/v2v3/hooks/transactor/usePayETHPaymentTerminalTx' import { useProjectHasErc20 } from 'packages/v2v3/hooks/useProjectHasErc20' @@ -9,8 +11,6 @@ import { V2V3_CURRENCY_ETH } from 'packages/v2v3/utils/currency' import { useCallback, useContext, useMemo } from 'react' import { buildPaymentMemo } from 'utils/buildPaymentMemo' import { parseWad } from 'utils/format/formatNumber' -import { useProjectSelector } from '../../redux/hooks' -import { ProjectPayReceipt } from '../useProjectPageQueries' import { useProjectPaymentTokens } from '../useProjectPaymentTokens' import { PayProjectModalFormValues } from './usePayProjectModal' import { usePrepareDelegatePayMetadata } from './usePrepareDelegatePayMetadata' diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePrepareDelegatePayMetadata.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePrepareDelegatePayMetadata.ts similarity index 95% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePrepareDelegatePayMetadata.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePrepareDelegatePayMetadata.ts index 56d5d4e7e1..c6d89354cb 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectModal/usePrepareDelegatePayMetadata.ts +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePrepareDelegatePayMetadata.ts @@ -2,14 +2,14 @@ import { useUniswapPriceQuery } from 'components/AMMPrices/hooks/useERC20Uniswap import { DEFAULT_ALLOW_OVERSPENDING } from 'constants/transactionDefaults' import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' import { BigNumber } from 'ethers' +import { ProjectCartNftReward } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/components/ReduxProjectCartProvider' +import { useProjectContext } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectContext' import { BUYBACK_DELEGATE_ENABLED_PROJECT_IDS } from 'packages/v2v3/constants/buybackDelegateEnabledProjectIds' import { JB721DelegateContractsContext } from 'packages/v2v3/contexts/NftRewards/JB721DelegateContracts/JB721DelegateContractsContext' import { MAX_RESERVED_RATE } from 'packages/v2v3/utils/math' import { useCallback, useContext } from 'react' import { encodeDelegatePayMetadata } from 'utils/delegateMetadata/encodeDelegateMetadata' import { parseWad, stripCommas } from 'utils/format/formatNumber' -import { ProjectCartNftReward } from '../../components/ReduxProjectCartProvider' -import { useProjectContext } from '../useProjectContext' function usePrepareJbBuybackDelegatePayMetadata({ weiAmount, diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPaymentTokens.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useProjectPaymentTokens.ts similarity index 82% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPaymentTokens.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useProjectPaymentTokens.ts index 8698ab1043..62f76dd00c 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPaymentTokens.ts +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/hooks/useProjectPaymentTokens.ts @@ -1,5 +1,5 @@ import { useTokensPerEth } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useTokensPerEth' -import { useProjectSelector } from '../redux/hooks' +import { useProjectSelector } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/redux/hooks' export const useProjectPaymentTokens = () => { const payAmount = useProjectSelector(state => state.projectCart.payAmount) diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayRedeemCard.tsx similarity index 95% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard.tsx rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayRedeemCard.tsx index 09557026ec..0875bca9b7 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayRedeemCard.tsx @@ -1,15 +1,17 @@ import { - ArrowDownIcon, - CheckCircleIcon, - InformationCircleIcon, - MinusIcon, - PlusIcon, - TrashIcon, + ArrowDownIcon, + CheckCircleIcon, + InformationCircleIcon, + MinusIcon, + PlusIcon, + TrashIcon, } from '@heroicons/react/24/outline' import { Trans, t } from '@lingui/macro' import { Button, Tooltip } from 'antd' import { Callout } from 'components/Callout/Callout' +import { CartItemBadge } from 'components/CartItemBadge' import Loading from 'components/Loading' +import { SmallNftSquare } from 'components/NftRewards/SmallNftSquare' import { TruncatedText } from 'components/TruncatedText' import { EthereumIcon } from 'components/icons/Ethereum' import { JuiceModal, JuiceModalProps } from 'components/modals/JuiceModal' @@ -24,8 +26,8 @@ import { useETHReceivedFromTokens } from 'packages/v2v3/hooks/contractReader/use import { useRedeemTokensTx } from 'packages/v2v3/hooks/transactor/useRedeemTokensTx' import { usePayProjectDisabled } from 'packages/v2v3/hooks/usePayProjectDisabled' import { - V2V3_CURRENCY_ETH, - V2V3_CURRENCY_USD, + V2V3_CURRENCY_ETH, + V2V3_CURRENCY_USD, } from 'packages/v2v3/utils/currency' import { formatCurrencyAmount } from 'packages/v2v3/utils/formatCurrencyAmount' import { isInfiniteDistributionLimit } from 'packages/v2v3/utils/fundingCycle' @@ -35,27 +37,25 @@ import { twMerge } from 'tailwind-merge' import { formatAmount } from 'utils/format/formatAmount' import { fromWad, parseWad } from 'utils/format/formatNumber' import { emitErrorNotification } from 'utils/notifications' -import { NftCreditsCallout } from '../../NftCreditsCallout' -import { useNftCartItem } from '../hooks/useNftCartItem' -import { useProjectContext } from '../hooks/useProjectContext' -import { useProjectHasErc20Token } from '../hooks/useProjectHasErc20Token' -import { useProjectPageQueries } from '../hooks/useProjectPageQueries' -import { useTokensPanel } from '../hooks/useTokensPanel' -import { useTokensPerEth } from '../hooks/useTokensPerEth' -import { useUnclaimedTokenBalance } from '../hooks/useUnclaimedTokenBalance' +import { NftCreditsCallout } from '../../../NftCreditsCallout' +import { useNftCartItem } from '../../hooks/useNftCartItem' +import { useProjectContext } from '../../hooks/useProjectContext' +import { useProjectHasErc20Token } from '../../hooks/useProjectHasErc20Token' +import { useProjectPageQueries } from '../../hooks/useProjectPageQueries' +import { useTokensPanel } from '../../hooks/useTokensPanel' +import { useTokensPerEth } from '../../hooks/useTokensPerEth' +import { useUnclaimedTokenBalance } from '../../hooks/useUnclaimedTokenBalance' import { - useProjectDispatch, - useProjectSelector, - useProjectStore, -} from '../redux/hooks' -import { payRedeemActions } from '../redux/payRedeemSlice' -import { projectCartActions } from '../redux/projectCartSlice' -import { CartItemBadge } from './CartItemBadge' -import { ClaimErc20Callout } from './ClaimErc20Callout' -import { EthPerTokenAccordion } from './EthPerTokenAccordion' + useProjectDispatch, + useProjectSelector, + useProjectStore, +} from '../../redux/hooks' +import { payRedeemActions } from '../../redux/payRedeemSlice' +import { projectCartActions } from '../../redux/projectCartSlice' +import { ClaimErc20Callout } from '../ClaimErc20Callout' +import { EthPerTokenAccordion } from '../EthPerTokenAccordion' +import { ProjectCartNftReward } from '../ReduxProjectCartProvider' import { PayProjectModal } from './PayProjectModal/PayProjectModal' -import { ProjectCartNftReward } from './ReduxProjectCartProvider' -import { SmallNftSquare } from './SmallNftSquare' const MAX_AMOUNT = BigInt(Number.MAX_SAFE_INTEGER) @@ -133,7 +133,8 @@ export const PayRedeemCard: React.FC = ({ className }) => { return t`Project isn't currently issuing tokens` }, [payerIssuanceRate, hasNfts, hasNftsLoading]) - const redeemDisabled = project.fundingCycleMetadata?.redemptionRate.eq(0) || + const redeemDisabled = + project.fundingCycleMetadata?.redemptionRate.eq(0) || isInfiniteDistributionLimit(project.distributionLimit) return ( @@ -184,7 +185,7 @@ export const PayRedeemCard: React.FC = ({ className }) => { {!payerIssuanceRate.enabled && !payerIssuanceRate.loading && ( } > diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx index b86fd29034..c9fe09d78c 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx @@ -5,11 +5,11 @@ import { SubscribeButton } from 'components/buttons/SubscribeButton/SubscribeBut import confettiAnimationJuicebox from 'data/lottie/confetti-animation-juicebox.json' import dynamic from 'next/dynamic' import Link from 'next/link' -import { useSuccessPayView } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useSuccessPayView' import { v2v3ProjectRoute } from 'utils/routes' import { SuccessNftItem } from './components/SuccessNftItem' import { SuccessPayCard } from './components/SuccessPayCard' import { SuccessTokensItem } from './components/SuccessTokensItem' +import { useSuccessPayView } from './hooks/useSuccessPayView' const Lottie = dynamic(() => import('lottie-react'), { ssr: false }) export const SuccessPayView = () => { diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx index 09e29eaa52..721976a3b4 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx @@ -1,9 +1,9 @@ import { Trans } from '@lingui/macro' +import { CartItemBadge } from 'components/CartItemBadge' import { NftPreview } from 'components/NftRewards/NftPreview' +import { SmallNftSquare } from 'components/NftRewards/SmallNftSquare' import { NftRewardsContext } from 'packages/v2v3/contexts/NftRewards/NftRewardsContext' import { useContext, useMemo, useState } from 'react' -import { CartItemBadge } from '../../CartItemBadge' -import { SmallNftSquare } from '../../SmallNftSquare' export const SuccessNftItem = ({ id }: { id: number }) => { const { diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx index ee3caaca05..4c5b987bb8 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx @@ -1,7 +1,7 @@ import { Trans } from '@lingui/macro' +import { CartItemBadge } from 'components/CartItemBadge' import { ProjectHeaderLogo } from 'components/Project/ProjectHeader/ProjectHeaderLogo' import { useProjectPageQueries } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPageQueries' -import { CartItemBadge } from '../../CartItemBadge' export const SuccessTokensItem = () => { const { projectPayReceipt } = useProjectPageQueries() diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useSuccessPayView.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/hooks/useSuccessPayView.ts similarity index 93% rename from src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useSuccessPayView.ts rename to src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/hooks/useSuccessPayView.ts index 6c3f48cdfb..f02caf289c 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useSuccessPayView.ts +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/SuccessPayView/hooks/useSuccessPayView.ts @@ -1,7 +1,7 @@ import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' import { V2V3ProjectContext } from 'packages/v2v3/contexts/Project/V2V3ProjectContext' import { useContext, useEffect, useState } from 'react' -import { useProjectPageQueries } from './useProjectPageQueries' +import { useProjectPageQueries } from '../../../hooks/useProjectPageQueries' export const useSuccessPayView = () => { const { projectMetadata, projectId } = useProjectMetadataContext() diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectCard.ts b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectCard.ts deleted file mode 100644 index 24fae190c8..0000000000 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/usePayProjectCard.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { FormikHelpers } from 'formik' -import { V2V3CurrencyOption } from 'packages/v2v3/models/currencyOption' -import { - V2V3_CURRENCY_ETH, - V2V3_CURRENCY_USD, -} from 'packages/v2v3/utils/currency' -import { useCallback } from 'react' -import * as Yup from 'yup' -import { useProjectDispatch } from '../redux/hooks' -import { projectCartActions } from '../redux/projectCartSlice' -import { useProjectContext } from './useProjectContext' - -const PayProjectCardSchema = Yup.object().shape({ - payAmount: Yup.object() - .shape({ - amount: Yup.number() - .typeError('Amount is invalid') - .required('Amount is required'), - currency: Yup.number() - .oneOf([V2V3_CURRENCY_ETH, V2V3_CURRENCY_USD] as const) - .required(), - }) - .required(), -}) -type PayProjectCardValues = Yup.InferType - -export const usePayProjectCard = () => { - const { fundingCycleMetadata } = useProjectContext() - const dispatch = useProjectDispatch() - const addPay = useCallback( - ( - values: PayProjectCardValues, - formikHelpers: FormikHelpers, - ) => { - dispatch( - projectCartActions.addPayment({ - amount: Number(values.payAmount.amount), - currency: values.payAmount.currency, - }), - ) - formikHelpers.resetForm({ - values: { - payAmount: { - amount: undefined as unknown as number, - currency: values.payAmount.currency, - }, - }, - }) - }, - [dispatch], - ) - - return { - addPay, - validationSchema: PayProjectCardSchema, - paymentsPaused: fundingCycleMetadata?.pausePay, - } -} diff --git a/src/packages/v4/components/PayoutsTable/ConvertAmountsModal.tsx b/src/packages/v4/components/PayoutsTable/ConvertAmountsModal.tsx index e7ed6b0a6a..f2247cff25 100644 --- a/src/packages/v4/components/PayoutsTable/ConvertAmountsModal.tsx +++ b/src/packages/v4/components/PayoutsTable/ConvertAmountsModal.tsx @@ -6,7 +6,6 @@ import { ExternalLinkWithIcon } from 'components/ExternalLinkWithIcon' import FormattedNumberInput from 'components/inputs/FormattedNumberInput' import { Parenthesis } from 'components/Parenthesis' import { JBSplit as Split, SPLITS_TOTAL_PERCENT } from 'juice-sdk-core' -import { useRouter } from 'next/router' import { V4CurrencyOption } from 'packages/v4/models/v4CurrencyOption' import { V4_CURRENCY_ETH, V4_CURRENCY_USD } from 'packages/v4/utils/currency' @@ -44,9 +43,6 @@ export const ConvertAmountsModal = ({ distributionLimit?.currency ?? V4_CURRENCY_ETH, ) - const router = useRouter() - const { chainName } = router.query - const totalPayoutsPercent = useMemo( () => splits @@ -143,7 +139,6 @@ export const ConvertAmountsModal = ({ {isJuiceboxProjectSplit(split) && allocation.projectId ? ( ) : ( diff --git a/src/packages/v4/components/PayoutsTable/PayoutTitle.tsx b/src/packages/v4/components/PayoutsTable/PayoutTitle.tsx index 1c27df60b2..522b7f86aa 100644 --- a/src/packages/v4/components/PayoutsTable/PayoutTitle.tsx +++ b/src/packages/v4/components/PayoutsTable/PayoutTitle.tsx @@ -3,15 +3,11 @@ import { t } from '@lingui/macro' import { Tooltip } from 'antd' import EthereumAddress from 'components/EthereumAddress' import { JBSplit as Split } from 'juice-sdk-core' -import { useRouter } from 'next/router' import { formatDate } from 'utils/format/formatDate' import V4ProjectHandleLink from '../V4ProjectHandleLink' import { usePayoutsTableContext } from './context/PayoutsTableContext' export function PayoutTitle({ payoutSplit }: { payoutSplit: Split }) { - const router = useRouter() - const { chainName } = router.query - const { showAvatars } = usePayoutsTableContext() const isProject = @@ -23,7 +19,6 @@ export function PayoutTitle({ payoutSplit }: { payoutSplit: Split }) { ) : ( { + const { rewardTiers } = useContext(NftRewardsContext).nftRewards + + const { userAddress } = useWallet() + const userNftCredits = useNftCredits(userAddress) + + const dispatch = useProjectDispatch() + + // Set the nfts on load + useEffect(() => { + dispatch(projectCartActions.setAllNftRewards(rewardTiers ?? [])) + }, [dispatch, rewardTiers]) + + // Set the user's NFT credits on load + useEffect(() => { + dispatch( + projectCartActions.setUserNftCredits( + userNftCredits.data?.toBigInt() ?? 0n, + ), + ) + }, [dispatch, userNftCredits.data]) + + return <>{children} +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/EthereumLogo.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/EthereumLogo.tsx new file mode 100644 index 0000000000..ca2c979f14 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/EthereumLogo.tsx @@ -0,0 +1,9 @@ +import { EthereumIcon } from 'components/icons/Ethereum' + +export const EthereumLogo = () => { + return ( +
+ +
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/NftReward.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/NftReward.tsx new file mode 100644 index 0000000000..ac0f817e24 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/NftReward.tsx @@ -0,0 +1,93 @@ +// const NftReward: React.FC<{ +// nft: ProjectCartNftReward +// className?: string +// }> = ({ nft, className }) => { +// const { +// price, +// name, +// quantity, +// fileUrl, +// removeNft, +// increaseQuantity, +// decreaseQuantity, +// } = useNftCartItem(nft) + +// const handleRemove = useCallback(() => { +// emitConfirmationDeletionModal({ +// onConfirm: removeNft, +// title: t`Remove NFT`, +// description: t`Are you sure you want to remove this NFT?`, +// }) +// }, [removeNft]) + +// const handleDecreaseQuantity = useCallback(() => { +// if (quantity - 1 <= 0) { +// handleRemove() +// } else { +// decreaseQuantity() +// } +// }, [decreaseQuantity, handleRemove, quantity]) + +// const priceText = price === null ? '-' : formatCurrencyAmount(price) + +// return ( +//
+//
+// +//
+//
+// +// NFT +//
+ +//
{priceText}
+//
+//
+ +//
+// +// +//
+//
+// ) +// } + +// const RemoveIcon: React.FC<{ onClick: () => void }> = ({ onClick }) => ( +// +// ) + +// const QuantityControl: React.FC<{ +// quantity: number +// onIncrease: () => void +// onDecrease: () => void +// }> = ({ quantity, onIncrease, onDecrease }) => { +// return ( +// +// +// {quantity} +// +// +// ) +// } diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayConfiguration.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayConfiguration.tsx new file mode 100644 index 0000000000..43207628f2 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayConfiguration.tsx @@ -0,0 +1,176 @@ +import { t, Trans } from '@lingui/macro' +import { Button, Tooltip } from 'antd' +import { PV_V2 } from 'constants/pv' +import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' +import { useProjectLogoSrc } from 'hooks/useProjectLogoSrc' +import { useWallet } from 'hooks/Wallet' +import { useJBTokenContext } from 'juice-sdk-react' +import { usePayProjectDisabled } from 'packages/v2v3/hooks/usePayProjectDisabled' +import { V4_CURRENCY_ETH } from 'packages/v4/utils/currency' +import { useCallback, useEffect, useMemo, useState } from 'react' +import { + useProjectDispatch, + useProjectSelector, + useProjectStore, +} from '../redux/hooks' +import { projectCartActions } from '../redux/projectCartSlice' +import { EthereumLogo } from './EthereumLogo' +import { useProjectPaymentTokens } from './PayProjectModal/hooks/useProjectPaymentTokens' +import { PayRedeemInput } from './PayRedeemInput' + +type PayConfigurationProps = { + userTokenBalance: number | undefined + projectHasErc20Token: boolean + isIssuingTokens: boolean +} + +export const PayConfiguration: React.FC = ({ + userTokenBalance, + projectHasErc20Token, + isIssuingTokens, +}) => { + const { payDisabled, message } = usePayProjectDisabled() + const { token } = useJBTokenContext() + const wallet = useWallet() + const { isConnected: walletConnected, connect } = useWallet() + const { projectId, projectMetadata } = useProjectMetadataContext() + const tokenReceivedAmount = useProjectPaymentTokens() + const chosenNftRewards = useProjectSelector( + state => state.projectCart.chosenNftRewards, + ) + const cartPayAmount = useProjectSelector( + state => state.projectCart.payAmount?.amount, + ) + const dispatch = useProjectDispatch() + const store = useProjectStore() + + const tokenLogo = useProjectLogoSrc({ + projectId, + pv: PV_V2, + uri: projectMetadata?.logoUri, + }) + + const [payAmount, setPayAmount] = useState() + const [fallbackImage, setFallbackImage] = useState() + + const tokenBSymbol = token?.data?.symbol // the token the user receives (the project token) + + const amount = cartPayAmount ?? 0 + const insufficientBalance = !wallet.balance + ? false + : amount > parseFloat(wallet.balance) + const tokenBTicker = tokenBSymbol || 'TOKENS' + + const handleUserPayAmountChange = useCallback( + (value: string | undefined) => { + const parsedValue = parseFloat(value || '0') + dispatch( + projectCartActions.addPayment({ + amount: !Number.isNaN(parsedValue) ? parsedValue : 0, + currency: V4_CURRENCY_ETH, + }), + ) + setPayAmount(value) + }, + [dispatch], + ) + + const payProject = useCallback(() => { + if (!walletConnected) { + connect() + return + } + dispatch(projectCartActions.openPayModal()) + }, [connect, dispatch, walletConnected]) + + // Update the pay amount input from the cart + useEffect(() => { + const unsubscribe = store.subscribe(() => { + const state = store.getState() + const payAmount = state.projectCart.payAmount?.amount + setPayAmount(payAmount?.toString() ?? '') + }) + return () => { + unsubscribe() + } + }, [store]) + + const payButtonDisabled = useMemo(() => { + if (!walletConnected) return false + return ( + insufficientBalance || + cartPayAmount === 0 || + !cartPayAmount || + payDisabled + ) + }, [cartPayAmount, insufficientBalance, payDisabled, walletConnected]) + + return ( +
+
+
+ , + ticker: 'ETH', + type: 'eth', + }} + value={payAmount ?? cartPayAmount?.toString()} + onChange={handleUserPayAmountChange} + /> + setFallbackImage(true)} + /> + ) : ( + '🧃' + ), + ticker: tokenBTicker, + type: projectHasErc20Token ? 'erc20' : 'native', + }} + nfts={chosenNftRewards} + value={ + tokenReceivedAmount.receivedTickets && + !!parseFloat(tokenReceivedAmount.receivedTickets) + ? tokenReceivedAmount.receivedTickets + : '' + } + /> +
+
+ + + + +
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/PayProjectModal.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/PayProjectModal.tsx new file mode 100644 index 0000000000..40725f1c79 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/PayProjectModal.tsx @@ -0,0 +1,174 @@ +import { Trans, t } from '@lingui/macro' +import EtherscanLink from 'components/EtherscanLink' +import ExternalLink from 'components/ExternalLink' +import { JuiceModal } from 'components/modals/JuiceModal' +import { Formik } from 'formik' +import Image from 'next/image' +import { twMerge } from 'tailwind-merge' +import { helpPagePath } from 'utils/routes' +import { MessageSection } from './components/MessageSection' +import { ReceiveSection } from './components/ReceiveSection' +import { + PayProjectModalFormValues, + usePayProjectModal, +} from './hooks/usePayProjectModal/usePayProjectModal' + +export const PayProjectModal: React.FC = () => { + const { + open, + primaryAmount, + secondaryAmount, + validationSchema, + isTransactionPending, + isTransactionConfirmed, + projectPayDisclosure, + pendingTransactionHash, + projectName, + setOpen, + onPaySubmit, + } = usePayProjectModal() + + return ( + + initialValues={{ + message: { + messageString: '', + attachedUrl: undefined, + }, + userAcceptsTerms: false, + beneficiaryAddress: undefined, + }} + validationSchema={validationSchema} + onSubmit={onPaySubmit} + > + {props => ( +
+ { + setOpen(false) + // Small timeout to allow the modal to close before resetting the form + setTimeout(() => props.resetForm(), 300) + }} + > + {isTransactionPending ? ( +
+ {t`Juicebox +

+ Transaction pending... +

+

+ + Your transaction has been submitted and is awaiting + confirmation. + +

+ {pendingTransactionHash ? ( +

+ + View on Etherscan + +

+ ) : null} +
+ ) : ( + <> +
+
+ + Total amount + +
+ {primaryAmount}{' '} + {secondaryAmount && ( + + ({secondaryAmount}) + + )} +
+
+ + + +
+ + +
+ + props.setFieldValue( + 'userAcceptsTerms', + !props.values.userAcceptsTerms, + ) + } + /> + +
+
+
+ + )} +
+
+ )} + + ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/EditRewardBeneficiary.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/EditRewardBeneficiary.tsx new file mode 100644 index 0000000000..f252b6ec2c --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/EditRewardBeneficiary.tsx @@ -0,0 +1,95 @@ +import { XCircleIcon } from '@heroicons/react/24/outline' +import { PencilSquareIcon } from '@heroicons/react/24/solid' +import { Trans } from '@lingui/macro' +import { Tooltip } from 'antd' +import EthereumAddress from 'components/EthereumAddress' +import Loading from 'components/Loading' +import { useEffect, useRef } from 'react' +import { twMerge } from 'tailwind-merge' +import { useEditRewardBeneficiary } from '../hooks/useEditRewardBeneficiary/useEditRewardBeneficiary' + +export const EditRewardBeneficiary = ({ + className, + value, + onChange, +}: { + className?: string + value?: string + onChange?: (value: string) => void +}) => { + const { + address, + isEditing, + isLoading, + error, + editClicked, + handleInputChanged, + handleInputBlur, + } = useEditRewardBeneficiary(value, onChange) + + const inputRef = useRef(null) + + useEffect(() => { + if (isLoading || !isEditing) return + inputRef.current?.focus() + }, [isEditing, isLoading]) + + return ( +
+ {isEditing ? ( + + + {isLoading ? ( + + ) : ( + error && ( + + + + ) + )} + + ) : ( + <> + + + {address ? ( + + ) : ( + Owner wallet + )} + + + + + )} +
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/MessageInput.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/MessageInput.tsx new file mode 100644 index 0000000000..8c6c481744 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/MessageInput.tsx @@ -0,0 +1,134 @@ +import { PhotoIcon, XCircleIcon } from '@heroicons/react/24/outline' +import { Trans, t } from '@lingui/macro' +import { Tooltip } from 'antd' +import ExternalLink from 'components/ExternalLink' +import { JuiceVideoThumbnailOrImage } from 'components/JuiceVideo/JuiceVideoThumbnailOrImage' +import { useIpfsFilePicker } from 'hooks/useIpfsFilePicker/useIpfsFilePicker' +import { twMerge } from 'tailwind-merge' + +type PayProjectModalMessageInputValue = { + messageString?: string | undefined + attachedUrl?: string | undefined +} + +type Props = Omit< + React.DetailedHTMLProps< + React.InputHTMLAttributes, + HTMLInputElement + >, + 'value' | 'onChange' +> & { + value: PayProjectModalMessageInputValue + onChange: (value: PayProjectModalMessageInputValue) => void +} + +export const MessageInput: React.FC = ({ + className, + value, + onChange, + ...props +}) => { + const acceptedFileTypes = + 'image/jpeg,image/png,image/webp,image/gif,video/mp4,video/quicktime,video/x-m4v,video/webm' + const { + uploadedUrl, + isUploading, + selectedFile, + uploadProgress, + FileInput, + openFilePicker, + cancelUpload, + removeFile, + } = useIpfsFilePicker({ + accept: acceptedFileTypes, + onFileUrlChange: url => onChange({ ...value, attachedUrl: url }), + }) + + return ( +
+
+ + onChange({ ...value, messageString: e.currentTarget.value }) + } + /> + + + +
+ {isUploading ? ( +
+
+
+
+
+
+
+ +
+
+ ) : ( + uploadedUrl && + selectedFile && ( +
+ + + + + Uploaded to: + + +
+ ) + )} +
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/MessageSection.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/MessageSection.tsx new file mode 100644 index 0000000000..e0fd91d638 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/MessageSection.tsx @@ -0,0 +1,46 @@ +import { EnvelopeIcon } from '@heroicons/react/24/outline' +import { Trans } from '@lingui/macro' +import { Callout } from 'components/Callout/Callout' +import { useFormikContext } from 'formik' +import { + PayProjectModalFormValues, + usePayProjectModal, +} from '../hooks/usePayProjectModal/usePayProjectModal' +import { MessageInput } from './MessageInput' + +export const MessageSection = () => { + const { projectName, projectPayDisclosure } = usePayProjectModal() + const { values, setFieldValue, handleBlur } = + useFormikContext() + return ( +
+ + Message (optional) + +
+ setFieldValue('message', v)} + onBlur={handleBlur} + /> +
+ {projectName && projectPayDisclosure && ( + } + > + <> +
+ Notice from {projectName} +
+

{projectPayDisclosure}

+ +
+ )} +
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx new file mode 100644 index 0000000000..5209e95a42 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx @@ -0,0 +1,37 @@ +import { Trans } from '@lingui/macro' +import { CartItemBadge } from 'components/CartItemBadge' +import { SmallNftSquare } from 'components/NftRewards/SmallNftSquare' +import { useNftCartItem } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useNftCartItem' +import { twMerge } from 'tailwind-merge' +import { ProjectCartNftReward } from '../../../ReduxProjectCartProvider' + +export const ReceiveNftItem = ({ + className, + nftReward, +}: { + className?: string + nftReward: ProjectCartNftReward +}) => { + const { fileUrl, name, quantity } = useNftCartItem(nftReward) + + return ( +
+
+
+ + {name} + + NFT + +
+
{quantity}
+
+
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx new file mode 100644 index 0000000000..fdb45559e5 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx @@ -0,0 +1,49 @@ +import { Trans } from '@lingui/macro' +import { useFormikContext } from 'formik' +import { + PayProjectModalFormValues, + usePayProjectModal, +} from '../hooks/usePayProjectModal/usePayProjectModal' +import { useProjectPaymentTokens } from '../hooks/useProjectPaymentTokens' +import { EditRewardBeneficiary } from './EditRewardBeneficiary' +import { ReceiveNftItem } from './ReceiveNftItem' +import { ReceiveTokensItem } from './ReceiveTokensItem' + +export const ReceiveSection = ({ className }: { className?: string }) => { + const { nftRewards } = usePayProjectModal() + const { receivedTickets } = useProjectPaymentTokens() + const { values, setFieldValue } = + useFormikContext() + + if (nftRewards.length === 0 && receivedTickets === '0') { + return null + } + + return ( +
+ + Receive + +
+ + + NFTs, tokens and rewards will be sent to{' '} + setFieldValue('beneficiaryAddress', address)} + /> + + +
+ + {nftRewards.map(nftReward => ( + + ))} +
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx new file mode 100644 index 0000000000..9b986bac6d --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx @@ -0,0 +1,55 @@ +import { Trans, t } from '@lingui/macro' +import { CartItemBadge } from 'components/CartItemBadge' +import { ProjectHeaderLogo } from 'components/Project/ProjectHeader/ProjectHeaderLogo' +import TooltipIcon from 'components/TooltipIcon' +import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' +import { useProjectHasErc20Token } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectHasErc20Token' +import { BUYBACK_DELEGATE_ENABLED_PROJECT_IDS } from 'packages/v2v3/constants/buybackDelegateEnabledProjectIds' +import { useContext } from 'react' +import { twMerge } from 'tailwind-merge' +import { useProjectPaymentTokens } from '../hooks/useProjectPaymentTokens' + +export const ReceiveTokensItem = ({ className }: { className?: string }) => { + const { projectId } = useContext(ProjectMetadataContext) + const { receivedTickets, receivedTokenSymbolText } = useProjectPaymentTokens() + const projectHasErc20Token = useProjectHasErc20Token() + + const badgeTitle = projectHasErc20Token ? ( + 'ERC-20' + ) : ( + Juicebox Native + ) + + if (receivedTickets === '0') { + return null + } + + const buybackDelegateEnabled = + projectId && BUYBACK_DELEGATE_ENABLED_PROJECT_IDS.includes(projectId) + + return ( +
+
+
+ + + {receivedTokenSymbolText} Token + + + {badgeTitle} Token + +
+ {buybackDelegateEnabled ? ( +
+ ≥ {receivedTickets}{' '} + +
+ ) : ( +
{receivedTickets}
+ )} +
+
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.ts b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.ts new file mode 100644 index 0000000000..71efa9cbac --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/editRewardBeneficiaryReducer.ts @@ -0,0 +1,69 @@ +type EditRewardBeneficiaryReducerState = { + isEditing: boolean + isLoading: boolean + address?: string + error?: string +} + +type EditRewardBeneficiaryReducerAction = + | { + type: 'edit' + } + | { + type: 'cancel' + } + | { + type: 'loading' + } + | { + type: 'save' + address: string | undefined + } + | { + type: 'error' + error: string + } + +export const editRewardBeneficiaryReducer = ( + state: EditRewardBeneficiaryReducerState, + action: EditRewardBeneficiaryReducerAction, +): EditRewardBeneficiaryReducerState => { + switch (action.type) { + case 'edit': + return { + ...state, + isEditing: true, + isLoading: false, + error: undefined, + } + case 'cancel': + return { + ...state, + isEditing: false, + isLoading: false, + error: undefined, + } + case 'save': + return { + ...state, + isEditing: false, + isLoading: false, + error: undefined, + address: action.address, + } + case 'loading': + return { + ...state, + isLoading: true, + error: undefined, + } + case 'error': + return { + ...state, + error: action.error, + isLoading: false, + } + default: + return state + } +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.ts b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.ts new file mode 100644 index 0000000000..8d0dd8ca20 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useEditRewardBeneficiary/useEditRewardBeneficiary.ts @@ -0,0 +1,70 @@ +import { isAddress } from 'ethers/lib/utils' +import { useWallet } from 'hooks/Wallet' +import { resolveAddress } from 'lib/api/ens' +import { useCallback, useReducer } from 'react' +import { editRewardBeneficiaryReducer } from './editRewardBeneficiaryReducer' + +const isENS = (address = '') => address.endsWith('.eth') + +export const useEditRewardBeneficiary = ( + _value: string | undefined, + onChange: ((value: string) => void) | undefined, +) => { + const { userAddress } = useWallet() + const address = _value || userAddress + + const [state, dispatch] = useReducer(editRewardBeneficiaryReducer, { + isEditing: false, + isLoading: false, + address, + }) + + const handleFinishedEditing = useCallback( + (newAddress: string) => { + dispatch({ type: 'save', address: newAddress }) + onChange?.(newAddress) + }, + [onChange], + ) + + const editClicked = useCallback(() => { + dispatch({ type: 'edit' }) + }, []) + + const handleInputChanged: React.ChangeEventHandler = + useCallback( + async e => { + dispatch({ type: 'edit' }) + const value = e.target.value + if (isENS(value)) { + dispatch({ type: 'loading' }) + try { + const { address: addressForEnsName } = await resolveAddress(value) + if (addressForEnsName) { + return handleFinishedEditing(addressForEnsName) + } + dispatch({ type: 'error', error: 'No address found for ENS name' }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (e: any) { + console.error(e) + dispatch({ type: 'error', error: e.message }) + } + } + if (isAddress(value)) { + return handleFinishedEditing(value) + } + }, + [handleFinishedEditing], + ) + + const handleInputBlur = useCallback(() => { + dispatch({ type: 'cancel' }) + }, []) + + return { + ...state, + editClicked, + handleInputChanged, + handleInputBlur, + } +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/payProjectModalReducer.ts b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/payProjectModalReducer.ts new file mode 100644 index 0000000000..ae543a24d5 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/payProjectModalReducer.ts @@ -0,0 +1,48 @@ +type PayProjectModalState = { + isTransactionPending: boolean + isTransactionConfirmed: boolean + transactionError: string | undefined +} +type PayProjectModalAction = + | { type: 'transactionPending' } + | { type: 'transactionConfirmed' } + | { type: 'transactionError'; error: string } + | { type: 'reset' } + +export const payProjectModalReducer = ( + state: PayProjectModalState, + action: PayProjectModalAction, +): PayProjectModalState => { + switch (action.type) { + case 'transactionPending': + return { + ...state, + isTransactionPending: true, + isTransactionConfirmed: false, + transactionError: undefined, + } + case 'transactionConfirmed': + return { + ...state, + isTransactionPending: false, + isTransactionConfirmed: true, + transactionError: undefined, + } + case 'transactionError': + return { + ...state, + isTransactionPending: false, + isTransactionConfirmed: false, + transactionError: action.error, + } + case 'reset': + return { + ...state, + isTransactionPending: false, + isTransactionConfirmed: false, + transactionError: undefined, + } + default: + return state + } +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts new file mode 100644 index 0000000000..d0ed9ee556 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts @@ -0,0 +1,142 @@ +import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' +import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' +import { useWallet } from 'hooks/Wallet' +import { useCurrencyConverter } from 'hooks/useCurrencyConverter' +import { NATIVE_TOKEN_DECIMALS } from 'juice-sdk-core' +import { TxStatus } from 'models/transaction' +import { useProjectPageQueries } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPageQueries' +import { + useProjectDispatch, + useProjectSelector, +} from 'packages/v2v3/components/V2V3Project/ProjectDashboard/redux/hooks' +import { projectCartActions } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/redux/projectCartSlice' +import { + V2V3_CURRENCY_ETH, + V2V3_CURRENCY_USD, +} from 'packages/v2v3/utils/currency' +import { formatCurrencyAmount } from 'packages/v2v3/utils/formatCurrencyAmount' +import { useCallback, useContext, useMemo, useReducer } from 'react' +import { emitErrorNotification } from 'utils/notifications' +import { formatEther, parseUnits } from 'viem' +import * as Yup from 'yup' +import { payProjectModalReducer } from './payProjectModalReducer' +import { usePayProjectTx } from './usePayProjectTx' + +const ValidationSchema = Yup.object().shape({ + message: Yup.object().shape({ + messageString: Yup.string().max(256, 'Message is too long'), + attachedUrl: Yup.string().url('Invalid URL'), + }), + userAcceptsTerms: Yup.boolean().oneOf( + [true], + 'You must accept the terms and conditions', + ), + beneficiaryAddress: Yup.string(), +}) + +const getValidationSchema = (projectHasPayNotice: boolean) => + projectHasPayNotice + ? ValidationSchema.shape({ + userAcceptsNotice: Yup.boolean().oneOf( + [true], + "You must understand and accept this project's notice.", + ), + }) + : ValidationSchema + +export type PayProjectModalFormValues = Yup.InferType + +export const usePayProjectModal = () => { + const { payModalOpen, payAmount, chosenNftRewards } = useProjectSelector( + state => state.projectCart, + ) + const dispatch = useProjectDispatch() + const { projectMetadata } = useProjectMetadataContext() + const { name, payDisclosure } = projectMetadata ?? {} + const { userAddress } = useWallet() + const converter = useCurrencyConverter() + const [modalState, modalDispatch] = useReducer(payProjectModalReducer, { + isTransactionPending: false, + isTransactionConfirmed: false, + transactionError: undefined, + }) + const { setProjectPayReceipt } = useProjectPageQueries() + const { transactions } = useContext(TxHistoryContext) + + const open = payModalOpen + const setOpen = useCallback( + (open: boolean) => { + dispatch(projectCartActions.setPayModal({ open })) + }, + [dispatch], + ) + + const onPaySubmit = usePayProjectTx({ + onTransactionPending: () => { + modalDispatch({ type: 'transactionPending' }) + }, + onTransactionConfirmed: (payReceipt, formikHelpers) => { + setProjectPayReceipt(payReceipt) + setOpen(false) + dispatch(projectCartActions.payProject()) + setTimeout(() => { + formikHelpers.setSubmitting(false) + formikHelpers.resetForm() + modalDispatch({ type: 'reset' }) + }, 300) + }, + onTransactionError: (error: Error, formikHelpers) => { + emitErrorNotification(error.message) + modalDispatch({ type: 'reset' }) + formikHelpers.setSubmitting(false) + }, + }) + + const primaryAmount = !payAmount + ? formatCurrencyAmount({ amount: 0, currency: V2V3_CURRENCY_ETH }) + : formatCurrencyAmount(payAmount) + + const secondaryAmount = useMemo(() => { + if (!payAmount || Number.isNaN(payAmount.amount)) { + return undefined + } + + if (payAmount.currency === V2V3_CURRENCY_ETH) { + const amount = Number( + converter.weiToUsd( + parseUnits(payAmount.amount.toString(), NATIVE_TOKEN_DECIMALS), + ), + ) + return formatCurrencyAmount({ + amount, + currency: V2V3_CURRENCY_USD, + }) + } + + return formatCurrencyAmount({ + amount: formatEther(converter.usdToWei(payAmount.amount).toBigInt()), + currency: V2V3_CURRENCY_ETH, + }) + }, [converter, payAmount]) + + const pendingTransactionHash = transactions?.find( + tx => tx.status === TxStatus.pending, + )?.tx?.hash + + const validationSchema = getValidationSchema(!!payDisclosure) + + return { + open, + primaryAmount, + secondaryAmount, + userAddress, + nftRewards: chosenNftRewards, + validationSchema, + projectName: name, + projectPayDisclosure: payDisclosure, + pendingTransactionHash, + ...modalState, + setOpen, + onPaySubmit, + } +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts new file mode 100644 index 0000000000..baa2aede9e --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts @@ -0,0 +1,167 @@ +import { FormikHelpers } from 'formik' +import { useWallet } from 'hooks/Wallet' +import { useCurrencyConverter } from 'hooks/useCurrencyConverter' +import { useProjectSelector } from 'packages/v4/components/ProjectDashboard/redux/hooks' +import { ProjectPayReceipt } from 'packages/v4/views/V4ProjectDashboard/hooks/useProjectPageQueries' +// import { NftRewardsContext } from 'packages/v4/contexts/NftRewards/NftRewardsContext' +// import { useProjectHasErc20 } from 'packages/v4/hooks/useProjectHasErc20' +import { waitForTransactionReceipt } from '@wagmi/core' +import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' +import { NATIVE_TOKEN } from 'juice-sdk-core' +import { + useJBContractContext, + useWriteJbMultiTerminalPay, +} from 'juice-sdk-react' +import { useProjectHasErc20 } from 'packages/v2v3/hooks/useProjectHasErc20' +import { V4_CURRENCY_ETH } from 'packages/v4/utils/currency' +import { wagmiConfig } from 'packages/v4/wagmiConfig' +import { useCallback, useContext, useMemo } from 'react' +import { buildPaymentMemo } from 'utils/buildPaymentMemo' +import { Address, Hash, parseEther } from 'viem' +import { useProjectPaymentTokens } from '../useProjectPaymentTokens' +import { PayProjectModalFormValues } from './usePayProjectModal' + +export const usePayProjectTx = ({ + onTransactionPending: onTransactionPendingCallback, + onTransactionConfirmed: onTransactionConfirmedCallback, + onTransactionError: onTransactionErrorCallback, +}: { + onTransactionPending: ( + formikHelpers: FormikHelpers, + ) => void + onTransactionConfirmed: ( + payReceipt: ProjectPayReceipt, + formikHelpers: FormikHelpers, + ) => void + onTransactionError: ( + error: Error, + formikHelpers: FormikHelpers, + ) => void +}) => { + const { userAddress } = useWallet() + const { payAmount, chosenNftRewards } = useProjectSelector( + state => state.projectCart, + ) + // const { + // nftRewards: { rewardTiers }, + // } = useContext(NftRewardsContext) + const converter = useCurrencyConverter() + const { receivedTickets } = useProjectPaymentTokens() + const projectHasErc20 = useProjectHasErc20() + + const buildPayReceipt = useCallback( + (txHash: Hash): ProjectPayReceipt => { + return { + totalAmount: payAmount ?? { + amount: 0, + currency: V4_CURRENCY_ETH, + }, + nfts: chosenNftRewards ?? [], + timestamp: new Date(), + transactionHash: txHash, + fromAddress: userAddress ?? '', + tokensReceived: receivedTickets ?? '', + } + }, + [chosenNftRewards, payAmount, receivedTickets, userAddress], + ) + + const weiAmount = useMemo(() => { + if (!payAmount) { + return 0n + } else if (payAmount.currency === V4_CURRENCY_ETH) { + return parseEther(payAmount.amount.toString()) + } else { + return converter.usdToWei(payAmount.amount).toBigInt() + } + }, [payAmount, converter]) + + // const prepareDelegateMetadata = usePrepareDelegatePayMetadata(weiAmount, { + // nftRewards: chosenNftRewards, + // receivedTickets, + // }) + + const { writeContractAsync: writePay } = useWriteJbMultiTerminalPay() + const { contracts, projectId } = useJBContractContext() + const { addTransaction } = useContext(TxHistoryContext) + + return useCallback( + async ( + values: PayProjectModalFormValues, + formikHelpers: FormikHelpers, + ) => { + if ( + !weiAmount || + !contracts.primaryNativeTerminal.data || + !userAddress || + !values.userAcceptsTerms + ) { + return + } + + const { messageString, attachedUrl } = values.message + const memo = buildPaymentMemo({ + text: messageString, + imageUrl: attachedUrl, + // nftUrls: chosenNftRewards + // .map( + // ({ id }) => + // (rewardTiers ?? []).find(({ id: tierId }) => tierId === id) + // ?.fileUrl, + // ) + // .filter((url): url is string => !!url), + }) + const beneficiary = (values.beneficiaryAddress ?? userAddress) as Address + const args = [ + projectId, + NATIVE_TOKEN, + weiAmount, + beneficiary, + 0n, + `JBM V4 ${projectId}`, // TODO update + '0x0', + ] as const + + try { + const hash = await writePay({ + address: contracts.primaryNativeTerminal.data, + args, + value: weiAmount, + }) + + onTransactionPendingCallback(formikHelpers) + addTransaction?.('Pay', { hash }) + const transactionReceipt = await waitForTransactionReceipt( + wagmiConfig, + { + hash, + }, + ) + + onTransactionConfirmedCallback(buildPayReceipt(hash), formikHelpers) + } catch (e) { + onTransactionErrorCallback( + (e as Error) ?? new Error('Transaction failed'), + formikHelpers, + ) + } + }, + [ + // projectHasErc20, + buildPayReceipt, + // chosenNftRewards, + onTransactionConfirmedCallback, + onTransactionErrorCallback, + onTransactionPendingCallback, + // payProjectTx, + // rewardTiers, + weiAmount, + userAddress, + // prepareDelegateMetadata, + projectId, + writePay, + contracts.primaryNativeTerminal.data, + addTransaction, + ], + ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useProjectPaymentTokens.ts b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useProjectPaymentTokens.ts new file mode 100644 index 0000000000..78ade4f438 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/useProjectPaymentTokens.ts @@ -0,0 +1,52 @@ +import { FixedInt } from 'fpnum' +import { getTokenAToBQuote } from 'juice-sdk-core' +import { + useJBRulesetContext, + useJBTokenContext, + useNativeTokenSymbol, +} from 'juice-sdk-react' +import { useProjectSelector } from 'packages/v4/components/ProjectDashboard/redux/hooks' +import { V4_CURRENCY_USD } from 'packages/v4/utils/currency' +import { tokenSymbolText } from 'utils/tokenSymbolText' +import { formatUnits } from 'viem' +export const useProjectPaymentTokens = () => { + const payAmount = useProjectSelector(state => state.projectCart.payAmount) + const { ruleset, rulesetMetadata } = useJBRulesetContext() + const nativeTokenSymbol = useNativeTokenSymbol() + const tokenA = { symbol: nativeTokenSymbol, decimals: 18 } + const { token } = useJBTokenContext() + + let payAmountWei = payAmount?.amount + if (payAmount?.currency === V4_CURRENCY_USD) { + // convert to wei first + } + + const amountBQuote = + ruleset.data && rulesetMetadata.data && payAmountWei + ? getTokenAToBQuote( + FixedInt.parse(payAmountWei.toString(), tokenA.decimals), + { + weight: ruleset.data.weight, + reservedPercent: rulesetMetadata.data.reservedPercent, + }, + ) + : null + + const receivedTickets = + token.data?.decimals && amountBQuote?.payerTokens + ? formatUnits(amountBQuote?.payerTokens, token.data?.decimals) + : null + const receivedTokenSymbolText = tokenSymbolText({ + tokenSymbol: token.data?.symbol, + capitalize: false, + plural: receivedTickets !== '1', + }) + + return { + receivedTickets, + receivedTokenSymbolText: + receivedTokenSymbolText === 'tokens' + ? 'Project' + : receivedTokenSymbolText, + } +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayRedeemInput.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayRedeemInput.tsx new file mode 100644 index 0000000000..e26aa7641d --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayRedeemInput.tsx @@ -0,0 +1,210 @@ +import { ArrowDownIcon } from '@heroicons/react/24/outline' +import { t } from '@lingui/macro' +import { Tooltip } from 'antd' +import { useCurrencyConverter } from 'hooks/useCurrencyConverter' +import { formatCurrencyAmount } from 'packages/v2v3/utils/formatCurrencyAmount' +import { V4_CURRENCY_USD } from 'packages/v4/utils/currency' +import { ReactNode, useMemo } from 'react' +import { twMerge } from 'tailwind-merge' +import { formatAmount } from 'utils/format/formatAmount' +import { ProjectCartNftReward } from '../ReduxProjectCartProvider' +import { EthereumLogo } from './EthereumLogo' + +const MAX_AMOUNT = BigInt(Number.MAX_SAFE_INTEGER) + +export const PayRedeemInput = ({ + className, + label, + downArrow, + readOnly, + redeemUnavailable, + token, + nfts, + value, + onChange, +}: { + className?: string + label?: React.ReactNode + downArrow?: boolean + readOnly?: boolean + redeemUnavailable?: boolean + token: { + type?: 'eth' | 'native' | 'erc20' + ticker: string + image: ReactNode + balance: string | undefined + } + nfts?: ProjectCartNftReward[] + value?: string | undefined + onChange?: (value: string | undefined) => void +}) => { + token.type = token.type || 'native' + + const converter = useCurrencyConverter() + + const convertedValue = useMemo(() => { + if (!value || token.type !== 'eth') { + return undefined + } + + const usdPerEth = converter.usdPerEth + const n = parseFloat(value) + if (Number.isNaN(n)) { + return undefined + } + + const amount = usdPerEth ? n * usdPerEth : undefined + return { + amount, + currency: V4_CURRENCY_USD, + } + }, [converter, token.type, value]) + + const handleInputChange = (event: React.ChangeEvent) => { + // only allow numbers and decimals + let value = event.target.value.replace(/[^0-9.]/g, '') + // If value contains more than one decimal point, remove the last one + if (value.split('.').length > 2) { + const idx = value.lastIndexOf('.') + value = value.slice(0, idx) + value.slice(idx + 1) + } + let num + try { + num = BigInt(value) + } catch (e) { + console.warn('Invalid number', e) + return onChange?.(value) + } + if (num > MAX_AMOUNT) return onChange?.(MAX_AMOUNT.toString()) + + return onChange?.(value) + } + + const handleBlur = () => { + if (value?.endsWith('.')) { + onChange?.(value.slice(0, -1)) + } + } + + if (redeemUnavailable && !nfts?.length) { + return null + } + + return ( +
+
+ + {!redeemUnavailable && ( +
+
+ + +
+
+ + {convertedValue && formatCurrencyAmount(convertedValue)} + + + {token.balance && <>Balance: {formatAmount(token.balance)}} + +
+
+ )} + {/* Only show spacer if redeem is available and nfts are not empty */} + {!redeemUnavailable && !!nfts?.length && ( +
+ )} + + {/* {nfts && nfts?.length > 0 && ( +
+ {nfts.map((nft, i) => ( + + ))} +
+ )} + */} +
+ + {downArrow && ( + + )} +
+ ) +} + +const TokenBadge = ({ + className, + token, + image, + isErc20, +}: { + className?: string + token: string + image: ReactNode + isErc20?: boolean +}) => { + return ( +
+ +
+
+ {image} +
+ {isErc20 && ( +
+ +
+ )} +
+
+ {token} +
+ ) +} + +const DownArrow = ({ className }: { className?: string }) => { + return ( +
+
+ +
+
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/RedeemConfiguration.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/RedeemConfiguration.tsx new file mode 100644 index 0000000000..93d988d914 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/RedeemConfiguration.tsx @@ -0,0 +1,225 @@ +// import { CheckCircleIcon } from '@heroicons/react/24/outline' +// import { t, Trans } from '@lingui/macro' +// import { Button, Tooltip } from 'antd' +// import Loading from 'components/Loading' +// import { JuiceModal, JuiceModalProps } from 'components/modals/JuiceModal' +// import { PV_V2 } from 'constants/pv' +// import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' +// import { useProjectLogoSrc } from 'hooks/useProjectLogoSrc' +// import { useWallet } from 'hooks/Wallet' +// import { useJBTokenContext } from 'juice-sdk-react' +// import { useETHReceivedFromTokens } from 'packages/v2v3/hooks/contractReader/useETHReceivedFromTokens' +// import { useRedeemTokensTx } from 'packages/v2v3/hooks/transactor/useRedeemTokensTx' +// import { usePayoutLimit } from 'packages/v4/hooks/usePayoutLimit' +// import { V4_CURRENCY_USD } from 'packages/v4/utils/currency' +// import { useCallback, useMemo, useState } from 'react' +// import { formatAmount } from 'utils/format/formatAmount' +// import { fromWad, parseWad } from 'utils/format/formatNumber' +// import { emitErrorNotification } from 'utils/notifications' +// import { EthereumLogo } from './EthereumLogo' +// import { PayRedeemInput } from './PayRedeemInput' + +// type RedeemConfigurationProps = { +// userTokenBalance: number | undefined +// projectHasErc20Token: boolean +// } + +// export const RedeemConfiguration: React.FC = ({ +// userTokenBalance, +// projectHasErc20Token, +// }) => { +// const { token } = useJBTokenContext() +// const tokenSymbol = token?.data?.symbol +// const { data: payoutLimit } = usePayoutLimit() +// const { projectId, projectMetadata } = useProjectMetadataContext() +// const redeemTokensTx = useRedeemTokensTx() +// const wallet = useWallet() +// // TODO: We should probably break out tokens panel hook into reusable module +// const tokenLogo = useProjectLogoSrc({ +// projectId, +// pv: PV_V2, +// uri: projectMetadata?.logoUri, +// }) + +// const [redeemAmount, setRedeemAmount] = useState() +// const [fallbackImage, setFallbackImage] = useState() +// const [modalOpen, setModalOpen] = useState(false) +// const [redeeming, setRedeeming] = useState(false) + +// const ethReceivedFromTokens = useETHReceivedFromTokens({ +// tokenAmount: redeemAmount, +// }) + +// const tokenFromRedeemAmount = useMemo(() => { +// if (!redeemAmount) return '' +// return formatAmount(fromWad(ethReceivedFromTokens)) +// }, [ethReceivedFromTokens, redeemAmount]) + +// const insufficientBalance = useMemo(() => { +// if (!userTokenBalance) return false +// const amount = Number(redeemAmount || 0) +// const balance = userTokenBalance ?? 0 +// return amount > balance +// }, [redeemAmount, userTokenBalance]) +// const tokenTicker = tokenSymbol || 'TOKENS' + +// // 0.5% slippage for USD-denominated tokens +// const slippage = useMemo(() => { +// if (payoutLimit?.currency === V4_CURRENCY_USD) { +// return ethReceivedFromTokens?.mul(1000).div(1005) +// } +// return ethReceivedFromTokens +// }, [payoutLimit?.currency, ethReceivedFromTokens]) + +// const redeem = useCallback(async () => { +// if (!slippage) { +// emitErrorNotification('Failed to calculate slippage') +// return +// } +// setRedeeming(true) +// const txSuccess = await redeemTokensTx( +// { +// redeemAmount: parseWad(redeemAmount), +// minReturnedTokens: slippage, +// memo: '', +// }, +// { +// onDone: () => { +// setModalOpen(true) +// }, +// onConfirmed: () => { +// setRedeeming(false) +// }, +// onError: (e: Error) => { +// setRedeeming(false) +// setModalOpen(false) +// emitErrorNotification(e.message) +// }, +// }, +// ) +// if (!txSuccess) { +// setRedeeming(false) +// setModalOpen(false) +// } +// }, [redeemAmount, redeemTokensTx, slippage]) + +// return ( +// <> +//
+//
+//
+// +// {t`You redeem`} +// +// } +// token={{ +// balance: userTokenBalance?.toString(), +// image: +// tokenLogo && !fallbackImage ? ( +// Token logo setFallbackImage(true)} +// /> +// ) : ( +// '🧃' +// ), +// ticker: tokenTicker, +// type: projectHasErc20Token ? 'erc20' : 'native', +// }} +// value={redeemAmount} +// onChange={setRedeemAmount} +// /> +// , +// ticker: 'ETH', +// type: 'eth', +// }} +// value={tokenFromRedeemAmount} +// /> +//
+//
+ +// +//
+// +// +// ) +// } + +// const RedeemModal: React.FC = ({ +// redeeming, +// ...props +// }) => { +// return ( +// +//
+// {redeeming ? ( +// <> +// +//

+// Redeeming tokens +//

+//
+// Your transaction is processing. +//
+//
+// You can safely close this modal. +//
+// +// ) : ( +// <> +//
+//
+// +//
+//
+//

+// Success! +//

+//
+// Your transaction was successful. +//
+//
+// You can safely close this modal. +//
+// +// )} + +// {/* View on block explorer */} +//
+//
+// ) +// } diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard.tsx new file mode 100644 index 0000000000..6d665f0d23 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard.tsx @@ -0,0 +1,160 @@ +import { InformationCircleIcon } from '@heroicons/react/24/outline' +import { Trans, t } from '@lingui/macro' +import { Tooltip } from 'antd' +import { Callout } from 'components/Callout/Callout' +import { useJBRulesetContext } from 'juice-sdk-react' +import { usePayoutLimit } from 'packages/v4/hooks/usePayoutLimit' +import { MAX_PAYOUT_LIMIT } from 'packages/v4/utils/math' +import { ReactNode } from 'react' +import { twMerge } from 'tailwind-merge' +import { useProjectDispatch, useProjectSelector } from '../redux/hooks' +import { payRedeemActions } from '../redux/payRedeemSlice' +import { PayConfiguration } from './PayConfiguration' +import { PayProjectModal } from './PayProjectModal/PayProjectModal' +// import { RedeemConfiguration } from './RedeemConfiguration' + +type PayRedeemCardProps = { + className?: string +} + +export const V4PayRedeemCard: React.FC = ({ + className, +}) => { + const { ruleset, rulesetMetadata } = useJBRulesetContext() + const state = useProjectSelector(state => state.payRedeem.cardState) + // const { value: hasNfts, loading: hasNftsLoading } = useHasNftRewards() + const { data: payoutLimit } = usePayoutLimit() + const dispatch = useProjectDispatch() + + const projectHasErc20Token = false // TODO + + // TODO: We should probably break out tokens panel hook into reusable module + // const { userTokenBalance: panelBalance } = useTokensPanel() + // const tokenBalance = panelBalance + // ? parseFloat(panelBalance.replaceAll(',', '')) + // : undefined + const tokenBalance = 0 // TODO + + const redeems = { + loading: ruleset.isLoading, + enabled: + !((rulesetMetadata.data?.redemptionRate?.value ?? 0n) > 0n) || false, + } + + const weight = ruleset.data?.weight + const isIssuingTokens = Boolean(weight && weight.value > 0n) + // const showNfts = hasNfts && !hasNftsLoading + const noticeText = isIssuingTokens + ? // showNfts + // ? t`Project isn't currently issuing tokens, but is issuing NFTs` + // : + t`Project isn't currently issuing tokens` + : undefined + + const redeemDisabled = + !rulesetMetadata.data?.redemptionRate || + payoutLimit?.amount === MAX_PAYOUT_LIMIT + + return ( +
+
+
+ dispatch(payRedeemActions.changeToPay())} + > + Pay + + {redeemDisabled ? null : ( + { + dispatch(payRedeemActions.changeToRedeem()) + }} + disabled={!redeems.enabled} + > + Redeem + + )} +
+ +
+ {state === 'pay' ? ( + + ) : null + // + } +
+
+ + {/* */} + + {!isIssuingTokens && noticeText && ( + } + > + {noticeText} + + )} + + {/* */} + {/* + {projectHasErc20Token && unclaimedTokenBalance?.gt(0) && ( + + )} */} + + +
+ ) +} + +const ChoiceButton = ({ + children, + onClick, + selected, + tooltip, + disabled, +}: { + children: React.ReactNode + onClick?: () => void + selected?: boolean + tooltip?: ReactNode + disabled?: boolean +}) => { + if (disabled) { + tooltip = t`Disabled for this project` + } + + return ( + + + + ) +} diff --git a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx new file mode 100644 index 0000000000..89df9f0c2a --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx @@ -0,0 +1,96 @@ +import { ArrowUturnLeftIcon } from '@heroicons/react/24/outline' +import { Trans } from '@lingui/macro' +import { Button } from 'antd' +import confettiAnimationJuicebox from 'data/lottie/confetti-animation-juicebox.json' +import dynamic from 'next/dynamic' +import Link from 'next/link' +import { v4ProjectRoute } from 'packages/v4/utils/routes' +import { useChainId } from 'wagmi' +import { SuccessNftItem } from './components/SuccessNftItem' +import { SuccessPayCard } from './components/SuccessPayCard' +import { SuccessTokensItem } from './components/SuccessTokensItem' +import { useSuccessPayView } from './hooks/useSuccessPayView' +const Lottie = dynamic(() => import('lottie-react'), { ssr: false }) + +export const SuccessPayView = () => { + const { + projectId, + confettiVisible, + name, + projectPayReceipt, + nftPaymentSuccessModal, + nftsPurchased, + tokensReceivedDuringTx, + } = useSuccessPayView() + + const chainId = useChainId() + + return ( +
+ {confettiVisible && ( + + )} +

+ Success! +

+

+ Thank you, your payment was successful. +

+ +
+
+ + +
+ {/* {projectId && ( + + Subscribe to updates + + )} */} + + + + +
+
+ + {nftsPurchased && nftPaymentSuccessModal && ( +
+

+ A message from {name} +

+

{nftPaymentSuccessModal.content}

+
+ )} + + {(nftsPurchased || tokensReceivedDuringTx) && ( +
+

+ Your NFTs & Rewards +

+
+ {projectPayReceipt?.nfts.map(({ id }) => ( + + ))} + +
+
+ )} +
+
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx new file mode 100644 index 0000000000..721976a3b4 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx @@ -0,0 +1,48 @@ +import { Trans } from '@lingui/macro' +import { CartItemBadge } from 'components/CartItemBadge' +import { NftPreview } from 'components/NftRewards/NftPreview' +import { SmallNftSquare } from 'components/NftRewards/SmallNftSquare' +import { NftRewardsContext } from 'packages/v2v3/contexts/NftRewards/NftRewardsContext' +import { useContext, useMemo, useState } from 'react' + +export const SuccessNftItem = ({ id }: { id: number }) => { + const { + nftRewards: { rewardTiers }, + } = useContext(NftRewardsContext) + const [previewVisible, setPreviewVisible] = useState(false) + + const openPreview = () => setPreviewVisible(true) + + const rewardTier = useMemo(() => { + if (!rewardTiers) return undefined + const nftReward = rewardTiers.find(reward => reward.id === id) + return nftReward + }, [id, rewardTiers]) + + return ( + <> +
+ + + {rewardTier?.name ?? ''} + + + NFT + +
+ {rewardTier && ( + + )} + + ) +} diff --git a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessPayCard.tsx b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessPayCard.tsx new file mode 100644 index 0000000000..8a9532a62a --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessPayCard.tsx @@ -0,0 +1,89 @@ +import { Trans } from '@lingui/macro' +import EthereumAddress from 'components/EthereumAddress' +import EtherscanLink from 'components/EtherscanLink' +import { ProjectHeaderLogo } from 'components/Project/ProjectHeader/ProjectHeaderLogo' +import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' +import useMobile from 'hooks/useMobile' +import moment from 'moment' +import { useProjectPageQueries } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPageQueries' +import { formatCurrencyAmount } from 'packages/v2v3/utils/formatCurrencyAmount' +import { useMemo } from 'react' +import { twMerge } from 'tailwind-merge' + +export const SuccessPayCard = ({ className }: { className?: string }) => { + const isMobile = useMobile() + const { name } = useProjectMetadataContext().projectMetadata ?? {} + const { projectPayReceipt } = useProjectPageQueries() + + const transactionDateString = useMemo(() => { + if (!projectPayReceipt?.timestamp) return null + const timestampMs = projectPayReceipt.timestamp.getTime() + return `${moment(timestampMs).fromNow(true)} ago` + }, [projectPayReceipt?.timestamp]) + + if (!projectPayReceipt || !transactionDateString) return null + + return ( +
+
+
+ +
+ + Paid + + {name} + + {formatCurrencyAmount({ + ...projectPayReceipt.totalAmount, + withScale: true, + })} + +
+
+ +
+
+ + {transactionDateString} + + {!isMobile && ( + + )} +
+ {!isMobile && ( + + )} +
+
+ {isMobile && ( +
+ + +
+ )} +
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx new file mode 100644 index 0000000000..4c5b987bb8 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx @@ -0,0 +1,32 @@ +import { Trans } from '@lingui/macro' +import { CartItemBadge } from 'components/CartItemBadge' +import { ProjectHeaderLogo } from 'components/Project/ProjectHeader/ProjectHeaderLogo' +import { useProjectPageQueries } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPageQueries' + +export const SuccessTokensItem = () => { + const { projectPayReceipt } = useProjectPageQueries() + + if ( + !projectPayReceipt || + !projectPayReceipt.tokensReceived.length || + projectPayReceipt.tokensReceived === '0' + ) + return null + + return ( +
+ +
+
+ + Project tokens + + Token +
+ + {projectPayReceipt.tokensReceived} + +
+
+ ) +} diff --git a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/hooks/useSuccessPayView.ts b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/hooks/useSuccessPayView.ts new file mode 100644 index 0000000000..606ada1ad9 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/hooks/useSuccessPayView.ts @@ -0,0 +1,35 @@ +import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' +import { useProjectPageQueries } from 'packages/v4/views/V4ProjectDashboard/hooks/useProjectPageQueries' +import { useEffect, useState } from 'react' + +export const useSuccessPayView = () => { + const { projectMetadata, projectId } = useProjectMetadataContext() + const { projectPayReceipt } = useProjectPageQueries() + + const [confettiVisible, setConfettiVisible] = useState(true) + + const { name, nftPaymentSuccessModal } = projectMetadata ?? {} + + const nftsPurchased = !!projectPayReceipt?.nfts.length + const tokensReceivedDuringTx = projectPayReceipt + ? projectPayReceipt.tokensReceived.length && + projectPayReceipt.tokensReceived !== '0' + : false + + useEffect(() => { + const timer = setTimeout(() => { + setConfettiVisible(false) + }, 4000) + return () => clearTimeout(timer) + }) + + return { + projectId, + name, + projectPayReceipt, + nftPaymentSuccessModal, + nftsPurchased, + tokensReceivedDuringTx, + confettiVisible, + } +} diff --git a/src/packages/v4/components/ProjectDashboard/redux/hooks.ts b/src/packages/v4/components/ProjectDashboard/redux/hooks.ts new file mode 100644 index 0000000000..0d419492ea --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/redux/hooks.ts @@ -0,0 +1,9 @@ +import type { TypedUseSelectorHook } from 'react-redux' +import { useDispatch, useSelector, useStore } from 'react-redux' +import { ProjectDispatch, ProjectStore, RootProjectState } from './store' + +// Use throughout your app instead of plain `useDispatch` and `useSelector` +export const useProjectDispatch: () => ProjectDispatch = useDispatch +export const useProjectSelector: TypedUseSelectorHook = + useSelector +export const useProjectStore: () => ProjectStore = useStore diff --git a/src/packages/v4/components/ProjectDashboard/redux/payRedeemSlice.ts b/src/packages/v4/components/ProjectDashboard/redux/payRedeemSlice.ts new file mode 100644 index 0000000000..cc9c9b3da6 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/redux/payRedeemSlice.ts @@ -0,0 +1,29 @@ +import { createSlice } from '@reduxjs/toolkit' + +export type PayRedeemState = { + cardState: 'pay' | 'redeem' + // TODO: Move projectCart slice here +} + +const payRedeemSlice = createSlice({ + name: 'payRedeem', + initialState: { + cardState: 'pay', + } as PayRedeemState, + reducers: { + changeToPay: state => { + state.cardState = 'pay' + }, + changeToRedeem: state => { + state.cardState = 'redeem' + }, + reset: state => { + state.cardState = 'pay' + }, + }, +}) + +export const payRedeemReducer = payRedeemSlice.reducer +export const payRedeemActions = payRedeemSlice.actions + +export default payRedeemSlice.reducer diff --git a/src/packages/v4/components/ProjectDashboard/redux/projectCartSlice.ts b/src/packages/v4/components/ProjectDashboard/redux/projectCartSlice.ts new file mode 100644 index 0000000000..54885ebb83 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/redux/projectCartSlice.ts @@ -0,0 +1,254 @@ +import { CaseReducer, createSlice, PayloadAction } from '@reduxjs/toolkit' +import { NftRewardTier } from 'models/nftRewards' +import { V4CurrencyOption } from 'packages/v4/models/v4CurrencyOption' +import { V4_CURRENCY_ETH } from 'packages/v4/utils/currency' +import { formatEther, parseEther } from 'viem' +import { + ProjectCartCurrencyAmount, + ProjectCartNftReward, +} from '../ReduxProjectCartProvider' + +export type ProjectCartState = { + payAmount: ProjectCartCurrencyAmount | undefined + /** + * The NFT rewards that the user has chosen or is eligible to mint. + */ + chosenNftRewards: ProjectCartNftReward[] + /** + * All NFTs of the project. + */ + allNftRewards: NftRewardTier[] + userNftCredits: string + nftRewardEligibilityDismissed: boolean + expanded: boolean + payModalOpen: boolean +} + +const resetReducer: CaseReducer = state => { + state.payAmount = undefined + state.chosenNftRewards = [] + state.nftRewardEligibilityDismissed = false + state.expanded = false +} + +export const projectCartInitialState = { + payAmount: undefined, + chosenNftRewards: [], + allNftRewards: [], + userNftCredits: BigInt(0).toString(), + nftRewardEligibilityDismissed: false, + expanded: false, + payModalOpen: false, +} as ProjectCartState + +const projectCartSlice = createSlice({ + name: 'projectCart', + initialState: projectCartInitialState, + reducers: { + addPayment: ( + state, + action: PayloadAction<{ amount: number; currency: V4CurrencyOption }>, + ) => { + const nftRewards = calculateEligibleNftRewards({ + rewardTiers: state.allNftRewards, + weiPayAmount: parseEther(action.payload.amount.toString()), + nftRewards: state.chosenNftRewards, + }) + state.payAmount = { + amount: action.payload.amount, + currency: action.payload.currency, + } + state.chosenNftRewards = nftRewards.map(r => ({ + id: r.id, + quantity: 1, + })) + state.nftRewardEligibilityDismissed = false + }, + removePayment: state => { + state.payAmount = undefined + state.chosenNftRewards = [] + state.nftRewardEligibilityDismissed = false + }, + reset: resetReducer, + payProject: resetReducer, + upsertNftReward: (state, action: PayloadAction) => { + const nftReward = action.payload + const chosenNftCost = state.allNftRewards.find( + n => n.id === nftReward.id, + )?.contributionFloor + const existingIndex = state.chosenNftRewards.findIndex( + reward => reward.id === nftReward.id, + ) + const payAmount = + parseEther((state.payAmount?.amount ?? 0).toString()) + + parseEther((chosenNftCost ?? 0).toString()) + + if (existingIndex === -1) { + state.payAmount = { + amount: Number(formatEther(payAmount)), + currency: state.payAmount?.currency ?? V4_CURRENCY_ETH, + } + state.chosenNftRewards = [...state.chosenNftRewards, nftReward] + } + const newNftRewards = [...state.chosenNftRewards] + newNftRewards[existingIndex] = nftReward + state.payAmount = { + amount: Number(formatEther(payAmount)), + currency: state.payAmount?.currency ?? V4_CURRENCY_ETH, + } + state.chosenNftRewards = newNftRewards + }, + removeNftReward: (state, action: PayloadAction<{ id: number }>) => { + const { id } = action.payload + let payAmount = state.payAmount?.amount ?? 0 + const removedNftCost = state.allNftRewards.find( + n => n.id === id, + )?.contributionFloor + const quantity = state.chosenNftRewards.find( + nft => nft.id === id, + )?.quantity + if (quantity && quantity > 0) { + const nftCostBn = + parseEther((removedNftCost ?? 0).toString()) * BigInt(quantity) + const payAmountBn = parseEther(payAmount.toString()) + payAmount = Math.max(0, Number(formatEther(payAmountBn - nftCostBn))) + } + state.payAmount = payAmount + ? { + amount: payAmount, + currency: state.payAmount?.currency ?? V4_CURRENCY_ETH, + } + : undefined + state.chosenNftRewards = state.chosenNftRewards.filter( + reward => reward.id !== id, + ) + }, + increaseNftRewardQuantity: ( + state, + action: PayloadAction<{ id: number }>, + ) => { + const { id } = action.payload + const existingIndex = state.chosenNftRewards.findIndex( + reward => reward.id === id, + ) + if (existingIndex === -1) return + const newNftRewards = [...state.chosenNftRewards] + newNftRewards[existingIndex] = { + ...newNftRewards[existingIndex], + quantity: newNftRewards[existingIndex].quantity + 1, + } + const chosenNftCost = state.allNftRewards.find( + n => n.id === id, + )?.contributionFloor + const payAmount = + parseEther((state.payAmount?.amount ?? 0).toString()) + + parseEther((chosenNftCost ?? 0).toString()) + + state.payAmount = { + amount: Number(formatEther(payAmount)), + currency: state.payAmount?.currency ?? V4_CURRENCY_ETH, + } + state.chosenNftRewards = newNftRewards + }, + decreaseNftRewardQuantity: ( + state, + action: PayloadAction<{ id: number }>, + ) => { + const { id } = action.payload + const existingIndex = state.chosenNftRewards.findIndex( + reward => reward.id === id, + ) + if (existingIndex === -1) return + const removedNftCost = state.allNftRewards.find( + n => n.id === id, + )?.contributionFloor + const payAmountBn = + parseEther((state.payAmount?.amount ?? 0).toString()) - + parseEther((removedNftCost ?? 0).toString()) + + const payAmount = Math.max(0, Number(formatEther(payAmountBn))) + const newNftRewards = [...state.chosenNftRewards] + if (newNftRewards[existingIndex].quantity - 1 <= 0) { + state.payAmount = payAmount + ? { + amount: payAmount, + currency: state.payAmount?.currency ?? V4_CURRENCY_ETH, + } + : undefined + state.chosenNftRewards = newNftRewards.filter( + reward => reward.id !== newNftRewards[existingIndex].id, + ) + } else { + newNftRewards[existingIndex] = { + ...newNftRewards[existingIndex], + quantity: newNftRewards[existingIndex].quantity - 1, + } + state.payAmount = payAmount + ? { + amount: payAmount, + currency: state.payAmount?.currency ?? V4_CURRENCY_ETH, + } + : undefined + state.chosenNftRewards = newNftRewards + } + }, + setPayModal: (state, action: PayloadAction<{ open: boolean }>) => { + const { open } = action.payload + state.payModalOpen = open + }, + setAllNftRewards: (state, action: PayloadAction) => { + state.allNftRewards = action.payload + }, + setUserNftCredits: (state, action: PayloadAction) => { + state.userNftCredits = action.payload.toString() + }, + openPayModal: state => { + state.payModalOpen = true + }, + closePayModal: state => { + state.payModalOpen = false + }, + }, +}) + +export const projectCartReducer = projectCartSlice.reducer +export const projectCartActions = projectCartSlice.actions + +const calculateEligibleNftRewards = ({ + rewardTiers, + weiPayAmount, + nftRewards, +}: { + rewardTiers: NftRewardTier[] | undefined + weiPayAmount: bigint + nftRewards: ProjectCartNftReward[] +}) => { + if (!rewardTiers || weiPayAmount === 0n) return [] + const ethAmount = Number(formatEther(weiPayAmount)) + const potentialRewards = rewardTiers + .filter(tier => (tier.remainingSupply ?? Infinity) > 0) + .filter(tier => tier.contributionFloor <= ethAmount) + .filter(tier => !nftRewards.find(nft => nft.id === tier.id)) + .sort((a, b) => b.contributionFloor - a.contributionFloor) + + const eligibleRewards = [] + let remainingAmount = ethAmount + // opt to try and keep the existing nft rewards if possible + for (const reward of nftRewards) { + const tier = rewardTiers.find(tier => tier.id === reward.id) + if (tier && tier.contributionFloor <= remainingAmount) { + eligibleRewards.push(reward) + remainingAmount -= tier.contributionFloor + } + } + + for (const reward of potentialRewards) { + if (remainingAmount >= reward.contributionFloor) { + eligibleRewards.push(reward) + remainingAmount -= reward.contributionFloor + } + } + return eligibleRewards +} + +export default projectCartSlice.reducer diff --git a/src/packages/v4/components/ProjectDashboard/redux/store.ts b/src/packages/v4/components/ProjectDashboard/redux/store.ts new file mode 100644 index 0000000000..a0e1a00d6b --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/redux/store.ts @@ -0,0 +1,15 @@ +import { configureStore } from '@reduxjs/toolkit' +import { payRedeemReducer } from './payRedeemSlice' +import { projectCartReducer } from './projectCartSlice' + +const store = configureStore({ + reducer: { projectCart: projectCartReducer, payRedeem: payRedeemReducer }, +}) + +// Infer the `RootState` and `AppDispatch` types from the store itself +export type RootProjectState = ReturnType +// Inferred type +export type ProjectDispatch = typeof store.dispatch +export type ProjectStore = typeof store + +export default store diff --git a/src/packages/v4/components/SplitList/SplitItem/JuiceboxProjectBeneficiary.tsx b/src/packages/v4/components/SplitList/SplitItem/JuiceboxProjectBeneficiary.tsx index 48cd9daa22..ffa1f767ea 100644 --- a/src/packages/v4/components/SplitList/SplitItem/JuiceboxProjectBeneficiary.tsx +++ b/src/packages/v4/components/SplitList/SplitItem/JuiceboxProjectBeneficiary.tsx @@ -3,7 +3,6 @@ import { Tooltip } from 'antd' import { AllocatorBadge } from 'components/AllocatorBadge' import { NULL_ALLOCATOR_ADDRESS } from 'constants/contracts/mainnet/Allocators' import { JBSplit } from 'juice-sdk-core' -import { useRouter } from 'next/router' import V4ProjectHandleLink from '../../V4ProjectHandleLink' export function JuiceboxProjectBeneficiary({ split, @@ -12,9 +11,6 @@ export function JuiceboxProjectBeneficiary({ split: JBSplit value?: string | JSX.Element }) { - const router = useRouter() - const { chainName } = router.query - if (!split.projectId) return null return ( @@ -23,7 +19,6 @@ export function JuiceboxProjectBeneficiary({
diff --git a/src/packages/v4/components/V4ProjectHandleLink.tsx b/src/packages/v4/components/V4ProjectHandleLink.tsx index eea594b52a..ef642b0da5 100644 --- a/src/packages/v4/components/V4ProjectHandleLink.tsx +++ b/src/packages/v4/components/V4ProjectHandleLink.tsx @@ -3,7 +3,9 @@ import ProjectLogo from 'components/ProjectLogo' import { PV_V4 } from 'constants/pv' import Link from 'next/link' import { twMerge } from 'tailwind-merge' -import { v4ProjectRoute } from 'utils/routes' +import { useChainId } from 'wagmi' +import { getChainName } from '../utils/networks' +import { v4ProjectRoute } from '../utils/routes' /** * Renders a link to a V4 project @@ -13,18 +15,21 @@ export default function V4ProjectHandleLink({ containerClassName, name, projectId, - chainName, withProjectAvatar = false, }: { className?: string containerClassName?: string name?: string | null - chainName: string projectId: number withProjectAvatar?: boolean }) { + const chainId = useChainId() + const chainName = getChainName(chainId) + return ( -
+
{withProjectAvatar ? ( - {chainName} Project #{projectId} + + {chainName} Project #{projectId} +
) diff --git a/src/packages/v4/utils/networks.ts b/src/packages/v4/utils/networks.ts new file mode 100644 index 0000000000..2b95929d91 --- /dev/null +++ b/src/packages/v4/utils/networks.ts @@ -0,0 +1,18 @@ +import { JBChainId } from 'juice-sdk-react' +import { + arbitrumSepolia, + baseSepolia, + optimismSepolia, + sepolia, +} from 'viem/chains' + +export const chainNameMap: Record = { + sepolia: sepolia.id, + opsepolia: optimismSepolia.id, + basesepolia: baseSepolia.id, + arbsepolia: arbitrumSepolia.id, +} + +export function getChainName(chainId: number) { + return Object.entries(chainNameMap).find(([, id]) => id === chainId)?.[0] +} diff --git a/src/packages/v4/utils/routes.ts b/src/packages/v4/utils/routes.ts new file mode 100644 index 0000000000..44bbe5b5c7 --- /dev/null +++ b/src/packages/v4/utils/routes.ts @@ -0,0 +1,12 @@ +import { getChainName } from './networks' + +export const v4ProjectRoute = ({ + chainId, + projectId, +}: { + chainId: number + projectId?: number +}) => { + const chainName = getChainName(chainId) + return `/v4/${chainName}/p/${projectId?.toString()}` +} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard.tsx b/src/packages/v4/views/V4ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard.tsx deleted file mode 100644 index 144855e9fe..0000000000 --- a/src/packages/v4/views/V4ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Button } from 'antd' -import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' -import { useWallet } from 'hooks/Wallet' -import { NATIVE_TOKEN, NATIVE_TOKEN_DECIMALS } from 'juice-sdk-core' -import { - useJBContractContext, - useWriteJbMultiTerminalPay, -} from 'juice-sdk-react' -import { useContext, useState } from 'react' -import { parseUnits } from 'viem' - -// TODO wildly incomplete. Needs full redo -export function V4PayRedeemCard({ className }: { className: string }) { - const [value, setValue] = useState('0.0001') - - const { contracts, projectId } = useJBContractContext() - const { addTransaction } = useContext(TxHistoryContext) - const { userAddress } = useWallet() - - const valuePayload = value ? parseUnits(value, NATIVE_TOKEN_DECIMALS) : 0n - - const { writeContractAsync: writePay } = useWriteJbMultiTerminalPay() - - const onWrite = async () => { - if (!value || !contracts.primaryNativeTerminal.data || !userAddress) { - return - } - - const args = [ - projectId, - NATIVE_TOKEN, - valuePayload, - userAddress, - 0n, - `JBM V4 ${projectId}`, // TODO update - '0x0', - ] as const - - const txHash = await writePay({ - address: contracts.primaryNativeTerminal.data, - args, - value: valuePayload, - }) - - addTransaction?.('Pay', { hash: txHash }) - } - - return ( -
- -
- ) -} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx index 0e4c9b2b55..329294c3b2 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx @@ -1,12 +1,29 @@ import { CoverPhoto } from 'components/Project/ProjectHeader/CoverPhoto' +import { SuccessPayView } from 'packages/v4/components/ProjectDashboard/components/SuccessPayView/SuccessPayView' +import { useProjectDispatch } from 'packages/v4/components/ProjectDashboard/redux/hooks' +import { payRedeemActions } from 'packages/v4/components/ProjectDashboard/redux/payRedeemSlice' +import { projectCartActions } from 'packages/v4/components/ProjectDashboard/redux/projectCartSlice' +import { V4PayRedeemCard } from 'packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard' +import { useEffect } from 'react' import { twMerge } from 'tailwind-merge' -import { V4PayRedeemCard } from './V4PayRedeemCard/V4PayRedeemCard' +import { useProjectPageQueries } from './hooks/useProjectPageQueries' import { V4ProjectHeader } from './V4ProjectHeader' import { V4ProjectTabs } from './V4ProjectTabs/V4ProjectTabs' export function V4ProjectDashboard() { + const { projectPayReceipt } = useProjectPageQueries() + + if (projectPayReceipt !== undefined) { + return ( +
+ +
+ ) + } + return ( <> +
@@ -37,3 +54,17 @@ export function V4ProjectDashboard() { ) } + +/** + * Reset the store on load. + */ +const ResetStoreOnLoad: React.FC = () => { + const dispatch = useProjectDispatch() + + useEffect(() => { + dispatch(projectCartActions.reset()) + dispatch(payRedeemActions.reset()) + }, [dispatch]) + + return null +} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx index 716f5ab625..b4e8431443 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx @@ -15,8 +15,10 @@ import Link from 'next/link' import V4ProjectHandleLink from 'packages/v4/components/V4ProjectHandleLink' import { useV4WalletHasPermission } from 'packages/v4/hooks/useV4WalletHasPermission' import { V4OperatorPermission } from 'packages/v4/models/v4Permissions' +import { v4ProjectRoute } from 'packages/v4/utils/routes' import { twMerge } from 'tailwind-merge' -import { settingsPagePath, v4ProjectRoute } from 'utils/routes' +import { settingsPagePath } from 'utils/routes' +import { useChainId } from 'wagmi' import { useV4ProjectHeader } from './hooks/useV4ProjectHeader' import { ProjectHeaderStats } from './ProjectHeaderStats' @@ -24,11 +26,11 @@ export type SocialLink = 'twitter' | 'discord' | 'telegram' | 'website' export const V4ProjectHeader = ({ className }: { className?: string }) => { const socialLinks = useSocialLinks() + const chainId = useChainId() const { title, subtitle, - chainName, projectId, owner, gnosisSafe, @@ -112,10 +114,9 @@ export const V4ProjectHeader = ({ className }: { className?: string }) => { ))}
- {projectId && chainName ? ( + {projectId ? ( ) : null} @@ -129,7 +130,7 @@ export const V4ProjectHeader = ({ className }: { className?: string }) => { {gnosisSafe && projectId && ( )} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4ProjectAllocationRow.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4ProjectAllocationRow.tsx index 6ab33ff5b1..2a71986764 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4ProjectAllocationRow.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4ProjectAllocationRow.tsx @@ -1,5 +1,4 @@ import { JuiceboxAccountLink } from 'components/JuiceboxAccountLink' -import { useRouter } from 'next/router' import V4ProjectHandleLink from 'packages/v4/components/V4ProjectHandleLink' import { ReactNode } from 'react' @@ -16,8 +15,6 @@ export const V4ProjectAllocationRow: React.FC = ({ amount, percent, }) => { - const router = useRouter() - const { chainName } = router.query return (
@@ -27,7 +24,6 @@ export const V4ProjectAllocationRow: React.FC = ({ diff --git a/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts b/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts index b43598df3c..3ccee5ced9 100644 --- a/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts +++ b/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts @@ -7,7 +7,6 @@ import { useJBProjectMetadataContext } from 'juice-sdk-react' import { GnosisSafe } from 'models/safe' -import { useRouter } from 'next/router' import { ProjectsDocument } from 'packages/v4/graphql/client/graphql' import { useSubgraphQuery } from 'packages/v4/graphql/useSubgraphQuery' import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' @@ -22,11 +21,9 @@ export interface ProjectHeaderData { gnosisSafe: GnosisSafe | undefined | null archived: boolean | undefined createdAtSeconds: number | undefined - chainName: string } export const useV4ProjectHeader = (): ProjectHeaderData => { - const router = useRouter() const { projectId } = useJBContractContext() const { metadata } = useJBProjectMetadataContext() const projectMetadata = metadata?.data @@ -60,8 +57,6 @@ export const useV4ProjectHeader = (): ProjectHeaderData => { const totalVolume = BigInt(totalVolumeStr) const trendingVolume = BigInt(trendingVolumeStr) - const { chainName } = router.query - const last7DaysPercent = useProjectTrendingPercentageIncrease({ totalVolume: BigNumber.from(totalVolume ?? 0), trendingVolume: BigNumber.from(trendingVolume ?? 0), @@ -73,7 +68,6 @@ export const useV4ProjectHeader = (): ProjectHeaderData => { return { title: projectMetadata?.name, - chainName: chainName as string, // TODO make this better. Single source for chain names, derived from useJBChainId. subtitle, projectId: projectIdNum, owner: projectOwnerAddress, diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index 88d9f54eb8..6216a246e3 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -3,26 +3,17 @@ import { FEATURE_FLAGS } from 'constants/featureFlags' import { OPEN_IPFS_GATEWAY_HOSTNAME } from 'constants/ipfs' import { JBChainId, JBProjectProvider } from 'juice-sdk-react' import { useRouter } from 'next/router' +import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' +import store from 'packages/v4/components/ProjectDashboard/redux/store' import V4ProjectMetadataProvider from 'packages/v4/contexts/V4ProjectMetadataProvider' +import { chainNameMap } from 'packages/v4/networks' import { V4ProjectDashboard } from 'packages/v4/views/V4ProjectDashboard/V4ProjectDashboard' import { wagmiConfig } from 'packages/v4/wagmiConfig' import React, { PropsWithChildren } from 'react' +import { Provider } from 'react-redux' import { featureFlagEnabled } from 'utils/featureFlags' -import { - arbitrumSepolia, - baseSepolia, - optimismSepolia, - sepolia, -} from 'viem/chains' import { WagmiProvider } from 'wagmi' -const chainNameMap: Record = { - sepolia: sepolia.id, - opsepolia: optimismSepolia.id, - basesepolia: baseSepolia.id, - arbsepolia: arbitrumSepolia.id, -} - export default function V4ProjectPage() { const router = useRouter() const { chainName, projectId } = router.query @@ -54,7 +45,9 @@ const Providers: React.FC< }} > - {children} + + {children} + diff --git a/src/utils/routes.ts b/src/utils/routes.ts index a8694cc385..69da8323bc 100644 --- a/src/utils/routes.ts +++ b/src/utils/routes.ts @@ -20,16 +20,6 @@ export const v2v3ProjectRoute = ({ return `${route}${query ? `?${qs.stringify(query)}` : ''}` } -export const v4ProjectRoute = ({ - projectId, - chainName, -}: { - projectId?: number - chainName?: string -}) => { - return `/v4/${chainName}/p/${projectId?.toString()}` -} - export function helpPagePath(path: string): string { return new URL(path, HELP_PAGE_HOSTNAME).toString() } From afb5a7ef443f5f70ab89222f7fbfecea359033c5 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Tue, 13 Aug 2024 09:31:28 +1000 Subject: [PATCH 05/46] doop --- src/pages/v4/[chainName]/p/[projectId]/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index 6216a246e3..bfb056f28b 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -6,7 +6,7 @@ import { useRouter } from 'next/router' import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' import store from 'packages/v4/components/ProjectDashboard/redux/store' import V4ProjectMetadataProvider from 'packages/v4/contexts/V4ProjectMetadataProvider' -import { chainNameMap } from 'packages/v4/networks' +import { chainNameMap } from 'packages/v4/utils/networks' import { V4ProjectDashboard } from 'packages/v4/views/V4ProjectDashboard/V4ProjectDashboard' import { wagmiConfig } from 'packages/v4/wagmiConfig' import React, { PropsWithChildren } from 'react' From 6977dfae99922ab7cbafc0f5e5bf33199560e98d Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Tue, 13 Aug 2024 20:12:58 +1000 Subject: [PATCH 06/46] fix v4 i18n --- .../v4/[chainName]/p/[projectId]/index.tsx | 89 ++++++++++++++----- 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index bfb056f28b..2ad7f40d08 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -2,6 +2,8 @@ import { AppWrapper } from 'components/common/CoreAppWrapper/CoreAppWrapper' import { FEATURE_FLAGS } from 'constants/featureFlags' import { OPEN_IPFS_GATEWAY_HOSTNAME } from 'constants/ipfs' import { JBChainId, JBProjectProvider } from 'juice-sdk-react' +import { loadCatalog } from 'locales/utils' +import { GetStaticPaths, GetStaticProps } from 'next' import { useRouter } from 'next/router' import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' import store from 'packages/v4/components/ProjectDashboard/redux/store' @@ -14,6 +16,71 @@ import { Provider } from 'react-redux' import { featureFlagEnabled } from 'utils/featureFlags' import { WagmiProvider } from 'wagmi' +// This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. +const _Wrapper: React.FC = ({ children }) => { + const [hasMounted, setHasMounted] = React.useState(false) + React.useEffect(() => { + setHasMounted(true) + }, []) + + if (!hasMounted) { + return null + } + + if (!featureFlagEnabled(FEATURE_FLAGS.V4)) { + return ( +
+ Too early sir. Please come back later. 🫡 +
+ ) + } + + return <>{children} +} + +export const getStaticPaths: GetStaticPaths = async () => { + // if (process.env.BUILD_CACHE_V2_PROJECTS === 'true') { + // const projects = await paginateDepleteProjectsQueryCall({ + // variables: { where: { pv: PV_V2 } }, + // }) + // const paths = projects.map(({ projectId }) => ({ + // params: { projectId: String(projectId) }, + // })) + // return { paths, fallback: true } + // } + + // TODO: We are switching to blocking as blocking fallback as its just not + // working. Need to investigate further + return { + paths: [], + fallback: 'blocking', + } +} + +export const getStaticProps: GetStaticProps<{ + i18n: unknown +}> = async context => { + const locale = context.locale as string + const messages = await loadCatalog(locale) + const i18n = { locale, messages } + + if (!context.params) throw new Error('params not supplied') + + const projectId = parseInt(context.params.projectId as string) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + // const props = (await getProjectStaticProps(projectId)) as any + const props = { + props: { + i18n, + }, + } + + return { + ...props, + revalidate: 10, // 10 seconds https://nextjs.org/docs/api-reference/data-fetching/get-static-props#revalidate + } +} + export default function V4ProjectPage() { const router = useRouter() const { chainName, projectId } = router.query @@ -54,25 +121,3 @@ const Providers: React.FC< ) } - -// This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. -const _Wrapper: React.FC = ({ children }) => { - const [hasMounted, setHasMounted] = React.useState(false) - React.useEffect(() => { - setHasMounted(true) - }, []) - - if (!hasMounted) { - return null - } - - if (!featureFlagEnabled(FEATURE_FLAGS.V4)) { - return ( -
- Too early sir. Please come back later. 🫡 -
- ) - } - - return <>{children} -} From f89bc333d2f0cbf29d3a057f733d093792955adc Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Tue, 13 Aug 2024 20:36:20 +1000 Subject: [PATCH 07/46] meh i18n? --- .../v4/[chainName]/p/[projectId]/index.tsx | 46 +------------------ 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index 2ad7f40d08..bb7218809f 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -2,8 +2,6 @@ import { AppWrapper } from 'components/common/CoreAppWrapper/CoreAppWrapper' import { FEATURE_FLAGS } from 'constants/featureFlags' import { OPEN_IPFS_GATEWAY_HOSTNAME } from 'constants/ipfs' import { JBChainId, JBProjectProvider } from 'juice-sdk-react' -import { loadCatalog } from 'locales/utils' -import { GetStaticPaths, GetStaticProps } from 'next' import { useRouter } from 'next/router' import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' import store from 'packages/v4/components/ProjectDashboard/redux/store' @@ -14,6 +12,7 @@ import { wagmiConfig } from 'packages/v4/wagmiConfig' import React, { PropsWithChildren } from 'react' import { Provider } from 'react-redux' import { featureFlagEnabled } from 'utils/featureFlags' +import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' import { WagmiProvider } from 'wagmi' // This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. @@ -38,48 +37,7 @@ const _Wrapper: React.FC = ({ children }) => { return <>{children} } -export const getStaticPaths: GetStaticPaths = async () => { - // if (process.env.BUILD_CACHE_V2_PROJECTS === 'true') { - // const projects = await paginateDepleteProjectsQueryCall({ - // variables: { where: { pv: PV_V2 } }, - // }) - // const paths = projects.map(({ projectId }) => ({ - // params: { projectId: String(projectId) }, - // })) - // return { paths, fallback: true } - // } - - // TODO: We are switching to blocking as blocking fallback as its just not - // working. Need to investigate further - return { - paths: [], - fallback: 'blocking', - } -} - -export const getStaticProps: GetStaticProps<{ - i18n: unknown -}> = async context => { - const locale = context.locale as string - const messages = await loadCatalog(locale) - const i18n = { locale, messages } - - if (!context.params) throw new Error('params not supplied') - - const projectId = parseInt(context.params.projectId as string) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - // const props = (await getProjectStaticProps(projectId)) as any - const props = { - props: { - i18n, - }, - } - - return { - ...props, - revalidate: 10, // 10 seconds https://nextjs.org/docs/api-reference/data-fetching/get-static-props#revalidate - } -} +export const getServerSideProps = globalGetServerSideProps export default function V4ProjectPage() { const router = useRouter() From 0bc8422bae0197750d2595a4888b0d67c86a96b9 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Tue, 13 Aug 2024 21:02:44 +1000 Subject: [PATCH 08/46] revert any i18n ting v4 --- .../v4/[chainName]/p/[projectId]/index.tsx | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index bb7218809f..49d4646b74 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -12,7 +12,6 @@ import { wagmiConfig } from 'packages/v4/wagmiConfig' import React, { PropsWithChildren } from 'react' import { Provider } from 'react-redux' import { featureFlagEnabled } from 'utils/featureFlags' -import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' import { WagmiProvider } from 'wagmi' // This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. @@ -37,25 +36,6 @@ const _Wrapper: React.FC = ({ children }) => { return <>{children} } -export const getServerSideProps = globalGetServerSideProps - -export default function V4ProjectPage() { - const router = useRouter() - const { chainName, projectId } = router.query - if (!chainName || !projectId) { - return
Invalid URL
- } - const chainId = chainNameMap[chainName as string] - - return ( - <_Wrapper> - - - - - ) -} - const Providers: React.FC< PropsWithChildren & { chainId: JBChainId; projectId: bigint } > = ({ chainId, projectId, children }) => { @@ -79,3 +59,20 @@ const Providers: React.FC< ) } + +export default function V4ProjectPage() { + const router = useRouter() + const { chainName, projectId } = router.query + if (!chainName || !projectId) { + return
Invalid URL
+ } + const chainId = chainNameMap[chainName as string] + + return ( + <_Wrapper> + + + + + ) +} From 3ece3193cead38f9ace06fc03a4cac1c157bff82 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:17:39 +1000 Subject: [PATCH 09/46] chore: huge jb contract-related dependency clean --- package.json | 3 +- scripts/clean-deps.sh | 2 + src/components/DomainBadge.tsx | 14 - src/hooks/ENS/useRegistry.ts | 3 +- src/hooks/useProjectLogoSrc.ts | 6 - src/models/networkName.ts | 4 - src/packages/v1/constants/archivedProjects.ts | 1 - .../v1/contexts/User/useV1ContractLoader.ts | 2 +- .../v2v3/constants/archivedProjects.ts | 1 - .../v2v3/constants/ballotStrategies/index.ts | 3 - .../useJB721DelegateContractAddress.ts | 5 - src/packages/v2v3/hooks/JBPrices/index.ts | 2 +- .../v2v3/hooks/JBPrices/loadJBPrices.ts | 43 +- .../hooks/JBV3Token/contracts/JBV3TokenAbi.ts | 662 ++++++++++++++++++ .../hooks/JBV3Token/contracts/useJBV3Token.ts | 4 +- .../v2v3/utils/contractLoaders/JuiceboxV2.ts | 9 - .../v2v3/utils/contractLoaders/JuiceboxV3.ts | 24 +- src/pages/api/juicebox/prices/ethusd.ts | 3 +- .../v4/[chainName]/p/[projectId]/index.tsx | 37 +- src/utils/featureFlags.ts | 1 - src/utils/juicecrowd.ts | 8 - yarn.lock | 5 - 22 files changed, 712 insertions(+), 130 deletions(-) create mode 100755 scripts/clean-deps.sh create mode 100644 src/packages/v2v3/hooks/JBV3Token/contracts/JBV3TokenAbi.ts delete mode 100644 src/utils/juicecrowd.ts diff --git a/package.json b/package.json index 2a94065fae..594f9cb9a3 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "i18n:extract": "./scripts/extract-translations-template.sh", "i18n:extract-source-locale": "NODE_ENV=development lingui extract --locale en", "i18n:lint": "./scripts/lint-translations-template.sh", - "postinstall": "yarn i18n:compile", + "postinstall": "yarn i18n:compile && ./scripts/clean-deps.sh", "lint": "next lint", "lint-staged": "lint-staged", "lint:fix": "yarn lint --fix", @@ -66,7 +66,6 @@ "@jbx-protocol/juice-721-delegate-v3-4": "npm:@jbx-protocol/juice-721-delegate@8.0.1", "@jbx-protocol/juice-contracts-v3": "5.0.1", "@jbx-protocol/juice-delegates-registry": "1.0.3", - "@jbx-protocol/juice-v3-migration": "1.0.0", "@jbx-protocol/project-handles": "^2.0.5", "@lingui/cli": "^4.0.0", "@lingui/detect-locale": "^4.0.0", diff --git a/scripts/clean-deps.sh b/scripts/clean-deps.sh new file mode 100755 index 0000000000..a5647140fe --- /dev/null +++ b/scripts/clean-deps.sh @@ -0,0 +1,2 @@ +rm -Rf node_modules/@jbx-protocol/**/goerli node_modules/@jbx-protocol/**/dry-run +rm -f node_modules/@jbx-protocol/**/*.sol \ No newline at end of file diff --git a/src/components/DomainBadge.tsx b/src/components/DomainBadge.tsx index ee2c18b5af..a8edf9716a 100644 --- a/src/components/DomainBadge.tsx +++ b/src/components/DomainBadge.tsx @@ -1,8 +1,6 @@ import Image from 'next/image' -import Link from 'next/link' import { useMemo } from 'react' import { twMerge } from 'tailwind-merge' -import { getJuicecrowdUrl } from 'utils/juicecrowd' import { Badge } from './Badge' type DomainBadgeProps = { @@ -26,11 +24,6 @@ export const DomainBadge: React.FC = ({ if (domain === 'juicecrowd') return '/assets/images/juicecrowd-logo.webp' }, [domain]) - const linkUrl = useMemo(() => { - if (!domain || !projectId) return undefined - if (domain === 'juicecrowd') return getJuicecrowdUrl(projectId) - }, [projectId, domain]) - if (!customDomainImageSrc) return null const badge = ( @@ -45,12 +38,5 @@ export const DomainBadge: React.FC = ({ ) - if (linkUrl) - return ( - - {badge} - - ) - return badge } diff --git a/src/hooks/ENS/useRegistry.ts b/src/hooks/ENS/useRegistry.ts index 4b441f91a3..800cb3d383 100644 --- a/src/hooks/ENS/useRegistry.ts +++ b/src/hooks/ENS/useRegistry.ts @@ -10,10 +10,9 @@ async function loadENSRegistryContract(): Promise { if ( name === NetworkName.mainnet || - name === NetworkName.goerli || name === NetworkName.sepolia ) { - // Registry address is the same for both mainnet + goerli + sepolia + // Registry address is the same for both mainnet + sepolia return await import('hooks/ENS/contracts/ENSRegistry.json') } } diff --git a/src/hooks/useProjectLogoSrc.ts b/src/hooks/useProjectLogoSrc.ts index da33ba5de7..24a9c6890a 100644 --- a/src/hooks/useProjectLogoSrc.ts +++ b/src/hooks/useProjectLogoSrc.ts @@ -11,10 +11,6 @@ const MAINNET_URI_OVERRIDES: { [k: number]: string } = { 470: `${imageUriOverridePath}/breadfruit_logo.webp`, } -const GOERLI_URI_OVERRIDES: { [k: number]: string } = { - 1: `${imageUriOverridePath}/juiceboxdao_logo.webp`, // the on-chain logo's filesize is too large. This is a smaller version. -} - const SEPOLIA_URI_OVERRIDES: { [k: number]: string } = { 1: `${imageUriOverridePath}/juiceboxdao_logo.webp`, // the on-chain logo's filesize is too large. This is a smaller version. } @@ -23,8 +19,6 @@ const imgOverrideForProjectId = (projectId: number) => { switch (readNetwork.name) { case NetworkName.mainnet: return MAINNET_URI_OVERRIDES[projectId] - case NetworkName.goerli: - return GOERLI_URI_OVERRIDES[projectId] case NetworkName.sepolia: return SEPOLIA_URI_OVERRIDES[projectId] } diff --git a/src/models/networkName.ts b/src/models/networkName.ts index e6f4dfa3fc..9653ec39bb 100644 --- a/src/models/networkName.ts +++ b/src/models/networkName.ts @@ -1,9 +1,5 @@ export enum NetworkName { localhost = 'localhost', mainnet = 'mainnet', - /** - * @deprecated Please use sepolia - */ - goerli = 'goerli', sepolia = 'sepolia', } diff --git a/src/packages/v1/constants/archivedProjects.ts b/src/packages/v1/constants/archivedProjects.ts index 22852cf99e..7f2546bc58 100644 --- a/src/packages/v1/constants/archivedProjects.ts +++ b/src/packages/v1/constants/archivedProjects.ts @@ -33,7 +33,6 @@ const V1ArchivedProjectIdsByNetwork: Partial> = { JUS_DAO, DEMU, ], - [NetworkName.goerli]: [], [NetworkName.sepolia]: [], } diff --git a/src/packages/v1/contexts/User/useV1ContractLoader.ts b/src/packages/v1/contexts/User/useV1ContractLoader.ts index f501f4d82a..8882059e90 100644 --- a/src/packages/v1/contexts/User/useV1ContractLoader.ts +++ b/src/packages/v1/contexts/User/useV1ContractLoader.ts @@ -14,7 +14,7 @@ const loadV1Contract = async ( ): Promise => { let contract: Contract | undefined - if (network === NetworkName.goerli || network === NetworkName.sepolia) return + if (network === NetworkName.sepolia) return switch (contractName) { case V1ContractName.FundingCycles: diff --git a/src/packages/v2v3/constants/archivedProjects.ts b/src/packages/v2v3/constants/archivedProjects.ts index ae3ae4cb96..1fa84b9ce9 100644 --- a/src/packages/v2v3/constants/archivedProjects.ts +++ b/src/packages/v2v3/constants/archivedProjects.ts @@ -31,7 +31,6 @@ const V2ArchivedProjectIdsByNetwork: Partial> = { PROJECT_445, // OCTRA, ], - [NetworkName.goerli]: [], [NetworkName.sepolia]: [], } diff --git a/src/packages/v2v3/constants/ballotStrategies/index.ts b/src/packages/v2v3/constants/ballotStrategies/index.ts index f0e8b2272e..e431bb3f54 100644 --- a/src/packages/v2v3/constants/ballotStrategies/index.ts +++ b/src/packages/v2v3/constants/ballotStrategies/index.ts @@ -29,17 +29,14 @@ const V2_BALLOT_ADDRESSES: BallotOption = { const BALLOT_ADDRESSES: BallotOption = { ONE_DAY: { mainnet: '0xDd9303491328F899796319C2b6bD614324b86314', - goerli: '0x9d5687A9A175308773Bb289159Aa61D326E3aDB5', sepolia: '0x34E2992ea3C3E6CcfCf5bC668B68F285C1EDFE24', }, THREE_DAY: { mainnet: '0x19D8C293D35EA4b2879A864A68D45a2025694929', - goerli: '0xAa818525455C52061455a87C4Fb6F3a5E6f91090', sepolia: '0xa2154aBD135be068540073cB4390139906d0FDc6', }, SEVEN_DAY: { mainnet: '0x8E1AEc30063565e597705E71Ba14Dffc4C390Ef0', - goerli: '0xd2eEEdB22f075eBFf0a2A7D38781AA320CBc357E', sepolia: '0xb958fEa9089208d0Cc990EceCEcc42458F1B618e', }, } diff --git a/src/packages/v2v3/hooks/JB721Delegate/contracts/useJB721DelegateContractAddress.ts b/src/packages/v2v3/hooks/JB721Delegate/contracts/useJB721DelegateContractAddress.ts index 54428c411a..d883ebe226 100644 --- a/src/packages/v2v3/hooks/JB721Delegate/contracts/useJB721DelegateContractAddress.ts +++ b/src/packages/v2v3/hooks/JB721Delegate/contracts/useJB721DelegateContractAddress.ts @@ -15,11 +15,6 @@ const ADDRESSES: { } } = { [JB721DelegateVersion.JB721DELEGATE_V3_4]: { - [NetworkName.goerli]: { - JBTiered721DelegateStore: '0x155B49f303443a3334bB2EF42E10C628438a0656', // the store from 3.3 - JBTiered721DelegateProjectDeployer: - '0xB5870d8eeb195E09Ac47641121889CCdBbA3E8FE', // this is in the forge deployment manifest, but the name isn't specified because of a failed verification - }, [NetworkName.sepolia]: { JBTiered721DelegateStore: '0xd7F9Ee12b5De2388109C9dD4fAAf39BEfe4C92FB', // the store from 3.3 JBTiered721DelegateProjectDeployer: diff --git a/src/packages/v2v3/hooks/JBPrices/index.ts b/src/packages/v2v3/hooks/JBPrices/index.ts index c4da21d130..c47934fa6d 100644 --- a/src/packages/v2v3/hooks/JBPrices/index.ts +++ b/src/packages/v2v3/hooks/JBPrices/index.ts @@ -10,7 +10,7 @@ export function useJBPrices({ cv }: { cv?: CV2V3 } = {}) { useEffect(() => { async function load() { - const JBPrices = await loadJBPrices({ cv: cv ?? defaultCv }) + const JBPrices = await loadJBPrices() setContract(JBPrices) } diff --git a/src/packages/v2v3/hooks/JBPrices/loadJBPrices.ts b/src/packages/v2v3/hooks/JBPrices/loadJBPrices.ts index a746177231..b05a9e60d4 100644 --- a/src/packages/v2v3/hooks/JBPrices/loadJBPrices.ts +++ b/src/packages/v2v3/hooks/JBPrices/loadJBPrices.ts @@ -1,45 +1,20 @@ -import { CV_V2, CV_V3 } from 'constants/cv' import { readNetwork } from 'constants/networks' import { readProvider } from 'constants/readProvider' import { Contract } from 'ethers' import { ContractJson } from 'models/contracts' import { NetworkName } from 'models/networkName' -import { CV2V3 } from 'packages/v2v3/models/cv' -export async function loadJBPrices({ - cv, -}: { - cv: CV2V3 | undefined -}): Promise { +export async function loadJBPrices(): Promise { let contractJson: ContractJson | undefined - if (cv === CV_V2) { - if (readNetwork.name === NetworkName.goerli) { - contractJson = await import( - '@jbx-protocol/contracts-v2-latest/deployments/mainnet/JBPrices.json' - ) - contractJson.address = '0x57bF7C005B77d487074AB3b6Dcd3E5f4D420E3C1' - } else if (readNetwork.name === NetworkName.sepolia) { - contractJson = await import( - '@jbx-protocol/contracts-v2-latest/deployments/mainnet/JBPrices.json' - ) - contractJson.address = '0x6EF51C14045B386A0ae6374E48a9EeB928105ffb' - } else { - contractJson = await import( - '@jbx-protocol/contracts-v2-latest/deployments/mainnet/JBPrices.json' - ) - } - } - if (cv === CV_V3) { - if (readNetwork.name === NetworkName.sepolia) { - contractJson = await import( - '@jbx-protocol/juice-contracts-v3/deployments/sepolia/JBPrices.json' - ) - } else { - contractJson = await import( - '@jbx-protocol/juice-contracts-v3/deployments/mainnet/JBPrices.json' - ) - } + if (readNetwork.name === NetworkName.sepolia) { + contractJson = await import( + '@jbx-protocol/juice-contracts-v3/deployments/sepolia/JBPrices.json' + ) + } else { + contractJson = await import( + '@jbx-protocol/juice-contracts-v3/deployments/mainnet/JBPrices.json' + ) } if (!contractJson || !contractJson.address || !contractJson.abi) diff --git a/src/packages/v2v3/hooks/JBV3Token/contracts/JBV3TokenAbi.ts b/src/packages/v2v3/hooks/JBV3Token/contracts/JBV3TokenAbi.ts new file mode 100644 index 0000000000..a2ad7666d7 --- /dev/null +++ b/src/packages/v2v3/hooks/JBV3Token/contracts/JBV3TokenAbi.ts @@ -0,0 +1,662 @@ +export const abi = [ + { + inputs: [ + { + internalType: 'string', + name: '_name', + type: 'string', + }, + { + internalType: 'string', + name: '_symbol', + type: 'string', + }, + { + internalType: 'uint256', + name: '_projectId', + type: 'uint256', + }, + { + internalType: 'contract ITicketBooth', + name: '_v1TicketBooth', + type: 'address', + }, + { + internalType: 'contract IJBTokenStore', + name: '_v2TokenStore', + type: 'address', + }, + { + internalType: 'uint256', + name: '_v1ProjectId', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'BAD_PROJECT', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_projectId', + type: 'uint256', + }, + { + internalType: 'address', + name: '_spender', + type: 'address', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_account', + type: 'address', + }, + { + internalType: 'uint256', + name: '_projectId', + type: 'uint256', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_projectId', + type: 'uint256', + }, + { + internalType: 'address', + name: '_account', + type: 'address', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'subtractedValue', + type: 'uint256', + }, + ], + name: 'decreaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'addedValue', + type: 'uint256', + }, + ], + name: 'increaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_projectId', + type: 'uint256', + }, + { + internalType: 'address', + name: '_account', + type: 'address', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'nonces', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deadline', + type: 'uint256', + }, + { + internalType: 'uint8', + name: 'v', + type: 'uint8', + }, + { + internalType: 'bytes32', + name: 'r', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 's', + type: 'bytes32', + }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'projectId', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_projectId', + type: 'uint256', + }, + ], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_projectId', + type: 'uint256', + }, + { + internalType: 'address', + name: '_to', + type: 'address', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_projectId', + type: 'uint256', + }, + { + internalType: 'address', + name: '_from', + type: 'address', + }, + { + internalType: 'address', + name: '_to', + type: 'address', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'v1ProjectId', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'v1TicketBooth', + outputs: [ + { + internalType: 'contract ITicketBooth', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'v2TokenStore', + outputs: [ + { + internalType: 'contract IJBTokenStore', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const diff --git a/src/packages/v2v3/hooks/JBV3Token/contracts/useJBV3Token.ts b/src/packages/v2v3/hooks/JBV3Token/contracts/useJBV3Token.ts index 72755ac683..36f043a64b 100644 --- a/src/packages/v2v3/hooks/JBV3Token/contracts/useJBV3Token.ts +++ b/src/packages/v2v3/hooks/JBV3Token/contracts/useJBV3Token.ts @@ -1,5 +1,5 @@ -import JBV3TokenJson from '@jbx-protocol/juice-v3-migration/out/JBV3Token.sol/JBV3Token.json' import { Contract } from 'ethers' +import { abi } from './JBV3TokenAbi' import { useLoadContractFromAddress } from 'hooks/useLoadContractFromAddress' @@ -10,6 +10,6 @@ export function useJBV3Token({ }): Contract | undefined { return useLoadContractFromAddress({ address: tokenAddress, - abi: JBV3TokenJson.abi, + abi, }) } diff --git a/src/packages/v2v3/utils/contractLoaders/JuiceboxV2.ts b/src/packages/v2v3/utils/contractLoaders/JuiceboxV2.ts index 9965c99619..f4dff22707 100644 --- a/src/packages/v2v3/utils/contractLoaders/JuiceboxV2.ts +++ b/src/packages/v2v3/utils/contractLoaders/JuiceboxV2.ts @@ -27,55 +27,46 @@ const V2_CONTRACT_ABI_OVERRIDES: { }, JBOperatorStore: { addresses: { - [NetworkName.goerli]: '0x99dB6b517683237dE9C494bbd17861f3608F3585', [NetworkName.sepolia]: '0x8f63c744c0280ef4b32af1f821c65e0fd4150ab3', }, }, JBProjects: { addresses: { - [NetworkName.goerli]: '0x21263a042aFE4bAE34F08Bb318056C181bD96D3b', [NetworkName.sepolia]: '0x43CB8FCe4F0d61579044342A5d5A027aB7aE4D63', }, }, JBDirectory: { addresses: { - [NetworkName.goerli]: '0xeFA8232c90EB523AA4eAe5C0CA2Dd63b5bDC91a1', [NetworkName.sepolia]: '0x3B3Bd16cc76cd53218e00b600bFCa27aA5057794', }, }, JBFundingCycleStore: { addresses: { - [NetworkName.goerli]: '0xa0FbC1c00C6d9F9d0DD344245E05F7618530A748', [NetworkName.sepolia]: '0xCb881e166d527010B9eF11159b487f907040D7C4', }, }, JBTokenStore: { addresses: { - [NetworkName.goerli]: '0x03104e05412729B98151875Fd83d20A95334E5b1', [NetworkName.sepolia]: '0x25fdda0eBD9e979b8c1657780045Cf87392a14E4', }, }, JBSplitsStore: { addresses: { - [NetworkName.goerli]: '0x2293Dbbd37a2CC6bdba109429b91d8398b2CC11f', [NetworkName.sepolia]: '0xEdE89dB755855aF041b5f100B39db9324b5227Ac', }, }, JBController: { addresses: { - [NetworkName.goerli]: '0xE270E62137ceB784FCb1f47Ad7cA0Ba84Cc19d92', [NetworkName.sepolia]: '0x0c750ac5805AC3357b72554e3AE70840BBD09A98', }, }, JBSingleTokenPaymentTerminalStore: { addresses: { - [NetworkName.goerli]: '0x27c4640aF8d1B24f1353C5d112a30fCed19b4978', [NetworkName.sepolia]: '0x981c8ECD009E3E84eE1fF99266BF1461a12e5c68', }, }, JBETHPaymentTerminal: { addresses: { - [NetworkName.goerli]: '0x8E8d0C73ddee3819Aaa1A2943350012803Cb8AcE', [NetworkName.sepolia]: '0x55FF1D8093166c1fF9664efd613D8C543b95feFc', }, }, diff --git a/src/packages/v2v3/utils/contractLoaders/JuiceboxV3.ts b/src/packages/v2v3/utils/contractLoaders/JuiceboxV3.ts index 6640a9b47c..1c02e10db3 100644 --- a/src/packages/v2v3/utils/contractLoaders/JuiceboxV3.ts +++ b/src/packages/v2v3/utils/contractLoaders/JuiceboxV3.ts @@ -39,12 +39,12 @@ export const loadJuiceboxV3Contract = async ( )) as ContractJson break } - case V2V3ContractName.JBETHPaymentTerminal3_1_1: { - contractJson = (await import( - `@jbx-protocol/juice-contracts-v3/deployments/${network}/JBETHPaymentTerminal3_1_1.json` - )) as ContractJson - break - } + // case V2V3ContractName.JBETHPaymentTerminal3_1_1: { + // contractJson = (await import( + // `@jbx-protocol/juice-contracts-v3/deployments/${network}/JBETHPaymentTerminal3_1_1.json` + // )) as ContractJson + // break + // } case V2V3ContractName.JBETHPaymentTerminal3_1_2: { contractJson = (await import( `@jbx-protocol/juice-contracts-v3/deployments/${network}/JBETHPaymentTerminal3_1_2.json` @@ -99,12 +99,12 @@ export const loadJuiceboxV3Contract = async ( )) as ContractJson break } - case V2V3ContractName.JBSingleTokenPaymentTerminalStore3_1_1: { - contractJson = (await import( - `@jbx-protocol/juice-contracts-v3/deployments/${network}/JBSingleTokenPaymentTerminalStore3_1_1.json` - )) as ContractJson - break - } + // case V2V3ContractName.JBSingleTokenPaymentTerminalStore3_1_1: { + // contractJson = (await import( + // `@jbx-protocol/juice-contracts-v3/deployments/${network}/JBSingleTokenPaymentTerminalStore3_1_1.json` + // )) as ContractJson + // break + // } case V2V3ContractName.JBETHERC20ProjectPayerDeployer: { contractJson = (await import( `@jbx-protocol/juice-contracts-v3/deployments/${network}/JBETHERC20ProjectPayerDeployer.json` diff --git a/src/pages/api/juicebox/prices/ethusd.ts b/src/pages/api/juicebox/prices/ethusd.ts index ae638b0244..9e2a3b53d7 100644 --- a/src/pages/api/juicebox/prices/ethusd.ts +++ b/src/pages/api/juicebox/prices/ethusd.ts @@ -1,4 +1,3 @@ -import { CV_V3 } from 'constants/cv' import { WAD_DECIMALS } from 'constants/numbers' import { enableCors } from 'lib/api/nextjs' import { getLogger } from 'lib/logger' @@ -22,7 +21,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { } try { - const JBPrices = await loadJBPrices({ cv: CV_V3 }) + const JBPrices = await loadJBPrices() const priceRaw = await JBPrices?.priceFor( V2V3_CURRENCY_USD, V2V3_CURRENCY_ETH, diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index 49d4646b74..bb7218809f 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -12,6 +12,7 @@ import { wagmiConfig } from 'packages/v4/wagmiConfig' import React, { PropsWithChildren } from 'react' import { Provider } from 'react-redux' import { featureFlagEnabled } from 'utils/featureFlags' +import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' import { WagmiProvider } from 'wagmi' // This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. @@ -36,6 +37,25 @@ const _Wrapper: React.FC = ({ children }) => { return <>{children} } +export const getServerSideProps = globalGetServerSideProps + +export default function V4ProjectPage() { + const router = useRouter() + const { chainName, projectId } = router.query + if (!chainName || !projectId) { + return
Invalid URL
+ } + const chainId = chainNameMap[chainName as string] + + return ( + <_Wrapper> + + + + + ) +} + const Providers: React.FC< PropsWithChildren & { chainId: JBChainId; projectId: bigint } > = ({ chainId, projectId, children }) => { @@ -59,20 +79,3 @@ const Providers: React.FC< ) } - -export default function V4ProjectPage() { - const router = useRouter() - const { chainName, projectId } = router.query - if (!chainName || !projectId) { - return
Invalid URL
- } - const chainId = chainNameMap[chainName as string] - - return ( - <_Wrapper> - - - - - ) -} diff --git a/src/utils/featureFlags.ts b/src/utils/featureFlags.ts index c66bbf171b..a4a50769bb 100644 --- a/src/utils/featureFlags.ts +++ b/src/utils/featureFlags.ts @@ -6,7 +6,6 @@ import { NetworkName } from 'models/networkName' * [FEATURE_FLAGS.NFT_MP4]: { mainnet: true, - goerli: true, sepolia: true, } */ diff --git a/src/utils/juicecrowd.ts b/src/utils/juicecrowd.ts deleted file mode 100644 index 4f8bccbd07..0000000000 --- a/src/utils/juicecrowd.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { readNetwork } from 'constants/networks' -import { NetworkName } from 'models/networkName' - -export function getJuicecrowdUrl(projectId: number) { - // No sepolia support - const prefix = readNetwork.name === NetworkName.goerli ? 'goerli.' : '' - return `https://${prefix}juicecrowd.gg/p/${projectId}` -} diff --git a/yarn.lock b/yarn.lock index 16b0257563..455a0becf3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2572,11 +2572,6 @@ "@jbx-protocol/juice-contracts-v3" "^2.0.2" "@openzeppelin/contracts" "^4.8.0" -"@jbx-protocol/juice-v3-migration@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@jbx-protocol/juice-v3-migration/-/juice-v3-migration-1.0.0.tgz#008663d8e09005d19a4837d98b519a1058c9060a" - integrity sha512-+jmoiGcvVlbYrs510UDGWcUy7r2+pkhP+BI2ZqAjH4numZ7FWMvyRFjyaWLhzVHnKNZCSTUvvTIwU4wH5n6LSg== - "@jbx-protocol/project-handles@^2.0.5": version "2.0.5" resolved "https://registry.yarnpkg.com/@jbx-protocol/project-handles/-/project-handles-2.0.5.tgz#28b547e94546101275d4844990e1882962731bea" From 2aa2df96db4249055c2779c3545d303429c3ff95 Mon Sep 17 00:00:00 2001 From: Johnny D Date: Wed, 14 Aug 2024 22:28:31 +1000 Subject: [PATCH 10/46] fix: minor misalignment in payouts table (#4428) --- .../v2v3/components/shared/PayoutsTable/PayoutSplitRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/v2v3/components/shared/PayoutsTable/PayoutSplitRow.tsx b/src/packages/v2v3/components/shared/PayoutsTable/PayoutSplitRow.tsx index be17157b54..6b3074d0e1 100644 --- a/src/packages/v2v3/components/shared/PayoutsTable/PayoutSplitRow.tsx +++ b/src/packages/v2v3/components/shared/PayoutsTable/PayoutSplitRow.tsx @@ -117,7 +117,7 @@ export function PayoutSplitRow({
{currencyOrPercentSymbol} +
{currencyOrPercentSymbol}
} accessoryPosition="left" value={_value} From c5784d5bee391591977bdc4262a13220e49eab97 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Wed, 14 Aug 2024 21:54:01 +1000 Subject: [PATCH 11/46] move project event types to own file --- src/components/ActivityList.tsx | 9 +++-- src/hooks/useProjectEvents.ts | 34 ++----------------- src/models/projectEvents.ts | 31 +++++++++++++++++ .../V4ActivityPanel/ActivityOptions.tsx | 30 ++++++++-------- 4 files changed, 53 insertions(+), 51 deletions(-) create mode 100644 src/models/projectEvents.ts diff --git a/src/components/ActivityList.tsx b/src/components/ActivityList.tsx index 3539a197e9..bc1824fb8d 100644 --- a/src/components/ActivityList.tsx +++ b/src/components/ActivityList.tsx @@ -4,11 +4,11 @@ import { Button, Divider } from 'antd' import Loading from 'components/Loading' import { JuiceListbox } from 'components/inputs/JuiceListbox' import { PV_V1, PV_V2 } from 'constants/pv' +import { useProjectEvents } from 'hooks/useProjectEvents' import { ProjectEventFilter, ProjectEventsQueryArgs, - useProjectEvents, -} from 'hooks/useProjectEvents' +} from 'models/projectEvents' import { useMemo, useState } from 'react' import { AnyProjectEvent } from './activityEventElems/AnyProjectEvent' @@ -17,7 +17,10 @@ export interface ActivityOption { value: ProjectEventFilter } -export const ALL_OPT = (): ActivityOption => ({ label: t`All activity`, value: 'all' }) +export const ALL_OPT = (): ActivityOption => ({ + label: t`All activity`, + value: 'all', +}) const PV1_OPTS = (): ActivityOption[] => [ ALL_OPT(), diff --git a/src/hooks/useProjectEvents.ts b/src/hooks/useProjectEvents.ts index 0f35cc1c40..2a00370fa9 100644 --- a/src/hooks/useProjectEvents.ts +++ b/src/hooks/useProjectEvents.ts @@ -1,40 +1,10 @@ import { OrderDirection, ProjectEvent_OrderBy, - ProjectEventsQuery, - useProjectEventsQuery, + useProjectEventsQuery } from 'generated/graphql' import { client } from 'lib/apollo/client' -import { PV } from 'models/pv' - -export type ProjectEventFilter = - | 'all' - | keyof Pick< - ProjectEventsQuery['projectEvents'][number], - | 'addToBalanceEvent' - | 'burnEvent' - | 'configureEvent' - | 'deployedERC20Event' - | 'deployETHERC20ProjectPayerEvent' - | 'distributePayoutsEvent' - | 'distributeReservedTokensEvent' - | 'payEvent' - | 'printReservesEvent' - | 'projectCreateEvent' - | 'redeemEvent' - | 'setFundAccessConstraintsEvent' - | 'tapEvent' - | 'v1ConfigureEvent' - > - -export type ProjectEventsQueryArgs = { - filter?: ProjectEventFilter - pv?: PV - from?: string - projectId?: number - skip?: number - first?: number -} +import { ProjectEventsQueryArgs } from 'models/projectEvents' export function useProjectEvents({ filter, diff --git a/src/models/projectEvents.ts b/src/models/projectEvents.ts new file mode 100644 index 0000000000..f63e3eee0b --- /dev/null +++ b/src/models/projectEvents.ts @@ -0,0 +1,31 @@ +import { ProjectEventsQuery } from 'generated/graphql' +import { PV } from './pv' + +export type ProjectEventFilter = + | 'all' + | keyof Pick< + ProjectEventsQuery['projectEvents'][number], + | 'addToBalanceEvent' + | 'burnEvent' + | 'configureEvent' + | 'deployedERC20Event' + | 'deployETHERC20ProjectPayerEvent' + | 'distributePayoutsEvent' + | 'distributeReservedTokensEvent' + | 'payEvent' + | 'printReservesEvent' + | 'projectCreateEvent' + | 'redeemEvent' + | 'setFundAccessConstraintsEvent' + | 'tapEvent' + | 'v1ConfigureEvent' + > + +export type ProjectEventsQueryArgs = { + filter?: ProjectEventFilter + pv?: PV + from?: string + projectId?: number + skip?: number + first?: number +} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/ActivityOptions.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/ActivityOptions.tsx index e7179bd976..cb98f5847e 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/ActivityOptions.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/ActivityOptions.tsx @@ -1,12 +1,12 @@ -import { ArrowDownTrayIcon } from "@heroicons/react/24/outline" -import { t } from "@lingui/macro" -import { Button } from "antd" -import { ActivityOption, ALL_OPT } from "components/ActivityList" -import { JuiceListbox } from "components/inputs/JuiceListbox" -import { ProjectEventFilter } from "hooks/useProjectEvents" -import { useState } from "react" -import DownloadActivityModal from "./DownloadActivityModal" -import { ActivityEvents } from "./models/ActivityEvents" +import { ArrowDownTrayIcon } from '@heroicons/react/24/outline' +import { t } from '@lingui/macro' +import { Button } from 'antd' +import { ActivityOption, ALL_OPT } from 'components/ActivityList' +import { JuiceListbox } from 'components/inputs/JuiceListbox' +import { ProjectEventFilter } from 'models/projectEvents' +import { useState } from 'react' +import DownloadActivityModal from './DownloadActivityModal' +import { ActivityEvents } from './models/ActivityEvents' const activityOptions: ActivityOption[] = [ ALL_OPT(), @@ -30,18 +30,16 @@ const activityOptions: ActivityOption[] = [ // { label: t`Created project`, value: 'projectCreateEvent' }, ] -export function ActivityOptions({ - events -}: { - events: ActivityEvents -}) { +export function ActivityOptions({ events }: { events: ActivityEvents }) { const [eventFilter, setEventFilter] = useState('all') const [downloadModalVisible, setDownloadModalVisible] = useState() const activityOption = activityOptions.find(o => o.value === eventFilter) - - const hasAnyEvents = Object.values(events).some(eventArray => eventArray && eventArray.length > 0); + + const hasAnyEvents = Object.values(events).some( + eventArray => eventArray && eventArray.length > 0, + ) const canDownload = hasAnyEvents return ( From 2c6debf9fa31f8683ecc78f7653421debf5d6311 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Wed, 14 Aug 2024 22:10:44 +1000 Subject: [PATCH 12/46] Fix: v4 pay, v2v3 imports --- .../ReduxProjectCartProvider.tsx | 34 ++- .../V4PayRedeemCard/PayConfiguration.tsx | 15 +- .../components/ReceiveNftItem.tsx | 37 --- .../components/ReceiveSection.tsx | 8 - .../components/ReceiveTokensItem.tsx | 24 +- .../usePayProjectModal/usePayProjectModal.ts | 21 +- .../usePayProjectModal/usePayProjectTx.ts | 4 +- .../V4PayRedeemCard/PayRedeemInput.tsx | 2 +- .../V4PayRedeemCard/RedeemConfiguration.tsx | 225 ------------------ .../SuccessPayView/SuccessPayView.tsx | 4 - .../components/SuccessNftItem.tsx | 48 ---- .../components/SuccessPayCard.tsx | 4 +- .../components/SuccessTokensItem.tsx | 2 +- 13 files changed, 43 insertions(+), 385 deletions(-) delete mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx delete mode 100644 src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/RedeemConfiguration.tsx delete mode 100644 src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx diff --git a/src/packages/v4/components/ProjectDashboard/ReduxProjectCartProvider.tsx b/src/packages/v4/components/ProjectDashboard/ReduxProjectCartProvider.tsx index 4eb1cc3ff2..02816d4d59 100644 --- a/src/packages/v4/components/ProjectDashboard/ReduxProjectCartProvider.tsx +++ b/src/packages/v4/components/ProjectDashboard/ReduxProjectCartProvider.tsx @@ -1,14 +1,12 @@ import { useWallet } from 'hooks/Wallet' -import { NftRewardsContext } from 'packages/v2v3/contexts/NftRewards/NftRewardsContext' -import { useNftCredits } from 'packages/v2v3/hooks/JB721Delegate/useNftCredits' -import { V2V3CurrencyOption } from 'packages/v2v3/models/currencyOption' -import React, { useContext, useEffect } from 'react' +import { V4CurrencyOption } from 'packages/v4/models/v4CurrencyOption' +import React from 'react' import { useProjectDispatch } from './redux/hooks' -import { projectCartActions } from './redux/projectCartSlice' +// import { projectCartActions } from './redux/projectCartSlice' export type ProjectCartCurrencyAmount = { amount: number - currency: V2V3CurrencyOption + currency: V4CurrencyOption } export type ProjectCartNftReward = { @@ -22,26 +20,26 @@ export const ReduxProjectCartProvider = ({ }: { children: React.ReactNode }) => { - const { rewardTiers } = useContext(NftRewardsContext).nftRewards + // const { rewardTiers } = useContext(NftRewardsContext).nftRewards const { userAddress } = useWallet() - const userNftCredits = useNftCredits(userAddress) + // const userNftCredits = useNftCredits(userAddress) const dispatch = useProjectDispatch() // Set the nfts on load - useEffect(() => { - dispatch(projectCartActions.setAllNftRewards(rewardTiers ?? [])) - }, [dispatch, rewardTiers]) + // useEffect(() => { + // dispatch(projectCartActions.setAllNftRewards(rewardTiers ?? [])) + // }, [dispatch, rewardTiers]) // Set the user's NFT credits on load - useEffect(() => { - dispatch( - projectCartActions.setUserNftCredits( - userNftCredits.data?.toBigInt() ?? 0n, - ), - ) - }, [dispatch, userNftCredits.data]) + // useEffect(() => { + // dispatch( + // projectCartActions.setUserNftCredits( + // userNftCredits.data?.toBigInt() ?? 0n, + // ), + // ) + // }, [dispatch, userNftCredits.data]) return <>{children} } diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayConfiguration.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayConfiguration.tsx index 43207628f2..675d89d0f1 100644 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayConfiguration.tsx +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayConfiguration.tsx @@ -5,7 +5,7 @@ import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' import { useProjectLogoSrc } from 'hooks/useProjectLogoSrc' import { useWallet } from 'hooks/Wallet' import { useJBTokenContext } from 'juice-sdk-react' -import { usePayProjectDisabled } from 'packages/v2v3/hooks/usePayProjectDisabled' +// import { usePayProjectDisabled } from 'packages/v2v3/hooks/usePayProjectDisabled' import { V4_CURRENCY_ETH } from 'packages/v4/utils/currency' import { useCallback, useEffect, useMemo, useState } from 'react' import { @@ -29,7 +29,7 @@ export const PayConfiguration: React.FC = ({ projectHasErc20Token, isIssuingTokens, }) => { - const { payDisabled, message } = usePayProjectDisabled() + // const { payDisabled, message } = usePayProjectDisabled() const { token } = useJBTokenContext() const wallet = useWallet() const { isConnected: walletConnected, connect } = useWallet() @@ -95,15 +95,12 @@ export const PayConfiguration: React.FC = ({ } }, [store]) + // TODO include other 'pay disabled' logic, usePayProjectDisabled etc const payButtonDisabled = useMemo(() => { if (!walletConnected) return false - return ( - insufficientBalance || - cartPayAmount === 0 || - !cartPayAmount || - payDisabled - ) - }, [cartPayAmount, insufficientBalance, payDisabled, walletConnected]) + return insufficientBalance || cartPayAmount === 0 || !cartPayAmount + }, [cartPayAmount, insufficientBalance, walletConnected]) + const message = undefined return (
diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx deleted file mode 100644 index 5209e95a42..0000000000 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveNftItem.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Trans } from '@lingui/macro' -import { CartItemBadge } from 'components/CartItemBadge' -import { SmallNftSquare } from 'components/NftRewards/SmallNftSquare' -import { useNftCartItem } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useNftCartItem' -import { twMerge } from 'tailwind-merge' -import { ProjectCartNftReward } from '../../../ReduxProjectCartProvider' - -export const ReceiveNftItem = ({ - className, - nftReward, -}: { - className?: string - nftReward: ProjectCartNftReward -}) => { - const { fileUrl, name, quantity } = useNftCartItem(nftReward) - - return ( -
-
-
- - {name} - - NFT - -
-
{quantity}
-
-
- ) -} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx index fdb45559e5..4d0a946216 100644 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveSection.tsx @@ -6,7 +6,6 @@ import { } from '../hooks/usePayProjectModal/usePayProjectModal' import { useProjectPaymentTokens } from '../hooks/useProjectPaymentTokens' import { EditRewardBeneficiary } from './EditRewardBeneficiary' -import { ReceiveNftItem } from './ReceiveNftItem' import { ReceiveTokensItem } from './ReceiveTokensItem' export const ReceiveSection = ({ className }: { className?: string }) => { @@ -37,13 +36,6 @@ export const ReceiveSection = ({ className }: { className?: string }) => {
- {nftRewards.map(nftReward => ( - - ))}
) } diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx index 9b986bac6d..9b5bf7e33f 100644 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ReceiveTokensItem.tsx @@ -1,10 +1,9 @@ -import { Trans, t } from '@lingui/macro' +import { Trans } from '@lingui/macro' import { CartItemBadge } from 'components/CartItemBadge' import { ProjectHeaderLogo } from 'components/Project/ProjectHeader/ProjectHeaderLogo' -import TooltipIcon from 'components/TooltipIcon' import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' -import { useProjectHasErc20Token } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectHasErc20Token' -import { BUYBACK_DELEGATE_ENABLED_PROJECT_IDS } from 'packages/v2v3/constants/buybackDelegateEnabledProjectIds' +// import { useProjectHasErc20Token } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectHasErc20Token' +// import { BUYBACK_DELEGATE_ENABLED_PROJECT_IDS } from 'packages/v2v3/constants/buybackDelegateEnabledProjectIds' import { useContext } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPaymentTokens } from '../hooks/useProjectPaymentTokens' @@ -12,7 +11,8 @@ import { useProjectPaymentTokens } from '../hooks/useProjectPaymentTokens' export const ReceiveTokensItem = ({ className }: { className?: string }) => { const { projectId } = useContext(ProjectMetadataContext) const { receivedTickets, receivedTokenSymbolText } = useProjectPaymentTokens() - const projectHasErc20Token = useProjectHasErc20Token() + // const projectHasErc20Token = useProjectHasErc20Token() + const projectHasErc20Token = false const badgeTitle = projectHasErc20Token ? ( 'ERC-20' @@ -24,9 +24,6 @@ export const ReceiveTokensItem = ({ className }: { className?: string }) => { return null } - const buybackDelegateEnabled = - projectId && BUYBACK_DELEGATE_ENABLED_PROJECT_IDS.includes(projectId) - return (
@@ -39,16 +36,7 @@ export const ReceiveTokensItem = ({ className }: { className?: string }) => { {badgeTitle} Token
- {buybackDelegateEnabled ? ( -
- ≥ {receivedTickets}{' '} - -
- ) : ( -
{receivedTickets}
- )} +
{receivedTickets}
) diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts index d0ed9ee556..6d3538dbd0 100644 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectModal.ts @@ -4,17 +4,14 @@ import { useWallet } from 'hooks/Wallet' import { useCurrencyConverter } from 'hooks/useCurrencyConverter' import { NATIVE_TOKEN_DECIMALS } from 'juice-sdk-core' import { TxStatus } from 'models/transaction' -import { useProjectPageQueries } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPageQueries' import { useProjectDispatch, useProjectSelector, -} from 'packages/v2v3/components/V2V3Project/ProjectDashboard/redux/hooks' -import { projectCartActions } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/redux/projectCartSlice' -import { - V2V3_CURRENCY_ETH, - V2V3_CURRENCY_USD, -} from 'packages/v2v3/utils/currency' -import { formatCurrencyAmount } from 'packages/v2v3/utils/formatCurrencyAmount' +} from 'packages/v4/components/ProjectDashboard/redux/hooks' +import { projectCartActions } from 'packages/v4/components/ProjectDashboard/redux/projectCartSlice' +import { V4_CURRENCY_ETH, V4_CURRENCY_USD } from 'packages/v4/utils/currency' +import { formatCurrencyAmount } from 'packages/v4/utils/formatCurrencyAmount' +import { useProjectPageQueries } from 'packages/v4/views/V4ProjectDashboard/hooks/useProjectPageQueries' import { useCallback, useContext, useMemo, useReducer } from 'react' import { emitErrorNotification } from 'utils/notifications' import { formatEther, parseUnits } from 'viem' @@ -93,7 +90,7 @@ export const usePayProjectModal = () => { }) const primaryAmount = !payAmount - ? formatCurrencyAmount({ amount: 0, currency: V2V3_CURRENCY_ETH }) + ? formatCurrencyAmount({ amount: 0, currency: V4_CURRENCY_ETH }) : formatCurrencyAmount(payAmount) const secondaryAmount = useMemo(() => { @@ -101,7 +98,7 @@ export const usePayProjectModal = () => { return undefined } - if (payAmount.currency === V2V3_CURRENCY_ETH) { + if (payAmount.currency === V4_CURRENCY_ETH) { const amount = Number( converter.weiToUsd( parseUnits(payAmount.amount.toString(), NATIVE_TOKEN_DECIMALS), @@ -109,13 +106,13 @@ export const usePayProjectModal = () => { ) return formatCurrencyAmount({ amount, - currency: V2V3_CURRENCY_USD, + currency: V4_CURRENCY_USD, }) } return formatCurrencyAmount({ amount: formatEther(converter.usdToWei(payAmount.amount).toBigInt()), - currency: V2V3_CURRENCY_ETH, + currency: V4_CURRENCY_ETH, }) }, [converter, payAmount]) diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts index baa2aede9e..67d648d0dc 100644 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/hooks/usePayProjectModal/usePayProjectTx.ts @@ -12,7 +12,7 @@ import { useJBContractContext, useWriteJbMultiTerminalPay, } from 'juice-sdk-react' -import { useProjectHasErc20 } from 'packages/v2v3/hooks/useProjectHasErc20' +// import { useProjectHasErc20 } from 'packages/v2v3/hooks/useProjectHasErc20' import { V4_CURRENCY_ETH } from 'packages/v4/utils/currency' import { wagmiConfig } from 'packages/v4/wagmiConfig' import { useCallback, useContext, useMemo } from 'react' @@ -47,7 +47,7 @@ export const usePayProjectTx = ({ // } = useContext(NftRewardsContext) const converter = useCurrencyConverter() const { receivedTickets } = useProjectPaymentTokens() - const projectHasErc20 = useProjectHasErc20() + // const projectHasErc20 = useProjectHasErc20() const buildPayReceipt = useCallback( (txHash: Hash): ProjectPayReceipt => { diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayRedeemInput.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayRedeemInput.tsx index e26aa7641d..7afc137db8 100644 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayRedeemInput.tsx +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayRedeemInput.tsx @@ -2,8 +2,8 @@ import { ArrowDownIcon } from '@heroicons/react/24/outline' import { t } from '@lingui/macro' import { Tooltip } from 'antd' import { useCurrencyConverter } from 'hooks/useCurrencyConverter' -import { formatCurrencyAmount } from 'packages/v2v3/utils/formatCurrencyAmount' import { V4_CURRENCY_USD } from 'packages/v4/utils/currency' +import { formatCurrencyAmount } from 'packages/v4/utils/formatCurrencyAmount' import { ReactNode, useMemo } from 'react' import { twMerge } from 'tailwind-merge' import { formatAmount } from 'utils/format/formatAmount' diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/RedeemConfiguration.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/RedeemConfiguration.tsx deleted file mode 100644 index 93d988d914..0000000000 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/RedeemConfiguration.tsx +++ /dev/null @@ -1,225 +0,0 @@ -// import { CheckCircleIcon } from '@heroicons/react/24/outline' -// import { t, Trans } from '@lingui/macro' -// import { Button, Tooltip } from 'antd' -// import Loading from 'components/Loading' -// import { JuiceModal, JuiceModalProps } from 'components/modals/JuiceModal' -// import { PV_V2 } from 'constants/pv' -// import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' -// import { useProjectLogoSrc } from 'hooks/useProjectLogoSrc' -// import { useWallet } from 'hooks/Wallet' -// import { useJBTokenContext } from 'juice-sdk-react' -// import { useETHReceivedFromTokens } from 'packages/v2v3/hooks/contractReader/useETHReceivedFromTokens' -// import { useRedeemTokensTx } from 'packages/v2v3/hooks/transactor/useRedeemTokensTx' -// import { usePayoutLimit } from 'packages/v4/hooks/usePayoutLimit' -// import { V4_CURRENCY_USD } from 'packages/v4/utils/currency' -// import { useCallback, useMemo, useState } from 'react' -// import { formatAmount } from 'utils/format/formatAmount' -// import { fromWad, parseWad } from 'utils/format/formatNumber' -// import { emitErrorNotification } from 'utils/notifications' -// import { EthereumLogo } from './EthereumLogo' -// import { PayRedeemInput } from './PayRedeemInput' - -// type RedeemConfigurationProps = { -// userTokenBalance: number | undefined -// projectHasErc20Token: boolean -// } - -// export const RedeemConfiguration: React.FC = ({ -// userTokenBalance, -// projectHasErc20Token, -// }) => { -// const { token } = useJBTokenContext() -// const tokenSymbol = token?.data?.symbol -// const { data: payoutLimit } = usePayoutLimit() -// const { projectId, projectMetadata } = useProjectMetadataContext() -// const redeemTokensTx = useRedeemTokensTx() -// const wallet = useWallet() -// // TODO: We should probably break out tokens panel hook into reusable module -// const tokenLogo = useProjectLogoSrc({ -// projectId, -// pv: PV_V2, -// uri: projectMetadata?.logoUri, -// }) - -// const [redeemAmount, setRedeemAmount] = useState() -// const [fallbackImage, setFallbackImage] = useState() -// const [modalOpen, setModalOpen] = useState(false) -// const [redeeming, setRedeeming] = useState(false) - -// const ethReceivedFromTokens = useETHReceivedFromTokens({ -// tokenAmount: redeemAmount, -// }) - -// const tokenFromRedeemAmount = useMemo(() => { -// if (!redeemAmount) return '' -// return formatAmount(fromWad(ethReceivedFromTokens)) -// }, [ethReceivedFromTokens, redeemAmount]) - -// const insufficientBalance = useMemo(() => { -// if (!userTokenBalance) return false -// const amount = Number(redeemAmount || 0) -// const balance = userTokenBalance ?? 0 -// return amount > balance -// }, [redeemAmount, userTokenBalance]) -// const tokenTicker = tokenSymbol || 'TOKENS' - -// // 0.5% slippage for USD-denominated tokens -// const slippage = useMemo(() => { -// if (payoutLimit?.currency === V4_CURRENCY_USD) { -// return ethReceivedFromTokens?.mul(1000).div(1005) -// } -// return ethReceivedFromTokens -// }, [payoutLimit?.currency, ethReceivedFromTokens]) - -// const redeem = useCallback(async () => { -// if (!slippage) { -// emitErrorNotification('Failed to calculate slippage') -// return -// } -// setRedeeming(true) -// const txSuccess = await redeemTokensTx( -// { -// redeemAmount: parseWad(redeemAmount), -// minReturnedTokens: slippage, -// memo: '', -// }, -// { -// onDone: () => { -// setModalOpen(true) -// }, -// onConfirmed: () => { -// setRedeeming(false) -// }, -// onError: (e: Error) => { -// setRedeeming(false) -// setModalOpen(false) -// emitErrorNotification(e.message) -// }, -// }, -// ) -// if (!txSuccess) { -// setRedeeming(false) -// setModalOpen(false) -// } -// }, [redeemAmount, redeemTokensTx, slippage]) - -// return ( -// <> -//
-//
-//
-// -// {t`You redeem`} -// -// } -// token={{ -// balance: userTokenBalance?.toString(), -// image: -// tokenLogo && !fallbackImage ? ( -// Token logo setFallbackImage(true)} -// /> -// ) : ( -// '🧃' -// ), -// ticker: tokenTicker, -// type: projectHasErc20Token ? 'erc20' : 'native', -// }} -// value={redeemAmount} -// onChange={setRedeemAmount} -// /> -// , -// ticker: 'ETH', -// type: 'eth', -// }} -// value={tokenFromRedeemAmount} -// /> -//
-//
- -// -//
-// -// -// ) -// } - -// const RedeemModal: React.FC = ({ -// redeeming, -// ...props -// }) => { -// return ( -// -//
-// {redeeming ? ( -// <> -// -//

-// Redeeming tokens -//

-//
-// Your transaction is processing. -//
-//
-// You can safely close this modal. -//
-// -// ) : ( -// <> -//
-//
-// -//
-//
-//

-// Success! -//

-//
-// Your transaction was successful. -//
-//
-// You can safely close this modal. -//
-// -// )} - -// {/* View on block explorer */} -//
-//
-// ) -// } diff --git a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx index 89df9f0c2a..262db2a19d 100644 --- a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx +++ b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/SuccessPayView.tsx @@ -6,7 +6,6 @@ import dynamic from 'next/dynamic' import Link from 'next/link' import { v4ProjectRoute } from 'packages/v4/utils/routes' import { useChainId } from 'wagmi' -import { SuccessNftItem } from './components/SuccessNftItem' import { SuccessPayCard } from './components/SuccessPayCard' import { SuccessTokensItem } from './components/SuccessTokensItem' import { useSuccessPayView } from './hooks/useSuccessPayView' @@ -83,9 +82,6 @@ export const SuccessPayView = () => { Your NFTs & Rewards

- {projectPayReceipt?.nfts.map(({ id }) => ( - - ))}
diff --git a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx deleted file mode 100644 index 721976a3b4..0000000000 --- a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessNftItem.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { Trans } from '@lingui/macro' -import { CartItemBadge } from 'components/CartItemBadge' -import { NftPreview } from 'components/NftRewards/NftPreview' -import { SmallNftSquare } from 'components/NftRewards/SmallNftSquare' -import { NftRewardsContext } from 'packages/v2v3/contexts/NftRewards/NftRewardsContext' -import { useContext, useMemo, useState } from 'react' - -export const SuccessNftItem = ({ id }: { id: number }) => { - const { - nftRewards: { rewardTiers }, - } = useContext(NftRewardsContext) - const [previewVisible, setPreviewVisible] = useState(false) - - const openPreview = () => setPreviewVisible(true) - - const rewardTier = useMemo(() => { - if (!rewardTiers) return undefined - const nftReward = rewardTiers.find(reward => reward.id === id) - return nftReward - }, [id, rewardTiers]) - - return ( - <> -
- - - {rewardTier?.name ?? ''} - - - NFT - -
- {rewardTier && ( - - )} - - ) -} diff --git a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessPayCard.tsx b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessPayCard.tsx index 8a9532a62a..6d9ccdfdd4 100644 --- a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessPayCard.tsx +++ b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessPayCard.tsx @@ -5,8 +5,8 @@ import { ProjectHeaderLogo } from 'components/Project/ProjectHeader/ProjectHeade import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' import useMobile from 'hooks/useMobile' import moment from 'moment' -import { useProjectPageQueries } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPageQueries' -import { formatCurrencyAmount } from 'packages/v2v3/utils/formatCurrencyAmount' +import { formatCurrencyAmount } from 'packages/v4/utils/formatCurrencyAmount' +import { useProjectPageQueries } from 'packages/v4/views/V4ProjectDashboard/hooks/useProjectPageQueries' import { useMemo } from 'react' import { twMerge } from 'tailwind-merge' diff --git a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx index 4c5b987bb8..f694cdaa32 100644 --- a/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx +++ b/src/packages/v4/components/ProjectDashboard/components/SuccessPayView/components/SuccessTokensItem.tsx @@ -1,7 +1,7 @@ import { Trans } from '@lingui/macro' import { CartItemBadge } from 'components/CartItemBadge' import { ProjectHeaderLogo } from 'components/Project/ProjectHeader/ProjectHeaderLogo' -import { useProjectPageQueries } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useProjectPageQueries' +import { useProjectPageQueries } from 'packages/v4/views/V4ProjectDashboard/hooks/useProjectPageQueries' export const SuccessTokensItem = () => { const { projectPayReceipt } = useProjectPageQueries() From 54b5592935233feb22c14d46a8dfa8b519645ebb Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Wed, 14 Aug 2024 22:41:56 +1000 Subject: [PATCH 13/46] Nuke more v4, including volume chart etc --- .../ProjectHeader/ProjectHeaderPopupMenu.tsx | 9 +++---- .../v4/components/V4TokenHoldersModal.tsx | 23 +++++++++--------- .../v4/hooks/useV4WalletHasPermission.ts | 23 ++++++++++-------- .../V4ProjectDashboard/V4ProjectHeader.tsx | 8 +++---- .../V4ActivityPanel/V4ActivityList.tsx | 21 ++++++++-------- .../V4ActivityPanel/V4ActivityPanel.tsx | 7 +++--- .../V4TokensPanel/V4TokensPanel.tsx | 24 ++++++++++--------- 7 files changed, 60 insertions(+), 55 deletions(-) diff --git a/src/components/Project/ProjectHeader/ProjectHeaderPopupMenu.tsx b/src/components/Project/ProjectHeader/ProjectHeaderPopupMenu.tsx index ed3a82fe80..320c7b6a06 100644 --- a/src/components/Project/ProjectHeader/ProjectHeaderPopupMenu.tsx +++ b/src/components/Project/ProjectHeader/ProjectHeaderPopupMenu.tsx @@ -6,14 +6,15 @@ import { SubscribeButtonIcon } from 'components/buttons/SubscribeButton/Subscrib import { useSubscribeButton } from 'components/buttons/SubscribeButton/hooks/useSubscribeButton' import { PV_V2 } from 'constants/pv' import useMobile from 'hooks/useMobile' -import { SocialLink } from 'packages/v2v3/components/V2V3Project/ProjectDashboard/hooks/useAboutPanel' -import { V2V3ProjectToolsDrawer } from 'packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer' +// import { V2V3ProjectToolsDrawer } from 'packages/v2v3/components/V2V3Project/V2V3ProjectToolsDrawer' import { useMemo, useState } from 'react' import { twJoin } from 'tailwind-merge' import { PopupMenu } from '../../ui/PopupMenu' import { SocialLinkButton } from './SocialLinkButton' import { useSocialLinks } from './hooks/useSocialLinks' +type SocialLink = 'twitter' | 'discord' | 'telegram' | 'website' + export function ProjectHeaderPopupMenu({ className, projectId, @@ -110,10 +111,10 @@ export function ProjectHeaderPopupMenu({ ]} /> - setToolsIsOpen(false)} - /> + /> */} ) } diff --git a/src/packages/v4/components/V4TokenHoldersModal.tsx b/src/packages/v4/components/V4TokenHoldersModal.tsx index ab9cf07315..798980d654 100644 --- a/src/packages/v4/components/V4TokenHoldersModal.tsx +++ b/src/packages/v4/components/V4TokenHoldersModal.tsx @@ -1,5 +1,5 @@ -import { BigNumber } from '@ethersproject/bignumber' -import ParticipantsModal from 'components/modals/ParticipantsModal' +// import { BigNumber } from '@ethersproject/bignumber' +// import ParticipantsModal from 'components/modals/ParticipantsModal' import useNameOfERC20 from 'hooks/ERC20/useNameOfERC20' import { useReadJbTokensTokenOf } from 'juice-sdk-react' import { useV4TotalTokenSupply } from '../hooks/useV4TotalTokenSupply' @@ -15,13 +15,14 @@ export const V4TokenHoldersModal = ({ const { data: tokenSymbol } = useNameOfERC20(tokenAddress) const { data: totalTokenSupply } = useV4TotalTokenSupply() - return ( - - ) + return null + // return ( + // + // ) } diff --git a/src/packages/v4/hooks/useV4WalletHasPermission.ts b/src/packages/v4/hooks/useV4WalletHasPermission.ts index 866b46b1d1..f68045fd1b 100644 --- a/src/packages/v4/hooks/useV4WalletHasPermission.ts +++ b/src/packages/v4/hooks/useV4WalletHasPermission.ts @@ -1,7 +1,10 @@ -import * as constants from '@ethersproject/constants' import { useWallet } from 'hooks/Wallet' -import { useJBContractContext, useReadJbPermissionsHasPermissions } from 'juice-sdk-react' +import { + useJBContractContext, + useReadJbPermissionsHasPermissions, +} from 'juice-sdk-react' import { isEqualAddress } from 'utils/address' +import { zeroAddress } from 'viem' import { V4OperatorPermission } from '../models/v4Permissions' import useProjectOwnerOf from './useV4ProjectOwnerOf' @@ -13,16 +16,16 @@ export function useV4WalletHasPermission( const { projectId } = useJBContractContext() const { data: projectOwnerAddress } = useProjectOwnerOf() - const _operator = userAddress ?? constants.AddressZero - const _account = projectOwnerAddress ?? constants.AddressZero + const _operator = userAddress ?? zeroAddress + const _account = projectOwnerAddress ?? zeroAddress const hasOperatorPermission = useReadJbPermissionsHasPermissions({ args: [ - _operator, - _account, - projectId, - [BigInt(permission.toString())], - true, - true + _operator, + _account, + projectId, + [BigInt(permission.toString())], + true, + true, ], }) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx index b4e8431443..6877ea3a70 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx @@ -8,7 +8,7 @@ import { useSocialLinks } from 'components/Project/ProjectHeader/hooks/useSocial import { ProjectHeaderLogo } from 'components/Project/ProjectHeader/ProjectHeaderLogo' import { ProjectHeaderPopupMenu } from 'components/Project/ProjectHeader/ProjectHeaderPopupMenu' import { SocialLinkButton } from 'components/Project/ProjectHeader/SocialLinkButton' -import { Subtitle } from 'components/Project/ProjectHeader/Subtitle' +// import { Subtitle } from 'components/Project/ProjectHeader/Subtitle' import { TruncatedText } from 'components/TruncatedText' import useMobile from 'hooks/useMobile' import Link from 'next/link' @@ -110,9 +110,9 @@ export const V4ProjectHeader = ({ className }: { className?: string }) => { className="text-grey-700 dark:text-slate-50 md:text-lg" text={subtitle.text} /> - ) : ( - - ))} + ) : null) + // + }
{projectId ? (

Activity

-
@@ -51,7 +50,7 @@ export function V4ActivityList() { className="mb-5 border-b border-smoke-200 pb-5 dark:border-grey-600" key={event.id} > - } - /> + /> */}
) }) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx index 1db9dacbc6..292c032e70 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx @@ -2,8 +2,7 @@ import { Trans } from '@lingui/macro' import { ErrorBoundaryCallout } from 'components/Callout/ErrorBoundaryCallout' import Loading from 'components/Loading' -import VolumeChart from 'components/VolumeChart' -import { PV_V4 } from 'constants/pv' +// import VolumeChart from 'components/VolumeChart' import { useJBContractContext } from 'juice-sdk-react' import { ProjectsDocument } from 'packages/v4/graphql/client/graphql' import { useSubgraphQuery } from 'packages/v4/graphql/useSubgraphQuery' @@ -31,12 +30,12 @@ export function V4ActivityPanel() { Volume chart failed to load.} > - + /> */}
diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4TokensPanel.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4TokensPanel.tsx index 9e86976584..0eff7023aa 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4TokensPanel.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4TokensPanel.tsx @@ -7,11 +7,9 @@ import { TitleDescriptionDisplayCard } from 'components/Project/ProjectTabs/Titl // import { ReservedTokensSubPanel } from './components/ReservedTokensSubPanel' // import { TokenRedemptionCallout } from './components/TokenRedemptionCallout' // import { TransferUnclaimedTokensModalWrapper } from './components/TransferUnclaimedTokensModalWrapper' -import { AddTokenToMetamaskButton } from 'components/buttons/AddTokenToMetamaskButton' -import { IssueErc20TokenButton } from 'components/buttons/IssueErc20TokenButton' +// import { IssueErc20TokenButton } from 'components/buttons/IssueErc20TokenButton' import { V4TokenHoldersModal } from 'packages/v4/components/V4TokenHoldersModal' import { useCallback, useState } from 'react' -import { reloadWindow } from 'utils/windowUtils' import { useV4TokensPanel } from './hooks/useV4TokensPanel' import { useV4YourBalanceMenuItems } from './hooks/useV4YourBalanceMenuItems' import { V4ReservedTokensSubPanel } from './V4ReservedTokensSubPanel' @@ -58,7 +56,7 @@ export const V4TokensPanel = () => { {/* */} -
+
{!userTokenBalanceLoading && userTokenBalance !== undefined && ( {
} - kebabMenu={userTokenBalance.value > 0n ? { - items - } : undefined} + kebabMenu={ + userTokenBalance.value > 0n + ? { + items, + } + : undefined + } /> )} @@ -183,15 +185,15 @@ const ProjectTokenCard = () => { )}
- {projectTokenAddress && projectHasErc20Token && ( + {/* {projectTokenAddress && projectHasErc20Token && ( - )} - {canCreateErc20Token && ( + )} */} + {/* {canCreateErc20Token && ( - )} + )} */} } /> From 0e74e479a0917bca2ae62e3b7b181d79b70e7138 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Wed, 14 Aug 2024 22:59:28 +1000 Subject: [PATCH 14/46] maybe fix --- .../V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx index f88a7c5575..823b1c5f60 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx @@ -2,13 +2,17 @@ import { Tab } from '@headlessui/react' import { t } from '@lingui/macro' import { ProjectTab } from 'components/Project/ProjectTabs/ProjectTab' import { useOnScreen } from 'hooks/useOnScreen' +import dynamic from 'next/dynamic' import { Fragment, useEffect, useMemo, useRef, useState } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPageQueries } from '../hooks/useProjectPageQueries' import V4AboutPanel from './V4AboutPanel' -import { V4ActivityPanel } from './V4ActivityPanel/V4ActivityPanel' import { V4CyclesPayoutsPanel } from './V4CyclesPayoutsPanel/V4CyclesPayoutsPanel' import { V4TokensPanel } from './V4TokensPanel/V4TokensPanel' +const V4ActivityPanel = dynamic( + () => import('./V4ActivityPanel/V4ActivityPanel'), + { ssr: false }, +) type ProjectTabConfig = { id: string @@ -45,7 +49,7 @@ export const V4ProjectTabs = ({ className }: { className?: string }) => { const tabs: ProjectTabConfig[] = useMemo( () => [ - { id: 'activity', name: t`Activity`, panel: }, + // { id: 'activity', name: t`Activity`, panel: }, { id: 'about', name: t`About`, panel: }, { id: 'cycle_payouts', From 798d749ce915e940de36b37eebf8913b20f0b4c5 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:03:46 +1000 Subject: [PATCH 15/46] dynamically load v4 project tabs --- .../V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx | 2 +- .../v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx index 292c032e70..ac9e9d5de8 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx @@ -9,7 +9,7 @@ import { useSubgraphQuery } from 'packages/v4/graphql/useSubgraphQuery' import { Suspense } from 'react' import { V4ActivityList } from './V4ActivityList' -export function V4ActivityPanel() { +export default function V4ActivityPanel() { const { projectId } = useJBContractContext() const { data } = useSubgraphQuery({ document: ProjectsDocument, diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx index 823b1c5f60..e9080c447c 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx @@ -49,7 +49,7 @@ export const V4ProjectTabs = ({ className }: { className?: string }) => { const tabs: ProjectTabConfig[] = useMemo( () => [ - // { id: 'activity', name: t`Activity`, panel: }, + { id: 'activity', name: t`Activity`, panel: }, { id: 'about', name: t`About`, panel: }, { id: 'cycle_payouts', From f631e7b1e673ebe93018a93e2baa6468f281271f Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:13:46 +1000 Subject: [PATCH 16/46] DYnamically load v4projectdash --- .../V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx | 6 +----- src/pages/v4/[chainName]/p/[projectId]/index.tsx | 10 ++++++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx index e9080c447c..f88a7c5575 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx @@ -2,17 +2,13 @@ import { Tab } from '@headlessui/react' import { t } from '@lingui/macro' import { ProjectTab } from 'components/Project/ProjectTabs/ProjectTab' import { useOnScreen } from 'hooks/useOnScreen' -import dynamic from 'next/dynamic' import { Fragment, useEffect, useMemo, useRef, useState } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPageQueries } from '../hooks/useProjectPageQueries' import V4AboutPanel from './V4AboutPanel' +import { V4ActivityPanel } from './V4ActivityPanel/V4ActivityPanel' import { V4CyclesPayoutsPanel } from './V4CyclesPayoutsPanel/V4CyclesPayoutsPanel' import { V4TokensPanel } from './V4TokensPanel/V4TokensPanel' -const V4ActivityPanel = dynamic( - () => import('./V4ActivityPanel/V4ActivityPanel'), - { ssr: false }, -) type ProjectTabConfig = { id: string diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index bb7218809f..f35170abf3 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -2,19 +2,25 @@ import { AppWrapper } from 'components/common/CoreAppWrapper/CoreAppWrapper' import { FEATURE_FLAGS } from 'constants/featureFlags' import { OPEN_IPFS_GATEWAY_HOSTNAME } from 'constants/ipfs' import { JBChainId, JBProjectProvider } from 'juice-sdk-react' +import dynamic from 'next/dynamic' import { useRouter } from 'next/router' import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' import store from 'packages/v4/components/ProjectDashboard/redux/store' import V4ProjectMetadataProvider from 'packages/v4/contexts/V4ProjectMetadataProvider' import { chainNameMap } from 'packages/v4/utils/networks' -import { V4ProjectDashboard } from 'packages/v4/views/V4ProjectDashboard/V4ProjectDashboard' import { wagmiConfig } from 'packages/v4/wagmiConfig' import React, { PropsWithChildren } from 'react' import { Provider } from 'react-redux' import { featureFlagEnabled } from 'utils/featureFlags' import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' import { WagmiProvider } from 'wagmi' - +const V4ProjectDashboard = dynamic( + () => + import('packages/v4/views/V4ProjectDashboard/V4ProjectDashboard').then( + m => m.V4ProjectDashboard, + ), + { ssr: false }, +) // This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. const _Wrapper: React.FC = ({ children }) => { const [hasMounted, setHasMounted] = React.useState(false) From 94ccfcfd94b031c08ad1eb2fddd34708fca6b994 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:17:16 +1000 Subject: [PATCH 17/46] fix thing --- src/packages/v4/contexts/V4ProjectMetadataProvider.tsx | 6 +----- .../V4ProjectTabs/V4ActivityPanel/V4ActivityPanel.tsx | 9 ++++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/packages/v4/contexts/V4ProjectMetadataProvider.tsx b/src/packages/v4/contexts/V4ProjectMetadataProvider.tsx index 636b8701d1..9841567941 100644 --- a/src/packages/v4/contexts/V4ProjectMetadataProvider.tsx +++ b/src/packages/v4/contexts/V4ProjectMetadataProvider.tsx @@ -2,7 +2,6 @@ import { PV_V4 } from 'constants/pv' import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' import { useJBProjectMetadataContext } from 'juice-sdk-react' import { PropsWithChildren } from 'react' -import { isHardArchived } from 'utils/archived' export default function V4ProjectMetadataProvider({ projectId, @@ -16,10 +15,7 @@ export default function V4ProjectMetadataProvider({ const projectMetadata = metadata?.data ?? undefined - const isArchived = - ((_projectId && isHardArchived({ pv: PV_V4, projectId: _projectId })) || - projectMetadata?.archived) ?? - false + const isArchived = false return ( Date: Wed, 14 Aug 2024 23:40:19 +1000 Subject: [PATCH 18/46] ci From c9091d005d01fbcbfb6a5155b3ef69806c7194d8 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:57:00 +1000 Subject: [PATCH 19/46] idk --- .../v4/[chainName]/p/[projectId]/index.tsx | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index f35170abf3..57818aef38 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -2,6 +2,8 @@ import { AppWrapper } from 'components/common/CoreAppWrapper/CoreAppWrapper' import { FEATURE_FLAGS } from 'constants/featureFlags' import { OPEN_IPFS_GATEWAY_HOSTNAME } from 'constants/ipfs' import { JBChainId, JBProjectProvider } from 'juice-sdk-react' +import { loadCatalog } from 'locales/utils' +import { GetStaticPaths, GetStaticProps } from 'next' import dynamic from 'next/dynamic' import { useRouter } from 'next/router' import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' @@ -12,7 +14,6 @@ import { wagmiConfig } from 'packages/v4/wagmiConfig' import React, { PropsWithChildren } from 'react' import { Provider } from 'react-redux' import { featureFlagEnabled } from 'utils/featureFlags' -import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' import { WagmiProvider } from 'wagmi' const V4ProjectDashboard = dynamic( () => @@ -21,6 +22,29 @@ const V4ProjectDashboard = dynamic( ), { ssr: false }, ) + +export const getStaticPaths: GetStaticPaths = async () => { + return { + paths: [], + fallback: 'blocking', + } +} + +export const getStaticProps: GetStaticProps<{ + i18n: unknown +}> = async context => { + const locale = context.locale as string + const messages = await loadCatalog(locale) + const i18n = { locale, messages } + + return { + props: { + i18n, + }, + revalidate: 10, // 10 seconds https://nextjs.org/docs/api-reference/data-fetching/get-static-props#revalidate + } +} + // This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. const _Wrapper: React.FC = ({ children }) => { const [hasMounted, setHasMounted] = React.useState(false) @@ -43,8 +67,6 @@ const _Wrapper: React.FC = ({ children }) => { return <>{children} } -export const getServerSideProps = globalGetServerSideProps - export default function V4ProjectPage() { const router = useRouter() const { chainName, projectId } = router.query @@ -70,12 +92,12 @@ const Providers: React.FC< - + {children} From 0910eca3ded9175f11096439548ee6902e9b1b2f Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Thu, 15 Aug 2024 07:24:01 +1000 Subject: [PATCH 20/46] Re add activity list --- .../ActivityElement/ActivityElement.tsx | 5 +- .../v1/components/shared/PayoutModsList.tsx | 2 +- .../v1/components/shared/TicketModsList.tsx | 2 +- .../components/shared/forms/PayModsForm.tsx | 17 +-- src/packages/v1/utils/csv.ts | 56 +++++++++ .../PayoutsSettingsPage/V2V3EditPayouts.tsx | 2 +- .../V2V3EditReservedTokens.tsx | 2 +- src/packages/v2v3/utils/csv.ts | 51 +++++++++ .../V4ActivityPanel/V4ActivityList.tsx | 16 ++- src/utils/csv.ts | 107 ------------------ 10 files changed, 130 insertions(+), 130 deletions(-) create mode 100644 src/packages/v1/utils/csv.ts create mode 100644 src/packages/v2v3/utils/csv.ts diff --git a/src/components/activityEventElems/ActivityElement/ActivityElement.tsx b/src/components/activityEventElems/ActivityElement/ActivityElement.tsx index 3a9abe833f..8d7f670a65 100644 --- a/src/components/activityEventElems/ActivityElement/ActivityElement.tsx +++ b/src/components/activityEventElems/ActivityElement/ActivityElement.tsx @@ -1,3 +1,5 @@ +import { Tooltip } from 'antd' +import EthereumAddress from 'components/EthereumAddress' import EtherscanLink from 'components/EtherscanLink' import { JuiceboxAccountLink } from 'components/JuiceboxAccountLink' import { PV_V2 } from 'constants/pv' @@ -5,9 +7,6 @@ import { PV } from 'models/pv' import V1ProjectHandle from 'packages/v1/components/shared/V1ProjectHandle' import V2V3ProjectHandleLink from 'packages/v2v3/components/shared/V2V3ProjectHandleLink' import { formatHistoricalDate } from 'utils/format/formatDate' - -import { Tooltip } from 'antd' -import EthereumAddress from 'components/EthereumAddress' import { ActivityElementEvent } from './activityElementEvent' const FromBeneficiary = ({ diff --git a/src/packages/v1/components/shared/PayoutModsList.tsx b/src/packages/v1/components/shared/PayoutModsList.tsx index f096bb596b..195c355f06 100644 --- a/src/packages/v1/components/shared/PayoutModsList.tsx +++ b/src/packages/v1/components/shared/PayoutModsList.tsx @@ -14,6 +14,7 @@ import { V1CurrencyOption } from 'packages/v1/models/currencyOption' import { V1FundingCycle } from 'packages/v1/models/fundingCycle' import { PayoutMod } from 'packages/v1/models/mods' import { V1OperatorPermission } from 'packages/v1/models/permissions' +import { parseV1PayoutModsCsv } from 'packages/v1/utils/csv' import { V1CurrencyName } from 'packages/v1/utils/currency' import { amountSubFee } from 'packages/v1/utils/math' import { MODS_TOTAL_PERCENT } from 'packages/v1/utils/mods' @@ -24,7 +25,6 @@ import { useMemo, useState, } from 'react' -import { parseV1PayoutModsCsv } from 'utils/csv' import { formatWad, fromWad, diff --git a/src/packages/v1/components/shared/TicketModsList.tsx b/src/packages/v1/components/shared/TicketModsList.tsx index 92181afd45..bf86edadd6 100644 --- a/src/packages/v1/components/shared/TicketModsList.tsx +++ b/src/packages/v1/components/shared/TicketModsList.tsx @@ -10,6 +10,7 @@ import { useSetTicketModsTx } from 'packages/v1/hooks/transactor/useSetTicketMod import { V1FundingCycle } from 'packages/v1/models/fundingCycle' import { TicketMod } from 'packages/v1/models/mods' import { V1OperatorPermission } from 'packages/v1/models/permissions' +import { parseV1TicketModsCsv } from 'packages/v1/utils/csv' import { MODS_TOTAL_PERCENT } from 'packages/v1/utils/mods' import { useCallback, @@ -18,7 +19,6 @@ import { useMemo, useState, } from 'react' -import { parseV1TicketModsCsv } from 'utils/csv' import { formatWad, permyriadToPercent } from 'utils/format/formatNumber' import { tokenSymbolText } from 'utils/tokenSymbolText' export default function TicketModsList({ diff --git a/src/packages/v1/components/shared/forms/PayModsForm.tsx b/src/packages/v1/components/shared/forms/PayModsForm.tsx index bd1df4294c..665501dcf8 100644 --- a/src/packages/v1/components/shared/forms/PayModsForm.tsx +++ b/src/packages/v1/components/shared/forms/PayModsForm.tsx @@ -2,21 +2,16 @@ import { t, Trans } from '@lingui/macro' import { Button, Form, Input, Space } from 'antd' import { useForm } from 'antd/lib/form/Form' -import { BigNumber } from 'ethers' +import { getTotalPercentage } from 'components/formItems/formHelpers' +import { CsvUpload } from 'components/inputs/CsvUpload' +import { CurrencyContext } from 'contexts/CurrencyContext' +import { BigNumber, constants } from 'ethers' +import ProjectPayoutMods from 'packages/v1/components/shared/ProjectPayMods/ProjectPayoutMods' import { V1CurrencyOption } from 'packages/v1/models/currencyOption' import { PayoutMod } from 'packages/v1/models/mods' +import { parseV1PayoutModsCsv } from 'packages/v1/utils/csv' import { useContext, useLayoutEffect, useState } from 'react' import { fromWad, perbicentToPercent } from 'utils/format/formatNumber' - -import { getTotalPercentage } from 'components/formItems/formHelpers' -import { CurrencyContext } from 'contexts/CurrencyContext' -import ProjectPayoutMods from 'packages/v1/components/shared/ProjectPayMods/ProjectPayoutMods' - -import { CsvUpload } from 'components/inputs/CsvUpload' -import { constants } from 'ethers' - -import { parseV1PayoutModsCsv } from 'utils/csv' - export default function PayModsForm({ initialMods, currency, diff --git a/src/packages/v1/utils/csv.ts b/src/packages/v1/utils/csv.ts new file mode 100644 index 0000000000..7d17b19eb4 --- /dev/null +++ b/src/packages/v1/utils/csv.ts @@ -0,0 +1,56 @@ +import { BigNumber } from 'ethers' +import { percentToPermyriad } from 'utils/format/formatNumber' +import { PayoutMod, TicketMod } from '../models/mods' + +const parseBoolean = (rawBoolean: string): boolean => { + try { + return JSON.parse(rawBoolean) + } catch (e) { + return false + } +} + +export const parseV1PayoutModsCsv = (csvContent: string): PayoutMod[] => { + const [, ...rows] = csvContent.split('\n') + + const payoutMods: PayoutMod[] = rows.map(row => { + const [ + beneficiary, + percent, + preferUnstaked, + lockedUntil, + projectId, + allocator, + ] = row.split(',') + + const payoutMod: PayoutMod = { + beneficiary, + percent: percentToPermyriad(parseFloat(percent) * 100).toNumber(), + preferUnstaked: parseBoolean(preferUnstaked), + lockedUntil: lockedUntil ? parseInt(lockedUntil) : undefined, + projectId: projectId ? BigNumber.from(projectId) : undefined, + allocator, + } + + return payoutMod + }) + + return payoutMods +} + +export const parseV1TicketModsCsv = (csvContent: string): TicketMod[] => { + const [, ...rows] = csvContent.split('\n') + + const ticketMods: TicketMod[] = rows.map(row => { + const [beneficiary, percent, preferUnstaked, lockedUntil] = row.split(',') + + return { + preferUnstaked: Boolean(preferUnstaked), + percent: percentToPermyriad(parseFloat(percent) * 100).toNumber(), + lockedUntil: lockedUntil ? parseInt(lockedUntil) : undefined, + beneficiary: beneficiary || undefined, + } + }) + + return ticketMods +} diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/PayoutsSettingsPage/V2V3EditPayouts.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/PayoutsSettingsPage/V2V3EditPayouts.tsx index 0e19051f9b..d7d2c8b16f 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/PayoutsSettingsPage/V2V3EditPayouts.tsx +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/PayoutsSettingsPage/V2V3EditPayouts.tsx @@ -17,10 +17,10 @@ import { import { OwnerPayoutCard } from 'packages/v2v3/components/shared/PayoutCard/OwnerPayoutCard' import { PayoutCard } from 'packages/v2v3/components/shared/PayoutCard/PayoutCard' import { V2V3CurrencyOption } from 'packages/v2v3/models/currencyOption' +import { parseV2SplitsCsv } from 'packages/v2v3/utils/csv' import { isInfiniteDistributionLimit } from 'packages/v2v3/utils/fundingCycle' import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' import { twMerge } from 'tailwind-merge' -import { parseV2SplitsCsv } from 'utils/csv' import { formatFundingTarget } from 'utils/format/formatFundingTarget' import { formatPercent } from 'utils/format/formatPercent' import { settingsPagePath } from 'utils/routes' diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/ReservedTokensSettingsPage/V2V3EditReservedTokens.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/ReservedTokensSettingsPage/V2V3EditReservedTokens.tsx index 1209a124ea..bae1398453 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/ReservedTokensSettingsPage/V2V3EditReservedTokens.tsx +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/ReservedTokensSettingsPage/V2V3EditReservedTokens.tsx @@ -4,9 +4,9 @@ import { CsvUpload } from 'components/inputs/CsvUpload' import { AllocationSplit } from 'packages/v2v3/components/shared/Allocation/Allocation' import { ReservedTokensList } from 'packages/v2v3/components/shared/ReservedTokensList' import { Split } from 'packages/v2v3/models/splits' +import { parseV2SplitsCsv } from 'packages/v2v3/utils/csv' import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' import { useCallback } from 'react' -import { parseV2SplitsCsv } from 'utils/csv' export function V2V3EditReservedTokens({ editingReservedTokensSplits, diff --git a/src/packages/v2v3/utils/csv.ts b/src/packages/v2v3/utils/csv.ts new file mode 100644 index 0000000000..761bbb1237 --- /dev/null +++ b/src/packages/v2v3/utils/csv.ts @@ -0,0 +1,51 @@ +import { getAddress } from 'viem' +import { Split } from '../models/splits' +import { splitPercentFrom } from './math' + +/** + * Parse a CSV file containing JB Splits. + * @param csvContent - raw CSV content, including a header row. + * @returns array of Split objects + */ +export const parseV2SplitsCsv = (csvContent: string): Split[] => { + // Skip the header row (the first row in the CSV file). + const [, ...rows] = csvContent.split('\n') + + const splits: Split[] = rows.map(row => { + const [ + beneficiary, + percent, + preferClaimed, + lockedUntil, + projectId, + allocator, + ] = row.split(',') + + return { + beneficiary: beneficiary ? getAddress(beneficiary) : undefined, + percent: splitPercentFrom(parseFloat(percent) * 100).toNumber(), + preferClaimed: Boolean(preferClaimed), + lockedUntil: lockedUntil ? parseInt(lockedUntil) : undefined, + projectId: projectId?.trim() || undefined, + allocator: allocator ? getAddress(allocator.trim()) : undefined, + } + }) + + if (splits.some(split => split.percent === 0)) { + throw new Error('CSV contains splits with 0% percent.') + } + + // find duplicates + const duplicateBeneficiaries = splits + .map(split => split.beneficiary) + .filter((beneficiary, index, self) => self.indexOf(beneficiary) !== index) + if (duplicateBeneficiaries.length > 0) { + throw new Error( + `CSV contains multiple splits for the same beneficiary: ${duplicateBeneficiaries.join( + ', ', + )}`, + ) + } + + return splits +} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx index f1d654c19e..678a0dbb57 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx @@ -1,6 +1,11 @@ -// import { ActivityEvent } from 'components/activityEventElems/ActivityElement/ActivityElement' +import { t } from '@lingui/macro' +import { ActivityEvent } from 'components/activityEventElems/ActivityElement/ActivityElement' import Loading from 'components/Loading' -import { useJBContractContext, useJBTokenContext } from 'juice-sdk-react' +import { + NativeTokenValue, + useJBContractContext, + useJBTokenContext, +} from 'juice-sdk-react' import { OrderDirection, PayEvent_OrderBy, @@ -50,7 +55,7 @@ export function V4ActivityList() { className="mb-5 border-b border-smoke-200 pb-5 dark:border-grey-600" key={event.id} > - {/* - bought {event.beneficiaryTokenCount?.format(6)} {token.data?.symbol} + bought {event.beneficiaryTokenCount?.format(6)}{' '} + {token.data?.symbol} } - /> */} + /> ) }) diff --git a/src/utils/csv.ts b/src/utils/csv.ts index d1c1da0026..5dc143782b 100644 --- a/src/utils/csv.ts +++ b/src/utils/csv.ts @@ -1,9 +1,3 @@ -import { BigNumber } from 'ethers' -import { getAddress } from 'ethers/lib/utils' -import { PayoutMod, TicketMod } from 'packages/v1/models/mods' -import { Split } from 'packages/v2v3/models/splits' -import { splitPercentFrom } from 'packages/v2v3/utils/math' -import { percentToPermyriad } from './format/formatNumber' export function downloadCsvFile( filename: string, @@ -21,104 +15,3 @@ export function downloadCsvFile( link.click() } - -const parseBoolean = (rawBoolean: string): boolean => { - try { - return JSON.parse(rawBoolean) - } catch (e) { - return false - } -} - -/** - * Parse a CSV file containing JB Splits. - * @param csvContent - raw CSV content, including a header row. - * @returns array of Split objects - */ -export const parseV2SplitsCsv = (csvContent: string): Split[] => { - // Skip the header row (the first row in the CSV file). - const [, ...rows] = csvContent.split('\n') - - const splits: Split[] = rows.map(row => { - const [ - beneficiary, - percent, - preferClaimed, - lockedUntil, - projectId, - allocator, - ] = row.split(',') - - return { - beneficiary: beneficiary ? getAddress(beneficiary) : undefined, - percent: splitPercentFrom(parseFloat(percent) * 100).toNumber(), - preferClaimed: Boolean(preferClaimed), - lockedUntil: lockedUntil ? parseInt(lockedUntil) : undefined, - projectId: projectId?.trim() || undefined, - allocator: allocator ? getAddress(allocator.trim()) : undefined, - } - }) - - if (splits.some(split => split.percent === 0)) { - throw new Error('CSV contains splits with 0% percent.') - } - - // find duplicates - const duplicateBeneficiaries = splits - .map(split => split.beneficiary) - .filter((beneficiary, index, self) => self.indexOf(beneficiary) !== index) - if (duplicateBeneficiaries.length > 0) { - throw new Error( - `CSV contains multiple splits for the same beneficiary: ${duplicateBeneficiaries.join( - ', ', - )}`, - ) - } - - return splits -} - -export const parseV1PayoutModsCsv = (csvContent: string): PayoutMod[] => { - const [, ...rows] = csvContent.split('\n') - - const payoutMods: PayoutMod[] = rows.map(row => { - const [ - beneficiary, - percent, - preferUnstaked, - lockedUntil, - projectId, - allocator, - ] = row.split(',') - - const payoutMod: PayoutMod = { - beneficiary, - percent: percentToPermyriad(parseFloat(percent) * 100).toNumber(), - preferUnstaked: parseBoolean(preferUnstaked), - lockedUntil: lockedUntil ? parseInt(lockedUntil) : undefined, - projectId: projectId ? BigNumber.from(projectId) : undefined, - allocator, - } - - return payoutMod - }) - - return payoutMods -} - -export const parseV1TicketModsCsv = (csvContent: string): TicketMod[] => { - const [, ...rows] = csvContent.split('\n') - - const ticketMods: TicketMod[] = rows.map(row => { - const [beneficiary, percent, preferUnstaked, lockedUntil] = row.split(',') - - return { - preferUnstaked: Boolean(preferUnstaked), - percent: percentToPermyriad(parseFloat(percent) * 100).toNumber(), - lockedUntil: lockedUntil ? parseInt(lockedUntil) : undefined, - beneficiary: beneficiary || undefined, - } - }) - - return ticketMods -} From 3fd3958fa4e1d2735dd8f17c3ad02d9738260d52 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Thu, 15 Aug 2024 07:36:40 +1000 Subject: [PATCH 21/46] Refactor v4 activity event --- .../V4ActivityPanel/V4ActivityList.tsx | 2 +- .../activityEventElems/ActivityElement.tsx | 183 ++++++++++++++++++ 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/activityEventElems/ActivityElement.tsx diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx index 678a0dbb57..43f1b487a6 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx @@ -1,5 +1,4 @@ import { t } from '@lingui/macro' -import { ActivityEvent } from 'components/activityEventElems/ActivityElement/ActivityElement' import Loading from 'components/Loading' import { NativeTokenValue, @@ -12,6 +11,7 @@ import { PayEventsDocument, } from 'packages/v4/graphql/client/graphql' import { useSubgraphQuery } from 'packages/v4/graphql/useSubgraphQuery' +import { ActivityEvent } from './activityEventElems/ActivityElement' import { ActivityOptions } from './ActivityOptions' import { PayEvent } from './models/ActivityEvents' import { transformPayEventsRes } from './utils/transformEventsData' diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/activityEventElems/ActivityElement.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/activityEventElems/ActivityElement.tsx new file mode 100644 index 0000000000..4ecc0d079b --- /dev/null +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/activityEventElems/ActivityElement.tsx @@ -0,0 +1,183 @@ +import { Tooltip } from 'antd' +import EthereumAddress from 'components/EthereumAddress' +import EtherscanLink from 'components/EtherscanLink' +import { JuiceboxAccountLink } from 'components/JuiceboxAccountLink' +import { PV } from 'models/pv' +import { formatHistoricalDate } from 'utils/format/formatDate' + +export interface ActivityElementEvent { + timestamp: number + txHash: string + from: string + beneficiary?: string + terminal?: string + projectId?: number + project?: { + handle?: string | null + } + pv?: PV +} + +const FromBeneficiary = ({ + from, + beneficiary, + distributionFromProjectId, +}: { + from?: string + beneficiary?: string + distributionFromProjectId?: number // projectId only defined for v2 events +}) => { + if (!(beneficiary || from || distributionFromProjectId)) return null + + return ( + +
+ Called by: +
+ {beneficiary && ( +
+ Beneficiary: +
+ )} + {/* {distributionFromProjectId && ( +
+ Paid from:{' '} + +
+ )} */} + + } + > +
+ {/* {distributionFromProjectId ? ( + + ) : ( + + )} */} + +
+
+ ) +} + +const ExtraContainer: React.FC> = ({ + children, +}) => { + return
{children}
+} + +function Header({ + header, + projectId, + handle, + pv, +}: { + header: string | JSX.Element + projectId?: number + handle?: string | null + pv?: PV +}) { + const withProjectLink = projectId && pv + + return ( +
+ {header} + {/* {withProjectLink && ( + + {pv === PV_V2 ? ( + + ) : ( + + )} + + )} */} +
+ ) +} + +function TimestampVersion({ timestamp, txHash }: ActivityElementEvent) { + return ( +
+ {timestamp && ( +
+ {formatHistoricalDate(timestamp * 1000)}{' '} + +
+ )} +
+ ) +} + +function Subject({ subject }: { subject: string | JSX.Element | null }) { + return
{subject}
+} + +/** + * + * @param header Text that concisely labels the event + * @param subject The primary information from a specific event + * @param event Project activity event object + * @param extra Optional content added beneath the subject + */ +export function ActivityEvent({ + header, + subject, + extra, + event, + withProjectLink, + pv, +}: { + header: string | JSX.Element + subject: string | JSX.Element | null + event: ActivityElementEvent | null | undefined + extra?: string | JSX.Element | null + withProjectLink?: boolean + pv?: PV +}) { + if (!event) return null + + return ( + <> +
+
+
+ +
+ +
+ + +
+
+ + {extra ? {extra} : null} + + ) +} From ad8c7115d27e0cbbf9b357bf7277dada0e87a7c3 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Thu, 15 Aug 2024 07:43:13 +1000 Subject: [PATCH 22/46] rm activity, again --- .../V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx index 43f1b487a6..243bdb8861 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/V4ActivityList.tsx @@ -1,9 +1,7 @@ -import { t } from '@lingui/macro' import Loading from 'components/Loading' import { - NativeTokenValue, useJBContractContext, - useJBTokenContext, + useJBTokenContext } from 'juice-sdk-react' import { OrderDirection, @@ -11,7 +9,7 @@ import { PayEventsDocument, } from 'packages/v4/graphql/client/graphql' import { useSubgraphQuery } from 'packages/v4/graphql/useSubgraphQuery' -import { ActivityEvent } from './activityEventElems/ActivityElement' +// import { ActivityEvent } from './activityEventElems/ActivityElement' import { ActivityOptions } from './ActivityOptions' import { PayEvent } from './models/ActivityEvents' import { transformPayEventsRes } from './utils/transformEventsData' @@ -55,7 +53,7 @@ export function V4ActivityList() { className="mb-5 border-b border-smoke-200 pb-5 dark:border-grey-600" key={event.id} > - } - /> + /> */} ) }) From 3be5e497dfa1bcb2ff04bdeeeee7276a8b59b1a5 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Thu, 15 Aug 2024 08:04:01 +1000 Subject: [PATCH 23/46] nuke static props again --- .../v4/[chainName]/p/[projectId]/index.tsx | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index 57818aef38..e73bdaaba8 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -2,8 +2,6 @@ import { AppWrapper } from 'components/common/CoreAppWrapper/CoreAppWrapper' import { FEATURE_FLAGS } from 'constants/featureFlags' import { OPEN_IPFS_GATEWAY_HOSTNAME } from 'constants/ipfs' import { JBChainId, JBProjectProvider } from 'juice-sdk-react' -import { loadCatalog } from 'locales/utils' -import { GetStaticPaths, GetStaticProps } from 'next' import dynamic from 'next/dynamic' import { useRouter } from 'next/router' import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' @@ -23,27 +21,27 @@ const V4ProjectDashboard = dynamic( { ssr: false }, ) -export const getStaticPaths: GetStaticPaths = async () => { - return { - paths: [], - fallback: 'blocking', - } -} +// export const getStaticPaths: GetStaticPaths = async () => { +// return { +// paths: [], +// fallback: 'blocking', +// } +// } -export const getStaticProps: GetStaticProps<{ - i18n: unknown -}> = async context => { - const locale = context.locale as string - const messages = await loadCatalog(locale) - const i18n = { locale, messages } +// export const getStaticProps: GetStaticProps<{ +// i18n: unknown +// }> = async context => { +// const locale = context.locale as string +// const messages = await loadCatalog(locale) +// const i18n = { locale, messages } - return { - props: { - i18n, - }, - revalidate: 10, // 10 seconds https://nextjs.org/docs/api-reference/data-fetching/get-static-props#revalidate - } -} +// return { +// props: { +// i18n, +// }, +// revalidate: 10, // 10 seconds https://nextjs.org/docs/api-reference/data-fetching/get-static-props#revalidate +// } +// } // This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. const _Wrapper: React.FC = ({ children }) => { From 4ffb5ed903f535ccbd894be39b072edcd59430f3 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Thu, 15 Aug 2024 08:32:52 +1000 Subject: [PATCH 24/46] blank static props --- .../v4/[chainName]/p/[projectId]/index.tsx | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index e73bdaaba8..c376952ff1 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -2,6 +2,7 @@ import { AppWrapper } from 'components/common/CoreAppWrapper/CoreAppWrapper' import { FEATURE_FLAGS } from 'constants/featureFlags' import { OPEN_IPFS_GATEWAY_HOSTNAME } from 'constants/ipfs' import { JBChainId, JBProjectProvider } from 'juice-sdk-react' +import { GetStaticPaths, GetStaticProps } from 'next' import dynamic from 'next/dynamic' import { useRouter } from 'next/router' import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' @@ -21,27 +22,27 @@ const V4ProjectDashboard = dynamic( { ssr: false }, ) -// export const getStaticPaths: GetStaticPaths = async () => { -// return { -// paths: [], -// fallback: 'blocking', -// } -// } +export const getStaticPaths: GetStaticPaths = async () => { + return { + paths: [], + fallback: 'blocking', + } +} -// export const getStaticProps: GetStaticProps<{ -// i18n: unknown -// }> = async context => { -// const locale = context.locale as string -// const messages = await loadCatalog(locale) -// const i18n = { locale, messages } +export const getStaticProps: GetStaticProps<{ + // i18n: unknown +}> = async context => { + // const locale = context.locale as string + // const messages = await loadCatalog(locale) + // const i18n = { locale, messages } -// return { -// props: { -// i18n, -// }, -// revalidate: 10, // 10 seconds https://nextjs.org/docs/api-reference/data-fetching/get-static-props#revalidate -// } -// } + return { + props: { + // i18n, + }, + revalidate: 10, // 10 seconds https://nextjs.org/docs/api-reference/data-fetching/get-static-props#revalidate + } +} // This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. const _Wrapper: React.FC = ({ children }) => { From a14db643e6fc97fd339f03dcdea7cdd507037409 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Thu, 15 Aug 2024 08:48:04 +1000 Subject: [PATCH 25/46] v4 getServerSideProps empty --- .../v4/[chainName]/p/[projectId]/index.tsx | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index c376952ff1..e455b76499 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -2,7 +2,6 @@ import { AppWrapper } from 'components/common/CoreAppWrapper/CoreAppWrapper' import { FEATURE_FLAGS } from 'constants/featureFlags' import { OPEN_IPFS_GATEWAY_HOSTNAME } from 'constants/ipfs' import { JBChainId, JBProjectProvider } from 'juice-sdk-react' -import { GetStaticPaths, GetStaticProps } from 'next' import dynamic from 'next/dynamic' import { useRouter } from 'next/router' import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' @@ -22,25 +21,9 @@ const V4ProjectDashboard = dynamic( { ssr: false }, ) -export const getStaticPaths: GetStaticPaths = async () => { +export async function getServerSideProps({ req, res }) { return { - paths: [], - fallback: 'blocking', - } -} - -export const getStaticProps: GetStaticProps<{ - // i18n: unknown -}> = async context => { - // const locale = context.locale as string - // const messages = await loadCatalog(locale) - // const i18n = { locale, messages } - - return { - props: { - // i18n, - }, - revalidate: 10, // 10 seconds https://nextjs.org/docs/api-reference/data-fetching/get-static-props#revalidate + props: {}, } } From c9aa70c2ca78a4b2c6ae129608f4b45123566dea Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Thu, 15 Aug 2024 08:54:55 +1000 Subject: [PATCH 26/46] fix v4 getServerSideProps build --- src/pages/v4/[chainName]/p/[projectId]/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index e455b76499..31fa442e16 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -21,7 +21,7 @@ const V4ProjectDashboard = dynamic( { ssr: false }, ) -export async function getServerSideProps({ req, res }) { +export async function getServerSideProps() { return { props: {}, } From 342932a7d964b1510c9f70e99bc3912327c344dc Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Thu, 15 Aug 2024 09:03:28 +1000 Subject: [PATCH 27/46] nuke getServerSideProps --- src/pages/v4/[chainName]/p/[projectId]/index.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index 31fa442e16..fb6fdfde52 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -21,12 +21,6 @@ const V4ProjectDashboard = dynamic( { ssr: false }, ) -export async function getServerSideProps() { - return { - props: {}, - } -} - // This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. const _Wrapper: React.FC = ({ children }) => { const [hasMounted, setHasMounted] = React.useState(false) From 92f2baebf7137eaf8f3f1533d113f2cbed6c540e Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Sun, 18 Aug 2024 13:28:52 +1000 Subject: [PATCH 28/46] ERR too many files fix attempt --- .../V4ProjectDashboard/V4ProjectDashboard.tsx | 16 ++++++++-------- src/pages/v4/[chainName]/p/[projectId]/index.tsx | 12 ++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx index 329294c3b2..551d69e712 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx @@ -3,12 +3,12 @@ import { SuccessPayView } from 'packages/v4/components/ProjectDashboard/componen import { useProjectDispatch } from 'packages/v4/components/ProjectDashboard/redux/hooks' import { payRedeemActions } from 'packages/v4/components/ProjectDashboard/redux/payRedeemSlice' import { projectCartActions } from 'packages/v4/components/ProjectDashboard/redux/projectCartSlice' -import { V4PayRedeemCard } from 'packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard' +// import { V4PayRedeemCard } from 'packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard' import { useEffect } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPageQueries } from './hooks/useProjectPageQueries' -import { V4ProjectHeader } from './V4ProjectHeader' -import { V4ProjectTabs } from './V4ProjectTabs/V4ProjectTabs' +// import { V4ProjectHeader } from './V4ProjectHeader' +// import { V4ProjectTabs } from './V4ProjectTabs/V4ProjectTabs' export function V4ProjectDashboard() { const { projectPayReceipt } = useProjectPageQueries() @@ -29,25 +29,25 @@ export function V4ProjectDashboard() {
- + {/* */}
- - */} + {/* + /> */}
diff --git a/src/pages/v4/[chainName]/p/[projectId]/index.tsx b/src/pages/v4/[chainName]/p/[projectId]/index.tsx index fb6fdfde52..22729b648e 100644 --- a/src/pages/v4/[chainName]/p/[projectId]/index.tsx +++ b/src/pages/v4/[chainName]/p/[projectId]/index.tsx @@ -2,24 +2,20 @@ import { AppWrapper } from 'components/common/CoreAppWrapper/CoreAppWrapper' import { FEATURE_FLAGS } from 'constants/featureFlags' import { OPEN_IPFS_GATEWAY_HOSTNAME } from 'constants/ipfs' import { JBChainId, JBProjectProvider } from 'juice-sdk-react' -import dynamic from 'next/dynamic' import { useRouter } from 'next/router' import { ReduxProjectCartProvider } from 'packages/v4/components/ProjectDashboard/ReduxProjectCartProvider' import store from 'packages/v4/components/ProjectDashboard/redux/store' import V4ProjectMetadataProvider from 'packages/v4/contexts/V4ProjectMetadataProvider' import { chainNameMap } from 'packages/v4/utils/networks' +import { V4ProjectDashboard } from 'packages/v4/views/V4ProjectDashboard/V4ProjectDashboard' import { wagmiConfig } from 'packages/v4/wagmiConfig' import React, { PropsWithChildren } from 'react' import { Provider } from 'react-redux' import { featureFlagEnabled } from 'utils/featureFlags' +import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' import { WagmiProvider } from 'wagmi' -const V4ProjectDashboard = dynamic( - () => - import('packages/v4/views/V4ProjectDashboard/V4ProjectDashboard').then( - m => m.V4ProjectDashboard, - ), - { ssr: false }, -) + +export const getServerSideProps = globalGetServerSideProps // This is a hack to avoid SSR for now. At the moment when this is not applied to this page, you will see a rehydration error. const _Wrapper: React.FC = ({ children }) => { From 2eba078f217a7029dd722e87603b547c0f54d2fe Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Sun, 18 Aug 2024 13:34:50 +1000 Subject: [PATCH 29/46] WIP: add back header --- .../v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx index 551d69e712..90e3f9b098 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx @@ -7,7 +7,7 @@ import { projectCartActions } from 'packages/v4/components/ProjectDashboard/redu import { useEffect } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPageQueries } from './hooks/useProjectPageQueries' -// import { V4ProjectHeader } from './V4ProjectHeader' +import { V4ProjectHeader } from './V4ProjectHeader' // import { V4ProjectTabs } from './V4ProjectTabs/V4ProjectTabs' export function V4ProjectDashboard() { @@ -29,7 +29,7 @@ export function V4ProjectDashboard() {
- {/* */} +
Date: Sun, 18 Aug 2024 13:41:01 +1000 Subject: [PATCH 30/46] WIP: pay redeem vard remove --- .../v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx index 90e3f9b098..5b82713fcd 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx @@ -3,11 +3,11 @@ import { SuccessPayView } from 'packages/v4/components/ProjectDashboard/componen import { useProjectDispatch } from 'packages/v4/components/ProjectDashboard/redux/hooks' import { payRedeemActions } from 'packages/v4/components/ProjectDashboard/redux/payRedeemSlice' import { projectCartActions } from 'packages/v4/components/ProjectDashboard/redux/projectCartSlice' -// import { V4PayRedeemCard } from 'packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard' +import { V4PayRedeemCard } from 'packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard' import { useEffect } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPageQueries } from './hooks/useProjectPageQueries' -import { V4ProjectHeader } from './V4ProjectHeader' +// import { V4ProjectHeader } from './V4ProjectHeader' // import { V4ProjectTabs } from './V4ProjectTabs/V4ProjectTabs' export function V4ProjectDashboard() { @@ -29,19 +29,19 @@ export function V4ProjectDashboard() {
- + {/* */}
- {/* */} + /> {/* Date: Sun, 18 Aug 2024 13:49:07 +1000 Subject: [PATCH 31/46] WIP tabs --- .../views/V4ProjectDashboard/V4ProjectDashboard.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx index 5b82713fcd..e6bdc87d5f 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx @@ -3,12 +3,12 @@ import { SuccessPayView } from 'packages/v4/components/ProjectDashboard/componen import { useProjectDispatch } from 'packages/v4/components/ProjectDashboard/redux/hooks' import { payRedeemActions } from 'packages/v4/components/ProjectDashboard/redux/payRedeemSlice' import { projectCartActions } from 'packages/v4/components/ProjectDashboard/redux/projectCartSlice' -import { V4PayRedeemCard } from 'packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard' +// import { V4PayRedeemCard } from 'packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard' import { useEffect } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPageQueries } from './hooks/useProjectPageQueries' // import { V4ProjectHeader } from './V4ProjectHeader' -// import { V4ProjectTabs } from './V4ProjectTabs/V4ProjectTabs' +import { V4ProjectTabs } from './V4ProjectTabs/V4ProjectTabs' export function V4ProjectDashboard() { const { projectPayReceipt } = useProjectPageQueries() @@ -36,18 +36,18 @@ export function V4ProjectDashboard() { '[@media(min-width:960px)]:flex [@media(min-width:960px)]:max-w-6xl [@media(min-width:960px)]:justify-between [@media(min-width:960px)]:gap-x-8', )} > - - {/* */} + */} + />
From 28efdcf812d8429444023ecfa42b3b34fd198018 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Sun, 18 Aug 2024 13:55:42 +1000 Subject: [PATCH 32/46] WIP header again --- .../v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx index e6bdc87d5f..90e3f9b098 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx @@ -7,8 +7,8 @@ import { projectCartActions } from 'packages/v4/components/ProjectDashboard/redu import { useEffect } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPageQueries } from './hooks/useProjectPageQueries' -// import { V4ProjectHeader } from './V4ProjectHeader' -import { V4ProjectTabs } from './V4ProjectTabs/V4ProjectTabs' +import { V4ProjectHeader } from './V4ProjectHeader' +// import { V4ProjectTabs } from './V4ProjectTabs/V4ProjectTabs' export function V4ProjectDashboard() { const { projectPayReceipt } = useProjectPageQueries() @@ -29,7 +29,7 @@ export function V4ProjectDashboard() {
- {/* */} +
*/} - + /> */}
From b3d8466d8649f9c748b5537bc0a40f25abddbc00 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Sun, 18 Aug 2024 14:17:04 +1000 Subject: [PATCH 33/46] Upgrade next etc --- package.json | 8 +- yarn.lock | 1217 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 924 insertions(+), 301 deletions(-) diff --git a/package.json b/package.json index 594f9cb9a3..7177793479 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "bottleneck": "^2.19.5", "discord.js": "^14.9.0", "dompurify": "^3.0.5", - "eslint-config-next": "^13.4.3", + "eslint-config-next": "^14.2.5", "ethereum-block-by-date": "1.4.6", "ethers": "^5.7.0", "fathom-client": "^3.6.0", @@ -115,7 +115,7 @@ "lottie-react": "^2.4.0", "mjml": "^4.15.3", "mustache": "^4.2.0", - "next": "^13.4.3", + "next": "^14.2.5", "object-hash": "^3.0.0", "pino": "^8.11.0", "pino-pretty": "^10.0.0", @@ -124,8 +124,8 @@ "prop-types": "^15.8.1", "qs": "^6.12.2", "quill": "^1.3.7", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-error-boundary": "^4.0.11", "react-quill": "^2.0.0", "react-redux": "^8", diff --git a/yarn.lock b/yarn.lock index 455a0becf3..b29a0f3b58 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3402,62 +3402,62 @@ dependencies: webpack-bundle-analyzer "4.10.1" -"@next/env@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/env/-/env-13.5.6.tgz#c1148e2e1aa166614f05161ee8f77ded467062bc" - integrity sha512-Yac/bV5sBGkkEXmAX5FWPS9Mmo2rthrOPRQQNfycJPkjUAUclomCPH7QFVCDQ4Mp2k2K1SSM6m0zrxYrOwtFQw== - -"@next/eslint-plugin-next@13.4.3": - version "13.4.3" - resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.3.tgz#9f3b9dedc8da57436e45d736f5fc6646e93a2656" - integrity sha512-5B0uOnh7wyUY9vNNdIA6NUvWozhrZaTMZOzdirYAefqD0ZBK5C/h3+KMYdCKrR7JrXGvVpWnHtv54b3dCzwICA== - dependencies: - glob "7.1.7" - -"@next/swc-darwin-arm64@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.6.tgz#b15d139d8971360fca29be3bdd703c108c9a45fb" - integrity sha512-5nvXMzKtZfvcu4BhtV0KH1oGv4XEW+B+jOfmBdpFI3C7FrB/MfujRpWYSBBO64+qbW8pkZiSyQv9eiwnn5VIQA== - -"@next/swc-darwin-x64@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.6.tgz#9c72ee31cc356cb65ce6860b658d807ff39f1578" - integrity sha512-6cgBfxg98oOCSr4BckWjLLgiVwlL3vlLj8hXg2b+nDgm4bC/qVXXLfpLB9FHdoDu4057hzywbxKvmYGmi7yUzA== - -"@next/swc-linux-arm64-gnu@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.6.tgz#59f5f66155e85380ffa26ee3d95b687a770cfeab" - integrity sha512-txagBbj1e1w47YQjcKgSU4rRVQ7uF29YpnlHV5xuVUsgCUf2FmyfJ3CPjZUvpIeXCJAoMCFAoGnbtX86BK7+sg== - -"@next/swc-linux-arm64-musl@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.6.tgz#f012518228017052736a87d69bae73e587c76ce2" - integrity sha512-cGd+H8amifT86ZldVJtAKDxUqeFyLWW+v2NlBULnLAdWsiuuN8TuhVBt8ZNpCqcAuoruoSWynvMWixTFcroq+Q== - -"@next/swc-linux-x64-gnu@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.6.tgz#339b867a7e9e7ee727a700b496b269033d820df4" - integrity sha512-Mc2b4xiIWKXIhBy2NBTwOxGD3nHLmq4keFk+d4/WL5fMsB8XdJRdtUlL87SqVCTSaf1BRuQQf1HvXZcy+rq3Nw== - -"@next/swc-linux-x64-musl@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.6.tgz#ae0ae84d058df758675830bcf70ca1846f1028f2" - integrity sha512-CFHvP9Qz98NruJiUnCe61O6GveKKHpJLloXbDSWRhqhkJdZD2zU5hG+gtVJR//tyW897izuHpM6Gtf6+sNgJPQ== - -"@next/swc-win32-arm64-msvc@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.6.tgz#a5cc0c16920485a929a17495064671374fdbc661" - integrity sha512-aFv1ejfkbS7PUa1qVPwzDHjQWQtknzAZWGTKYIAaS4NMtBlk3VyA6AYn593pqNanlicewqyl2jUhQAaFV/qXsg== - -"@next/swc-win32-ia32-msvc@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.6.tgz#6a2409b84a2cbf34bf92fe714896455efb4191e4" - integrity sha512-XqqpHgEIlBHvzwG8sp/JXMFkLAfGLqkbVsyN+/Ih1mR8INb6YCc2x/Mbwi6hsAgUnqQztz8cvEbHJUbSl7RHDg== - -"@next/swc-win32-x64-msvc@13.5.6": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.6.tgz#4a3e2a206251abc729339ba85f60bc0433c2865d" - integrity sha512-Cqfe1YmOS7k+5mGu92nl5ULkzpKuxJrP3+4AEuPmrpFZ3BHxTY3TnHmU1On3bFmFFs6FbTcdF58CCUProGpIGQ== +"@next/env@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.5.tgz#1d9328ab828711d3517d0a1d505acb55e5ef7ad0" + integrity sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA== + +"@next/eslint-plugin-next@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.5.tgz#f7e3ff3efe40a2855e5f29bc2692175f85913ba8" + integrity sha512-LY3btOpPh+OTIpviNojDpUdIbHW9j0JBYBjsIp8IxtDFfYFyORvw3yNq6N231FVqQA7n7lwaf7xHbVJlA1ED7g== + dependencies: + glob "10.3.10" + +"@next/swc-darwin-arm64@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz#d0a160cf78c18731c51cc0bff131c706b3e9bb05" + integrity sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ== + +"@next/swc-darwin-x64@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz#eb832a992407f6e6352eed05a073379f1ce0589c" + integrity sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA== + +"@next/swc-linux-arm64-gnu@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz#098fdab57a4664969bc905f5801ef5a89582c689" + integrity sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA== + +"@next/swc-linux-arm64-musl@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz#243a1cc1087fb75481726dd289c7b219fa01f2b5" + integrity sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA== + +"@next/swc-linux-x64-gnu@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz#b8a2e436387ee4a52aa9719b718992e0330c4953" + integrity sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ== + +"@next/swc-linux-x64-musl@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz#cb8a9adad5fb8df86112cfbd363aab5c6d32757b" + integrity sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ== + +"@next/swc-win32-arm64-msvc@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz#81f996c1c38ea0900d4e7719cc8814be8a835da0" + integrity sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw== + +"@next/swc-win32-ia32-msvc@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz#f61c74ce823e10b2bc150e648fc192a7056422e0" + integrity sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg== + +"@next/swc-win32-x64-msvc@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz#ed199a920efb510cfe941cd75ed38a7be21e756f" + integrity sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g== "@nicolo-ribaudo/semver-v6@^6.3.3": version "6.3.3" @@ -3742,10 +3742,10 @@ resolved "https://registry.yarnpkg.com/@repeaterjs/repeater/-/repeater-3.0.4.tgz#a04d63f4d1bf5540a41b01a921c9a7fddc3bd1ca" integrity sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA== -"@rushstack/eslint-patch@^1.1.3": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.3.0.tgz#f5635b36fc0dad96ef1e542a302cd914230188c0" - integrity sha512-IthPJsJR85GhOkp3Hvp8zFOPK5ynKn6STyHa/WZpioK7E1aYDiBzpqQPrngc14DszIUkIrdd3k9Iu0XSzlP/1w== +"@rushstack/eslint-patch@^1.3.3": + version "1.10.4" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz#427d5549943a9c6fce808e39ea64dbe60d4047f1" + integrity sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA== "@safe-global/safe-apps-provider@0.18.1": version "0.18.1" @@ -4130,11 +4130,17 @@ "@supabase/storage-js" "^2.5.1" cross-fetch "^3.1.5" -"@swc/helpers@0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.2.tgz#85ea0c76450b61ad7d10a37050289eded783c27d" - integrity sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw== +"@swc/counter@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9" + integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== + +"@swc/helpers@0.5.5": + version "0.5.5" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.5.tgz#12689df71bfc9b21c4f4ca00ae55f2f16c8b77c0" + integrity sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A== dependencies: + "@swc/counter" "^0.1.3" tslib "^2.4.0" "@szmarczak/http-timer@^4.0.5": @@ -4903,24 +4909,17 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@^5.42.0": - version "5.59.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.7.tgz#02682554d7c1028b89aa44a48bf598db33048caa" - integrity sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ== +"@typescript-eslint/parser@^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.2.0.tgz#44356312aea8852a3a82deebdacd52ba614ec07a" + integrity sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg== dependencies: - "@typescript-eslint/scope-manager" "5.59.7" - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/typescript-estree" "5.59.7" + "@typescript-eslint/scope-manager" "7.2.0" + "@typescript-eslint/types" "7.2.0" + "@typescript-eslint/typescript-estree" "7.2.0" + "@typescript-eslint/visitor-keys" "7.2.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.59.7": - version "5.59.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz#0243f41f9066f3339d2f06d7f72d6c16a16769e2" - integrity sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ== - dependencies: - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/visitor-keys" "5.59.7" - "@typescript-eslint/scope-manager@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" @@ -4929,6 +4928,14 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" +"@typescript-eslint/scope-manager@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz#cfb437b09a84f95a0930a76b066e89e35d94e3da" + integrity sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg== + dependencies: + "@typescript-eslint/types" "7.2.0" + "@typescript-eslint/visitor-keys" "7.2.0" + "@typescript-eslint/type-utils@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" @@ -4939,28 +4946,15 @@ debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.59.7": - version "5.59.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.7.tgz#6f4857203fceee91d0034ccc30512d2939000742" - integrity sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A== - "@typescript-eslint/types@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/typescript-estree@5.59.7": - version "5.59.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz#b887acbd4b58e654829c94860dbff4ac55c5cff8" - integrity sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ== - dependencies: - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/visitor-keys" "5.59.7" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" +"@typescript-eslint/types@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.2.0.tgz#0feb685f16de320e8520f13cca30779c8b7c403f" + integrity sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA== "@typescript-eslint/typescript-estree@5.62.0": version "5.62.0" @@ -4975,6 +4969,20 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz#5beda2876c4137f8440c5a84b4f0370828682556" + integrity sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA== + dependencies: + "@typescript-eslint/types" "7.2.0" + "@typescript-eslint/visitor-keys" "7.2.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + "@typescript-eslint/utils@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" @@ -4989,14 +4997,6 @@ eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.59.7": - version "5.59.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz#09c36eaf268086b4fbb5eb9dc5199391b6485fc5" - integrity sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ== - dependencies: - "@typescript-eslint/types" "5.59.7" - eslint-visitor-keys "^3.3.0" - "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" @@ -5005,6 +5005,14 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz#5035f177752538a5750cca1af6044b633610bf9e" + integrity sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A== + dependencies: + "@typescript-eslint/types" "7.2.0" + eslint-visitor-keys "^3.4.1" + "@uiw/copy-to-clipboard@~1.0.12": version "1.0.15" resolved "https://registry.yarnpkg.com/@uiw/copy-to-clipboard/-/copy-to-clipboard-1.0.15.tgz#959cebbae64df353964647bb5b9d705176b2e613" @@ -6158,7 +6166,7 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^5.0.0, aria-query@^5.1.3: +aria-query@^5.0.0, aria-query@~5.1.3: version "5.1.3" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== @@ -6183,6 +6191,14 @@ array-buffer-byte-length@^1.0.0: call-bind "^1.0.2" is-array-buffer "^3.0.1" +array-buffer-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== + dependencies: + call-bind "^1.0.5" + is-array-buffer "^3.0.4" + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -6199,6 +6215,18 @@ array-includes@^3.1.5, array-includes@^3.1.6: get-intrinsic "^1.1.3" is-string "^1.0.7" +array-includes@^3.1.7, array-includes@^3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" + integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + is-string "^1.0.7" + array-tree-filter@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz#873ac00fec83749f255ac8dd083814b4f6329190" @@ -6209,6 +6237,30 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array.prototype.findlast@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz#3e4fbcb30a15a7f5bf64cf2faae22d139c2e4904" + integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-shim-unscopables "^1.0.2" + +array.prototype.findlastindex@^1.2.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d" + integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-shim-unscopables "^1.0.2" + array.prototype.flat@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" @@ -6219,26 +6271,50 @@ array.prototype.flat@^1.3.1: es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" -array.prototype.flatmap@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" - integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== +array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -array.prototype.tosorted@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz#ccf44738aa2b5ac56578ffda97c03fd3e23dd532" - integrity sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ== +array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" - get-intrinsic "^1.1.3" + +array.prototype.tosorted@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz#fe954678ff53034e717ea3352a03f0b0b86f7ffc" + integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.3" + es-errors "^1.3.0" + es-shim-unscopables "^1.0.2" + +arraybuffer.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6" + integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== + dependencies: + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.2.1" + get-intrinsic "^1.2.3" + is-array-buffer "^3.0.4" + is-shared-array-buffer "^1.0.2" asap@~2.0.3: version "2.0.6" @@ -6266,10 +6342,10 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== +ast-types-flow@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" + integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== astral-regex@^2.0.0: version "2.0.0" @@ -6351,6 +6427,13 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -6361,10 +6444,10 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== -axe-core@^4.6.2: - version "4.7.1" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.1.tgz#04392c9ccb3d7d7c5d2f8684f148d56d3442f33d" - integrity sha512-sCXXUhA+cljomZ3ZAwb8i1p3oOlkABzPy08ZDAoGcYuvtBPlQ1Ytde129ArXyHWDhfeewq7rlx9F+cUx2SSlkg== +axe-core@^4.9.1: + version "4.10.0" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.0.tgz#d9e56ab0147278272739a000880196cdfe113b59" + integrity sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g== axios@1.6.0: version "1.6.0" @@ -6382,7 +6465,7 @@ axios@^0.25.0: dependencies: follow-redirects "^1.14.7" -axobject-query@^3.1.1: +axobject-query@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== @@ -6976,7 +7059,7 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -call-bind@^1.0.7: +call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== @@ -7033,16 +7116,21 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001629: - version "1.0.30001639" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz#972b3a6adeacdd8f46af5fc7f771e9639f6c1521" - integrity sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg== - caniuse-lite@^1.0.30001426, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001503: version "1.0.30001621" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001621.tgz" integrity sha512-+NLXZiviFFKX0fk8Piwv3PfLPGtRqJeq2TiNoUff/qB5KJgwecJTvCXDpmlyP/eCI/GUEmp/h/y5j0yckiiZrA== +caniuse-lite@^1.0.30001579: + version "1.0.30001651" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz#52de59529e8b02b1aedcaaf5c05d9e23c0c28138" + integrity sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg== + +caniuse-lite@^1.0.30001629: + version "1.0.30001639" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz#972b3a6adeacdd8f46af5fc7f771e9639f6c1521" + integrity sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg== + capital-case@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" @@ -8048,6 +8136,33 @@ data-urls@^3.0.2: whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" +data-view-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" + integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz#90721ca95ff280677eb793749fce1011347669e2" + integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz#5e0bbfb4828ed2d1b9b400cd8a7d119bca0ff18a" + integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + dataloader@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.2.2.tgz#216dc509b5abe39d43a9b9d97e6e5e473dfbe3e0" @@ -8242,7 +8357,7 @@ deferred-leveldown@~1.2.1: dependencies: abstract-leveldown "~2.6.0" -define-data-property@^1.1.4: +define-data-property@^1.0.1, define-data-property@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== @@ -8269,6 +8384,15 @@ define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + defined@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" @@ -8737,6 +8861,58 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-abstract@^1.17.5, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2, es-abstract@^1.23.3: + version "1.23.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== + dependencies: + array-buffer-byte-length "^1.0.1" + arraybuffer.prototype.slice "^1.0.3" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + data-view-buffer "^1.0.1" + data-view-byte-length "^1.0.1" + data-view-byte-offset "^1.0.0" + es-define-property "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-set-tostringtag "^2.0.3" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.4" + get-symbol-description "^1.0.2" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" + has-symbols "^1.0.3" + hasown "^2.0.2" + internal-slot "^1.0.7" + is-array-buffer "^3.0.4" + is-callable "^1.2.7" + is-data-view "^1.0.1" + is-negative-zero "^2.0.3" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.3" + is-string "^1.0.7" + is-typed-array "^1.1.13" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.5" + regexp.prototype.flags "^1.5.2" + safe-array-concat "^1.1.2" + safe-regex-test "^1.0.3" + string.prototype.trim "^1.2.9" + string.prototype.trimend "^1.0.8" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.2" + typed-array-byte-length "^1.0.1" + typed-array-byte-offset "^1.0.2" + typed-array-length "^1.0.6" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.15" + es-abstract@^1.19.0, es-abstract@^1.20.4: version "1.21.2" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" @@ -8784,7 +8960,7 @@ es-define-property@^1.0.0: dependencies: get-intrinsic "^1.2.4" -es-errors@^1.3.0: +es-errors@^1.2.1, es-errors@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== @@ -8804,6 +8980,33 @@ es-get-iterator@^1.1.3: isarray "^2.0.5" stop-iteration-iterator "^1.0.0" +es-iterator-helpers@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz#117003d0e5fec237b4b5c08aded722e0c6d50ca8" + integrity sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.3" + es-errors "^1.3.0" + es-set-tostringtag "^2.0.3" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + globalthis "^1.0.3" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" + has-symbols "^1.0.3" + internal-slot "^1.0.7" + iterator.prototype "^1.1.2" + safe-array-concat "^1.1.2" + +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== + dependencies: + es-errors "^1.3.0" + es-set-tostringtag@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" @@ -8813,6 +9016,15 @@ es-set-tostringtag@^2.0.1: has "^1.0.3" has-tostringtag "^1.0.0" +es-set-tostringtag@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" + integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== + dependencies: + get-intrinsic "^1.2.4" + has-tostringtag "^1.0.2" + hasown "^2.0.1" + es-shim-unscopables@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" @@ -8820,6 +9032,13 @@ es-shim-unscopables@^1.0.0: dependencies: has "^1.0.3" +es-shim-unscopables@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -8955,22 +9174,22 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-next@^13.4.3: - version "13.4.3" - resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-13.4.3.tgz#15fccfddd69a2634e8939dba6a428362e09cbb21" - integrity sha512-1lXwdFi29fKxzeugof/TUE7lpHyJQt5+U4LaUHyvQfHjvsWO77vFNicJv5sX6k0VDVSbnfz0lw+avxI+CinbMg== +eslint-config-next@^14.2.5: + version "14.2.5" + resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-14.2.5.tgz#cdd43d89047eb7391ba25445d5855b4600b6adb9" + integrity sha512-zogs9zlOiZ7ka+wgUnmcM0KBEDjo4Jis7kxN1jvC0N4wynQ2MIx/KBkg4mVF63J5EK4W0QMCn7xO3vNisjaAoA== dependencies: - "@next/eslint-plugin-next" "13.4.3" - "@rushstack/eslint-patch" "^1.1.3" - "@typescript-eslint/parser" "^5.42.0" + "@next/eslint-plugin-next" "14.2.5" + "@rushstack/eslint-patch" "^1.3.3" + "@typescript-eslint/parser" "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0" eslint-import-resolver-node "^0.3.6" eslint-import-resolver-typescript "^3.5.2" - eslint-plugin-import "^2.26.0" - eslint-plugin-jsx-a11y "^6.5.1" - eslint-plugin-react "^7.31.7" - eslint-plugin-react-hooks "^4.5.0" + eslint-plugin-import "^2.28.1" + eslint-plugin-jsx-a11y "^6.7.1" + eslint-plugin-react "^7.33.2" + eslint-plugin-react-hooks "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" -eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.7: +eslint-import-resolver-node@^0.3.6: version "0.3.7" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== @@ -8979,6 +9198,15 @@ eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.7: is-core-module "^2.11.0" resolve "^1.22.1" +eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== + dependencies: + debug "^3.2.7" + is-core-module "^2.13.0" + resolve "^1.22.4" + eslint-import-resolver-typescript@^3.5.2: version "3.5.5" resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz#0a9034ae7ed94b254a360fbea89187b60ea7456d" @@ -9000,74 +9228,86 @@ eslint-module-utils@^2.7.4: dependencies: debug "^3.2.7" -eslint-plugin-import@^2.26.0: - version "2.27.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" - integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== +eslint-module-utils@^2.8.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz#52f2404300c3bd33deece9d7372fb337cc1d7c34" + integrity sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q== dependencies: - array-includes "^3.1.6" - array.prototype.flat "^1.3.1" - array.prototype.flatmap "^1.3.1" + debug "^3.2.7" + +eslint-plugin-import@^2.28.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" + integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== + dependencies: + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" debug "^3.2.7" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.7" - eslint-module-utils "^2.7.4" - has "^1.0.3" - is-core-module "^2.11.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" is-glob "^4.0.3" minimatch "^3.1.2" - object.values "^1.1.6" - resolve "^1.22.1" - semver "^6.3.0" - tsconfig-paths "^3.14.1" - -eslint-plugin-jsx-a11y@^6.5.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" - integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== - dependencies: - "@babel/runtime" "^7.20.7" - aria-query "^5.1.3" - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - ast-types-flow "^0.0.7" - axe-core "^4.6.2" - axobject-query "^3.1.1" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.15.0" + +eslint-plugin-jsx-a11y@^6.7.1: + version "6.9.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz#67ab8ff460d4d3d6a0b4a570e9c1670a0a8245c8" + integrity sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g== + dependencies: + aria-query "~5.1.3" + array-includes "^3.1.8" + array.prototype.flatmap "^1.3.2" + ast-types-flow "^0.0.8" + axe-core "^4.9.1" + axobject-query "~3.1.1" damerau-levenshtein "^1.0.8" emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.3.3" - language-tags "=1.0.5" + es-iterator-helpers "^1.0.19" + hasown "^2.0.2" + jsx-ast-utils "^3.3.5" + language-tags "^1.0.9" minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - semver "^6.3.0" - -eslint-plugin-react-hooks@^4.5.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" - integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + object.fromentries "^2.0.8" + safe-regex-test "^1.0.3" + string.prototype.includes "^2.0.0" -eslint-plugin-react@^7.31.7: - version "7.32.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz#e71f21c7c265ebce01bcbc9d0955170c55571f10" - integrity sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg== - dependencies: - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - array.prototype.tosorted "^1.1.1" +"eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": + version "4.6.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz#c829eb06c0e6f484b3fbb85a97e57784f328c596" + integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ== + +eslint-plugin-react@^7.33.2: + version "7.35.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz#00b1e4559896710e58af6358898f2ff917ea4c41" + integrity sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA== + dependencies: + array-includes "^3.1.8" + array.prototype.findlast "^1.2.5" + array.prototype.flatmap "^1.3.2" + array.prototype.tosorted "^1.1.4" doctrine "^2.1.0" + es-iterator-helpers "^1.0.19" estraverse "^5.3.0" + hasown "^2.0.2" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - object.hasown "^1.1.2" - object.values "^1.1.6" + object.entries "^1.1.8" + object.fromentries "^2.0.8" + object.values "^1.2.0" prop-types "^15.8.1" - resolve "^2.0.0-next.4" - semver "^6.3.0" - string.prototype.matchall "^4.0.8" + resolve "^2.0.0-next.5" + semver "^6.3.1" + string.prototype.matchall "^4.0.11" + string.prototype.repeat "^1.0.0" eslint-scope@^5.1.1: version "5.1.1" @@ -10217,6 +10457,16 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" +function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" @@ -10257,7 +10507,7 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ has-proto "^1.0.1" has-symbols "^1.0.3" -get-intrinsic@^1.2.4: +get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== @@ -10308,6 +10558,15 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +get-symbol-description@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" + integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== + dependencies: + call-bind "^1.0.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + get-tsconfig@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f" @@ -10339,10 +10598,16 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== +glob@10.3.10: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" glob@7.1.7: version "7.1.7" @@ -10494,7 +10759,7 @@ got@^11.8.2, got@^11.8.5: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -10616,6 +10881,11 @@ has-proto@^1.0.1: resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== +has-proto@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" @@ -10628,6 +10898,13 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -10660,7 +10937,7 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hasown@^2.0.0: +hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== @@ -11210,7 +11487,7 @@ inquirer@^8.0.0: through "^2.3.6" wrap-ansi "^7.0.0" -internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: +internal-slot@^1.0.4, internal-slot@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== @@ -11219,6 +11496,15 @@ internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: has "^1.0.3" side-channel "^1.0.4" +internal-slot@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== + dependencies: + es-errors "^1.3.0" + hasown "^2.0.0" + side-channel "^1.0.4" + "internmap@1 - 2": version "2.0.3" resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" @@ -11294,11 +11580,26 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: get-intrinsic "^1.2.0" is-typed-array "^1.1.10" +is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + dependencies: + has-tostringtag "^1.0.0" + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -11331,13 +11632,27 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.11.0, is-core-module@^2.9.0: +is-core-module@^2.11.0: version "2.12.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== dependencies: has "^1.0.3" +is-core-module@^2.13.0, is-core-module@^2.13.1: + version "2.15.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.0.tgz#71c72ec5442ace7e76b306e9d48db361f22699ea" + integrity sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA== + dependencies: + hasown "^2.0.2" + +is-data-view@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.1.tgz#4b4d3a511b70f3dc26d42c03ca9ca515d847759f" + integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== + dependencies: + is-typed-array "^1.1.13" + is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" @@ -11365,6 +11680,13 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== + dependencies: + call-bind "^1.0.2" + is-fn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" @@ -11402,7 +11724,7 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-generator-function@^1.0.7: +is-generator-function@^1.0.10, is-generator-function@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== @@ -11457,11 +11779,21 @@ is-map@^2.0.1, is-map@^2.0.2: resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== +is-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" + integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== + is-number-object@^1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" @@ -11519,6 +11851,11 @@ is-set@^2.0.1, is-set@^2.0.2: resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== +is-set@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" + integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -11526,6 +11863,13 @@ is-shared-array-buffer@^1.0.2: dependencies: call-bind "^1.0.2" +is-shared-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== + dependencies: + call-bind "^1.0.7" + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" @@ -11561,6 +11905,13 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9: gopd "^1.0.1" has-tostringtag "^1.0.0" +is-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== + dependencies: + which-typed-array "^1.1.14" + is-typedarray@1.0.0, is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -11602,6 +11953,11 @@ is-weakmap@^2.0.1: resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== +is-weakmap@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" + integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -11617,6 +11973,14 @@ is-weakset@^2.0.1: call-bind "^1.0.2" get-intrinsic "^1.1.1" +is-weakset@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.3.tgz#e801519df8c0c43e12ff2834eead84ec9e624007" + integrity sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + is-what@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" @@ -11738,6 +12102,26 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +iterator.prototype@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" + integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== + dependencies: + define-properties "^1.2.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.4" + set-function-name "^2.0.1" + +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jackspeak@^3.1.2: version "3.4.0" resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.0.tgz#a75763ff36ad778ede6a156d8ee8b124de445b4a" @@ -12528,7 +12912,7 @@ jsprim@^1.2.2: json-schema "0.4.0" verror "1.10.0" -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: +"jsx-ast-utils@^2.4.1 || ^3.0.0": version "3.3.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== @@ -12536,6 +12920,16 @@ jsprim@^1.2.2: array-includes "^3.1.5" object.assign "^4.1.3" +jsx-ast-utils@^3.3.5: + version "3.3.5" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" + integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + object.assign "^4.1.4" + object.values "^1.1.6" + juice-sdk-core@^10.0.3-alpha: version "10.0.3-alpha" resolved "https://registry.yarnpkg.com/juice-sdk-core/-/juice-sdk-core-10.0.3-alpha.tgz#dcd1afa2faa13f42559ced3b308e5e886892c7bd" @@ -12634,17 +13028,17 @@ kleur@^4.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== -language-subtag-registry@~0.3.2: - version "0.3.22" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== +language-subtag-registry@^0.3.20: + version "0.3.23" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7" + integrity sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ== -language-tags@=1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== +language-tags@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" + integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== dependencies: - language-subtag-registry "~0.3.2" + language-subtag-registry "^0.3.20" lcid@^1.0.0: version "1.0.0" @@ -13726,6 +14120,13 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -13747,7 +14148,7 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.3, minimatch@^9.0.4: +minimatch@^9.0.1, minimatch@^9.0.3, minimatch@^9.0.4: version "9.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== @@ -14331,28 +14732,28 @@ next-tick@1, next-tick@^1.1.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== -next@^13.4.3: - version "13.5.6" - resolved "https://registry.yarnpkg.com/next/-/next-13.5.6.tgz#e964b5853272236c37ce0dd2c68302973cf010b1" - integrity sha512-Y2wTcTbO4WwEsVb4A8VSnOsG1I9ok+h74q0ZdxkwM3EODqrs4pasq7O0iUxbcS9VtWMicG7f3+HAj0r1+NtKSw== +next@^14.2.5: + version "14.2.5" + resolved "https://registry.yarnpkg.com/next/-/next-14.2.5.tgz#afe4022bb0b752962e2205836587a289270efbea" + integrity sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA== dependencies: - "@next/env" "13.5.6" - "@swc/helpers" "0.5.2" + "@next/env" "14.2.5" + "@swc/helpers" "0.5.5" busboy "1.6.0" - caniuse-lite "^1.0.30001406" + caniuse-lite "^1.0.30001579" + graceful-fs "^4.2.11" postcss "8.4.31" styled-jsx "5.1.1" - watchpack "2.4.0" optionalDependencies: - "@next/swc-darwin-arm64" "13.5.6" - "@next/swc-darwin-x64" "13.5.6" - "@next/swc-linux-arm64-gnu" "13.5.6" - "@next/swc-linux-arm64-musl" "13.5.6" - "@next/swc-linux-x64-gnu" "13.5.6" - "@next/swc-linux-x64-musl" "13.5.6" - "@next/swc-win32-arm64-msvc" "13.5.6" - "@next/swc-win32-ia32-msvc" "13.5.6" - "@next/swc-win32-x64-msvc" "13.5.6" + "@next/swc-darwin-arm64" "14.2.5" + "@next/swc-darwin-x64" "14.2.5" + "@next/swc-linux-arm64-gnu" "14.2.5" + "@next/swc-linux-arm64-musl" "14.2.5" + "@next/swc-linux-x64-gnu" "14.2.5" + "@next/swc-linux-x64-musl" "14.2.5" + "@next/swc-win32-arm64-msvc" "14.2.5" + "@next/swc-win32-ia32-msvc" "14.2.5" + "@next/swc-win32-x64-msvc" "14.2.5" no-case@^2.2.0, no-case@^2.3.2: version "2.3.2" @@ -14607,31 +15008,43 @@ object.assign@^4.1.3, object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" -object.entries@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" - integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== +object.assign@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + call-bind "^1.0.5" + define-properties "^1.2.1" + has-symbols "^1.0.3" + object-keys "^1.1.1" -object.fromentries@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" - integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== +object.entries@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.8.tgz#bffe6f282e01f4d17807204a24f8edd823599c41" + integrity sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" -object.hasown@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92" - integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== +object.fromentries@^2.0.7, object.fromentries@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" + integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== dependencies: - define-properties "^1.1.4" - es-abstract "^1.20.4" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + +object.groupby@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" + integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" object.values@^1.1.6: version "1.1.6" @@ -14642,6 +15055,15 @@ object.values@^1.1.6: define-properties "^1.1.4" es-abstract "^1.20.4" +object.values@^1.1.7, object.values@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" + integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + oboe@2.1.5: version "2.1.5" resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd" @@ -15059,7 +15481,7 @@ path-root@^0.1.1: dependencies: path-root-regex "^0.1.0" -path-scurry@^1.11.1: +path-scurry@^1.10.1, path-scurry@^1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== @@ -15299,6 +15721,11 @@ pony-cause@^2.1.10: resolved "https://registry.yarnpkg.com/pony-cause/-/pony-cause-2.1.11.tgz#d69a20aaccdb3bdb8f74dd59e5c68d8e6772e4bd" integrity sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg== +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + postcss-cli@10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/postcss-cli/-/postcss-cli-10.0.0.tgz#404e468d1ff39fb5ead3f707e2021be7cd3f8c9f" @@ -16170,13 +16597,13 @@ rc-virtual-list@^3.2.0, rc-virtual-list@^3.4.8: rc-resize-observer "^1.0.0" rc-util "^5.15.0" -react-dom@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== +react-dom@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== dependencies: loose-envify "^1.1.0" - scheduler "^0.23.0" + scheduler "^0.23.2" react-error-boundary@^3.1.0: version "3.1.4" @@ -16303,10 +16730,10 @@ react-transition-group@^4.4.5: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== +react@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== dependencies: loose-envify "^1.1.0" @@ -16479,6 +16906,19 @@ redux@^4.2.1: dependencies: "@babel/runtime" "^7.9.2" +reflect.getprototypeof@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz#3ab04c32a8390b770712b7a8633972702d278859" + integrity sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.1" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" + refractor@^4.7.0: version "4.8.1" resolved "https://registry.yarnpkg.com/refractor/-/refractor-4.8.1.tgz#fbdd889333a3d86c9c864479622855c9b38e9d42" @@ -16508,6 +16948,16 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.3, regexp.prototype.f define-properties "^1.2.0" functions-have-names "^1.2.3" +regexp.prototype.flags@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== + dependencies: + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" + rehackt@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/rehackt/-/rehackt-0.1.0.tgz#a7c5e289c87345f70da8728a7eb878e5d03c696b" @@ -16784,12 +17234,21 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^2.0.0-next.4: - version "2.0.0-next.4" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" - integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== +resolve@^1.22.4: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.5: + version "2.0.0-next.5" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== + dependencies: + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -16919,6 +17378,16 @@ sade@^1.7.3, sade@^1.8.1: dependencies: mri "^1.1.0" +safe-array-concat@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" + integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -16945,6 +17414,15 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" +safe-regex-test@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" + integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-regex "^1.1.4" + safe-stable-stringify@^2.1.0, safe-stable-stringify@^2.3.1: version "2.4.3" resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" @@ -16983,6 +17461,13 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + schema-utils@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" @@ -17161,6 +17646,16 @@ set-function-length@^1.2.1: gopd "^1.0.1" has-property-descriptors "^1.0.2" +set-function-name@^2.0.1, set-function-name@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.2" + set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" @@ -17614,19 +18109,39 @@ string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string.prototype.matchall@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" - integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== +string.prototype.includes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz#8986d57aee66d5460c144620a6d873778ad7289f" + integrity sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.matchall@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz#1092a72c59268d2abaad76582dccc687c0297e0a" + integrity sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + gopd "^1.0.1" has-symbols "^1.0.3" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.4.3" - side-channel "^1.0.4" + internal-slot "^1.0.7" + regexp.prototype.flags "^1.5.2" + set-function-name "^2.0.2" + side-channel "^1.0.6" + +string.prototype.repeat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz#e90872ee0308b29435aa26275f6e1b762daee01a" + integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" string.prototype.trim@^1.2.7: version "1.2.7" @@ -17637,6 +18152,16 @@ string.prototype.trim@^1.2.7: define-properties "^1.1.4" es-abstract "^1.20.4" +string.prototype.trim@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" + integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" + string.prototype.trimend@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" @@ -17646,6 +18171,15 @@ string.prototype.trimend@^1.0.6: define-properties "^1.1.4" es-abstract "^1.20.4" +string.prototype.trimend@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229" + integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + string.prototype.trimstart@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" @@ -17655,6 +18189,15 @@ string.prototype.trimstart@^1.0.6: define-properties "^1.1.4" es-abstract "^1.20.4" +string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -18253,6 +18796,11 @@ trough@^2.0.0: resolved "https://registry.yarnpkg.com/true-myth/-/true-myth-4.1.1.tgz#ff4ac9d5130276e34aa338757e2416ec19248ba2" integrity sha512-rqy30BSpxPznbbTcAcci90oZ1YR4DqvKcNXNerG5gQBU2v4jk0cygheiul5J6ExIMrgDVuanv/MkGfqZbKrNNg== +ts-api-utils@^1.0.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + ts-command-line-args@^2.2.0: version "2.5.1" resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0" @@ -18305,10 +18853,10 @@ ts-prune@^0.10.3: "true-myth" "^4.1.0" ts-morph "^13.0.1" -tsconfig-paths@^3.14.1: - version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" - integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== +tsconfig-paths@^3.15.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.2" @@ -18422,6 +18970,38 @@ typechain@8.0.0: ts-command-line-args "^2.2.0" ts-essentials "^7.0.1" +typed-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" + +typed-array-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-byte-offset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" @@ -18431,6 +19011,18 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" +typed-array-length@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" + typed-function@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-2.1.0.tgz#ded6f8a442ba8749ff3fe75bc41419c8d46ccc3f" @@ -19020,14 +19612,6 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" -watchpack@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -19453,6 +20037,24 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-builtin-type@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.4.tgz#592796260602fc3514a1b5ee7fa29319b72380c3" + integrity sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w== + dependencies: + function.prototype.name "^1.1.6" + has-tostringtag "^1.0.2" + is-async-function "^2.0.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" + is-generator-function "^1.0.10" + is-regex "^1.1.4" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.2" + which-typed-array "^1.1.15" + which-collection@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" @@ -19463,6 +20065,16 @@ which-collection@^1.0.1: is-weakmap "^2.0.1" is-weakset "^2.0.1" +which-collection@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" + integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== + dependencies: + is-map "^2.0.3" + is-set "^2.0.3" + is-weakmap "^2.0.2" + is-weakset "^2.0.3" + which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" @@ -19473,6 +20085,17 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== +which-typed-array@^1.1.14, which-typed-array@^1.1.15: + version "1.1.15" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.2" + which-typed-array@^1.1.2, which-typed-array@^1.1.9: version "1.1.9" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" From fdc5dd23d2f2dc97a657a311640bf08339bb8237 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Sun, 18 Aug 2024 14:18:20 +1000 Subject: [PATCH 34/46] Codemod next image --- next.config.js | 2 +- .../components/AboutTheProtocolSection.tsx | 2 +- .../AboutDashboard/components/HeroSection.tsx | 2 +- .../components/JuiceboxDaoSection.tsx | 2 +- .../components/OurMissionSection.tsx | 2 +- src/components/Contact/Contact.tsx | 2 +- .../ReviewDeploy/components/DeploySuccess.tsx | 2 +- src/components/DomainBadge.tsx | 2 +- .../BuiltForSection/BuiltForBlobAndImage.tsx | 2 +- .../Home/ConclusionSection/ConclusionSection.tsx | 2 +- .../HowJuiceboxWorksSection.tsx | 2 +- .../components/ExploreCategories.tsx | 2 +- .../SuccessStoriesSection/SuccessStoriesCard.tsx | 2 +- src/components/IconedImage.tsx | 2 +- .../JuiceVideo/JuiceVideoOrImgPreview.tsx | 2 +- .../JuiceVideo/JuiceVideoThumbnailOrImage.tsx | 2 +- src/components/Logo.tsx | 2 +- .../NftRewards/RewardImage/RewardImage.tsx | 2 +- .../Project/ProjectHeader/CoverPhoto.tsx | 2 +- .../Project/ProjectTabs/EmptyScreen.tsx | 2 +- .../RichNote/hooks/useProcessedRichNote.ts | 2 +- src/components/inputs/FormattedNumberInput.tsx | 2 +- .../AttachStickerModal/AttachableSticker.tsx | 2 +- src/components/modals/TransactionModal.tsx | 2 +- .../PayProjectModal/PayProjectModal.tsx | 2 +- .../LaunchNftCollection/EnableNftsCard.tsx | 2 +- .../PayProjectModal/PayProjectModal.tsx | 2 +- src/pages/success-stories/constitutiondao.tsx | 2 +- src/pages/success-stories/moondao.tsx | 2 +- src/pages/success-stories/sharkdao.tsx | 2 +- src/pages/success-stories/studiodao.tsx | 2 +- src/utils/bigNumbers.ts | 16 +++++++--------- src/utils/format/formatNumber.ts | 4 ++-- src/utils/string.ts | 2 +- src/utils/url.ts | 4 ++-- 35 files changed, 43 insertions(+), 45 deletions(-) diff --git a/next.config.js b/next.config.js index be5622c9ce..50919d1bd3 100644 --- a/next.config.js +++ b/next.config.js @@ -176,7 +176,7 @@ const nextConfig = removeImports({ ...SECURITY_HEADERS, ], }, - ] + ]; }, images: { remotePatterns: [ diff --git a/src/components/AboutDashboard/components/AboutTheProtocolSection.tsx b/src/components/AboutDashboard/components/AboutTheProtocolSection.tsx index f345633d45..8e0ed4698d 100644 --- a/src/components/AboutDashboard/components/AboutTheProtocolSection.tsx +++ b/src/components/AboutDashboard/components/AboutTheProtocolSection.tsx @@ -3,7 +3,7 @@ import { Trans, t } from '@lingui/macro' import { Button } from 'antd' import ExternalLink from 'components/ExternalLink' import { TickIconListItem } from 'components/TickIconListItem' -import Image from 'next/image' +import Image from "next/legacy/image" import { SectionContainer } from './SectionContainer' import illustration from '/public/assets/images/about/illustration2.webp' diff --git a/src/components/AboutDashboard/components/HeroSection.tsx b/src/components/AboutDashboard/components/HeroSection.tsx index b6d990e766..a15694a30b 100644 --- a/src/components/AboutDashboard/components/HeroSection.tsx +++ b/src/components/AboutDashboard/components/HeroSection.tsx @@ -1,5 +1,5 @@ import { Trans } from '@lingui/macro' -import Image from 'next/image' +import Image from "next/legacy/image" import { twMerge } from 'tailwind-merge' import { SectionContainer } from './SectionContainer' import illustration from '/public/assets/images/about/hero.webp' diff --git a/src/components/AboutDashboard/components/JuiceboxDaoSection.tsx b/src/components/AboutDashboard/components/JuiceboxDaoSection.tsx index a5768e008d..e5e1bb77d2 100644 --- a/src/components/AboutDashboard/components/JuiceboxDaoSection.tsx +++ b/src/components/AboutDashboard/components/JuiceboxDaoSection.tsx @@ -1,5 +1,5 @@ import { Trans } from '@lingui/macro' -import Image from 'next/image' +import Image from "next/legacy/image" import { JoinOurDiscordButton } from './JoinOurDiscordButton' import { SectionContainer } from './SectionContainer' import illustration from '/public/assets/images/about/illustration3.webp' diff --git a/src/components/AboutDashboard/components/OurMissionSection.tsx b/src/components/AboutDashboard/components/OurMissionSection.tsx index 88c9ad3369..f0b139587c 100644 --- a/src/components/AboutDashboard/components/OurMissionSection.tsx +++ b/src/components/AboutDashboard/components/OurMissionSection.tsx @@ -2,7 +2,7 @@ import { Trans } from '@lingui/macro' import { ONE_BILLION } from 'constants/numbers' import { useProtocolLogQuery } from 'generated/graphql' import { client } from 'lib/apollo/client' -import Image from 'next/image' +import Image from "next/legacy/image" import { twMerge } from 'tailwind-merge' import { formatAmount } from 'utils/format/formatAmount' import { fromWad } from 'utils/format/formatNumber' diff --git a/src/components/Contact/Contact.tsx b/src/components/Contact/Contact.tsx index 054e48aa3a..d5fd639901 100644 --- a/src/components/Contact/Contact.tsx +++ b/src/components/Contact/Contact.tsx @@ -6,7 +6,7 @@ import { JuiceTextArea } from 'components/inputs/JuiceTextArea' import { JuiceInput } from 'components/inputs/JuiceTextInput' import { ThemeContext } from 'contexts/Theme/ThemeContext' import { createContactMessage } from 'lib/api/discord' -import Image from 'next/image' +import Image from "next/legacy/image" import { useContext, useState } from 'react' import contactHeroDark from '/public/assets/images/contact-hero-od.webp' import contactHeroLight from '/public/assets/images/contact-hero-ol.webp' diff --git a/src/components/Create/components/pages/ReviewDeploy/components/DeploySuccess.tsx b/src/components/Create/components/pages/ReviewDeploy/components/DeploySuccess.tsx index 3966a80168..1a26890e68 100644 --- a/src/components/Create/components/pages/ReviewDeploy/components/DeploySuccess.tsx +++ b/src/components/Create/components/pages/ReviewDeploy/components/DeploySuccess.tsx @@ -7,7 +7,7 @@ import { XLButton } from 'components/buttons/XLButton' import { readNetwork } from 'constants/networks' import { useWallet } from 'hooks/Wallet' import { NetworkName } from 'models/networkName' -import Image from 'next/image' +import Image from "next/legacy/image" import { useRouter } from 'next/router' import { useCallback, useMemo, useState } from 'react' import DeploySuccessHero from '/public/assets/images/create-success-hero.webp' diff --git a/src/components/DomainBadge.tsx b/src/components/DomainBadge.tsx index a8edf9716a..a3c3f12c7c 100644 --- a/src/components/DomainBadge.tsx +++ b/src/components/DomainBadge.tsx @@ -1,4 +1,4 @@ -import Image from 'next/image' +import Image from "next/legacy/image" import { useMemo } from 'react' import { twMerge } from 'tailwind-merge' import { Badge } from './Badge' diff --git a/src/components/Home/BuiltForSection/BuiltForBlobAndImage.tsx b/src/components/Home/BuiltForSection/BuiltForBlobAndImage.tsx index f447ae410f..0f1d6c9bd7 100644 --- a/src/components/Home/BuiltForSection/BuiltForBlobAndImage.tsx +++ b/src/components/Home/BuiltForSection/BuiltForBlobAndImage.tsx @@ -1,5 +1,5 @@ import { ThemeContext } from 'contexts/Theme/ThemeContext' -import Image from 'next/image' +import Image from "next/legacy/image" import { useContext } from 'react' import buildersImage from '/public/assets/images/home/why-juicebox/builders.webp' import crowdfundingImage from '/public/assets/images/home/why-juicebox/crowdfunding.webp' diff --git a/src/components/Home/ConclusionSection/ConclusionSection.tsx b/src/components/Home/ConclusionSection/ConclusionSection.tsx index 6e5943941b..9aa3181511 100644 --- a/src/components/Home/ConclusionSection/ConclusionSection.tsx +++ b/src/components/Home/ConclusionSection/ConclusionSection.tsx @@ -2,7 +2,7 @@ import { Trans } from '@lingui/macro' import { Button } from 'antd' import { TickIconList } from 'components/Home/ConclusionSection/TickIconList' import { SectionContainer } from 'components/Home/SectionContainer' -import Image from 'next/image' +import Image from "next/legacy/image" import Link from 'next/link' export function ConclusionSection() { diff --git a/src/components/Home/HowJuiceboxWorksSection/HowJuiceboxWorksSection.tsx b/src/components/Home/HowJuiceboxWorksSection/HowJuiceboxWorksSection.tsx index c5b10ca444..da557c5792 100644 --- a/src/components/Home/HowJuiceboxWorksSection/HowJuiceboxWorksSection.tsx +++ b/src/components/Home/HowJuiceboxWorksSection/HowJuiceboxWorksSection.tsx @@ -8,7 +8,7 @@ import ExternalLink from 'components/ExternalLink' import { SectionContainer } from 'components/Home/SectionContainer' import { SectionHeading } from 'components/Home/SectionHeading' import { XLButton } from 'components/buttons/XLButton' -import Image from 'next/image' +import Image from "next/legacy/image" import Link from 'next/link' import sassyBlueberry from '/public/assets/images/sassy-blueberry.webp' diff --git a/src/components/Home/JuicyPicksSection/components/ExploreCategories.tsx b/src/components/Home/JuicyPicksSection/components/ExploreCategories.tsx index 73e62b9390..d31b6021cf 100644 --- a/src/components/Home/JuicyPicksSection/components/ExploreCategories.tsx +++ b/src/components/Home/JuicyPicksSection/components/ExploreCategories.tsx @@ -6,7 +6,7 @@ import { SectionHeading } from 'components/Home/SectionHeading' import Loading from 'components/Loading' import template from 'lodash/template' import { projectTagText } from 'models/project-tags' -import Image from 'next/image' +import Image from "next/legacy/image" export const ExploreCategories = () => { const { tags, isLoading } = useExploreCategories() diff --git a/src/components/Home/SuccessStoriesSection/SuccessStoriesCard.tsx b/src/components/Home/SuccessStoriesSection/SuccessStoriesCard.tsx index 62b9f0487b..ac3516f259 100644 --- a/src/components/Home/SuccessStoriesSection/SuccessStoriesCard.tsx +++ b/src/components/Home/SuccessStoriesSection/SuccessStoriesCard.tsx @@ -5,7 +5,7 @@ import ETHAmount from 'components/currency/ETHAmount' import ProjectLogo from 'components/ProjectLogo' import { useProjectMetadata } from 'hooks/useProjectMetadata' import { ProjectTagName, projectTagText } from 'models/project-tags' -import Image from 'next/image' +import Image from "next/legacy/image" import Link from 'next/link' import { diff --git a/src/components/IconedImage.tsx b/src/components/IconedImage.tsx index 3b9b3edb7a..a7d7538e16 100644 --- a/src/components/IconedImage.tsx +++ b/src/components/IconedImage.tsx @@ -1,4 +1,4 @@ -import { ImageProps } from 'next/image' +import { ImageProps } from "next/legacy/image" import { ReactNode } from 'react' import { JuiceVideoThumbnailOrImage } from './JuiceVideo/JuiceVideoThumbnailOrImage' diff --git a/src/components/JuiceVideo/JuiceVideoOrImgPreview.tsx b/src/components/JuiceVideo/JuiceVideoOrImgPreview.tsx index 93ab5a1521..24d04eb4b5 100644 --- a/src/components/JuiceVideo/JuiceVideoOrImgPreview.tsx +++ b/src/components/JuiceVideo/JuiceVideoOrImgPreview.tsx @@ -1,7 +1,7 @@ import { CloseOutlined } from '@ant-design/icons' import { JuiceVideoPreview } from 'components/JuiceVideo/JuiceVideoPreview' import { useContentType } from 'hooks/useContentType' -import { ImageProps } from 'next/image' +import { ImageProps } from "next/legacy/image" import { stopPropagation } from 'react-stop-propagation' import { fileTypeIsVideo } from 'utils/nftRewards' diff --git a/src/components/JuiceVideo/JuiceVideoThumbnailOrImage.tsx b/src/components/JuiceVideo/JuiceVideoThumbnailOrImage.tsx index 8f693d536c..3f7323f81d 100644 --- a/src/components/JuiceVideo/JuiceVideoThumbnailOrImage.tsx +++ b/src/components/JuiceVideo/JuiceVideoThumbnailOrImage.tsx @@ -1,6 +1,6 @@ import { LoadingOutlined } from '@ant-design/icons' import { useContentType } from 'hooks/useContentType' -import { ImageProps } from 'next/image' +import { ImageProps } from "next/legacy/image" import { useCallback, useState } from 'react' import { twMerge } from 'tailwind-merge' import { fileTypeIsVideo } from 'utils/nftRewards' diff --git a/src/components/Logo.tsx b/src/components/Logo.tsx index db69bf99db..dc08b071ed 100644 --- a/src/components/Logo.tsx +++ b/src/components/Logo.tsx @@ -1,6 +1,6 @@ import { ThemeOption } from 'constants/theme/themeOption' import { ThemeContext } from 'contexts/Theme/ThemeContext' -import Image from 'next/image' +import Image from "next/legacy/image" import { useContext } from 'react' import { twMerge } from 'tailwind-merge' import LIGHT_JUICE_LOGO from '/public/assets/juice-logo-full_black.svg' diff --git a/src/components/NftRewards/RewardImage/RewardImage.tsx b/src/components/NftRewards/RewardImage/RewardImage.tsx index b9047c67e6..e9ddf9268a 100644 --- a/src/components/NftRewards/RewardImage/RewardImage.tsx +++ b/src/components/NftRewards/RewardImage/RewardImage.tsx @@ -1,4 +1,4 @@ -import { ImageProps } from 'next/image' +import { ImageProps } from "next/legacy/image" import { stopPropagation } from 'react-stop-propagation' import { classNames } from 'utils/classNames' diff --git a/src/components/Project/ProjectHeader/CoverPhoto.tsx b/src/components/Project/ProjectHeader/CoverPhoto.tsx index 4e68c61975..28e88d2728 100644 --- a/src/components/Project/ProjectHeader/CoverPhoto.tsx +++ b/src/components/Project/ProjectHeader/CoverPhoto.tsx @@ -1,5 +1,5 @@ // import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' -import Image from 'next/image' +import Image from "next/legacy/image" import { useMemo } from 'react' import { twMerge } from 'tailwind-merge' import { useCoverPhoto } from './hooks/useCoverPhoto' diff --git a/src/components/Project/ProjectTabs/EmptyScreen.tsx b/src/components/Project/ProjectTabs/EmptyScreen.tsx index 7c0a85e26c..2004abc1e7 100644 --- a/src/components/Project/ProjectTabs/EmptyScreen.tsx +++ b/src/components/Project/ProjectTabs/EmptyScreen.tsx @@ -1,6 +1,6 @@ import { t } from '@lingui/macro' import { useJuiceTheme } from 'contexts/Theme/useJuiceTheme' -import Image from 'next/image' +import Image from "next/legacy/image" import { twMerge } from 'tailwind-merge' export const EmptyScreen = ({ diff --git a/src/components/RichNote/hooks/useProcessedRichNote.ts b/src/components/RichNote/hooks/useProcessedRichNote.ts index d36af95314..55f340227a 100644 --- a/src/components/RichNote/hooks/useProcessedRichNote.ts +++ b/src/components/RichNote/hooks/useProcessedRichNote.ts @@ -44,7 +44,7 @@ export const useProcessedRichNote = (note: string | undefined) => { ?.split('\n') .map(line => { if (line.match(URLRegex)) { - return line.replace(/\s/g, '') //remove any whitespace + return line.replace(/\s/g, ''); //remove any whitespace } return '' }) diff --git a/src/components/inputs/FormattedNumberInput.tsx b/src/components/inputs/FormattedNumberInput.tsx index 944cea899e..a7f822ae45 100644 --- a/src/components/inputs/FormattedNumberInput.tsx +++ b/src/components/inputs/FormattedNumberInput.tsx @@ -110,5 +110,5 @@ export default function FormattedNumberInput({ {accessory &&
{accessory}
}
- ) + ); } diff --git a/src/components/modals/AttachStickerModal/AttachableSticker.tsx b/src/components/modals/AttachStickerModal/AttachableSticker.tsx index e05bd2422c..f52f0efbe4 100644 --- a/src/components/modals/AttachStickerModal/AttachableSticker.tsx +++ b/src/components/modals/AttachStickerModal/AttachableSticker.tsx @@ -1,4 +1,4 @@ -import Image from 'next/image' +import Image from "next/legacy/image" import { PaymentMemoSticker } from './paymentMemoSticker' export const AttachableSticker = ({ diff --git a/src/components/modals/TransactionModal.tsx b/src/components/modals/TransactionModal.tsx index 9fc3b523aa..2b51768c40 100644 --- a/src/components/modals/TransactionModal.tsx +++ b/src/components/modals/TransactionModal.tsx @@ -4,7 +4,7 @@ import { readNetwork } from 'constants/networks' import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' import { useWallet } from 'hooks/Wallet' import { TxStatus } from 'models/transaction' -import Image from 'next/image' +import Image from "next/legacy/image" import { PropsWithChildren, useContext, useMemo } from 'react' import EtherscanLink from '../EtherscanLink' diff --git a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/PayProjectModal.tsx b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/PayProjectModal.tsx index 40725f1c79..53e4a0124c 100644 --- a/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/PayProjectModal.tsx +++ b/src/packages/v2v3/components/V2V3Project/ProjectDashboard/components/PayRedeemCard/PayProjectModal/PayProjectModal.tsx @@ -3,7 +3,7 @@ import EtherscanLink from 'components/EtherscanLink' import ExternalLink from 'components/ExternalLink' import { JuiceModal } from 'components/modals/JuiceModal' import { Formik } from 'formik' -import Image from 'next/image' +import Image from "next/legacy/image" import { twMerge } from 'tailwind-merge' import { helpPagePath } from 'utils/routes' import { MessageSection } from './components/MessageSection' diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/LaunchNftCollection/EnableNftsCard.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/LaunchNftCollection/EnableNftsCard.tsx index c8ab9b2eed..9fd6f4d9a4 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/LaunchNftCollection/EnableNftsCard.tsx +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/LaunchNftCollection/EnableNftsCard.tsx @@ -1,6 +1,6 @@ import { Trans } from '@lingui/macro' import { Button } from 'antd' -import Image from 'next/image' +import Image from "next/legacy/image" import { useState } from 'react' import { EnableNftsModal } from './EnableNftsModal' import noNftsImage from '/public/assets/images/settings/no-nfts.webp' diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/PayProjectModal.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/PayProjectModal.tsx index 40725f1c79..53e4a0124c 100644 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/PayProjectModal.tsx +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/PayProjectModal.tsx @@ -3,7 +3,7 @@ import EtherscanLink from 'components/EtherscanLink' import ExternalLink from 'components/ExternalLink' import { JuiceModal } from 'components/modals/JuiceModal' import { Formik } from 'formik' -import Image from 'next/image' +import Image from "next/legacy/image" import { twMerge } from 'tailwind-merge' import { helpPagePath } from 'utils/routes' import { MessageSection } from './components/MessageSection' diff --git a/src/pages/success-stories/constitutiondao.tsx b/src/pages/success-stories/constitutiondao.tsx index 018de76868..5542f76b40 100644 --- a/src/pages/success-stories/constitutiondao.tsx +++ b/src/pages/success-stories/constitutiondao.tsx @@ -9,7 +9,7 @@ import { CASE_STUDY_PROJECTS, CONSTITUTION_FUNDING_CONFIG, } from 'constants/successStoryProjects' -import Image from 'next/image' +import Image from "next/legacy/image" import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' export default function ConstitutionDAOPage() { diff --git a/src/pages/success-stories/moondao.tsx b/src/pages/success-stories/moondao.tsx index 9f33940dab..1ec4ebb314 100644 --- a/src/pages/success-stories/moondao.tsx +++ b/src/pages/success-stories/moondao.tsx @@ -9,7 +9,7 @@ import { CASE_STUDY_PROJECTS, MOONDAO_FUNDING_CONFIG, } from 'constants/successStoryProjects' -import Image from 'next/image' +import Image from "next/legacy/image" import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' export default function MoonDAOPage() { diff --git a/src/pages/success-stories/sharkdao.tsx b/src/pages/success-stories/sharkdao.tsx index c7e3b1a0e0..41054bee07 100644 --- a/src/pages/success-stories/sharkdao.tsx +++ b/src/pages/success-stories/sharkdao.tsx @@ -9,7 +9,7 @@ import { CASE_STUDY_PROJECTS, SHARKDAO_FUNDING_CONFIG, } from 'constants/successStoryProjects' -import Image from 'next/image' +import Image from "next/legacy/image" import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' export default function SharkDAOPage() { diff --git a/src/pages/success-stories/studiodao.tsx b/src/pages/success-stories/studiodao.tsx index 3c7faa6075..2741dc648e 100644 --- a/src/pages/success-stories/studiodao.tsx +++ b/src/pages/success-stories/studiodao.tsx @@ -9,7 +9,7 @@ import { CASE_STUDY_PROJECTS, STUDIODAO_FUNDING_CONFIG, } from 'constants/successStoryProjects' -import Image from 'next/image' +import Image from "next/legacy/image" import globalGetServerSideProps from 'utils/next-server/globalGetServerSideProps' export default function StudioDAOPage() { diff --git a/src/utils/bigNumbers.ts b/src/utils/bigNumbers.ts index 582e56619f..a1129642d9 100644 --- a/src/utils/bigNumbers.ts +++ b/src/utils/bigNumbers.ts @@ -4,15 +4,13 @@ import { isBytes, isHexString } from 'ethers/lib/utils' import { parseWad } from './format/formatNumber' export function isBigNumberish(value: unknown): value is BigNumberish { - return ( - value != null && - (BigNumber.isBigNumber(value) || - (typeof value === 'number' && value % 1 === 0) || - (typeof value === 'string' && !!value.match(/^-?[0-9]+$/)) || - isHexString(value) || - typeof value === 'bigint' || - isBytes(value)) - ) + return value != null && + (BigNumber.isBigNumber(value) || + (typeof value === 'number' && value % 1 === 0) || + (typeof value === 'string' && !!value.match(/^-?[0-9]+$/)) || + isHexString(value) || + typeof value === 'bigint' || + isBytes(value)); } export const bigNumbersDiff = (a?: BigNumber, b?: BigNumber) => { diff --git a/src/utils/format/formatNumber.ts b/src/utils/format/formatNumber.ts index be6019f6bc..8b8db46001 100644 --- a/src/utils/format/formatNumber.ts +++ b/src/utils/format/formatNumber.ts @@ -161,12 +161,12 @@ export const fracDiv = (quotient: string, dividend: string) => { const separateThousands = (str?: string, separator = thousandsSeparator) => { if (!str?.trim().length) return - return str.replace(/\B(?=(\d{3})+(?!\d))/g, separator) + return str.replace(/\B(?=(\d{3})+(?!\d))/g, separator); } // Strips string of all commas export const stripCommas = (string: string) => { - return string.replace(/,/g, '') + return string.replace(/,/g, ''); } export const formattedNum = ( diff --git a/src/utils/string.ts b/src/utils/string.ts index a24363ee0e..33d30a4b57 100644 --- a/src/utils/string.ts +++ b/src/utils/string.ts @@ -1,3 +1,3 @@ export const stripHtmlTags = (html: string): string => { - return html.replace(/<[^>]*>/g, '') + return html.replace(/<[^>]*>/g, ''); } diff --git a/src/utils/url.ts b/src/utils/url.ts index 9a8532d176..b0064a4fd7 100644 --- a/src/utils/url.ts +++ b/src/utils/url.ts @@ -1,13 +1,13 @@ export const prettyUrl = (url: string) => { if (url.startsWith('https://')) { if (url.endsWith('/')) { - return url.replace(/https:|[/]/g, '') + return url.replace(/https:|[/]/g, ''); } return url.split('https://')[1] } else if (url.startsWith('http://')) { if (url.endsWith('/')) { - return url.replace(/https:|[/]/g, '') + return url.replace(/https:|[/]/g, ''); } return url.split('http://')[1] From bf85b52127df7a955cda37e7174de55d165076ae Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Sun, 18 Aug 2024 14:22:03 +1000 Subject: [PATCH 35/46] fix api/image/url warnings --- src/pages/api/image/[url].ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/api/image/[url].ts b/src/pages/api/image/[url].ts index 3880ce8d06..b599eec6fa 100644 --- a/src/pages/api/image/[url].ts +++ b/src/pages/api/image/[url].ts @@ -49,7 +49,8 @@ export default async function handler( 'image/vnd.mozilla.apng', ] if (!acceptedTypes.includes(contentType)) { - return res.status(403).json({ error: 'Forbidden. Invalid content-type.' }) + res.status(403).json({ error: 'Forbidden. Invalid content-type.' }) + return } // Check the file signature (magic numbers) https://en.wikipedia.org/wiki/List_of_file_signatures @@ -69,14 +70,13 @@ export default async function handler( data[3] === 0x38 ) // GIF ) { - return res - .status(403) - .json({ error: 'Forbidden. Invalid file signature.' }) + res.status(403).json({ error: 'Forbidden. Invalid file signature.' }) + return } - return res.redirect(imageUrl).end() + res.redirect(imageUrl).end() } catch (error) { logger.error({ error }) - return res.status(500).json({ error: 'failed to resolve image' }) + res.status(500).json({ error: 'failed to resolve image' }) } } From e065f072beb55899fa2d5ed32ca7d5bae9370143 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Sun, 18 Aug 2024 14:28:55 +1000 Subject: [PATCH 36/46] Fix --- src/components/Project/ProjectHeader/CoverPhoto.tsx | 2 +- src/components/Project/ProjectTabs/EmptyScreen.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Project/ProjectHeader/CoverPhoto.tsx b/src/components/Project/ProjectHeader/CoverPhoto.tsx index 28e88d2728..03bb834431 100644 --- a/src/components/Project/ProjectHeader/CoverPhoto.tsx +++ b/src/components/Project/ProjectHeader/CoverPhoto.tsx @@ -1,5 +1,5 @@ // import { useProjectMetadataContext } from 'contexts/ProjectMetadataContext' -import Image from "next/legacy/image" +import Image from "next/image" import { useMemo } from 'react' import { twMerge } from 'tailwind-merge' import { useCoverPhoto } from './hooks/useCoverPhoto' diff --git a/src/components/Project/ProjectTabs/EmptyScreen.tsx b/src/components/Project/ProjectTabs/EmptyScreen.tsx index 2004abc1e7..66eeb8c31b 100644 --- a/src/components/Project/ProjectTabs/EmptyScreen.tsx +++ b/src/components/Project/ProjectTabs/EmptyScreen.tsx @@ -1,6 +1,6 @@ import { t } from '@lingui/macro' import { useJuiceTheme } from 'contexts/Theme/useJuiceTheme' -import Image from "next/legacy/image" +import Image from "next/image" import { twMerge } from 'tailwind-merge' export const EmptyScreen = ({ From 8d66985d942c4dc7ae288ef7781252a1b3e76f5b Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Sun, 18 Aug 2024 14:41:43 +1000 Subject: [PATCH 37/46] v4 pay --- .../v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx index 90e3f9b098..72be4e6f70 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectDashboard.tsx @@ -3,7 +3,7 @@ import { SuccessPayView } from 'packages/v4/components/ProjectDashboard/componen import { useProjectDispatch } from 'packages/v4/components/ProjectDashboard/redux/hooks' import { payRedeemActions } from 'packages/v4/components/ProjectDashboard/redux/payRedeemSlice' import { projectCartActions } from 'packages/v4/components/ProjectDashboard/redux/projectCartSlice' -// import { V4PayRedeemCard } from 'packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard' +import { V4PayRedeemCard } from 'packages/v4/components/ProjectDashboard/V4PayRedeemCard/V4PayRedeemCard' import { useEffect } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPageQueries } from './hooks/useProjectPageQueries' @@ -36,12 +36,12 @@ export function V4ProjectDashboard() { '[@media(min-width:960px)]:flex [@media(min-width:960px)]:max-w-6xl [@media(min-width:960px)]:justify-between [@media(min-width:960px)]:gap-x-8', )} > - {/* */} + /> {/* Date: Sun, 18 Aug 2024 15:02:07 +1000 Subject: [PATCH 38/46] More antd icons --- src/components/FormItemWarningText.tsx | 4 ++-- src/components/Loading.tsx | 2 +- .../ProjectHeader/EditProjectHandleButton.tsx | 4 ++-- .../Project/ProjectHeader/GnosisSafeBadge.tsx | 2 +- src/components/Projects/TrendingProjects.tsx | 8 ++++---- .../QuickProjectSearchModal.tsx | 18 ++++++++++-------- .../buttons/SubscribeButton/SubscribeModal.tsx | 4 ++-- src/components/currency/ETHToUSD.tsx | 2 +- .../v4/components/PayoutsTable/HeaderRows.tsx | 10 ++++++---- .../v4/components/PayoutsTable/PayoutTitle.tsx | 4 ++-- .../SplitItem/EthAddressBeneficiary.tsx | 2 +- .../SplitList/SplitItem/LockedUntilValue.tsx | 4 ++-- .../SplitList/SplitItem/SplitAmountValue.tsx | 4 ++-- 13 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/components/FormItemWarningText.tsx b/src/components/FormItemWarningText.tsx index 23e4f1ad0f..fda30e6a84 100644 --- a/src/components/FormItemWarningText.tsx +++ b/src/components/FormItemWarningText.tsx @@ -1,9 +1,9 @@ -import { InfoCircleOutlined } from '@ant-design/icons' +import { InformationCircleIcon } from '@heroicons/react/24/outline' import { PropsWithChildren } from 'react' export default function FormItemWarningText({ children, - icon = , + icon = , }: PropsWithChildren<{ icon?: JSX.Element }>) { return (

diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx index 3075be3c05..fb50821208 100644 --- a/src/components/Loading.tsx +++ b/src/components/Loading.tsx @@ -1,4 +1,4 @@ -import { LoadingOutlined } from '@ant-design/icons' +import LoadingOutlined from '@ant-design/icons/LoadingOutlined' import { Spin } from 'antd' import { SpinSize } from 'antd/lib/spin' import { twMerge } from 'tailwind-merge' diff --git a/src/components/Project/ProjectHeader/EditProjectHandleButton.tsx b/src/components/Project/ProjectHeader/EditProjectHandleButton.tsx index 1b0afefbd9..1aab19889e 100644 --- a/src/components/Project/ProjectHeader/EditProjectHandleButton.tsx +++ b/src/components/Project/ProjectHeader/EditProjectHandleButton.tsx @@ -1,4 +1,4 @@ -import { EditOutlined } from '@ant-design/icons' +import { PencilSquareIcon } from '@heroicons/react/24/outline' import { t, Trans } from '@lingui/macro' import { Button, Tooltip } from 'antd' import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' @@ -24,7 +24,7 @@ export function EditProjectHandleButton() { })} legacyBehavior > -