From 33f3fe708d5aa0962d1e76cd2104989985a1bf5d Mon Sep 17 00:00:00 2001 From: WRadoslaw <92513933+WRadoslaw@users.noreply.github.com> Date: Tue, 10 Oct 2023 12:03:06 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=98=AE=E2=80=8D=F0=9F=92=A8=20Start=20rev?= =?UTF-8?q?enue=20share=20modal=20(#4869)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add start revenue share modal * CR fixes * CR fixes v2 * Lint --- .../StartRevenueShareModal.tsx | 235 ++++++++++++++++++ .../AuctionDatePicker/AuctionDatePicker.tsx | 1 + .../studio/CrtDashboard/CrtDashboard.tsx | 22 +- 3 files changed, 253 insertions(+), 5 deletions(-) create mode 100644 packages/atlas/src/components/_crt/StartRevenueShareModal/StartRevenueShareModal.tsx diff --git a/packages/atlas/src/components/_crt/StartRevenueShareModal/StartRevenueShareModal.tsx b/packages/atlas/src/components/_crt/StartRevenueShareModal/StartRevenueShareModal.tsx new file mode 100644 index 0000000000..8d2266891a --- /dev/null +++ b/packages/atlas/src/components/_crt/StartRevenueShareModal/StartRevenueShareModal.tsx @@ -0,0 +1,235 @@ +import styled from '@emotion/styled' +import { useCallback, useMemo } from 'react' +import { Controller, useForm } from 'react-hook-form' + +import { FlexBox } from '@/components/FlexBox/FlexBox' +import { JoyTokenIcon } from '@/components/JoyTokenIcon' +import { NumberFormat } from '@/components/NumberFormat' +import { Text } from '@/components/Text' +import { TextButton } from '@/components/_buttons/Button' +import { AuctionDatePicker, AuctionDatePickerProps } from '@/components/_inputs/AuctionDatePicker' +import { FormField } from '@/components/_inputs/FormField' +import { TokenInput } from '@/components/_inputs/TokenInput' +import { DetailsContent } from '@/components/_nft/NftTile' +import { DialogModal } from '@/components/_overlays/DialogModal' +import { useMediaMatch } from '@/hooks/useMediaMatch' +import { pluralizeNoun } from '@/utils/misc' + +export type StartRevenueShareProps = { + tokenId: string + onClose: () => void + show: boolean +} + +const getTokenDetails = (_: string) => ({ + title: 'JBC', + pricePerUnit: 1000, + tokensOnSale: 67773, + userBalance: 100000, + patronageRate: 0.8, +}) + +const datePickerItemsFactory = (days: number[]) => + days.map((value) => ({ + name: pluralizeNoun(value, 'day'), + value: { + type: 'duration' as const, + durationDays: value, + }, + })) + +const endDateItems = datePickerItemsFactory([7, 14, 30]) + +export const StartRevenueShare = ({ tokenId, onClose, show }: StartRevenueShareProps) => { + const smMatch = useMediaMatch('sm') + const { patronageRate, userBalance } = getTokenDetails(tokenId) + + const form = useForm<{ + tokens: number | null + startDate: AuctionDatePickerProps['value'] | null + endDate: AuctionDatePickerProps['value'] | null + }>() + const { trigger, control, watch } = form + const [startDate, endDate, tokens] = watch(['startDate', 'endDate', 'tokens']) + + const details = useMemo( + () => [ + { + title: 'You will receive', + content: ( + + + + ({Math.round(patronageRate * 100)}%) + + + ), + }, + { + title: 'Your holders will receive', + content: ( + + + + ( {Math.round((1 - patronageRate) * 100)}%) + + + ), + }, + ], + [patronageRate, tokens] + ) + + const selectDurationToDate = useCallback((value: AuctionDatePickerProps['value'], base?: Date) => { + if (value?.type === 'date') { + return value.date + } + + if (value?.type === 'duration') { + const now = base ? new Date(base.getTime()) : new Date() + now.setDate(now.getDate() + value.durationDays) + return now + } + return undefined + }, []) + + return ( + + + + } + withDenomination + /> + + ( + + + + $0.00 + + Max + + } + /> + + )} + /> + + + {details.map((row) => ( + + + + {row.title} + + + {row.content} + + ))} + + + + ( + + + + { + onChange(value) + trigger('startDate') + }} + value={value} + /> + + + + )} + /> + ( + + + + { + onChange(value) + trigger('endDate') + }} + value={value} + /> + + + + )} + /> + + + + ) +} + +const OuterBox = styled.div` + position: relative; + height: 50px; +` + +const InnerBox = styled.div` + position: absolute; + inset: 0; +` diff --git a/packages/atlas/src/components/_inputs/AuctionDatePicker/AuctionDatePicker.tsx b/packages/atlas/src/components/_inputs/AuctionDatePicker/AuctionDatePicker.tsx index 6cb9f41368..c3c5e3175c 100644 --- a/packages/atlas/src/components/_inputs/AuctionDatePicker/AuctionDatePicker.tsx +++ b/packages/atlas/src/components/_inputs/AuctionDatePicker/AuctionDatePicker.tsx @@ -136,6 +136,7 @@ export const AuctionDatePicker: FC = ({ offset={[0, 8]} ref={popOverRef} triggerMode="manual" + appendTo={document.body} triggerTarget={selectRef.current} trigger={null} onShow={() => { diff --git a/packages/atlas/src/views/studio/CrtDashboard/CrtDashboard.tsx b/packages/atlas/src/views/studio/CrtDashboard/CrtDashboard.tsx index f900f62ae8..fdacb90930 100644 --- a/packages/atlas/src/views/studio/CrtDashboard/CrtDashboard.tsx +++ b/packages/atlas/src/views/studio/CrtDashboard/CrtDashboard.tsx @@ -1,10 +1,11 @@ import { useCallback, useState } from 'react' -import { SvgActionEdit, SvgActionLinkUrl, SvgActionSell } from '@/assets/icons' +import { SvgActionEdit, SvgActionLinkUrl, SvgActionRevenueShare, SvgActionSell } from '@/assets/icons' import { LimitedWidthContainer } from '@/components/LimitedWidthContainer' import { Tabs } from '@/components/Tabs' import { Text } from '@/components/Text' import { Button } from '@/components/_buttons/Button' +import { StartRevenueShare } from '@/components/_crt/StartRevenueShareModal/StartRevenueShareModal' import { HeaderContainer, MainContainer, TabsContainer } from '@/views/studio/CrtDashboard/CrtDashboard.styles' import { CrtDashboardMainTab } from '@/views/studio/CrtDashboard/tabs/CrtDashboardMainTab' import { CrtHoldersTab } from '@/views/studio/CrtDashboard/tabs/CrtHoldersTab' @@ -14,6 +15,7 @@ const TABS = ['Dashboard', 'Holders', 'Revenue share', 'Settings'] as const export const CrtDashboard = () => { const [currentTab, setCurrentTab] = useState(0) + const [openRevenueShareModal, setOpenRevenueShareModal] = useState(false) const handleChangeTab = useCallback((idx: number) => { setCurrentTab(idx) }, []) @@ -22,6 +24,7 @@ export const CrtDashboard = () => { return ( + setOpenRevenueShareModal(false)} /> @@ -34,10 +37,19 @@ export const CrtDashboard = () => { - - + {currentTab === 0 && ( + <> + + + + )} + {currentTab === 2 && ( + + )} {currentTab === 0 && } {currentTab === 1 && }