A community-driven platform to discover the best restaurants, cafés, and food spots on Maginhawa Street, Quezon City, Philippines.
🌟 Community-Powered: Anyone can contribute by adding or updating places via pull requests!
This project uses Turborepo with pnpm for efficient monorepo management.
whereinmaginhawa/
├── apps/
│ └── web/ # Main user-facing website (Phase 1)
│ └── admin/ # Admin panel (Phase 2 - Coming Soon)
├── packages/
│ └── typescript-config/ # Shared TypeScript configurations
└── turbo.json # Turborepo configuration
User Features:
- ✅ Beautiful Hero Section with animated gradients and MagicUI-inspired components
- ✅ Advanced Search Bar with real-time autocomplete suggestions
- ✅ Smart Search powered by Fuse.js for fuzzy matching
- ✅ Place Listings with grid view and filtering
- ✅ Detailed Place Pages with complete information
- ✅ Tag-Based Filtering (cuisines, amenities, cravings)
- ✅ SEO Category Pages - 25 optimized landing pages for organic search traffic
- ✅ Responsive Design optimized for all devices
Community Features:
- ✅ Community Contributions - Add places via pull requests
- ✅ Automated PR Validation - Instant feedback on contributions
- ✅ Zero Merge Conflicts - Each place has its own file
- ✅ Auto-Generated Index - Optimized search performance
- ✅ GitHub Actions CI/CD - Automated build and deployment
- 🔜 Supabase PostgreSQL integration
- 🔜 Image upload to Supabase Storage
- 🔜 Full-text search with PostgreSQL
- 🔜 User authentication
- 🔜 Admin panel for managing places
- 🔜 User reviews and ratings
- 🔜 Interactive map integration
- Framework: Next.js 14+ (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- UI Components: shadcn/ui
- Animations: Framer Motion
- Search: Fuse.js
- Icons: Lucide React
- Validation: Zod (JSON schema validation)
- Build Tools: tsx (TypeScript execution)
- Data Format: JSON (individual files + auto-generated index)
- Automation: GitHub Actions
- Deployment: Vercel
- Quality Gates: Automated PR validation
- Node.js 18+
- pnpm 8+ (recommended:
npm install -g pnpm)
- Install dependencies (installs for all workspaces):
pnpm install- Set up environment variables:
Create
apps/web/.env.localfile with your MagicUI Pro API key:
NEXT_PUBLIC_MAGICUI_API_KEY=your_api_key_here- Run the development server:
pnpm devThis will start all apps in development mode using Turborepo.
- Open http://localhost:3000 in your browser
# Development
pnpm dev # Run dev servers for all apps
pnpm build # Build all apps and packages
pnpm lint # Run linting for all apps
pnpm type-check # Type check all TypeScript
# Data Management
pnpm build:index # Generate places.json from individual files
pnpm build:stats # Generate stats.json from individual files
pnpm validate:places # Validate all place files
pnpm validate:place <file> # Validate a specific place file
# Maintenance
pnpm clean # Clean all build artifacts and node_modules
# Package Management
pnpm add <package> --filter @whereinmaginhawa/web # Install in specific workspace
pnpm add -Dw <package> # Install dev dependency in rootwhereinmaginhawa/
├── apps/
│ └── web/ # Main website
│ ├── src/
│ │ ├── app/ # Next.js app directory
│ │ ├── components/ # React components
│ │ ├── data/ # JSON data (Phase 1)
│ │ ├── lib/ # Utility functions
│ │ └── types/ # TypeScript types
│ ├── public/ # Static assets
│ └── package.json
├── packages/
│ └── typescript-config/ # Shared TS configs
│ ├── base.json
│ └── nextjs.json
├── turbo.json # Turborepo config
└── package.json # Root package.json
src/
├── app/ # Next.js app directory
│ ├── page.tsx # Home page with hero
│ ├── layout.tsx # Root layout
│ ├── [category]/ # SEO category pages
│ │ └── page.tsx # Dynamic category landing pages
│ └── places/ # Places routes
├── components/ # React components
│ ├── hero/ # Hero section
│ ├── place/ # Place components
│ ├── search/ # Search components
│ └── ui/ # shadcn/ui components
├── data/ # JSON data (Phase 1)
│ ├── places.json # Auto-generated index (lightweight)
│ ├── stats.json # Auto-generated statistics
│ └── places/ # Individual place files
│ ├── rodics-diner.json
│ ├── crazy-katsu.json
│ └── ... # 225+ place files
├── lib/ # Utility functions
│ ├── places.ts # Place data operations
│ ├── categories.ts # Category configuration
│ └── utils.ts # General utilities
└── types/ # TypeScript types
├── place.ts # Place types & DB schema
├── category.ts # Category types
└── tags.ts # Tag definitions
The complete Supabase PostgreSQL schema is documented in src/types/place.ts, including:
placestable with full-text search supporttagstable for normalized tag managementplace_tagsjunction table- Indexes for optimal search performance
25 statically-generated category pages optimized for organic search traffic. Each category page is designed to rank for specific search queries like "bars in maginhawa" or "coffee shops maginhawa".
- 🎯 Targeted SEO metadata - Optimized titles, descriptions, keywords, and OpenGraph tags
- 📊 Pre-filtered results - Keyword-based search across tags, amenities, cuisineTypes, and specialties
- 🎨 Emoji hero icons - Visual branding for each category
- 📍 Canonical URLs - Proper SEO with sitemap integration
- ⚡ Static generation - Built at compile time for fast page loads
| Category | URL | Type | Priority |
|---|---|---|---|
| 🍻 Bars in Maginhawa | /bars-in-maginhawa |
Amenity | 0.85 |
| ☕ Coffee Shops | /coffee-shops-in-maginhawa |
Cuisine | 0.90 |
| 🇵🇭 Filipino Restaurants | /filipino-restaurants-in-maginhawa |
Cuisine | 0.85 |
| 🍱 Japanese Restaurants | /japanese-restaurants-in-maginhawa |
Cuisine | 0.80 |
| 🇰🇷 Korean Restaurants | /korean-restaurants-in-maginhawa |
Cuisine | 0.80 |
| 🍝 Italian Restaurants | /italian-restaurants-in-maginhawa |
Cuisine | 0.75 |
| 🍕 Pizza Places | /pizza-in-maginhawa |
Cuisine | 0.85 |
| 🥡 Chinese Restaurants | /chinese-restaurants-in-maginhawa |
Cuisine | 0.80 |
| 🍔 Burger Joints | /burger-joints-in-maginhawa |
Cuisine | 0.80 |
| 🥪 Breakfast & Brunch | /breakfast-brunch-in-maginhawa |
Experience | 0.75 |
| 🍜 Vietnamese Restaurants | /vietnamese-restaurants-in-maginhawa |
Cuisine | 0.70 |
| 🌮 Mexican Restaurants | /mexican-restaurants-in-maginhawa |
Cuisine | 0.70 |
| 🍛 Thai Restaurants | /thai-restaurants-in-maginhawa |
Cuisine | 0.70 |
| 🍦 Desserts & Ice Cream | /desserts-ice-cream-in-maginhawa |
Cuisine | 0.75 |
| 🍗 Fried Chicken | /fried-chicken-in-maginhawa |
Cuisine | 0.75 |
| 🐾 Pet-Friendly Places | /pet-friendly-restaurants-in-maginhawa |
Amenity | 0.80 |
| 📶 Places with WiFi | /wifi-cafes-in-maginhawa |
Amenity | 0.85 |
| 🌳 Outdoor Seating | /outdoor-seating-in-maginhawa |
Amenity | 0.70 |
| 💰 Budget-Friendly Eats | /budget-restaurants-in-maginhawa |
Price | 0.85 |
| 🌙 Late-Night Dining | /late-night-dining-in-maginhawa |
Experience | 0.80 |
| 💑 Romantic Date Spots | /romantic-date-spots-in-maginhawa |
Experience | 0.75 |
| 👨👩👧👦 Family-Friendly | /family-friendly-restaurants-in-maginhawa |
Experience | 0.70 |
| 📸 Instagram-Worthy Spots | /instagram-worthy-spots-in-maginhawa |
Experience | 0.75 |
| 🥗 Vegetarian & Vegan | /vegetarian-vegan-in-maginhawa |
Cuisine | 0.70 |
| 🎉 Group Dining | /group-dining-in-maginhawa |
Experience | 0.70 |
- Dynamic Route:
apps/web/src/app/[category]/page.tsx - Configuration:
apps/web/src/lib/categories.ts - Types:
apps/web/src/types/category.ts - Filtering: Keyword-based search across all place metadata
- Generation: Static generation via
generateStaticParams()at build time - SEO: Dynamic metadata via
generateMetadata()for each category
We welcome community contributions! Help us keep Where In Maginhawa up to date.
- Fork the repository on GitHub
- Create a new file:
apps/web/src/data/places/your-place-slug.json - Use this template:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Your Restaurant Name",
"slug": "your-restaurant-name",
"description": "Brief description (minimum 10 characters)",
"address": "Full address in Maginhawa",
"operatingHours": {
"monday": { "open": "10:00", "close": "22:00" }
},
"priceRange": "$$",
"cuisineTypes": ["filipino"],
"createdAt": "2025-11-09T00:00:00.000Z",
"updatedAt": "2025-11-09T00:00:00.000Z"
}- Generate a UUID for the
idfield at uuidgenerator.net - Submit a pull request
When you create a PR:
- ✅ GitHub Actions automatically validates your file
- ✅ Bot comments on your PR with validation results
- ✅ If errors found, fix them and push - validation runs again
- ✅ Once valid, maintainers will review and merge
No need to edit places.json or stats.json - they're auto-generated!
See CONTRIBUTING.md for:
- Complete field reference
- UUID generators
- Validation rules
- Common errors and fixes
- Schema documentation
- Find the file in
apps/web/src/data/places/ - Edit the JSON
- Update the
updatedAttimestamp - Submit a pull request
This project uses GitHub Actions for automated deployment:
-
PR Validation (
.github/workflows/validate-pr.yml)- Validates place files when PRs are created
- Comments on PR with validation results
- Blocks merge if validation fails
-
Build and Deploy (
.github/workflows/build-and-deploy.yml)- Triggers when PRs are merged to
main - Validates changed files
- Builds
places.jsonandstats.json - Commits built files back to repo
- Triggers Vercel deployment via webhook
- Triggers when PRs are merged to
- Disable automatic deployments in Vercel (Settings → Git)
- Create a Deploy Hook in Vercel (Settings → Git → Deploy Hooks)
- Add to GitHub Secrets as
VERCEL_DEPLOY_HOOK
For local testing:
pnpm build:index # Build places index
pnpm build:stats # Build statistics
pnpm build # Build all appsThen deploy via the Vercel Platform.
Individual Files Auto-Generated Files
───────────────── ──────────────────────
places/
├── rodics-diner.json ┌─→ places.json (index)
├── crazy-katsu.json ───────┤ - Lightweight
├── friuli-trattoria.json │ - Search optimized
└── ... (200+ files) │ - 168KB vs 380KB
│
└─→ stats.json
- Cuisine counts
- Amenity stats
Benefits:
- ✅ Zero merge conflicts - each contributor edits their own file
- ✅ Faster page loads - 56% smaller index file
- ✅ Better for Git - meaningful diffs, easy to review
- ✅ Scalable - add 1000s of places without performance issues
Want to add a restaurant? It's easy:
- Fork this repo on GitHub
- Create one file:
apps/web/src/data/places/your-restaurant.json - Copy template from CONTRIBUTING.md
- Get a UUID at https://www.uuidgenerator.net/
- Submit PR - our bot will validate it automatically!
You create PR
↓
Bot validates your file (< 1 minute)
↓
Bot comments: ✅ "All good!" or ❌ "Fix these errors"
↓
If needed: Fix & push (validation runs again)
↓
Maintainer reviews
↓
Merged!
↓
GitHub Actions builds & deploys
↓
Your place is LIVE! 🎉
- 📖 Read CONTRIBUTING.md
- 🔍 Look at existing files in
apps/web/src/data/places/ - 💬 Ask questions in your PR
- 📧 Open an issue
Built with ❤️ for the Maginhawa community
This project is open source and available under the MIT License.