Skip to content

Commit

Permalink
Update to prod (#4489)
Browse files Browse the repository at this point in the history
  • Loading branch information
wraeth-eth authored Oct 27, 2024
1 parent 8823ae0 commit 8402e3f
Show file tree
Hide file tree
Showing 12 changed files with 318 additions and 70 deletions.
10 changes: 1 addition & 9 deletions src/components/Project/ProjectTabs/ProjectTab.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Tab } from '@headlessui/react'
import { ReactNode, useRef } from 'react'
import React, { ReactNode, useRef } from 'react'
import { twMerge } from 'tailwind-merge'

interface ProjectTabProps {
Expand All @@ -26,14 +26,6 @@ export const ProjectTab: React.FC<ProjectTabProps> = ({
onClick={onClick}
>
{({ selected }) => {
if (selected && tabRef.current) {
tabRef.current.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'start',
})
}

return (
<div
className={twMerge(
Expand Down
61 changes: 55 additions & 6 deletions src/components/VolumeChart/components/TimelineViewSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,65 @@
import { t } from '@lingui/macro'
import { JuiceListbox } from 'components/inputs/JuiceListbox'
import React from 'react'
import { classNames } from 'utils/classNames'
import { twMerge } from 'tailwind-merge'
import { ProjectTimelineView } from '../types'

export default function TimelineViewSelector({
export default function TimelineViewSelector(props: {
timelineView: ProjectTimelineView
setTimelineView: React.Dispatch<React.SetStateAction<ProjectTimelineView>>
}) {
return (
<>
<MobileTimelineViewSelector {...props} />
<DesktopTimelineViewSelector {...props} />
</>
)
}

const MobileTimelineViewSelector = ({
timelineView,
setTimelineView,
}: {
timelineView: ProjectTimelineView
setTimelineView: React.Dispatch<React.SetStateAction<ProjectTimelineView>>
}) {
}) => {
const opts = (): { label: string; value: ProjectTimelineView }[] => [
{
label: t`Volume`,
value: 'volume',
},
{
label: t`In Juicebox`,
value: 'balance',
},
{
label: t`Trending`,
value: 'trendingScore',
},
]

const handleChange = (value: ProjectTimelineView) => {
setTimelineView(value)
}

return (
<JuiceListbox
className="w-full max-w-[116px] text-xs uppercase md:hidden"
buttonClassName="text-xs uppercase py-1 px-2"
options={opts()}
value={opts().find(o => o.value === timelineView)}
onChange={v => handleChange(v.value)}
/>
)
}

const DesktopTimelineViewSelector = ({
timelineView,
setTimelineView,
}: {
timelineView: ProjectTimelineView
setTimelineView: React.Dispatch<React.SetStateAction<ProjectTimelineView>>
}) => {
const tab = (view: ProjectTimelineView) => {
const selected = view === timelineView

Expand All @@ -28,7 +78,7 @@ export default function TimelineViewSelector({

return (
<div
className={classNames(
className={twMerge(
'cursor-pointer text-sm uppercase',
selected
? 'font-medium text-grey-500 dark:text-slate-100'
Expand All @@ -40,9 +90,8 @@ export default function TimelineViewSelector({
</div>
)
}

return (
<div className="flex gap-3">
<div className="mb-2 hidden gap-3 md:flex">
{tab('volume')}
{tab('balance')}
{tab('trendingScore')}
Expand Down
2 changes: 1 addition & 1 deletion src/components/inputs/FormattedNumberInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,5 @@ export default function FormattedNumberInput({
{accessory && <div>{accessory}</div>}
</div>
</div>
);
)
}
3 changes: 3 additions & 0 deletions src/locales/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ msgstr ""
msgid "Project tokens"
msgstr ""

msgid "NFT Credits"
msgstr ""

msgid "You must grant permission to migrate your V1 tokens."
msgstr ""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ import EtherscanLink from 'components/EtherscanLink'
import ExternalLink from 'components/ExternalLink'
import { JuiceModal } from 'components/modals/JuiceModal'
import { Formik } from 'formik'
import Image from "next/legacy/image"
import { useWallet } from 'hooks/Wallet'
import Image from 'next/legacy/image'
import { useNftCredits } from 'packages/v2v3/hooks/JB721Delegate/useNftCredits'
import React, { ReactNode } from 'react'
import { twMerge } from 'tailwind-merge'
import { helpPagePath } from 'utils/helpPagePath'
import { MessageSection } from './components/MessageSection'
import { ReceiveSection } from './components/ReceiveSection'
import { usePayAmounts } from './hooks/usePayAmounts'
import {
PayProjectModalFormValues,
usePayProjectModal,
Expand All @@ -16,8 +20,6 @@ import {
export const PayProjectModal: React.FC = () => {
const {
open,
primaryAmount,
secondaryAmount,
validationSchema,
isTransactionPending,
isTransactionConfirmed,
Expand All @@ -27,6 +29,7 @@ export const PayProjectModal: React.FC = () => {
setOpen,
onPaySubmit,
} = usePayProjectModal()
const { formattedTotalAmount } = usePayAmounts()

return (
<Formik<PayProjectModalFormValues>
Expand All @@ -50,7 +53,7 @@ export const PayProjectModal: React.FC = () => {
position="top"
okLoading={props.isSubmitting || isTransactionPending}
okButtonForm="PayProjectModalForm"
okText={t`Pay ${primaryAmount}`}
okText={t`Pay ${formattedTotalAmount.primaryAmount}`}
cancelText={
isTransactionPending || isTransactionConfirmed
? t`Close`
Expand Down Expand Up @@ -97,19 +100,7 @@ export const PayProjectModal: React.FC = () => {
) : (
<>
<div className="flex flex-col divide-y divide-grey-200 dark:divide-slate-500">
<div className="flex justify-between gap-3 py-3">
<span className="font-medium">
<Trans>Total amount</Trans>
</span>
<div>
<span>{primaryAmount}</span>{' '}
{secondaryAmount && (
<span className="text-grey-500 dark:text-slate-200">
({secondaryAmount})
</span>
)}
</div>
</div>
<AmountSection />

<ReceiveSection className="py-6" />

Expand Down Expand Up @@ -172,3 +163,61 @@ export const PayProjectModal: React.FC = () => {
</Formik>
)
}

const AmountSection = () => {
const { userAddress } = useWallet()
const { data: nftCredits } = useNftCredits(userAddress)
const { formattedAmount, formattedNftCredits, formattedTotalAmount } =
usePayAmounts()

const RowData = ({
label,
primaryAmount,
secondaryAmount,
}: {
label: ReactNode
primaryAmount: ReactNode
secondaryAmount: ReactNode
}) => (
<div className="flex justify-between gap-3 py-3">
<span className="font-medium">{label}</span>
<div>
<span>{primaryAmount}</span>{' '}
{secondaryAmount && (
<span className="text-grey-500 dark:text-slate-200">
({secondaryAmount})
</span>
)}
</div>
</div>
)

if (!nftCredits?.gt(0) || !formattedNftCredits)
return (
<RowData
label={t`Total amount`}
primaryAmount={formattedTotalAmount?.primaryAmount}
secondaryAmount={formattedTotalAmount?.secondaryAmount}
/>
)

return (
<div>
<RowData
label={t`Amount`}
primaryAmount={formattedAmount.primaryAmount}
secondaryAmount={formattedAmount.secondaryAmount}
/>
<RowData
label={t`NFT Credits`}
primaryAmount={`-${formattedNftCredits.primaryAmount}`}
secondaryAmount={`-${formattedNftCredits.secondaryAmount}`}
/>
<RowData
label={t`Total amount`}
primaryAmount={formattedTotalAmount?.primaryAmount}
secondaryAmount={formattedTotalAmount?.secondaryAmount}
/>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { useCurrencyConverter } from 'hooks/useCurrencyConverter'
import { useWallet } from 'hooks/Wallet'
import { useNftCredits } from 'packages/v2v3/hooks/JB721Delegate/useNftCredits'
import {
V2V3_CURRENCY_ETH,
V2V3_CURRENCY_USD,
} from 'packages/v2v3/utils/currency'
import { formatCurrencyAmount } from 'packages/v2v3/utils/formatCurrencyAmount'
import React from 'react'
import { fromWad, parseWad } from 'utils/format/formatNumber'
import { useProjectSelector } from '../../../../redux/hooks'
import { usePayProjectModal } from './usePayProjectModal/usePayProjectModal'

export const usePayAmounts = () => {
const converter = useCurrencyConverter()
const { payAmount } = useProjectSelector(state => state.projectCart)
const { primaryAmount, secondaryAmount } = usePayProjectModal()
const { userAddress } = useWallet()
const { data: nftCreditsData } = useNftCredits(userAddress)

const payAmountRaw = React.useMemo(() => {
if (!payAmount) return

switch (payAmount.currency) {
case V2V3_CURRENCY_ETH:
return {
eth: parseWad(payAmount.amount),
usd: converter.weiToUsd(parseWad(payAmount.amount))!,
}
case V2V3_CURRENCY_USD:
return {
eth: converter.usdToWei(payAmount.amount),
usd: parseWad(payAmount.amount),
}
}
}, [converter, payAmount])

const appliedNFTCreditsRaw = React.useMemo(() => {
if (!payAmountRaw || !nftCreditsData) return

const nftCreditsApplied = payAmountRaw.eth.lt(nftCreditsData)
? payAmountRaw.eth
: nftCreditsData

const eth = nftCreditsApplied
const usd = parseWad(converter.weiToUsd(nftCreditsApplied))!

return {
eth,
usd,
}
}, [converter, nftCreditsData, payAmountRaw])

const formattedNftCredits = React.useMemo(() => {
if (!appliedNFTCreditsRaw || !payAmount) return

switch (payAmount.currency) {
case V2V3_CURRENCY_ETH:
return {
primaryAmount: formatCurrencyAmount({
amount: fromWad(appliedNFTCreditsRaw.eth),
currency: V2V3_CURRENCY_ETH,
}),
secondaryAmount: formatCurrencyAmount({
amount: fromWad(appliedNFTCreditsRaw.usd),
currency: V2V3_CURRENCY_USD,
}),
}
case V2V3_CURRENCY_USD:
return {
primaryAmount: formatCurrencyAmount({
amount: fromWad(appliedNFTCreditsRaw.usd),
currency: V2V3_CURRENCY_USD,
}),
secondaryAmount: formatCurrencyAmount({
amount: fromWad(appliedNFTCreditsRaw.eth),
currency: V2V3_CURRENCY_ETH,
}),
}
}
}, [appliedNFTCreditsRaw, payAmount])

const formattedTotalAmount = React.useMemo(() => {
if (!payAmountRaw || !payAmount) return

if (!appliedNFTCreditsRaw) {
return {
primaryAmount: primaryAmount,
secondaryAmount: secondaryAmount,
}
}

const totalEth = payAmountRaw.eth.sub(appliedNFTCreditsRaw.eth)
const totalUsd = converter.weiToUsd(parseWad(totalEth))

const formattedEth = formatCurrencyAmount({
amount: fromWad(totalEth),
currency: V2V3_CURRENCY_ETH,
})
const formattedUsd = formatCurrencyAmount({
amount: fromWad(totalUsd),
currency: V2V3_CURRENCY_USD,
})

switch (payAmount?.currency) {
case V2V3_CURRENCY_ETH:
return {
primaryAmount: formattedEth,
secondaryAmount: formattedUsd,
}
case V2V3_CURRENCY_USD:
return {
primaryAmount: formattedUsd,
secondaryAmount: formattedEth,
}
}
}, [
appliedNFTCreditsRaw,
converter,
payAmount,
payAmountRaw,
primaryAmount,
secondaryAmount,
])

return {
formattedAmount: { primaryAmount, secondaryAmount },
formattedNftCredits: {
primaryAmount: formattedNftCredits?.primaryAmount,
secondaryAmount: formattedNftCredits?.secondaryAmount,
},
formattedTotalAmount: {
primaryAmount: formattedTotalAmount?.primaryAmount,
secondaryAmount: formattedTotalAmount?.secondaryAmount,
},
}
}
Loading

0 comments on commit 8402e3f

Please sign in to comment.