# Siteforge

This project is a React + TypeScript portfolio app built with Vite.

It is designed to showcase two categories of work:

- Websites
- Apps

The app now supports:

- Dynamic cards generated from a project data source
- Built vs Hosted filters
- A dedicated About page route for each project
- An admin editor route to update cards and About pages
- A per-project README summary block on each project page
- Embedded Spotify podcast player on the home section

## Run locally

```bash
npm install
npm run dev:full
```

`dev:full` starts both:

- Vite frontend (`http://localhost:5173`)
- Admin content API (`http://localhost:4173`)

## Build for production

```bash
npm run build
```

## Run in container

Pull image directly:

```bash
docker pull ghcr.io/nmemmert/siteforge:latest
docker run -d --name siteforge-app -p 4173:4173 -v ./data:/app/data ghcr.io/nmemmert/siteforge:latest
```

Run with Docker Compose:

```bash
docker compose pull
docker compose up -d
```

Admin auth:

- Set `ADMIN_PASSWORD` on the server/container to protect `/admin` and admin stats/maintenance endpoints.
- Without `ADMIN_PASSWORD`, admin login is disabled until configured.
- Optional: set `CACHE_PURGE_WEBHOOK_URL` to enable one-click cache purge from Admin Operations.
- Optional: set `DEPLOY_WEBHOOK_URL` to enable one-click deploy trigger from Admin Operations.
- Optional: set `BUILD_COMMIT`, `BUILD_NUMBER`, and `DEPLOYED_AT` to display deployment status in Admin.

The app will be available at `http://localhost:4173`.

Persistent admin saves:

- Admin updates are written to `data/admin-content.json`.
- Admin drafts are written to `data/admin-content-draft.json`.
- Built-in page hit stats are written to `data/hit-stats.json`.
- Detailed visitor analytics are written to `data/visitor-stats.json`.
- Backup snapshots are written to `data/backups/`.
- Uploaded admin assets are stored in `data/uploads/` and served at `/uploads/*`.
- `docker-compose.yml` mounts `./data` into the container at `/app/data`.
- This keeps all admin-managed data after container restarts/rebuilds/updates.

## Where to edit content

- Project domain data and ownership: `src/data/projects.ts`
- Portfolio rendering logic: `src/App.tsx`
- Portfolio UI styles: `src/App.css`
- Global theme variables: `src/index.css`

## Routes

- Site home: `/`
- Start Here: `/start-here`
- Questions: `/questions`
- Privacy: `/privacy`
- Terms: `/terms`
- Admin editor: `/admin`
- Admin draft preview: `/preview`

## Admin editing

- Open `/admin` to edit homepage content, links, archived studies, Q&A moderation, and analytics.
- Use **Operations** to manage SEO metadata, sitemap paths, legal page text, redirect rules, and podcast highlights.
- Use **Operations** to upload/delete hosted image assets for use in content and social cards.
- Use **Save Draft**, **Preview Draft**, and **Publish Draft** for a safer publish workflow.
- Saved edits are written to `data/admin-content.json` through the API server.
- Built-in stats in `/admin` include page hits plus visitor details (IP, country/state/county/city, returning visitors, and recent visitor log).
- Site Stats in `/admin` includes a Bible Questions inbox sourced from contact form submissions marked as Bible Question.
- Analytics cookies are consent-based. Visitors can accept or decline tracking from the site banner.
- Admin now includes maintenance actions: **Export JSON**, **Backup Now**, **Prune Old Data**, and **Clear Analytics**.
- Admin also supports restoring from a backup snapshot from `/admin`.
- The server creates startup + daily backup snapshots and retains recent backups automatically.
- Operations can trigger optional **Purge Cache** and **Trigger Deploy** webhooks.

Deployment note:

- To keep Admin saves working on the internet, deploy with the Node API (`server.js`) and writable server storage for `data/`.

Titus study download gate:

- The site now gates Titus study downloads behind a name/email form.
- Default source file is `A_Study_of_Titus.pdf` in the project root.
- Override source path with `TITUS_STUDY_FILE` (relative to project root or absolute).
- Override downloaded filename with `TITUS_STUDY_DOWNLOAD_NAME`.
- When the form checkbox is left enabled (default), contacts are synced to Resend using the same contact sync flow as the contact form.

Useful container commands:

```bash
docker compose logs -f
docker compose down
```

Update to latest image:

```bash
docker compose pull
docker compose up -d
```

## Notes

- The current project cards are sample placeholders.
- Most metadata was scanned from live pages.
- Skywatch currently uses a manual fallback description due to a `401` response during automated scan.
