CleanFrame
A personal home screen for Samsung The Frame. A starting point to fork and adapt.
Events, restaurants, parks and hidden gems across all 13 Newton villages — searchable by village, category, date and price.
Translation pending
LifestyleTypeScript · PLpgSQLGitHub @brandonrfung1-collabOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Things to do in Newton, Massachusetts — events, restaurants, parks, seasonal activities and hidden gems across all 13 villages, filterable by village, category, date, price and distance.
Built with Next.js 15 (App Router), TypeScript, Tailwind CSS and Supabase.
npm install
npm run dev
Open http://localhost:3000.
No credentials needed. With no Supabase environment variables set, the app runs in demo mode: it serves the bundled seed dataset (64 activities across all 13 villages, each pictured with a real, verified Wikimedia Commons photo) and every page works. Accounts, favorites, reviews and the moderation queue show a friendly "needs Supabase" notice instead of erroring.
.env.example to .env.local and fill in:NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
NEXT_PUBLIC_SITE_URL=http://localhost:3000
Find all three under Project Settings → API. The service-role key is server
only — never prefix it with NEXT_PUBLIC_.
Paste supabase/migrations/0001_init.sql into the Supabase SQL Editor and
run it. This creates all nine tables, the enums, the triggers that maintain
rating/save counters, the RPC functions, and row-level security policies on
every table.
Or, with the Supabase CLI:
npx supabase link --project-ref <your-ref>
npx supabase db push
npm run seed
This regenerates supabase/seed.sql from src/lib/data/*.ts and — if
SUPABASE_SERVICE_ROLE_KEY is set — pushes 13 villages, 8 categories and 65
activities straight to your database. Re-running is safe; everything upserts on
slug.
Without the service key, paste supabase/seed.sql into the SQL Editor instead.
Email/password works immediately.
Google OAuth:
https://<your-project-ref>.supabase.co/auth/v1/callbackhttp://localhost:3000/auth/callbackhttps://ntactivity.space/auth/callbackSign up through the app, then in the SQL Editor:
update public.profiles
set is_admin = true
where id = (select id from auth.users where email = '[email protected]');
/admin is now available: moderation queue, listing management, and analytics.
Admin status is deliberately not self-assignable. A trigger blocks any change to
profiles.is_adminthat does not come from the service role.
npm i -g vercel
vercel # link the project
vercel --prod
Or push to GitHub and import the repo at https://vercel.com/new. Framework
detection picks up Next.js automatically; no vercel.json is required.
Add these in Vercel → Project → Settings → Environment Variables (Production and Preview):
| Name | Value |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | your Supabase URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | your anon key |
SUPABASE_SERVICE_ROLE_KEY | your service-role key (not public) |
NEXT_PUBLIC_SITE_URL | https://ntactivity.space |
Then pull them locally with:
vercel env pull .env.local
ntactivity.space under Settings → Domains.NEXT_PUBLIC_SITE_URL to the final origin — it drives canonical URLs,
OpenGraph tags, the sitemap and calendar links.https://ntactivity.space/auth/callback to Supabase's allowed redirect
URLs.https://ntactivity.space/sitemap.xml to Google Search Console.Pages
/activities — search with village, category, date-range, free/paid and distance filters/activities/[slug] — photos, embedded map, add-to-calendar (.ics + Google), reviews, related listings/villages and /villages/[slug] — a page per village with local trivia and its own filters/categories and /categories/[slug] — eight browse categories/submit — public submission form feeding the moderation queue/admin — approve/reject submissions, hide/delete listings, view analytics/favorites, /login, /signupFeatures
sitemap.xml, robots.txt, and schema.org
Event / Place JSON-LD for rich resultsAccessibility & performance
aria-* on interactive elementsnext/image optimization with a graceful fallback for dead photo URLs.dark to <html> to enable a toggle)npm run dev # dev server
npm run build # production build
npm run start # serve the production build
npm run typecheck # tsc --noEmit
npm run lint # next lint
npm run seed # regenerate supabase/seed.sql (+ push if service key present)
See CLAUDE.md for architecture, the database schema reference,
the demo-mode contract, design tokens and coding conventions.
Landmarks are real Newton fixtures — Crystal Lake, Echo Bridge, Hemlock Gorge, Cold Spring Park, Nahanton Park, Newton Community Farm, the West Newton Cinema, Nonantum's St. Mary of Carmen Festival. Hours, prices and specific event times are illustrative placeholders for demonstrating the app, not verified listings. Replace them with real submissions before launch.