{"id":390,"date":"2026-01-15T08:49:31","date_gmt":"2026-01-15T07:49:31","guid":{"rendered":"http:\/\/traveltennis.com\/?page_id=390"},"modified":"2026-01-20T12:27:41","modified_gmt":"2026-01-20T11:27:41","slug":"3-inside-travel-tennis","status":"publish","type":"page","link":"https:\/\/traveltennis.com\/en\/3-inside-travel-tennis\/","title":{"rendered":"3. Inside Travel Tennis"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"390\" class=\"elementor elementor-390\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d317396 e-flex e-con-boxed e-con e-parent\" data-id=\"d317396\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-46ef0f1 elementor-widget elementor-widget-html\" data-id=\"46ef0f1\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<section style=\"background:#000; color:#fff; padding:90px 20px;\">\n  <div style=\"max-width:1200px; margin:0 auto;\">\n\n    <!-- ===== HERO ===== -->\n    <div style=\"text-align:center; margin-bottom:70px;\">\n      <span style=\"        display:inline-block;        padding:8px 18px;        border-radius:999px;        background:rgba(255,255,255,0.08);        font-size:13px;        font-weight:700;        letter-spacing:.5px;        margin-bottom:18px;      \">\n        \ud83d\udd12 ESPACE MEMBRES\n      <\/span>\n\n      <h1 style=\"        font-size:44px;        line-height:1.15;        margin:0 0 20px;        font-weight:900;      \">\n        Inside <span style=\"color:#E76F1D;\">Travel Tennis<\/span>\n      <\/h1>\n\n      <p style=\"        max-width:760px;        margin:0 auto;        font-size:17px;        line-height:1.7;        color:#d1d5db;      \">\n        Inside Travel Tennis est l\u2019espace r\u00e9serv\u00e9 aux <strong>joueurs<\/strong> et aux <strong>coachs<\/strong>\n        engag\u00e9s dans un projet structur\u00e9.  \n        Un lieu pour suivre, \u00e9changer, analyser, progresser\u2026 et garder une trace\n        de l\u2019aventure Travel Tennis.\n      <\/p>\n    <\/div>\n\n    <!-- ===== BLOCS ===== -->\n    <div style=\"      display:grid;      grid-template-columns:repeat(3, 1fr);      gap:26px;    \">\n\n      <!-- JOUEURS -->\n      <article style=\"        background:linear-gradient(160deg,#111 0%, #050505 100%);        border-radius:22px;        padding:32px;        border:1px solid rgba(255,255,255,0.08);        box-shadow:0 30px 80px rgba(0,0,0,.6);      \">\n        <h3 style=\"margin:0 0 12px; font-size:22px;\">\n          \ud83c\udfbe Le terrain des joueurs\n        <\/h3>\n\n        <p style=\"color:#cbd5e1; line-height:1.65;\">\n          L\u2019espace personnel des joueurs Travel Tennis.  \n          Un outil pour structurer le travail, fixer des objectifs clairs\n          et suivre sa progression tout au long de la saison.\n        <\/p>\n\n        <ul style=\"          list-style:none;          padding:0;          margin:18px 0;          display:grid;          gap:10px;          font-size:14px;        \">\n          <li>\u2714\ufe0f Fixation d\u2019objectifs sportifs<\/li>\n          <li>\u2714\ufe0f Suivi individuel & bilans<\/li>\n          <li>\u2714\ufe0f Vision long terme du projet<\/li>\n        <\/ul>\n\n        <a href=\"http:\/\/traveltennis.com\/en\/le-terrain-des-joueurs\/\" style=\"          display:inline-block;          margin-top:12px;          background:#1F5F3B;          color:#fff;          padding:12px 18px;          border-radius:999px;          font-weight:800;          font-size:14px;          text-decoration:none;        \">\n          Acc\u00e9der \u00e0 l\u2019espace joueur\n        <\/a>\n      <\/article>\n\n      <!-- COACHS -->\n      <article style=\"        background:linear-gradient(160deg,#111 0%, #050505 100%);        border-radius:22px;        padding:32px;        border:1px solid rgba(255,255,255,0.08);        box-shadow:0 30px 80px rgba(0,0,0,.6);      \">\n        <h3 style=\"margin:0 0 12px; font-size:22px;\">\n          \ud83c\udfa7 La tribune des coachs\n        <\/h3>\n\n        <p style=\"color:#cbd5e1; line-height:1.65;\">\n          L\u2019espace r\u00e9serv\u00e9 aux coachs Travel Tennis.  \n          Un lieu d\u2019\u00e9change, d\u2019analyse et de coordination\n          autour des joueurs et de leurs projets.\n        <\/p>\n\n        <ul style=\"          list-style:none;          padding:0;          margin:18px 0;          display:grid;          gap:10px;          font-size:14px;        \">\n          <li>\u2714\ufe0f Suivi des joueurs<\/li>\n          <li>\u2714\ufe0f Observations & feedbacks<\/li>\n          <li>\u2714\ufe0f Vision commune staff \/ projet<\/li>\n        <\/ul>\n\n        <a href=\"http:\/\/traveltennis.com\/en\/la-tribune-des-coachs\/\" style=\"          display:inline-block;          margin-top:12px;          background:#E76F1D;          color:#000;          padding:12px 18px;          border-radius:999px;          font-weight:900;          font-size:14px;          text-decoration:none;        \">\n          Acc\u00e9der \u00e0 l\u2019espace coach\n        <\/a>\n      <\/article>\n\n      <!-- RETRO -->\n      <article style=\"        background:linear-gradient(160deg,#111 0%, #050505 100%);        border-radius:22px;        padding:32px;        border:1px solid rgba(255,255,255,0.08);        box-shadow:0 30px 80px rgba(0,0,0,.6);      \">\n        <h3 style=\"margin:0 0 12px; font-size:22px;\">\n          \ud83d\udcf8 La R\u00e9tro\n        <\/h3>\n\n        <p style=\"color:#cbd5e1; line-height:1.65;\">\n          L\u2019espace souvenirs Travel Tennis.  \n          Photos, moments forts, r\u00e9sultats marquants\n          et histoire de l\u2019aventure depuis les d\u00e9buts.\n        <\/p>\n\n        <ul style=\"          list-style:none;          padding:0;          margin:18px 0;          display:grid;          gap:10px;          font-size:14px;        \">\n          <li>\u2714\ufe0f Albums photos des stages<\/li>\n          <li>\u2714\ufe0f R\u00e9sultats & performances<\/li>\n          <li>\u2714\ufe0f M\u00e9moire collective Travel Tennis<\/li>\n        <\/ul>\n\n        <a href=\"http:\/\/traveltennis.com\/en\/la-retro\/\" style=\"          display:inline-block;          margin-top:12px;          background:#fff;          color:#000;          padding:12px 18px;          border-radius:999px;          font-weight:900;          font-size:14px;          text-decoration:none;        \">\n          Entrer dans la R\u00e9tro\n        <\/a>\n      <\/article>\n\n    <\/div>\n\n    <!-- FOOTER NOTE -->\n    <div style=\"      text-align:center;      margin-top:70px;      font-size:14px;      color:#9ca3af;    \">\n      Inside Travel Tennis est accessible aux membres engag\u00e9s dans un projet suivi\n      par l\u2019\u00e9quipe Travel Tennis.\n    <\/div>\n\n  <\/div>\n<\/section>\n\n<style>\n@media (max-width: 900px){\n  section > div > div:nth-child(2){\n    grid-template-columns:1fr !important;\n  }\n}\n<\/style>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-40c7cc5 e-flex e-con-boxed e-con e-parent\" data-id=\"40c7cc5\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b170dee elementor-widget elementor-widget-html\" data-id=\"b170dee\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t\/* =========================================================\n   Travel Tennis - Inside (Login + App Joueurs) via shortcode\n   Shortcode: [tt_inside_players]\n   ========================================================= *\/\nadd_shortcode('tt_inside_players', function () {\n\n  \/\/ URL actuelle (pour rediriger apr\u00e8s login)\n  $current_url = (is_ssl() ? 'https:\/\/' : 'http:\/\/') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];\n\n  \/\/ Si pas connect\u00e9 => affiche un login WP natif\n  if (!is_user_logged_in()) {\n    ob_start(); ?>\n    <section style=\"padding:90px 20px; background:linear-gradient(135deg,#000 0%, #0E0E0E 50%, #000 100%); color:#fff; border-radius:18px; max-width:1100px; margin:24px auto;\">\n      <div style=\"max-width:760px; margin:0 auto; text-align:center;\">\n        <div style=\"display:inline-block; padding:8px 18px; border-radius:999px; background:rgba(255,255,255,0.10); border:1px solid rgba(255,255,255,0.10); font-weight:800; font-size:13px; letter-spacing:.4px;\">\n          \ud83d\udd12 ESPACE MEMBRES\n        <\/div>\n\n        <h1 style=\"margin:18px 0 10px; font-size:42px; line-height:1.1; color:#E76F1D; text-shadow:0 0 18px rgba(231,111,29,0.35);\">\n          Inside Travel Tennis\n        <\/h1>\n\n        <p style=\"margin:0 auto 22px; font-size:16px; line-height:1.7; color:rgba(255,255,255,0.90);\">\n          Cet espace est r\u00e9serv\u00e9 aux membres Travel Tennis (joueurs & coachs).\n          Connecte-toi pour acc\u00e9der \u00e0 tes outils de suivi.\n        <\/p>\n\n        <div style=\"background:#fff; color:#0F172A; border-radius:16px; padding:18px; text-align:left; border:1px solid rgba(255,255,255,0.10);\">\n          <?php\n            wp_login_form([\n              'echo'           => true,\n              'redirect'       => $current_url,\n              'remember'       => true,\n              'label_username' => 'Identifiant ou email',\n              'label_password' => 'Mot de passe',\n              'label_remember' => 'Se souvenir de moi',\n              'label_log_in'   => 'Se connecter',\n            ]);\n          ?>\n          <p style=\"margin:10px 0 0; font-size:13px; color:#475569;\">\n            Mot de passe oubli\u00e9 ? <a href=\"\/en\/<\/?php echo esc_url(wp_lostpassword_url($current_url)); ?>\">Clique ici<\/a>.\n          <\/p>\n        <\/div>\n      <\/div>\n    <\/section>\n    <?php\n    return ob_get_clean();\n  }\n\n  \/\/ Connect\u00e9 => zone priv\u00e9e + app joueurs\n  $logout_url = wp_logout_url($current_url);\n\n  ob_start(); ?>\n  <section style=\"max-width:1100px; margin:24px auto; padding:0 20px;\">\n\n    <!-- HERO priv\u00e9 -->\n    <div style=\"padding:60px 22px; border-radius:18px; background:linear-gradient(135deg,#000 0%, #0E0E0E 50%, #000 100%); color:#fff; overflow:hidden; border:1px solid rgba(255,255,255,0.08); box-shadow:0 18px 55px rgba(0,0,0,0.18);\">\n      <div style=\"display:flex; gap:18px; align-items:center; justify-content:space-between; flex-wrap:wrap;\">\n        <div style=\"min-width:260px;\">\n          <div style=\"display:inline-block; padding:8px 16px; border-radius:999px; background:rgba(255,255,255,0.10); border:1px solid rgba(255,255,255,0.10); font-weight:900; font-size:13px;\">\n            \u2705 Acc\u00e8s membre activ\u00e9\n          <\/div>\n          <h2 style=\"margin:14px 0 10px; font-size:34px; line-height:1.1; color:#E76F1D; text-shadow:0 0 18px rgba(231,111,29,0.35);\">\n            Le terrain des joueurs\n          <\/h2>\n          <p style=\"margin:0; color:rgba(255,255,255,0.90); line-height:1.7; max-width:640px;\">\n            Fixe tes objectifs, suis tes entra\u00eenements et garde une trace de ta progression.\n          <\/p>\n        <\/div>\n\n        <div>\n          <a href=\"\/en\/<\/?php echo esc_url($logout_url); ?>\" style=\"background:rgba(255,255,255,0.10); border:1px solid rgba(255,255,255,0.14); color:#fff; text-decoration:none; padding:10px 14px; border-radius:12px; font-weight:900;\">\n            Se d\u00e9connecter\n          <\/a>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- APP JOUEUR (maquette fonctionnelle) -->\n    <div style=\"margin-top:18px; display:grid; grid-template-columns: 1.2fr 0.8fr; gap:18px;\">\n\n      <!-- Colonne gauche -->\n      <div style=\"background:#fff; border:1px solid rgba(11,45,69,0.10); border-radius:18px; padding:18px; box-shadow:0 10px 22px rgba(0,0,0,0.06);\">\n        <h3 style=\"margin:0 0 10px; font-size:22px; color:#0B2D45;\">\ud83c\udfaf Objectifs<\/h3>\n        <p style=\"margin:0 0 14px; color:#475569; line-height:1.6;\">\n          Ajoute des objectifs (technique \/ tactique \/ physique \/ mental), d\u00e9finis une date, puis coche quand c\u2019est valid\u00e9.\n          (Cette V1 est stock\u00e9e sur ton navigateur.)\n        <\/p>\n\n        <div style=\"display:grid; grid-template-columns: 1fr 160px; gap:10px; margin-bottom:10px;\">\n          <input id=\"ttGoalText\" type=\"text\" placeholder=\"Ex: Am\u00e9liorer 1re balle (60% +)\" style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n          <input id=\"ttGoalDate\" type=\"date\" style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n        <\/div>\n\n        <div style=\"display:grid; grid-template-columns: 1fr 180px; gap:10px; margin-bottom:14px;\">\n          <select id=\"ttGoalCat\" style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n            <option value=\"Technique\">Technique<\/option>\n            <option value=\"Tactique\">Tactique<\/option>\n            <option value=\"Physique\">Physique<\/option>\n            <option value=\"Mental\">Mental<\/option>\n          <\/select>\n          <button id=\"ttAddGoal\" style=\"background:#1F5F3B; color:#fff; border:none; border-radius:12px; font-weight:900; cursor:pointer;\">\n            + Ajouter\n          <\/button>\n        <\/div>\n\n        <div id=\"ttGoalsList\" style=\"display:grid; gap:10px;\"><\/div>\n      <\/div>\n\n      <!-- Colonne droite -->\n      <aside style=\"background:#F4F6F8; border:1px solid rgba(11,45,69,0.10); border-radius:18px; padding:18px;\">\n        <h3 style=\"margin:0 0 10px; font-size:18px; color:#0B2D45;\">\ud83d\udcd2 Journal rapide<\/h3>\n        <p style=\"margin:0 0 10px; font-size:13px; color:#475569; line-height:1.6;\">\n          Note ton ressenti du jour (\u00e9nergie, confiance, focus) et un point \u00e0 retenir.\n        <\/p>\n\n        <textarea id=\"ttNote\" rows=\"6\" placeholder=\"Ex: Bon focus \u00e0 l\u2019entra\u00eenement, \u00e0 travailler: retour revers\u2026\"\n          style=\"width:100%; padding:12px; border-radius:12px; border:1px solid #CBD5E1;\"><\/textarea>\n\n        <div style=\"display:flex; gap:10px; margin-top:10px;\">\n          <button id=\"ttSaveNote\" style=\"flex:1; background:#0B2D45; color:#fff; border:none; border-radius:12px; font-weight:900; padding:12px; cursor:pointer;\">\n            Enregistrer\n          <\/button>\n          <button id=\"ttClearAll\" style=\"background:transparent; border:1px solid rgba(11,45,69,0.25); color:#0B2D45; border-radius:12px; font-weight:900; padding:12px; cursor:pointer;\">\n            Reset\n          <\/button>\n        <\/div>\n\n        <div id=\"ttSaved\" style=\"margin-top:12px; font-size:13px; color:#1F5F3B; font-weight:900; display:none;\">\n          \u2705 Sauvegard\u00e9\n        <\/div>\n\n        <div style=\"margin-top:14px; padding:12px; border-radius:14px; background:#fff; border:1px solid rgba(11,45,69,0.08);\">\n          <strong style=\"color:#0B2D45;\">Prochaine \u00e9tape (V2)<\/strong>\n          <p style=\"margin:6px 0 0; font-size:13px; color:#475569; line-height:1.55;\">\n            Synchronisation serveur (compte joueur), acc\u00e8s coach, export PDF, et modules tournoi.\n          <\/p>\n        <\/div>\n      <\/aside>\n\n    <\/div>\n\n    <style>\n      @media (max-width: 980px){\n        #ttGoalsList{ }\n        section[style*=\"grid-template-columns\"]{ grid-template-columns: 1fr !important; }\n      }\n      .tt-goal{\n        display:grid;\n        grid-template-columns: 28px 1fr 120px 34px;\n        gap:10px;\n        align-items:center;\n        padding:12px;\n        border-radius:14px;\n        border:1px solid rgba(11,45,69,0.10);\n        background:#fff;\n      }\n      .tt-goal small{ color:#64748B; font-weight:800; }\n      .tt-pill-cat{\n        display:inline-flex;\n        justify-content:center;\n        align-items:center;\n        padding:6px 10px;\n        border-radius:999px;\n        font-weight:900;\n        font-size:12px;\n        background:rgba(231,111,29,0.10);\n        color:#E76F1D;\n        border:1px solid rgba(231,111,29,0.20);\n        white-space:nowrap;\n      }\n      .tt-del{\n        width:34px; height:34px;\n        border-radius:12px;\n        border:1px solid rgba(11,45,69,0.12);\n        background:#F8FAFC;\n        cursor:pointer;\n        font-weight:900;\n      }\n      .tt-check{\n        width:18px; height:18px;\n      }\n      .tt-done{\n        opacity:0.65;\n      }\n      .tt-done .tt-titleline{\n        text-decoration: line-through;\n      }\n    <\/style>\n\n    <script>\n      (function(){\n        const KEY_GOALS = \"tt_player_goals_v1\";\n        const KEY_NOTE  = \"tt_player_note_v1\";\n\n        const $ = (id)=>document.getElementById(id);\n        const goalsList = $(\"ttGoalsList\");\n        const goalText  = $(\"ttGoalText\");\n        const goalDate  = $(\"ttGoalDate\");\n        const goalCat   = $(\"ttGoalCat\");\n        const addBtn    = $(\"ttAddGoal\");\n        const note      = $(\"ttNote\");\n        const saveNote  = $(\"ttSaveNote\");\n        const clearAll  = $(\"ttClearAll\");\n        const saved     = $(\"ttSaved\");\n\n        function loadGoals(){\n          try { return JSON.parse(localStorage.getItem(KEY_GOALS) || \"[]\"); }\n          catch(e){ return []; }\n        }\n        function saveGoals(goals){\n          localStorage.setItem(KEY_GOALS, JSON.stringify(goals));\n        }\n\n        function render(){\n          const goals = loadGoals();\n          goalsList.innerHTML = \"\";\n\n          if(goals.length === 0){\n            goalsList.innerHTML = '<div style=\"padding:14px; border-radius:14px; background:#F8FAFC; border:1px dashed rgba(11,45,69,0.18); color:#475569; font-weight:800;\">Ajoute ton premier objectif \ud83c\udfaf<\/div>';\n            return;\n          }\n\n          goals.forEach((g, idx)=>{\n            const el = document.createElement(\"div\");\n            el.className = \"tt-goal\" + (g.done ? \" tt-done\" : \"\");\n            el.innerHTML = `\n              <input class=\"tt-check\" type=\"checkbox\" ${g.done ? \"checked\" : \"\"} aria-label=\"Valider\">\n              <div>\n                <div class=\"tt-titleline\" style=\"font-weight:900; color:#0B2D45;\">${escapeHtml(g.text)}<\/div>\n                <small>${escapeHtml(g.date || \"Sans date\")}<\/small>\n              <\/div>\n              <span class=\"tt-pill-cat\">${escapeHtml(g.cat)}<\/span>\n              <button class=\"tt-del\" title=\"Supprimer\">\u00d7<\/button>\n            `;\n\n            el.querySelector(\".tt-check\").addEventListener(\"change\", (e)=>{\n              const goals = loadGoals();\n              goals[idx].done = e.target.checked;\n              saveGoals(goals);\n              render();\n            });\n\n            el.querySelector(\".tt-del\").addEventListener(\"click\", ()=>{\n              const goals = loadGoals();\n              goals.splice(idx, 1);\n              saveGoals(goals);\n              render();\n            });\n\n            goalsList.appendChild(el);\n          });\n        }\n\n        function escapeHtml(str){\n          return String(str).replace(\/[&<>\"']\/g, (m)=>({\n            \"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#039;\"\n          }[m]));\n        }\n\n        if(addBtn){\n          addBtn.addEventListener(\"click\", ()=>{\n            const text = (goalText.value || \"\").trim();\n            if(!text) return;\n\n            const goals = loadGoals();\n            goals.unshift({\n              text,\n              date: goalDate.value || \"\",\n              cat: goalCat.value || \"Technique\",\n              done: false,\n              ts: Date.now()\n            });\n            saveGoals(goals);\n\n            goalText.value = \"\";\n            goalDate.value = \"\";\n            goalCat.value = \"Technique\";\n            render();\n          });\n        }\n\n        \/\/ Note\n        if(note){\n          note.value = localStorage.getItem(KEY_NOTE) || \"\";\n        }\n        if(saveNote){\n          saveNote.addEventListener(\"click\", ()=>{\n            localStorage.setItem(KEY_NOTE, note.value || \"\");\n            if(saved){\n              saved.style.display = \"block\";\n              setTimeout(()=> saved.style.display = \"none\", 1200);\n            }\n          });\n        }\n\n        if(clearAll){\n          clearAll.addEventListener(\"click\", ()=>{\n            localStorage.removeItem(KEY_GOALS);\n            localStorage.removeItem(KEY_NOTE);\n            if(note) note.value = \"\";\n            render();\n          });\n        }\n\n        render();\n      })();\n    <\/script>\n\n  <\/section>\n  <?php\n  return ob_get_clean();\n});\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-49ed15c e-flex e-con-boxed e-con e-parent\" data-id=\"49ed15c\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-46d25a7 elementor-widget elementor-widget-shortcode\" data-id=\"46d25a7\" data-element_type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">[tt_inside_players]\n<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-663be2e e-flex e-con-boxed e-con e-parent\" data-id=\"663be2e\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-40a952a elementor-widget elementor-widget-html\" data-id=\"40a952a\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- ============================== -->\n<!-- TRAVEL TENNIS \u2022 APP JOUEUR V1  -->\n<!-- Objectifs + S\u00e9ances + Notes    -->\n<!-- Stockage local navigateur      -->\n<!-- ============================== -->\n\n<section id=\"ttPlayerApp\" style=\"max-width:1140px; margin:24px auto; padding:0 20px;\">\n\n  <!-- HERO -->\n  <div style=\"padding:60px 22px; border-radius:18px; background:linear-gradient(135deg,#000 0%, #0E0E0E 50%, #000 100%); color:#fff; overflow:hidden; border:1px solid rgba(255,255,255,0.08); box-shadow:0 18px 55px rgba(0,0,0,0.18);\">\n    <div style=\"display:flex; gap:18px; align-items:center; justify-content:space-between; flex-wrap:wrap;\">\n      <div style=\"min-width:260px;\">\n        <div style=\"display:inline-block; padding:8px 16px; border-radius:999px; background:rgba(255,255,255,0.10); border:1px solid rgba(255,255,255,0.10); font-weight:900; font-size:13px;\">\n          \ud83c\udfbe Le terrain des joueurs\n        <\/div>\n        <h1 style=\"margin:14px 0 10px; font-size:34px; line-height:1.1; color:#E76F1D; text-shadow:0 0 18px rgba(231,111,29,0.35);\">\n          Ton suivi de progression\n        <\/h1>\n        <p style=\"margin:0; color:rgba(255,255,255,0.90); line-height:1.7; max-width:720px;\">\n          Fixe tes objectifs, note tes s\u00e9ances et garde une trace de ce qui fonctionne.\n          <strong>V1<\/strong> : tout est enregistr\u00e9 sur ton appareil (navigateur).\n        <\/p>\n      <\/div>\n\n      <div style=\"display:flex; gap:10px; flex-wrap:wrap;\">\n        <button id=\"ttExport\" style=\"background:rgba(255,255,255,0.10); border:1px solid rgba(255,255,255,0.14); color:#fff; border-radius:12px; padding:10px 14px; font-weight:900; cursor:pointer;\">\n          Exporter\n        <\/button>\n        <button id=\"ttResetAll\" style=\"background:rgba(231,111,29,0.12); border:1px solid rgba(231,111,29,0.25); color:#fff; border-radius:12px; padding:10px 14px; font-weight:900; cursor:pointer;\">\n          Reset\n        <\/button>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <!-- MAIN -->\n  <div style=\"margin-top:18px; display:grid; grid-template-columns: 1.25fr 0.75fr; gap:18px;\">\n\n    <!-- LEFT: Objectifs + S\u00e9ances -->\n    <div style=\"display:grid; gap:18px;\">\n\n      <!-- OBJECTIFS -->\n      <div style=\"background:#fff; border:1px solid rgba(11,45,69,0.10); border-radius:18px; padding:18px; box-shadow:0 10px 22px rgba(0,0,0,0.06);\">\n        <h2 style=\"margin:0 0 8px; font-size:22px; color:#0B2D45;\">\ud83c\udfaf Objectifs<\/h2>\n        <p style=\"margin:0 0 14px; color:#475569; line-height:1.6; font-size:14px;\">\n          Ajoute un objectif, choisis une cat\u00e9gorie et une date cible. Coche quand c\u2019est valid\u00e9.\n        <\/p>\n\n        <div style=\"display:grid; grid-template-columns: 1fr 160px; gap:10px; margin-bottom:10px;\">\n          <input id=\"ttGoalText\" type=\"text\" placeholder=\"Ex : 60% de premi\u00e8res balles en match\"\n                 style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n          <input id=\"ttGoalDate\" type=\"date\"\n                 style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n        <\/div>\n\n        <div style=\"display:grid; grid-template-columns: 1fr 180px; gap:10px; margin-bottom:14px;\">\n          <select id=\"ttGoalCat\" style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n            <option value=\"Technique\">Technique<\/option>\n            <option value=\"Tactique\">Tactique<\/option>\n            <option value=\"Physique\">Physique<\/option>\n            <option value=\"Mental\">Mental<\/option>\n          <\/select>\n          <button id=\"ttAddGoal\" style=\"background:#1F5F3B; color:#fff; border:none; border-radius:12px; font-weight:900; cursor:pointer;\">\n            + Ajouter\n          <\/button>\n        <\/div>\n\n        <div id=\"ttGoalsList\" style=\"display:grid; gap:10px;\"><\/div>\n      <\/div>\n\n      <!-- S\u00c9ANCES -->\n      <div style=\"background:#fff; border:1px solid rgba(11,45,69,0.10); border-radius:18px; padding:18px; box-shadow:0 10px 22px rgba(0,0,0,0.06);\">\n        <h2 style=\"margin:0 0 8px; font-size:22px; color:#0B2D45;\">\ud83d\udcc5 S\u00e9ances<\/h2>\n        <p style=\"margin:0 0 14px; color:#475569; line-height:1.6; font-size:14px;\">\n          Note l\u2019entra\u00eenement du jour : dur\u00e9e, th\u00e8me, et un point cl\u00e9 \u00e0 retenir.\n        <\/p>\n\n        <div style=\"display:grid; grid-template-columns: 160px 140px 1fr; gap:10px; margin-bottom:10px;\">\n          <input id=\"ttSessionDate\" type=\"date\" style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n          <input id=\"ttSessionMin\" type=\"number\" min=\"0\" placeholder=\"Dur\u00e9e (min)\" style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n          <select id=\"ttSessionTheme\" style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n            <option value=\"Tennis\">Tennis<\/option>\n            <option value=\"Physique\">Physique<\/option>\n            <option value=\"Match\">Match<\/option>\n            <option value=\"Mental\">Mental<\/option>\n            <option value=\"R\u00e9cup\u00e9ration\">R\u00e9cup\u00e9ration<\/option>\n          <\/select>\n        <\/div>\n\n        <div style=\"display:grid; grid-template-columns: 1fr 180px; gap:10px; margin-bottom:14px;\">\n          <input id=\"ttSessionKey\" type=\"text\" placeholder=\"Point cl\u00e9 (ex : mont\u00e9e de balle + rel\u00e2chement)\"\n                 style=\"padding:12px; border-radius:12px; border:1px solid #CBD5E1;\">\n          <button id=\"ttAddSession\" style=\"background:#0B2D45; color:#fff; border:none; border-radius:12px; font-weight:900; cursor:pointer;\">\n            + Ajouter\n          <\/button>\n        <\/div>\n\n        <div id=\"ttSessionsList\" style=\"display:grid; gap:10px;\"><\/div>\n      <\/div>\n    <\/div>\n\n    <!-- RIGHT: Dashboard + Notes -->\n    <aside style=\"background:#F4F6F8; border:1px solid rgba(11,45,69,0.10); border-radius:18px; padding:18px;\">\n      <h3 style=\"margin:0 0 10px; font-size:18px; color:#0B2D45;\">\ud83d\udcca Dashboard<\/h3>\n\n      <div style=\"display:grid; gap:10px;\">\n        <div style=\"background:#fff; border:1px solid rgba(11,45,69,0.08); border-radius:14px; padding:12px;\">\n          <div style=\"font-size:12px; font-weight:900; color:#64748B;\">Objectifs actifs<\/div>\n          <div id=\"ttStatGoals\" style=\"font-size:26px; font-weight:900; color:#0B2D45;\">0<\/div>\n        <\/div>\n\n        <div style=\"background:#fff; border:1px solid rgba(11,45,69,0.08); border-radius:14px; padding:12px;\">\n          <div style=\"font-size:12px; font-weight:900; color:#64748B;\">S\u00e9ances (7 jours)<\/div>\n          <div id=\"ttStatSessions7\" style=\"font-size:26px; font-weight:900; color:#0B2D45;\">0<\/div>\n        <\/div>\n\n        <div style=\"background:#fff; border:1px solid rgba(11,45,69,0.08); border-radius:14px; padding:12px;\">\n          <div style=\"font-size:12px; font-weight:900; color:#64748B;\">Temps (7 jours)<\/div>\n          <div id=\"ttStatMinutes7\" style=\"font-size:26px; font-weight:900; color:#0B2D45;\">0 min<\/div>\n        <\/div>\n      <\/div>\n\n      <hr style=\"border:none; border-top:1px solid rgba(11,45,69,0.12); margin:16px 0;\">\n\n      <h3 style=\"margin:0 0 10px; font-size:18px; color:#0B2D45;\">\ud83d\udcdd Notes<\/h3>\n      <p style=\"margin:0 0 10px; font-size:13px; color:#475569; line-height:1.6;\">\n        \u00c9cris ton ressenti du jour (\u00e9nergie, confiance, focus) + une phrase \u201cle\u00e7on du jour\u201d.\n      <\/p>\n\n      <textarea id=\"ttNote\" rows=\"7\" placeholder=\"Ex : Bon focus. \u00c0 travailler : retour revers\u2026\"\n        style=\"width:100%; padding:12px; border-radius:12px; border:1px solid #CBD5E1;\"><\/textarea>\n\n      <div style=\"display:flex; gap:10px; margin-top:10px;\">\n        <button id=\"ttSaveNote\" style=\"flex:1; background:#1F5F3B; color:#fff; border:none; border-radius:12px; font-weight:900; padding:12px; cursor:pointer;\">\n          Enregistrer\n        <\/button>\n      <\/div>\n\n      <div id=\"ttSaved\" style=\"margin-top:12px; font-size:13px; color:#1F5F3B; font-weight:900; display:none;\">\n        \u2705 Sauvegard\u00e9\n      <\/div>\n\n      <div style=\"margin-top:14px; padding:12px; border-radius:14px; background:#fff; border:1px solid rgba(11,45,69,0.08);\">\n        <strong style=\"color:#0B2D45;\">V2 bient\u00f4t<\/strong>\n        <p style=\"margin:6px 0 0; font-size:13px; color:#475569; line-height:1.55;\">\n          Comptes connect\u00e9s, acc\u00e8s coach, export PDF, et modules tournois.\n        <\/p>\n      <\/div>\n    <\/aside>\n  <\/div>\n\n  <!-- Styles internes -->\n  <style>\n    @media (max-width: 980px){\n      #ttPlayerApp > div[style*=\"grid-template-columns\"]{ grid-template-columns: 1fr !important; }\n    }\n\n    .tt-item{\n      display:grid;\n      grid-template-columns: 28px 1fr 120px 34px;\n      gap:10px;\n      align-items:center;\n      padding:12px;\n      border-radius:14px;\n      border:1px solid rgba(11,45,69,0.10);\n      background:#fff;\n    }\n    .tt-item small{ color:#64748B; font-weight:800; }\n\n    .tt-pill-cat{\n      display:inline-flex;\n      justify-content:center;\n      align-items:center;\n      padding:6px 10px;\n      border-radius:999px;\n      font-weight:900;\n      font-size:12px;\n      background:rgba(231,111,29,0.10);\n      color:#E76F1D;\n      border:1px solid rgba(231,111,29,0.20);\n      white-space:nowrap;\n    }\n    .tt-del{\n      width:34px; height:34px;\n      border-radius:12px;\n      border:1px solid rgba(11,45,69,0.12);\n      background:#F8FAFC;\n      cursor:pointer;\n      font-weight:900;\n    }\n    .tt-check{ width:18px; height:18px; }\n\n    .tt-done{ opacity:0.70; }\n    .tt-done .tt-titleline{ text-decoration: line-through; }\n\n    .tt-session{\n      display:grid;\n      grid-template-columns: 1fr 120px 34px;\n      gap:10px;\n      align-items:center;\n      padding:12px;\n      border-radius:14px;\n      border:1px solid rgba(11,45,69,0.10);\n      background:#fff;\n    }\n    .tt-session strong{ color:#0B2D45; }\n    .tt-session .tt-pill-cat{ background:rgba(11,45,69,0.08); border-color:rgba(11,45,69,0.12); color:#0B2D45; }\n  <\/style>\n\n  <!-- Script -->\n  <script>\n    (function(){\n      const KEY_GOALS = \"tt_player_goals_v1\";\n      const KEY_SESS  = \"tt_player_sessions_v1\";\n      const KEY_NOTE  = \"tt_player_note_v1\";\n\n      const $ = (id)=>document.getElementById(id);\n\n      const goalsList = $(\"ttGoalsList\");\n      const goalText  = $(\"ttGoalText\");\n      const goalDate  = $(\"ttGoalDate\");\n      const goalCat   = $(\"ttGoalCat\");\n      const addGoal   = $(\"ttAddGoal\");\n\n      const sessList  = $(\"ttSessionsList\");\n      const sessDate  = $(\"ttSessionDate\");\n      const sessMin   = $(\"ttSessionMin\");\n      const sessTheme = $(\"ttSessionTheme\");\n      const sessKey   = $(\"ttSessionKey\");\n      const addSess   = $(\"ttAddSession\");\n\n      const note      = $(\"ttNote\");\n      const saveNote  = $(\"ttSaveNote\");\n      const saved     = $(\"ttSaved\");\n\n      const statGoals    = $(\"ttStatGoals\");\n      const statSess7    = $(\"ttStatSessions7\");\n      const statMin7     = $(\"ttStatMinutes7\");\n\n      const btnExport = $(\"ttExport\");\n      const btnReset  = $(\"ttResetAll\");\n\n      function nowISO(){\n        const d = new Date();\n        const pad = (n)=> String(n).padStart(2,\"0\");\n        return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}`;\n      }\n\n      function load(key, fallback){\n        try { return JSON.parse(localStorage.getItem(key) || JSON.stringify(fallback)); }\n        catch(e){ return fallback; }\n      }\n      function save(key, value){\n        localStorage.setItem(key, JSON.stringify(value));\n      }\n      function escapeHtml(str){\n        return String(str).replace(\/[&<>\"']\/g, (m)=>({\n          \"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#039;\"\n        }[m]));\n      }\n\n      \/\/ Defaults dates\n      if(sessDate && !sessDate.value) sessDate.value = nowISO();\n\n      \/\/ GOALS\n      function renderGoals(){\n        const goals = load(KEY_GOALS, []);\n        goalsList.innerHTML = \"\";\n\n        if(goals.length === 0){\n          goalsList.innerHTML = '<div style=\"padding:14px; border-radius:14px; background:#F8FAFC; border:1px dashed rgba(11,45,69,0.18); color:#475569; font-weight:800;\">Ajoute ton premier objectif \ud83c\udfaf<\/div>';\n          return;\n        }\n\n        goals.forEach((g, idx)=>{\n          const el = document.createElement(\"div\");\n          el.className = \"tt-item\" + (g.done ? \" tt-done\" : \"\");\n          el.innerHTML = `\n            <input class=\"tt-check\" type=\"checkbox\" ${g.done ? \"checked\" : \"\"} aria-label=\"Valider\">\n            <div>\n              <div class=\"tt-titleline\" style=\"font-weight:900; color:#0B2D45;\">${escapeHtml(g.text)}<\/div>\n              <small>${escapeHtml(g.date || \"Sans date\")}<\/small>\n            <\/div>\n            <span class=\"tt-pill-cat\">${escapeHtml(g.cat)}<\/span>\n            <button class=\"tt-del\" title=\"Supprimer\">\u00d7<\/button>\n          `;\n\n          el.querySelector(\".tt-check\").addEventListener(\"change\", (e)=>{\n            const goals2 = load(KEY_GOALS, []);\n            goals2[idx].done = e.target.checked;\n            save(KEY_GOALS, goals2);\n            renderAll();\n          });\n\n          el.querySelector(\".tt-del\").addEventListener(\"click\", ()=>{\n            const goals2 = load(KEY_GOALS, []);\n            goals2.splice(idx, 1);\n            save(KEY_GOALS, goals2);\n            renderAll();\n          });\n\n          goalsList.appendChild(el);\n        });\n      }\n\n      if(addGoal){\n        addGoal.addEventListener(\"click\", ()=>{\n          const text = (goalText.value || \"\").trim();\n          if(!text) return;\n\n          const goals = load(KEY_GOALS, []);\n          goals.unshift({\n            text,\n            date: goalDate.value || \"\",\n            cat: goalCat.value || \"Technique\",\n            done: false,\n            ts: Date.now()\n          });\n          save(KEY_GOALS, goals);\n\n          goalText.value = \"\";\n          goalDate.value = \"\";\n          goalCat.value = \"Technique\";\n          renderAll();\n        });\n      }\n\n      \/\/ SESSIONS\n      function renderSessions(){\n        const sessions = load(KEY_SESS, []);\n        sessList.innerHTML = \"\";\n\n        if(sessions.length === 0){\n          sessList.innerHTML = '<div style=\"padding:14px; border-radius:14px; background:#F8FAFC; border:1px dashed rgba(11,45,69,0.18); color:#475569; font-weight:800;\">Ajoute ta premi\u00e8re s\u00e9ance \ud83d\udcc5<\/div>';\n          return;\n        }\n\n        sessions.forEach((s, idx)=>{\n          const el = document.createElement(\"div\");\n          el.className = \"tt-session\";\n          el.innerHTML = `\n            <div>\n              <strong>${escapeHtml(s.date || \"Sans date\")}<\/strong> \u2022 ${escapeHtml(s.theme)} \u2022 ${escapeHtml(String(s.min || 0))} min\n              <div style=\"margin-top:6px; color:#475569; font-weight:800; font-size:13px;\">\n                ${escapeHtml(s.key || \"\")}\n              <\/div>\n            <\/div>\n            <span class=\"tt-pill-cat\">${escapeHtml(s.theme)}<\/span>\n            <button class=\"tt-del\" title=\"Supprimer\">\u00d7<\/button>\n          `;\n\n          el.querySelector(\".tt-del\").addEventListener(\"click\", ()=>{\n            const s2 = load(KEY_SESS, []);\n            s2.splice(idx, 1);\n            save(KEY_SESS, s2);\n            renderAll();\n          });\n\n          sessList.appendChild(el);\n        });\n      }\n\n      if(addSess){\n        addSess.addEventListener(\"click\", ()=>{\n          const date = sessDate.value || nowISO();\n          const min  = parseInt(sessMin.value || \"0\", 10);\n          const theme= sessTheme.value || \"Tennis\";\n          const key  = (sessKey.value || \"\").trim();\n\n          const sessions = load(KEY_SESS, []);\n          sessions.unshift({ date, min: isNaN(min)?0:min, theme, key, ts: Date.now() });\n          save(KEY_SESS, sessions);\n\n          sessMin.value = \"\";\n          sessKey.value = \"\";\n          renderAll();\n        });\n      }\n\n      \/\/ NOTE\n      if(note){\n        note.value = localStorage.getItem(KEY_NOTE) || \"\";\n      }\n      if(saveNote){\n        saveNote.addEventListener(\"click\", ()=>{\n          localStorage.setItem(KEY_NOTE, note.value || \"\");\n          if(saved){\n            saved.style.display = \"block\";\n            setTimeout(()=> saved.style.display = \"none\", 1200);\n          }\n        });\n      }\n\n      \/\/ DASHBOARD\n      function renderStats(){\n        const goals = load(KEY_GOALS, []);\n        const sessions = load(KEY_SESS, []);\n\n        const activeGoals = goals.filter(g=>!g.done).length;\n        if(statGoals) statGoals.textContent = String(activeGoals);\n\n        const now = new Date();\n        const weekAgo = new Date(now.getTime() - 7*24*60*60*1000);\n\n        const sessions7 = sessions.filter(s=>{\n          const d = new Date((s.date || \"\").replace(\/-\/g,\"\/\"));\n          return d >= weekAgo && d <= now;\n        });\n\n        const minutes7 = sessions7.reduce((acc, s)=> acc + (parseInt(s.min||0,10)||0), 0);\n\n        if(statSess7) statSess7.textContent = String(sessions7.length);\n        if(statMin7) statMin7.textContent = minutes7 + \" min\";\n      }\n\n      function renderAll(){\n        renderGoals();\n        renderSessions();\n        renderStats();\n      }\n\n      \/\/ EXPORT\n      if(btnExport){\n        btnExport.addEventListener(\"click\", ()=>{\n          const payload = {\n            goals: load(KEY_GOALS, []),\n            sessions: load(KEY_SESS, []),\n            note: localStorage.getItem(KEY_NOTE) || \"\",\n            exportedAt: new Date().toISOString()\n          };\n          const blob = new Blob([JSON.stringify(payload, null, 2)], {type:\"application\/json\"});\n          const url = URL.createObjectURL(blob);\n          const a = document.createElement(\"a\");\n          a.href = url;\n          a.download = \"traveltennis-player-v1.json\";\n          document.body.appendChild(a);\n          a.click();\n          a.remove();\n          URL.revokeObjectURL(url);\n        });\n      }\n\n      \/\/ RESET\n      if(btnReset){\n        btnReset.addEventListener(\"click\", ()=>{\n          const ok = confirm(\"Confirmer le reset ? (objectifs, s\u00e9ances, notes)\");\n          if(!ok) return;\n          localStorage.removeItem(KEY_GOALS);\n          localStorage.removeItem(KEY_SESS);\n          localStorage.removeItem(KEY_NOTE);\n          if(note) note.value = \"\";\n          renderAll();\n        });\n      }\n\n      renderAll();\n    })();\n  <\/script>\n\n<\/section>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0d183a2 e-flex e-con-boxed e-con e-parent\" data-id=\"0d183a2\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6f39578 elementor-widget elementor-widget-html\" data-id=\"6f39578\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t\/* ============================================\n   TRAVEL TENNIS \u2013 APP JOUEURS V2\n   ============================================ *\/\n\n\/* 1. Custom Post Type : Entr\u00e9es joueurs *\/\nadd_action('init', function(){\n  register_post_type('tt_player_entry', [\n    'label' => 'Suivi joueurs',\n    'public' => false,\n    'show_ui' => true,\n    'supports' => ['title','custom-fields'],\n    'menu_icon' => 'dashicons-chart-line'\n  ]);\n});\n\n\/* 2. Shortcode principal *\/\nadd_shortcode('tt_player_app_v2', function(){\n\n  if(!is_user_logged_in()){\n    return '<p style=\"text-align:center; padding:40px; font-weight:800;\">\n      \ud83d\udd12 Connecte-toi pour acc\u00e9der \u00e0 ton espace joueur.\n    <\/p>';\n  }\n\n  $user = wp_get_current_user();\n  $user_id = $user->ID;\n\n  \/\/ R\u00e9cup\u00e9ration des entr\u00e9es du joueur\n  $entries = get_posts([\n    'post_type' => 'tt_player_entry',\n    'posts_per_page' => -1,\n    'meta_key' => 'tt_user_id',\n    'meta_value' => $user_id,\n  ]);\n\n  ob_start(); ?>\n\n  <section style=\"max-width:1100px; margin:30px auto; padding:0 20px;\">\n    \n    <h2 style=\"font-size:32px; font-weight:900;\">\n      \ud83c\udfbe Le terrain de <?php echo esc_html($user->display_name); ?>\n    <\/h2>\n\n    <p style=\"color:#475569;\">\n      Tes objectifs et ton suivi sont enregistr\u00e9s et visibles par le staff Travel Tennis.\n    <\/p>\n\n    <!-- FORMULAIRE -->\n    <form method=\"post\" style=\"margin:20px 0; background:#fff; padding:18px; border-radius:16px;\" action=\"\">\n      <input type=\"hidden\" name=\"tt_action\" value=\"add_entry\">\n\n      <label style=\"font-weight:800;\">Objectif \/ s\u00e9ance<\/label>\n      <input required name=\"tt_title\" style=\"width:100%; padding:12px; margin:6px 0 12px;\">\n\n      <label style=\"font-weight:800;\">Cat\u00e9gorie<\/label>\n      <select name=\"tt_cat\" style=\"width:100%; padding:12px; margin-bottom:12px;\">\n        <option>Technique<\/option>\n        <option>Tactique<\/option>\n        <option>Physique<\/option>\n        <option>Mental<\/option>\n      <\/select>\n\n      <label style=\"font-weight:800;\">Note \/ point cl\u00e9<\/label>\n      <textarea name=\"tt_note\" rows=\"4\" style=\"width:100%; padding:12px;\"><\/textarea>\n\n      <button style=\"margin-top:12px; background:#1F5F3B; color:#fff; padding:12px 18px; border:none; border-radius:999px; font-weight:900;\">\n        Enregistrer\n      <\/button>\n    <input type=\"hidden\" name=\"trp-form-language\" value=\"en\"\/><\/form>\n\n    <!-- HISTORIQUE -->\n    <h3 style=\"margin-top:30px;\">\ud83d\udcca Historique<\/h3>\n\n    <?php if(!$entries): ?>\n      <p>Aucune entr\u00e9e pour le moment.<\/p>\n    <?php endif; ?>\n\n    <?php foreach($entries as $e): ?>\n      <div style=\"background:#f8fafc; padding:14px; border-radius:14px; margin-bottom:10px;\">\n        <strong><?php echo esc_html($e->post_title); ?><\/strong><br>\n        <small><?php echo esc_html(get_post_meta($e->ID,'tt_cat',true)); ?><\/small>\n        <p><?php echo esc_html(get_post_meta($e->ID,'tt_note',true)); ?><\/p>\n      <\/div>\n    <?php endforeach; ?>\n\n  <\/section>\n\n  <?php\n  return ob_get_clean();\n});\n\n\/* 3. Sauvegarde *\/\nadd_action('init', function(){\n  if(isset($_POST['tt_action']) && $_POST['tt_action']==='add_entry' && is_user_logged_in()){\n    $user_id = get_current_user_id();\n\n    $post_id = wp_insert_post([\n      'post_type' => 'tt_player_entry',\n      'post_title' => sanitize_text_field($_POST['tt_title']),\n      'post_status' => 'publish'\n    ]);\n\n    if($post_id){\n      update_post_meta($post_id,'tt_user_id',$user_id);\n      update_post_meta($post_id,'tt_cat',sanitize_text_field($_POST['tt_cat']));\n      update_post_meta($post_id,'tt_note',sanitize_textarea_field($_POST['tt_note']));\n    }\n\n    wp_redirect($_SERVER['REQUEST_URI']);\n    exit;\n  }\n});\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>\ud83d\udd12 ESPACE MEMBRES Inside Travel Tennis Inside Travel Tennis est l\u2019espace r\u00e9serv\u00e9 aux joueurs et aux coachs engag\u00e9s dans un [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-390","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/traveltennis.com\/en\/wp-json\/wp\/v2\/pages\/390","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/traveltennis.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/traveltennis.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/traveltennis.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/traveltennis.com\/en\/wp-json\/wp\/v2\/comments?post=390"}],"version-history":[{"count":19,"href":"https:\/\/traveltennis.com\/en\/wp-json\/wp\/v2\/pages\/390\/revisions"}],"predecessor-version":[{"id":723,"href":"https:\/\/traveltennis.com\/en\/wp-json\/wp\/v2\/pages\/390\/revisions\/723"}],"wp:attachment":[{"href":"https:\/\/traveltennis.com\/en\/wp-json\/wp\/v2\/media?parent=390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}