Polyscope Frontend is the React/Vite client for the Polyscope prediction analytics platform. It connects to the backend API in real time and provides market browsing, prediction review, performance tracking, notifications, and a protected admin dashboard.
This project is intentionally thin on mock logic and heavy on real API integration. The app is structured around the backend API, with page-level routing handled on the client and data fetched only when the user opens a page.
The frontend supports:
- Markets browsing and search
- Approved prediction viewing and voting feedback
- Performance reporting for win rate and resolution trends
- Email and push notification subscriptions
- Protected admin access for moderation and operational controls
- React 18
- Vite 5
- Plain CSS with CSS variables
- Browser service worker for push notifications
- Browse live Polymarket markets from the backend
- Search markets by title or keyword
- View trending markets
- Open a market and jump into related prediction content
- Graceful empty and error states
- View approved predictions from the API
- Filter by timeframe where supported
- Read prediction reasoning and confidence details clearly
- Vote on predictions as UI feedback
- Jump directly from a market to related predictions
- View summary statistics for predictions
- Track win rate over a selectable window
- See correct, incorrect, and pending prediction groups
- Review historical performance trends from backend data
- Subscribe to push notifications
- Subscribe to email notifications
- Handle email verification flow
- Use the backend VAPID key for browser push setup
- Protected admin access via
/adminor/#/admin - Admin login requires only backend admin keys, not email
- Pending predictions moderation
- Approved prediction edits
- Dashboard stats and system status
- Operations tab for cache, cron, and diagnostics actions
Admin content is not exposed in the normal navigation. The admin screen only appears when the user navigates directly to:
/admin/#/admin
From there, the admin user must log in with:
x-admin-keyX-API-Key
No email field is requested in the frontend admin login.
The frontend also clears admin access if the backend returns unauthorized responses for protected admin requests.
src/
├── api/
│ └── client.js
├── components/
│ ├── ErrorBoundary.jsx
│ ├── Toast.jsx
│ └── layout/
│ ├── Header.jsx
│ └── Navigation.jsx
├── pages/
│ ├── AdminPage.jsx
│ ├── EmailVerificationPage.jsx
│ ├── MarketsPage.jsx
│ ├── NotificationPage.jsx
│ ├── PerformancePage.jsx
│ └── PredictionsPage.jsx
├── App.jsx
├── main.jsx
└── index.css
- Node.js 18 or newer
- A running backend API for Polyscope
- A valid backend URL configured in the frontend environment
Create a local environment file from the example template:
cp .env.example .env.localCurrent frontend environment variables:
VITE_API_URL=https://polyscope.onrender.comFor local development, point VITE_API_URL to your local backend, for example:
VITE_API_URL=http://localhost:5000- Install dependencies:
npm install- Configure the environment:
cp .env.example .env.local- Start the frontend:
npm run devThe app runs on:
http://localhost:5173
Build the app for production:
npm run buildPreview the production build locally:
npm run previewnpm run dev- Start the Vite development servernpm run build- Create a production build indist/npm run preview- Preview the production build locally
All data comes from the backend API configured by VITE_API_URL.
GET /api/markets
GET /api/markets/:id
GET /api/markets/search?q=...
GET /api/markets/trendingGET /api/predictions
GET /api/predictions/:id
GET /api/predictions/performance
POST /api/predictions/:id/voteGET /api/notifications/push/vapid-public-key
POST /api/notifications/push/subscribe
POST /api/notifications/push/unsubscribe
POST /api/notifications/email/subscribe
GET /api/notifications/email/verify
POST /api/notifications/email/unsubscribeAdmin endpoints are called with the backend admin headers:
x-admin-keyX-API-Key
Admin API usage in the frontend includes:
GET /api/admin/predictions/status/:status
GET /api/admin/predictions?status=...
POST /api/admin/predictions/:id/approve
POST /api/admin/predictions/:id/reject
PATCH /api/admin/predictions/:id/approved/probability
DELETE /api/admin/predictions/:id/pending
DELETE /api/admin/predictions/:id/approved
GET /api/admin/debug
GET /api/admin/stats/predictions
GET /api/admin/stats/notifications
POST /api/admin/cleanup/subscriptions
POST /api/admin/cache/clear
POST /api/admin/cron/run
GET /api/admin/health/external-sources
GET /api/admin/metrics/external-data
GET /api/admin/external-data/:marketId- The header and navigation are responsive.
- On mobile, navigation collapses into a hamburger menu with animated transitions.
- Admin-only UI is hidden from normal navigation.
- Error states are presented with friendly messages and retry actions.
- Backend error details are not surfaced directly to end users.
This frontend can be deployed to Vercel or any static host.
- Push the frontend to GitHub.
- Import the repository into Vercel.
- Set the build command to:
npm run build- Set the output directory to:
dist
- Add the production environment variable:
VITE_API_URL=https://your-backend-domain- Deploy.
Make sure the backend allows requests from the deployed frontend domain through CORS, and make sure the production backend URL is set before building.
- Do not hardcode secret admin keys into the frontend source.
- The frontend only sends the admin keys entered by the authenticated operator.
- Admin access should be restricted on the backend as the real source of truth.
- If an admin token becomes invalid, the frontend clears the session and returns to login.
- Check that the backend is running.
- Verify
VITE_API_URLpoints to the correct backend. - Confirm the backend accepts both
x-admin-keyandX-API-Keyheaders. - Make sure the admin keys are correct in the backend environment.
- Confirm the backend API is reachable from the browser.
- Check browser console and network errors.
- Confirm CORS is configured on the backend.
- Check that the frontend is deployed with the correct
VITE_API_URL. - Open the browser dev tools and inspect failed network requests.
MIT