Easy-to-manage touch screens
무료 오픈소스 터치스크린으로 USB 설정 가이드, 드래그‑드롭 편집기, 로컬 제어를 제공하며 Home Assistant용으로 제작되었습니다
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Temperature history chart
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A web application that shows how today's temperature (or this week's, month's, or year's) compares to the same period across the past 50 years, for any supported location.
/feed and accessible via the Snapshots link in the sidebar; filterable by period (daily/weekly/monthly/yearly)Clone the repository:
git clone [repository-url]
cd TempHist
Install dependencies:
npm install
Create a .env file:
VITE_API_BASE=/api
VITE_TEST_TOKEN=your_test_token_here
API_BASE=http://localhost:8000
API_BASE is the address of the TempHist API. With http://localhost:8000 you'll need the API running locally — follow its setup instructions. Alternatively, point it at the dev or staging API to avoid running the API locally:
API_BASE=https://devapi.temphist.com
Start the local dev server (in separate terminals):
npm run dev # Vite dev server — hot reload, no OG injection
The app is available at http://localhost:5173.
There are two ways to run the frontend locally, depending on what you're testing:
| Mode | Command | Port | Hot reload | API proxy | OG tag injection |
|---|---|---|---|---|---|
| Dev (daily use) | npm run dev | 5173 | ✅ | via Vite | ❌ |
| Prod-like (OG testing) | npm run start:local | 3000 | ❌ | ✅ | ✅ |
npm run dev — use this for everyday development, like if you're updating the styles or content. Vite serves source files directly and watches for changes: edits to .scss styles, TypeScript, or HTML are reflected in the browser instantly without a build step or page reload. API calls are proxied to http://localhost:8000 automatically.
npm run start:local — use this when testing social sharing or OG image previews (e.g. Share to Notes in Safari). It serves the built dist/ files, proxies /api to localhost:8000, and injects og:image / og:title tags server-side for /s/:id share URLs.
Note:
npm run start:localserves the last build. Runnpm run buildfirst if you've changed source files since the last build.
Note:
npm startrunsserver.js, the production server. It has no API proxy and is not suitable for local development.
To test OG sharing locally:
npm run build # build latest source into dist/
npm run start:local # serve on localhost:3000 with OG injection
# then visit http://localhost:3000/s/<share-id> in Safari and share
| Variable | Required | Description |
|---|---|---|
VITE_API_BASE | Yes | API base URL. Dev: /api (relative — proxied by Vite or server-local.js). Prod: https://api.temphist.com |
VITE_ENABLE_SNAPSHOTS | No | Set to false to disable the Snapshots feed and splash-screen carousel entirely. Defaults to true. When false the nav link is hidden at build time and all related JS is tree-shaken from the production bundle. |
VITE_TEST_TOKEN | Dev only | Test token injected by server-local.js when Firebase auth is unavailable |
VITE_APPCHECK_DEBUG_TOKEN | Dev only | Firebase App Check debug token UUID. Register it once in Firebase Console → App Check → Manage debug tokens. Omit to let Firebase generate a new one (you'll be prompted to register it on first run). |
PORT | No | Server port (default: 3000). Set automatically by Railway in production |
API_BASE | Dev only | TempHist API URL used by server-local.js. Set to http://localhost:8000 to run the API locally, or point at https://devapi.temphist.com / https://stagingapi.temphist.com to skip running it locally. |
npm run type-check # TypeScript check
npm run build # Outputs to dist/
Deploy the dist/ directory to your web root.
Pushes to main → production auto-deploy via GitHub webhook.
Pushes to develop → dev/staging auto-deploy.
For manual deployment:
git checkout main && git pull
npm install && npm run build
# copy dist/ to web root
For Apache hosts (e.g. SiteGround), add a .htaccess to serve clean URLs:
RewriteEngine On
# Remove .html extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
# Redirect .html URLs to clean versions
RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ /%1 [NC,L,R=301]
VITE_RECAPTCHA_SITE_KEY in .envsrc/firebase.tsIn dev mode, the app sets FIREBASE_APPCHECK_DEBUG_TOKEN so Firebase generates a debug token instead of requiring reCAPTCHA. On first run you'll see this in the browser console:
App Check debug token: <uuid>. You will need to add it to your app's App Check settings in the Firebase console for it to work.
Register that UUID in Firebase Console → App Check → Apps → [your web app] → Manage debug tokens, then add it to .env:
VITE_APPCHECK_DEBUG_TOKEN=<your-debug-token-uuid>
Without this, anonymous sign-in can fail or hang. After 12 s the app shows a "couldn't connect" / "privacy settings" message with a Retry button (on the home page and on share pages) rather than loading forever.
/analytics endpoint as recent_errors entries with error_type auth_signin or app_check_token, the Firebase error code in message, and endpoint share or spa. See src/auth/signIn.ts and recordAuthFailure in src/analytics/analytics.ts.npm test # run all tests
npm run test:coverage # with coverage report
npm run test:watch # watch mode
npm run test:ui # browser UI
src/
main.ts # App entry point, router, auth, location init
share.ts # Share page logic (fetch metadata, render chart)
chart/
chart.ts # Chart creation, bar colours, tooltip handler
views/
today.ts # Today view — fetch, render, location display
period.ts # Week/Month/Year views (shared renderer)
about.ts # About page content builder
feed.ts # Snapshots feed page — card builder, pagination, filter bar
utils/
uiHelpers.ts # Shared DOM helpers: location display, stats rendering
location.ts # Country code → flag, location slug lookup
types/
index.ts # TypeScript type definitions
services/ # Location detection, carousel, API interactions
api/ # API client functions
templates/
header.html # Site header partial (included at build time)
nav.html # Sidebar nav partial (Snapshots link hidden when VITE_ENABLE_SNAPSHOTS=false)
styles.scss # Global styles
index.html # Main SPA shell
about.html # Standalone about page
privacy.html # Standalone privacy page
feed.html # Standalone Snapshots feed page
server.js # Production proxy + OG tag injection
server-local.js # Local dev proxy with test token injection
Session analytics are submitted to POST /v1/analytics in two situations:
beforeunload) — when the tab closes or navigates awayEach submission includes session-level counters (api_calls, api_failure_rate, retry_attempts, location_failures, error_count) plus richer fields captured from the initial daily load:
| Field | Source |
|---|---|
response_time_ms | Wall-clock time for the daily temperature fetch (async job creation → result) |
cache_hit | X-Cache: HIT/MISS header on the job result response (null if header absent) |
canonical_location | Location string returned by the API (may differ from what was requested) |
requested_location | window.tempLocation at the time of the fetch |
selection_method | How the location was chosen: own_location (browser geolocation), carousel (manual pick), popular (app default) |
user_agent | navigator.userAgent |
Current limitation — period views not instrumented. When the user navigates to Past week / Past month / Past year, those fetches increment the api_calls counter (so failures are captured) but their individual response times and cache hit status are not recorded. If period view latency becomes a concern, extend period.ts to populate window.TempHist.analytics.lastRequestMetadata after each fetch (mirroring the pattern in src/views/today/fetchHistoricalData.ts) and call sendAnalytics() after each load.
MIT License — Copyright (c) 2025 Turnpiece