{
+ onOrderClicked(params.row.id, params.row.coordinatorShortAlias);
+ }}
+ >
{`#${params.row.id}`}
@@ -495,7 +614,14 @@ const BookTable = ({
type: 'number',
width: width * fontSize,
renderCell: (params: any) => {
- return
{`${Number(params.row.bond_size)}%`}
;
+ return (
+
{
+ onOrderClicked(params.row.id, params.row.coordinatorShortAlias);
+ }}
+ >{`${Number(params.row.bond_size)}%`}
+ );
},
};
}, []);
@@ -504,7 +630,7 @@ const BookTable = ({
return {
amount: {
priority: 1,
- order: 4,
+ order: 5,
normal: {
width: fav.mode === 'swap' ? 9.5 : 6.5,
object: amountObj,
@@ -512,7 +638,7 @@ const BookTable = ({
},
currency: {
priority: 2,
- order: 5,
+ order: 6,
normal: {
width: fav.mode === 'swap' ? 0 : 5.9,
object: currencyObj,
@@ -520,7 +646,7 @@ const BookTable = ({
},
premium: {
priority: 3,
- order: 11,
+ order: 12,
normal: {
width: 6,
object: premiumObj,
@@ -528,7 +654,7 @@ const BookTable = ({
},
payment_method: {
priority: 4,
- order: 6,
+ order: 7,
normal: {
width: 12.85,
object: paymentObj,
@@ -550,9 +676,17 @@ const BookTable = ({
object: robotSmallObj,
},
},
+ coordinatorShortAlias: {
+ priority: 5,
+ order: 3,
+ normal: {
+ width: 4.1,
+ object: coordinatorObj,
+ },
+ },
price: {
priority: 6,
- order: 10,
+ order: 11,
normal: {
width: 10,
object: priceObj,
@@ -560,7 +694,7 @@ const BookTable = ({
},
expires_at: {
priority: 7,
- order: 7,
+ order: 8,
normal: {
width: 5,
object: expiryObj,
@@ -568,7 +702,7 @@ const BookTable = ({
},
escrow_duration: {
priority: 8,
- order: 8,
+ order: 9,
normal: {
width: 4.8,
object: timerObj,
@@ -576,7 +710,7 @@ const BookTable = ({
},
satoshis_now: {
priority: 9,
- order: 9,
+ order: 10,
normal: {
width: 6,
object: satoshisObj,
@@ -592,7 +726,7 @@ const BookTable = ({
},
bond_size: {
priority: 11,
- order: 10,
+ order: 11,
normal: {
width: 4.2,
object: bondObj,
@@ -600,7 +734,7 @@ const BookTable = ({
},
id: {
priority: 12,
- order: 12,
+ order: 13,
normal: {
width: 4.8,
object: idObj,
@@ -666,11 +800,7 @@ const BookTable = ({
- {
- fetchBook();
- }}
- >
+
@@ -766,6 +896,7 @@ const BookTable = ({
rowHeight={3.714 * theme.typography.fontSize}
headerHeight={3.25 * theme.typography.fontSize}
rows={filteredOrders}
+ getRowId={(params: PublicOrder) => `${params.coordinatorShortAlias}/${params.id}`}
loading={book.loading}
columns={columns}
columnVisibilityModel={columnVisibilityModel}
@@ -782,15 +913,16 @@ const BookTable = ({
paymentMethod: paymentMethods,
setPaymentMethods,
},
+ loadingOverlay: {
+ variant: 'determinate',
+ value: loadingProgress,
+ },
}}
paginationModel={paginationModel}
pageSizeOptions={width < 22 ? [] : [0, defaultPageSize, defaultPageSize * 2, 50, 100]}
onPaginationModelChange={(newPaginationModel) => {
setPaginationModel(newPaginationModel);
}}
- onRowClick={(params: any) => {
- onOrderClicked(params.row.id);
- }}
/>
);
@@ -825,9 +957,6 @@ const BookTable = ({
onPaginationModelChange={(newPaginationModel) => {
setPaginationModel(newPaginationModel);
}}
- onRowClick={(params: any) => {
- onOrderClicked(params.row.id);
- }}
/>
diff --git a/frontend/src/components/Charts/DepthChart/index.tsx b/frontend/src/components/Charts/DepthChart/index.tsx
index 5302f52dc..e7599b90a 100644
--- a/frontend/src/components/Charts/DepthChart/index.tsx
+++ b/frontend/src/components/Charts/DepthChart/index.tsx
@@ -20,13 +20,13 @@ import {
} from '@mui/material';
import { AddCircleOutline, RemoveCircleOutline } from '@mui/icons-material';
import { useTranslation } from 'react-i18next';
-import { type PublicOrder, LimitList, type Order } from '../../../models';
+import { type PublicOrder, type Order } from '../../../models';
import RobotAvatar from '../../RobotAvatar';
import { amountToString, matchMedian, statusBadgeColor } from '../../../utils';
import currencyDict from '../../../../static/assets/currencies.json';
import { PaymentStringAsIcons } from '../../PaymentMethods';
import getNivoScheme from '../NivoScheme';
-import { type UseAppStoreType, AppContext } from '../../../contexts/AppContext';
+import { type UseAppStoreType, AppContext, hostUrl, origin } from '../../../contexts/AppContext';
interface DepthChartProps {
maxWidth: number;
@@ -43,7 +43,8 @@ const DepthChart: React.FC
= ({
elevation = 6,
onOrderClicked = () => null,
}) => {
- const { book, fav, info, limits, baseUrl } = useContext(AppContext);
+ const { book, federation, fav, exchange, limits, settings } =
+ useContext(AppContext);
const { t } = useTranslation();
const theme = useTheme();
const [enrichedOrders, setEnrichedOrders] = useState([]);
@@ -94,16 +95,16 @@ const DepthChart: React.FC = ({
setXRange(maxRange);
setRangeSteps(rangeSteps);
} else {
- if (info.last_day_nonkyc_btc_premium === undefined) {
+ if (exchange.info?.last_day_nonkyc_btc_premium === undefined) {
const premiums: number[] = enrichedOrders.map((order) => order?.premium || 0);
setCenter(~~matchMedian(premiums));
} else {
- setCenter(info.last_day_nonkyc_btc_premium);
+ setCenter(exchange.info?.last_day_nonkyc_btc_premium);
}
setXRange(8);
setRangeSteps(0.5);
}
- }, [enrichedOrders, xType, info.last_day_nonkyc_btc_premium, currencyCode]);
+ }, [enrichedOrders, xType, exchange.info, currencyCode]);
const generateSeries: () => void = () => {
const sortedOrders: PublicOrder[] =
@@ -225,7 +226,7 @@ const DepthChart: React.FC = ({
orderType={order.type}
statusColor={statusBadgeColor(order.maker_status)}
tooltip={t(order.maker_status)}
- baseUrl={baseUrl}
+ baseUrl={federation[order.coordinatorShortAlias][settings.network][origin]}
small={true}
/>
diff --git a/frontend/src/components/Dialogs/Info.tsx b/frontend/src/components/Dialogs/About.tsx
similarity index 99%
rename from frontend/src/components/Dialogs/Info.tsx
rename to frontend/src/components/Dialogs/About.tsx
index 27578abaf..461305e68 100644
--- a/frontend/src/components/Dialogs/Info.tsx
+++ b/frontend/src/components/Dialogs/About.tsx
@@ -22,7 +22,7 @@ interface Props {
onClose: () => void;
}
-const InfoDialog = ({ maxAmount, open, onClose }: Props): JSX.Element => {
+const AboutDialog = ({ maxAmount, open, onClose }: Props): JSX.Element => {
const { t } = useTranslation();
return (
@@ -263,4 +263,4 @@ const InfoDialog = ({ maxAmount, open, onClose }: Props): JSX.Element => {
);
};
-export default InfoDialog;
+export default AboutDialog;
diff --git a/frontend/src/components/Dialogs/Client.tsx b/frontend/src/components/Dialogs/Client.tsx
new file mode 100644
index 000000000..8c6952004
--- /dev/null
+++ b/frontend/src/components/Dialogs/Client.tsx
@@ -0,0 +1,80 @@
+import React, { useContext } from 'react';
+import { useTranslation } from 'react-i18next';
+
+import {
+ Dialog,
+ DialogContent,
+ Divider,
+ List,
+ ListItemText,
+ ListItem,
+ ListItemIcon,
+ Typography,
+} from '@mui/material';
+
+import BoltIcon from '@mui/icons-material/Bolt';
+import PublicIcon from '@mui/icons-material/Public';
+import FavoriteIcon from '@mui/icons-material/Favorite';
+
+import { RoboSatsNoTextIcon } from '../Icons';
+import { AppContext, type AppContextProps } from '../../contexts/AppContext';
+
+interface Props {
+ open: boolean;
+ onClose: () => void;
+}
+
+const ClientDialog = ({ open = false, onClose }: Props): JSX.Element => {
+ const { t } = useTranslation();
+ const { clientVersion } = useContext(AppContext);
+
+ return (
+
+ }
+ secondary={t('... somewhere on Earth!')}
+ />
+
+
+
+
+ );
+};
+
+export default ClientDialog;
diff --git a/frontend/src/components/Dialogs/Coordinator.tsx b/frontend/src/components/Dialogs/Coordinator.tsx
new file mode 100644
index 000000000..7c8a19ed9
--- /dev/null
+++ b/frontend/src/components/Dialogs/Coordinator.tsx
@@ -0,0 +1,734 @@
+import React, { useContext, useState } from 'react';
+import { useTranslation } from 'react-i18next';
+
+import {
+ Dialog,
+ DialogContent,
+ Divider,
+ Grid,
+ List,
+ ListItemText,
+ ListItem,
+ ListItemIcon,
+ Typography,
+ IconButton,
+ Tooltip,
+ Link,
+ Box,
+ CircularProgress,
+ Accordion,
+ AccordionDetails,
+ AccordionSummary,
+} from '@mui/material';
+
+import {
+ Inventory,
+ Sell,
+ SmartToy,
+ Percent,
+ PriceChange,
+ Book,
+ Reddit,
+ Key,
+ Bolt,
+ Description,
+ Dns,
+ Email,
+ Equalizer,
+ ExpandMore,
+ GitHub,
+ Language,
+ Send,
+ Tag,
+ Twitter,
+} from '@mui/icons-material';
+import LinkIcon from '@mui/icons-material/Link';
+
+import { pn } from '../../utils';
+import { type Contact, type Coordinator } from '../../models';
+import RobotAvatar from '../RobotAvatar';
+import {
+ AmbossIcon,
+ BitcoinSignIcon,
+ RoboSatsNoTextIcon,
+ BadgeFounder,
+ BadgeDevFund,
+ BadgePrivacy,
+ BadgeLoved,
+ BadgeLimits,
+ NostrIcon,
+} from '../Icons';
+import { AppContext, type AppContextProps, hostUrl } from '../../contexts/AppContext';
+import { systemClient } from '../../services/System';
+import { type Badges } from '../../models/Coordinator.model';
+
+interface Props {
+ open: boolean;
+ onClose: () => void;
+ coordinator: Coordinator | undefined;
+ network: 'mainnet' | 'testnet' | undefined;
+}
+
+const ContactButtons = ({
+ nostr,
+ pgp,
+ email,
+ telegram,
+ twitter,
+ matrix,
+ website,
+ reddit,
+}: Contact): JSX.Element => {
+ const { t } = useTranslation();
+ const [showMatrix, setShowMatrix] = useState