2026-06-07 14:59:12 +00:00

966 lines
71 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Plugin Name: WAX MVP
* Description: WAX AI-native learning MVP: premium landing styles, profile/course UI helpers, and AI Career Coach submissions.
* Version: 0.1.6
*/
if (!defined('ABSPATH')) { exit; }
define('MATTHEW_LMS_MVP_VERSION', '0.1.6');
add_action('init', function () {
register_post_type('mlms_coach_request', [
'labels' => [
'name' => 'Career Coach Requests',
'singular_name' => 'Career Coach Request',
'menu_name' => 'Career Coach Leads',
'add_new_item' => 'Add Career Coach Request',
'edit_item' => 'Review Career Coach Request',
],
'public' => false,
'show_ui' => true,
'show_in_menu' => true,
'menu_icon' => 'dashicons-welcome-learn-more',
'supports' => ['title', 'editor', 'custom-fields'],
'capability_type' => 'post',
]);
register_post_type('mlms_onboard', [
'labels' => [
'name' => 'Onboarding Profiles',
'singular_name' => 'Onboarding Profile',
'menu_name' => 'WAX Onboarding',
'add_new_item' => 'Add Onboarding Profile',
'edit_item' => 'Review Onboarding Profile',
],
'public' => false,
'show_ui' => true,
'show_in_menu' => true,
'menu_icon' => 'dashicons-id-alt',
'supports' => ['title', 'editor', 'custom-fields'],
'capability_type' => 'post',
]);
});
add_action('wp_enqueue_scripts', function () {
wp_register_style('matthew-lms-mvp', false, [], MATTHEW_LMS_MVP_VERSION);
wp_enqueue_style('matthew-lms-mvp');
wp_add_inline_style('matthew-lms-mvp', matthew_lms_mvp_css());
wp_register_script('matthew-lms-mvp-onboarding', false, [], MATTHEW_LMS_MVP_VERSION, true);
wp_enqueue_script('matthew-lms-mvp-onboarding');
wp_add_inline_script('matthew-lms-mvp-onboarding', matthew_lms_mvp_js());
});
add_action('wp_head', function () {
$_SERVER['PROJECT_DESCRIPTION'] = 'WAX helps non-technical professionals become fluent in AI-powered work through guided lessons, practical workflows, and shareable credentials.';
}, 0);
add_action('template_redirect', 'matthew_lms_mvp_maybe_handle_login_submission');
add_action('template_redirect', 'matthew_lms_mvp_maybe_handle_google_oauth_callback');
add_filter('body_class', function ($classes) {
if (is_page(['home', 'career-coach', 'platform', 'sign-up', 'log-in'])) {
$classes[] = 'mlms-wax-page';
}
return $classes;
});
add_filter('render_block', function ($block_content, $block) {
if (($block['blockName'] ?? '') === 'core/template-part') {
$slug = $block['attrs']['slug'] ?? '';
if ($slug === 'header') {
return matthew_lms_mvp_render_header();
}
if ($slug === 'footer') {
return matthew_lms_mvp_render_footer();
}
}
return $block_content;
}, 10, 2);
function matthew_lms_mvp_public_url(string $path = ''): string {
$host = sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'] ?? ''));
if ($host && !in_array($host, ['localhost', '127.0.0.1'], true)) {
$scheme = is_ssl() ? 'https' : 'http';
return $scheme . '://' . $host . '/' . ltrim($path, '/');
}
return home_url('/' . ltrim($path, '/'));
}
function matthew_lms_mvp_render_header(): string {
$links = [
'Home' => matthew_lms_mvp_public_url(),
'WAX Coach' => matthew_lms_mvp_public_url('career-coach/'),
'Platform' => matthew_lms_mvp_public_url('platform/'),
];
$login_url = add_query_arg('redirect_to', rawurlencode(matthew_lms_mvp_public_url('platform/')), matthew_lms_mvp_public_url('log-in/'));
ob_start();
?>
<header class="mlms-site-header" role="banner">
<div class="mlms-shell mlms-site-header-inner">
<a class="mlms-header-brand" href="<?php echo esc_url(matthew_lms_mvp_public_url()); ?>" aria-label="WAX home">WAX</a>
<nav class="mlms-header-nav" aria-label="WAX main navigation">
<?php foreach ($links as $label => $url): ?>
<a href="<?php echo esc_url($url); ?>"><?php echo esc_html($label); ?></a>
<?php endforeach; ?>
</nav>
<div class="mlms-header-actions">
<a class="mlms-header-login" href="<?php echo esc_url($login_url); ?>">Login</a>
<a class="mlms-btn mlms-btn-primary mlms-header-signup" href="<?php echo esc_url(matthew_lms_mvp_public_url('sign-up/')); ?>">Sign Up</a>
</div>
</div>
</header>
<?php
return ob_get_clean();
}
function matthew_lms_mvp_render_footer(): string {
$links = [
'Career Coach' => matthew_lms_mvp_public_url('career-coach/'),
'Platform' => matthew_lms_mvp_public_url('platform/'),
'Log In' => matthew_lms_mvp_public_url('log-in/'),
'Sign Up' => matthew_lms_mvp_public_url('sign-up/'),
];
ob_start();
?>
<footer class="mlms-site-footer" role="contentinfo">
<div class="mlms-shell mlms-site-footer-inner">
<div>
<a class="mlms-footer-brand" href="<?php echo esc_url(matthew_lms_mvp_public_url()); ?>">WAX</a>
<p>AI-native work training for modern teams.</p>
</div>
<nav class="mlms-footer-links" aria-label="WAX footer navigation">
<?php foreach ($links as $label => $url): ?>
<a href="<?php echo esc_url($url); ?>"><?php echo esc_html($label); ?></a>
<?php endforeach; ?>
</nav>
</div>
</footer>
<?php
return ob_get_clean();
}
function matthew_lms_mvp_css(): string {
return <<<'CSS'
:root{
--mlms-ink:#0A2540;
--mlms-navy:#0A2540;
--mlms-deep:#07182D;
--mlms-muted:#425466;
--mlms-soft:#697386;
--mlms-bg:#F6F9FC;
--mlms-surface:#FFFFFF;
--mlms-line:#E6ECF2;
--mlms-wax:#D7D0FF;
--mlms-amber:#EEEAFE;
--mlms-violet:#635BFF;
--mlms-primary:#635BFF;
--mlms-primary-dark:#5548E8;
--mlms-primary-soft:#F1EFFF;
--mlms-cyan:#A7B6FF;
--mlms-pink:#B9A8FF;
--mlms-green:#21C58E;
--mlms-radius:24px;
--mlms-shadow:0 30px 80px rgba(50,50,93,.14),0 16px 36px rgba(0,0,0,.08);
--mlms-shadow-soft:0 18px 45px rgba(50,50,93,.10),0 8px 18px rgba(0,0,0,.06);
}
html{scroll-behavior:smooth}
body{
background:
radial-gradient(circle at 74% -10%,rgba(99,91,255,.13),transparent 32%),
linear-gradient(180deg,#fff 0%,var(--mlms-bg) 48%,#fff 100%);
color:var(--mlms-ink);
font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
}
.wp-site-blocks{overflow:hidden;background:transparent}
.wp-site-blocks>.wp-block-template-part:first-child{position:relative;z-index:20}
.wp-block-site-title a,.wp-block-navigation a{color:var(--mlms-ink);text-decoration:none!important}
.wp-block-site-title a{font-weight:900;letter-spacing:-.05em}
.wp-block-navigation a{font-weight:760;color:#31445B}
.mlms-site-header{position:sticky;top:0;z-index:50;background:rgba(255,255,255,.82);border-bottom:1px solid rgba(10,37,64,.08);backdrop-filter:blur(18px)}
.mlms-site-header-inner{min-height:74px;display:flex;align-items:center;justify-content:space-between;gap:24px}
.mlms-header-brand{color:var(--mlms-ink);font-weight:950;font-size:26px;letter-spacing:-.06em;text-decoration:none!important;line-height:1}
.mlms-header-nav{display:flex;align-items:center;justify-content:center;gap:26px;flex:1}
.mlms-header-nav a,.mlms-header-login{color:#31445B;text-decoration:none!important;font-weight:800;font-size:15px;line-height:1}
.mlms-header-nav a:hover,.mlms-header-login:hover{color:var(--mlms-primary)}
.mlms-header-actions{display:flex;align-items:center;justify-content:flex-end;gap:12px}
.mlms-header-login{padding:11px 14px;border-radius:999px;background:#fff;border:1px solid rgba(10,37,64,.10);box-shadow:0 6px 16px rgba(50,50,93,.06)}
.mlms-header-signup{min-height:40px;padding:11px 16px;font-size:15px;box-shadow:0 10px 24px rgba(99,91,255,.20)}
body.page-id-47 .wp-block-post-title,body.page-id-48 .wp-block-post-title,body.page-id-49 .wp-block-post-title,body.page-id-50 .wp-block-post-title,.mlms-wax-page .wp-block-post-title{display:none!important}
.entry-content{margin-top:0}.entry-content a{text-decoration:none}
.entry-content>.mlms-page,.wp-block-post-content>.mlms-page{max-width:none!important;width:100%!important;margin-left:0!important;margin-right:0!important}
.mlms-page{font-size:18px;line-height:1.65;position:relative;color:var(--mlms-ink)}
.mlms-page:before{
content:"";position:absolute;z-index:0;left:-12vw;right:-12vw;top:42px;height:420px;
background:linear-gradient(110deg,rgba(99,91,255,.72),rgba(236,233,255,.9));
transform:skewY(-7deg);transform-origin:0 0;border-radius:0 0 52px 52px;opacity:.11;pointer-events:none;
}
.mlms-page *{box-sizing:border-box}.mlms-page>section{position:relative;z-index:1}
.mlms-shell{max-width:1120px;margin:0 auto;padding:0 24px}
.mlms-pill{
display:inline-flex;gap:8px;align-items:center;border:1px solid rgba(99,91,255,.18);
background:rgba(255,255,255,.74);backdrop-filter:blur(16px);color:#4F46E5;
padding:8px 13px;border-radius:999px;font-size:13px;font-weight:820;letter-spacing:.01em;
box-shadow:0 8px 22px rgba(50,50,93,.08);
}
.mlms-hero{position:relative;padding:104px 0 70px}
.mlms-hero-grid{display:grid;grid-template-columns:minmax(0,1.02fr) minmax(360px,.98fr);gap:52px;align-items:center}
.mlms-eyebrow{margin-bottom:22px}.mlms-h1{font-size:clamp(54px,7.8vw,92px);line-height:.94;letter-spacing:-.075em;margin:0 0 24px;color:var(--mlms-ink);font-weight:900;max-width:780px}
.mlms-gradient-text{background:linear-gradient(100deg,#3D2A8F 0%,var(--mlms-primary) 48%,#897DFF 100%);-webkit-background-clip:text;background-clip:text;color:transparent}
.mlms-lede{max-width:680px;font-size:clamp(20px,2.2vw,24px);line-height:1.48;color:var(--mlms-muted);margin:0 0 30px;font-weight:520}
.mlms-actions{display:flex;flex-wrap:wrap;gap:12px;margin:26px 0}.mlms-btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:10px;border-radius:999px;padding:12px 18px;font-weight:850;border:1px solid transparent;transition:transform .18s ease,box-shadow .18s ease,background .18s ease;color:inherit;min-height:46px;line-height:1.15;text-decoration:none!important}.mlms-btn:hover{transform:translateY(-2px)}
.mlms-btn-primary{background:var(--mlms-primary);color:#fff;box-shadow:0 14px 34px rgba(99,91,255,.24)}
.mlms-btn-primary:hover{background:var(--mlms-primary-dark)}
.mlms-btn-secondary{background:#fff;color:#33425F;border-color:rgba(10,37,64,.10);box-shadow:0 10px 26px rgba(50,50,93,.08)}
.mlms-btn-wax{background:var(--mlms-primary);color:#fff;box-shadow:0 14px 34px rgba(99,91,255,.24)}
.mlms-btn-wax:hover{background:var(--mlms-primary-dark)}
.mlms-site-header .mlms-header-signup{min-height:40px;padding:11px 16px;font-size:15px;box-shadow:0 10px 24px rgba(99,91,255,.20)}
.wp-element-button,.wp-block-button__link{background:var(--mlms-primary);color:#fff;border-radius:999px;box-shadow:0 12px 28px rgba(99,91,255,.22)}
.mlms-trust{display:flex;flex-wrap:wrap;gap:16px;color:var(--mlms-muted);font-size:14px;margin-top:22px}.mlms-trust span{display:inline-flex;align-items:center;gap:8px;font-weight:650}.mlms-trust span:before{content:"";width:8px;height:8px;border-radius:999px;background:var(--mlms-primary)}
.mlms-ai-card{position:relative;min-height:560px;border:1px solid rgba(255,255,255,.88);background:rgba(255,255,255,.78);backdrop-filter:blur(18px);border-radius:30px;box-shadow:var(--mlms-shadow);padding:20px;overflow:hidden}.mlms-ai-card:before{content:"";position:absolute;inset:-90px -70px auto auto;width:320px;height:320px;border-radius:50%;background:radial-gradient(circle,rgba(99,91,255,.18),transparent 65%);filter:blur(10px)}.mlms-ai-card:after{content:"";position:absolute;left:-100px;bottom:-95px;width:330px;height:330px;border-radius:50%;background:radial-gradient(circle,rgba(10,37,64,.08),transparent 68%)}
.mlms-card-top{position:relative;z-index:1;display:flex;justify-content:space-between;align-items:center;margin-bottom:18px}.mlms-signal{display:flex;gap:7px;align-items:end}.mlms-signal i{display:block;width:8px;border-radius:99px;background:linear-gradient(#A7A1FF,var(--mlms-primary));animation:mlmsPulse 1.9s ease-in-out infinite}.mlms-signal i:nth-child(1){height:16px}.mlms-signal i:nth-child(2){height:27px;animation-delay:.16s}.mlms-signal i:nth-child(3){height:39px;animation-delay:.32s}
.mlms-dashboard{position:relative;z-index:1;background:linear-gradient(160deg,#0A2540 0%,#132747 58%,#1B1744 100%);color:#fff;border-radius:24px;padding:25px;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08),0 18px 45px rgba(10,37,64,.22)}.mlms-dashboard:before{content:"";position:absolute;top:-1px;left:22px;right:22px;height:3px;border-radius:0 0 99px 99px;background:var(--mlms-primary)}.mlms-dashboard h3{font-size:19px;margin:0 0 4px;color:#fff}.mlms-dashboard p{margin:0;color:#AFC0D4}
.mlms-orbs{display:flex;gap:12px;margin:28px 0}.mlms-orb{width:56px;height:56px;border-radius:18px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.07);position:relative;transform:rotate(-6deg)}.mlms-orb.earned{background:linear-gradient(135deg,#fff,#AFA9FF 24%,var(--mlms-primary) 72%);box-shadow:0 0 24px rgba(99,91,255,.32)}.mlms-orb.current{background:linear-gradient(135deg,#fff,#C9C4FF 24%,var(--mlms-primary) 72%);box-shadow:0 0 26px rgba(99,91,255,.34);animation:mlmsGlow 2.4s ease-in-out infinite}
.mlms-phase{display:flex;justify-content:space-between;gap:16px;align-items:center;padding:15px 16px;border-radius:17px;background:rgba(255,255,255,.075);border:1px solid rgba(255,255,255,.09);margin-top:12px}.mlms-phase strong{display:block}.mlms-phase small{color:#AFC0D4}.mlms-lock{font-size:12px;color:#C9C4FF;font-weight:900;letter-spacing:.04em}
.mlms-coach-preview{position:relative;z-index:2;margin:-30px 18px 0 auto;max-width:370px;background:#fff;border:1px solid var(--mlms-line);border-radius:22px;padding:19px;box-shadow:var(--mlms-shadow-soft);color:#31445B}.mlms-coach-preview b{color:var(--mlms-violet)}
.mlms-section{padding:64px 0}.mlms-section-head{display:flex;justify-content:space-between;align-items:end;gap:24px;margin-bottom:27px}.mlms-kicker{color:var(--mlms-violet);font-weight:900;text-transform:uppercase;font-size:12px;letter-spacing:.14em;margin:0 0 10px}.mlms-h2{font-size:clamp(34px,4.5vw,58px);line-height:1.02;letter-spacing:-.052em;margin:0;color:var(--mlms-ink);font-weight:900}.mlms-section-copy{max-width:560px;color:var(--mlms-muted);margin:12px 0 0;font-weight:520}.mlms-grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.mlms-feature,.mlms-panel,.mlms-testimonial,.mlms-brand-card,.mlms-form-card,.mlms-profile-card,.mlms-course-card{background:rgba(255,255,255,.88);border:1px solid rgba(10,37,64,.09);border-radius:var(--mlms-radius);box-shadow:var(--mlms-shadow-soft);padding:26px}.mlms-feature,.mlms-testimonial,.mlms-panel,.mlms-course-card{position:relative;overflow:hidden}.mlms-feature:before,.mlms-testimonial:before,.mlms-course-card:before{content:"";position:absolute;left:0;right:0;top:0;height:3px;background:var(--mlms-primary);opacity:.55}.mlms-feature-number{width:42px;height:42px;border-radius:14px;background:var(--mlms-primary-soft);color:var(--mlms-primary);display:flex;align-items:center;justify-content:center;font-weight:950;margin-bottom:38px}.mlms-feature h3,.mlms-panel h3,.mlms-testimonial h3,.mlms-brand-card h3{margin:0 0 10px;font-size:22px;color:var(--mlms-ink);letter-spacing:-.026em}.mlms-feature p,.mlms-panel p,.mlms-testimonial p,.mlms-brand-card p{color:var(--mlms-muted);margin:0}
.mlms-coach-band{background:linear-gradient(145deg,#0A2540 0%,#172B4D 58%,#211B54 100%);color:#fff;border-radius:30px;padding:38px;display:grid;grid-template-columns:1fr 380px;gap:28px;align-items:center;box-shadow:var(--mlms-shadow);position:relative;overflow:hidden}.mlms-coach-band:before{content:"";position:absolute;left:-120px;top:-160px;width:440px;height:320px;background:linear-gradient(120deg,rgba(99,91,255,.42),rgba(255,255,255,.12));filter:blur(20px);transform:rotate(-12deg)}.mlms-coach-band:after{content:"";position:absolute;right:-90px;top:-120px;width:320px;height:320px;border-radius:50%;background:radial-gradient(circle,rgba(99,91,255,.20),transparent 68%)}.mlms-coach-band>*{position:relative;z-index:1}.mlms-coach-band h2{color:#fff}.mlms-coach-band p{color:#CFD9E7}.mlms-coach-band .mlms-kicker{color:#C9C4FF}.mlms-mini-output{position:relative;z-index:1;background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.17);border-radius:22px;padding:20px;backdrop-filter:blur(12px)}.mlms-mini-output div{padding:12px 0;border-bottom:1px solid rgba(255,255,255,.13)}.mlms-mini-output div:last-child{border-bottom:0}
.mlms-brand-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px}.mlms-brand-card.wax{background:linear-gradient(135deg,#FFFFFF,var(--mlms-primary-soft));border-color:#DCD8FF}.mlms-swatches{display:flex;gap:10px;margin-top:20px}.mlms-swatch{width:44px;height:44px;border-radius:14px;border:3px solid rgba(255,255,255,.55)}
.mlms-form-card{max-width:880px;margin:0 auto}.mlms-form-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}.mlms-field{display:flex;flex-direction:column;gap:7px;margin-bottom:16px}.mlms-field label{font-weight:850;color:var(--mlms-ink);font-size:15px}.mlms-field input,.mlms-field textarea,.mlms-field select{width:100%;border:1px solid #D9E2EC;border-radius:14px;padding:14px 16px;background:#fff;color:var(--mlms-ink);font:inherit;box-shadow:0 1px 1px rgba(0,0,0,.02)}.mlms-field input:focus,.mlms-field textarea:focus,.mlms-field select:focus{outline:0;border-color:var(--mlms-violet);box-shadow:0 0 0 4px rgba(99,91,255,.12)}.mlms-field textarea{min-height:130px}.mlms-help{font-size:14px;color:var(--mlms-soft);margin:0 0 18px}.mlms-notice{border-radius:20px;padding:18px 20px;margin:0 0 22px;border:1px solid rgba(33,197,142,.26);background:#ECFBF6;color:#0B5D45}.mlms-ai-output{white-space:pre-wrap;background:linear-gradient(145deg,#0A2540,#172B4D);color:#EAF3FF;border-radius:22px;padding:24px;line-height:1.55;margin-top:20px;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08)}
.mlms-steps{display:flex;gap:8px;margin-bottom:24px}.mlms-step{height:8px;flex:1;border-radius:999px;background:#DDE6F0}.mlms-step.active{background:var(--mlms-primary)}.mlms-role-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}.mlms-role{border:1px solid #DDE6F0;border-radius:18px;padding:18px;background:#fff;font-weight:850;box-shadow:0 8px 20px rgba(50,50,93,.05)}.mlms-profile-hero{display:grid;grid-template-columns:1fr 1.2fr;gap:20px;align-items:stretch}.mlms-avatar{width:88px;height:88px;border-radius:26px;background:linear-gradient(135deg,#3D2A8F,var(--mlms-primary));box-shadow:0 14px 34px rgba(99,91,255,.22);margin-bottom:18px;transform:rotate(-4deg)}.mlms-nodes{display:flex;gap:14px;flex-wrap:wrap;margin:20px 0}.mlms-node{width:70px;height:70px;border-radius:18px;background:#F2F6FA;border:1px solid #DDE6F0;display:grid;place-items:center;color:#6F7F90;font-weight:950;transform:rotate(-5deg)}.mlms-node.earned{color:#fff;background:linear-gradient(135deg,#AFA9FF,var(--mlms-primary));box-shadow:0 0 24px rgba(99,91,255,.30)}.mlms-node.next{color:#fff;background:linear-gradient(135deg,#C9C4FF,var(--mlms-primary));box-shadow:0 0 24px rgba(99,91,255,.28)}.mlms-path{display:grid;gap:14px}.mlms-course-card{display:grid;grid-template-columns:auto 1fr auto;gap:16px;align-items:center}.mlms-course-index{width:48px;height:48px;border-radius:15px;display:grid;place-items:center;background:var(--mlms-primary-soft);color:var(--mlms-primary);font-weight:950}.mlms-course-card.locked{opacity:.75}.mlms-footer-cta{text-align:center;padding:76px 24px 96px}.mlms-sample-label{font-size:12px;text-transform:uppercase;letter-spacing:.12em;color:#6C7F91;font-weight:900}.mlms-admin-link{font-size:14px;color:#697386;margin-top:18px}.mlms-admin-link a{color:var(--mlms-violet);font-weight:800}
.mlms-onboarding-hero{padding:76px 0 64px}.mlms-login-grid{display:grid;grid-template-columns:minmax(0,.92fr) minmax(360px,480px);gap:34px;align-items:start}.mlms-login-card{position:relative;overflow:hidden}.mlms-login-card:before{content:"";position:absolute;inset:0 0 auto 0;height:4px;background:var(--mlms-primary);opacity:.9}.mlms-login-card h2{font-size:clamp(30px,3vw,42px);line-height:1.04;letter-spacing:-.045em;margin:0 0 10px;color:var(--mlms-ink)}.mlms-login-card>p{color:var(--mlms-muted);margin:0 0 22px}.mlms-login-actions{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin:2px 0 18px}.mlms-checkbox{display:inline-flex;align-items:center;gap:9px;font-weight:750;color:var(--mlms-muted);font-size:14px}.mlms-checkbox input{width:18px;height:18px;accent-color:var(--mlms-primary)}.mlms-login-link{font-size:14px;font-weight:850;color:var(--mlms-primary);text-decoration:none!important}.mlms-login-link:hover{color:var(--mlms-primary-dark)}.mlms-login-submit{width:100%;border:0;cursor:pointer}.mlms-login-footnote{margin:18px 0 0;color:var(--mlms-muted);font-size:15px;text-align:center}.mlms-login-footnote a{color:var(--mlms-primary);font-weight:850;text-decoration:none!important}.mlms-signup-grid{display:grid;grid-template-columns:minmax(0,.9fr) minmax(420px,1fr);gap:34px;align-items:start}.mlms-onboarding-copy{padding-top:20px}.mlms-onboarding-card{position:relative;overflow:hidden}.mlms-onboarding-card:before{content:"";position:absolute;inset:0 0 auto 0;height:4px;background:var(--mlms-primary);opacity:.9}.mlms-mini-list{display:grid;gap:12px;margin:28px 0 0;padding:0;list-style:none}.mlms-mini-list li{display:flex;gap:10px;align-items:flex-start;color:var(--mlms-muted);font-weight:650}.mlms-mini-list li:before{content:"";width:10px;height:10px;margin-top:9px;border-radius:99px;background:var(--mlms-primary);box-shadow:0 0 0 5px rgba(99,91,255,.10)}.mlms-onboarding-progress{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:4px 0 22px}.mlms-onboarding-progress span{height:8px;border-radius:999px;background:#DEE7F0;transition:background .2s ease,transform .2s ease}.mlms-onboarding-progress span.active{background:var(--mlms-primary);transform:scaleY(1.15)}.mlms-onboarding-step-label{font-size:13px;font-weight:900;text-transform:uppercase;letter-spacing:.12em;color:var(--mlms-violet);margin:0 0 8px}.mlms-onboarding-panel{display:none;animation:mlmsFadeUp .24s ease both}.mlms-onboarding-panel.active{display:block}.mlms-onboarding-panel h2{font-size:clamp(28px,3vw,38px);line-height:1.06;letter-spacing:-.04em;margin:0 0 10px;color:var(--mlms-ink)}.mlms-onboarding-panel p{color:var(--mlms-muted);margin:0 0 22px}.mlms-google-button{width:100%;min-height:52px;margin:4px 0 14px;border-color:rgba(10,37,64,.12);background:#fff;color:#1F2B3D;box-shadow:0 12px 28px rgba(50,50,93,.10)}.mlms-google-mark{width:26px;height:26px;border-radius:50%;display:inline-grid;place-items:center;border:1px solid #E0E6EF;color:#4285F4;font-weight:950;background:#fff}.mlms-divider{display:flex;align-items:center;gap:12px;color:#7A8798;font-size:13px;font-weight:800;margin:16px 0}.mlms-divider:before,.mlms-divider:after{content:"";height:1px;background:#E4EAF2;flex:1}.mlms-role-picker{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:20px 0 22px}.mlms-role-card{position:relative;display:flex;gap:12px;align-items:flex-start;border:1px solid #DDE6F0;border-radius:18px;background:#fff;padding:16px;cursor:pointer;box-shadow:0 8px 20px rgba(50,50,93,.05);transition:border-color .18s ease,box-shadow .18s ease,transform .18s ease,background .18s ease}.mlms-role-card:hover{transform:translateY(-2px);border-color:rgba(99,91,255,.38);box-shadow:0 14px 30px rgba(50,50,93,.10)}.mlms-role-card input{position:absolute;opacity:0;pointer-events:none}.mlms-role-icon{width:38px;height:38px;border-radius:14px;display:grid;place-items:center;background:var(--mlms-primary-soft);color:var(--mlms-primary);font-weight:950;flex:0 0 auto}.mlms-role-card strong{display:block;color:var(--mlms-ink);line-height:1.2}.mlms-role-card small{display:block;color:var(--mlms-soft);font-weight:650;margin-top:3px}.mlms-role-card.selected,.mlms-role-card:has(input:checked){border-color:var(--mlms-primary);background:#FBFAFF;box-shadow:0 16px 34px rgba(99,91,255,.16)}.mlms-role-card.selected .mlms-role-icon,.mlms-role-card:has(input:checked) .mlms-role-icon{background:var(--mlms-primary);color:#fff}.mlms-onboarding-actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-top:16px}.mlms-onboarding-actions .mlms-btn{border:0;cursor:pointer}.mlms-onboarding-actions .mlms-btn-secondary{border:1px solid rgba(10,37,64,.10)}.mlms-inline-note{border-radius:18px;padding:14px 16px;background:#F6F4FF;border:1px solid rgba(99,91,255,.18);color:#3C367A;margin:0 0 18px;font-size:15px}.mlms-error-note{border-radius:18px;padding:14px 16px;background:#FFF5F5;border:1px solid rgba(220,38,38,.18);color:#7F1D1D;margin:0 0 18px;font-size:15px}.mlms-building-profile{display:none;margin-top:20px;border-radius:22px;background:linear-gradient(145deg,#0A2540,#172B4D);color:#fff;padding:22px;box-shadow:var(--mlms-shadow-soft)}.mlms-building-profile.active{display:block}.mlms-building-profile strong{display:block;font-size:20px;margin-bottom:4px}.mlms-building-profile p{margin:0;color:#C8D7EA}.mlms-loading-dots{display:flex;gap:8px;margin-top:18px}.mlms-loading-dots i{width:10px;height:10px;border-radius:50%;background:#C9C4FF;animation:mlmsDots 1s ease-in-out infinite}.mlms-loading-dots i:nth-child(2){animation-delay:.15s}.mlms-loading-dots i:nth-child(3){animation-delay:.3s}.mlms-onboarding-success{display:grid;grid-template-columns:minmax(0,.76fr) minmax(0,1fr);gap:24px;align-items:start}.mlms-profile-summary-card{background:linear-gradient(145deg,#0A2540,#172B4D);color:#fff;border-radius:28px;padding:28px;box-shadow:var(--mlms-shadow)}.mlms-profile-summary-card h2{color:#fff;margin:0 0 12px;font-size:34px;line-height:1.05;letter-spacing:-.04em}.mlms-profile-summary-card p{color:#D7E3F1}.mlms-profile-meta{display:grid;gap:10px;margin-top:22px}.mlms-profile-meta span{display:flex;justify-content:space-between;gap:14px;border-top:1px solid rgba(255,255,255,.12);padding-top:10px;color:#C8D7EA}.mlms-profile-meta b{color:#fff}.mlms-ai-profile{white-space:pre-wrap;background:#fff;border:1px solid var(--mlms-line);border-radius:24px;padding:24px;box-shadow:var(--mlms-shadow-soft);color:#26364A;line-height:1.6}.mlms-ai-profile h3{margin:0 0 12px;color:var(--mlms-ink)}
@keyframes mlmsFadeUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes mlmsDots{0%,80%,100%{transform:scale(.78);opacity:.55}40%{transform:scale(1);opacity:1}}
@media (max-width:900px){.mlms-login-grid,.mlms-signup-grid,.mlms-onboarding-success{grid-template-columns:1fr}.mlms-onboarding-copy{padding-top:0}.mlms-role-picker{grid-template-columns:1fr}}
@media (max-width:560px){.mlms-onboarding-hero{padding:48px 0}.mlms-role-picker{grid-template-columns:1fr}.mlms-onboarding-actions{display:grid}.mlms-onboarding-actions .mlms-btn{width:100%}}
.mlms-site-footer{position:relative;z-index:5;margin-top:40px;padding:38px 0 48px;background:rgba(255,255,255,.62);border-top:1px solid rgba(10,37,64,.08);backdrop-filter:blur(16px)}.mlms-site-footer-inner{display:flex;justify-content:space-between;align-items:center;gap:24px}.mlms-footer-brand{display:inline-flex;color:var(--mlms-ink);font-weight:950;font-size:24px;letter-spacing:-.055em;text-decoration:none!important}.mlms-site-footer p{margin:6px 0 0;color:var(--mlms-muted);font-size:14px}.mlms-footer-links{display:flex;gap:18px;flex-wrap:wrap}.mlms-footer-links a{color:#33425F;font-weight:800;text-decoration:none!important}.mlms-footer-links a:hover{color:var(--mlms-violet)}
@keyframes mlmsPulse{0%,100%{transform:scaleY(.78);opacity:.76}50%{transform:scaleY(1.08);opacity:1}}@keyframes mlmsGlow{0%,100%{filter:saturate(1)}50%{filter:saturate(1.12) brightness(1.04)}}
@media (max-width:900px){.mlms-site-header-inner{min-height:auto;padding-top:16px;padding-bottom:16px;flex-wrap:wrap}.mlms-header-nav{order:3;flex-basis:100%;justify-content:flex-start;gap:18px;overflow-x:auto}.mlms-page:before{height:300px}.mlms-hero{padding:70px 0 46px}.mlms-hero-grid,.mlms-coach-band,.mlms-profile-hero{grid-template-columns:1fr}.mlms-grid-3,.mlms-brand-grid,.mlms-form-grid,.mlms-role-grid{grid-template-columns:1fr}.mlms-ai-card{min-height:auto}.mlms-section-head{display:block}.mlms-h1{font-size:48px}.mlms-course-card{grid-template-columns:1fr}.mlms-shell{padding:0 18px}.mlms-section{padding:46px 0}.mlms-coach-band{padding:28px;border-radius:24px}}
@media (max-width:560px){.mlms-site-header{position:relative}.mlms-header-actions{gap:8px}.mlms-header-login,.mlms-header-signup{padding:10px 12px;font-size:14px}.mlms-site-footer-inner{flex-direction:column;align-items:flex-start}.mlms-footer-links{gap:12px}.mlms-site-footer{padding:30px 0 36px}.mlms-actions{display:grid}.mlms-btn{width:100%}.mlms-h1{font-size:42px}.mlms-h2{font-size:34px}.mlms-ai-card{padding:14px;border-radius:24px}.mlms-dashboard{padding:20px}.mlms-orb{width:46px;height:46px}.mlms-coach-preview{margin:14px 0 0;max-width:none}.mlms-footer-cta{padding-left:0;padding-right:0}}
CSS;
}
function matthew_lms_mvp_role_options(): array {
return [
'Product Manager' => ['PM', 'Shape AI-ready product workflows'],
'Marketing' => ['M', 'Plan campaigns and content systems'],
'Sales' => ['S', 'Improve outreach and pipeline rituals'],
'Operations' => ['O', 'Automate repeatable team processes'],
'Executive' => ['E', 'Lead strategy with AI leverage'],
'Other' => ['+', 'Build a custom learning path'],
];
}
function matthew_lms_mvp_google_oauth_config(): array {
$client_id = defined('MLMS_GOOGLE_CLIENT_ID') ? (string) MLMS_GOOGLE_CLIENT_ID : (string) getenv('MLMS_GOOGLE_CLIENT_ID');
$client_secret = defined('MLMS_GOOGLE_CLIENT_SECRET') ? (string) MLMS_GOOGLE_CLIENT_SECRET : (string) getenv('MLMS_GOOGLE_CLIENT_SECRET');
if ($client_id === '' || $client_secret === '') {
return [];
}
return [
'client_id' => $client_id,
'client_secret' => $client_secret,
// Keep one callback URL for both sign-up and login so Google only needs one authorized redirect URI.
'redirect_uri' => matthew_lms_mvp_public_url('sign-up/'),
];
}
function matthew_lms_mvp_google_oauth_url(string $flow = 'signup', string $redirect_to = ''): string {
$flow = $flow === 'login' ? 'login' : 'signup';
$fallback_path = $flow === 'login' ? 'log-in/' : 'sign-up/';
$anchor = $flow === 'login' ? '#mlms-login-card' : '#mlms-signup-flow';
$redirect = matthew_lms_mvp_clean_redirect_url($redirect_to, 'platform/');
$config = matthew_lms_mvp_google_oauth_config();
if (!$config) {
$notice_url = add_query_arg('mlms_google_notice', '1', matthew_lms_mvp_public_url($fallback_path));
if ($flow === 'login') {
$notice_url = add_query_arg('redirect_to', rawurlencode($redirect), $notice_url);
}
return $notice_url . $anchor;
}
$state = wp_generate_password(32, false, false);
set_transient('mlms_google_oauth_state_' . $state, [
'flow' => $flow,
'redirect_to' => $redirect,
'issued_at' => time(),
], 10 * MINUTE_IN_SECONDS);
return add_query_arg([
'client_id' => $config['client_id'],
'redirect_uri' => $config['redirect_uri'],
'response_type' => 'code',
'scope' => 'openid email profile',
'state' => $state,
'prompt' => 'select_account',
], 'https://accounts.google.com/o/oauth2/v2/auth');
}
function matthew_lms_mvp_store_google_oauth_message(array $result): string {
$token = wp_generate_password(20, false, false);
set_transient('mlms_google_oauth_msg_' . $token, [
'success' => !empty($result['success']),
'message' => sanitize_text_field((string) ($result['message'] ?? 'Google sign-in could not be completed.')),
], 5 * MINUTE_IN_SECONDS);
return $token;
}
function matthew_lms_mvp_take_google_oauth_message(): ?array {
$token = sanitize_text_field(wp_unslash($_GET['mlms_google_msg'] ?? ''));
if ($token === '') {
return null;
}
$key = 'mlms_google_oauth_msg_' . $token;
$message = get_transient($key);
delete_transient($key);
return is_array($message) ? $message : null;
}
function matthew_lms_mvp_unique_username_from_email(string $email): string {
$base = sanitize_user(current(explode('@', $email)), true);
if ($base === '') {
$base = 'wax_user';
}
$username = $base;
$i = 1;
while (username_exists($username)) {
$i++;
$username = $base . $i;
}
return $username;
}
function matthew_lms_mvp_login_user(int $user_id): void {
$user = get_user_by('id', $user_id);
if (!$user) {
return;
}
wp_set_current_user($user_id);
wp_set_auth_cookie($user_id, true);
do_action('wp_login', $user->user_login, $user);
}
function matthew_lms_mvp_clean_redirect_url(string $raw = '', string $fallback_path = 'platform/'): string {
$fallback = matthew_lms_mvp_public_url($fallback_path);
$raw = trim($raw);
if ($raw === '') {
return $fallback;
}
if (str_starts_with($raw, '/')) {
return matthew_lms_mvp_public_url(ltrim($raw, '/'));
}
$target = esc_url_raw($raw);
$target_host = wp_parse_url($target, PHP_URL_HOST);
if (!$target_host) {
return $fallback;
}
$current_host = sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'] ?? ''));
$fallback_host = wp_parse_url($fallback, PHP_URL_HOST);
$home_host = wp_parse_url(home_url('/'), PHP_URL_HOST);
$allowed_hosts = array_filter(array_unique([$current_host, $fallback_host, $home_host]));
return in_array($target_host, $allowed_hosts, true) ? $target : $fallback;
}
function matthew_lms_mvp_redirect_url(string $fallback_path = 'platform/'): string {
$raw = isset($_REQUEST['redirect_to']) ? (string) wp_unslash($_REQUEST['redirect_to']) : '';
return matthew_lms_mvp_clean_redirect_url($raw, $fallback_path);
}
function matthew_lms_mvp_maybe_handle_login_submission(): void {
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST' || !isset($_POST['mlms_login_nonce'])) {
return;
}
$GLOBALS['mlms_login_result'] = matthew_lms_mvp_handle_login_submission();
if (!empty($GLOBALS['mlms_login_result']['success'])) {
wp_redirect($GLOBALS['mlms_login_result']['redirect']);
exit;
}
}
function matthew_lms_mvp_handle_login_submission(): array {
$redirect = matthew_lms_mvp_redirect_url('platform/');
$nonce = sanitize_text_field(wp_unslash($_POST['mlms_login_nonce'] ?? ''));
if (!wp_verify_nonce($nonce, 'mlms_login_submit')) {
return ['success' => false, 'message' => 'Your login session expired. Please refresh and try again.'];
}
$identifier = sanitize_text_field(wp_unslash($_POST['mlms_login_identifier'] ?? ''));
$password = (string) wp_unslash($_POST['mlms_login_password'] ?? '');
$remember = !empty($_POST['mlms_login_remember']);
if ($identifier === '' || $password === '') {
return ['success' => false, 'message' => 'Enter your email or username and password to continue.'];
}
$login = $identifier;
if (is_email($identifier)) {
$user = get_user_by('email', $identifier);
if ($user) {
$login = $user->user_login;
}
}
$user = wp_signon([
'user_login' => $login,
'user_password' => $password,
'remember' => $remember,
], is_ssl());
if (is_wp_error($user)) {
return ['success' => false, 'message' => 'That email/username and password combination did not match. Please try again.'];
}
return ['success' => true, 'redirect' => $redirect];
}
function matthew_lms_mvp_maybe_handle_google_oauth_callback(): void {
if (!is_page(['sign-up', 'log-in'])) {
return;
}
if (!isset($_GET['state']) || (!isset($_GET['code']) && !isset($_GET['error']))) {
return;
}
$result = matthew_lms_mvp_handle_google_oauth_callback();
$flow = (($result['flow'] ?? '') === 'login') ? 'login' : 'signup';
if (!empty($result['success'])) {
if ($flow === 'login' && empty($result['new_user'])) {
wp_redirect($result['redirect'] ?? matthew_lms_mvp_public_url('platform/'));
exit;
}
wp_redirect(add_query_arg('mlms_google_connected', '1', matthew_lms_mvp_public_url('sign-up/')) . '#mlms-signup-flow');
exit;
}
$message_token = matthew_lms_mvp_store_google_oauth_message($result);
$target_path = $flow === 'login' ? 'log-in/' : 'sign-up/';
$target_url = add_query_arg('mlms_google_msg', $message_token, matthew_lms_mvp_public_url($target_path));
if ($flow === 'login' && !empty($result['redirect'])) {
$target_url = add_query_arg('redirect_to', rawurlencode((string) $result['redirect']), $target_url);
}
$target_url .= $flow === 'login' ? '#mlms-login-card' : '#mlms-signup-flow';
wp_redirect($target_url);
exit;
}
function matthew_lms_mvp_handle_google_oauth_callback(): array {
$page_flow = is_page('log-in') ? 'login' : 'signup';
$redirect = matthew_lms_mvp_redirect_url('platform/');
$state = sanitize_text_field(wp_unslash($_GET['state'] ?? ''));
$state_payload = $state !== '' ? get_transient('mlms_google_oauth_state_' . $state) : false;
if ($state === '' || !$state_payload) {
return ['success' => false, 'flow' => $page_flow, 'redirect' => $redirect, 'message' => 'Google sign-in could not be verified. Please try again.'];
}
delete_transient('mlms_google_oauth_state_' . $state);
$flow = is_array($state_payload) && (($state_payload['flow'] ?? '') === 'login') ? 'login' : 'signup';
if (is_array($state_payload) && !empty($state_payload['redirect_to'])) {
$redirect = matthew_lms_mvp_clean_redirect_url((string) $state_payload['redirect_to'], 'platform/');
}
if (isset($_GET['error'])) {
$error = sanitize_text_field(wp_unslash($_GET['error']));
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => $error === 'access_denied' ? 'Google sign-in was cancelled.' : 'Google returned an authorization error. Please try again.'];
}
$config = matthew_lms_mvp_google_oauth_config();
if (!$config) {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => 'Google sign-in is designed into this flow, but it still needs Google OAuth credentials before it can connect real Gmail accounts.'];
}
$code = sanitize_text_field(wp_unslash($_GET['code'] ?? ''));
if ($code === '') {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => 'Google did not return an authorization code.'];
}
$token_response = wp_remote_post('https://oauth2.googleapis.com/token', [
'timeout' => 20,
'body' => [
'code' => $code,
'client_id' => $config['client_id'],
'client_secret' => $config['client_secret'],
'redirect_uri' => $config['redirect_uri'],
'grant_type' => 'authorization_code',
],
]);
if (is_wp_error($token_response)) {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => $token_response->get_error_message()];
}
if ((int) wp_remote_retrieve_response_code($token_response) >= 400) {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => 'Google sign-in could not exchange the authorization code. Check the OAuth redirect URI and credentials.'];
}
$token_data = json_decode(wp_remote_retrieve_body($token_response), true);
if (!is_array($token_data) || empty($token_data['access_token'])) {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => 'Google sign-in did not return an access token. Check the OAuth redirect URI and credentials.'];
}
$profile_response = wp_remote_get('https://www.googleapis.com/oauth2/v3/userinfo', [
'timeout' => 20,
'headers' => ['Authorization' => 'Bearer ' . $token_data['access_token']],
]);
if (is_wp_error($profile_response)) {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => $profile_response->get_error_message()];
}
$profile = json_decode(wp_remote_retrieve_body($profile_response), true);
if (!is_array($profile)) {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => 'Google did not return a readable profile.'];
}
$email = sanitize_email($profile['email'] ?? '');
if ($email === '') {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => 'Google did not provide an email address.'];
}
if (isset($profile['email_verified']) && !$profile['email_verified']) {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => 'Google did not confirm that this email address is verified.'];
}
$email_name = sanitize_text_field(strstr($email, '@', true) ?: $email);
$name = sanitize_text_field($profile['name'] ?? $email_name);
$user_id = email_exists($email);
$created_user = false;
if (!$user_id) {
$user_id = wp_insert_user([
'user_login' => matthew_lms_mvp_unique_username_from_email($email),
'user_pass' => wp_generate_password(32, true, true),
'user_email' => $email,
'display_name' => $name,
'role' => 'subscriber',
]);
if (is_wp_error($user_id)) {
return ['success' => false, 'flow' => $flow, 'redirect' => $redirect, 'message' => $user_id->get_error_message()];
}
$created_user = true;
}
if (!get_user_meta((int) $user_id, '_mlms_signup_auth_method', true)) {
update_user_meta((int) $user_id, '_mlms_signup_auth_method', 'google');
}
update_user_meta((int) $user_id, '_mlms_last_auth_method', 'google');
if (!empty($profile['picture'])) {
update_user_meta((int) $user_id, '_mlms_google_picture', esc_url_raw($profile['picture']));
}
matthew_lms_mvp_login_user((int) $user_id);
$message = $flow === 'login'
? ($created_user ? 'Google account created. Finish two onboarding questions to personalize WAX.' : 'Signed in with Google.')
: 'Google connected. Two quick questions and WAX will build your starter profile.';
return ['success' => true, 'flow' => $flow, 'redirect' => $redirect, 'new_user' => $created_user, 'message' => $message, 'email' => $email];
}
function matthew_lms_mvp_handle_signup_onboarding_submission(): array {
$role_options = matthew_lms_mvp_role_options();
$role = sanitize_text_field(wp_unslash($_POST['mlms_signup_role'] ?? ''));
$goal = sanitize_textarea_field(wp_unslash($_POST['mlms_signup_goal'] ?? ''));
$link = esc_url_raw(wp_unslash($_POST['mlms_profile_link'] ?? ''));
if (!array_key_exists($role, $role_options)) {
return ['success' => false, 'message' => 'Choose the role that best matches how you work.'];
}
if ($goal === '') {
return ['success' => false, 'message' => 'Tell WAX what you want to learn first.'];
}
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$user = get_userdata($user_id);
$email = $user ? $user->user_email : '';
} else {
$email = sanitize_email(wp_unslash($_POST['mlms_signup_email'] ?? ''));
$password = (string) wp_unslash($_POST['mlms_signup_password'] ?? '');
if ($email === '' || !is_email($email)) {
return ['success' => false, 'message' => 'Enter a valid email address.'];
}
if (strlen($password) < 8) {
return ['success' => false, 'message' => 'Use a password with at least 8 characters.'];
}
if (email_exists($email)) {
return ['success' => false, 'message' => 'An account already exists for this email. Use Login, then return here to finish onboarding.'];
}
$user_id = wp_insert_user([
'user_login' => matthew_lms_mvp_unique_username_from_email($email),
'user_pass' => $password,
'user_email' => $email,
'display_name' => current(explode('@', $email)),
'role' => 'subscriber',
]);
if (is_wp_error($user_id)) {
return ['success' => false, 'message' => $user_id->get_error_message()];
}
update_user_meta((int) $user_id, '_mlms_signup_auth_method', 'email');
matthew_lms_mvp_login_user((int) $user_id);
}
$profile = matthew_lms_mvp_generate_profile_bootstrap($email, $role, $goal, $link);
update_user_meta((int) $user_id, '_mlms_functional_role', $role);
update_user_meta((int) $user_id, '_mlms_learning_goal', $goal);
update_user_meta((int) $user_id, '_mlms_profile_link', $link);
update_user_meta((int) $user_id, '_mlms_ai_profile_bootstrap', $profile);
$post_id = wp_insert_post([
'post_type' => 'mlms_onboard',
'post_status' => 'private',
'post_author' => (int) $user_id,
'post_title' => sprintf('%s — %s onboarding', $email, $role),
'post_content' => "Email: $email\nRole: $role\nLearning goals:\n$goal\nLinked account: $link\n\nAI profile bootstrap:\n$profile",
], true);
if (!is_wp_error($post_id)) {
foreach (['email' => $email, 'role' => $role, 'goal' => $goal, 'profile_link' => $link, 'ai_profile' => $profile] as $key => $value) {
update_post_meta($post_id, '_mlms_' . $key, $value);
}
}
return ['success' => true, 'email' => $email, 'role' => $role, 'goal' => $goal, 'link' => $link, 'profile' => $profile, 'post_id' => is_wp_error($post_id) ? 0 : (int) $post_id];
}
function matthew_lms_mvp_generate_profile_bootstrap(string $email, string $role, string $goal, string $link): string {
$fallback = "Starter WAX profile\n\nHeadline: AI-native $role building practical workflows with WAX.\n\nLearning path: Start with AI workflow fluency, then map one real weekly task into a repeatable prompt-and-review system.\n\nFirst wins:\n1. Pick one high-friction task connected to your goal.\n2. Build a simple AI-assisted draft, review, and handoff loop.\n3. Save the result as your first portfolio artifact.";
$api = dirname(__DIR__, 3) . '/ai/LocalAIApi.php';
if (!file_exists($api)) { return $fallback; }
require_once $api;
if (!class_exists('LocalAIApi')) { return $fallback; }
$link_context = $link ? "Linked account/profile URL supplied by user: $link." : 'No linked account was supplied.';
$prompt = "Create a concise starter profile for a new WAX learner. Email: $email. Functional role: $role. Learning goals: $goal. $link_context Include: 1) one-line professional headline, 2) a recommended first learning path, 3) three practical starter actions. Sound friendly, premium, and specific. Keep under 180 words.";
$resp = LocalAIApi::createResponse([
'input' => [
['role' => 'system', 'content' => 'You are WAX, an AI onboarding assistant that turns short sign-up answers into useful AI-native learning profiles.'],
['role' => 'user', 'content' => $prompt],
],
], ['poll_interval' => 2, 'poll_timeout' => 30, 'timeout' => 20]);
if (!empty($resp['success'])) {
$text = LocalAIApi::extractText($resp);
if (is_string($text) && trim($text) !== '') { return trim($text); }
}
return $fallback;
}
function matthew_lms_mvp_render_signup_success(array $result): string {
ob_start();
?>
<div class="mlms-page"><section class="mlms-section mlms-onboarding-hero"><div class="mlms-shell">
<div class="mlms-onboarding-success">
<div class="mlms-profile-summary-card">
<p class="mlms-kicker" style="color:#C9C4FF">Profile bootstrap complete</p>
<h2>Your WAX profile is ready.</h2>
<p>WAX used your sign-up answers<?php echo !empty($result['link']) ? ' and linked profile URL' : ''; ?> to create a starter learning profile you can refine over time.</p>
<div class="mlms-profile-meta">
<span><b>Email</b> <?php echo esc_html($result['email']); ?></span>
<span><b>Role</b> <?php echo esc_html($result['role']); ?></span>
</div>
<div class="mlms-actions"><a class="mlms-btn mlms-btn-primary" href="<?php echo esc_url(matthew_lms_mvp_public_url('platform/')); ?>">Go to WAX platform →</a><a class="mlms-btn mlms-btn-secondary" href="<?php echo esc_url(matthew_lms_mvp_public_url('career-coach/')); ?>">Try Free Career Coach</a></div>
</div>
<div class="mlms-ai-profile"><h3>AI-generated starter profile</h3><?php echo esc_html($result['profile']); ?></div>
</div>
</div></section></div>
<?php
return ob_get_clean();
}
function matthew_lms_mvp_js(): string {
return <<<'JS'
(function(){
function initWaxOnboarding(){
var root=document.getElementById('mlms-signup-flow');
if(!root){return;}
var form=document.getElementById('mlms-onboarding-form');
var panels=[].slice.call(root.querySelectorAll('.mlms-onboarding-panel'));
var bars=[].slice.call(root.querySelectorAll('.mlms-onboarding-progress span'));
if(!form || !panels.length){return;}
var current=Math.max(0, Math.min(panels.length-1, (parseInt(root.getAttribute('data-start-step')||'1',10)-1)));
function show(index){
current=index;
panels.forEach(function(panel,i){panel.classList.toggle('active',i===current);});
bars.forEach(function(bar,i){bar.classList.toggle('active',i<=current);});
}
function syncRoles(){
root.querySelectorAll('.mlms-role-card').forEach(function(card){
var input=card.querySelector('input');
card.classList.toggle('selected', !!(input && input.checked));
});
}
function validPanel(panel){
var roleInputs=[].slice.call(panel.querySelectorAll('input[name="mlms_signup_role"]'));
if(roleInputs.length && !roleInputs.some(function(input){return input.checked;})){
roleInputs[0].setCustomValidity('Choose a role to continue.');
roleInputs[0].reportValidity();
roleInputs[0].setCustomValidity('');
return false;
}
var fields=[].slice.call(panel.querySelectorAll('input, textarea')).filter(function(field){return field.offsetParent!==null && field.type!=='radio';});
for(var i=0;i<fields.length;i++){
if(!fields[i].checkValidity()){
fields[i].reportValidity();
return false;
}
}
return true;
}
root.querySelectorAll('[data-mlms-next]').forEach(function(button){
button.addEventListener('click',function(){
if(validPanel(panels[current])){show(Math.min(current+1,panels.length-1));}
});
});
root.querySelectorAll('[data-mlms-prev]').forEach(function(button){
button.addEventListener('click',function(){show(Math.max(current-1,0));});
});
root.querySelectorAll('.mlms-role-card input').forEach(function(input){input.addEventListener('change',syncRoles);});
form.addEventListener('submit',function(event){
if(!validPanel(panels[current])){event.preventDefault();return;}
var loading=root.querySelector('.mlms-building-profile');
if(loading){loading.classList.add('active');}
form.querySelectorAll('button').forEach(function(button){button.disabled=true;});
});
syncRoles();
show(current);
}
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded', initWaxOnboarding);
} else {
initWaxOnboarding();
}
})();
JS;
}
add_shortcode('matthew_login', function () {
$redirect_url = matthew_lms_mvp_redirect_url('platform/');
$result = $GLOBALS['mlms_login_result'] ?? null;
$google_message = matthew_lms_mvp_take_google_oauth_message();
$google_url = matthew_lms_mvp_google_oauth_url('login', $redirect_url);
$identifier = sanitize_text_field(wp_unslash($_POST['mlms_login_identifier'] ?? ''));
$current_user = wp_get_current_user();
ob_start();
?>
<div class="mlms-page"><section class="mlms-onboarding-hero"><div class="mlms-shell">
<div class="mlms-login-grid">
<div class="mlms-onboarding-copy">
<div class="mlms-eyebrow mlms-pill">WAX account access</div>
<h1 class="mlms-h1">Welcome back to <span class="mlms-gradient-text">AI-powered work</span>.</h1>
<p class="mlms-lede">Log in to continue your WAX learning path, revisit your AI profile, and keep building practical role-specific workflows.</p>
<ul class="mlms-mini-list">
<li>Continue your personalized WAX platform preview.</li>
<li>Return to saved onboarding and profile context.</li>
<li>Use the same account you created during sign-up.</li>
</ul>
</div>
<div class="mlms-form-card mlms-login-card" id="mlms-login-card">
<?php if (is_user_logged_in()): ?>
<div class="mlms-inline-note"><strong>Youre already signed in.</strong> Continue as <?php echo esc_html($current_user->user_email ?: $current_user->display_name); ?>.</div>
<div class="mlms-actions"><a class="mlms-btn mlms-btn-primary" href="<?php echo esc_url($redirect_url); ?>">Go to WAX platform →</a><a class="mlms-btn mlms-btn-secondary" href="<?php echo esc_url(wp_logout_url(matthew_lms_mvp_public_url('log-in/'))); ?>">Log out</a></div>
<?php else: ?>
<h2>Log in to WAX.</h2>
<p>Use Google for one-click access, or log in with your email/username and password.</p>
<?php if (isset($_GET['mlms_google_notice'])): ?>
<div class="mlms-inline-note"><strong>Google login is ready to connect.</strong> Add Google OAuth client credentials to enable real Gmail authentication. You can still log in with your password now.</div>
<?php endif; ?>
<?php if (is_array($google_message)): ?>
<div class="<?php echo !empty($google_message['success']) ? 'mlms-inline-note' : 'mlms-error-note'; ?>"><strong><?php echo !empty($google_message['success']) ? 'Google connected.' : 'Google login needs attention.'; ?></strong> <?php echo esc_html($google_message['message'] ?? ''); ?></div>
<?php endif; ?>
<?php if (is_array($result) && empty($result['success'])): ?>
<div class="mlms-error-note"><strong>Login failed.</strong> <?php echo esc_html($result['message']); ?></div>
<?php endif; ?>
<a class="mlms-btn mlms-btn-secondary mlms-google-button" href="<?php echo esc_url($google_url); ?>"><span class="mlms-google-mark">G</span> Continue with Google</a>
<div class="mlms-divider">or use password</div>
<form method="post" class="mlms-login-form" novalidate>
<?php wp_nonce_field('mlms_login_submit', 'mlms_login_nonce'); ?>
<input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_url); ?>">
<div class="mlms-field"><label for="mlms_login_identifier">Email or username</label><input id="mlms_login_identifier" name="mlms_login_identifier" type="text" value="<?php echo esc_attr($identifier); ?>" autocomplete="username" required placeholder="you@example.com"></div>
<div class="mlms-field"><label for="mlms_login_password">Password</label><input id="mlms_login_password" name="mlms_login_password" type="password" autocomplete="current-password" required placeholder="Your password"></div>
<div class="mlms-login-actions">
<label class="mlms-checkbox"><input type="checkbox" name="mlms_login_remember" value="1" checked> Remember me</label>
<a class="mlms-login-link" href="<?php echo esc_url(wp_lostpassword_url($redirect_url)); ?>">Forgot password?</a>
</div>
<button class="mlms-btn mlms-btn-primary mlms-login-submit" type="submit">Log in →</button>
</form>
<p class="mlms-login-footnote">Need a WAX account? <a href="<?php echo esc_url(matthew_lms_mvp_public_url('sign-up/')); ?>">Start onboarding</a>.</p>
<?php endif; ?>
</div>
</div>
</div></section></div>
<?php
return ob_get_clean();
});
add_shortcode('matthew_signup_onboarding', function () {
$result = null;
$google_message = matthew_lms_mvp_take_google_oauth_message();
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['mlms_signup_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['mlms_signup_nonce'])), 'mlms_signup_submit')) {
$result = matthew_lms_mvp_handle_signup_onboarding_submission();
if (is_array($result) && !empty($result['success'])) {
return matthew_lms_mvp_render_signup_success($result);
}
}
$current_user = wp_get_current_user();
$is_logged_in = is_user_logged_in();
$prefill_email = $is_logged_in ? $current_user->user_email : sanitize_email(wp_unslash($_POST['mlms_signup_email'] ?? ''));
$start_step = $is_logged_in ? 2 : 1;
$google_url = matthew_lms_mvp_google_oauth_url('signup');
$role_options = matthew_lms_mvp_role_options();
ob_start();
?>
<div class="mlms-page"><section class="mlms-onboarding-hero"><div class="mlms-shell">
<div class="mlms-signup-grid" id="mlms-signup-flow" data-start-step="<?php echo esc_attr((string) $start_step); ?>">
<div class="mlms-onboarding-copy">
<p class="mlms-kicker">Sign Up & Onboarding</p>
<h1 class="mlms-h2">Create your WAX profile in under a minute.</h1>
<p class="mlms-section-copy">Start with only the essentials. Then answer two friendly onboarding questions so WAX can build a useful AI-native learning profile immediately.</p>
<ul class="mlms-mini-list">
<li>Minimal email/password sign-up with a prominent Google option.</li>
<li>Card-based role selection — no corporate dropdown maze.</li>
<li>A short “building your profile” moment powered by WAX AI.</li>
</ul>
</div>
<div class="mlms-form-card mlms-onboarding-card">
<?php if (isset($_GET['mlms_google_notice'])): ?>
<div class="mlms-inline-note"><strong>Google sign-in is ready to connect.</strong> Add Google OAuth client credentials to enable real Gmail authentication. You can still sign up with email now.</div>
<?php endif; ?>
<?php if (isset($_GET['mlms_google_connected'])): ?>
<div class="mlms-inline-note"><strong>Google connected.</strong> Two quick questions and WAX will build your starter profile.</div>
<?php endif; ?>
<?php if (is_array($google_message)): ?>
<div class="<?php echo !empty($google_message['success']) ? 'mlms-inline-note' : 'mlms-error-note'; ?>"><strong><?php echo !empty($google_message['success']) ? 'Google connected.' : 'Google sign-in needs attention.'; ?></strong> <?php echo esc_html($google_message['message'] ?? ''); ?></div>
<?php endif; ?>
<?php if (is_array($result) && empty($result['success'])): ?>
<div class="mlms-error-note"><strong>Almost there.</strong> <?php echo esc_html($result['message']); ?></div>
<?php endif; ?>
<form method="post" id="mlms-onboarding-form" novalidate>
<?php wp_nonce_field('mlms_signup_submit', 'mlms_signup_nonce'); ?>
<div class="mlms-onboarding-progress" aria-label="Onboarding progress"><span class="<?php echo $start_step >= 1 ? 'active' : ''; ?>"></span><span class="<?php echo $start_step >= 2 ? 'active' : ''; ?>"></span><span class="<?php echo $start_step >= 3 ? 'active' : ''; ?>"></span></div>
<div class="mlms-onboarding-panel <?php echo $start_step === 1 ? 'active' : ''; ?>" data-step="1">
<p class="mlms-onboarding-step-label">Step 1 of 3</p>
<h2>First, create your account.</h2>
<p>No long form. Use Google, or enter just email and password.</p>
<?php if (!$is_logged_in): ?>
<a class="mlms-btn mlms-btn-secondary mlms-google-button" href="<?php echo esc_url($google_url); ?>"><span class="mlms-google-mark">G</span> Continue with Google</a>
<div class="mlms-divider">or use email</div>
<div class="mlms-form-grid">
<div class="mlms-field"><label for="mlms_signup_email">Email</label><input id="mlms_signup_email" name="mlms_signup_email" type="email" value="<?php echo esc_attr($prefill_email); ?>" autocomplete="email" required placeholder="you@example.com"></div>
<div class="mlms-field"><label for="mlms_signup_password">Password</label><input id="mlms_signup_password" name="mlms_signup_password" type="password" autocomplete="new-password" minlength="8" required placeholder="At least 8 characters"></div>
</div>
<?php else: ?>
<div class="mlms-inline-note"><strong>Youre signed in.</strong> Well finish onboarding for <?php echo esc_html($prefill_email); ?>.</div>
<input type="hidden" name="mlms_signup_email" value="<?php echo esc_attr($prefill_email); ?>">
<?php endif; ?>
<div class="mlms-onboarding-actions"><button class="mlms-btn mlms-btn-primary" type="button" data-mlms-next>Continue →</button></div>
</div>
<div class="mlms-onboarding-panel <?php echo $start_step === 2 ? 'active' : ''; ?>" data-step="2">
<p class="mlms-onboarding-step-label">Step 2 of 3</p>
<h2>What kind of work do you do?</h2>
<p>Pick the closest role. WAX will personalize examples and first projects around it.</p>
<div class="mlms-role-picker" role="radiogroup" aria-label="Functional role">
<?php foreach ($role_options as $label => $meta): ?>
<label class="mlms-role-card"><input type="radio" name="mlms_signup_role" value="<?php echo esc_attr($label); ?>" required><span class="mlms-role-icon"><?php echo esc_html($meta[0]); ?></span><span><strong><?php echo esc_html($label); ?></strong><small><?php echo esc_html($meta[1]); ?></small></span></label>
<?php endforeach; ?>
</div>
<div class="mlms-onboarding-actions"><button class="mlms-btn mlms-btn-secondary" type="button" data-mlms-prev>Back</button><button class="mlms-btn mlms-btn-primary" type="button" data-mlms-next>Continue →</button></div>
</div>
<div class="mlms-onboarding-panel <?php echo $start_step === 3 ? 'active' : ''; ?>" data-step="3">
<p class="mlms-onboarding-step-label">Step 3 of 3</p>
<h2>What should WAX help you learn first?</h2>
<p>Use normal language. Add LinkedIn or GitHub only if it helps WAX understand your background.</p>
<div class="mlms-field"><label for="mlms_signup_goal">Learning goal</label><textarea id="mlms_signup_goal" name="mlms_signup_goal" required placeholder="Example: I want to use AI to speed up campaign planning, reporting, and team handoffs."><?php echo esc_textarea(wp_unslash($_POST['mlms_signup_goal'] ?? '')); ?></textarea></div>
<div class="mlms-field"><label for="mlms_profile_link">LinkedIn or GitHub URL <span style="font-weight:650;color:var(--mlms-soft)">(optional)</span></label><input id="mlms_profile_link" name="mlms_profile_link" type="url" value="<?php echo esc_attr(esc_url_raw(wp_unslash($_POST['mlms_profile_link'] ?? ''))); ?>" placeholder="https://linkedin.com/in/yourname"></div>
<div class="mlms-onboarding-actions"><button class="mlms-btn mlms-btn-secondary" type="button" data-mlms-prev>Back</button><button class="mlms-btn mlms-btn-primary" type="submit">Build my WAX profile →</button></div>
<div class="mlms-building-profile" aria-live="polite"><strong>Building your profile…</strong><p>WAX is turning your role, goals, and optional linked profile into a starter learning path.</p><div class="mlms-loading-dots"><i></i><i></i><i></i></div></div>
</div>
</form>
</div>
</div>
</div></section></div>
<?php
return ob_get_clean();
});
add_shortcode('matthew_career_coach', function () {
$result = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['mlms_coach_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['mlms_coach_nonce'])), 'mlms_coach_submit')) {
$result = matthew_lms_mvp_handle_coach_submission();
}
ob_start();
?>
<div class="mlms-page"><section class="mlms-section"><div class="mlms-shell">
<div class="mlms-section-head"><div><p class="mlms-kicker">Free AI Career Coach</p><h1 class="mlms-h2">Get a calm, practical path into AI-native work.</h1><p class="mlms-section-copy">Upload a resume or describe your current role. The coach identifies skill gaps, recommends next steps, and shows how WAX can turn progress into a visible credential.</p></div><span class="mlms-pill">FREE • no course purchase needed</span></div>
<div class="mlms-form-card">
<?php if (is_array($result) && !empty($result['success'])): ?>
<div class="mlms-notice"><strong>Your career coach plan is ready.</strong> Your request was saved for follow-up and the AI-generated guidance is below.</div>
<div class="mlms-ai-output"><?php echo esc_html($result['advice']); ?></div>
<?php elseif (is_array($result) && empty($result['success'])): ?>
<div class="mlms-notice"><strong>Saved with a note:</strong> <?php echo esc_html($result['message']); ?></div>
<?php endif; ?>
<form method="post" enctype="multipart/form-data">
<?php wp_nonce_field('mlms_coach_submit', 'mlms_coach_nonce'); ?>
<div class="mlms-steps"><span class="mlms-step active"></span><span class="mlms-step active"></span><span class="mlms-step"></span></div>
<p class="mlms-help">We use your answers only to generate this coaching plan and save your request for follow-up.</p>
<div class="mlms-form-grid">
<div class="mlms-field"><label for="mlms_name">Name</label><input id="mlms_name" name="mlms_name" required placeholder="Alex Morgan"></div>
<div class="mlms-field"><label for="mlms_email">Email</label><input id="mlms_email" name="mlms_email" type="email" required placeholder="alex@example.com"></div>
<div class="mlms-field"><label for="mlms_current_role">Current role</label><input id="mlms_current_role" name="mlms_current_role" required placeholder="Marketing Director"></div>
<div class="mlms-field"><label for="mlms_target_role">Target role / aspiration</label><input id="mlms_target_role" name="mlms_target_role" required placeholder="AI-native growth leader"></div>
</div>
<div class="mlms-field"><label for="mlms_goal">What would make AI feel immediately useful at work?</label><textarea id="mlms_goal" name="mlms_goal" required placeholder="Tell the coach where you feel behind, what you want to automate, or what career outcome matters most."></textarea></div>
<div class="mlms-field"><label for="mlms_resume">Resume upload (optional)</label><input id="mlms_resume" name="mlms_resume" type="file" accept=".pdf,.doc,.docx,.txt"><p class="mlms-help">Privacy note: the file is attached to your follow-up request; this instant AI plan is based on your typed answers.</p></div>
<button class="mlms-btn mlms-btn-primary" type="submit">Generate my AI career path →</button>
</form>
</div>
</div></section></div>
<?php
return ob_get_clean();
});
function matthew_lms_mvp_handle_coach_submission(): array {
$name = sanitize_text_field(wp_unslash($_POST['mlms_name'] ?? ''));
$email = sanitize_email(wp_unslash($_POST['mlms_email'] ?? ''));
$current = sanitize_text_field(wp_unslash($_POST['mlms_current_role'] ?? ''));
$target = sanitize_text_field(wp_unslash($_POST['mlms_target_role'] ?? ''));
$goal = sanitize_textarea_field(wp_unslash($_POST['mlms_goal'] ?? ''));
if (!$name || !$email || !$current || !$target || !$goal) {
return ['success' => false, 'message' => 'Please complete all required fields.'];
}
$post_id = wp_insert_post([
'post_type' => 'mlms_coach_request',
'post_status' => 'private',
'post_title' => sprintf('%s — %s to %s', $name, $current, $target),
'post_content' => "Name: $name\nEmail: $email\nCurrent role: $current\nTarget role: $target\nGoal:\n$goal",
], true);
if (is_wp_error($post_id)) {
return ['success' => false, 'message' => $post_id->get_error_message()];
}
foreach (['name'=>$name,'email'=>$email,'current_role'=>$current,'target_role'=>$target,'goal'=>$goal] as $key => $value) {
update_post_meta($post_id, '_mlms_' . $key, $value);
}
if (!empty($_FILES['mlms_resume']['name'])) {
require_once ABSPATH . 'wp-admin/includes/file.php';
$upload = wp_handle_upload($_FILES['mlms_resume'], ['test_form' => false]);
if (!empty($upload['url'])) {
update_post_meta($post_id, '_mlms_resume_url', esc_url_raw($upload['url']));
}
}
$advice = matthew_lms_mvp_generate_ai_advice($name, $current, $target, $goal);
update_post_meta($post_id, '_mlms_ai_advice', $advice);
return ['success' => true, 'advice' => $advice, 'post_id' => $post_id];
}
function matthew_lms_mvp_generate_ai_advice(string $name, string $current, string $target, string $goal): string {
$fallback = "Hi $name — here is a first AI-native career path:\n\n1. Immediate win: choose one weekly workflow in your $current role and redesign it with AI assistance.\n2. Skill gap: learn prompt framing, evaluation, workflow mapping, and safe handoff from AI output to human decision-making.\n3. Build task: create a reusable AI playbook for the goal you described: $goal\n4. Credential path: complete Phase 1 for AI workflow fluency, Phase 2 for role-specific automation, and Phase 3 for a portfolio-ready AI operator certification.\n\nNext step: start with the first lesson and turn one real task into a shareable portfolio artifact.";
$api = dirname(__DIR__, 3) . '/ai/LocalAIApi.php';
if (!file_exists($api)) { return $fallback; }
require_once $api;
if (!class_exists('LocalAIApi')) { return $fallback; }
$prompt = "Create a concise, encouraging AI career coaching plan for a non-technical professional. Name: $name. Current role: $current. Target role: $target. Goal/context: $goal. Include: personalized career path, top 3 skill gaps, 3 next steps, and how an AI-native operator certification helps. Keep under 220 words, calm and premium.";
$resp = LocalAIApi::createResponse([
'input' => [
['role' => 'system', 'content' => 'You are WAX, a calm expert AI career coach for non-technical professionals. Be practical, specific, reassuring, and concise.'],
['role' => 'user', 'content' => $prompt],
],
], ['poll_interval' => 2, 'poll_timeout' => 30, 'timeout' => 20]);
if (!empty($resp['success'])) {
$text = LocalAIApi::extractText($resp);
if (is_string($text) && trim($text) !== '') { return trim($text); }
}
return $fallback;
}
add_filter('manage_mlms_coach_request_posts_columns', function ($columns) {
$columns['mlms_email'] = 'Email';
$columns['mlms_current'] = 'Current Role';
$columns['mlms_target'] = 'Target Role';
return $columns;
});
add_action('manage_mlms_coach_request_posts_custom_column', function ($column, $post_id) {
if ($column === 'mlms_email') { echo esc_html(get_post_meta($post_id, '_mlms_email', true)); }
if ($column === 'mlms_current') { echo esc_html(get_post_meta($post_id, '_mlms_current_role', true)); }
if ($column === 'mlms_target') { echo esc_html(get_post_meta($post_id, '_mlms_target_role', true)); }
}, 10, 2);