-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: update documentation for balance management and SSE integration
- Add documentation for new balance components (BalanceDisplay, BalanceHandler) - Create documentation for ContractSSEHandler component - Add balance service REST API documentation - Update llms.txt with new balance management section - Update component and service cross-references
- Loading branch information
1 parent
19891e6
commit 4a8fee6
Showing
30 changed files
with
778 additions
and
262 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React from 'react'; | ||
import { useClientStore } from '@/stores/clientStore'; | ||
|
||
interface BalanceDisplayProps { | ||
onDeposit?: () => void; | ||
depositLabel?: string; | ||
className?: string; | ||
loginUrl?: string; | ||
} | ||
|
||
export const BalanceDisplay: React.FC<BalanceDisplayProps> = ({ | ||
onDeposit, | ||
depositLabel = 'Deposit', | ||
className = '', | ||
loginUrl = 'https://options-trading.deriv.ai/', | ||
}) => { | ||
const { isLoggedIn, balance, currency } = useClientStore(); | ||
|
||
if (!isLoggedIn) { | ||
return ( | ||
<div className={`w-full flex items-center justify-end ${className}`}> | ||
<a | ||
href={loginUrl} | ||
className="px-4 py-2 font-bold text-white bg-teal-500 rounded-3xl hover:bg-teal-600" | ||
> | ||
Log in | ||
</a> | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<div className={`flex items-center justify-between landscape:gap-4 ${className}`}> | ||
<div className="flex flex-col"> | ||
<span className="text-sm text-gray-700">Real</span> | ||
<span className="text-xl font-bold text-teal-500">{balance} {currency}</span> | ||
</div> | ||
<button | ||
className="px-4 py-2 font-bold border border-gray-700 rounded-3xl" | ||
onClick={onDeposit} | ||
> | ||
{depositLabel} | ||
</button> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# BalanceDisplay Component | ||
|
||
The BalanceDisplay component is responsible for presenting the user's current balance in a clear and concise manner. | ||
|
||
## Features | ||
- Displays the current balance along with the currency. | ||
- Integrates with the clientStore for real-time updates. | ||
- Built following atomic component design principles. | ||
|
||
## Props | ||
- **balance**: *number* — The current balance value. | ||
- **currency**: *string* — The currency symbol or code (e.g., USD, EUR). | ||
|
||
## Usage Example | ||
|
||
```tsx | ||
import { BalanceDisplay } from '@/components/BalanceDisplay'; | ||
|
||
function App() { | ||
return ( | ||
<div> | ||
<BalanceDisplay balance={1000} currency="USD" /> | ||
</div> | ||
); | ||
} | ||
|
||
export default App; | ||
``` | ||
|
||
## Testing | ||
- Unit tests are located in the __tests__ folder (`__tests__/BalanceDisplay.test.tsx`), covering rendering scenarios and prop validations. | ||
|
||
## Integration Notes | ||
- This component retrieves balance data from the global clientStore. | ||
- Designed with TDD in mind, ensuring reliability and ease of maintenance. |
110 changes: 110 additions & 0 deletions
110
src/components/BalanceDisplay/__tests__/BalanceDisplay.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { render, screen, fireEvent } from '@testing-library/react'; | ||
import { BalanceDisplay } from '../BalanceDisplay'; | ||
|
||
jest.mock('@/stores/clientStore', () => ({ | ||
useClientStore: jest.fn(() => ({ | ||
token: 'test-token', | ||
isLoggedIn: true, | ||
balance: '1,000', | ||
currency: 'USD', | ||
setBalance: jest.fn(), | ||
setToken: jest.fn(), | ||
logout: jest.fn() | ||
})), | ||
getState: () => ({ | ||
token: 'test-token', | ||
isLoggedIn: true, | ||
balance: '1,000', | ||
currency: 'USD', | ||
setBalance: jest.fn(), | ||
setToken: jest.fn(), | ||
logout: jest.fn() | ||
}) | ||
})); | ||
|
||
describe('BalanceDisplay', () => { | ||
beforeEach(() => { | ||
// Reset all mocks before each test | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
describe('when logged in', () => { | ||
beforeEach(() => { | ||
// Import the mocked module inside the test | ||
const { useClientStore } = require('@/stores/clientStore'); | ||
(useClientStore as jest.Mock).mockReturnValue({ | ||
isLoggedIn: true, | ||
balance: '1,000', | ||
currency: 'USD' | ||
}); | ||
}); | ||
|
||
it('renders balance from store and default deposit label', () => { | ||
render(<BalanceDisplay />); | ||
|
||
expect(screen.getByText('Real')).toBeInTheDocument(); | ||
expect(screen.getByText('1,000 USD')).toBeInTheDocument(); // matches combined balance and currency | ||
expect(screen.getByText('Deposit')).toBeInTheDocument(); | ||
}); | ||
|
||
it('renders custom deposit label when provided', () => { | ||
render(<BalanceDisplay depositLabel="Add Funds" />); | ||
|
||
expect(screen.getByText('Add Funds')).toBeInTheDocument(); | ||
}); | ||
|
||
it('calls onDeposit when deposit button is clicked', () => { | ||
const mockOnDeposit = jest.fn(); | ||
render(<BalanceDisplay onDeposit={mockOnDeposit} />); | ||
|
||
fireEvent.click(screen.getByText('Deposit')); | ||
expect(mockOnDeposit).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('applies custom className when provided', () => { | ||
render(<BalanceDisplay className="custom-class" />); | ||
|
||
expect(screen.getByText('Real').parentElement?.parentElement).toHaveClass('custom-class'); | ||
}); | ||
}); | ||
|
||
describe('when logged out', () => { | ||
beforeEach(() => { | ||
const { useClientStore } = require('@/stores/clientStore'); | ||
(useClientStore as jest.Mock).mockReturnValue({ | ||
isLoggedIn: false, | ||
balance: '0', | ||
currency: 'USD' | ||
}); | ||
}); | ||
|
||
it('renders login button', () => { | ||
render(<BalanceDisplay />); | ||
|
||
expect(screen.getByText('Log in')).toBeInTheDocument(); | ||
expect(screen.queryByText('Real')).not.toBeInTheDocument(); | ||
expect(screen.queryByText('0 USD')).not.toBeInTheDocument(); | ||
}); | ||
|
||
it('renders login button with default login URL', () => { | ||
render(<BalanceDisplay />); | ||
|
||
const loginLink = screen.getByText('Log in'); | ||
expect(loginLink).toHaveAttribute('href', 'https://options-trading.deriv.ai/'); | ||
}); | ||
|
||
it('renders login button with custom login URL when provided', () => { | ||
const customUrl = 'https://custom-login.example.com'; | ||
render(<BalanceDisplay loginUrl={customUrl} />); | ||
|
||
const loginLink = screen.getByText('Log in'); | ||
expect(loginLink).toHaveAttribute('href', customUrl); | ||
}); | ||
|
||
it('applies custom className when provided', () => { | ||
render(<BalanceDisplay className="custom-class" />); | ||
|
||
expect(screen.getByText('Log in').parentElement).toHaveClass('custom-class'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { BalanceDisplay } from './BalanceDisplay'; |
Oops, something went wrong.