# Minijob Calculator Export Debugging Guide

**Last Updated:** 2025-12-30

## Overview

This guide helps debug export functionality issues in the Minijob calculator. The export system uses Alpine.js for click handlers and requires proper component scope and email gating.

## Simple Alpine.js Click Handler Pattern

**Solution**: The calculator uses a simple Alpine.js click handler pattern that matches the working `arbeitslosengeld_rechner.php` implementation:

- Simple `@click="exportPDF(); $event.stopPropagation()"` handlers in PHP
- No complex handler binding logic
- No `ensureExportHandlersBound()` function
- No x-init directives trying to bind handlers
- Simple email check: `if (!this.emailCollected) { this.showEmailModal = true; return; }`
- Direct export function calls

**Reference**: See `v2/pages/tools_arbeitslosengeld_rechner.php` and `v2/js/arbeitslosengeld/calculator.js` for the working pattern.

## Quick Debugging Steps

### 1. Check Browser Console

Open browser DevTools (F12) and check for JavaScript errors:

```javascript
// Check if Alpine.js is loaded
console.log("Alpine:", typeof Alpine);

// Check if component is registered
console.log("Component:", typeof Alpine?.data("minijobCalculator"));

// Check if functions exist
const mainElement = document.querySelector('main[x-data*="minijobCalculator"]');
if (mainElement?.__x?.$data) {
  console.log("exportPDF:", typeof mainElement.__x.$data.exportPDF);
  console.log("exportCSV:", typeof mainElement.__x.$data.exportCSV);
  console.log("mode:", mainElement.__x.$data.mode);
  console.log("showEmailModal:", mainElement.__x.$data.showEmailModal);
}
```

### 2. Test Click Handlers

Verify buttons are clickable and handlers are bound:

```javascript
// Find export buttons
const pdfButton = document.querySelector('button[title*="PDF"]');
const csvButton = document.querySelector('button[title*="CSV"]');

// Check if buttons exist and are visible
console.log("PDF button:", pdfButton);
console.log("PDF button visible:", pdfButton?.offsetParent !== null);
console.log("PDF button disabled:", pdfButton?.disabled);

// Check for Alpine handlers
console.log(
  "PDF button Alpine handler:",
  !!(pdfButton?.__x || pdfButton?._x_click)
);

// Check for @click attribute
console.log("PDF button has @click:", pdfButton?.innerHTML.includes("@click"));

// Manually trigger click
if (pdfButton) {
  pdfButton.click();
}

// Test direct function call
const mainEl = document.querySelector('main[x-data*="minijobCalculator"]');
if (mainEl?.__x?.$data?.exportPDF) {
  console.log("Calling exportPDF directly...");
  mainEl.__x.$data.exportPDF().catch((err) => console.error("Error:", err));
}
```

### 2a. Comprehensive Browser Test Script

Use the provided test script for comprehensive testing:

```javascript
// Copy and paste tests/minijob_export_browser_test.js into browser console
// This will test all aspects of the export functionality
```

### 3. Test Export Functions Directly

Call export functions directly from console:

```javascript
const mainElement = document.querySelector('main[x-data*="minijobCalculator"]');
if (mainElement?.__x?.$data) {
  const data = mainElement.__x.$data;

  // Test exportPDF
  data
    .exportPDF()
    .then(() => {
      console.log("PDF export completed");
    })
    .catch((err) => {
      console.error("PDF export error:", err);
    });

  // Test exportCSV
  data
    .exportCSV()
    .then(() => {
      console.log("CSV export completed");
    })
    .catch((err) => {
      console.error("CSV export error:", err);
    });
}
```

### 4. Check Email Modal State

Verify email modal can be shown:

```javascript
const mainElement = document.querySelector('main[x-data*="minijobCalculator"]');
if (mainElement?.__x?.$data) {
  const data = mainElement.__x.$data;

  // Check email collection status
  console.log("emailCollected:", data.emailCollected);
  console.log("showEmailModal:", data.showEmailModal);

  // Manually show modal
  data.showEmailModal = true;
  console.log("Modal should now be visible");
}
```

