.im-form-wrap{max-width:720px;margin:0 auto;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC",sans-serif} .im-form{background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:40px 48px;box-shadow:0 4px 24px rgba(0,0,0,.06)} @media(max-width:640px){.im-form{padding:28px 20px}} .im-form h2{margin:0 0 6px;font-size:22px;font-weight:700;color:#111827} .im-form .im-subtitle{color:#6b7280;font-size:15px;margin:0 0 32px} .im-section-title{font-size:16px;font-weight:700;color:#009dff;margin:32px 0 16px;padding-bottom:8px;border-bottom:2px solid #d0f0ff} .im-section-title:first-of-type{margin-top:0} .im-field{margin-bottom:20px} .im-field label{display:block;font-size:14px;font-weight:600;color:#374151;margin-bottom:6px} .im-field label .req{color:#ef4444;margin-left:2px} .im-field label .hint{font-weight:400;color:#9ca3af;font-size:12px;margin-left:6px} .im-input,.im-select,.im-textarea{width:100%;padding:11px 14px;border:1.5px solid #d1d5db;border-radius:8px;font-size:15px; color:#111827;background:#fff;transition:border-color .2s,box-shadow .2s;box-sizing:border-box;font-family:inherit} .im-input:focus,.im-select:focus,.im-textarea:focus{outline:none;border-color:#009dff;box-shadow:0 0 0 3px rgba(0,157,255,.15)} .im-input.error,.im-select.error,.im-textarea.error{border-color:#ef4444} .im-textarea{resize:vertical;min-height:100px;line-height:1.6} .im-row{display:grid;grid-template-columns:1fr 1fr;gap:16px} @media(max-width:540px){.im-row{grid-template-columns:1fr}} .im-radio-group,.im-check-group{display:flex;flex-wrap:wrap;gap:10px;margin-top:4px} .im-radio-group label,.im-check-group label{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:400; cursor:pointer;padding:8px 14px;border:1.5px solid #d1d5db;border-radius:8px;transition:all .15s;color:#374151;white-space:nowrap;position:relative} .im-radio-group label:hover,.im-check-group label:hover{border-color:#009dff;background:#e6f9ff} .im-radio-group input[type=radio],.im-check-group input[type=checkbox]{position:absolute;opacity:0;width:0;height:0;pointer-events:none} .im-radio-group .im-ck,.im-check-group .im-ck{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px; border:2px solid #d1d5db;border-radius:4px;flex-shrink:0;transition:all .2s;background:#fff;position:relative} .im-radio-group .im-ck{border-radius:50%} .im-ck::after{content:"";display:block;opacity:0;transition:opacity .15s} .im-check-group .im-ck::after{width:5px;height:9px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg);margin-top:-1px} .im-radio-group .im-ck::after{width:8px;height:8px;border-radius:50%;background:#fff} input:checked~.im-ck{background:linear-gradient(135deg,#009dff,#3de1fe,#53eee0);border-color:transparent} input:checked~.im-ck::after{opacity:1} .im-radio-group input:checked~span,.im-check-group input:checked~span{color:#009dff;font-weight:600} .im-checkbox-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;margin-top:4px} .im-checkbox-grid label{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:400; cursor:pointer;padding:8px 12px;border:1.5px solid #e5e7eb;border-radius:8px;transition:all .15s;color:#374151;position:relative} .im-checkbox-grid label:hover{border-color:#009dff;background:#e6f9ff} .im-checkbox-grid input[type=checkbox]{position:absolute;opacity:0;width:0;height:0;pointer-events:none} .im-checkbox-grid .im-ck{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px; border:2px solid #d1d5db;border-radius:4px;flex-shrink:0;transition:all .2s;background:#fff} .im-checkbox-grid .im-ck::after{content:"";width:4px;height:8px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg);opacity:0;transition:opacity .15s;margin-top:-1px} .im-checkbox-grid input:checked~.im-ck{background:linear-gradient(135deg,#009dff,#3de1fe,#53eee0);border-color:transparent} .im-checkbox-grid input:checked~.im-ck::after{opacity:1} .im-checkbox-grid input:checked~span{color:#009dff;font-weight:600} .im-upload-box{border:2px dashed #cbd5e1;border-radius:10px;padding:28px 20px;text-align:center; cursor:pointer;background:#f8fafc;position:relative;transition:all .2s} .im-upload-box:hover,.im-upload-box.drag{border-color:#009dff;background:#e6f9ff} .im-upload-box input[type=file]{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%;height:100%} .im-upload-box p{margin:0;color:#64748b;font-size:14px} .im-upload-icon{font-size:28px;color:#94a3b8;margin-bottom:8px} .im-file-list{margin-top:12px;text-align:left} .im-file-item{font-size:13px;color:#374151;padding:4px 0;display:flex;align-items:center;gap:6px} .im-file-item::before{content:"📎";font-size:12px} .im-conditional{display:none} .im-field-error{color:#ef4444;font-size:12px;margin-top:4px;display:block;animation:imFadeIn .3s ease} .im-field.has-error .im-input,.im-field.has-error .im-select,.im-field.has-error .im-textarea, .im-field.has-error .im-cs-trigger,.im-declaration.has-error,.im-field.has-error .im-upload-box{border-color:#ef4444} .im-error-msg{color:#ef4444;font-size:12px;margin-top:4px;display:none} .im-notice{padding:14px 18px;border-radius:8px;font-size:14px;margin-bottom:20px} .im-notice.success{background:#d1fae5;color:#065f46;border:1px solid #6ee7b7} .im-notice.error{background:#fee2e2;color:#991b1b;border:1px solid #fca5a5} .im-notice.info{background:#e6f9ff;color:#007acc;border:1px solid #80d4ff} .im-btn{display:inline-flex;align-items:center;gap:8px;padding:13px 32px;background:linear-gradient(135deg,#009dff,#3de1fe,#53eee0);color:#fff; border:none;border-radius:8px;font-size:16px;font-weight:700;cursor:pointer;transition:all .3s; font-family:inherit;margin-top:8px;text-shadow:0 1px 2px rgba(0,0,0,.1)} .im-btn:hover{background:linear-gradient(135deg,#0088e0,#30cce8,#45ddd2);transform:translateY(-1px);box-shadow:0 4px 12px rgba(0,157,255,.3)} .im-btn:disabled{background:#94a3b8;cursor:not-allowed;transform:none;box-shadow:none} .im-btn-wrap{margin-top:28px;border-top:1px solid #f3f4f6;padding-top:24px} .im-declaration{background:#f9fafb;border:1px solid #e5e7eb;border-radius:10px;padding:20px 24px;margin-top:24px} .im-declaration label{display:flex;align-items:flex-start;gap:10px;font-size:14px;color:#374151;cursor:pointer;margin-bottom:12px;position:relative} .im-declaration label:last-child{margin-bottom:0} .im-declaration input[type=checkbox]{position:absolute;opacity:0;width:0;height:0;pointer-events:none} .im-declaration .im-ck{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px; border:2px solid #d1d5db;border-radius:4px;flex-shrink:0;transition:all .2s;background:#fff;margin-top:1px} .im-declaration .im-ck::after{content:"";width:5px;height:9px;border:solid #fff;border-width:0 2px 2px 0; transform:rotate(45deg);opacity:0;transition:opacity .15s;margin-top:-1px} .im-declaration input:checked~.im-ck{background:linear-gradient(135deg,#009dff,#3de1fe,#53eee0);border-color:transparent} .im-declaration input:checked~.im-ck::after{opacity:1} .im-step-badge{display:inline-block;background:#e6f9ff;color:#009dff;border:1px solid #80d4ff; border-radius:20px;padding:4px 14px;font-size:13px;font-weight:600;margin-bottom:16px} .im-cs{position:relative;width:100%} .im-cs .im-select{display:none} .im-cs-trigger{display:flex;align-items:center;justify-content:space-between;width:100%;padding:11px 14px; border:1.5px solid #d1d5db;border-radius:8px;font-size:15px;color:#111827;background:#fff; cursor:pointer;transition:all .2s;box-sizing:border-box;font-family:inherit;outline:none;user-select:none} .im-cs-trigger:hover{border-color:#009dff} .im-cs.open .im-cs-trigger{border-color:#009dff;box-shadow:0 0 0 3px rgba(0,157,255,.15);border-radius:8px 8px 0 0} .im-cs-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .im-cs-ph{color:#9ca3af} .im-cs-arrow{width:18px;height:18px;flex-shrink:0;margin-left:8px;transition:transform .25s ease;color:#9ca3af} .im-cs.open .im-cs-arrow{transform:rotate(180deg);color:#009dff} .im-cs-drop{position:absolute;top:100%;left:0;right:0;background:#fff;border:1.5px solid #009dff;border-top:none; border-radius:0 0 8px 8px;z-index:100;visibility:hidden;opacity:0;transform:translateY(-6px); transition:all .2s ease;pointer-events:none;max-height:280px;overflow-y:auto; box-shadow:0 8px 24px rgba(0,157,255,.1)} .im-cs.open .im-cs-drop{visibility:visible;opacity:1;transform:translateY(0);pointer-events:auto} .im-cs-search-wrap{padding:8px 10px;border-bottom:1px solid #f3f4f6;position:sticky;top:0;background:#fff;z-index:1} .im-cs-search{width:100%;padding:8px 12px;border:1.5px solid #e5e7eb;border-radius:6px;font-size:13px;font-family:inherit; outline:none;box-sizing:border-box;transition:border-color .2s} .im-cs-search:focus{border-color:#009dff} .im-cs-opt{padding:10px 14px;cursor:pointer;font-size:14px;color:#374151;transition:background .1s,color .1s; display:flex;align-items:center;gap:8px} .im-cs-opt:hover{background:#e6f9ff;color:#009dff} .im-cs-opt.sel{color:#009dff;font-weight:600;background:#f0faff} .im-cs-opt.sel::before{content:"✓";font-size:12px;font-weight:700} .im-cs-opt.hid{display:none} .im-cs-empty{padding:20px 16px;text-align:center;color:#9ca3af;font-size:13px} .im-cs-drop::-webkit-scrollbar{width:5px} .im-cs-drop::-webkit-scrollbar-track{background:transparent} .im-cs-drop::-webkit-scrollbar-thumb{background:#d1d5db;border-radius:3px} .im-cs-drop::-webkit-scrollbar-thumb:hover{background:#9ca3af} @keyframes imSpin{to{transform:rotate(360deg)}} @keyframes imFadeIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}} .im-fade-in{animation:imFadeIn .5s ease} .im-btn-loading{position:relative;color:transparent!important} .im-btn-loading::after{content:"";position:absolute;width:20px;height:20px;top:50%;left:50%;margin:-10px 0 0 -10px; border:3px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:imSpin .6s linear infinite} '; echo ''; } add_action('wp_ajax_im_get_cities', 'im_ajax_get_cities'); add_action('wp_ajax_nopriv_im_get_cities', 'im_ajax_get_cities'); function im_ajax_get_cities() { global $wpdb; $country_code = sanitize_text_field($_POST['country'] ?? ''); if (!$country_code) wp_send_json_success([]); $cities = $wpdb->get_results($wpdb->prepare("SELECT name FROM cities WHERE country_code = %s ORDER BY name ASC", $country_code)); $res = []; foreach ($cities as $c) $res[] = $c->name; wp_send_json_success($res); } /* ============================================================ AJAX Handlers ============================================================ */ add_action('wp_ajax_im_joinus_submit', 'im_ajax_joinus'); add_action('wp_ajax_nopriv_im_joinus_submit', 'im_ajax_joinus'); function im_ajax_joinus() { if (!wp_verify_nonce($_POST['im_joinus_nonce'] ?? '', 'im_joinus_submit')) { wp_send_json_error(['message' => 'Security verification failed. Please refresh and try again.']); } $first = sanitize_text_field(trim($_POST['first_name'] ?? '')); $last = sanitize_text_field(trim($_POST['last_name'] ?? '')); $email = sanitize_email(trim($_POST['email'] ?? '')); if (!$first || !$last || !$email) wp_send_json_error(['message' => 'Please fill in all required fields.']); if (!is_email($email)) wp_send_json_error(['message' => 'Please enter a valid email address.']); $id = IM_Candidate::create_from_joinus($first, $last, $email); if (!$id) wp_send_json_error(['message' => 'Submission failed. Please try again later.']); IM_Mailer::send_joinus_confirmation($id); wp_send_json_success(['message' => 'ok']); } add_action('wp_ajax_im_apply_submit', 'im_ajax_apply'); add_action('wp_ajax_nopriv_im_apply_submit', 'im_ajax_apply'); function im_ajax_apply() { $apply_token = sanitize_text_field($_POST['im_apply_token'] ?? ''); $candidate = $apply_token ? IM_Candidate::get_by_apply_token($apply_token) : null; if (!$candidate) wp_send_json_error(['messages' => ['Invalid or expired application link.']]); if (!wp_verify_nonce($_POST['im_apply_nonce'] ?? '', 'im_apply_submit_' . $candidate->id)) { wp_send_json_error(['messages' => ['Security verification failed. Please refresh and try again.']]); } $errors = []; $field_errors = []; $required = [ 'preferred_name'=>'Preferred Name','country'=>'Country','city'=>'City','phone'=>'Phone Number', 'degree_level'=>'Highest Degree Level','university'=>'University','major'=>'Major', 'grad_year'=>'Graduation Year','gpa'=>'GPA','languages'=>'English Fluency','teaching_exp'=>'Teaching Experience', ]; foreach ($required as $field => $label) { if (empty(trim($_POST[$field] ?? ''))) $field_errors[$field] = "\"$label\" is required."; } if (empty($_POST['deans_list'])) $field_errors['deans_list'] = 'Please select an option.'; if (!isset($_POST['ca_highschool']) || $_POST['ca_highschool'] === '') $field_errors['ca_highschool'] = 'Please select an option.'; if (empty($_POST['subjects'])) $field_errors['subjects'] = 'Please select at least one teaching subject.'; if (empty($_FILES['transcript_files']['name'][0])) $field_errors['transcript_files'] = 'Transcript upload is required.'; if (empty($_POST['decl_truth'])) $field_errors['decl_truth'] = ''; if (empty($_POST['decl_privacy'])) $field_errors['decl_privacy'] = ''; $degree_level = sanitize_text_field($_POST['degree_level'] ?? ''); if (in_array($degree_level, ["Master's", "PhD"])) { if (empty(trim($_POST['ug_university'] ?? ''))) $field_errors['ug_university'] = '"Undergraduate University" is required.'; if (empty(trim($_POST['ug_major'] ?? ''))) $field_errors['ug_major'] = '"Undergraduate Major" is required.'; if (empty(trim($_POST['ug_grad_year'] ?? ''))) $field_errors['ug_grad_year'] = '"Undergraduate Graduation Year" is required.'; } $has_ach = (int)($_POST['has_achievement'] ?? 0); $has_ca_hs = (int)($_POST['ca_highschool'] ?? 0); if ($has_ca_hs && empty(trim($_POST['ca_highschool_name'] ?? ''))) { $field_errors['ca_highschool_name'] = 'Please enter your high school name.'; } if ($has_ach) { if (empty($_POST['achievement_type'])) $field_errors['achievement_type'] = 'Please select an achievement type.'; if (($_POST['achievement_type'] ?? '') === 'other' && empty(trim($_POST['achievement_desc'] ?? ''))) { $field_errors['achievement_desc'] = 'Please specify your achievement description.'; } if (empty($_FILES['achievement_files']['name'][0])) { $field_errors['achievement_files'] = 'Supporting documents must be uploaded when listing achievements.'; } } if ($field_errors) wp_send_json_error(['field_errors' => $field_errors]); $data = [ 'preferred_name'=>$_POST['preferred_name']??'','phone'=>$_POST['phone']??'', 'country'=>$_POST['country']??'','city'=>$_POST['city']??'', 'degree_level'=>$_POST['degree_level']??'','university'=>$_POST['university']??'','major'=>$_POST['major']??'', 'grad_year'=>$_POST['grad_year']??'','gpa'=>$_POST['gpa']??'','deans_list'=>(int)(($_POST['deans_list']??'')==='yes'), 'ug_university'=>$_POST['ug_university']??'','ug_major'=>$_POST['ug_major']??'','ug_grad_year'=>$_POST['ug_grad_year']??'', 'ms_university'=>$_POST['ms_university']??'','ms_major'=>$_POST['ms_major']??'','ms_grad_year'=>$_POST['ms_grad_year']??'', 'ca_highschool'=>$has_ca_hs,'ca_highschool_name'=>$_POST['ca_highschool_name']??'', 'languages'=>$_POST['languages']??'','teaching_exp'=>$_POST['teaching_exp']??'', 'has_achievement'=>$has_ach,'achievement_type'=>$_POST['achievement_type']??'', 'achievement_desc'=>$_POST['achievement_desc']??'','subjects'=>$_POST['subjects']??[],'extra_notes'=>$_POST['extra_notes']??'', ]; IM_Candidate::update_full($candidate->id, $data); $upload_dir = wp_upload_dir(); $save_dir = $upload_dir['basedir'] . '/im-applications/' . $candidate->id; wp_mkdir_p($save_dir); file_put_contents($save_dir . '/index.html', ''); $allowed_mime = ['application/pdf','image/jpeg','image/png','image/jpg']; foreach (['transcript_files','achievement_files','extra_files'] as $field) { if (empty($_FILES[$field]['name'])) continue; $files = $_FILES[$field]; $count = is_array($files['name']) ? count($files['name']) : 1; for ($i = 0; $i < $count; $i++) { $name = is_array($files['name']) ? $files['name'][$i] : $files['name']; $tmp = is_array($files['tmp_name']) ? $files['tmp_name'][$i] : $files['tmp_name']; $err = is_array($files['error']) ? $files['error'][$i] : $files['error']; if ($err !== UPLOAD_ERR_OK || !$tmp) continue; $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $tmp); finfo_close($finfo); if (!in_array($mime, $allowed_mime, true)) continue; $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); $dest = $save_dir . '/' . $field . '_' . $i . '_' . time() . '.' . $ext; if (move_uploaded_file($tmp, $dest)) IM_Attachment::add($candidate->id, $dest, $name, $field); } } IM_Mailer::send_apply_confirmation($candidate->id); wp_send_json_success(['message' => 'ok']); } /* ============================================================ Shortcode 1: [im_joinus_form] — Join Us Simple Form ============================================================ */ add_shortcode('im_joinus_form', function() { im_enqueue_form_styles(); ob_start(); ?>
Step 1 of 2

Join Us

Please provide your basic information below to receive a link to the detailed application form via email.

apply_token_used): ?>

Application Already Submitted

You have already submitted your application form.

Our team will contact you after review, which typically takes 3–5 business days. Thank you for your patience!

!

Link Expired

This link has expired. Please fill out the Join Us form again, and we’ll send you a new application link shortly.

apply_opened_at)) { IM_Candidate::mark_apply_opened($candidate->id); } $p = []; $degree = ''; $has_ach = -1; ?>
Step 2 of 2

