# Feature Plan: WhatsApp Share Column in hw-guest-table

> This plan file will be written to `d:\LocalWP\howe\app\public\feature_whatsappshare.md` as first implementation step.

---

## Context

Guest table in editor shows Name, Email, Groups, Persons, RSVP, Actions.  
Couple needs fast way to share personalized invitation via WhatsApp per guest.  
WhatsApp text = resolved email body (same variables as email send) + personalization URL.  
No new backend needed — pure frontend, all data already in scope.

---

## Files to Modify

| File | Purpose |
|------|---------|
| `assets/js/editor-app.js` | Main: add helper fn, table column, return export |
| `assets/lang/de.js` | 2 new lang keys |
| `assets/lang/en.js` | 2 new lang keys |
| `assets/css/editor.css` (or equivalent) | Optional: style new column if needed |

---

## Critical Code Locations

| What | File | Line(s) |
|------|------|---------|
| `mailTemplates` ref | editor-app.js | 3811 |
| `mailDefaultLang` computed | editor-app.js | 3822 |
| `mailWeddingDate` ref | editor-app.js | 3844 |
| `publicBase` constant | editor-app.js | 3801 |
| Variable resolution pattern | editor-app.js | 3950–3956 |
| `hw-guest-table` thead | editor-app.js | 4115–4123 |
| `hw-guest-table` tbody rows | editor-app.js | 4129–4155 |
| Empty state `colspan="6"` | editor-app.js | 4127 |
| Actions `<td>` (last column) | editor-app.js | 4143–4154 |
| Component return statement | editor-app.js | 4077–4085 |
| Existing WhatsApp button (dashboard) | editor-app.js | 2478 |

---

## Implementation Steps

### Step 1 — New Helper Function `guestWhatsAppText(guest)`

**Where:** Add after `mailPreviewHtml` computed (around line 3975), before return statement.

**What it does:**
1. Resolves correct language template for the guest
2. Strips HTML from body → plain text (DOM trick: `div.innerHTML + innerText`)
3. Replaces all `{{variables}}` with guest-specific values (plain text, no `escHtml`)
4. `{{rsvp_button}}` → replaced with raw RSVP URL (button HTML useless in WA)

```javascript
function guestWhatsAppText(guest) {
    const lang  = guest.language || mailDefaultLang.value;
    const tpl   = mailTemplates.value[lang]
               || mailTemplates.value[mailDefaultLang.value]
               || Object.values(mailTemplates.value)[0]
               || {};
    const token    = guest.token    || '';
    const siteLink = publicBase + '/?g=' + token;
    const rsvpLink = publicBase + '/?g=' + token + '&lang=' + lang;

    // Strip HTML to plain text for WhatsApp (no markup allowed)
    const tmp    = document.createElement('div');
    tmp.innerHTML = tpl.body || '';
    let body     = (tmp.innerText || tmp.textContent || '').trim();

    return body
        .replace(/\{\{name\}\}/g,                             guest.name          || '')
        .replace(/\{\{greeting\}\}|\{\{begrüssung\}\}/g,      guest.greeting      || '')
        .replace(/\{\{wedding_date\}\}|\{\{hochzeitsdatum\}\}/g, mailWeddingDate.value || '')
        .replace(/\{\{website_link\}\}|\{\{websitelink\}\}/g, siteLink)
        .replace(/\{\{rsvp_link\}\}/g,                        rsvpLink)
        .replace(/\{\{rsvp_button\}\}/g,                      rsvpLink);
}
```

**Closure access:** `mailTemplates`, `mailDefaultLang`, `mailWeddingDate`, `publicBase` are all in same component scope — no props needed.

---

### Step 2 — Export from Return Statement

Find component return statement (~line 4077–4085). Add `guestWhatsAppText` to exported object:

```javascript
// existing return adds:
guestWhatsAppText,
```

---

### Step 3 — Add Column Header to `<thead>`

