update
This commit is contained in:
@@ -52,7 +52,7 @@ header {
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
letter-spacing: 0.25em;
|
letter-spacing: 0.25em;
|
||||||
text-shadow: 0 10 30px rgba(88, 166, 255, 0.3);
|
text-shadow: 4px 12px 12px rgb(173, 1, 124);
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
@@ -105,15 +105,16 @@ header {
|
|||||||
.date-label {
|
.date-label {
|
||||||
font-family: 'Ac437_Rainbow100_re_132';
|
font-family: 'Ac437_Rainbow100_re_132';
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 1.45rem;
|
font-size: 1.65rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
letter-spacing: 2px;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.date-status {
|
.date-status {
|
||||||
display: block;
|
display: block;
|
||||||
font-family: 'Ac437_Rainbow100_re_132', monospace;
|
font-family: 'Ac437_Rainbow100_re_132', monospace;
|
||||||
font-size: 0.75rem;
|
font-size: 1rem;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
margin-top: 0.25rem;
|
margin-top: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { Login } from './pages/Login';
|
|||||||
import { Signup } from './pages/Signup';
|
import { Signup } from './pages/Signup';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
|
||||||
// Create React Query client
|
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {
|
queries: {
|
||||||
@@ -20,7 +19,6 @@ const queryClient = new QueryClient({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Redirect authenticated users away from auth pages
|
|
||||||
function PublicRoute({ children }) {
|
function PublicRoute({ children }) {
|
||||||
const { currentUser } = useAuth();
|
const { currentUser } = useAuth();
|
||||||
|
|
||||||
|
|||||||
@@ -1,77 +1,50 @@
|
|||||||
/**
|
|
||||||
* Trading API Client
|
|
||||||
* Communicates with backend REST API
|
|
||||||
*/
|
|
||||||
|
|
||||||
const API_BASE = 'http://localhost:3001/v1';
|
const API_BASE = 'http://localhost:3001/v1';
|
||||||
|
|
||||||
export const tradingApi = {
|
export const tradingApi = {
|
||||||
/**
|
|
||||||
* Get current trading day prices
|
|
||||||
*/
|
|
||||||
getCurrentPrices: async () => {
|
getCurrentPrices: async () => {
|
||||||
const response = await fetch(`${API_BASE}/prices/today`);
|
const response = await fetch(`${API_BASE}/prices/today`);
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
return response.json();
|
return response.json();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current trading day trades
|
|
||||||
*/
|
|
||||||
getCurrentTrades: async () => {
|
getCurrentTrades: async () => {
|
||||||
const response = await fetch(`${API_BASE}/trades/today`);
|
const response = await fetch(`${API_BASE}/trades/today`);
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
return response.json();
|
return response.json();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current grid state
|
|
||||||
*/
|
|
||||||
getCurrentGrid: async () => {
|
getCurrentGrid: async () => {
|
||||||
const response = await fetch(`${API_BASE}/grid/current`);
|
const response = await fetch(`${API_BASE}/grid/current`);
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
return response.json();
|
return response.json();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Get latest support/resistance levels
|
|
||||||
*/
|
|
||||||
getLatestSR: async () => {
|
getLatestSR: async () => {
|
||||||
const response = await fetch(`${API_BASE}/support-resistance/latest`);
|
const response = await fetch(`${API_BASE}/support-resistance/latest`);
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
return response.json();
|
return response.json();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Get available trading days
|
|
||||||
*/
|
|
||||||
getAvailableDays: async () => {
|
getAvailableDays: async () => {
|
||||||
const response = await fetch(`${API_BASE}/prices/days`);
|
const response = await fetch(`${API_BASE}/prices/days`);
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
return response.json();
|
return response.json();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Get historical prices for a specific day
|
|
||||||
*/
|
|
||||||
getPricesByDay: async (date) => {
|
getPricesByDay: async (date) => {
|
||||||
const response = await fetch(`${API_BASE}/prices/day/${date}`);
|
const response = await fetch(`${API_BASE}/prices/day/${date}`);
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
return response.json();
|
return response.json();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Get historical trades for a specific day
|
|
||||||
*/
|
|
||||||
getTradesByDay: async (date) => {
|
getTradesByDay: async (date) => {
|
||||||
const response = await fetch(`${API_BASE}/trades/day/${date}`);
|
const response = await fetch(`${API_BASE}/trades/day/${date}`);
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
return response.json();
|
return response.json();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Get trade statistics
|
|
||||||
*/
|
|
||||||
getTradeStats: async () => {
|
getTradeStats: async () => {
|
||||||
const response = await fetch(`${API_BASE}/trades/stats`);
|
const response = await fetch(`${API_BASE}/trades/stats`);
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ const app = initializeApp(firebaseConfig);
|
|||||||
export const auth = getAuth(app);
|
export const auth = getAuth(app);
|
||||||
export const db = getFirestore(app);
|
export const db = getFirestore(app);
|
||||||
|
|
||||||
// Add email to waitlist collection
|
|
||||||
export async function addToWaitlist(email) {
|
export async function addToWaitlist(email) {
|
||||||
try {
|
try {
|
||||||
await addDoc(collection(db, 'trahn-trade-signups'), {
|
await addDoc(collection(db, 'trahn-trade-signups'), {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ export function Chart({ prices, trades }) {
|
|||||||
const [tooltip, setTooltip] = useState(null);
|
const [tooltip, setTooltip] = useState(null);
|
||||||
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
|
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
|
||||||
|
|
||||||
// Handle resize
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updateDimensions = () => {
|
const updateDimensions = () => {
|
||||||
if (containerRef.current) {
|
if (containerRef.current) {
|
||||||
@@ -53,7 +52,6 @@ export function Chart({ prices, trades }) {
|
|||||||
const chartWidth = width - PADDING.left - PADDING.right;
|
const chartWidth = width - PADDING.left - PADDING.right;
|
||||||
const chartHeight = height - PADDING.top - PADDING.bottom;
|
const chartHeight = height - PADDING.top - PADDING.bottom;
|
||||||
|
|
||||||
// Clear
|
|
||||||
ctx.clearRect(0, 0, width, height);
|
ctx.clearRect(0, 0, width, height);
|
||||||
|
|
||||||
if (!prices || prices.length === 0) {
|
if (!prices || prices.length === 0) {
|
||||||
@@ -64,7 +62,6 @@ export function Chart({ prices, trades }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate bounds
|
|
||||||
const priceValues = prices.map(d => d.p || d.price);
|
const priceValues = prices.map(d => d.p || d.price);
|
||||||
const times = prices.map(d => d.t || d.timestamp);
|
const times = prices.map(d => d.t || d.timestamp);
|
||||||
|
|
||||||
@@ -79,7 +76,6 @@ export function Chart({ prices, trades }) {
|
|||||||
|
|
||||||
const baselinePrice = priceValues[0];
|
const baselinePrice = priceValues[0];
|
||||||
|
|
||||||
// Coordinate converters
|
|
||||||
const priceToY = (price) => {
|
const priceToY = (price) => {
|
||||||
const range = maxPrice - minPrice;
|
const range = maxPrice - minPrice;
|
||||||
const normalized = (price - minPrice) / range;
|
const normalized = (price - minPrice) / range;
|
||||||
@@ -92,7 +88,6 @@ export function Chart({ prices, trades }) {
|
|||||||
return PADDING.left + chartWidth * normalized;
|
return PADDING.left + chartWidth * normalized;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draw grid
|
|
||||||
ctx.strokeStyle = COLORS.grid;
|
ctx.strokeStyle = COLORS.grid;
|
||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
|
|
||||||
@@ -191,13 +186,11 @@ export function Chart({ prices, trades }) {
|
|||||||
ctx.fillStyle = color + '33';
|
ctx.fillStyle = color + '33';
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
|
|
||||||
// Outer
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(x, y, radius, 0, Math.PI * 2);
|
ctx.arc(x, y, radius, 0, Math.PI * 2);
|
||||||
ctx.fillStyle = color;
|
ctx.fillStyle = color;
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
|
|
||||||
// Inner
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(x, y, radius - 3, 0, Math.PI * 2);
|
ctx.arc(x, y, radius - 3, 0, Math.PI * 2);
|
||||||
ctx.fillStyle = COLORS.bg;
|
ctx.fillStyle = COLORS.bg;
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ function reducer(state, action) {
|
|||||||
export function TradingDataProvider({ children }) {
|
export function TradingDataProvider({ children }) {
|
||||||
const [state, dispatch] = useReducer(reducer, initialState);
|
const [state, dispatch] = useReducer(reducer, initialState);
|
||||||
|
|
||||||
// React Query: Poll current day data every 1 minute
|
|
||||||
const { data: currentData, error, isLoading } = useQuery({
|
const { data: currentData, error, isLoading } = useQuery({
|
||||||
queryKey: ['currentDay'],
|
queryKey: ['currentDay'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
@@ -87,7 +86,6 @@ export function TradingDataProvider({ children }) {
|
|||||||
retryDelay: 2000,
|
retryDelay: 2000,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update context when live data changes
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentData) {
|
if (currentData) {
|
||||||
dispatch({
|
dispatch({
|
||||||
@@ -97,7 +95,6 @@ export function TradingDataProvider({ children }) {
|
|||||||
}
|
}
|
||||||
}, [currentData]);
|
}, [currentData]);
|
||||||
|
|
||||||
// Handle connection status
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (error) {
|
if (error) {
|
||||||
dispatch({ type: 'SET_CONNECTION_STATUS', status: 'error' });
|
dispatch({ type: 'SET_CONNECTION_STATUS', status: 'error' });
|
||||||
|
|||||||
@@ -1,18 +1,3 @@
|
|||||||
/**
|
|
||||||
* DEPRECATED - Replaced by TradingDataContext + React Query
|
|
||||||
*
|
|
||||||
* This file is kept for reference but no longer used.
|
|
||||||
* The new implementation:
|
|
||||||
* - Uses React Query for polling
|
|
||||||
* - Uses Context for state management
|
|
||||||
* - Calls REST API instead of JSON files
|
|
||||||
*
|
|
||||||
* See:
|
|
||||||
* - contexts/TradingDataContext.jsx
|
|
||||||
* - hooks/useTradingData.js
|
|
||||||
* - api/tradingApi.js
|
|
||||||
*/
|
|
||||||
|
|
||||||
export function useChartData() {
|
export function useChartData() {
|
||||||
throw new Error('useChartData is deprecated. Use useTradingData from TradingDataContext instead.');
|
throw new Error('useChartData is deprecated. Use useTradingData from TradingDataContext instead.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,7 @@
|
|||||||
/**
|
|
||||||
* Custom hooks for trading data management
|
|
||||||
* Handles carousel navigation and historical day loading
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { useTradingData } from '../contexts/TradingDataContext';
|
import { useTradingData } from '../contexts/TradingDataContext';
|
||||||
import { tradingApi } from '../api/tradingApi';
|
import { tradingApi } from '../api/tradingApi';
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook for loading historical day data (lazy load)
|
|
||||||
*/
|
|
||||||
export function useHistoricalDay(date, enabled = false) {
|
export function useHistoricalDay(date, enabled = false) {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['historicalDay', date],
|
queryKey: ['historicalDay', date],
|
||||||
@@ -26,9 +18,6 @@ export function useHistoricalDay(date, enabled = false) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook for carousel navigation
|
|
||||||
*/
|
|
||||||
export function useCarousel() {
|
export function useCarousel() {
|
||||||
const { state, dispatch } = useTradingData();
|
const { state, dispatch } = useTradingData();
|
||||||
|
|
||||||
@@ -38,12 +27,9 @@ export function useCarousel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (index === state.availableDays.length - 1) {
|
if (index === state.availableDays.length - 1) {
|
||||||
// Navigate to live (current) day
|
|
||||||
dispatch({ type: 'SWITCH_TO_LIVE' });
|
dispatch({ type: 'SWITCH_TO_LIVE' });
|
||||||
} else {
|
} else {
|
||||||
// Load historical day
|
|
||||||
const date = state.availableDays[index];
|
const date = state.availableDays[index];
|
||||||
// Historical data will be loaded via useHistoricalDay in Dashboard
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'LOAD_HISTORICAL_DAY',
|
type: 'LOAD_HISTORICAL_DAY',
|
||||||
prices: [],
|
prices: [],
|
||||||
|
|||||||
@@ -12,11 +12,9 @@ export function Dashboard() {
|
|||||||
const { state, dispatch } = useTradingData();
|
const { state, dispatch } = useTradingData();
|
||||||
const carousel = useCarousel();
|
const carousel = useCarousel();
|
||||||
|
|
||||||
// Load historical day data when viewing past days
|
|
||||||
const historicalDate = !state.isLive ? state.availableDays[state.currentDayIndex] : null;
|
const historicalDate = !state.isLive ? state.availableDays[state.currentDayIndex] : null;
|
||||||
const { data: historicalData } = useHistoricalDay(historicalDate, !state.isLive);
|
const { data: historicalData } = useHistoricalDay(historicalDate, !state.isLive);
|
||||||
|
|
||||||
// Update context with historical data when loaded
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (historicalData && !state.isLive) {
|
if (historicalData && !state.isLive) {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { addToWaitlist } from '../auth/firebase';
|
import { addToWaitlist } from '../auth/firebase';
|
||||||
//a comment
|
|
||||||
|
|
||||||
export function Signup() {
|
export function Signup() {
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [submitted, setSubmitted] = useState(false);
|
const [submitted, setSubmitted] = useState(false);
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
async function handleSubmit(e) {
|
async function handleSubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -33,8 +30,7 @@ export function Signup() {
|
|||||||
}
|
}
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
// some spacing
|
|
||||||
//more
|
|
||||||
return (
|
return (
|
||||||
<div className="auth-container">
|
<div className="auth-container">
|
||||||
<div className="auth-card">
|
<div className="auth-card">
|
||||||
|
|||||||
Reference in New Issue
Block a user