## Common Issues and Solutions

### Issue 1: Buttons Don't Respond to Clicks

**Symptoms:**

- Clicking export buttons does nothing
- No console errors
- No modal appears
- No console logs from export functions

**Possible Causes:**

1. Click handler syntax incorrect
2. Component not initialized
3. Buttons outside Alpine scope
4. `showResults` is false, so buttons are hidden
5. Email already collected, so export proceeds silently

**Solutions:**

1. **Verify showResults is true:**

   ```javascript
   const mainEl = document.querySelector('main[x-data*="minijobCalculator"]');
   console.log("showResults:", mainEl?.__x?.$data?.showResults);
   ```

2. **Check click handler syntax:**

   - ✅ Correct: `@click="exportPDF(); $event.stopPropagation()"`
   - ❌ Incorrect: `@click="exportPDF(mode, $event)"`
   - ❌ Incorrect: `@click.stop.prevent="exportPDF(mode, $event)"`

3. **Verify buttons are in Alpine scope:**

   - Buttons must be inside element with `x-data="minijobCalculator()"`
   - Check parent elements for `x-data` attribute
   - Verify results section is inside main element

4. **Check if handlers are bound:**

   ```javascript
   const pdfButton = document.querySelector('button[title*="PDF"]');
   console.log(
     "PDF button Alpine handler:",
     !!(pdfButton?.__x || pdfButton?._x_click)
   );
   ```

5. **Manual test - call function directly:**

   ```javascript
   const mainEl = document.querySelector('main[x-data*="minijobCalculator"]');
   if (mainEl?.__x?.$data?.exportPDF) {
     mainEl.__x.$data.exportPDF().catch((err) => console.error("Error:", err));
   }
   ```

6. **Verify component initialization:**

   ```javascript
   const mainEl = document.querySelector('main[x-data*="minijobCalculator"]');
   console.log("Component:", mainEl?.__x?.$data);
   console.log("exportPDF function:", typeof mainEl?.__x?.$data?.exportPDF);
   ```

### Issue 2: Email Modal Doesn't Appear

**Symptoms:**

- Clicking export button doesn't show email modal
- No errors in console
- `showEmailModal` is false

**Possible Causes:**

1. Email already collected (check localStorage)
2. Alpine reactivity not working
3. Modal element hidden or not in DOM

**Solutions:**

1. **Clear email from localStorage:**

   ```javascript
   localStorage.removeItem("ordio_email_Minijob-Rechner");
   localStorage.removeItem("ordio_email_collected_Minijob-Rechner");
   ```

2. **Check Alpine reactivity:**

   ```javascript
   const mainElement = document.querySelector(
     'main[x-data*="minijobCalculator"]'
   );
   if (mainElement?.__x?.$data) {
     const data = mainElement.__x.$data;
     data.showEmailModal = true;
     // Check if modal appears
     setTimeout(() => {
       const modal = document.querySelector('[x-show*="showEmailModal"]');
       console.log("Modal visible:", modal?.offsetParent !== null);
     }, 100);
   }
   ```

3. **Verify modal element exists:**
   ```javascript
   const modal = document.querySelector('[x-show*="showEmailModal"]');
   console.log("Modal element:", modal);
   console.log("Modal in DOM:", document.body.contains(modal));
   ```

### Issue 3: Export Functions Not Found

**Symptoms:**

- Console error: "exportPDF is not a function"
- Functions undefined in Alpine scope

**Possible Causes:**

1. JavaScript file not loaded
2. Component not initialized
3. Function not defined in component

**Solutions:**

1. **Check if JavaScript file loaded:**

   ```javascript
   console.log("window.minijobCalculator:", typeof window.minijobCalculator);
   ```

2. **Verify component initialization:**

   ```javascript
   const mainElement = document.querySelector(
     'main[x-data*="minijobCalculator"]'
   );
   console.log("Alpine instance:", mainElement?.__x);
   console.log("Component data:", mainElement?.__x?.$data);
   ```

