Skip to content

Commit

Permalink
Merge pull request #54 from bleu/pedro/cow-311-copy-minor-cow-feedbacks
Browse files Browse the repository at this point in the history
Pedro/cow 311 copy minor cow feedbacks
  • Loading branch information
ribeirojose authored Jul 12, 2024
2 parents 0146755 + 38e2c32 commit 0131995
Show file tree
Hide file tree
Showing 41 changed files with 2,193 additions and 1,963 deletions.
53 changes: 26 additions & 27 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
"test:watch": "pnpm exec jest --watchAll --verbose"
},
"dependencies": {
"@bleu/ui": "^0.1.122",
"@cowprotocol/app-data": "^1.2.2",
"@graphql-codegen/typescript": "^4.0.6",
"@graphql-codegen/typescript-operations": "^4.2.0",
"@hookform/resolvers": "^3.3.4",
"@bleu/ui": "^0.1.124",
"@cowprotocol/app-data": "^2.1.0",
"@graphql-codegen/typescript": "^4.0.9",
"@graphql-codegen/typescript-operations": "^4.2.3",
"@hookform/resolvers": "^3.9.0",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.1",
Expand Down Expand Up @@ -57,12 +57,11 @@
"@radix-ui/react-toggle-group": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.2",
"@safe-global/safe-apps-react-sdk": "^4.7.2",
"@safe-global/safe-apps-sdk": "^9.0.0",
"@safe-global/safe-gateway-typescript-sdk": "^3.18.0",
"@tanstack/react-query": "^5.50.1",
"@safe-global/safe-apps-sdk": "^9.1.0",
"@safe-global/safe-gateway-typescript-sdk": "^3.21.8",
"@tanstack/react-query": "^5.51.1",
"@testing-library/jest-dom": "^6.4.6",
"@wagmi/core": "^2.11.6",
"babel-plugin-react-compiler": "0.0.0-experimental-696af53-20240625",
"@wagmi/core": "^2.11.7",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^0.2.1",
Expand All @@ -73,31 +72,31 @@
"graphql-request": "6.1.0",
"graphql-tag": "^2.12.6",
"jest-environment-jsdom": "^29.7.0",
"next": "15.0.0-canary.60",
"next-themes": "^0.2.1",
"lucide-react": "^0.408.0",
"next": "14.2.5",
"npm-run-all": "^4.1.5",
"parse-prometheus-text-format": "^1.1.1",
"react": "19.0.0-rc-c3cdbec0a7-20240708",
"react-day-picker": "^8.10.0",
"react-dom": "19.0.0-rc-c3cdbec0a7-20240708",
"react-hook-form": "^7.52.0",
"react": "^18.3.1",
"react-day-picker": "^8.10.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.52.1",
"react-query": "^3.39.3",
"react-resizable-panels": "^2.0.9",
"reactflow": "^11.10.4",
"react-resizable-panels": "^2.0.20",
"reactflow": "^11.11.4",
"sonner": "^1.5.0",
"swr": "^2.2.5",
"tailwind-merge": "^2.3.0",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7",
"ts-jest": "^29.1.5",
"ts-jest": "^29.2.2",
"vaul": "^0.9.1",
"viem": "^2.7.9",
"viem": "^2.17.3",
"vocs": "1.0.0-alpha.52",
"zod": "^3.23.8"
},
"devDependencies": {
"@graphql-codegen/cli": "5.0.0",
"@graphql-codegen/typescript-graphql-request": "6.1.0",
"@next/eslint-plugin-next": "^14.1.0",
"@graphql-codegen/cli": "5.0.2",
"@graphql-codegen/typescript-graphql-request": "6.2.0",
"@next/eslint-plugin-next": "^14.2.5",
"@types/dagre": "^0.7.52",
"@types/jest": "^29.5.12",
"@types/node": "^20.14.10",
Expand All @@ -107,7 +106,7 @@
"@typescript-eslint/parser": "^6.21.0",
"autoprefixer": "^10.4.19",
"eslint": "^8.56.0",
"eslint-config-next": "14.2.4",
"eslint-config-next": "14.2.5",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-compat": "latest",
Expand All @@ -118,8 +117,8 @@
"eslint-plugin-simple-import-sort": "latest",
"eslint-plugin-tailwindcss": "^3.17.4",
"jest": "^29.7.0",
"postcss": "^8.4.35",
"prettier": "^3.1.1",
"postcss": "^8.4.39",
"prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.5.11",
"tailwind-scrollbar": "^3.1.0",
"tailwindcss": "^3.4.4",
Expand Down
2,739 changes: 1,271 additions & 1,468 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/app/[chainId]/[safeAddress]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ export default function Page() {
return (
<>
<TxPendingDialog />
<div className="flex size-full mb-2 mt-16 px-8 flex gap-6">
<div className="w-[600px]">
<SwapCardContextProvider>
<SwapCardContextProvider>
<div className="flex size-full mb-2 mt-16 px-8 gap-6">
<div className="mx-auto w-1/3">
<SwapCard />
</SwapCardContextProvider>
</div>
<OrderTabs />
</div>
<OrderTabs />
</div>
</SwapCardContextProvider>
</>
);
}
4 changes: 2 additions & 2 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ div[data-rk] {
--card-foreground: 0 0% 100%;
--radius: 20px;

--highlight: 39 100% 50%;
--highlight: 42 100% 71%;
--info: 203 13% 88%;
--success: 162 99% 40%;
--warning: 39 100% 50%;
--warning: 42 100% 71%;
}

* {
Expand Down
2 changes: 1 addition & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function Layout({
className={cn(
flechaS.variable,
circularStd.variable,
"bg-background flex h-full flex-col font-sans font-normal text-white bg-background border-border",
"flex h-full flex-col font-sans font-normal text-white bg-background border-border",
)}
>
<RootLayout>{children}</RootLayout>
Expand Down
82 changes: 59 additions & 23 deletions src/components/AdvancedSettingsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import {
} from "@bleu/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { Label } from "@radix-ui/react-dropdown-menu";
import { GearIcon, ResetIcon } from "@radix-ui/react-icons";
import { ArrowTopRightIcon, GearIcon, ResetIcon } from "@radix-ui/react-icons";
import { useSafeAppsSDK } from "@safe-global/safe-apps-react-sdk";
import cn from "clsx";
import * as React from "react";
import { useForm } from "react-hook-form";
import { useForm, useWatch } from "react-hook-form";

import { useSwapCardContext } from "#/contexts/swapCardContext";
import { ChainId } from "#/lib/publicClients";
Expand All @@ -25,6 +25,7 @@ import { TOOLTIP_DESCRIPTIONS } from "#/lib/tooltipDescriptions";
import { AdvancedSwapSettings } from "#/lib/types";

import { Checkbox } from "./Checkbox";
import { BlockExplorerLink } from "./ExplorerLink";
import { Input } from "./Input";
import {
Accordion,
Expand All @@ -34,40 +35,70 @@ import {
} from "./ui/accordion";
import { Form } from "./ui/form";

function haveSettingsChanged(
current: Partial<AdvancedSwapSettings>,
defaults: AdvancedSwapSettings
): boolean {
return Object.keys(current).some(
(key) =>
current[key as keyof AdvancedSwapSettings] !==
defaults[key as keyof AdvancedSwapSettings]
);
}

export function AdvancedSettingsDialog() {
const [open, setOpen] = React.useState(false);
const {
safe: { safeAddress, chainId },
} = useSafeAppsSDK();
const { setAdvancedSettings, advancedSettings } = useSwapCardContext();

const defaultSettings = {
receiver: safeAddress,
maxHoursSinceOracleUpdates: 1,
tokenBuyOracle: "" as const,
tokenSellOracle: "" as const,
partiallyFillable: false,
} as const;

const form = useForm<AdvancedSwapSettings>({
resolver: zodResolver(generateAdvancedSettingsSchema(chainId as ChainId)),
defaultValues: advancedSettings,
});

const {
reset,
control,
formState: { isSubmitting },
} = form;

const currentValues = useWatch({ control });
const areSettingsDifferentFromDefault = haveSettingsChanged(
currentValues,
defaultSettings
);

const receiver = useWatch({ control, name: "receiver" });

return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<button>
<button
className={cn(areSettingsDifferentFromDefault && "text-primary")}
>
<GearIcon className="size-6" />
</button>
</DialogTrigger>
<DialogPortal>
<DialogOverlay
id="dialog-overlay"
className={cn(
"bg-black/20 data-[state=open]:animate-overlayShow fixed inset-0 rounded-lg",
"bg-black/20 data-[state=open]:animate-overlayShow fixed inset-0 rounded-lg"
)}
/>
<DialogContent
className={cn(
"data-[state=open]:animate-contentShow fixed top-[50%] left-[50%] max-h-[85vh] translate-x-[-50%] translate-y-[-50%] rounded-lg focus:outline-none bg-foreground w-[90vw] max-w-[450px] p-[25px]",
"data-[state=open]:animate-contentShow fixed top-[50%] left-[50%] max-h-[85vh] translate-x-[-50%] translate-y-[-50%] rounded-lg focus:outline-none bg-foreground w-[90vw] max-w-[450px] p-[25px]"
)}
>
<div className="flex flex-col justify-between w-full">
Expand All @@ -88,6 +119,14 @@ export function AdvancedSettingsDialog() {
label="Receiver"
placeholder="0xabc...123"
tooltipText={TOOLTIP_DESCRIPTIONS.RECIPIENT}
extraLabelElement={
<BlockExplorerLink
type="address"
label={<ArrowTopRightIcon />}
identifier={receiver}
networkId={chainId as ChainId}
/>
}
/>
<Separator className="bg-white mt-2" />
<div className="flex flex-col gap-2">
Expand Down Expand Up @@ -132,6 +171,8 @@ export function AdvancedSettingsDialog() {
tooltipText={
TOOLTIP_DESCRIPTIONS.MAX_TIME_SINCE_LAST_ORACLE_UPDATE
}
min={0}
max={24 * 365}
/>
</Accordion>
</div>
Expand All @@ -154,24 +195,19 @@ export function AdvancedSettingsDialog() {
>
Save Settings
</Button>
<Button
variant="link"
type="button"
className="text-xs flex gap-1 text-white items-center "
onClick={() => {
const defaultSettings = {
receiver: safeAddress,
maxHoursSinceOracleUpdates: 1,
tokenBuyOracle: "" as const,
tokenSellOracle: "" as const,
partiallyFillable: false,
};
reset(defaultSettings);
setAdvancedSettings(defaultSettings);
}}
>
<ResetIcon className="size-3" /> Reset to default settings
</Button>
{areSettingsDifferentFromDefault && (
<Button
variant="link"
type="button"
className="text-xs flex gap-1 text-white items-center pb-0 h-min"
onClick={() => {
reset(defaultSettings);
setAdvancedSettings(defaultSettings);
}}
>
<ResetIcon className="size-3" /> Reset to default settings
</Button>
)}
</Form>
</DialogContent>
</DialogPortal>
Expand Down
80 changes: 69 additions & 11 deletions src/components/CurrentMarketPrice.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,84 @@
"use client";

import { formatNumber } from "@bleu/ui";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
formatNumber,
} from "@bleu/ui";
import { ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons";
import { useState } from "react";
import { useFormContext, useWatch } from "react-hook-form";

import { useTokens } from "#/contexts/tokensContext";
import { SwapData } from "#/lib/types";

export function CurrentMarketPrice() {
const { control } = useFormContext<SwapData>();

const [tokenSell, tokenBuy, marketPrice] = useWatch({
const [tokenSell, tokenBuy] = useWatch({
control,
name: ["tokenSell", "tokenBuy", "marketPrice"],
name: ["tokenSell", "tokenBuy"],
});
const [open, setOpen] = useState(false);

const { useTokenPairPrice, useTokenPrice } = useTokens();
const { data: tokenBuyPrice } = useTokenPrice(tokenBuy);
const { data: tokenSellPrice } = useTokenPrice(tokenSell);
const { data: marketPrice } = useTokenPairPrice(tokenSell, tokenBuy);

if (!tokenSell || !tokenBuy || !marketPrice || marketPrice <= 0) return null;

const formatPrice = (price: number) =>
formatNumber(price, 6, "currency", "standard");
const formatDecimal = (price: number) =>
formatNumber(price, 6, "decimal", "standard");
const inversePrice = 1 / marketPrice;

return (
<span className="text-xs">
Current market price:{" "}
<b>
{tokenSell.symbol} = {formatNumber(marketPrice, 4)}{" "}
</b>
{tokenBuy.symbol}
</span>
<div className="text-xs font-mono p-2 rounded-lg text-white inline-block">
<Collapsible open={open} onOpenChange={setOpen}>
<div className="flex items-center justify-between">
<span className="w-24 flex space-x-1 hover:opacity-100 opacity-50">
<span>1 {tokenSell.symbol} </span>
<CollapsibleTrigger>
{open ? (
<ChevronUpIcon className="size-3" />
) : (
<ChevronDownIcon className="size-3" />
)}
</CollapsibleTrigger>
</span>

<div className="flex items-center justify-end flex-1 space-x-2">
<span className="text-right whitespace-nowrap">
{formatDecimal(inversePrice)} {tokenBuy.symbol}
</span>
{tokenSellPrice && (
<span className="opacity-50 text-right whitespace-nowrap">
~{formatPrice(tokenSellPrice)}
</span>
)}
</div>
</div>

<CollapsibleContent>
<div className="flex items-center justify-between mt-1">
<span className="w-24 hover:opacity-100 opacity-50">
1 {tokenBuy.symbol}
</span>
<div className="flex items-center justify-end flex-1 space-x-2">
<span className="text-right whitespace-nowrap">
{formatDecimal(marketPrice)} {tokenSell.symbol}
</span>
{tokenBuyPrice && (
<span className="opacity-50 text-right whitespace-nowrap">
~{formatPrice(tokenBuyPrice)}
</span>
)}
</div>
</div>
</CollapsibleContent>
</Collapsible>
</div>
);
}
Loading

0 comments on commit 0131995

Please sign in to comment.