diff --git a/packages/boba/gateway/package.json b/packages/boba/gateway/package.json index 1b4624c812..d24da6ae19 100644 --- a/packages/boba/gateway/package.json +++ b/packages/boba/gateway/package.json @@ -40,9 +40,11 @@ "axios": "^0.21.1", "bignumber.js": "^9.0.1", "bn.js": "^5.1.3", + "bootstrap-daterangepicker": "^3.1.0", "browserify-fs": "^1.0.0", "browserify-zlib": "^0.2.0", "buffer": "^6.0.3", + "date-fns": "^2.30.0", "dayjs": "^1.11.7", "dotenv": "^8.2.0", "eslint-config-react-app": "^7.0.0", @@ -60,8 +62,10 @@ "postcss-normalize": "^10.0.1", "process": "^0.11.10", "react": "^17.0.2", + "react-bootstrap-daterangepicker": "^8.0.0", "react-card-flip": "^1.1.5", "react-datepicker": "^4.6.0", + "react-day-picker": "^8.8.0", "react-dom": "^17.0.2", "react-ga4": "^1.4.1", "react-multi-carousel": "^2.6.5", diff --git a/packages/boba/gateway/src/assets/images/Boba_Logo_Black_Circle.png b/packages/boba/gateway/src/assets/images/Boba_Logo_Black_Circle.png new file mode 100644 index 0000000000..538855100d Binary files /dev/null and b/packages/boba/gateway/src/assets/images/Boba_Logo_Black_Circle.png differ diff --git a/packages/boba/gateway/src/assets/images/Boba_Logo_White_Circle.png b/packages/boba/gateway/src/assets/images/Boba_Logo_White_Circle.png new file mode 100644 index 0000000000..f2567dd19e Binary files /dev/null and b/packages/boba/gateway/src/assets/images/Boba_Logo_White_Circle.png differ diff --git a/packages/boba/gateway/src/assets/images/bobaAvax.png b/packages/boba/gateway/src/assets/images/bobaAvax.png new file mode 100644 index 0000000000..d3ef8812db Binary files /dev/null and b/packages/boba/gateway/src/assets/images/bobaAvax.png differ diff --git a/packages/boba/gateway/src/assets/images/bobaBNB.png b/packages/boba/gateway/src/assets/images/bobaBNB.png new file mode 100644 index 0000000000..67b060122a Binary files /dev/null and b/packages/boba/gateway/src/assets/images/bobaBNB.png differ diff --git a/packages/boba/gateway/src/assets/images/bobaETH.png b/packages/boba/gateway/src/assets/images/bobaETH.png new file mode 100644 index 0000000000..9833cf0b0f Binary files /dev/null and b/packages/boba/gateway/src/assets/images/bobaETH.png differ diff --git a/packages/boba/gateway/src/components/global/table/themes.ts b/packages/boba/gateway/src/components/global/table/themes.ts index 3660c71ad1..dbbeed3cec 100644 --- a/packages/boba/gateway/src/components/global/table/themes.ts +++ b/packages/boba/gateway/src/components/global/table/themes.ts @@ -4,7 +4,7 @@ import { Svg } from 'components/global/svg' import { TableRow } from './styles' import { sdesktop } from 'themes/screens' export const TransactionsTableHeader = styled(TableHeader)` - padding: 8px 24px 4px 24px; + padding: 10px 24px 10px 24px; background: none; position: sticky; top: 0; diff --git a/packages/boba/gateway/src/components/icons/chain/L2/BobaAvaxIcon.js b/packages/boba/gateway/src/components/icons/chain/L2/BobaAvaxIcon.js index e1d79e18a1..3c6c4b6021 100644 --- a/packages/boba/gateway/src/components/icons/chain/L2/BobaAvaxIcon.js +++ b/packages/boba/gateway/src/components/icons/chain/L2/BobaAvaxIcon.js @@ -11,16 +11,16 @@ function BobaAvaxIcon({ selected = false }) { .st3{fill:#5D6E3C;} .st4{fill-rule:evenodd;clip-rule:evenodd;fill:#E64142;}`} - + - - - @@ -29,13 +29,13 @@ function BobaAvaxIcon({ selected = false }) { - - + - - - @@ -30,7 +30,7 @@ function BobaBnbIcon({ selected = false }) { - diff --git a/packages/boba/gateway/src/components/layout/Header/Navigation/index.tsx b/packages/boba/gateway/src/components/layout/Header/Navigation/index.tsx index 11e0ca7bf0..a9f5065a23 100644 --- a/packages/boba/gateway/src/components/layout/Header/Navigation/index.tsx +++ b/packages/boba/gateway/src/components/layout/Header/Navigation/index.tsx @@ -2,6 +2,9 @@ import React, { FC } from 'react' import { StyledNav, NavLinkItem } from './style' import { MENU_LIST } from './constant' import { MenuProps } from './types' +import { useSelector } from 'react-redux' +import { selectActiveNetwork } from 'selectors' +import { NETWORK } from 'util/network/network.util' /** * @@ -24,9 +27,18 @@ import { MenuProps } from './types' */ const Navigation: FC = ({ isOpen }) => { + const activeNetwork = useSelector(selectActiveNetwork()) + return ( {MENU_LIST.map((menu) => { + if ( + activeNetwork !== NETWORK.ETHEREUM && + ['Stake', 'Dao'].includes(menu.label) + ) { + return null + } + return ( ({ value: 'BOBA', diff --git a/packages/boba/gateway/src/components/stake/transactionList/styles.ts b/packages/boba/gateway/src/components/stake/transactionList/styles.ts index f4498689b8..0575888b4c 100644 --- a/packages/boba/gateway/src/components/stake/transactionList/styles.ts +++ b/packages/boba/gateway/src/components/stake/transactionList/styles.ts @@ -32,9 +32,7 @@ export const StakeItemDetails = styled.div` box-sizing: border-box; padding: 20px 35px; border-radius: 8px; - ${sdesktop(css` - width: 1024px; - `)} + > div { display: flex; margin: 0px auto; diff --git a/packages/boba/gateway/src/containers/Bridging/BridgeInput/index.tsx b/packages/boba/gateway/src/containers/Bridging/BridgeInput/index.tsx index 5048d27468..477e546031 100644 --- a/packages/boba/gateway/src/containers/Bridging/BridgeInput/index.tsx +++ b/packages/boba/gateway/src/containers/Bridging/BridgeInput/index.tsx @@ -24,6 +24,7 @@ import { TokenSymbol, } from './styles' import { SectionLabel } from '../chain/styles' +import bobaLogo from 'assets/images/Boba_Logo_White_Circle.png' type Props = {} @@ -52,7 +53,11 @@ const BridgeInput: FC = (props) => { {token && ( {`ETH props.theme.text.body1}; cursor: pointer; background: transparent; @@ -40,4 +39,11 @@ export const BridgeTabItem = styled.div<{ : props.theme.colors.gray[600]}; background: ${props.theme.colors.green[300]}; `}; + + &:nth-child(odd) { + border-radius: 8px 0 0 8px; + } + &:nth-child(even) { + border-radius: 0 8px 8px 0; + } ` diff --git a/packages/boba/gateway/src/containers/history/DatePicker.tsx b/packages/boba/gateway/src/containers/history/DatePicker.tsx new file mode 100644 index 0000000000..806d9ecd69 --- /dev/null +++ b/packages/boba/gateway/src/containers/history/DatePicker.tsx @@ -0,0 +1,119 @@ +import React, { FC, useRef, useState, useEffect, useCallback } from 'react' +import { subMonths } from 'date-fns' +import { + DatePickerDropdown, + DatePickerHeader, + DatePickerContainer, +} from './styles' +import { formatDate } from 'util/dates' +import { DayPicker, DateRange } from 'react-day-picker' +import 'react-day-picker/dist/style.css' + +export interface IDatePickerProps { + selected: Date + timeFormat?: string + onChange: Function + range?: boolean + onChangeFrom?: Function + onChangeTo?: Function +} + +const DatePicker = (props: IDatePickerProps) => { + const dropdownRef = useRef(null) + useEffect(() => { + const handleClickOutside = (e: Event) => { + if ( + dropdownRef.current && + !dropdownRef.current.contains(e.target as Node) + ) { + setIsOpen(false) + } + } + // Bind the event listener + document.addEventListener('mousedown', handleClickOutside) + return () => { + // Unbind the event listener on clean up + document.removeEventListener('mousedown', handleClickOutside) + } + }, [dropdownRef]) + + const [selectedDate, setSelectedDate] = useState(props.selected) + const [isOpen, setIsOpen] = useState(false) + const today = new Date() + const defaultSelectedRange: DateRange = { + from: subMonths(today, 6), + to: today, + } + const [selectedRange, setSelectedRange] = useState( + defaultSelectedRange + ) + + const handleClick = useCallback(() => { + setIsOpen(!isOpen) + }, [isOpen]) + + const handleDateChange = (date: Date | undefined) => { + if (date && selectedDate !== date) { + setSelectedDate(date) + props.onChange(date) + } + } + const handleRangeChange = (range: DateRange | undefined) => { + if (range && range !== selectedRange) { + setSelectedRange(range) + props.onChangeFrom && props.onChangeFrom(range.from) + props.onChangeTo && props.onChangeTo(range.to) + } + } + + if (props.range) { + const dateRangeString = `${ + selectedRange?.from + ? formatDate(selectedRange?.from?.getTime() / 1000, props.timeFormat) + : 'From' + } - ${ + selectedRange?.to + ? formatDate(selectedRange?.to?.getTime() / 1000, props.timeFormat) + : 'To' + }` + + return ( + + + {dateRangeString} + + {isOpen && ( + + handleRangeChange(range)} + /> + + )} + + ) + } + + return ( + + + {formatDate(selectedDate.getTime() / 1000, props.timeFormat)} + + {isOpen && ( + + handleDateChange(date)} + /> + + )} + + ) +} + +export default DatePicker diff --git a/packages/boba/gateway/src/containers/history/History.tsx b/packages/boba/gateway/src/containers/history/History.tsx index b1f55f49f0..ebb44a807d 100644 --- a/packages/boba/gateway/src/containers/history/History.tsx +++ b/packages/boba/gateway/src/containers/history/History.tsx @@ -19,7 +19,7 @@ import { isEqual } from 'util/lodash' import { ValidValuesFromArray } from 'util/objectManipulation' import { useTheme } from 'styled-components' -// import Input from 'components/input/Input' + import { Button } from 'components/global' import transctionService from 'services/transaction.service' @@ -43,20 +43,22 @@ import { import { fetchTransactions } from 'actions/networkAction' import { - DropdownNetwork, + SearchInput, + Table, + NoHistory, HistoryPageContainer, - Icon, - IconContainer, - Input, + TableHeader, + TableFilters, NetworkDropdowns, - NoHistory, - SearchInput, + DateDescriptions, + Input, SwitchChainIcon, SwitchIcon, - Table, - TableFilters, - TableHeader, TableTransactionsContainer, + DatePickerWrapper, + DropdownNetwork, + MobileDateDescriptions, + MobileDatePickerWrapper, } from './styles' import { setConnect } from 'actions/setupAction' @@ -65,7 +67,6 @@ import useInterval from 'hooks/useInterval' import { POLL_INTERVAL } from 'util/constant' import FilterIcon from 'assets/images/filter.svg' -import switchButton from 'assets/images/icons/switchButton.svg' import noHistoryIcon from 'assets/images/noHistory.svg' import { FilterDropDown } from 'components/filter' import { Svg } from 'components/global/svg' @@ -74,6 +75,7 @@ import { TransactionsResolver } from './TransactionsResolver' import { CHAIN_NAME, TRANSACTION_FILTER_STATUS } from './types' import { Typography } from 'components/global/typography' +import DatePicker from './DatePicker' const History = () => { const [toNetwork, setToNetwork] = useState(ALL_NETWORKS) @@ -108,31 +110,25 @@ const History = () => { const transactions = useSelector(selectTransactions, isEqual) - /* // TODO: not working as implementation needs be rewrite. - const getDatePicker = (label: string) => { + const getDatePicker = (label: string, range: boolean = false) => { const dateSelector = (date: Date) => { label === 'To' ? setFilterEndDate(date) : setFilterStartDate(date) } return ( - date && !Array.isArray(date) && dateSelector(date) } - {...(label === 'From' ? { selectsStart: true } : { selectsEnd: true })} - calendarClassName={theme.name} - placeholderText={label} - {...(label === 'From' - ? { endDate: new Date(filterEndDate) } - : { - startDate: new Date(filterStartDate), - minDate: new Date(filterStartDate), - })} - maxDate={new Date(now)} + timeFormat="MM/DD/YYYY" + range={range} + {...(range + ? { onChangeFrom: setFilterStartDate, onChangeTo: setFilterEndDate } + : {})} /> ) - } */ + } const syncTransactions = async () => { if (accountEnabled) { const newTransactions = await transctionService.getTransactions() @@ -170,6 +166,20 @@ const History = () => { }} /> + + + Date Range From + + {getDatePicker('From')} + To + {getDatePicker('To')} + + + + Date Range + + {getDatePicker('', true)} + diff --git a/packages/boba/gateway/src/containers/history/TransactionsResolver.tsx b/packages/boba/gateway/src/containers/history/TransactionsResolver.tsx index 207886e260..8a9c031f26 100644 --- a/packages/boba/gateway/src/containers/history/TransactionsResolver.tsx +++ b/packages/boba/gateway/src/containers/history/TransactionsResolver.tsx @@ -20,6 +20,7 @@ import { TransactionHash, TransactionChain, IconContainer, + Image, } from './styles' import { ITransactionsResolverProps, @@ -35,6 +36,7 @@ import truncate from 'truncate-middle' import { logAmount } from 'util/amountConvert' import networkService from 'services/networkService' import noHistoryIcon from 'assets/images/noHistory.svg' +import bobaLogo from 'assets/images/Boba_Logo_White_Circle.png' const NetworkNameToSymbol: { [key: string]: string } = { ethereum: 'ETH', @@ -225,7 +227,13 @@ export const TransactionsResolver: React.FC = ({ const getTransactionToken = (symbol: string) => { return ( - {} + + {symbol === 'BOBA' ? ( + + ) : ( + + )} +
{symbol}
) @@ -239,7 +247,13 @@ export const TransactionsResolver: React.FC = ({ return ( - {} + + {symbol === 'BOBA' ? ( + + ) : ( + + )} + {networkName} theme.color}; +` + export const NetworkDropdowns = styled.div` display: flex; flex-direction: row; @@ -248,6 +281,7 @@ export const IconContainer = styled.div` margin: 0px; } ` + export const Icon = styled(Svg)` display: flex; align-content: center; @@ -265,6 +299,13 @@ export const Icon = styled(Svg)` } ` +export const Image = styled.img` + display: flex; + align-content: center; + width: 32px; + height: 32px; +` + export const SwitchIcon = styled(Svg).attrs({ src: Switch, fill: '#AEDB01', @@ -376,63 +417,6 @@ export const NoHistory = styled.div` `} } ` -export const Actions = styled.div` - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - white-space: nowrap; - gap: 0px 20px; - - .react-datepicker__tab-loop { - margin: 0px -10px; - } - @media ${screen.mobile} { - justify-content: flex-start; - margin-right: 0px; - margin-left: auto; - gap: 0px 10px; - } -` - -export const DatePickerWrapper = styled.div` - width: 100%; - position: relative; - height: 44px; - margin: 0px; - padding: 15px; - border-radius: 12px; - text-align: left; - font-size: ${(props) => props.theme.text.body1}; - color: inherit; - border: 1px solid ${(props) => props.theme.colors.box.border}; - outline: none; - max-width: 115px; - + div { - margin: 0px -15px; - } - ${(props) => - props.theme.name === 'light' && - css` - background: ${props.theme.colors.gray[50]}; - `} - ${(props) => - props.theme.name === 'dark' && - css` - background: ${props.theme.colors.gray[500]}; - `} - @media ${screen.laptop} { - width: 136px; - } - @media ${screen.mobile} { - min-width: 40px; - width: 75px; - height: 30px; - font-size: 11px; - padding: 15px 5px; - text-align: center; - } -` export const SearchInput = styled.div` display: flex; @@ -540,7 +524,7 @@ export const DropdownNetwork = styled(Dropdown)` } } ${Header} { - border-radius: 20px; + border-radius: 12px; min-width: 0px; width: 210px; padding: 6px 16px; @@ -697,7 +681,6 @@ export const DropdownNetwork = styled(Dropdown)` } color: ${props.theme.colors.gray[100]}; border: 1px solid ${props.theme.colors.gray[400]}; - /* background: ${props.theme.colors.gray[500]}; */ box-shadow: ${props.theme.backShadow}; `} } @@ -743,3 +726,99 @@ export const TableTransactionsContainer = styled.div` overflow-x: auto; `)} ` + +export const DatePickerHeader = styled.div` + font-size: 14px; + padding: 8px 20px; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + + ${({ theme: { name, colors } }) => + name === 'light' + ? css` + background: ${colors?.gray[50]}; + border: 1px solid ${colors?.gray[500]}; + ` + : css` + background: ${colors?.gray[500]}; + border: 1px solid ${colors?.gray[300]}; + `} + + ${mobile(css` + height: 30px; + font-family: roboto; + width: 130px; + font-size: 10px; + `)} +` + +export const DatePickerHeadersContainer = styled.div` + box-sizing: border-box; + position: relative; + display: flex; + flex-direction: row; +` + +export const DatePickerDropdown = styled.div` + transition: 0.25s all; + position: absolute; + width: 250px; + right: 0px; + top: 40px; + z-index: 1; + border-radius: 12px; + + ${({ theme: { colors, name } }) => + name === 'light' + ? css` + color: ${colors.gray[800]}; + background: ${colors.gray[50]}; + border: 1px solid ${colors.gray[500]}; + .rdp-day_selected { + border: 1px solid ${colors.gray[600]}; + color: ${colors.gray[800]}; + } + ` + : css` + color: ${colors.gray[50]}; + background: ${colors.gray[500]}; + border: 1px solid ${colors.gray[300]}; + .rdp-day_selected { + border: 1px solid ${colors.gray[100]}; + } + `} + + .rdp-day { + border-radius: 20%; + } + .rdp { + --rdp-cell-size: 30px; + --rdp-caption-font-size: 14px; + --rdp-caption-font-weight: 400; + --rdp-caption-font-family: roboto; + --rdp-accent-color: ${(props) => props.theme.colors.gray[400]}; + --rdp-background-color: ${(props) => props.theme.colors.gray[400]}; + } +` + +export const DatePickerContainer = styled.div` + display: inline-flex; + flex-direction: column; + position: relative; + cursor: pointer; + width: 100%; + transition: 0.25s all; + box-sizing: border-box; + ${(props) => + props.theme.name === 'light' && + css` + color: ${props.theme.colors.gray[800]}; + `} + ${(props) => + props.theme.name === 'dark' && + css` + color: ${props.theme.colors.gray[50]}; + `} +` diff --git a/packages/boba/gateway/src/containers/history/tests/__snapshots__/history.test.tsx.snap b/packages/boba/gateway/src/containers/history/tests/__snapshots__/history.test.tsx.snap index 103773fc05..9fe3b4c80a 100644 --- a/packages/boba/gateway/src/containers/history/tests/__snapshots__/history.test.tsx.snap +++ b/packages/boba/gateway/src/containers/history/tests/__snapshots__/history.test.tsx.snap @@ -1,15 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Testing history page Date Picker 1`] = ` + +
+
+ 05/10/1970 12:00 am +
+
+
+`; + exports[`Testing history page Test History Page 1`] = `
@@ -20,24 +34,74 @@ exports[`Testing history page Test History Page 1`] = `
+
+

+ Date Range From +

+
+
+ 02/09/2023 +
+
+

+ To +

+
+
+ 08/09/2023 +
+
+
+
+

+ Date Range +

+
+
+ 02/09/2023 - 08/09/2023 +
+
+