From 79b5d04c899818bd4992255b81ecaad989978242 Mon Sep 17 00:00:00 2001 From: topeth Date: Mon, 22 Apr 2024 22:28:27 -0700 Subject: [PATCH] WIP: redesign purchase page --- package.json | 1 + src/assets/dollar.png | Bin 0 -> 992 bytes src/assets/graph.png | Bin 0 -> 690 bytes src/assets/list.png | Bin 0 -> 712 bytes .../Buttons/ActionButton/index.module.scss | 8 ++ .../Elements/Buttons/ActionButton/index.tsx | 19 ++++ .../Buttons/ProgressButton/index.module.scss | 8 ++ .../Elements/Buttons/ProgressButton/index.tsx | 25 +++++ src/components/Elements/Buttons/index.tsx | 2 + .../CoreDetailsPanel/index.module.scss | 39 ++++++++ .../Elements/CoreDetailsPanel/index.tsx | 94 ++++++++++++++++++ src/components/Elements/SaleInfo/index.tsx | 93 ----------------- .../DetailCard/index.module.scss | 31 ++++++ .../SaleInfoPanel/DetailCard/index.tsx | 49 +++++++++ .../index.module.scss | 0 .../Elements/SaleInfoPanel/index.tsx | 86 ++++++++++++++++ src/components/Elements/index.ts | 5 +- src/components/Header/index.tsx | 11 +- src/components/Layout/index.tsx | 14 +-- src/components/index.ts | 1 - src/pages/purchase.tsx | 72 +++++--------- src/pages/regions.tsx | 6 +- 22 files changed, 400 insertions(+), 164 deletions(-) create mode 100644 src/assets/dollar.png create mode 100644 src/assets/graph.png create mode 100644 src/assets/list.png create mode 100644 src/components/Elements/Buttons/ActionButton/index.module.scss create mode 100644 src/components/Elements/Buttons/ActionButton/index.tsx create mode 100644 src/components/Elements/Buttons/ProgressButton/index.module.scss create mode 100644 src/components/Elements/Buttons/ProgressButton/index.tsx create mode 100644 src/components/Elements/Buttons/index.tsx create mode 100644 src/components/Elements/CoreDetailsPanel/index.module.scss create mode 100644 src/components/Elements/CoreDetailsPanel/index.tsx delete mode 100644 src/components/Elements/SaleInfo/index.tsx create mode 100644 src/components/Elements/SaleInfoPanel/DetailCard/index.module.scss create mode 100644 src/components/Elements/SaleInfoPanel/DetailCard/index.tsx rename src/components/Elements/{SaleInfo => SaleInfoPanel}/index.module.scss (100%) create mode 100644 src/components/Elements/SaleInfoPanel/index.tsx diff --git a/package.json b/package.json index 044312b5..e9a4dcc6 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "decimal.js": "^10.4.3", "humanize-duration": "^3.31.0", "javascript-time-ago": "^2.5.9", + "moment": "^2.30.1", "next": "^13.3.1", "notistack": "^3.0.1", "react": "^18.2.0", diff --git a/src/assets/dollar.png b/src/assets/dollar.png new file mode 100644 index 0000000000000000000000000000000000000000..6e3e6b181ddd7769e4b1bcf46280d28301a05ed7 GIT binary patch literal 992 zcmV<610Vc}P)27*M5^L$B_MO+s zeg@Hh8X!DKnX(p=KxZ9Tw#l|hJzl}|b{{wNlX-$sG`QAz2Fe~?GByJWMCT6x{Mh#H zslq5YUkTz%VXRUhBr=61&{KA6bl=_ymwGTEZ>N#xbShh1)!yreA`OLDs+b~}=qR$qTj*@6?8GMx~$+n^G z3w4whA+G^?o}u6#T^J{pF(vtB)=l>JihSSlo}uneC( zTyI9BX(5wA@HMMEG!FkE$s{8fATYR}(CNeoyX+F&BEPbNu2kC4`dsx9TVO^wwxSNK zg0U?h2uRJ+oRz^^ijWnyQ?v?9uzDQJ1u5ON(`-OeWy+H9*YoP0YA2zqqeKUz)YeD=Qlaeg8`=-00XC&4a6NyNwe5m z%FH`j*&eV`<=@QgJ;_CgoVpOO%f7S8qe=7juJJOPZBo?y{TKP&cXFj6S*1o%AE0YW zL{r4~nU54Lfg*KUqnM!PQPuCQ{o(xh;k`Xc?Lk@_-m1#)ob?t)+TQl@o%&zzKY#lB zR)9Qyc>iz^2ehXP8d?=QU4SkE_49%nF>qE-@s`wXHh6Xa#nT#ItMM=AT6ut{n>L`6KPh(AvHuXy+5QK601MiD$jDn=nF zrf3O5D;^Ar7z|o=e!S=G?5>;CR+MD>3A4MI*?B*{@9i$YUhsM0%Jp{f+6{;R%RO)f zC5iF`M1XOCsDL0EM%;rUZC*y>!gm0X;Yp;F8N;BRzk2ZF{N+@i16Lv=(|~+9b}8d1 zc@!Di!JH=%A`HsA-1$iXDig=p#>AsrjXnoBVD#%V7Zc2;IYHQMZM2{Eu7zFn7v9dE zOL9i3m=&{C3|i?Yw_Cy5TCP0i5HG|W;2rt>!TkG&PVZi?2D-qz$@DyTW^#*RQHPM^ zB$#q!u8}>Pao4K*kB@RWQq&6AuJP=%NTMa|7xO7_WO z;{J5KvI)E3*P#CyxO1Rvk2#`%7TB@4Slpia?8_y$1}*ppOa@X*)SJL~T;wD|;wM+N zopk*lOa`PiQq1^*rBpuSpqyYxjY4x}69yz~Q(q<_h_g7=OU-H%hJe>a=F-#X)cSA? z2Y5A5sv{MRLj?FA9H{9BExkOIANpsL1s9d6{3}L~CZgBCSjQ;FAUJvS{qd&=_3b)N z!Z2ocA5rDxTJ@$C+*o?Ea!7)@KtLULlWtrvwWsiGe&`P~kH)9B2By^!ym|e0V6Yeb Y0^l1_MQl(d)&Kwi07*qoM6N<$f*poFUjP6A literal 0 HcmV?d00001 diff --git a/src/assets/list.png b/src/assets/list.png new file mode 100644 index 0000000000000000000000000000000000000000..bcc168c5de7b7db7d187112b1d3c5228b0d51c24 GIT binary patch literal 712 zcmV;(0yq7MP)ey3jhXEqpumDZoF0p@1Y2H%`UuI|GI0jymRo*bd#m>h%93w-3>i17VKID*?f7U3lR^g;~asiM*GE9Ks=Ey{N@qJZMyv_rJA-%&l>Ea%aHq(K>B1$(aEIAU}mSaU0|Vu%NqEyc@c~%Rp@V$MxtO z@wk5LM#$u$q_QzrZ8Osq9&mxIuU)!W8P0YZO_1xsN0000 void; +} +export const ActionButton = ({ label, onClick }: ActionButtonProps) => { + return ( + + ); +}; diff --git a/src/components/Elements/Buttons/ProgressButton/index.module.scss b/src/components/Elements/Buttons/ProgressButton/index.module.scss new file mode 100644 index 00000000..41e71bf8 --- /dev/null +++ b/src/components/Elements/Buttons/ProgressButton/index.module.scss @@ -0,0 +1,8 @@ +.buttonContainer { + background:linear-gradient(180deg, #E84D68 0%, #AD2B49 100%); + border-radius: 100px; + font-weight: 500; + text-transform: none; + padding: 0.5rem 1.25rem; + font-size: 0.8rem; +} \ No newline at end of file diff --git a/src/components/Elements/Buttons/ProgressButton/index.tsx b/src/components/Elements/Buttons/ProgressButton/index.tsx new file mode 100644 index 00000000..29175669 --- /dev/null +++ b/src/components/Elements/Buttons/ProgressButton/index.tsx @@ -0,0 +1,25 @@ +import { LoadingButton } from '@mui/lab'; + +import styles from './index.module.scss'; + +interface ProgressButtonProps { + label: string; + onClick: () => void; + loading: boolean; +} +export const ProgressButton = ({ + label, + onClick, + loading, +}: ProgressButtonProps) => { + return ( + + {label} + + ); +}; diff --git a/src/components/Elements/Buttons/index.tsx b/src/components/Elements/Buttons/index.tsx new file mode 100644 index 00000000..1a65d096 --- /dev/null +++ b/src/components/Elements/Buttons/index.tsx @@ -0,0 +1,2 @@ +export * from './ActionButton'; +export * from './ProgressButton'; diff --git a/src/components/Elements/CoreDetailsPanel/index.module.scss b/src/components/Elements/CoreDetailsPanel/index.module.scss new file mode 100644 index 00000000..9fe0fd9e --- /dev/null +++ b/src/components/Elements/CoreDetailsPanel/index.module.scss @@ -0,0 +1,39 @@ +.container { + display: flex; + flex-direction: column; + gap: 2rem; + padding: 1.5rem; + flex-grow: 1; + box-shadow: 2px 2px 55px rgba(0, 0, 0, 0.08); +} + +.titleWrapper { + display: flex; + align-items: center; +} + +.iconWrapper { + width: 1.5rem; + height: 1.5rem; + margin: 0.5rem; +} + +.infoWrapper { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.detailWrapper { + display: flex; + justify-content: space-between; + padding: 1.5rem; +} + +.valueWrapper { + background: #ecf1f9; + padding: 0.5rem 0.75rem; + border-radius: 0.5rem; + display: flex; + align-items: center; +} diff --git a/src/components/Elements/CoreDetailsPanel/index.tsx b/src/components/Elements/CoreDetailsPanel/index.tsx new file mode 100644 index 00000000..0969d133 --- /dev/null +++ b/src/components/Elements/CoreDetailsPanel/index.tsx @@ -0,0 +1,94 @@ +import { Box, Paper, Typography, useTheme } from '@mui/material'; +import Image from 'next/image'; + +import GraphIcon from '@/assets/graph.png'; +import { SaleInfo } from '@/models'; + +import styles from './index.module.scss'; + +interface DetailItemProps { + label: string; + description: string; + value: number; +} + +const DetailItem = ({ label, description, value }: DetailItemProps) => { + const theme = useTheme(); + return ( + + + + {label} + + + {description} + + + + + {value} + + + + ); +}; + +interface CoreDetailsPanelProps { + saleInfo: SaleInfo; +} + +export const CoreDetailsPanel = ({ saleInfo }: CoreDetailsPanelProps) => { + const theme = useTheme(); + return ( + + + graph + + Core Details + + + + + + + + + ); +}; diff --git a/src/components/Elements/SaleInfo/index.tsx b/src/components/Elements/SaleInfo/index.tsx deleted file mode 100644 index 338e29a3..00000000 --- a/src/components/Elements/SaleInfo/index.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { Box, Typography } from '@mui/material'; -import TimeAgo from 'javascript-time-ago'; -import en from 'javascript-time-ago/locale/en.json'; - -import { formatBalance } from '@/utils/functions'; - -import { useCoretimeApi } from '@/contexts/apis'; -import { SaleInfo, SalePhase } from '@/models'; - -import styles from './index.module.scss'; - -interface SaleInfoGridProps { - saleInfo: SaleInfo; - currentPhase: SalePhase; - currentPrice: number; - saleEndTimestamp: number; - saleStartTimestamp: number; -} - -export const SaleInfoGrid = ({ - saleInfo, - currentPhase, - currentPrice, - saleEndTimestamp, - saleStartTimestamp, -}: SaleInfoGridProps) => { - TimeAgo.addLocale(en); - const timeAgo = new TimeAgo('en-US'); - - const { - state: { symbol }, - } = useCoretimeApi(); - - const nextPhase = (): SalePhase => { - const phases = Object.values(SalePhase); - const currentIndex = phases.indexOf(currentPhase); - - // Calculate the index of the next phase - const nextIndex = (currentIndex + 1) % phases.length; - return phases[nextIndex]; - }; - - return ( - - - - {`Sale start: ${timeAgo.format(saleStartTimestamp)}`} - - - {`Sale ends ${timeAgo.format(saleEndTimestamp)}`} - - - - {`Current phase: ${currentPhase}`} - {`Upcoming phase: ${nextPhase()}`} - - - - {`Current price: ${formatBalance(currentPrice.toString(), false)} ${symbol}`} - - - {`Floor price: ${formatBalance(saleInfo.price.toString(), false)} ${symbol}`} - - - - - - {`Cores offered: ${saleInfo.coresOffered}`} - - Number of cores which are offered for sale. - - - - - - {`Cores sold: ${saleInfo.coresSold}`} - - Number of cores which have been sold - - - - - - {`Ideal cores sold: ${saleInfo.idealCoresSold}`} - - - Number of cores sold to not affect the price for next sale - - - - - ); -}; diff --git a/src/components/Elements/SaleInfoPanel/DetailCard/index.module.scss b/src/components/Elements/SaleInfoPanel/DetailCard/index.module.scss new file mode 100644 index 00000000..4292c791 --- /dev/null +++ b/src/components/Elements/SaleInfoPanel/DetailCard/index.module.scss @@ -0,0 +1,31 @@ +.container { + display: flex; + flex-direction: column; + padding: 1rem 2rem; + border-radius: .5rem; + gap: 1.5rem; +} + +.titleWrapper { + display: flex; + align-items: center; +} + +.iconWrapper { + margin: 0.5rem; + margin-left: 0; + width: 2rem; + height: 2rem; +} + +.infoSection { + display: flex; + align-items: center; + justify-content: space-between; +} + +.infoItem { + display: flex; + flex-direction: column; + gap: 0.5rem; +} \ No newline at end of file diff --git a/src/components/Elements/SaleInfoPanel/DetailCard/index.tsx b/src/components/Elements/SaleInfoPanel/DetailCard/index.tsx new file mode 100644 index 00000000..6da14b9e --- /dev/null +++ b/src/components/Elements/SaleInfoPanel/DetailCard/index.tsx @@ -0,0 +1,49 @@ +import { Box, Paper, Typography, useTheme } from '@mui/material'; +import Image from 'next/image'; + +import styles from './index.module.scss'; + +interface ItemDetail { + label: string; + value: string; +} + +interface DetailCardProps { + icon: any; + title: string; + left: ItemDetail; + right: ItemDetail; +} + +const ItemContainer = ({ label, value }: ItemDetail) => { + const theme = useTheme(); + return ( + + {label} + + {value} + + + ); +}; + +export const DetailCard = ({ icon, title, left, right }: DetailCardProps) => { + const theme = useTheme(); + return ( + + + icon + + {title} + + + + + + + + ); +}; diff --git a/src/components/Elements/SaleInfo/index.module.scss b/src/components/Elements/SaleInfoPanel/index.module.scss similarity index 100% rename from src/components/Elements/SaleInfo/index.module.scss rename to src/components/Elements/SaleInfoPanel/index.module.scss diff --git a/src/components/Elements/SaleInfoPanel/index.tsx b/src/components/Elements/SaleInfoPanel/index.tsx new file mode 100644 index 00000000..305579cf --- /dev/null +++ b/src/components/Elements/SaleInfoPanel/index.tsx @@ -0,0 +1,86 @@ +import { Box } from '@mui/material'; +import TimeAgo from 'javascript-time-ago'; +import en from 'javascript-time-ago/locale/en.json'; +import moment from 'moment'; + +import { formatBalance } from '@/utils/functions'; + +import DollarIcon from '@/assets/dollar.png'; +import ListIcon from '@/assets/list.png'; +import ShoppingIcon from '@/assets/shopping.png'; +import { useCoretimeApi } from '@/contexts/apis'; +import { SaleInfo, SalePhase } from '@/models'; + +import { DetailCard } from './DetailCard'; + +interface SaleInfoGridProps { + saleInfo: SaleInfo; + currentPhase: SalePhase; + currentPrice: number; + saleEndTimestamp: number; + saleStartTimestamp: number; +} + +export const SaleInfoPanel = ({ + saleInfo, + currentPhase, + currentPrice, + saleEndTimestamp, + saleStartTimestamp, +}: SaleInfoGridProps) => { + TimeAgo.addLocale(en); + const { + state: { symbol }, + } = useCoretimeApi(); + + const nextPhase = (): SalePhase => { + const phases = Object.values(SalePhase); + const currentIndex = phases.indexOf(currentPhase); + + // Calculate the index of the next phase + const nextIndex = (currentIndex + 1) % phases.length; + return phases[nextIndex]; + }; + + return ( + + + + + + ); +}; diff --git a/src/components/Elements/index.ts b/src/components/Elements/index.ts index 6b96619d..0456f2fd 100644 --- a/src/components/Elements/index.ts +++ b/src/components/Elements/index.ts @@ -1,10 +1,13 @@ export * from './AmountInput'; export * from './Banner'; +export * from './Buttons'; +export * from './CoreDetailsPanel'; export * from './FeatureCard'; export * from './Label'; export * from './ListingCard'; export * from './MarketFilters'; export * from './Progress'; export * from './RegionCard'; -export * from './SaleInfo'; +export * from './SaleInfoPanel'; +export * from './Selectors'; export * from './StatusIndicator'; diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 4ea3b70e..7f033806 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -1,7 +1,6 @@ import { ExpandMore } from '@mui/icons-material'; import { Box, - Button, Collapse, Divider, List, @@ -12,6 +11,7 @@ import { useInkathon } from '@scio-labs/use-inkathon'; import React, { useState } from 'react'; import styles from './index.module.scss'; +import { ActionButton } from '../Elements'; import { WalletModal } from '../Modals/WalletConnect'; export const Header = () => { @@ -96,13 +96,10 @@ export const Header = () => { ) : ( - + label='Connect Wallet' + /> )} diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 76c86ddd..42e81386 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -1,4 +1,3 @@ -import { Paper } from '@mui/material'; import React, { ReactElement } from 'react'; import styles from './index.module.scss'; @@ -15,18 +14,7 @@ export const Layout = ({ children }: Props) => {
- -
{children}
-
+
{children}
); diff --git a/src/components/index.ts b/src/components/index.ts index ea987eed..93333dfa 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,5 +1,4 @@ export * from './Elements'; -export * from './Elements/Selectors'; export * from './Header'; export * from './Layout'; export * from './Modals'; diff --git a/src/pages/purchase.tsx b/src/pages/purchase.tsx index b91cca66..24a869da 100644 --- a/src/pages/purchase.tsx +++ b/src/pages/purchase.tsx @@ -1,4 +1,3 @@ -import { LoadingButton } from '@mui/lab'; import { Box, Button, Typography, useTheme } from '@mui/material'; import { useInkathon } from '@scio-labs/use-inkathon'; import TimeAgo from 'javascript-time-ago'; @@ -11,7 +10,7 @@ import useSalePhase from '@/hooks/salePhase'; import useSalePrice from '@/hooks/salePrice'; import { formatBalance } from '@/utils/functions'; -import { Progress, SaleInfoGrid } from '@/components'; +import { CoreDetailsPanel, ProgressButton, SaleInfoPanel } from '@/components'; import { useCoretimeApi } from '@/contexts/apis'; import { ApiState } from '@/contexts/apis/types'; @@ -25,7 +24,6 @@ const Purchase = () => { const [working, setWorking] = useState(false); TimeAgo.addLocale(en); // Create formatter (English). - const timeAgo = new TimeAgo('en-US'); const { activeSigner, activeAccount } = useInkathon(); const { toastError, toastSuccess, toastInfo } = useToast(); @@ -39,13 +37,8 @@ const Purchase = () => { const balance = useBalance(); const currentPrice = useSalePrice(); - const { - currentPhase, - progress, - saleStartTimestamp, - saleEndTimestamp, - saleSections, - } = useSalePhase(); + const { currentPhase, progress, saleStartTimestamp, saleEndTimestamp } = + useSalePhase(); const purchase = async () => { if (!api || apiState !== ApiState.READY || !activeAccount || !activeSigner) @@ -86,6 +79,7 @@ const Purchase = () => { sx={{ display: 'flex', justifyContent: 'space-between', + alignItems: 'center', }} > @@ -99,11 +93,14 @@ const Purchase = () => { variant='subtitle2' sx={{ color: theme.palette.text.primary }} > - Purchase a core directly from the Coretime chain + Buy a core straight from the Coretime chain - {`Your balance: ${formatBalance(balance.toString(), false)} ${symbol}`} + {`Your balance: ${formatBalance( + balance.toString(), + false + )} ${symbol}`} @@ -114,40 +111,25 @@ const Purchase = () => { !saleEndTimestamp ? ( <> - Connect your wallet + Check your network conection and connect your wallet ) : ( - <> - - - - - - Current Bulk Sale: - Ends {timeAgo.format(saleEndTimestamp)} - - - - + + + + + + { - - Purchase - + label='Purchase Core' + /> - + )} diff --git a/src/pages/regions.tsx b/src/pages/regions.tsx index cfdfa542..5446d679 100644 --- a/src/pages/regions.tsx +++ b/src/pages/regions.tsx @@ -5,6 +5,7 @@ import { Box, Button, CircularProgress, + Paper, Typography, useTheme, } from '@mui/material'; @@ -176,11 +177,10 @@ const Dashboard = () => { )} - { ))} - + {regionSelected && ( <>