mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-08-25 06:39:53 -04:00
feat(gui): Rework transaction history ui (#470)
Co-authored-by: b-enedict <benedict.seuss@gmail.com>
This commit is contained in:
parent
c1c45571f0
commit
1ad4bcadf5
7 changed files with 331 additions and 89 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit dbbccecc89e1121762a4ad6b531638ece82aa0c7
|
Subproject commit 5f714f147fd29228698070e6bd80e41ce2f86fb0
|
|
@ -1,4 +1,4 @@
|
||||||
import { Tooltip } from "@mui/material";
|
import { Box, SxProps, Tooltip, Typography } from "@mui/material";
|
||||||
import { useAppSelector, useSettings } from "store/hooks";
|
import { useAppSelector, useSettings } from "store/hooks";
|
||||||
import { getMarkup, piconerosToXmr, satsToBtc } from "utils/conversionUtils";
|
import { getMarkup, piconerosToXmr, satsToBtc } from "utils/conversionUtils";
|
||||||
|
|
||||||
|
@ -10,12 +10,18 @@ export function AmountWithUnit({
|
||||||
fixedPrecision,
|
fixedPrecision,
|
||||||
exchangeRate,
|
exchangeRate,
|
||||||
parenthesisText = null,
|
parenthesisText = null,
|
||||||
|
labelStyles,
|
||||||
|
amountStyles,
|
||||||
|
disableTooltip = false,
|
||||||
}: {
|
}: {
|
||||||
amount: Amount;
|
amount: Amount;
|
||||||
unit: string;
|
unit: string;
|
||||||
fixedPrecision: number;
|
fixedPrecision: number;
|
||||||
exchangeRate?: Amount;
|
exchangeRate?: Amount;
|
||||||
parenthesisText?: string;
|
parenthesisText?: string;
|
||||||
|
labelStyles?: SxProps;
|
||||||
|
amountStyles?: SxProps;
|
||||||
|
disableTooltip?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const [fetchFiatPrices, fiatCurrency] = useSettings((settings) => [
|
const [fetchFiatPrices, fiatCurrency] = useSettings((settings) => [
|
||||||
settings.fetchFiatPrices,
|
settings.fetchFiatPrices,
|
||||||
|
@ -29,12 +35,25 @@ export function AmountWithUnit({
|
||||||
? `≈ ${(exchangeRate * amount).toFixed(2)} ${fiatCurrency}`
|
? `≈ ${(exchangeRate * amount).toFixed(2)} ${fiatCurrency}`
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
|
const content = (
|
||||||
|
<span>
|
||||||
|
<Box sx={{ display: "inline", ...amountStyles }}>
|
||||||
|
{amount != null ? amount.toFixed(fixedPrecision) : "?"}
|
||||||
|
</Box>{" "}
|
||||||
|
<Box sx={{ display: "inline", ...labelStyles }}>
|
||||||
|
{unit}
|
||||||
|
{parenthesisText != null ? ` (${parenthesisText})` : null}
|
||||||
|
</Box>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (disableTooltip) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip arrow title={title}>
|
<Tooltip arrow title={title}>
|
||||||
<span>
|
{content}
|
||||||
{amount != null ? amount.toFixed(fixedPrecision) : "?"} {unit}
|
|
||||||
{parenthesisText != null ? ` (${parenthesisText})` : null}
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -89,9 +108,15 @@ export function BitcoinAmount({ amount }: { amount: Amount }) {
|
||||||
export function MoneroAmount({
|
export function MoneroAmount({
|
||||||
amount,
|
amount,
|
||||||
fixedPrecision = 4,
|
fixedPrecision = 4,
|
||||||
|
labelStyles,
|
||||||
|
amountStyles,
|
||||||
|
disableTooltip = false,
|
||||||
}: {
|
}: {
|
||||||
amount: Amount;
|
amount: Amount;
|
||||||
fixedPrecision?: number;
|
fixedPrecision?: number;
|
||||||
|
labelStyles?: SxProps;
|
||||||
|
amountStyles?: SxProps;
|
||||||
|
disableTooltip?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const xmrRate = useAppSelector((state) => state.rates.xmrPrice);
|
const xmrRate = useAppSelector((state) => state.rates.xmrPrice);
|
||||||
|
|
||||||
|
@ -101,6 +126,9 @@ export function MoneroAmount({
|
||||||
unit="XMR"
|
unit="XMR"
|
||||||
fixedPrecision={fixedPrecision}
|
fixedPrecision={fixedPrecision}
|
||||||
exchangeRate={xmrRate}
|
exchangeRate={xmrRate}
|
||||||
|
labelStyles={labelStyles}
|
||||||
|
amountStyles={amountStyles}
|
||||||
|
disableTooltip={disableTooltip}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -164,14 +192,23 @@ export function SatsAmount({ amount }: { amount: Amount }) {
|
||||||
export function PiconeroAmount({
|
export function PiconeroAmount({
|
||||||
amount,
|
amount,
|
||||||
fixedPrecision = 8,
|
fixedPrecision = 8,
|
||||||
|
labelStyles,
|
||||||
|
amountStyles,
|
||||||
|
disableTooltip = false,
|
||||||
}: {
|
}: {
|
||||||
amount: Amount;
|
amount: Amount;
|
||||||
fixedPrecision?: number;
|
fixedPrecision?: number;
|
||||||
|
labelStyles?: SxProps;
|
||||||
|
amountStyles?: SxProps;
|
||||||
|
disableTooltip?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<MoneroAmount
|
<MoneroAmount
|
||||||
amount={amount == null ? null : piconerosToXmr(amount)}
|
amount={amount == null ? null : piconerosToXmr(amount)}
|
||||||
fixedPrecision={fixedPrecision}
|
fixedPrecision={fixedPrecision}
|
||||||
|
labelStyles={labelStyles}
|
||||||
|
amountStyles={amountStyles}
|
||||||
|
disableTooltip={disableTooltip}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { Box, Chip, Tooltip, Typography } from "@mui/material";
|
||||||
|
import {
|
||||||
|
AutoAwesome as AutoAwesomeIcon,
|
||||||
|
CheckCircleOutline as CheckCircleOutlineIcon,
|
||||||
|
} from "@mui/icons-material";
|
||||||
|
|
||||||
|
export default function ConfirmationsBadge({
|
||||||
|
confirmations,
|
||||||
|
}: {
|
||||||
|
confirmations: number;
|
||||||
|
}) {
|
||||||
|
if (confirmations === 0) {
|
||||||
|
return (
|
||||||
|
<Chip
|
||||||
|
icon={<AutoAwesomeIcon />}
|
||||||
|
label="Published"
|
||||||
|
color="secondary"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else if (confirmations < 10) {
|
||||||
|
const label = (
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "end",
|
||||||
|
gap: 0.4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="body2" sx={{ fontWeight: "bold" }}>
|
||||||
|
{confirmations}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="caption">/10</Typography>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
return <Chip label={label} color="warning" size="small" />;
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Tooltip title={`${confirmations} Confirmations`}>
|
||||||
|
<CheckCircleOutlineIcon
|
||||||
|
sx={{ color: "text.secondary" }}
|
||||||
|
fontSize="small"
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +1,8 @@
|
||||||
import {
|
import { Typography, Box, Paper } from "@mui/material";
|
||||||
Typography,
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableContainer,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
Paper,
|
|
||||||
Chip,
|
|
||||||
IconButton,
|
|
||||||
Tooltip,
|
|
||||||
Stack,
|
|
||||||
} from "@mui/material";
|
|
||||||
import { OpenInNew as OpenInNewIcon } from "@mui/icons-material";
|
|
||||||
import { open } from "@tauri-apps/plugin-shell";
|
|
||||||
import { PiconeroAmount } from "../../../other/Units";
|
|
||||||
import { getMoneroTxExplorerUrl } from "../../../../../utils/conversionUtils";
|
|
||||||
import { isTestnet } from "store/config";
|
|
||||||
import { TransactionInfo } from "models/tauriModel";
|
import { TransactionInfo } from "models/tauriModel";
|
||||||
|
import _ from "lodash";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import TransactionItem from "./TransactionItem";
|
||||||
|
|
||||||
interface TransactionHistoryProps {
|
interface TransactionHistoryProps {
|
||||||
history?: {
|
history?: {
|
||||||
|
@ -27,76 +10,52 @@ interface TransactionHistoryProps {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TransactionGroup {
|
||||||
|
date: string;
|
||||||
|
displayDate: string;
|
||||||
|
transactions: TransactionInfo[];
|
||||||
|
}
|
||||||
|
|
||||||
// Component for displaying transaction history
|
// Component for displaying transaction history
|
||||||
export default function TransactionHistory({
|
export default function TransactionHistory({
|
||||||
history,
|
history,
|
||||||
}: TransactionHistoryProps) {
|
}: TransactionHistoryProps) {
|
||||||
if (!history || !history.transactions || history.transactions.length === 0) {
|
if (!history || !history.transactions || history.transactions.length === 0) {
|
||||||
return <Typography variant="h5">Transaction History</Typography>;
|
return <Typography variant="h5">Transactions</Typography>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
const transactions = history.transactions;
|
||||||
<>
|
|
||||||
<Typography variant="h5">Transaction History</Typography>
|
|
||||||
|
|
||||||
<TableContainer component={Paper} variant="outlined">
|
// Group transactions by date using dayjs and lodash
|
||||||
<Table size="small">
|
const transactionGroups: TransactionGroup[] = _(transactions)
|
||||||
<TableHead>
|
.groupBy((tx) => dayjs(tx.timestamp * 1000).format("YYYY-MM-DD")) // Convert Unix timestamp to date string
|
||||||
<TableRow>
|
.map((txs, dateKey) => ({
|
||||||
<TableCell>Amount</TableCell>
|
date: dateKey,
|
||||||
<TableCell>Fee</TableCell>
|
displayDate: dayjs(dateKey).format("MMMM D, YYYY"), // Human-readable format
|
||||||
<TableCell align="right">Confirmations</TableCell>
|
transactions: _.orderBy(txs, ["timestamp"], ["desc"]), // Sort transactions within group by newest first
|
||||||
<TableCell align="center">Explorer</TableCell>
|
}))
|
||||||
</TableRow>
|
.orderBy(["date"], ["desc"]) // Sort groups by newest date first
|
||||||
</TableHead>
|
.value();
|
||||||
<TableBody>
|
|
||||||
{[...history.transactions]
|
return (
|
||||||
.sort((a, b) => a.confirmations - b.confirmations)
|
<Box>
|
||||||
.map((tx, index) => (
|
<Typography variant="h5" sx={{ mb: 2 }}>
|
||||||
<TableRow key={index}>
|
Transactions
|
||||||
<TableCell>
|
</Typography>
|
||||||
<Stack direction="row" spacing={1} alignItems="center">
|
<Box sx={{ display: "flex", flexDirection: "column", gap: 6 }}>
|
||||||
<PiconeroAmount amount={tx.amount} />
|
{transactionGroups.map((group) => (
|
||||||
<Chip
|
<Box key={group.date}>
|
||||||
label={tx.direction === "In" ? "Received" : "Sent"}
|
<Typography variant="body1" color="text.secondary" sx={{ mb: 1 }}>
|
||||||
color={tx.direction === "In" ? "success" : "default"}
|
{group.displayDate}
|
||||||
size="small"
|
</Typography>
|
||||||
/>
|
<Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
|
||||||
</Stack>
|
{group.transactions.map((tx) => (
|
||||||
</TableCell>
|
<TransactionItem key={tx.tx_hash} transaction={tx} />
|
||||||
<TableCell>
|
|
||||||
<PiconeroAmount amount={tx.fee} />
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="right">
|
|
||||||
<Chip
|
|
||||||
label={tx.confirmations}
|
|
||||||
color={tx.confirmations >= 10 ? "success" : "warning"}
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="center">
|
|
||||||
{tx.tx_hash && (
|
|
||||||
<Tooltip title="View on block explorer">
|
|
||||||
<IconButton
|
|
||||||
size="small"
|
|
||||||
onClick={() => {
|
|
||||||
const url = getMoneroTxExplorerUrl(
|
|
||||||
tx.tx_hash,
|
|
||||||
isTestnet(),
|
|
||||||
);
|
|
||||||
open(url);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<OpenInNewIcon fontSize="small" />
|
|
||||||
</IconButton>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</Box>
|
||||||
</Table>
|
</Box>
|
||||||
</TableContainer>
|
))}
|
||||||
</>
|
</Box>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Chip,
|
||||||
|
IconButton,
|
||||||
|
Menu,
|
||||||
|
MenuItem,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { TransactionDirection, TransactionInfo } from "models/tauriModel";
|
||||||
|
import {
|
||||||
|
CallReceived as IncomingIcon,
|
||||||
|
MoreVert as MoreVertIcon,
|
||||||
|
} from "@mui/icons-material";
|
||||||
|
import { CallMade as OutgoingIcon } from "@mui/icons-material";
|
||||||
|
import {
|
||||||
|
FiatPiconeroAmount,
|
||||||
|
PiconeroAmount,
|
||||||
|
} from "renderer/components/other/Units";
|
||||||
|
import ConfirmationsBadge from "./ConfirmationsBadge";
|
||||||
|
import { getMoneroTxExplorerUrl } from "utils/conversionUtils";
|
||||||
|
import { isTestnet } from "store/config";
|
||||||
|
import { open } from "@tauri-apps/plugin-shell";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
interface TransactionItemProps {
|
||||||
|
transaction: TransactionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TransactionItem({ transaction }: TransactionItemProps) {
|
||||||
|
const isIncoming = transaction.direction === TransactionDirection.In;
|
||||||
|
const displayDate = dayjs(transaction.timestamp * 1000).format(
|
||||||
|
"MMM DD YYYY, HH:mm",
|
||||||
|
);
|
||||||
|
|
||||||
|
const amountStyles = isIncoming
|
||||||
|
? { color: "success.tint" }
|
||||||
|
: { color: "error.tint" };
|
||||||
|
|
||||||
|
const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);
|
||||||
|
const menuOpen = Boolean(menuAnchorEl);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: 0.5,
|
||||||
|
backgroundColor: "grey.800",
|
||||||
|
borderRadius: "100%",
|
||||||
|
height: 40,
|
||||||
|
aspectRatio: 1,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isIncoming ? <IncomingIcon /> : <OutgoingIcon />}
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "grid",
|
||||||
|
gridTemplateColumns: "min-content max-content",
|
||||||
|
columnGap: 0.5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
sx={{
|
||||||
|
opacity: !isIncoming ? 1 : 0,
|
||||||
|
gridArea: "1 / 1",
|
||||||
|
fontWeight: "bold",
|
||||||
|
...amountStyles,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
‐
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
sx={{ gridArea: "1 / 2", fontWeight: "bold", ...amountStyles }}
|
||||||
|
>
|
||||||
|
<PiconeroAmount
|
||||||
|
amount={transaction.amount}
|
||||||
|
labelStyles={{ fontSize: 14, ml: -0.3 }}
|
||||||
|
disableTooltip
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="caption" sx={{ gridArea: "2 / 2" }}>
|
||||||
|
<FiatPiconeroAmount amount={transaction.amount} />
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
color="text.secondary"
|
||||||
|
sx={{ fontSize: 14 }}
|
||||||
|
>
|
||||||
|
{displayDate}
|
||||||
|
</Typography>
|
||||||
|
<ConfirmationsBadge confirmations={transaction.confirmations} />
|
||||||
|
<IconButton
|
||||||
|
onClick={(event) => {
|
||||||
|
setMenuAnchorEl(event.currentTarget);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MoreVertIcon />
|
||||||
|
</IconButton>
|
||||||
|
<Menu
|
||||||
|
anchorEl={menuAnchorEl}
|
||||||
|
open={menuOpen}
|
||||||
|
onClose={() => setMenuAnchorEl(null)}
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
navigator.clipboard.writeText(transaction.tx_hash);
|
||||||
|
setMenuAnchorEl(null);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography>Copy Transaction ID</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
open(getMoneroTxExplorerUrl(transaction.tx_hash, isTestnet()));
|
||||||
|
setMenuAnchorEl(null);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography>View on Explorer</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
|
@ -72,6 +72,7 @@ export default function WalletOverview({
|
||||||
<PiconeroAmount
|
<PiconeroAmount
|
||||||
amount={parseFloat(balance.unlocked_balance)}
|
amount={parseFloat(balance.unlocked_balance)}
|
||||||
fixedPrecision={4}
|
fixedPrecision={4}
|
||||||
|
disableTooltip
|
||||||
/>
|
/>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
|
|
|
@ -18,6 +18,17 @@ declare module "@mui/material/Button" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extend the palette to include custom color properties
|
||||||
|
declare module "@mui/material/styles" {
|
||||||
|
interface PaletteColor {
|
||||||
|
tint?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PaletteColorOptions {
|
||||||
|
tint?: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export enum Theme {
|
export enum Theme {
|
||||||
Light = "light",
|
Light = "light",
|
||||||
Dark = "dark",
|
Dark = "dark",
|
||||||
|
@ -93,6 +104,19 @@ const baseTheme: ThemeOptions = {
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
props: { size: "tiny" },
|
||||||
|
style: {
|
||||||
|
fontSize: "0.75rem",
|
||||||
|
fontWeight: 500,
|
||||||
|
padding: "4px 8px",
|
||||||
|
minHeight: "24px",
|
||||||
|
minWidth: "auto",
|
||||||
|
lineHeight: 1.2,
|
||||||
|
textTransform: "none",
|
||||||
|
borderRadius: "4px",
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
MuiChip: {
|
MuiChip: {
|
||||||
|
@ -142,6 +166,14 @@ const darkTheme = createTheme({
|
||||||
main: "#f4511e", // Monero orange
|
main: "#f4511e", // Monero orange
|
||||||
},
|
},
|
||||||
secondary: indigo,
|
secondary: indigo,
|
||||||
|
error: {
|
||||||
|
main: "#f44336",
|
||||||
|
tint: "#e58686",
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
main: "#4caf50",
|
||||||
|
tint: "#70c491",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -153,6 +185,14 @@ const lightTheme = createTheme({
|
||||||
main: "#f4511e", // Monero orange
|
main: "#f4511e", // Monero orange
|
||||||
},
|
},
|
||||||
secondary: indigo,
|
secondary: indigo,
|
||||||
|
error: {
|
||||||
|
main: "#f44336",
|
||||||
|
tint: "#ff5252",
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
main: "#4caf50",
|
||||||
|
tint: "#4caf50",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue