Skip to content

Commit

Permalink
Merge pull request #42 from deriv-com/f_ui_fixes
Browse files Browse the repository at this point in the history
Contract Detail Desktop View and UI Fixes
  • Loading branch information
ahmadtaimoor-deriv authored Feb 19, 2025
2 parents 86ce2c6 + 622b9e1 commit 27310e7
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 30 deletions.
14 changes: 7 additions & 7 deletions src/components/MarketInfo/MarketInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ export const MarketInfo: React.FC<MarketInfoProps> = ({
if (isMobile) {
return (
<div
className="w-full cursor-pointer"
className="inline-flex cursor-pointer mx-4 my-2"
data-id="market-info"
onClick={onClick}
>
<div className="flex items-center gap-4 px-4 py-3 bg-black/[0.04]">
<div className="flex items-center gap-4 px-4 py-3 bg-black/[0.04] rounded-lg">
{selectedMarket && (
<div className="w-8 h-8 flex items-center justify-center">
<MarketIcon
Expand All @@ -49,7 +49,7 @@ export const MarketInfo: React.FC<MarketInfoProps> = ({

return (
<div
className="inline-flex cursor-pointer bg-white hover:bg-gray-100 active:bg-gray-200 rounded-lg transition-colors"
className="inline-flex cursor-pointer bg-gray-100 hover:bg-gray-100 active:bg-gray-200 rounded-lg transition-colors"
data-id="market-info"
onClick={onClick}
>
Expand All @@ -65,12 +65,12 @@ export const MarketInfo: React.FC<MarketInfoProps> = ({
)}
<div className="min-w-0">
<div className="flex items-center gap-2">
<div className="text-base font-bold text-black/[0.72] leading-6 font-ibm-plex-sans truncate">{title}</div>
<ChevronDown className="w-5 text-black/[0.72] flex-shrink-0 stroke-[1.5]" />
<div className="text-base font-bold text-[#4C4C4C] leading-6 font-ibm-plex-sans truncate">{title}</div>
<ChevronDown className="w-5 text-[#4C4C4C] flex-shrink-0 stroke-[1.5]" />
</div>
<div className="text-sm text-black/[0.48] leading-5 font-ibm-plex-sans truncate">{subtitle}</div>
<div className="text-sm text-[#808080] leading-5 font-ibm-plex-sans truncate">{subtitle}</div>
</div>
</div>
</div>
)
}
}
2 changes: 1 addition & 1 deletion src/components/PositionsSidebar/PositionsSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,4 @@ export const PositionsSidebar: FC<PositionsSidebarProps> = ({ isOpen, onClose })
);
};

export default PositionsSidebar;
export default PositionsSidebar;
2 changes: 1 addition & 1 deletion src/layouts/MainLayout/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,4 @@ export const MainLayout: React.FC<MainLayoutProps> = ({ children }) => {
</div>
</div>
);
};
};
54 changes: 33 additions & 21 deletions src/screens/ContractDetailsPage/ContractDetailsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useHeaderStore } from "@/stores/headerStore";
import { useBottomNavStore } from "@/stores/bottomNavStore";
import React, { useEffect } from "react"
import { useNavigate } from "react-router-dom"
import { useDeviceDetection } from "@/hooks/useDeviceDetection"
import { useHeaderStore } from "@/stores/headerStore"
import { useBottomNavStore } from "@/stores/bottomNavStore"
import DesktopContractDetailsPage from "./DesktopContractDetailsPage"
import {
Header,
ContractSummary,
OrderDetails,
Chart,
Payout,
EntryExitDetails,
} from "./components";
} from "./components"

const ContractDetailsPage: React.FC = () => {
const navigate = useNavigate();
const setHeaderVisible = useHeaderStore(state => state.setIsVisible);
const setBottomNavVisible = useBottomNavStore(state => state.setIsVisible);
const MobileContractDetailsPage: React.FC = () => {
const navigate = useNavigate()
const setHeaderVisible = useHeaderStore((state) => state.setIsVisible)
const setBottomNavVisible = useBottomNavStore((state) => state.setIsVisible)

useEffect(() => {
setHeaderVisible(false);
setBottomNavVisible(false);
setHeaderVisible(false)
setBottomNavVisible(false)
return () => {
setHeaderVisible(true);
setBottomNavVisible(true);
};
}, [setHeaderVisible, setBottomNavVisible]);
setHeaderVisible(true)
setBottomNavVisible(true)
}
}, [setHeaderVisible, setBottomNavVisible])

return (
<div className="w-full bg-gray-100 h-screen flex flex-col">
<Header />
Expand All @@ -35,11 +38,11 @@ const ContractDetailsPage: React.FC = () => {
<Payout />
<EntryExitDetails />
</div>
</div>
</div>

{/* Close Button */}
<div className=" fixed bottom-0 left-0 right-0 z-[60]">
<div className="mx-2 text-center">
<div className="fixed bottom-0 left-0 right-0 z-[60]">
<div className="mx-2 text-center">
<button
onClick={() => navigate(-1)}
className="text-white bg-black max-w-[500px] mx-auto w-full p-3 px-8 text-center rounded-xl shadow-md"
Expand All @@ -49,7 +52,16 @@ const ContractDetailsPage: React.FC = () => {
</div>
</div>
</div>
);
};
)
}

const ContractDetailsPage: React.FC = () => {
const { isMobile } = useDeviceDetection()
return isMobile ? (
<MobileContractDetailsPage />
) : (
<DesktopContractDetailsPage />
)
}