3. **Check function definitions:**
   - Open `v2/js/minijob/calculator.js`
   - Verify `exportPDF` and `exportCSV` are defined in component object
   - Check for syntax errors

### Issue 4: Wrong Mode Exported

**Symptoms:**

- Export contains data from wrong mode
- Mode parameter incorrect

**Possible Causes:**

1. Using parameter instead of `this.mode`
2. Mode changed between click and export

**Solutions:**

1. **Verify function uses `this.mode`:**

   ```javascript
   // In exportPDF function, should use:
   const mode = this.mode; // ✅ Correct

   // NOT:
   async exportPDF(mode) { // ❌ Incorrect
   ```

2. **Check current mode:**
   ```javascript
   const mainElement = document.querySelector(
     'main[x-data*="minijobCalculator"]'
   );
   if (mainElement?.__x?.$data) {
     console.log("Current mode:", mainElement.__x.$data.mode);
   }
   ```

### Issue 5: Module Not Found Errors

**Symptoms:**

- Error: "Export-Modul konnte nicht geladen werden"
- `window.MinijobExport` is undefined

**Possible Causes:**

1. Export module not loaded
2. Script loading order incorrect
3. Module file missing

**Solutions:**

1. **Check if module exists:**

   ```javascript
   console.log("MinijobExport:", typeof window.MinijobExport);
   ```

2. **Verify script loading order:**

   - Constants → Utils → Helpers → Calculator → Export
   - Check Network tab for failed requests

3. **Manually load module:**
   ```javascript
   const script = document.createElement("script");
   script.src = "/v2/js/minijob/export.min.js";
   document.head.appendChild(script);
   ```

## Testing Checklist

### Basic Functionality

- [ ] Click PDF button → Email modal appears (new user)
- [ ] Click CSV button → Email modal appears (new user)
- [ ] Submit email → Export downloads
- [ ] Click PDF button again → Export downloads immediately (email collected)
- [ ] Click CSV button again → Export downloads immediately (email collected)

### All Modes

- [ ] Basic mode: PDF export works
- [ ] Basic mode: CSV export works
- [ ] Advanced mode: PDF export works
- [ ] Advanced mode: CSV export works
- [ ] Employer mode: PDF export works
- [ ] Employer mode: CSV export works
- [ ] Vacation mode: PDF export works
- [ ] Vacation mode: CSV export works

### Edge Cases

- [ ] Export without calculation → Error message shown
- [ ] Export with missing module → Error message shown
- [ ] Export with network error → Error message shown
- [ ] Mode switch during export → Correct mode exported
- [ ] Multiple rapid clicks → Only one export triggered

## Debugging Script

Run this complete debugging script in browser console:

```javascript
(function () {
  console.log("=== Minijob Export Debug ===");

  // 1. Check Alpine.js
  console.log(
    "1. Alpine.js:",
    typeof Alpine !== "undefined" ? "✓ Loaded" : "✗ Not loaded"
  );

  // 2. Check component
  const mainElement = document.querySelector(
    'main[x-data*="minijobCalculator"]'
  );
  console.log("2. Main element:", mainElement ? "✓ Found" : "✗ Not found");

  if (mainElement?.__x?.$data) {
    const data = mainElement.__x.$data;
    console.log("3. Functions:");
    console.log("   - exportPDF:", typeof data.exportPDF);
    console.log("   - exportCSV:", typeof data.exportCSV);
    console.log("   - mode:", data.mode);
    console.log("   - showEmailModal:", data.showEmailModal);
    console.log("   - emailCollected:", data.emailCollected);

    // 4. Check buttons
    const pdfButton = document.querySelector('button[title*="PDF"]');
    const csvButton = document.querySelector('button[title*="CSV"]');
    console.log("4. Buttons:");
    console.log("   - PDF button:", pdfButton ? "✓ Found" : "✗ Not found");
    console.log("   - CSV button:", csvButton ? "✓ Found" : "✗ Not found");
    console.log("   - PDF visible:", pdfButton?.offsetParent !== null);
    console.log("   - CSV visible:", csvButton?.offsetParent !== null);

    // 5. Check modules
    console.log("5. Modules:");
    console.log("   - MinijobExport:", typeof window.MinijobExport);
    console.log("   - OrdioEmailModal:", typeof window.OrdioEmailModal);

    // 6. Test function call
    console.log("6. Testing exportPDF...");
    try {
      data.exportPDF();
      console.log("   ✓ Function called successfully");
    } catch (error) {
      console.error("   ✗ Error:", error);
    }
  } else {
    console.log("3. Component data: ✗ Not accessible");
  }

  console.log("=== Debug Complete ===");
})();
```

