# Contracts Admin MVP

This is a single-file PHP admin and JSON API that lets you:

- List all `.md` contracts stored in a `/contracts` folder
- Edit a contract in a modal and save changes back to disk
- Email a signing link to a client and mark the item as "sent"
- Mark contracts as "signed" automatically from your existing `contract.php` page, or manually from the UI

## Quick start

1. Copy `contracts-admin.php` to a folder that is **not** public or is protected by HTTP auth.
2. Make sure your contracts live in a folder named `contracts` alongside this file. Each file is `clientid.md`.
3. Open the admin in a browser and log in with `admin / changeme`.
4. Click **Edit** to update an `.md`. Click **Email link** to send the client a link like:

   ```
   https://modulosdesign.com.au/contracts/contract.php?clientid=3043
   ```

   The "sent" tick updates automatically on success.

## Configuration

Open the top of `contracts-admin.php` and adjust:

- `CONTRACTS_DIR` absolute path to your contracts folder
- `BASE_URL` base URL where the public `contract.php` lives
- `ADMIN_SHARED_SECRET` shared token used by `contract.php` to mark items as signed
- `ADMIN_USER` and `ADMIN_PASS` for Basic Auth
- Database: by default uses SQLite `contracts.sqlite`. You can override with `DB_DSN`, `DB_USER`, `DB_PASS` for MySQL or Postgres

If you already have a `config.php` with `$pdo` or constants, keep it next to the file. It will be included automatically.

## Database

The app auto-creates a table named `contract_status`.

```sql
CREATE TABLE IF NOT EXISTS contract_status (
  clientid        TEXT PRIMARY KEY,
  sent            INTEGER DEFAULT 0,
  sent_at         TEXT NULL,
  signed          INTEGER DEFAULT 0,
  signed_at       TEXT NULL,
  last_email_to   TEXT NULL,
  pdf_path        TEXT NULL,
  signer_name     TEXT NULL,
  signer_ip       TEXT NULL
);
```

On MySQL, use `VARCHAR(64)` for `clientid` and `DATETIME` for timestamps.

## Hooking into your existing `contract.php`

After the client signs and the PDF has been generated and emailed, call the admin endpoint to mark it signed.

**Add this snippet near the end of your `contract.php` after a successful send:**

```php
// Mark as signed in the admin database
$clientid = $_GET['clientid'] ?? '';
$signerName = $clientName ?? null; // replace with your variable if available
$pdfPath = $savedPdfPath ?? null;  // replace with your PDF path if you store it

$ch = curl_init('https://your-admin-url/contracts-admin.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
  'action' => 'mark_signed',
  'secret' => ADMIN_SHARED_SECRET, // define the same secret in both places
  'clientid' => $clientid,
  'name' => $signerName,
  'pdf' => $pdfPath,
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
```

If you prefer direct DB access from `contract.php`, insert or update `contract_status` with `signed=1` instead.

## Email sending

The MVP uses PHP `mail()` by default. If PHPMailer is present and SMTP constants are defined (`SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASS`, `SMTP_SECURE`), it will send via SMTP.

The email body is simple and friendly. Tweak it in `send_contract_email()`.

## Security

- Protect this admin with HTTP Basic Auth or an allowlist in your reverse proxy
- The signing webhook uses a shared secret
- Filenames are validated to prevent path traversal

## Embedding

You can embed the admin as an iframe inside Grav's admin route accessible only to you. Example shortcode:

```html
<iframe src="/protected/contracts-admin.php" width="100%" height="900" style="border:0"></iframe>
```

For better integration, use an Nginx rule to restrict by your IP or VPN.

## Styling and UX

- Sticky header for the table
- Search box filters by client id or last sent email
- Buttons for edit, email, copy link, and open

You can brand it by adding your logo and colors in the `<style>` block.
