the statusphere demo reworked into a vite/react app in a monorepo

tidy, css reset, add simple readme

+58 -4
+2 -2
.env.template
··· 2 2 NODE_ENV="development" # Options: 'development', 'production' 3 3 PORT="8080" # The port your server will listen on 4 4 HOST="localhost" # Hostname for the server 5 - PUBLIC_URL="" 5 + PUBLIC_URL="" # Set when deployed publicly, e.g. "https://mysite.com". Informs OAuth client id. 6 6 7 7 # CORS Settings 8 8 CORS_ORIGIN="http://localhost:*" # Allowed CORS origin, adjust as necessary ··· 12 12 COMMON_RATE_LIMIT_MAX_REQUESTS="20" # Max number of requests per window per IP 13 13 14 14 # Secrets 15 - # Must this in production. May be generated with `openssl rand -base64 33` 15 + # Must set this in production. May be generated with `openssl rand -base64 33` 16 16 # COOKIE_SECRET=""
+15
README.md
··· 1 + # AT Protocol Express App 2 + 3 + A demo application covering: 4 + - public firehose ingestion 5 + - identity and login with OAuth 6 + - writing to the network 7 + 8 + ## Getting Started 9 + ### Development 10 + ```sh 11 + pnpm i 12 + cp .env.template .env 13 + pnpm run dev 14 + # Navigate to http://localhost:8080 15 + ```
+1 -1
src/pages/home.ts
··· 13 13 } 14 14 15 15 function content({ posts, profile }: Props) { 16 - return html`<div> 16 + return html`<div id="root"> 17 17 <h1>Welcome to the Atmosphere</h1> 18 18 ${ 19 19 profile
+1 -1
src/pages/login.ts
··· 11 11 } 12 12 13 13 function content({ error }: Props) { 14 - return html`<div> 14 + return html`<div id="root"> 15 15 <form action="/login" method="post"> 16 16 <input type="text" name="handle" placeholder="handle" required /> 17 17 <button type="submit">Log in.</button>
+1
src/pages/shell.ts
··· 4 4 return html`<html> 5 5 <head> 6 6 <title>${title}</title> 7 + <link rel="stylesheet" href="/public/styles.css"> 7 8 </head> 8 9 <body> 9 10 ${content}
+35
src/public/styles.css
··· 1 + body { 2 + font-family: Arial, Helvetica, sans-serif; 3 + } 4 + 5 + #root { 6 + padding: 20px; 7 + } 8 + 9 + /* 10 + Josh's Custom CSS Reset 11 + https://www.joshwcomeau.com/css/custom-css-reset/ 12 + */ 13 + *, *::before, *::after { 14 + box-sizing: border-box; 15 + } 16 + * { 17 + margin: 0; 18 + } 19 + body { 20 + line-height: 1.5; 21 + -webkit-font-smoothing: antialiased; 22 + } 23 + img, picture, video, canvas, svg { 24 + display: block; 25 + max-width: 100%; 26 + } 27 + input, button, textarea, select { 28 + font: inherit; 29 + } 30 + p, h1, h2, h3, h4, h5, h6 { 31 + overflow-wrap: break-word; 32 + } 33 + #root, #__next { 34 + isolation: isolate; 35 + }
+3
src/routes/index.ts
··· 1 + import path from 'node:path' 1 2 import { OAuthResolverError } from '@atproto/oauth-client-node' 2 3 import { isValidHandle } from '@atproto/syntax' 3 4 import express from 'express' ··· 10 11 11 12 export const createRouter = (ctx: AppContext) => { 12 13 const router = express.Router() 14 + 15 + router.use('/public', express.static(path.join(__dirname, '..', 'public'))) 13 16 14 17 router.get( 15 18 '/client-metadata.json',