At line 4122 (current empty `<th></th>` for actions), add new `<th>` BEFORE it:

```html
<th></th>  <!-- WhatsApp — icon only, no text label needed -->
<th></th>  <!-- Actions — existing -->
```

Or with title attribute:
```html
<th :title="t('guests_col_whatsapp')"></th>
```

---

### Step 4 — Add Column Cell to Each Row

After the RSVP `<td>` (line 4142) and BEFORE the actions `<td>` (line 4143):

```html
<td class="hw-guest-row__whatsapp" @click.stop>
    <a  :href="'https://wa.me/?text=' + encodeURIComponent(guestWhatsAppText(guest))"
        target="_blank"
        class="hw-album-action"
        :title="t('guests_whatsapp_share')">
        <i class="hgi-stroke hgi-whatsapp"></i>
    </a>
</td>
```

**Notes:**
- `@click.stop` prevents row-click opening edit modal
- `<a>` not `<button>` — navigates to external URL
- `hgi-whatsapp` — check if Hugeicons has this glyph; fallback: `hgi-share-08` or `hgi-message-01`
- Title uses lang key for accessibility

---

### Step 5 — Fix Empty State colspan

Line 4127: `colspan="6"` → `colspan="7"` (one new column added).

---

### Step 6 — Lang Keys

**`assets/lang/de.js`** — add:
```javascript
guests_col_whatsapp:    'WhatsApp',
guests_whatsapp_share:  'Via WhatsApp teilen',
```

**`assets/lang/en.js`** — add:
```javascript
guests_col_whatsapp:    'WhatsApp',
guests_whatsapp_share:  'Share via WhatsApp',
```

---

### Step 7 — CSS (if needed)

`hw-guest-row__whatsapp` likely needs no custom CSS — same width/behavior as actions column.  
If column too wide: add to stylesheet:
```css
.hw-guest-row__whatsapp { width: 40px; text-align: center; }
```

---

## Icon Availability Check

Before implementing, verify Hugeicons has `hgi-whatsapp`:
```
Grep for: hgi-whatsapp
In: assets/ or any icon reference file
```
If missing, use semantic fallback such as `hgi-share-08`, `hgi-send-02`, or `hgi-message-01`.

---

## Edge Cases

| Case | Handling |
|------|---------|
| `mailTemplates` empty (no email configured) | `tpl.body = ''` → WA text = variable-resolved empty string → link still valid, WA opens with empty/partial text |
| Guest has no `token` | `token = ''` → URL = `/?g=` → invalid but harmless; consider hiding button with `v-if="guest.token"` |
| Guest language not in `mailTemplates` | Falls back to `mailDefaultLang`, then first template — mirrors existing preview logic |
| `{{rsvp_button}}` in plain-text body | Replaced with raw `rsvpLink` URL — readable in WA |
| HTML entities in `innerText` result | `innerText` decodes entities automatically — no double-encoding issue |
| Long email body | WhatsApp URL has no official length limit but browsers/OS may truncate; typical email body fine |

---

## What NOT to Change

- No PHP changes needed
- No new API endpoints
- No changes to `Mailer.php` or email send flow
- No changes to dashboard WhatsApp button (separate, shares public URL)

---

## Verification

1. Open Editor → Gästeliste tab
2. Confirm new column visible with WhatsApp icon per row
3. Click icon on guest with full email template configured
4. Verify WhatsApp Web opens with:
   - `{{name}}` resolved to guest's actual name
   - `{{rsvp_link}}` resolved to `/?g={token}&lang={lang}`
   - No HTML tags in message
   - `{{rsvp_button}}` replaced with plain URL
5. Test guest with no token — button hidden or graceful empty
6. Test with DE and EN guests — correct language template selected
7. Verify row click still opens edit modal (WA cell click does NOT propagate)
8. Verify colspan=7 on empty state row when 0 guests
