--- phase: quick-001 plan: 01 type: execute wave: 1 depends_on: [] files_modified: - includes/class-notifications.php - includes/class-pages.php autonomous: true must_haves: truths: - "Logged-in providers visiting /anbieter-login/ see a logout option instead of login/registration forms" - "Admin submission email includes the job description text" - "Admin deactivation email shows the actual deactivation reason entered by the provider" - "Admin email edit/view links are clickable HTML hyperlinks" artifacts: - path: "includes/class-notifications.php" provides: "Fixed admin email templates with HTML links, job description, and deactivation reason timing fix" - path: "includes/class-pages.php" provides: "Login page with logged-in provider detection and logout option" key_links: - from: "includes/class-notifications.php" to: "ddhh_job_deactivated action" via: "Hook into ddhh_job_deactivated instead of transition_post_status for deactivation emails" pattern: "ddhh_job_deactivated" --- Fix 4 UX/notification issues discovered during Phase 7 testing: 1. Add logout option on login page for already-logged-in providers 2. Include job description in admin submission email 3. Fix deactivation reason not appearing in admin notification (timing bug) 4. Make admin email edit links clickable HTML hyperlinks Purpose: Polish UX and notification quality before production deployment. Output: Updated class-notifications.php and class-pages.php with all 4 fixes. @~/.claude/get-shit-done/workflows/execute-plan.md @~/.claude/get-shit-done/templates/summary.md @includes/class-notifications.php @includes/class-pages.php @includes/class-formidable.php (lines 700-765: deactivation handler showing meta save AFTER wp_update_post) @includes/class-acf-fields.php (lines 82-99: field name is job_deactivation_reason) Task 1: Fix login page for logged-in providers includes/class-pages.php The login page content is static HTML created during activation via `create_login_page()`. Since the page content includes `wp_login_form()` output baked in, we need a dynamic approach. Add a new method and hook to `DDHH_JM_Pages`: 1. Add a `setup_hooks()` static method that registers a `template_redirect` hook for the login page. 2. In the `template_redirect` callback (`maybe_redirect_logged_in_from_login`): - Check if current page is the login page (`get_option('ddhh_jm_login_page_id')`) - If user is logged in AND has `ddhh_provider` role: redirect to dashboard page (`get_option('ddhh_jm_dashboard_page_id')`) - If user is logged in but NOT a provider: do nothing (let them see the page as-is) - If user is not logged in: do nothing (show login/registration forms) 3. Register `setup_hooks()` call in the class. The main plugin orchestrator (`class-ddhh-job-manager.php`) calls static setup methods, so add `DDHH_JM_Pages::setup_hooks()` there if not already called, OR make `setup_hooks()` callable from the existing init pattern. NOTE: Check `class-ddhh-job-manager.php` for how Pages is initialized. If Pages has no `setup_hooks()` yet, add one and register it in the main plugin class `init_hooks()` method. This approach is simpler than modifying static page content - logged-in providers simply get redirected to their dashboard (where they already have a logout link). - Log in as provider, visit /anbieter-login/ -- should redirect to /anbieter-dashboard/ - Visit /anbieter-login/ while logged out -- should show login/registration forms normally - Grep for `maybe_redirect_logged_in_from_login` in class-pages.php confirms method exists Logged-in providers are redirected from login page to dashboard; non-logged-in users see login/registration forms as before Task 2: Fix all 3 admin email issues in notifications includes/class-notifications.php Three fixes in class-notifications.php: **Fix A: Add job description to admin submission email (`send_admin_new_job_notification_after_submit`)** After line 67 (where job_contact_email is fetched), add: ```php $job_description = $post->post_content; ``` In the email body sprintf, add a "Beschreibung:" section after the contact email line and before the submission date. Truncate to 500 characters with "..." suffix if longer, to keep emails readable: ```php $description_text = wp_strip_all_tags( $job_description ); if ( strlen( $description_text ) > 500 ) { $description_text = substr( $description_text, 0, 500 ) . '...'; } ``` Add `"Beschreibung:\n%s\n\n"` to the format string and `$description_text` as parameter. Also add job description to the EDIT notification (`send_admin_job_edit_notification_after_submit`) using the same pattern. **Fix B: Fix deactivation reason timing bug (`send_admin_job_deactivation_notification`)** ROOT CAUSE: The `transition_post_status` hook fires when `wp_update_post()` changes status to draft (class-formidable.php line 742). But the deactivation reason meta is saved AFTER that (line 756-758). So `get_post_meta($post->ID, 'job_deactivation_reason', true)` returns empty at notification time. SOLUTION: Change the deactivation notification to hook into `ddhh_job_deactivated` action instead of `transition_post_status`. The `ddhh_job_deactivated` action fires AFTER meta is saved (class-formidable.php line 764). In `setup_hooks()`: - REMOVE: `add_action( 'transition_post_status', array( __CLASS__, 'send_admin_job_deactivation_notification' ), 10, 3 );` - ADD: `add_action( 'ddhh_job_deactivated', array( __CLASS__, 'send_admin_job_deactivation_notification' ), 10, 2 );` Update `send_admin_job_deactivation_notification` method signature: - OLD: `( $new_status, $old_status, $post )` - NEW: `( $post_id, $entry_id )` Update method body: - Get post via `get_post( $post_id )` at the top - Remove the status transition checks (lines 233-240) since the action only fires on deactivation - Keep all the rest (meta retrieval, email building, sending) - The `get_post_meta( $post->ID, 'job_deactivation_reason', true )` will now work because meta is already saved **Fix C: Make admin email links clickable HTML hyperlinks** All three admin email methods use this pattern: ```php $headers = array( 'Content-Type: text/html; charset=UTF-8' ); $html_body = nl2br( esc_html( $body ) ); ``` The problem: `esc_html()` escapes the URL but does NOT wrap it in `` tags. The Content-Type says HTML but the links are plain text. For each of the three admin notification methods (`send_admin_new_job_notification_after_submit`, `send_admin_job_edit_notification_after_submit`, `send_admin_job_deactivation_notification`): Replace the plain text link pattern with proper HTML. Instead of building plain text and converting with nl2br(esc_html()), build the email body as proper HTML from the start: Change the email body construction to use HTML directly. Replace the plain text sprintf approach with an HTML template approach: - Use `
` instead of `\n` - Wrap the edit link in `
` tag: `Stellenangebot pruefen` - Remove the `nl2br( esc_html( $body ) )` conversion -- assign the HTML body directly - Use `esc_html()` on individual data values (job title, author name, etc.) but NOT on the entire body - Keep the `Content-Type: text/html; charset=UTF-8` header Example pattern for the link section: ```php '

Stellenangebot in WordPress bearbeiten' ```
- Grep class-notifications.php for `ddhh_job_deactivated` -- should appear in setup_hooks - Grep class-notifications.php for `transition_post_status` -- should only appear once (for mentor publish notification, NOT for deactivation) - Grep class-notifications.php for `esc_url.*edit_link` -- confirms links use esc_url in href attributes - Grep class-notifications.php for `Beschreibung` -- confirms job description added to email - Grep class-notifications.php for ` - Admin submission/edit emails include job description (truncated to 500 chars) - Deactivation notification hooks into ddhh_job_deactivated (fires after meta save) so reason is populated - All admin email links are clickable HTML hyperlinks using esc_url() in href attributes
After both tasks complete: 1. `grep -c 'ddhh_job_deactivated' includes/class-notifications.php` returns 1 (in setup_hooks) 2. `grep -c 'transition_post_status' includes/class-notifications.php` returns 1 (only mentor publish hook) 3. `grep -c ' - Logged-in providers are redirected away from /anbieter-login/ to dashboard - Admin submission emails contain the job description text - Admin deactivation emails display the actual deactivation reason (not "Kein Grund angegeben") - All admin email links are clickable HTML hyperlinks - No PHP syntax errors in modified files After completion, create `.planning/quick/001-fix-4-ux-notification-issues-from-phase/001-SUMMARY.md`