225 lines
6.3 KiB
TypeScript
225 lines
6.3 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
|
import { AuthProvider, useAuth } from './contexts/AuthContext';
|
|
import { SocketProvider } from './contexts/SocketContext';
|
|
import Navbar from './components/Navbar';
|
|
import Footer from './components/Footer';
|
|
import AuthModal from './components/AuthModal';
|
|
import AlphaGate from './components/AlphaGate';
|
|
import FeedbackButton from './components/FeedbackButton';
|
|
import Home from './pages/Home';
|
|
import GoogleCallback from './pages/GoogleCallback';
|
|
import VerifyEmail from './pages/VerifyEmail';
|
|
import ResetPassword from './pages/ResetPassword';
|
|
import ItemList from './pages/ItemList';
|
|
import ItemDetail from './pages/ItemDetail';
|
|
import EditItem from './pages/EditItem';
|
|
import RentItem from './pages/RentItem';
|
|
import CreateItem from './pages/CreateItem';
|
|
import Renting from './pages/Renting';
|
|
import Owning from './pages/Owning';
|
|
import Profile from './pages/Profile';
|
|
import PublicProfile from './pages/PublicProfile';
|
|
import Messages from './pages/Messages';
|
|
import ForumPosts from './pages/ForumPosts';
|
|
import ForumPostDetail from './pages/ForumPostDetail';
|
|
import CreateForumPost from './pages/CreateForumPost';
|
|
import MyPosts from './pages/MyPosts';
|
|
import EarningsDashboard from './pages/EarningsDashboard';
|
|
import FAQ from './pages/FAQ';
|
|
import NotFound from './pages/NotFound';
|
|
import PrivateRoute from './components/PrivateRoute';
|
|
import axios from 'axios';
|
|
import './App.css';
|
|
|
|
const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:5001';
|
|
|
|
const AppContent: React.FC = () => {
|
|
const { showAuthModal, authModalMode, closeAuthModal, user } = useAuth();
|
|
const [hasAlphaAccess, setHasAlphaAccess] = useState<boolean | null>(null);
|
|
const [checkingAccess, setCheckingAccess] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const checkAlphaAccess = async () => {
|
|
// Bypass alpha access check if feature is disabled
|
|
if (process.env.REACT_APP_ALPHA_TESTING_ENABLED !== 'true') {
|
|
setHasAlphaAccess(true);
|
|
setCheckingAccess(false);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await axios.get(`${API_URL}/alpha/verify-session`, {
|
|
withCredentials: true,
|
|
});
|
|
setHasAlphaAccess(response.data.hasAccess);
|
|
} catch (error) {
|
|
console.error('Error checking alpha access:', error);
|
|
setHasAlphaAccess(false);
|
|
} finally {
|
|
setCheckingAccess(false);
|
|
}
|
|
};
|
|
|
|
checkAlphaAccess();
|
|
}, []);
|
|
|
|
// Show loading state while checking
|
|
if (checkingAccess) {
|
|
return (
|
|
<div className="d-flex align-items-center justify-content-center min-vh-100">
|
|
<div className="spinner-border text-primary" role="status">
|
|
<span className="visually-hidden">Loading...</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Show alpha gate if no access
|
|
if (!hasAlphaAccess) {
|
|
return <AlphaGate />;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Router>
|
|
<div className="d-flex flex-column min-vh-100">
|
|
<Navbar />
|
|
<main className="flex-grow-1">
|
|
<Routes>
|
|
<Route path="/" element={<Home />} />
|
|
<Route path="/auth/google/callback" element={<GoogleCallback />} />
|
|
<Route path="/verify-email" element={<VerifyEmail />} />
|
|
<Route path="/reset-password" element={<ResetPassword />} />
|
|
<Route path="/items" element={<ItemList />} />
|
|
<Route path="/items/:id" element={<ItemDetail />} />
|
|
<Route path="/users/:id" element={<PublicProfile />} />
|
|
<Route
|
|
path="/items/:id/edit"
|
|
element={
|
|
<PrivateRoute>
|
|
<EditItem />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/items/:id/rent"
|
|
element={
|
|
<PrivateRoute>
|
|
<RentItem />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/create-item"
|
|
element={
|
|
<PrivateRoute>
|
|
<CreateItem />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/renting"
|
|
element={
|
|
<PrivateRoute>
|
|
<Renting />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/owning"
|
|
element={
|
|
<PrivateRoute>
|
|
<Owning />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/profile"
|
|
element={
|
|
<PrivateRoute>
|
|
<Profile />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/messages"
|
|
element={
|
|
<PrivateRoute>
|
|
<Messages />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route path="/forum" element={<ForumPosts />} />
|
|
<Route path="/forum/:id" element={<ForumPostDetail />} />
|
|
<Route
|
|
path="/forum/create"
|
|
element={
|
|
<PrivateRoute>
|
|
<CreateForumPost />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/forum/:id/edit"
|
|
element={
|
|
<PrivateRoute>
|
|
<CreateForumPost />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/my-posts"
|
|
element={
|
|
<PrivateRoute>
|
|
<MyPosts />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/earnings"
|
|
element={
|
|
<PrivateRoute>
|
|
<EarningsDashboard />
|
|
</PrivateRoute>
|
|
}
|
|
/>
|
|
<Route path="/faq" element={<FAQ />} />
|
|
<Route path="*" element={<NotFound />} />
|
|
</Routes>
|
|
</main>
|
|
<Footer />
|
|
</div>
|
|
</Router>
|
|
|
|
<AuthModal
|
|
show={showAuthModal}
|
|
onHide={closeAuthModal}
|
|
initialMode={authModalMode}
|
|
/>
|
|
|
|
{/* Show feedback button for authenticated users */}
|
|
{user && <FeedbackButton />}
|
|
</>
|
|
);
|
|
};
|
|
|
|
const AppWithSocket: React.FC = () => {
|
|
const { user } = useAuth();
|
|
|
|
return (
|
|
<SocketProvider isAuthenticated={!!user}>
|
|
<AppContent />
|
|
</SocketProvider>
|
|
);
|
|
};
|
|
|
|
function App() {
|
|
return (
|
|
<AuthProvider>
|
|
<AppWithSocket />
|
|
</AuthProvider>
|
|
);
|
|
}
|
|
|
|
export default App; |