first commit

This commit is contained in:
2026-09-07 20:36:18 +05:30
commit fd366f7e4a
231 changed files with 52631 additions and 0 deletions

110
src/App.jsx Normal file
View File

@@ -0,0 +1,110 @@
import { Toaster } from '@/components/ui/toaster';
import { Toaster as HotToaster } from 'react-hot-toast';
import { QueryClientProvider } from '@tanstack/react-query';
import { queryClientInstance } from '@/lib/query-client';
import { Navigate, BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { AuthProvider, useAuth } from '@/lib/AuthContext';
import PageNotFound from '@/lib/PageNotFound';
import ErrorBoundary from '@/components/ErrorBoundary';
import ScrollToTop from '@/components/ScrollToTop';
import ProtectedRoute from '@/components/ProtectedRoute';
import EmployerRoute from '@/routes/EmployerRoute';
import RoleHome from '@/routes/RoleHome';
import EmployerLayout from '@/layouts/EmployerLayout';
import Login from '@/pages/Login';
import OwliverHome from '@/pages/OwliverHome';
import Dashboard from '@/pages/hiring/Overview';
import Positions from '@/pages/hiring/Positions';
import CreatePosition from '@/pages/hiring/CreatePosition';
import PositionDetail from '@/pages/hiring/PositionDetail';
import Candidates from '@/pages/hiring/Candidates';
import CandidateProfile from '@/pages/hiring/CandidateProfile';
import HiredHistory from '@/pages/hiring/HiredHistory';
import TalentPool from '@/pages/hiring/TalentPool';
import Analytics from '@/pages/hiring/Analytics';
import Activity from '@/pages/Activity';
import Profile from '@/pages/Profile';
import Settings from '@/pages/Settings';
const AuthenticatedApp = () => {
const { isLoadingAuth, isLoadingPublicSettings } = useAuth();
if (isLoadingPublicSettings || isLoadingAuth) {
return (
<div className="fixed inset-0 flex items-center justify-center">
<div className="h-8 w-8 animate-spin rounded-full border-4 border-slate-200 border-t-slate-800" />
<span className="sr-only">Checking your session</span>
</div>
);
}
return (
<Routes>
{/* Sign-in sits outside the protected boundary, for the obvious reason. */}
<Route path="/login" element={<Login />} />
<Route element={<ProtectedRoute />}>
{/* Everyone who reaches here has a session — `ProtectedRoute` saw to
that — so `/` is a question about who they are, not whether they are
signed in. A role with no console in this build lands back on the
sign-in page, where it says so. */}
<Route path="/" element={<RoleHome />} />
<Route element={<EmployerRoute />}>
<Route element={<EmployerLayout />}>
{/* The Owliver AI home — the post-login landing. A separate page
from the Dashboard, which keeps its own address below. */}
<Route path="/home" element={<OwliverHome />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/positions" element={<Positions />} />
{/* Static before dynamic, so `positions/new` cannot be read as a
position whose id is "new". */}
<Route path="/positions/new" element={<CreatePosition />} />
<Route path="/positions/:id" element={<PositionDetail />} />
<Route path="/candidates" element={<Candidates />} />
{/* The full candidate record is a page rather than a drawer: it
carries around forty fields and fifteen screening dimensions,
which a 480px column cannot show without hiding most of it. */}
<Route path="/candidates/:id" element={<CandidateProfile />} />
<Route path="/hired" element={<HiredHistory />} />
<Route path="/talent-pool" element={<TalentPool />} />
<Route path="/analytics" element={<Analytics />} />
<Route path="/activity" element={<Activity />} />
<Route path="/profile" element={<Profile />} />
<Route path="/settings" element={<Settings />} />
</Route>
</Route>
{/* The addresses this console was lifted from. Bookmarks and links
written against the two-console build still resolve. */}
<Route path="/admin" element={<Navigate to="/dashboard" replace />} />
<Route path="/employer" element={<Navigate to="/dashboard" replace />} />
<Route path="/overview" element={<Navigate to="/dashboard" replace />} />
</Route>
<Route path="*" element={<PageNotFound />} />
</Routes>
);
};
export default function App() {
return (
<ErrorBoundary>
<AuthProvider>
<QueryClientProvider client={queryClientInstance}>
<Router>
<ScrollToTop />
<AuthenticatedApp />
</Router>
<Toaster />
{/* The design system's `toast` helper wraps react-hot-toast, which
needs its own renderer mounted. Without this every toast in the
app fires into nothing. */}
<HotToaster position="bottom-right" />
</QueryClientProvider>
</AuthProvider>
</ErrorBoundary>
);
}