# Angular frontend deployment (Nginx)
#
# https://calendar.gventure.info
#
# CRITICAL: /book/* must serve the public-booking SPA, NOT host-dashboard.
# If /book falls through to host-dashboard, guests only see
# "Opening booking page…" and the booking UI never loads.

```nginx
upstream calendar_api {
    server 127.0.0.1:3671;
}

server {
    listen 443 ssl http2;
    server_name calendar.gventure.info;

    # ssl_certificate /etc/letsencrypt/live/calendar.gventure.info/fullchain.pem;
    # ssl_certificate_key /etc/letsencrypt/live/calendar.gventure.info/privkey.pem;

    root /var/www/calendar/host-dashboard;

    # Node API (Angular uses apiUrl: '/api/v1')
    location /api/v1/ {
        proxy_pass http://calendar_api/v1/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Public booking SPA (production build uses deployUrl: /book/)
    # Deploy: mkdir -p /var/www/calendar/book && cp -r dist/public-booking/browser/. /var/www/calendar/book/
    location ^~ /book/ {
        root /var/www/calendar;
        try_files $uri $uri/ /book/index.html;
    }

    # Same SPA for cancel / feedback routes (assets still under /book/)
    location ^~ /cancel/ {
        rewrite ^ /book/index.html last;
    }

    location ^~ /feedback {
        rewrite ^ /book/index.html last;
    }

    # Embed widget iframe SPA
    # Deploy: mkdir -p /var/www/calendar/embed/widget && cp -r dist/embed-widget/browser/. /var/www/calendar/embed/widget/
    location ^~ /embed/widget/ {
        root /var/www/calendar;
        try_files $uri $uri/ /embed/widget/index.html;
    }

    # Embed loader (Express static) — do not swallow /embed/widget/
    location ^~ /embed/ {
        proxy_pass http://calendar_api/embed/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # Host dashboard SPA
    location / {
        try_files $uri $uri/ /index.html;
    }
}
```

Build all apps:

```bash
cd angular
npm run build:all
```

Copy build output (paths must match nginx `root` / `try_files` above):

```bash
cp -r dist/host-dashboard/browser/. /var/www/calendar/host-dashboard/
mkdir -p /var/www/calendar/book
cp -r dist/public-booking/browser/. /var/www/calendar/book/
mkdir -p /var/www/calendar/embed/widget
cp -r dist/embed-widget/browser/. /var/www/calendar/embed/widget/
nginx -t && systemctl reload nginx
```

Verify booking (title must be **Book a meeting**, not Host Dashboard):

```bash
curl -sI https://calendar.gventure.info/book/YOUR_USERNAME/YOUR_SLUG | head
curl -s https://calendar.gventure.info/book/index.html | head -n 5
# Expect: <title>Book a meeting</title>
```

Server `.env` (see `node/.env.production.example`):

```
APP_URL=https://calendar.gventure.info
BOOKING_APP_URL=https://calendar.gventure.info
API_URL=https://calendar.gventure.info/api
CORS_ALLOWED_ORIGINS=https://calendar.gventure.info
```
