# TypeDialog Web Backend

HTTP server with browser-based forms powered by [Axum](https://github.com/tokio-rs/axum).

## Overview

The Web backend (`typedialog-web`) provides a full-featured HTTP server with browser-based forms. Built with Axum for high performance, supporting REST APIs, WebSockets, and modern web interfaces.

## Features

- **HTTP Server**: Fast async server with Axum
- **Browser Forms**: Responsive HTML forms with JavaScript
- **Auto-Open**: Launch default browser automatically with `--open` flag
- **REST API**: JSON endpoints for form submission
- **Real-time Validation**: Client-side and server-side validation
- **RepeatingGroups**: Inline expandable cards with live counter
- **Mobile-Friendly**: Responsive design for all screen sizes
- **HTTPS Support**: TLS/SSL for production
- **Session Management**: Stateful forms with session persistence

## Quick Start

### Installation

```bash
cargo build --release -p typedialog-web
sudo cp target/release/typedialog-web /usr/local/bin/

# Or use just
just build::web
```text

### Basic Usage

```bash
# Start server (default: http://localhost:3000)
typedialog-web --config examples/form.toml

# Custom port
typedialog-web --config form.toml --port 8080

# Auto-open in browser
typedialog-web --config form.toml --open

# Custom port with auto-open
typedialog-web --config form.toml --port 8080 --open

# With HTTPS
typedialog-web --config form.toml --tls-cert cert.pem --tls-key key.pem

# From config file
typedialog-web --config config/web/production.toml
```text

### Browser Auto-Launch

Use `--open` to automatically open the form in your default web browser:

```bash
# Opens http://localhost:8080 automatically
typedialog-web --config form.toml --port 8080 --open
```text

This is particularly useful for:

- **Development**: Edit form and see changes instantly without manual URL entry
- **Demonstrations**: Show forms to stakeholders without extra steps
- **Scripting**: Automated workflows that need visual interaction
- **User Experience**: Users don't need to copy/paste URLs

If browser opening fails (e.g., in headless environments), a warning is shown but the form continues to serve normally.

## Server Endpoints

### Form Endpoints

| Method | Path | Description |
 | -------- | ------ | ------------- |
| `GET` | `/` | Render form HTML |
| `POST` | `/submit` | Submit form data |
| `GET` | `/api/form` | Get form definition (JSON) |
| `POST` | `/api/validate` | Validate field |
| `GET` | `/health` | Health check |

### Static Assets

| Path | Description |
 | ------ | ------------- |
| `/static/css/form.css` | Form styles |
| `/static/js/form.js` | Form logic |
| `/static/js/repeating-group.js` | RepeatingGroup handler |

## Configuration

### Server Config

```toml
[web]
host = "0.0.0.0"
port = 3000
tls_enabled = false

[web.cors]
allow_origin = "*"
allow_methods = ["GET", "POST"]
allow_headers = ["Content-Type"]

[web.session]
secret_key = "change-me-in-production"
timeout_seconds = 3600
```text

### TLS/HTTPS Config

```toml
[web.tls]
enabled = true
cert_path = "/path/to/cert.pem"
key_path = "/path/to/key.pem"
```text

### Form Config

```toml
[form]
title = "Registration Form"
description = "User registration"
submit_text = "Register"
cancel_text = "Cancel"

[[fields]]
name = "email"
field_type = "Text"
label = "Email"
validation = "email"
required = true
```text

## API Usage

### Get Form Definition

```bash
curl http://localhost:3000/api/form
```text

Response:

```json
{
  "form": {
    "title": "Registration",
    "fields": [...]
  }
}
```text

### Submit Form

```bash
curl -X POST http://localhost:3000/submit \
  -H "Content-Type: application/json" \
  -d '{"name":"John","email":"john@example.com"}'
```text

Response:

```json
{
  "status": "success",
  "data": {
    "name": "John",
    "email": "john@example.com"
  }
}
```text

### Validate Field

```bash
curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{"field":"email","value":"invalid"}'
```text

Response:

```json
{
  "valid": false,
  "error": "Invalid email format"
}
```text

## Frontend Features

### JavaScript API

```javascript
// Form submission
document.getElementById('form').addEventListener('submit', async (e) => {
  e.preventDefault();
  const formData = new FormData(e.target);
  const data = Object.fromEntries(formData);

  const response = await fetch('/submit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  });

  const result = await response.json();
  console.log('Submitted:', result);
});

// Real-time validation
input.addEventListener('blur', async () => {
  const response = await fetch('/api/validate', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      field: input.name,
      value: input.value
    })
  });

  const result = await response.json();
  if (!result.valid) {
    showError(result.error);
  }
});
```text

### RepeatingGroups

The web backend renders RepeatingGroups as inline expandable cards:

```html
<div class="repeating-group" data-min-items="1" data-max-items="10">
  <div class="items-counter">Items: 0/10</div>
  <div class="items-container">
    <!-- Item cards here -->
  </div>
  <button class="add-item-btn">Add Item</button>
</div>
```text

Features:

- Click "Add Item" to create new items
- Expand/collapse cards
- Delete items
- Live counter updates
- Min/max validation
- Duplicate detection (when `unique = true`)

### Styling

Custom CSS for forms:

```css
.form-container {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}

.field-group {
  margin-bottom: 1.5rem;
}

.field-label {
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.field-input {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.field-error {
  color: red;
  font-size: 0.875rem;
  margin-top: 0.25rem;
}

.submit-btn {
  background: #007bff;
  color: white;
  padding: 0.75rem 1.5rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
```text

## Deployment

### Development

```bash
typedialog-web --config config/web/dev.toml
```text

### Production

```bash
# With systemd
sudo systemctl start typedialog-web

# Or directly
typedialog-web \
  --config config/web/production.toml \
  --tls-cert /etc/ssl/cert.pem \
  --tls-key /etc/ssl/key.pem \
  --port 443
```text

### Docker

```bash
# Build image
docker build -t typedialog-web .

# Run container
docker run -p 3000:3000 \
  -v $(pwd)/config:/config \
  typedialog-web --config /config/web/production.toml
```text

### Reverse Proxy (Nginx)

```nginx
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}
```text

## Use Cases

### 1. SaaS Applications

Customer onboarding forms with validation:

```bash
typedialog-web --config saas/onboarding.toml --port 443 --tls
```text

### 2. Internal Tools

Admin panels and configuration interfaces:

```bash
typedialog-web --config admin/settings.toml --host 0.0.0.0
```text

### 3. Public Forms

Contact forms, surveys, registrations:

```bash
typedialog-web --config public/contact.toml
```text

### 4. API Integration

Headless forms with JSON API:

```bash
curl http://localhost:3000/api/form | jq .
```text

## Security

### HTTPS

Always use HTTPS in production:

```toml
[web.tls]
enabled = true
cert_path = "/etc/ssl/cert.pem"
key_path = "/etc/ssl/key.pem"
```text

### CORS

Configure CORS for cross-origin requests:

```toml
[web.cors]
allow_origin = "https://example.com"
allow_methods = ["GET", "POST"]
allow_headers = ["Content-Type", "Authorization"]
```text

### Session Security

Use strong session secrets:

```toml
[web.session]
secret_key = "generate-random-32-byte-key"
timeout_seconds = 1800  # 30 minutes
secure_cookies = true
http_only = true
```text

### Input Validation

Always validate on server-side:

```toml
[[fields]]
name = "email"
validation = "email"
required = true

[[fields]]
name = "age"
validation = "range(18..120)"
```text

## Examples

See [examples/04-backends/web/](../../examples/04-backends/web/) for:

- Basic forms
- REST API integration
- RepeatingGroups
- Custom styling
- HTTPS configuration
- Multi-page forms

## Related Documentation

- [Installation](../installation.md) - Setup guide
- [Configuration](../configuration.md) - Web configuration options
- [Field Types](../field-types.md) - Available field types
- [Encryption](../encryption/) - Secure field handling
- [Examples](../../examples/04-backends/web/) - Working examples

## Troubleshooting

### "Address already in use"

Port is occupied. Use different port:

```bash
typedialog-web --config form.toml --port 8080
```text

### "TLS certificate error"

Check cert paths and permissions:

```bash
ls -l /path/to/cert.pem /path/to/key.pem
```text

### "CORS error"

Configure CORS in config:

```toml
[web.cors]
allow_origin = "http://localhost:3000"
```text

### "Form not submitting"

Check JavaScript console for errors. Ensure `/submit` endpoint is reachable.

### "Session expired"

Increase session timeout:

```toml
[web.session]
timeout_seconds = 7200  # 2 hours
```text

---

**Ready to start?** See [examples/04-backends/web/](../../examples/04-backends/web/)
