From 3de91a32d3ae7afded0cc9da1f03b0fd1a692c40 Mon Sep 17 00:00:00 2001 From: Justin Ferrari <‘justinwesleyferrari@gmail.com’> Date: Wed, 25 Dec 2024 15:08:04 -0500 Subject: [PATCH] More styling changes --- .../reusable-modal/ReusableModal-styles.tsx | 23 +- .../common/reusable-modal/ReusableModal.tsx | 14 +- src/components/header/Header-styles.tsx | 122 ++++++++++- src/components/header/Header.tsx | 176 ++++++++++++++- src/components/history/History-styles.tsx | 57 +++++ src/components/history/History.tsx | 201 ++++++++++-------- src/pages/Home/Home.tsx | 1 - 7 files changed, 484 insertions(+), 110 deletions(-) create mode 100644 src/components/history/History-styles.tsx diff --git a/src/components/common/reusable-modal/ReusableModal-styles.tsx b/src/components/common/reusable-modal/ReusableModal-styles.tsx index c9358b4..8ed0f36 100644 --- a/src/components/common/reusable-modal/ReusableModal-styles.tsx +++ b/src/components/common/reusable-modal/ReusableModal-styles.tsx @@ -1,5 +1,6 @@ import { Box, Button } from "@mui/material"; import { styled } from "@mui/system"; +import CloseIcon from '@mui/icons-material/Close'; export const ReusableModalContainer = styled(Box)(({ theme }) => ({ display: "flex", @@ -21,15 +22,6 @@ export const ReusableModalContainer = styled(Box)(({ theme }) => ({ "0px 4px 5px 0px hsla(0,0%,0%,0.14), \n\t\t0px 1px 10px 0px hsla(0,0%,0%,0.12), \n\t\t0px 2px 4px -1px hsla(0,0%,0%,0.2)", })); -export const ReusableModalSubContainer = styled(Box)({ - display: "flex", - flexDirection: "column", - alignItems: "center", - justifyContent: "center", - gap: "20px", - padding: "70px", -}); - export const ReusableModalBackdrop = styled(Box)({ position: "fixed", top: "0", @@ -50,4 +42,17 @@ export const ReusableModalButton = styled(Button)(({ theme }) => ({ border: `1px solid ${theme.palette.text.primary}`, color: theme.palette.text.primary, boxShadow: "1px 4px 10.5px 0px #0000004D" +})); + +export const ReusableModalCloseIcon = styled(CloseIcon)(({ theme }) => ({ + color: theme.palette.text.primary, + cursor: "pointer", + fontSize: "30px", + position: "absolute", + top: "20px", + right: "20px", + transition: "all 0.3s ease-in-out", + "&:hover": { + transform: "scale(1.1)", + }, })); \ No newline at end of file diff --git a/src/components/common/reusable-modal/ReusableModal.tsx b/src/components/common/reusable-modal/ReusableModal.tsx index d2b6d74..877b136 100644 --- a/src/components/common/reusable-modal/ReusableModal.tsx +++ b/src/components/common/reusable-modal/ReusableModal.tsx @@ -1,20 +1,26 @@ import { ReusableModalBackdrop, + ReusableModalCloseIcon, ReusableModalContainer, - ReusableModalSubContainer, } from "./ReusableModal-styles"; interface ReusableModalProps { backdrop?: boolean; + onClickClose: () => void; children: React.ReactNode; } -export const ReusableModal: React.FC = ({ backdrop, children }) => { +export const ReusableModal: React.FC = ({ + backdrop, + children, + onClickClose, +}) => { return ( <> - {children} + + {children} - {backdrop && } + {backdrop && } ); }; diff --git a/src/components/header/Header-styles.tsx b/src/components/header/Header-styles.tsx index de67e5b..7778779 100644 --- a/src/components/header/Header-styles.tsx +++ b/src/components/header/Header-styles.tsx @@ -1,5 +1,5 @@ import { styled } from "@mui/system"; -import { Box, Button, Typography } from "@mui/material"; +import { Box, Button, Typography, Theme, TextField } from "@mui/material"; import { HomeSVG } from "../common/icons/HomeSVG"; import { QortalLogoSVG } from "../common/icons/QortalLogoSVG"; import { CaretDownSVG } from "../common/icons/CaretDownSVG"; @@ -217,3 +217,123 @@ export const CoinSelectRow = styled(Box)({ gap: "5px", alignSelf: "flex-start", }); + +export const CoinActionContainer = styled(Box)({ + display: "flex", + flexDirection: "column", + gap: "25px", + alignItems: "center", + justifyContent: "center", + width: "80%", +}); + +export const CoinActionRow = styled(Box)({ + display: "flex", + flexDirection: "row", + width: "100%", + alignItems: "center", + justifyContent: "center", +}); + +export const HeaderRow = styled(Box)({ + display: "flex", + flexDirection: "row", + gap: "10px", + alignItems: "center", + justifyContent: "center", +}); + +export const SendFont = styled(Typography)(({ theme }) => ({ + fontFamily: "Inter", + color: theme.palette.text.primary, + fontWeight: 400, + fontSize: "18px", + lineHeight: "25px", + userSelect: "none", +})); + +const customInputStyle = (theme: Theme) => { + return { + fontFamily: "Inter", + fontSize: "18px", + fontWeight: 300, + color: theme.palette.text.primary, + backgroundColor: theme.palette.background.default, + borderColor: theme.palette.background.paper, + "& label": { + color: theme.palette.mode === "light" ? "#808183" : "#edeef0", + fontFamily: "Inter", + fontSize: "18px", + letterSpacing: "0px", + }, + "& label.Mui-focused": { + color: theme.palette.mode === "light" ? "#A0AAB4" : "#d7d8da", + }, + "& .MuiInput-underline:after": { + borderBottomColor: theme.palette.mode === "light" ? "#B2BAC2" : "#c9cccf", + }, + "& .MuiOutlinedInput-root": { + "& fieldset": { + borderColor: "#E0E3E7", + }, + "&:hover fieldset": { + borderColor: "#B2BAC2", + }, + "&.Mui-focused fieldset": { + borderColor: "#6F7E8C", + }, + }, + "& .MuiInputBase-root": { + fontFamily: "Inter", + fontSize: "18px", + letterSpacing: "0px", + }, + "& .MuiFilledInput-root:after": { + borderBottomColor: theme.palette.secondary.main, + }, + }; +}; + +export const CustomInputField = styled(TextField)(({ theme }) => + customInputStyle(theme as Theme) +); + +export const CoinCancelBtn = styled(Button)({ + backgroundColor: "transparent", + color: "#d62525", + border: "1px solid #d62525", + fontFamily: "Inter, sans-serif", + fontWeight: 500, + fontSize: "14px", + height: "32px", + width: "80px", + lineHeight: "16px", + padding: "5px 10px", + borderRadius: "0px", + transition: "all 0.3s ease-in-out", + "&:hover": { + border: "1px solid #d62525", + backgroundColor: "#d62525", + color: "#000000" + }, +}); + +export const CoinConfirmSendBtn = styled(Button)(({ theme }) => ({ + backgroundColor: theme.palette.primary.main, + color: "#000000", + border: `1px solid ${theme.palette.primary.main}`, + fontFamily: "Inter, sans-serif", + fontWeight: 500, + fontSize: "14px", + height: "32px", + width: "80px", + lineHeight: "16px", + padding: "5px 10px", + borderRadius: "0px", + transition: "all 0.3s ease-in-out", + "&:hover": { + border: `1px solid ${theme.palette.text.primary}`, + color: "#000000", + backgroundColor: theme.palette.text.primary, + }, +})); \ No newline at end of file diff --git a/src/components/header/Header.tsx b/src/components/header/Header.tsx index f4e5515..3fa5edc 100644 --- a/src/components/header/Header.tsx +++ b/src/components/header/Header.tsx @@ -1,15 +1,22 @@ import { useState, useEffect, useRef, useContext, ChangeEvent } from "react"; import { BubbleCardColored1, + CoinActionContainer, + CoinActionRow, CoinActionsRow, + CoinCancelBtn, + CoinConfirmSendBtn, CoinReceiveBtn, CoinSelectRow, CoinSendBtn, + CustomInputField, HeaderNav, + HeaderRow, HeaderText, LogoColumn, NameRow, RightColumn, + SendFont, TotalCol, Username, } from "./Header-styles"; @@ -25,6 +32,7 @@ import { Box, Card, CardContent, + FormControl, FormControlLabel, MenuItem, Select, @@ -42,6 +50,8 @@ import rvnIcon from "../../assets/img/rvn.png"; import dgbIcon from "../../assets/img/dgb.png"; import arrrIcon from "../../assets/img/arrr.png"; import { Spacer } from "../common/Spacer"; +import { ReusableModal } from "../common/reusable-modal/ReusableModal"; +import { NotificationContext } from "../../contexts/notificationContext"; const checkIfLocal = async () => { try { @@ -65,6 +75,11 @@ export const Label = styled("label")( ` ); +interface CoinModalProps { + coin: string; + type: string; +} + const getCoinIcon = (coin) => { let img; @@ -126,6 +141,11 @@ export const Header = ({ qortBalance, foreignCoinBalance }: any) => { const [checked, setChecked] = useState(false); const [open, setOpen] = useState(false); const [info, setInfo] = useState(null); + const [openCoinActionModal, setOpenCoinActionModal] = + useState(null); + const [receiverAddress, setReceiverAddress] = useState(""); + const [senderAddress, setSenderAddress] = useState(""); + const { isUsingGateway } = useContext(gameContext); const handleChange = (event: ChangeEvent) => { @@ -138,7 +158,7 @@ export const Header = ({ qortBalance, foreignCoinBalance }: any) => { }; const { userInfo, selectedCoin, setSelectedCoin, getCoinLabel } = useContext(gameContext); - const { avatar, setAvatar } = useContext(UserContext); + const { setNotification } = useContext(NotificationContext); const LocalNodeSwitch = styled(Switch)(({ theme }) => ({ padding: 8, @@ -327,8 +347,26 @@ export const Header = ({ qortBalance, foreignCoinBalance }: any) => { {qortBalance} QORT - Send - Receive + { + setOpenCoinActionModal({ + coin: "QORT", + type: "send", + }); + }} + > + Send + + { + setOpenCoinActionModal({ + coin: "QORT", + type: "receive", + }); + }} + > + Receive + @@ -351,8 +389,26 @@ export const Header = ({ qortBalance, foreignCoinBalance }: any) => { {getCoinLabel()} - Send - Receive + { + setOpenCoinActionModal({ + coin: selectedCoin, + type: "send", + }); + }} + > + Send + + { + setOpenCoinActionModal({ + coin: selectedCoin, + type: "receive", + }); + }} + > + Receive + @@ -400,6 +456,116 @@ export const Header = ({ qortBalance, foreignCoinBalance }: any) => { {info?.message} + {openCoinActionModal && ( + { + setOpenCoinActionModal(null); + }} + backdrop + > + + + + {openCoinActionModal.type === "send" && + openCoinActionModal.coin === "QORT" ? ( + <> + Send {openCoinActionModal.coin} + + + ) : openCoinActionModal.type === "send" && + openCoinActionModal.coin !== "QORT" ? ( + <> + Send {openCoinActionModal.coin} + + + ) : openCoinActionModal.type === "receive" && + openCoinActionModal.coin === "QORT" ? ( + <> + Receive {openCoinActionModal.coin} + + + ) : openCoinActionModal.type === "receive" && + openCoinActionModal.coin !== "QORT" ? ( + <> + Receive {openCoinActionModal.coin} + + + ) : null} + + + + + { + if (openCoinActionModal.type === "send") { + setSenderAddress(e.target.value); + } else { + setReceiverAddress(e.target.value); + } + }} + /> + + + + setOpenCoinActionModal(null)}> + Cancel + + { + setNotification({ + alertType: "alertInfo", + msg: "Sending...", + }); + }} + > + {openCoinActionModal.type === "send" ? "Send" : "Receive"} + + + + + )} ); diff --git a/src/components/history/History-styles.tsx b/src/components/history/History-styles.tsx new file mode 100644 index 0000000..7950943 --- /dev/null +++ b/src/components/history/History-styles.tsx @@ -0,0 +1,57 @@ +import { Box, styled } from "@mui/system"; +import { Button, Typography } from "@mui/material"; +import RefreshIcon from "@mui/icons-material/Refresh"; + +type HistoryBtnProp = { + activeBtn: boolean; +}; + +export const HistoryButtonRow = styled(Box)({ + display: "flex", + alignItems: "center", + gap: "5px", + margin: "5px 5px 5px 0", +}); + +export const HistoryButton = styled(Button, { + shouldForwardProp: (prop) => prop !== "activeBtn", +})(({ theme, activeBtn }) => ({ + fontFamily: "Inter", + color: activeBtn ? theme.palette.text.primary : theme.palette.primary.main, + fontWeight: 400, + fontSize: "16px", + height: "30px", + lineHeight: "40px", + userSelect: "none", + background: activeBtn ? theme.palette.primary.main : "transparent", + border: `1px solid ${theme.palette.primary.main}`, + transition: "all 0.3s ease-in-out", + "&:hover": { + border: `1px solid ${theme.palette.primary.main}`, + background: theme.palette.primary.main, + color: theme.palette.text.primary, + cursor: "pointer", + }, +})); + +export const Refresh = styled(RefreshIcon)({ + cursor: "pointer", + color: "#fff", + fontSize: "25px", + marginLeft: "5px", + transition: "all 0.3s ease-in-out", + "&:hover": { + cursor: "pointer", + transform: "scale(1.1)", + }, +}); + +export const ShowingFont = styled(Typography)(({ theme }) => ({ + fontFamily: "Inter", + color: theme.palette.text.primary, + fontWeight: 400, + fontSize: "16px", + lineHeight: "25px", + marginBottom: "5px", + userSelect: "none", +})); diff --git a/src/components/history/History.tsx b/src/components/history/History.tsx index 6cb056d..cf039e9 100644 --- a/src/components/history/History.tsx +++ b/src/components/history/History.tsx @@ -1,110 +1,131 @@ -import { Alert, Box, Button, ButtonBase, DialogActions, DialogContent, DialogTitle, IconButton, InputLabel, Snackbar, SnackbarCloseReason, TextField, Typography, styled } from '@mui/material' -import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react' -import { BootstrapDialog } from '../Terms' -import CloseIcon from '@mui/icons-material/Close'; -import { Spacer } from '../common/Spacer'; -import gameContext from '../../contexts/gameContext'; -import HistoryList from './HistoryList'; -import RefreshIcon from "@mui/icons-material/Refresh"; +import { + Alert, + Box, + ButtonBase, + Snackbar +} from "@mui/material"; +import React, { + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from "react"; +import gameContext from "../../contexts/gameContext"; +import HistoryList from "./HistoryList"; +import { ShowingFont, Refresh, HistoryButtonRow, HistoryButton } from "./History-styles"; +export const History = ({ qortAddress, show }) => { + const [buyHistory, setBuyHistory] = useState({}); + const [sellHistory, setSellHistory] = useState({}); - + const { selectedCoin } = useContext(gameContext); + const [mode, setMode] = useState("buyHistory"); + const [open, setOpen] = useState(false); -export const History = ({qortAddress, show}) => { - const [buyHistory, setBuyHistory] = useState({}) - const [sellHistory, setSellHistory] = useState({}) + const selectedHistory = useMemo(() => { + if (mode === "buyHistory") return buyHistory[selectedCoin] || []; + if (mode === "sellHistory") return sellHistory[selectedCoin] || []; + }, [selectedCoin, buyHistory, sellHistory, mode]); + const getBuyHistory = useCallback( + (address, foreignBlockchain, mode, limit = 20) => { + setOpen(true); + let historyUrl; + if (mode === "buyHistory") { + historyUrl = `/crosschain/trades?foreignBlockchain=${foreignBlockchain}&buyerAddress=${address}&limit=${limit}&reverse=true`; + } + if (mode === "sellHistory") { + historyUrl = `/crosschain/trades?foreignBlockchain=${foreignBlockchain}&sellerAddress=${address}&limit=${limit}&reverse=true`; + } - const { getCoinLabel, selectedCoin} = useContext(gameContext) - const [mode, setMode] = useState('buyHistory') - const [open, setOpen] = useState(false) + fetch(historyUrl) + .then((response) => { + return response.json(); + }) + .then((data) => { + if (mode === "buyHistory") { + setBuyHistory((prev) => { + return { + ...prev, + [foreignBlockchain]: data, + }; + }); + } + if (mode === "sellHistory") { + setSellHistory((prev) => { + return { + ...prev, + [foreignBlockchain]: data, + }; + }); + } + }) + .catch(() => {}) + .finally(() => { + setOpen(false); + }); + }, + [] + ); - const selectedHistory = useMemo(()=> { - if(mode === 'buyHistory') return buyHistory[selectedCoin] || [] - if(mode === 'sellHistory') return sellHistory[selectedCoin] || [] - }, [selectedCoin, buyHistory, sellHistory, mode]) - const getBuyHistory = useCallback((address, foreignBlockchain, mode, limit = 20)=> { - setOpen(true) - let historyUrl - if(mode === 'buyHistory'){ - historyUrl = `/crosschain/trades?foreignBlockchain=${foreignBlockchain}&buyerAddress=${address}&limit=${limit}&reverse=true`; + useEffect(() => { + if (!qortAddress || !selectedCoin) return; + if (mode === "buyHistory" && buyHistory[selectedCoin]) return; + if (mode === "sellHistory" && sellHistory[selectedCoin]) return; - } - if(mode === 'sellHistory'){ - historyUrl = `/crosschain/trades?foreignBlockchain=${foreignBlockchain}&sellerAddress=${address}&limit=${limit}&reverse=true`; + getBuyHistory(qortAddress, selectedCoin, mode); + }, [qortAddress, selectedCoin, buyHistory, mode]); - } - - - - fetch(historyUrl) - .then((response) => { - return response.json(); - }) - .then((data) => { - if(mode === 'buyHistory'){ - setBuyHistory((prev)=> { - return { - ...prev, - [foreignBlockchain]: data - } - }) - } - if(mode === 'sellHistory'){ - setSellHistory((prev)=> { - return { - ...prev, - [foreignBlockchain]: data - } - }) - } - - }).catch(()=> {}).finally(()=> { - setOpen(false) - }) - }, []) - - useEffect(()=> { - if(!qortAddress || !selectedCoin) return - if(mode === 'buyHistory' && buyHistory[selectedCoin])return - if(mode === 'sellHistory' && sellHistory[selectedCoin])return - - getBuyHistory(qortAddress, selectedCoin, mode) - }, [qortAddress, selectedCoin, buyHistory, mode]) - return ( -
- - - { - getBuyHistory(qortAddress, selectedCoin, mode) - }}> - + + + { + setMode("buyHistory"); + }} + > + Buy History + + { + setMode("sellHistory"); + }} + > + Sell History + + { + getBuyHistory(qortAddress, selectedCoin, mode); + }} + > + - Showing most recent 20 results - - + Showing most recent 20 results + + { - setOpen(false) + onClose={() => { + setOpen(false); }} > setOpen(false)} + onClose={() => setOpen(false)} severity="info" variant="filled" sx={{ width: "100%" }} > - {'Fetching History'} + {"Fetching History"} -
- ) -} + + ); +}; diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index ccb1cda..69fdc30 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -8,7 +8,6 @@ import { OngoingTrades } from "../../components/Grids/OngoingTrades"; import { Box } from "@mui/material"; import { TextTableTitle } from "../../components/Grids/Table-styles"; import { Spacer } from "../../components/common/Spacer"; -import { ReusableModal } from "../../components/common/reusable-modal/ReusableModal"; import { Tab, TabDivider, TabsContainer, TabsRow } from "./Home-Styles"; import { CreateSell } from "../../components/sell/CreateSell"; import { History } from "../../components/history/History";