https://github.com/andyrei/impro-generator
Impro suggestions generator for some fun
https://github.com/andyrei/impro-generator
first-timers-friendly impro improvisation-tools newbie-code newbie-friendly nextjs typescript
Last synced: 7 days ago
JSON representation
Impro suggestions generator for some fun
- Host: GitHub
- URL: https://github.com/andyrei/impro-generator
- Owner: Andyrei
- Created: 2025-02-01T19:47:51.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-16T20:01:07.000Z (about 1 year ago)
- Last Synced: 2025-03-16T21:24:11.901Z (about 1 year ago)
- Topics: first-timers-friendly, impro, improvisation-tools, newbie-code, newbie-friendly, nextjs, typescript
- Language: TypeScript
- Homepage: https://impro-generator.vercel.app/
- Size: 779 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 🎭 IMPRO GENERATOR
> A mobile-first random prompt generator for improvisation theater.
This 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.
[](https://impro-generator.vercel.app)
[](https://nextjs.org)
[](#)
Pick 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.
---
## ✨ Features
- 🎲 **Random word draw** per category and difficulty (Easy / Medium / Hard)
- 🔁 **Anti-repeat sampling** — drawn words are excluded until the pool resets
- ⏱ **Configurable stopwatch** with WakeLock (screen stays on while timing)
- 🌍 **Multi-language** — English, Italian, Romanian (UI + words)
- 📱 **Mobile-first** with haptic feedback
- 🌙 **Dark / Light / System** theme
- 🔁 **Not repeating words** the routes have a call specific logic to not repeat the calls on words
- 📟 Retro Nokia/CRT visual aesthetic
- 🗃 Long-press any category button to browse the full word list
---
## 🛠 Tech Stack
| Layer | Technology |
| ---------- | ------------------------------------------------------------------------- |
| Framework | [Next.js](https://nextjs.org) 16 (App Router) |
| UI | React 19 +[shadcn/ui](https://ui.shadcn.com) + [Radix UI](https://radix-ui.com) |
| Styling | Tailwind CSS 3 |
| Database | MongoDB via[Mongoose](https://mongoosejs.com) |
| Table | [@tanstack/react-table](https://tanstack.com/table) v8 |
| Carousel | [Embla Carousel](https://www.embla-carousel.com) |
| Toasts | [Sonner](https://sonner.emilkowal.ski) |
| Haptics | [Tactus](https://github.com/nicktindall/tactus) |
| Analytics | [Vercel Analytics](https://vercel.com/analytics) |
| Deployment | [Vercel](https://vercel.com) |
---
## 🚀 Getting Started
### Prerequisites
- Node.js ≥ 18
- A MongoDB instance (local or [MongoDB Atlas](https://www.mongodb.com/atlas))
### Installation
```bash
git clone https://github.com/Andyrei/impro-generator.git
cd impro-generator
npm install
```
### Environment Variables
Create a `.env.local` file in the project root:
```env
MONGODB_URI=mongodb+srv://:@.mongodb.net/?retryWrites=true&w=majority
```
### Database Seeding
```bash
# Seed default structured data (categories, languages, words)
npm run seed
# Seed additional words from CSV files in /assets/wordlist/
npm run seed:csv
```
### Run Locally
```bash
npm run dev
```
Open [http://localhost:3000](http://localhost:3000) — you will be redirected to `/en` (or your browser's preferred language).
---
## 📁 Project Structure
```
src/
├── app/
│ ├── [lang]/ # All routes are locale-prefixed (/en, /it, /ro)
│ │ ├── page.tsx # Home — server component, fetches categories
│ │ ├── layout.tsx # Root layout with theme + locale providers
│ │ ├── globals.css # Global styles + CRT/Nokia effects
│ │ ├── getDictionary.ts # Loads the locale JSON dictionary
│ │ ├── dictionaries/ # en.json, it.json, ro.json
│ │ └── (pages)/
│ │ └── settings/ # Language, theme, stopwatch settings
│ └── api/
│ ├── v0/action/ # Legacy CSV-based API (deprecated)
│ └── v1/
│ ├── categories/ # GET all categories with word counts
│ ├── languages/ # GET all supported languages
│ └── words/ # GET words with filtering and random sampling
├── components/
│ ├── custom-ui/ # App-specific components
│ │ ├── ClientAction.tsx # Root game state manager
│ │ ├── ActionButton.tsx # Category button (tap = draw, long-press = browse)
│ │ ├── Screen.tsx # CRT display area
│ │ ├── LevelChecker.tsx # Difficulty selector
│ │ ├── StopWatch.tsx # Scene timer with WakeLock
│ │ ├── Navbar.tsx # Bottom navigation
│ │ └── ToggleAction.tsx # Simple action button variant
│ └── ui/ # shadcn/ui components
├── context/
│ ├── LocaleContext.tsx # Locale state + cookie persistence
│ └── ThemeContext.tsx # Theme state + localStorage persistence
├── hooks/
│ └── useLongPress.ts # Distinguishes tap vs. 600ms long-press
└── lib/
├── general.ts # Shared utilities
└── db/
├── mongodb.ts # Mongoose connection singleton
├── models/ # Category, Language, Word schemas
├── queries/ # getCategories (with ISR cache)
├── seed/ # seed.ts, seedFromCsv.ts
└── types/ # TypeScript types mirroring DB models
```
---
## 🔌 API Reference
### `GET /api/v1/categories`
Returns all categories with a pre-computed `wordCount`.
```json
[
{ "_id": "...", "name": { "en": "Place", "it": "Luogo" }, "wordCount": 42 }
]
```
### `GET /api/v1/words`
| Parameter | Type | Description |
| ----------- | ----------------------- | ------------------------------------------------- |
| `action` | string | Category ObjectId to filter by |
| `level` | `1` \| `2` \| `3` | Difficulty (1 = Easy, 2 = Medium, 3 = Hard) |
| `limit` | number | Max results (1–200, default 1) |
| `sample` | `1` | Use MongoDB `$sample` for a random draw |
| `exclude` | string | Comma-separated Word IDs to exclude from sampling |
### `GET /api/v1/languages`
Returns all supported language documents.
---
## 🌍 Internationalization
Routes are prefixed by locale: `/en/`, `/it/`, `/ro/`.
- Active locale is stored in a **cookie** (`locale=`)
- UI strings live in `src/app/[lang]/dictionaries/{lang}.json`
- Words in the database are stored **multilingually** as a `Map` — the display layer reads `word[locale] ?? word.en`
- Language negotiation on first visit uses `@formatjs/intl-localematcher` + `negotiator`
To add a new language:
1. Add a `{lang}.json` dictionary file in `src/app/[lang]/dictionaries/`
2. Register the locale in `src/app/[lang]/layout.tsx` static params
3. Seed the language record and translated words via `npm run seed`
---
## 🚢 Deployment
Deployed on [Vercel](https://vercel.com). Required environment variable in Vercel project settings:
```
MONGODB_URI=
```
The home page uses ISR with a 1-hour revalidation window (`revalidate = 3600`). Categories can be revalidated on-demand using the `'categories'` cache tag.
---
## 🗺 Roadmap
- [ ] Complete FAB button actions
- [ ] Scene Card Mode — generate a full scene prompt in one tap Character + Location + Situation + Relation all at once, shown as a card
- [ ] 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.
- [ ] Native Share API - integration Share the current prompt via iOS/Android Share Sheet or copy to clipboard
- [ ] Favorites / History - Star words you liked; see last N drawn words per session
- [ ] Word suggestions from users
- [ ] Admin editor for categories and words - A protected `/admin` page to add, edit, delete words and categories without touching MongoDB directly
- [ ] Sound Effects - Optional button click / word-reveal sounds themed to the retro aesthetic
- [ ] Multiplayer / Room Mode - Host generates a prompt and all players on the same "room" see it simultaneously (WebSocket or polling)
- [ ] QR Code Share - Generate a QR code for a specific prompt to display on a projector/screen
- [ ] Animated Word Reveal - Glitch/typewriter animation when a new word appears, matching the CRT aesthetic
---
## 🤝 Contributing
Contributions are very welcome! Here are some ways you can help:
1. **Report Bugs** — Open an issue describing what went wrong.
2. **Suggest Features** — Open an issue with your idea.
3. **Submit Pull Requests** — Fork the repo, make your changes, and open a PR.
To better understand the project vision, import [PROJECT_IDEA.excalidraw](./PROJECT_IDEA.excalidraw) into [Excalidraw](https://excalidraw.com/).
---
## 👤 Author
**Andy Andrei** — [radoacaandrei3@gmail.com](mailto:radoacaandrei3@gmail.com)