Skip to content

Commit

Permalink
feat: APP-364 order summary card (#2498)
Browse files Browse the repository at this point in the history
  • Loading branch information
blushi authored Oct 23, 2024
1 parent b198ebe commit 01f2590
Show file tree
Hide file tree
Showing 32 changed files with 575 additions and 302 deletions.
2 changes: 1 addition & 1 deletion web-components/src/components/buttons/SetMaxButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function SetMaxButton({
type="button"
onClick={onClick}
aria-label={ariaLabel}
className="ml-3 sm:ml-10 border-none w-[46px] h-[30px] py-[5px] bg-grey-500 hover:bg-grey-400 rounded text-grey-0 text-sm font-bold font-['Lato'] hover:cursor-pointer"
className="ml-3 sm:ml-10 border-none w-[46px] h-[30px] py-[5px] bg-grey-500 hover:bg-grey-400 rounded text-grey-0 text-sm font-bold font-sans hover:cursor-pointer"
>
{buttonText}
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { action } from '@storybook/addon-actions';
import { Meta, StoryObj } from '@storybook/react';

import { EditableInput } from './EditableInput';
Expand All @@ -15,5 +16,6 @@ export const Default: Story = {

Default.args = {
value: 5,
onChange: () => {},
maxValue: 10,
onChange: action('onChange'),
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ describe('EditableInput', () => {
render(
<EditableInput
value={100}
maxValue={1000}
onChange={onChangeMock}
inputAriaLabel="testEditableInput"
editButtonAriaLabel="Edit"
Expand All @@ -24,11 +25,12 @@ describe('EditableInput', () => {
expect(editButton).toBeInTheDocument();
});

it('renders the input field and update button when when click edit', () => {
it('renders the input field and update button when click edit', () => {
const onChangeMock = vi.fn();
render(
<EditableInput
value={100}
maxValue={1000}
onChange={onChangeMock}
inputAriaLabel="testEditableInput"
editButtonAriaLabel="Edit"
Expand All @@ -55,6 +57,7 @@ describe('EditableInput', () => {
render(
<EditableInput
value={100}
maxValue={1000}
onChange={onChangeMock}
inputAriaLabel="testEditableInput"
editButtonAriaLabel="Edit"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,61 @@
import { ChangeEvent, KeyboardEvent, useState } from 'react';
import {
ChangeEvent,
KeyboardEvent,
useEffect,
useMemo,
useState,
} from 'react';
import { EditButtonIcon } from 'web-components/src/components/buttons/EditButtonIcon';
import { TextButton } from 'web-components/src/components/buttons/TextButton';

interface EditableInputProps {
value: number;
maxValue: number;
onChange: (amount: number) => void;
name?: string;
inputAriaLabel: string;
editButtonAriaLabel: string;
updateButtonText: string;
className?: string;
onInvalidValue?: () => void;
}

export const EditableInput = ({
value,
maxValue,
onChange,
name = '',
inputAriaLabel,
editButtonAriaLabel,
updateButtonText,
className = '',
onInvalidValue,
}: EditableInputProps) => {
const [editable, setEditable] = useState(false);
const [amount, setAmount] = useState(value);

useEffect(() => {
if (!editable && value !== amount) setAmount(value);
}, [amount, value, editable]);

const toggleEditable = () => {
setEditable(!editable);
};

const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
if (isNaN(+e.target.value)) return;
setAmount(+e.target.value);
const value = e.target.value;
const newValue = +value;

if (isNaN(newValue)) return;
if (newValue > maxValue && onInvalidValue) {
onInvalidValue();
}
setAmount(Math.min(newValue, maxValue));
};

const handleOnUpdate = () => {
if (!amountValid) return;
onChange(+amount);
toggleEditable();
};
Expand All @@ -47,17 +68,23 @@ export const EditableInput = ({
}
};

const amountValid = useMemo(
() => amount <= maxValue && amount > 0,
[amount, maxValue],
);

return (
<>
{editable ? (
<div
className={`flex [@media(max-width:340px)]:flex-col [@media(max-width:340px)]:mb-20 sm:flex-row items-center [@media(max-width:340px)]:items-start h-[47px] ${className}`}
>
<input
pattern="[0-9]*"
maxLength={6}
className="min-w-60 max-w-[80px] h-30 py-20 px-10 border border-gray-300 text-base font-normal font-['Lato']"
type="text"
type="number"
step="0.000001"
min={0}
max={maxValue}
className="[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none h-50 py-20 px-15 w-[120px] border border-solid border-grey-300 text-base font-normal font-sans focus:outline-none"
value={amount}
onChange={handleOnChange}
onKeyDown={handleKeyDown}
Expand All @@ -67,7 +94,11 @@ export const EditableInput = ({
data-testid="editable-input"
/>
<TextButton
className="lowercase text-[12px] mt-5 sm:mt-0"
className={`lowercase text-[12px] mt-5 sm:mt-0 font-sans ${
amountValid
? ''
: 'text-grey-300 hover:text-grey-300 cursor-default'
}`}
onClick={handleOnUpdate}
aria-label={updateButtonText}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { makeStyles } from 'tss-react/mui';

import Section from './index';

interface OnBoardingSectionProps {
export interface OnBoardingSectionProps {
title: string;
description?: string | JSX.Element;
headerChildren?: ReactNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function CreditsAmountHeader({
<Title variant="h2" className="text-lg font-black">
<Trans>Amount</Trans>
</Title>
<div className="flex flex-grow justify-end items-center font-['Lato'] text-base">
<div className="flex flex-grow justify-end items-center font-sans text-base">
<div className="text-sm sm:text-base pr-5 flex flex-col items-end sm:flex-row sm:items-center h-[55px]">
<span
className={`${
Expand All @@ -44,9 +44,7 @@ export function CreditsAmountHeader({
: 'pt-[7px] sm:pt-0'
}`}
>
<span className="font-bold font-['Lato'] mr-5">
{creditsAvailable}
</span>
<span className="font-bold font-sans mr-5">{creditsAvailable}</span>
<Trans>credits available</Trans>
</span>
{paymentOption === PAYMENT_OPTIONS.CRYPTO && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ const CreditsWithForm = (args: any) => {
const filteredCryptoSellOrders = cryptoSellOrders.filter(
order => order.askDenom === initCurrency.askDenom,
);
const card = args.paymentOption === PAYMENT_OPTIONS.CARD;
const orderedSellOrders = card
? cardSellOrders.sort((a, b) => a.usdPrice - b.usdPrice)
: filteredCryptoSellOrders?.sort(
(a, b) => Number(a.askAmount) - Number(b.askAmount),
) || [];

return (
<Form form={form as any} onSubmit={form.handleSubmit as any}>
<CreditsAmount
Expand All @@ -58,6 +65,8 @@ const CreditsWithForm = (args: any) => {
creditsAvailable={creditsAvailable}
setCreditsAvailable={setCreditsAvailable}
filteredCryptoSellOrders={filteredCryptoSellOrders}
card={card}
orderedSellOrders={orderedSellOrders}
/>
</Form>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ describe('CreditsAmount', () => {
filteredCryptoSellOrders: [],
cardSellOrders,
cryptoCurrencies,
card: true,
orderedSellOrders: cardSellOrders.sort((a, b) => a.usdPrice - b.usdPrice),
};

it('renders without crashing', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { ChangeEvent, useCallback, useEffect, useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { i18n } from '@lingui/core';
import { msg, plural, Trans } from '@lingui/macro';
import { msg, Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { useSetAtom } from 'jotai';
import { ChooseCreditsFormSchemaType } from 'web-marketplace/src/components/organisms/ChooseCreditsForm/ChooseCreditsForm.schema';

import { errorBannerTextAtom } from 'lib/atoms/error.atoms';

import { PAYMENT_OPTIONS } from 'pages/BuyCredits/BuyCredits.constants';
import { getCreditsAvailableBannerText } from 'pages/BuyCredits/BuyCredits.utils';

import { findDisplayDenom } from '../DenomLabel/DenomLabel.utils';
import {
Expand Down Expand Up @@ -41,6 +41,8 @@ export const CreditsAmount = ({
cryptoCurrencies,
allowedDenoms,
creditTypePrecision,
card,
orderedSellOrders,
}: CreditsAmountProps) => {
const { _ } = useLingui();

Expand All @@ -49,21 +51,6 @@ export const CreditsAmount = ({
useFormContext<ChooseCreditsFormSchemaType>();
const setErrorBannerTextAtom = useSetAtom(errorBannerTextAtom);

const card = useMemo(
() => paymentOption === PAYMENT_OPTIONS.CARD,
[paymentOption],
);
const orderedSellOrders = useMemo(
() =>
card
? cardSellOrders.sort((a, b) => a.usdPrice - b.usdPrice)
: filteredCryptoSellOrders?.sort(
(a, b) => Number(a.askAmount) - Number(b.askAmount),
) || [],

[card, cardSellOrders, filteredCryptoSellOrders],
);

useEffect(() => {
// Set initial credits amount to min(1, creditsAvailable)
if (
Expand Down Expand Up @@ -143,12 +130,8 @@ export const CreditsAmount = ({
return formatSellOrder({ order, card, price });
}),
);
const formattedCreditsAvailable = i18n.number(_creditsAvailable);
setErrorBannerTextAtom(
plural(_creditsAvailable, {
one: `Only ${formattedCreditsAvailable} credit available with those paramaters, order quantity changed`,
other: `Only ${formattedCreditsAvailable} credits available with those paramaters, order quantity changed`,
}),
getCreditsAvailableBannerText(_creditsAvailable),
);
} else {
// Else we keep the same amount of credits
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export interface CreditsAmountProps {
allowedDenoms?: AllowedDenoms;
creditTypePrecision?: number | null;
currency: Currency;
card: boolean;
orderedSellOrders: UISellOrderInfo[];
}

export interface CreditsInputProps {
Expand Down
Loading

0 comments on commit 01f2590

Please sign in to comment.