Files
exposedgays/README.md

178 lines
5.4 KiB
Markdown

# ExposedGays
100% free gay cruising map + chat + spots directory + sex shop. No subscriptions ever.
**Domain:** exposedgays.com
## Quick Start
```bash
npm install
cp .env.example .env.local
# Edit .env.local with your Supabase keys (optional for local demo — mock data works offline)
npm run dev
```
Open [http://localhost:3000](http://localhost:3000)
## Features
| Feature | Status |
|---------|--------|
| Real-time cruising map (Leaflet + OSM) | ✅ Mock data + Supabase-ready |
| User clustering + position badges | ✅ |
| Map filters (age, position, kinks, PrEP) | ✅ |
| Cruiser Cards + Profile popup | ✅ |
| Instant chat + city chat + DMs + groups | ✅ Mock + Supabase schema |
| Cruising spot directory | ✅ |
| **Shop** (affiliate links, local cart) | ✅ |
| Age verification gate (Florida-compliant) | ✅ |
| Vanilla mode blur toggle | ✅ |
| Dark mode, mobile-first, PWA manifest | ✅ |
| Anonymous browsing + optional profile | ✅ |
| **Hosting events** (Sniffies-style map parties) | ✅ |
| Schedule ahead · 2 photos + 1 video · invites | ✅ |
| Request/auto-accept · edit · cancel · RSVP | ✅ |
## Tech Stack
- **Next.js 15** App Router + TypeScript
- **Tailwind CSS** + shadcn/ui components
- **React-Leaflet** + OpenStreetMap tiles
- **Supabase** — Auth, Postgres + PostGIS, Realtime, Storage
- **Zustand** — localStorage cart
## Project Structure
```
exposedgays/
├── public/
│ └── manifest.json # PWA manifest
├── src/
│ ├── app/
│ │ ├── layout.tsx # Root layout + nav
│ │ ├── page.tsx # Map (home)
│ │ ├── shop/page.tsx # Sex shop
│ │ ├── chat/page.tsx # City chat + DMs
│ │ ├── spots/page.tsx # Spot directory
│ │ └── profile/page.tsx # User profile editor
│ ├── components/
│ │ ├── AgeGate.tsx # 18+ DOB verification
│ │ ├── Map.tsx # Interactive cruising map
│ │ ├── Shop.tsx # Product grid + cart
│ │ ├── Nav.tsx # Top/bottom nav with Shop link
│ │ ├── ChatPanel.tsx # Real-time chat UI
│ │ ├── CruiserCard.tsx # Squirt-style cruiser cards
│ │ ├── ProfilePopup.tsx # Tap icon → profile modal
│ │ ├── SpotDirectory.tsx # Spot listings + search
│ │ └── ui/ # shadcn components
│ ├── lib/
│ │ ├── products.ts # Dummy shop inventory
│ │ ├── cart.ts # Zustand localStorage cart
│ │ ├── mock-data.ts # Demo cruisers + spots
│ │ └── supabase/ # Supabase client helpers
│ └── types/index.ts
├── supabase/
│ └── schema.sql # Full Postgres + PostGIS + RLS
├── .env.example
└── package.json
```
## Auth (Supabase)
Auth is wired via `src/lib/auth/context.tsx` + `AuthModal.tsx`:
- **Join Free** in nav → email/password signup or login
- **Continue Anonymously** → `signInAnonymously()` (enable in Supabase Dashboard → Auth → Providers → Anonymous)
- Profile page syncs to `profiles` table when signed in
Enable on https://supabase.onsethost.com → Authentication → Providers:
- Email (confirm email optional for dev)
- Anonymous sign-ins
## Supabase Setup
### 1. Create project
Go to [supabase.com](https://supabase.com) → New Project (free tier).
### 2. Run schema
SQL Editor → paste contents of `supabase/schema.sql` → Run.
### 3. Enable Realtime
Dashboard → Database → Replication → enable `chat_messages` and `profiles`.
### 4. Create Storage bucket
```sql
INSERT INTO storage.buckets (id, name, public) VALUES ('gallery', 'gallery', true);
INSERT INTO storage.buckets (id, name, public) VALUES ('shop', 'shop', true);
```
### 5. Copy keys to `.env.local`
```
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
```
### CLI alternative
```bash
npx supabase init
npx supabase link --project-ref YOUR_PROJECT_REF
npx supabase db push
```
## 5-Minute Deployment (Vercel + Supabase + DNS)
### Step 1 — Push to GitHub (1 min)
```bash
git init
git add .
git commit -m "ExposedGays starter"
gh repo create exposedgays --private --push
```
### Step 2 — Vercel deploy (2 min)
1. [vercel.com](https://vercel.com) → Import Git repo
2. Framework: **Next.js** (auto-detected)
3. Add environment variables from `.env.example`
4. Deploy → get `exposedgays.vercel.app`
### Step 3 — Custom domain (1 min)
1. Vercel → Project → Settings → Domains → Add `exposedgays.com` + `www.exposedgays.com`
2. Vercel shows required DNS records
### Step 4 — DNS at registrar (1 min)
| Type | Name | Value |
|------|------|-------|
| A | @ | `76.76.21.21` |
| CNAME | www | `cname.vercel-dns.com` |
(Or use Cloudflare CNAME flattening if proxied.)
### Step 5 — Verify
- Visit `https://exposedgays.com` — age gate appears
- Map loads with cruiser icons
- Shop nav works with affiliate buttons
- PWA installable on mobile
## Shop Affiliate Notes
- Cart is **localStorage only** — no checkout on-site
- "Buy Now" opens affiliate URLs in new tab (`rel="sponsored"`)
- Replace placeholder URLs with real Amazon Associates / AdamMale affiliate links
- Products defined in `src/lib/products.ts` (static) or `shop_products` table (DB)
## License
Private — exposedgays.com © 2026