# Great Rift Valley Innovation Summit

Marketing site for the [Great Rift Valley Innovation Summit](https://grvsummit.com/), built with Next.js App Router, TypeScript, Tailwind CSS, and [shadcn/ui](https://ui.shadcn.com/).

## Getting started

```bash
npm install
npm run download-assets   # optional: refresh logos/speakers from grvsummit.com
npm run dev
```

Open [http://localhost:3000](http://localhost:3000).

If you see `ENOENT` errors under `.next/…/app-build-manifest.json` or `_buildManifest.js.tmp`, stop the server, run `rm -rf .next`, then `npm run dev` again. Use `npm run dev:clean` to do both. Turbopack (`npm run dev:turbo`) is opt-in and can be flaky with manifest writes on some setups.

## Scripts

| Command | Description |
|---------|-------------|
| `npm run dev` | Start dev server (webpack — stable default) |
| `npm run dev:turbo` | Dev server with Turbopack (faster, optional) |
| `npm run dev:clean` | Remove `.next` cache then start dev (fixes broken dev cache) |
| `npm run build` | Production build |
| `npm run start` | Start production server |
| `npm run lint` | ESLint |
| `npm run download-assets` | Download branding assets from official WordPress uploads |

## shadcn/ui

Add components:

```bash
npx shadcn@latest add <component>
```

Config: [`components.json`](components.json). Theme tokens live in [`app/globals.css`](app/globals.css) (GRV navy `#1F3D7E`, gold `#FFB300`).

## Content

Editable copy and data: [`content/`](content/). Images: [`public/branding/`](public/branding/).

## Inquiry API

`POST /api/inquiry` accepts JSON with `intent` (`general` | `exhibitor` | `sponsor` | `sales` | `press` | `newsletter`), `name`, `email`, `message`, and optional `company` / `phone`. v1 logs to the server console only.

To wire email (e.g. Resend), update [`app/api/inquiry/route.ts`](app/api/inquiry/route.ts) and set env vars from [`.env.example`](.env.example).

## Assets

Logos and speaker cutouts are downloaded from the official site via `scripts/download-assets.mjs`. Confirm trademark and usage rights with EDTF before production deployment.

## Pages

- `/` — Home
- `/program` — Agenda
- `/pitch-competition` — Grant competition
- `/payment` — Ticket selection & checkout (API stub)
- `/payment/success` — Order confirmation
- `/exhibit` — Exhibitor inquiries
- `/sponsor` — Sponsorship tiers
- `/contact` — Contact channels & form

## Calendar

- **`.ics` download** at [`/calendar`](app/calendar/route.ts) for Apple Calendar / iCal (direct URL still works if you share it)

## Payment API

`POST /api/payment` accepts `ticketId`, `quantity`, `name`, `email`, `paymentMethod` (`card` | `bank`). v1 logs orders to the console; wire Stripe, Chapa, or similar for production.

## Deploy – Cloudflare Workers (OpenNext)

This project is configured for [**OpenNext on Cloudflare**](https://opennext.js.org/cloudflare).

### One-time setup

1. Install deps: `npm install`
2. Authenticate Cloudflare:
   ```bash
   npx wrangler@4 login
   ```
   Or export **`CLOUDFLARE_API_TOKEN`** and **`CLOUDFLARE_ACCOUNT_ID`**.
3. Set production env vars in Cloudflare Workers (or your CI):
   - `NEXT_PUBLIC_SITE_URL` (your production URL)

### Deploy now

```bash
npm run deploy
```

`predeploy` automatically removes `.next` and `.open-next` first so each deploy matches a clean local build (avoids stale worker bundles).

Alias:

```bash
npm run deploy:cf
```

### Other useful commands

```bash
npm run preview      # build + local Workers preview runtime
npm run upload       # build + upload worker version (no immediate rollout)
npm run cf-typegen   # generate cloudflare-env.d.ts from wrangler bindings
```

### CI (optional)

Workflow file: [`.github/workflows/cloudflare-workers-opennext.yml`](.github/workflows/cloudflare-workers-opennext.yml)

Add repo secrets:
- `CLOUDFLARE_API_TOKEN`
- `CLOUDFLARE_ACCOUNT_ID`

### Notes

- OpenNext Cloudflare does **not** support `export const runtime = "edge"`; those exports were removed.
- Build output is generated under **`.open-next/`** (gitignored).
- **`open-next.config.ts`** imports `@opennextjs/cloudflare` — that package **must** be installed locally (`npm install`). Using only `npx @opennextjs/cloudflare` without installing deps will fail with “Could not resolve `@opennextjs/cloudflare`”.
- Use **Node 20 or 22 LTS** for deploys. Node 25 is not recommended for Wrangler / workerd toolchains.
- Local **`next dev`** does not wire OpenNext’s miniflare shim unless you set **`OPENNEXT_CLOUDFLARE_DEV=1`** (only needed if you call `getCloudflareContext` in app code during dev). Production deploys are unchanged.

### Troubleshooting

**`ENOENT` / missing `app-build-manifest.json` or `_buildManifest.js.tmp` in dev**

Stop the dev server, delete the cache (`rm -rf .next`), and run `npm run dev` again. Prefer the default dev script (webpack); use `dev:turbo` only if you need Turbopack.

**`ETIMEDOUT` downloading `workerd` or other npm packages**

Retry when the network is stable, or use a VPN / different DNS. You can also raise timeouts:

```bash
npm config set fetch-timeout 600000
npm config set fetch-retries 5
```

Then run `npm install` again before `npm run deploy`.

