Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test #69

Closed
wants to merge 2 commits into from
Closed

Test #69

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ A React-based trading application for options trading, built with Test-Driven De
- Atomic component architecture
- Test-driven development methodology
- State management with Zustand
- Progressive Web App (PWA) support with offline capabilities

## Getting Started

Expand Down Expand Up @@ -280,6 +281,24 @@ RSBUILD_SSE_PUBLIC_PATH=/sse
RSBUILD_SSE_PROTECTED_PATH=/sse
```

## Progressive Web App (PWA)

Champion Trader is enabled as a Progressive Web App, providing:

- Offline functionality
- Install prompts for adding to home screen
- Background synchronization for offline trades
- Push notifications support
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Provide details about push notification implementation and usage

The documentation mentions push notification support, but lacks details about how it's implemented and used within the app. Adding this information would be beneficial.

Suggested change
- Push notifications support
- Push notifications support
- Implemented with the Web Push API, allowing real-time notifications.
- A dedicated service worker listens for push events and displays notifications even when the app is in the background.
- The server triggers notifications via a configured push service, ensuring users are alerted to relevant trading updates.

- Cache-first strategy for static assets
- Fallback offline page

### Offline Support
- Automatic detection of online/offline status with visual indicators
- Queuing of trades when offline for later processing
- IndexedDB storage for pending operations
- Background sync when connection is restored
- Customized offline experience

## Contributing

1. Fork the repository
Expand Down
5 changes: 5 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#0033ff" />
<meta name="description" content="A React-based trading application for options trading" />
<link rel="manifest" href="/manifest.json" />
<link rel="apple-touch-icon" href="/logo192.png" />
<title>Champion Trader</title>
</head>
<body>
<div id="root"></div>
<noscript>You need to enable JavaScript to run this app.</noscript>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
Empty file added public/icons/trade.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added public/logo192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added public/logo512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "Champion Trader",
"short_name": "ChampionTrader",
"description": "A React-based trading application for options trading",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0033ff",
"icons": [
{
"src": "/logo192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/logo512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
],
"orientation": "portrait",
"categories": ["finance", "trading"],
"shortcuts": [
{
"name": "Open Trading Page",
"short_name": "Trade",
"description": "Go to trading page",
"url": "/trade",
"icons": [{ "src": "/icons/trade.png", "sizes": "96x96" }]
}
]
}
161 changes: 161 additions & 0 deletions public/offline.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Champion Trader - Offline</title>
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#0033ff">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f5f5f5;
color: #333;
}

.container {
text-align: center;
padding: 2rem;
border-radius: 8px;
background-color: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
max-width: 90%;
width: 400px;
}

h1 {
margin-top: 0;
color: #0033ff;
}

.icon {
font-size: 64px;
margin-bottom: 1rem;
}

.btn {
display: inline-block;
background-color: #0033ff;
color: white;
padding: 10px 20px;
border-radius: 4px;
text-decoration: none;
font-weight: 500;
margin-top: 1rem;
border: none;
cursor: pointer;
}

.pending-trades {
margin-top: 2rem;
text-align: left;
border-top: 1px solid #eee;
padding-top: 1rem;
}

.trade-item {
padding: 0.5rem;
border-bottom: 1px solid #eee;
}

@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
color: #eee;
}

.container {
background-color: #1e1e1e;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
}

h1 {
color: #4d8cff;
}

.btn {
background-color: #4d8cff;
}

.pending-trades {
border-top: 1px solid #333;
}

.trade-item {
border-bottom: 1px solid #333;
}
}
</style>
</head>
<body>
<div class="container">
<div class="icon">📡</div>
<h1>You're offline</h1>
<p>Champion Trader can't connect to the internet right now. Some features may be unavailable until you're back online.</p>

<button class="btn" id="refresh-btn">Try Again</button>

<div class="pending-trades" id="pending-trades" style="display: none;">
<h2>Pending Trades</h2>
<div id="pending-trades-list"></div>
</div>
</div>

<script>
// Check if the browser is online
function updateOnlineStatus() {
if (navigator.onLine) {
document.querySelector('.container p').textContent = 'Connected! Refreshing...';
// Reload the page
window.location.reload();
}
}

// Try again button
document.getElementById('refresh-btn').addEventListener('click', () => {
document.querySelector('.container p').textContent = 'Checking connection...';
updateOnlineStatus();
});

// Listen for online event
window.addEventListener('online', updateOnlineStatus);

// Try to load the pending trades from IndexedDB
if ('indexedDB' in window) {
const request = indexedDB.open('ChampionTraderDB', 1);

request.onsuccess = (event) => {
const db = event.target.result;

if (db.objectStoreNames.contains('pendingTrades')) {
const transaction = db.transaction('pendingTrades', 'readonly');
const store = transaction.objectStore('pendingTrades');
const getAll = store.getAll();

getAll.onsuccess = () => {
const pendingTrades = getAll.result;

if (pendingTrades && pendingTrades.length > 0) {
document.getElementById('pending-trades').style.display = 'block';
const list = document.getElementById('pending-trades-list');

pendingTrades.forEach(trade => {
const item = document.createElement('div');
item.className = 'trade-item';
item.textContent = `${trade.type} trade - ${trade.instrument} (${new Date(trade.timestamp).toLocaleString()})`;
list.appendChild(item);
});
}
};
}
};
}
</script>
</body>
</html>
Loading
Loading