diff --git a/packages/renderer/src/Routes.tsx b/packages/renderer/src/Routes.tsx index d3cd127..59b80eb 100644 --- a/packages/renderer/src/Routes.tsx +++ b/packages/renderer/src/Routes.tsx @@ -30,6 +30,7 @@ import { PaymentMethods, } from "@pages/Account"; import { MyWallet } from "@pages/MyWallet"; +import { MarketsTransactions } from "@pages/Markets"; export function AppRoutes() { return ( @@ -38,6 +39,7 @@ export function AppRoutes() { } /> } /> } /> + } /> ; + +const Template: ComponentStory = () => { + return ; +}; + +export const Default = Template.bind({}); + +Default.args = {}; + +const data = [ + { + price: 123, + priceComparison: 0.12, + amount: 123123, + amountCurrency: "EUR", + cost: 123, + costCurrency: "USD", + paymentMethod: "ASD", + accountAge: 12, + accountTrades: 1212, + }, + { + price: 123, + priceComparison: 0.12, + amount: 123123, + amountCurrency: "EUR", + cost: 123, + costCurrency: "USD", + paymentMethod: "ASD", + accountAge: 12, + accountTrades: 1212, + }, +]; diff --git a/packages/renderer/src/components/organisms/MarketTransactions/MarketTransactions.test.tsx b/packages/renderer/src/components/organisms/MarketTransactions/MarketTransactions.test.tsx new file mode 100644 index 0000000..4c5bd14 --- /dev/null +++ b/packages/renderer/src/components/organisms/MarketTransactions/MarketTransactions.test.tsx @@ -0,0 +1,118 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import { describe, expect, it } from "vitest"; +import { render, screen } from "@testing-library/react"; +import { MarketTransactions } from "./MarketTransactions"; +import { AppProviders } from "@atoms/AppProviders"; + +describe("organisms::MarketTransactions", () => { + it("renders without exploding.", () => { + const { asFragment, unmount } = render( + + + + ); + expect(asFragment()).toMatchSnapshot(); + unmount(); + }); + + it("renders all columns.", () => { + const { unmount } = render( + + + + ); + expect(screen.queryByText("Price")).toBeInTheDocument(); + expect(screen.queryByText("Amount")).toBeInTheDocument(); + expect(screen.queryByText("Costs")).toBeInTheDocument(); + expect(screen.queryByText("Payment Method")).toBeInTheDocument(); + expect(screen.queryByText("Account Age")).toBeInTheDocument(); + expect(screen.queryByText("Account Trades")).toBeInTheDocument(); + unmount(); + }); + + it("renders formatted price value with currency sign.", () => { + const { unmount } = render( + + + + ); + expect(screen.queryByText("€5,000.96")).toBeInTheDocument(); + expect(screen.queryByText("€9,637.41")).toBeInTheDocument(); + unmount(); + }); + + it("renders formatted amount value with currency code.", () => { + const { unmount } = render( + + + + ); + expect(screen.queryByText("7,564.94 XMR")).toBeInTheDocument(); + expect(screen.queryByText("6,483.23 XMR")).toBeInTheDocument(); + unmount(); + }); + + it("renders formatted cost value with currency sign.", () => { + const { unmount } = render( + + + + ); + expect(screen.queryByText("$532.34")).toBeInTheDocument(); + expect(screen.queryByText("$983.32")).toBeInTheDocument(); + unmount(); + }); + + it("renders formatted account trades.", () => { + const { unmount } = render( + + + + ); + expect(screen.queryByText("3,412")).toBeInTheDocument(); + expect(screen.queryByText("1,212")).toBeInTheDocument(); + unmount(); + }); +}); + +const data = [ + { + price: 5000.956, + priceComparison: 0.12, + priceCurrency: "EUR", + amount: 7564.94, + amountCurrency: "XMR", + cost: 532.34, + costCurrency: "USD", + paymentMethod: "ASD", + accountAge: 12, + accountTrades: 1212, + }, + { + price: 9637.41, + priceComparison: 0.12, + priceCurrency: "EUR", + amount: 6483.23, + amountCurrency: "XMR", + cost: 983.32, + costCurrency: "USD", + paymentMethod: "ASD", + accountAge: 12, + accountTrades: 3412, + }, +]; diff --git a/packages/renderer/src/components/organisms/MarketTransactions/MarketTransactions.tsx b/packages/renderer/src/components/organisms/MarketTransactions/MarketTransactions.tsx new file mode 100644 index 0000000..d26127e --- /dev/null +++ b/packages/renderer/src/components/organisms/MarketTransactions/MarketTransactions.tsx @@ -0,0 +1,96 @@ +import { createStyles } from "@mantine/core"; +import { createTable } from "@tanstack/react-table"; +import { Table } from "@molecules/Table"; +import type { MarketTransaction } from "./_types"; +import { + MarketTransactionsPriceCell, + MarketTransactionsAmountCell, + MarketTransactionsAccountTradesCell, + MarketTransactionsCostsCell, + MarketTransactionsAccountAgeCell, +} from "./MarketTransactionsCell"; + +const table = createTable().setRowType(); + +const columns = [ + table.createDataColumn("price", { + id: "price", + header: "Price", + cell: ({ row }) => , + size: 400, + }), + table.createDataColumn("amount", { + id: "amount", + header: "Amount", + size: 400, + cell: ({ row }) => , + }), + table.createDataColumn("cost", { + id: "costs", + header: "Costs", + size: 400, + cell: ({ row }) => , + }), + table.createDataColumn("paymentMethod", { + id: "paymentMethod", + header: "Payment Method", + size: 400, + }), + table.createDataColumn("accountAge", { + id: "accountAge", + header: "Account Age", + size: 400, + cell: ({ row }) => , + }), + table.createDataColumn("accountTrades", { + id: "accountTrades", + header: "Account Trades", + size: 400, + cell: ({ row }) => ( + + ), + }), +]; + +interface MarketTransactionsProps { + data: MarketTransaction[]; +} + +export function MarketTransactions({ data }: MarketTransactionsProps) { + const { classes, cx } = useStyles(); + + return ( + + ); +} + +const useStyles = createStyles(() => ({ + root: { + "thead tr": { + backgroundColor: "#F8F8F8", + color: "#B7B6BD", + + th: { + fontSize: 10, + letterSpacing: "0.05em", + textTransform: "uppercase", + borderBottomColor: "#E8E7EC", + }, + }, + "tbody tr": { + td: { + paddingTop: 22, + paddingBottom: 22, + borderBottomColor: "#E8E7EC", + }, + }, + }, +})); diff --git a/packages/renderer/src/components/organisms/MarketTransactions/MarketTransactionsCell.tsx b/packages/renderer/src/components/organisms/MarketTransactions/MarketTransactionsCell.tsx new file mode 100644 index 0000000..8aa01dc --- /dev/null +++ b/packages/renderer/src/components/organisms/MarketTransactions/MarketTransactionsCell.tsx @@ -0,0 +1,76 @@ +import { Currency } from "@atoms/Currency"; +import { BodyText } from "@atoms/Typography"; +import { Group, Text, ThemeIcon } from "@mantine/core"; +import type { MarketTransaction } from "./_types"; + +export function MarketTransactionsAccountAgeCell({ + row, +}: { + row?: MarketTransaction; +}) { + return ( + + + X + + 65 Days + + ); +} + +export function MarketTransactionsPriceCell({ + row, +}: { + row?: MarketTransaction; +}) { + return ( + + + + + -1% + + ); +} + +export function MarketTransactionsAmountCell({ + row, +}: { + row?: MarketTransaction; +}) { + return ( + + ); +} + +export function MarketTransactionsCostsCell({ + row, +}: { + row?: MarketTransaction; +}) { + return ( + + + + ); +} + +export function MarketTransactionsAccountTradesCell({ + row, +}: { + row?: MarketTransaction; +}) { + return ( + + + + ); +} diff --git a/packages/renderer/src/components/organisms/MarketTransactions/__snapshots__/MarketTransactions.test.tsx.snap b/packages/renderer/src/components/organisms/MarketTransactions/__snapshots__/MarketTransactions.test.tsx.snap new file mode 100644 index 0000000..e2dc4ce --- /dev/null +++ b/packages/renderer/src/components/organisms/MarketTransactions/__snapshots__/MarketTransactions.test.tsx.snap @@ -0,0 +1,184 @@ +// Vitest Snapshot v1 + +exports[`organisms::MarketTransactions > renders without exploding. 1`] = ` + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Price + + Amount + + Costs + + Payment Method + + Account Age + + Account Trades +
+
+
+ €5,000.96 +
+
+ -1% +
+
+
+ XMR 7,564.94 + +
+ $532.34 +
+
+ ASD + +
+
+ X +
+
+ 65 Days +
+
+
+
+ 1,212.00 +
+
+
+
+ €9,637.41 +
+
+ -1% +
+
+
+ XMR 6,483.23 + +
+ $983.32 +
+
+ ASD + +
+
+ X +
+
+ 65 Days +
+
+
+
+ 3,412.00 +
+
+ +`; diff --git a/packages/renderer/src/components/organisms/MarketTransactions/_types.ts b/packages/renderer/src/components/organisms/MarketTransactions/_types.ts new file mode 100644 index 0000000..c6c59d7 --- /dev/null +++ b/packages/renderer/src/components/organisms/MarketTransactions/_types.ts @@ -0,0 +1,12 @@ +export interface MarketTransaction { + price: number; + priceComparison: number; + priceCurrency: string; + amount: number; + amountCurrency: string; + cost: number; + costCurrency: string; + paymentMethod: string; + accountAge: number; + accountTrades: number; +} diff --git a/packages/renderer/src/components/organisms/MarketTransactions/index.ts b/packages/renderer/src/components/organisms/MarketTransactions/index.ts new file mode 100644 index 0000000..addb0fe --- /dev/null +++ b/packages/renderer/src/components/organisms/MarketTransactions/index.ts @@ -0,0 +1 @@ +export * from "./MarketTransactions"; diff --git a/packages/renderer/src/components/organisms/Sidebar/_constants.tsx b/packages/renderer/src/components/organisms/Sidebar/_constants.tsx index 603b449..4f56188 100644 --- a/packages/renderer/src/components/organisms/Sidebar/_constants.tsx +++ b/packages/renderer/src/components/organisms/Sidebar/_constants.tsx @@ -26,6 +26,7 @@ export const NAV_LINKS = [ { icon: , label: "Markets", + link: "/markets", }, { icon: , diff --git a/packages/renderer/src/constants/haveno-daemon.ts b/packages/renderer/src/constants/haveno-daemon.ts index fc261d5..1972b1a 100644 --- a/packages/renderer/src/constants/haveno-daemon.ts +++ b/packages/renderer/src/constants/haveno-daemon.ts @@ -14,7 +14,6 @@ // limitations under the License. // ============================================================================= -export const HAVENO_DAEMON_URL = - import.meta.env.VITE_HAVENO_URL ?? "http://localhost:8080"; +export const HAVENO_DAEMON_URL = "http://170.187.138.125:8080"; export const HAVENO_DAEMON_PASSWORD = import.meta.env.VITE_HAVENO_PASSWORD ?? "apitest"; diff --git a/packages/renderer/src/constants/routes.ts b/packages/renderer/src/constants/routes.ts index 95d46fe..90f00f9 100644 --- a/packages/renderer/src/constants/routes.ts +++ b/packages/renderer/src/constants/routes.ts @@ -22,6 +22,7 @@ export const ROUTES = { CreateAccount: "/onboarding/create-account", RestoreBackup: "/onboarding/restore-backup", MyWallet: "/my-wallet", + Markets: "/markets", // Account routes PaymentAccounts: "/account/payment-accounts", diff --git a/packages/renderer/src/hooks/haveno/useMarketsOffers.ts b/packages/renderer/src/hooks/haveno/useMarketsOffers.ts new file mode 100644 index 0000000..18a76cc --- /dev/null +++ b/packages/renderer/src/hooks/haveno/useMarketsOffers.ts @@ -0,0 +1,34 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import { useQuery } from "react-query"; +import type { OfferInfo } from "haveno-ts"; +import { QueryKeys } from "@constants/query-keys"; +import { useHavenoClient } from "./useHavenoClient"; + +interface MarketsOfferesQuery { + assetCode: string; + direction?: "buy" | "sell"; +} + +export function useMarketsOffers(query: MarketsOfferesQuery) { + const client = useHavenoClient(); + + return useQuery( + [QueryKeys.MoneroNodeIsRunning, query], + () => client.getOffers(query.assetCode, query.direction) + ); +} diff --git a/packages/renderer/src/pages/Markets/MarketsTransactions.tsx b/packages/renderer/src/pages/Markets/MarketsTransactions.tsx new file mode 100644 index 0000000..4eeebd4 --- /dev/null +++ b/packages/renderer/src/pages/Markets/MarketsTransactions.tsx @@ -0,0 +1,35 @@ +import { NavbarLayout } from "@templates/NavbarLayout"; +import { MarketTransactions } from "@organisms/MarketTransactions"; + +export function MarketsTransactions() { + return ( + + + + ); +} + +const data = [ + { + price: 123, + priceComparison: 0.12, + amount: 123123, + amountCurrency: "EUR", + cost: 123, + costCurrency: "USD", + paymentMethod: "ASD", + accountAge: 12, + accountTrades: 1212, + }, + { + price: 123, + priceComparison: 0.12, + amount: 123123, + amountCurrency: "EUR", + cost: 123, + costCurrency: "USD", + paymentMethod: "ASD", + accountAge: 12, + accountTrades: 1212, + }, +]; diff --git a/packages/renderer/src/pages/Markets/index.ts b/packages/renderer/src/pages/Markets/index.ts new file mode 100644 index 0000000..180ed09 --- /dev/null +++ b/packages/renderer/src/pages/Markets/index.ts @@ -0,0 +1 @@ +export * from "./MarketsTransactions";