## Reference Files

- **Calculator Component**: `v2/js/minijob/calculator.js`
- **Export Module**: `v2/js/minijob/export.js`
- **Page Template**: `v2/pages/tools_minijob_rechner.php`
- **Working Reference**: `v2/js/tools-midijob-calculator.js` (lines 398-437)

## Best Practices

1. **Always use `this.mode`** instead of parameters in export functions
2. **Use simple click handlers**: `@click="exportPDF(); $event.stopPropagation()"` - match the arbeitslosengeld pattern
3. **Check email collection** before showing modal: `if (!this.emailCollected) { this.showEmailModal = true; return; }`
4. **Handle errors gracefully** with user-friendly messages
5. **Log errors** for debugging but don't expose internals to users
6. **Test all modes** after making changes
7. **Verify minified files** are updated after code changes
8. **Keep it simple**: Don't over-engineer handler binding - Alpine.js handles `x-show` correctly with simple click handlers
9. **Reference working examples**: Use `arbeitslosengeld_rechner.php` as a reference for the correct pattern
10. **No complex handler binding**: Avoid `ensureExportHandlersBound()`, `x-init` directives, and complex lifecycle hooks

## Simple Alpine.js Click Handler Pattern

When using Alpine.js with `x-show` and click handlers:

1. **Use simple click handlers**: `@click="exportPDF(); $event.stopPropagation()"` - Alpine.js handles `x-show` correctly
2. **No complex binding logic**: Alpine.js automatically binds handlers when elements become visible
3. **Simple email check**: Check `this.emailCollected` directly, no complex fallback logic needed
4. **Reference working examples**: See `v2/pages/tools_arbeitslosengeld_rechner.php` for the correct pattern
5. **Test thoroughly**: Always test with elements initially hidden by `x-show` - Alpine.js handles this correctly

## Browser Testing Checklist

### Pre-Testing Setup

- [ ] Clear browser cache
- [ ] Clear localStorage for email collection
- [ ] Open DevTools Console
- [ ] Check for JavaScript errors

### Component Initialization

- [ ] Verify Alpine.js loads: `typeof Alpine !== 'undefined'`
- [ ] Check component registration: Look for `[Minijob] Component registered with Alpine.js`
- [ ] Verify component init: Component checks for stored email in `init()` hook

### Calculation & Results Display

- [ ] Enter calculation value (e.g., 556 in Basic mode)
- [ ] Verify results appear automatically (no "Berechnen" button needed)
- [ ] Verify `showResults` becomes `true`
- [ ] Verify buttons are visible in DOM

### Export Button Testing

- [ ] Verify PDF button exists and is visible
- [ ] Verify CSV button exists and is visible
- [ ] Click PDF button
- [ ] Verify email modal appears (if email not collected)
- [ ] Click CSV button
- [ ] Verify email modal appears (if email not collected)

### Email Modal Testing

- [ ] Clear email from localStorage
- [ ] Click export button
- [ ] Verify email modal appears
- [ ] Enter email and submit
- [ ] Verify export downloads
- [ ] Click export button again
- [ ] Verify export downloads immediately (no modal)

### All Modes Testing

- [ ] Test Basic mode exports (PDF and CSV)
- [ ] Test Advanced mode exports (PDF and CSV)
- [ ] Test Employer mode exports (PDF and CSV)
- [ ] Test Vacation mode exports (PDF and CSV)
