尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
A single-file web app for planning family trips: day-by-day itinerary with
reservations (flights, hotels, attractions, transport), an interactive map of
each day's stops, budget tracking, and optional shared storage via Supabase.
Open index.html in a browser — no build step. Data is saved in
localStorage. (For the map/geocoding features a local server is nicer:
npx http-server and open http://localhost:8080.)查看完整 README ↗A single-file web app for planning family trips: day-by-day itinerary with reservations (flights, hotels, attractions, transport), an interactive map of each day's stops, budget tracking, and optional shared storage via Supabase.
Open index.html in a browser — no build step. Data is saved in
localStorage. (For the map/geocoding features a local server is nicer:
npx http-server and open http://localhost:8080.)
lat, lng, decimal or DMS, works too). A share-sheet
paste that includes a place name plus the link is fine. Short
maps.app.goo.gl links are expanded by the app's own /api/expand (the one
serverless function, api/expand.js; also served by tools/serve.js locally) —
if that is unreachable the sheet asks you to paste the full URL. Every stop has an
"open in Google Maps" link, which doubles as the fallback when the map
library or coordinates are unavailable. Flights are not pinned on the map.
The stop rows carry the booking's notes and confirmation alongside the address,
and a locate button puts you on the map with an accuracy circle and the walking
distance to your next unvisited stop. It only ever asks for a position when you
press it.?room=…&key=…). Anyone with the link sees and edits the same data,
synced every ~20 s (last write wins).supabase-schema.sql.config.js (see config.example.js for the shape).config.js is committed in this repo on purpose: the hosted app on GitHub
Pages needs it to enable Save/sharing, and the publishable key is safe to
expose in client code. Trip data is protected by the per-trip secret embedded
in each share link. Without config.js the app is fully local — no errors, no
Save button.
Sharing: one person creates the room, everyone else Joins. These are different actions and only the first person does the first one:
The link carries a room id and a secret; the app strips them from its own address
bar once joined, so the secret isn't left on screen or leaked in outbound
Referer headers. Use Copy share link when you need it again. You'll be asked
who you are once per device, so changes are stamped with a name. The room you're in
(Shared · 3644ee) is shown in the app bar on a wide screen and at the top of the ⋯
menu on a phone — two devices showing different codes are in different rooms, which
is the first thing to check if syncing seems broken. The badge turns amber when a
device hasn't synced for a week. Leave shared trip (the exit-arrow button, or the
⋯ menu on a phone) disconnects and keeps your trips on the device.
A device starts empty: there is no sample data, so a second family can install
this and see only their own trips. ⋯ → Start fresh on this device empties a
device again — it takes a backup first and refuses to go ahead if that backup can't
be written, and Restore in the same menu brings it back. One device belongs to
one room at a time; see design/MULTI-ROOM-PLAN.md for what switching between
several would take.
How syncing behaves: your edits upload automatically, and incoming changes apply on their own within about 20 seconds while the tab is open (backgrounded tabs pause polling and catch up when you return). The exception is when you have unsaved edits of your own: then the app waits, shows a dot and a "tap Sync" toast, and merges both sides when you tap it — so two people editing different things at once both keep their work. If you both change the same field, the value that reached the server first wins. Large documents make every sync heavier, so keep attachments small.
The app is static, so there's no build step to speak of. Share links only work for others once the app is hosted somewhere they can reach.
One-time setup:
vercel.json already sets the build command and output
directory — leave the defaults alone.VACATION_SUPABASE_URL — e.g. https://xxxx.supabase.coVACATION_SUPABASE_ANON_KEY — the publishable keyscripts/write-config.js writes config.js from those variables at
build time; if they're missing it silently no-ops and the committed
config.js is used instead..vercelignore keeps the design archive, handoff bundles, and the source CSV
out of the public deployment. vercel.json also sets a Content-Security-Policy
and Referrer-Policy: no-referrer — if you add a new external script, image
host, or API, add it to the CSP or the browser will block it.
To deploy from the terminal instead:
npx vercel --prod