export default ContractDetailsPage;
export default ContractDetailsPage
52 changes: 52 additions & 0 deletions src/screens/ContractDetailsPage/DesktopContractDetailsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from "react"
import { useNavigate } from "react-router-dom"
import { X } from "lucide-react"
import {
ContractSummary,
EntryExitDetails,
OrderDetails,
Payout,
} from "./components"

const DesktopContractDetailsPage: React.FC = () => {
const navigate = useNavigate()

return (
<div className="flex flex-col h-screen bg-gray-50 w-full" data-testid="desktop-contract-details">
<div className="flex justify-between items-center p-4 bg-white">
<h1 className="text-xl font-bold mx-auto">Contract details</h1>
<button onClick={() => navigate(-1)} className="text-gray-600">
<X className="w-6 h-6" />
</button>
</div>

<div className="flex flex-1 overflow-hidden relative">
<div className="w-[320px] border-r bg-white flex flex-col" data-testid="left-panel">
<div className="flex-1 overflow-y-auto p-4 pb-40" data-testid="content-area">
<ContractSummary />
<OrderDetails />
<Payout />
<EntryExitDetails />
</div>
<div className="absolute bottom-16 left-0 right-0 m-4 w-[290px] b-[55px]" data-testid="close-button-container">
<div className="max-w-[1200px] mx-auto">
<button
onClick={() => navigate(-1)}
className="w-full bg-black text-white py-3 rounded-lg"
>
Close
</button>
</div>
</div>
</div>
<div className="flex-1 flex flex-col">
<div className="flex-1 m-4 mb-20 bg-white rounded-lg border flex items-center justify-center text-gray-500 ">
Chart placeholder
</div>
</div>
</div>
</div>
)
}

export default DesktopContractDetailsPage
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { useNavigate } from "react-router-dom";
import DesktopContractDetailsPage from "../DesktopContractDetailsPage";

// Mock the router hook
jest.mock("react-router-dom", () => ({
useNavigate: jest.fn(),
}));

// Mock the components
jest.mock("../components", () => ({
ContractSummary: function ContractSummary() { return React.createElement('div', { 'data-testid': 'contract-summary' }, 'Contract Summary') },
OrderDetails: function OrderDetails() { return React.createElement('div', { 'data-testid': 'order-details' }, 'Order Details') },
Payout: function Payout() { return React.createElement('div', { 'data-testid': 'payout' }, 'Payout') },
EntryExitDetails: function EntryExitDetails() { return React.createElement('div', { 'data-testid': 'entry-exit-details' }, 'Entry Exit Details') },
}), { virtual: true });

describe("DesktopContractDetailsPage", () => {
const mockNavigate = jest.fn();

beforeEach(() => {
(useNavigate as jest.Mock).mockReturnValue(mockNavigate);
});

afterEach(() => {
jest.clearAllMocks();
});

it("renders all components correctly", () => {
render(<DesktopContractDetailsPage />);

// Check header
expect(screen.getByText("Contract details")).toBeInTheDocument();

// Check all sections are rendered
expect(screen.getByTestId("contract-summary")).toBeInTheDocument();
expect(screen.getByTestId("order-details")).toBeInTheDocument();
expect(screen.getByTestId("payout")).toBeInTheDocument();
expect(screen.getByTestId("entry-exit-details")).toBeInTheDocument();

// Check chart placeholder
expect(screen.getByText("Chart placeholder")).toBeInTheDocument();

// Check close button
expect(screen.getByText("Close")).toBeInTheDocument();
});

it("navigates back when close button is clicked", () => {
render(<DesktopContractDetailsPage />);

const closeButton = screen.getByText("Close");
fireEvent.click(closeButton);

expect(mockNavigate).toHaveBeenCalledWith(-1);
});

it("navigates back when header close button is clicked", () => {
render(<DesktopContractDetailsPage />);

const headerCloseButton = screen.getByRole("button", { name: /close/i });
fireEvent.click(headerCloseButton);

expect(mockNavigate).toHaveBeenCalledWith(-1);
});

it("has correct layout structure", () => {
render(<DesktopContractDetailsPage />);

// Check main container
const mainContainer = screen.getByTestId("desktop-contract-details");
expect(mainContainer).toHaveClass("flex flex-col h-screen bg-gray-50 w-full");

// Check left panel
const leftPanel = screen.getByTestId("left-panel");
expect(leftPanel).toHaveClass("w-[320px] border-r bg-white flex flex-col");

// Check content area
const contentArea = screen.getByTestId("content-area");
expect(contentArea).toHaveClass("flex-1 overflow-y-auto p-4 pb-40");

// Check close button container
const closeButtonContainer = screen.getByTestId("close-button-container");
expect(closeButtonContainer).toHaveClass("absolute bottom-16 left-0 right-0 m-4 w-[290px] b-[55px]");
});

it("renders in correct order", () => {
render(<DesktopContractDetailsPage />);

const content = screen.getByTestId("content-area");
const children = Array.from(content.children);

// Check components are rendered in correct order
expect(children[0]).toHaveAttribute("data-testid", "contract-summary");
expect(children[1]).toHaveAttribute("data-testid", "order-details");
expect(children[2]).toHaveAttribute("data-testid", "payout");
expect(children[3]).toHaveAttribute("data-testid", "entry-exit-details");
});
});

0 comments on commit 27310e7

Please sign in to comment.