{"id":24905701,"url":"https://github.com/andyrei/impro-generator","last_synced_at":"2026-04-19T19:32:05.151Z","repository":{"id":275344775,"uuid":"925807811","full_name":"Andyrei/impro-generator","owner":"Andyrei","description":"Impro suggestions generator for some fun ","archived":false,"fork":false,"pushed_at":"2025-03-16T20:01:07.000Z","size":798,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-16T21:24:11.901Z","etag":null,"topics":["first-timers-friendly","impro","improvisation-tools","newbie-code","newbie-friendly","nextjs","typescript"],"latest_commit_sha":null,"homepage":"https://impro-generator.vercel.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Andyrei.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-01T19:47:51.000Z","updated_at":"2025-03-16T20:01:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"989e48be-ba1e-48ac-b1fb-2dc2ce496b46","html_url":"https://github.com/Andyrei/impro-generator","commit_stats":null,"previous_names":["andyrei/impro-generator"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Andyrei%2Fimpro-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Andyrei%2Fimpro-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Andyrei%2Fimpro-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Andyrei%2Fimpro-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Andyrei","download_url":"https://codeload.github.com/Andyrei/impro-generator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245931756,"owners_count":20695958,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["first-timers-friendly","impro","improvisation-tools","newbie-code","newbie-friendly","nextjs","typescript"],"created_at":"2025-02-02T00:24:12.525Z","updated_at":"2026-04-19T19:32:05.144Z","avatar_url":"https://github.com/Andyrei.png","language":"TypeScript","readme":"# 🎭 IMPRO GENERATOR\n\n\u003e A mobile-first random prompt generator for improvisation theater.\nThis project was created for fun, with the idea of having a tool for improv shows or lessons. This web app (and potentially a future mobile app) aims to be creative and enjoyable. It is a friendly repository for anyone who wants to contribute and have fun.\n\n[![Deployed on Vercel](https://img.shields.io/badge/deployed-vercel-black?logo=vercel)](https://impro-generator.vercel.app)\n[![Next.js](https://img.shields.io/badge/Next.js-16-black?logo=next.js)](https://nextjs.org)\n[![License](https://img.shields.io/badge/license-private-lightgrey)](#)\n\nPick a **category** and a **difficulty level** — get a random word to build your improv scene around. Tracks already-drawn words so you never repeat until the pool is exhausted. Designed to be used live on stage from a phone or tablet.\n\n---\n\n## ✨ Features\n\n- 🎲 **Random word draw** per category and difficulty (Easy / Medium / Hard)\n- 🔁 **Anti-repeat sampling** — drawn words are excluded until the pool resets\n- ⏱ **Configurable stopwatch** with WakeLock (screen stays on while timing)\n- 🌍 **Multi-language** — English, Italian, Romanian (UI + words)\n- 📱 **Mobile-first** with haptic feedback\n- 🌙 **Dark / Light / System** theme\n- 🔁 **Not repeating words** the routes have a call specific logic to not repeat the calls on words\n- 📟 Retro Nokia/CRT visual aesthetic\n- 🗃 Long-press any category button to browse the full word list\n\n---\n\n## 🛠 Tech Stack\n\n| Layer      | Technology                                                                |\n| ---------- | ------------------------------------------------------------------------- |\n| Framework  | [Next.js](https://nextjs.org) 16 (App Router)                                |\n| UI         | React 19 +[shadcn/ui](https://ui.shadcn.com) + [Radix UI](https://radix-ui.com) |\n| Styling    | Tailwind CSS 3                                                            |\n| Database   | MongoDB via[Mongoose](https://mongoosejs.com)                                |\n| Table      | [@tanstack/react-table](https://tanstack.com/table) v8                       |\n| Carousel   | [Embla Carousel](https://www.embla-carousel.com)                             |\n| Toasts     | [Sonner](https://sonner.emilkowal.ski)                                       |\n| Haptics    | [Tactus](https://github.com/nicktindall/tactus)                              |\n| Analytics  | [Vercel Analytics](https://vercel.com/analytics)                             |\n| Deployment | [Vercel](https://vercel.com)                                                 |\n\n---\n\n## 🚀 Getting Started\n\n### Prerequisites\n\n- Node.js ≥ 18\n- A MongoDB instance (local or [MongoDB Atlas](https://www.mongodb.com/atlas))\n\n### Installation\n\n```bash\ngit clone https://github.com/Andyrei/impro-generator.git\ncd impro-generator\nnpm install\n```\n\n### Environment Variables\n\nCreate a `.env.local` file in the project root:\n\n```env\nMONGODB_URI=mongodb+srv://\u003cuser\u003e:\u003cpassword\u003e@\u003ccluster\u003e.mongodb.net/\u003cdbname\u003e?retryWrites=true\u0026w=majority\n```\n\n### Database Seeding\n\n```bash\n# Seed default structured data (categories, languages, words)\nnpm run seed\n\n# Seed additional words from CSV files in /assets/wordlist/\nnpm run seed:csv\n```\n\n### Run Locally\n\n```bash\nnpm run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000) — you will be redirected to `/en` (or your browser's preferred language).\n\n---\n\n## 📁 Project Structure\n\n```\nsrc/\n├── app/\n│   ├── [lang]/                  # All routes are locale-prefixed (/en, /it, /ro)\n│   │   ├── page.tsx             # Home — server component, fetches categories\n│   │   ├── layout.tsx           # Root layout with theme + locale providers\n│   │   ├── globals.css          # Global styles + CRT/Nokia effects\n│   │   ├── getDictionary.ts     # Loads the locale JSON dictionary\n│   │   ├── dictionaries/        # en.json, it.json, ro.json\n│   │   └── (pages)/\n│   │       └── settings/        # Language, theme, stopwatch settings\n│   └── api/\n│       ├── v0/action/           # Legacy CSV-based API (deprecated)\n│       └── v1/\n│           ├── categories/      # GET all categories with word counts\n│           ├── languages/       # GET all supported languages\n│           └── words/           # GET words with filtering and random sampling\n├── components/\n│   ├── custom-ui/               # App-specific components\n│   │   ├── ClientAction.tsx     # Root game state manager\n│   │   ├── ActionButton.tsx     # Category button (tap = draw, long-press = browse)\n│   │   ├── Screen.tsx           # CRT display area\n│   │   ├── LevelChecker.tsx     # Difficulty selector\n│   │   ├── StopWatch.tsx        # Scene timer with WakeLock\n│   │   ├── Navbar.tsx           # Bottom navigation\n│   │   └── ToggleAction.tsx     # Simple action button variant\n│   └── ui/                      # shadcn/ui components\n├── context/\n│   ├── LocaleContext.tsx        # Locale state + cookie persistence\n│   └── ThemeContext.tsx         # Theme state + localStorage persistence\n├── hooks/\n│   └── useLongPress.ts          # Distinguishes tap vs. 600ms long-press\n└── lib/\n    ├── general.ts               # Shared utilities\n    └── db/\n        ├── mongodb.ts           # Mongoose connection singleton\n        ├── models/              # Category, Language, Word schemas\n        ├── queries/             # getCategories (with ISR cache)\n        ├── seed/                # seed.ts, seedFromCsv.ts\n        └── types/               # TypeScript types mirroring DB models\n```\n\n---\n\n## 🔌 API Reference\n\n### `GET /api/v1/categories`\n\nReturns all categories with a pre-computed `wordCount`.\n\n```json\n[\n  { \"_id\": \"...\", \"name\": { \"en\": \"Place\", \"it\": \"Luogo\" }, \"wordCount\": 42 }\n]\n```\n\n### `GET /api/v1/words`\n\n| Parameter   | Type                    | Description                                       |\n| ----------- | ----------------------- | ------------------------------------------------- |\n| `action`  | string                  | Category ObjectId to filter by                    |\n| `level`   | `1` \\| `2` \\| `3` | Difficulty (1 = Easy, 2 = Medium, 3 = Hard)       |\n| `limit`   | number                  | Max results (1–200, default 1)                   |\n| `sample`  | `1`                   | Use MongoDB `$sample` for a random draw         |\n| `exclude` | string                  | Comma-separated Word IDs to exclude from sampling |\n\n### `GET /api/v1/languages`\n\nReturns all supported language documents.\n\n---\n\n## 🌍 Internationalization\n\nRoutes are prefixed by locale: `/en/`, `/it/`, `/ro/`.\n\n- Active locale is stored in a **cookie** (`locale=`)\n- UI strings live in `src/app/[lang]/dictionaries/{lang}.json`\n- Words in the database are stored **multilingually** as a `Map\u003clangCode, string\u003e` — the display layer reads `word[locale] ?? word.en`\n- Language negotiation on first visit uses `@formatjs/intl-localematcher` + `negotiator`\n\nTo add a new language:\n\n1. Add a `{lang}.json` dictionary file in `src/app/[lang]/dictionaries/`\n2. Register the locale in `src/app/[lang]/layout.tsx` static params\n3. Seed the language record and translated words via `npm run seed`\n\n---\n\n## 🚢 Deployment\n\nDeployed on [Vercel](https://vercel.com). Required environment variable in Vercel project settings:\n\n```\nMONGODB_URI=\u003cyour MongoDB connection string\u003e\n```\n\nThe home page uses ISR with a 1-hour revalidation window (`revalidate = 3600`). Categories can be revalidated on-demand using the `'categories'` cache tag.\n\n---\n\n## 🗺 Roadmap\n\n- [ ] Complete FAB button actions\n- [ ] Scene Card Mode — generate a full scene prompt in one tap Character + Location + Situation + Relation all at once, shown as a card\n- [ ] PWA / offline support with pre-cached word lists - This is used live on stage where Wi-Fi can be spotty. A service worker with pre-cached word lists would be a huge reliability win.\n- [ ] Native Share API - integration Share the current prompt via iOS/Android Share Sheet or copy to clipboard\n- [ ] Favorites / History - Star words you liked; see last N drawn words per session\n- [ ] Word suggestions from users\n- [ ] Admin editor for categories and words - A protected `/admin` page to add, edit, delete words and categories without touching MongoDB directly\n- [ ] Sound Effects - Optional button click / word-reveal sounds themed to the retro aesthetic\n- [ ] Multiplayer / Room Mode - Host generates a prompt and all players on the same \"room\" see it simultaneously (WebSocket or polling)\n- [ ] QR Code Share - Generate a QR code for a specific prompt to display on a projector/screen\n- [ ] Animated Word Reveal - Glitch/typewriter animation when a new word appears, matching the CRT aesthetic\n\n---\n\n## 🤝 Contributing\n\nContributions are very welcome! Here are some ways you can help:\n\n1. **Report Bugs** — Open an issue describing what went wrong.\n2. **Suggest Features** — Open an issue with your idea.\n3. **Submit Pull Requests** — Fork the repo, make your changes, and open a PR.\n\nTo better understand the project vision, import [PROJECT_IDEA.excalidraw](./PROJECT_IDEA.excalidraw) into [Excalidraw](https://excalidraw.com/).\n\n---\n\n## 👤 Author\n\n**Andy Andrei** — [radoacaandrei3@gmail.com](mailto:radoacaandrei3@gmail.com)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandyrei%2Fimpro-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandyrei%2Fimpro-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandyrei%2Fimpro-generator/lists"}