From 0ff69106c091e34dcdd18727284723bc25f3fac2 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Sun, 2 Mar 2025 05:22:41 +0000 Subject: [PATCH] ok try fix serving --- README.md | 5 +++- package.json | 3 --- packages/appview/src/index.ts | 25 ++++++++++--------- packages/appview/src/routes.ts | 9 +++++++ packages/client/src/components/StatusForm.tsx | 8 +++--- packages/client/src/components/StatusList.tsx | 8 ++++-- packages/client/src/hooks/useAuth.tsx | 6 ++--- packages/client/src/pages/HomePage.tsx | 8 ++++-- packages/client/src/services/api.ts | 20 ++++++--------- 9 files changed, 53 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 12cad0a..d180264 100644 --- a/README.md +++ b/README.md @@ -63,11 +63,13 @@ pnpm format # Format all code For production deployment: 1. Build all packages in the correct order: + ```bash pnpm build ``` - + This will: + - Build the lexicon package first (shared type definitions) - Build the frontend (`packages/client`) next - Finally build the backend (`packages/appview`) @@ -78,6 +80,7 @@ For production deployment: ``` The backend server will: + - Serve the API at `/api/*` endpoints - Serve the frontend static files from the client's build directory - Handle client-side routing by serving index.html for all non-API routes diff --git a/package.json b/package.json index 794762b..98f8d2e 100644 --- a/package.json +++ b/package.json @@ -11,17 +11,14 @@ "dev:client": "pnpm --filter @statusphere/client dev", "dev:oauth": "node scripts/setup-ngrok.js", "lexgen": "pnpm --filter @statusphere/lexicon build", - "build": "pnpm build:lexicon && pnpm build:client && pnpm build:appview", "build:lexicon": "pnpm --filter @statusphere/lexicon build", "build:appview": "pnpm --filter @statusphere/appview build", "build:client": "pnpm --filter @statusphere/client build", - "start": "pnpm --filter @statusphere/appview start", "start:dev": "pnpm -r start", "start:appview": "pnpm --filter @statusphere/appview start", "start:client": "pnpm --filter @statusphere/client start", - "clean": "pnpm -r clean", "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"", "typecheck": "pnpm -r typecheck" diff --git a/packages/appview/src/index.ts b/packages/appview/src/index.ts index 334b536..03cc0ea 100644 --- a/packages/appview/src/index.ts +++ b/packages/appview/src/index.ts @@ -1,4 +1,5 @@ import events from 'node:events' +import fs from 'node:fs' import type http from 'node:http' import path from 'node:path' import type { OAuthClient } from '@atproto/oauth-client-node' @@ -18,7 +19,6 @@ import { import { createIngester } from '#/ingester' import { env } from '#/lib/env' import { createRouter } from '#/routes' -import fs from 'node:fs' // Application state passed to the router and elsewhere export type AppContext = { @@ -121,28 +121,29 @@ export class Server { const router = createRouter(ctx) app.use(express.json()) app.use(express.urlencoded({ extended: true })) - - // API routes + + // Two versions of the API routes: + // 1. Mounted at /api for the client app.use('/api', router) - + // Serve static files from the frontend build const frontendPath = path.resolve(__dirname, '../../../client/dist') - + // Check if the frontend build exists if (fs.existsSync(frontendPath)) { logger.info(`Serving frontend static files from: ${frontendPath}`) - + // Serve static files app.use(express.static(frontendPath)) - + // For any other requests, send the index.html file app.get('*', (req, res) => { - // Skip API routes - if (req.path.startsWith('/api/')) { - return res.sendStatus(404) + // Only handle non-API paths + if (!req.path.startsWith('/api/')) { + res.sendFile(path.join(frontendPath, 'index.html')) + } else { + res.status(404).json({ error: 'API endpoint not found' }) } - - res.sendFile(path.join(frontendPath, 'index.html')) }) } else { logger.warn(`Frontend build not found at: ${frontendPath}`) diff --git a/packages/appview/src/routes.ts b/packages/appview/src/routes.ts index cc1b27b..a78f4ec 100644 --- a/packages/appview/src/routes.ts +++ b/packages/appview/src/routes.ts @@ -117,6 +117,15 @@ export const createRouter = (ctx: AppContext) => { clientSession.did = session.did await clientSession.save() + // Get the origin and determine appropriate redirect + const host = req.get('host') || '' + const protocol = req.protocol || 'http' + const baseUrl = `${protocol}://${host}` + + ctx.logger.info( + `OAuth callback successful, redirecting to ${baseUrl}/oauth-callback`, + ) + // Redirect to the frontend oauth-callback page res.redirect('/oauth-callback') } catch (err) { diff --git a/packages/client/src/components/StatusForm.tsx b/packages/client/src/components/StatusForm.tsx index 1dd1311..32147bb 100644 --- a/packages/client/src/components/StatusForm.tsx +++ b/packages/client/src/components/StatusForm.tsx @@ -160,9 +160,11 @@ const StatusForm = () => { transition-all duration-200 ${isSelected ? 'opacity-60' : 'opacity-100'} ${!isSelected ? 'hover:bg-gray-100 dark:hover:bg-gray-700 hover:scale-110' : ''} - ${isCurrentStatus - ? 'bg-blue-50 ring-1 ring-blue-200 dark:bg-blue-900 dark:bg-opacity-30 dark:ring-blue-700' - : ''} + ${ + isCurrentStatus + ? 'bg-blue-50 ring-1 ring-blue-200 dark:bg-blue-900 dark:bg-opacity-30 dark:ring-blue-700' + : '' + } active:scale-95 focus:outline-none focus:ring-2 focus:ring-blue-300 dark:focus:ring-blue-500 `} diff --git a/packages/client/src/components/StatusList.tsx b/packages/client/src/components/StatusList.tsx index 10a480f..3551d08 100644 --- a/packages/client/src/components/StatusList.tsx +++ b/packages/client/src/components/StatusList.tsx @@ -18,7 +18,9 @@ const StatusList = () => { if (isLoading && !data) { return ( -
Loading statuses...
+
+ Loading statuses... +
) } @@ -32,7 +34,9 @@ const StatusList = () => { if (statuses.length === 0) { return ( -
No statuses yet.
+
+ No statuses yet. +
) } diff --git a/packages/client/src/hooks/useAuth.tsx b/packages/client/src/hooks/useAuth.tsx index 927689a..c113525 100644 --- a/packages/client/src/hooks/useAuth.tsx +++ b/packages/client/src/hooks/useAuth.tsx @@ -77,13 +77,13 @@ export function AuthProvider({ children }: { children: ReactNode }) { try { // Add a small artificial delay for UX purposes const loginPromise = api.login(handle) - + // Ensure the loading state shows for at least 800ms for better UX const result = await Promise.all([ loginPromise, - new Promise(resolve => setTimeout(resolve, 800)) + new Promise((resolve) => setTimeout(resolve, 800)), ]).then(([loginResult]) => loginResult) - + return result } catch (err) { const message = err instanceof Error ? err.message : 'Login failed' diff --git a/packages/client/src/pages/HomePage.tsx b/packages/client/src/pages/HomePage.tsx index 94e0cb2..52be5a6 100644 --- a/packages/client/src/pages/HomePage.tsx +++ b/packages/client/src/pages/HomePage.tsx @@ -13,7 +13,9 @@ const HomePage = () => {

Loading Statusphere...

-

Setting up your experience

+

+ Setting up your experience +

) @@ -23,7 +25,9 @@ const HomePage = () => { return (
-

Error

+

+ Error +

{error}