Application Form

Hello, first_name) ?>! Please complete all the information below.

id, 'im_apply_nonce'); ?>
Part 1: Personal Information
Part 2: Education Background
"Bachelor’s", "Master’s" => "Master’s", 'PhD' => 'PhD'] as $val => $lbl): ?>
Master's Degree (Optional) Skip if not applicable.
Undergraduate Degree
📄

Click to select or drag files here

Part 3: English Fluency
Part 4: Experience & Achievements
🏆

Click to select or drag supporting documents

Part 5: Teaching Subjects (Select All That Apply)*
'subject_cat', 'hide_empty' => false, 'orderby' => 'name' ]); $sel_subjects = (array)($p['subjects'] ?? []); if (!is_wp_error($subject_cats) && !empty($subject_cats)): foreach ($subject_cats as $cat): $subjects = get_posts([ 'post_type' => 'subject', 'posts_per_page' => -1, 'tax_query' => [ [ 'taxonomy' => 'subject_cat', 'field' => 'term_id', 'terms' => $cat->term_id ] ], 'orderby' => 'title', 'order' => 'ASC' ]); if (empty($subjects)) continue; ?>
🔹 name) ?>
ID, $sel_subjects, true) ? 'checked' : ''; ?>
Part 6: Additional Documents (Optional)
📎

Additional materials (resume, reference letters, etc.)

PDF / JPG / PNG supported, multiple files allowed

Part 7: Declaration & Submission