templates/application/whileresume/website/articles/list.html.twig line 1

Open in your IDE?
  1. {% extends 'application/whileresume/website/layout-social.html.twig' %}
  2. {% macro cta_recruiter_candidate(locale) %}
  3.     <div class="articles-cta-inline">
  4.         <h2 class="articles-cta-title">
  5.             {% if locale == 'fr' %}Talents et entreprises se rencontrent ici.
  6.             {% else %}Where talent meets fast-growing companies.{% endif %}
  7.         </h2>
  8.         <div class="articles-cta-grid">
  9.             {# ── Recruteur ── #}
  10.             <div class="articles-cta-side">
  11.                 <div class="articles-cta-side-head">
  12.                     <span class="articles-cta-side-icon">
  13.                         <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  14.                             <rect x="2" y="7" width="20" height="14" rx="2" ry="2"/>
  15.                             <path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/>
  16.                         </svg>
  17.                     </span>
  18.                     <span class="articles-cta-side-label">{{ locale == 'fr' ? 'Recruteur' : 'Recruiter' }}</span>
  19.                 </div>
  20.                 <h3 class="articles-cta-side-heading">
  21.                     {% if locale == 'fr' %}Recrutez des profils d'exception, plus vite.{% else %}Hire exceptional talent, faster.{% endif %}
  22.                 </h3>
  23.                 <p class="articles-cta-side-text">
  24.                     {% if locale == 'fr' %}Accédez aux meilleurs talents du marché et connectez-vous directement à des candidats qualifiés en quête de leur prochain défi.{% else %}Get access to top market talent and connect directly with qualified candidates ready for their next challenge.{% endif %}
  25.                 </p>
  26.                 <a href="{{ path('whileresume_business_' ~ locale) }}" class="articles-cta-side-btn">
  27.                     {{ locale == 'fr' ? 'Je recrute' : "I'm recruiting" }}
  28.                     <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
  29.                         <line x1="5" y1="12" x2="19" y2="12"/>
  30.                         <polyline points="12 5 19 12 12 19"/>
  31.                     </svg>
  32.                 </a>
  33.             </div>
  34.             {# ── Candidat ── #}
  35.             <div class="articles-cta-side">
  36.                 <div class="articles-cta-side-head">
  37.                     <span class="articles-cta-side-icon">
  38.                         <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  39.                             <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
  40.                             <circle cx="12" cy="7" r="4"/>
  41.                         </svg>
  42.                     </span>
  43.                     <span class="articles-cta-side-label">{{ locale == 'fr' ? 'Candidat' : 'Candidate' }}</span>
  44.                 </div>
  45.                 <h3 class="articles-cta-side-heading">
  46.                     {% if locale == 'fr' %}Trouvez le job qui vous ressemble.{% else %}Find the job that fits you.{% endif %}
  47.                 </h3>
  48.                 <p class="articles-cta-side-text">
  49.                     {% if locale == 'fr' %}On vous accompagne dans la recherche de votre poste idéal au sein des entreprises les plus prometteuses du marché.{% else %}We support you in finding your ideal position within the most promising companies on the market.{% endif %}
  50.                 </p>
  51.                 <a href="{% if app.request.locale == "en" %}{{ path('whileresume_homepage') }}{% else %}{{ path('locale_whileresume_homepage',{'_locale':app.request.locale}) }}{% endif %}#register" class="articles-cta-side-btn">
  52.                     {{ locale == 'fr' ? 'Je cherche un job' : "I'm looking for a job" }}
  53.                     <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
  54.                         <line x1="5" y1="12" x2="19" y2="12"/>
  55.                         <polyline points="12 5 19 12 12 19"/>
  56.                     </svg>
  57.                 </a>
  58.             </div>
  59.         </div>
  60.     </div>
  61. {% endmacro %}
  62. {% import _self as ctaMacro %}
  63. {% block title %}{{ page.shortTitle }}{% endblock title %}
  64. {% block description %}{{ page.shortDescription }}{% endblock description %}
  65. {% block robots %}{{ page.robots }}{% endblock robots %}
  66. {% block meta_social %}{{ parent() }}{% include "/vitrine/components/socialmedia.html.twig" with { 'page':page,'social_type':'website' } %}{% endblock meta_social %}
  67. {% block canonical %}{% include "/vitrine/lexend/components/pages/canonical.html.twig" with {'page':page} %}{% endblock canonical %}
  68. {% block css %}
  69.     {{ parent() }}
  70.     <style>
  71.         /* ─── Page liste articles (mêmes patterns que /jobs) ─── */
  72.         .articles-dash{max-width:880px;margin:0 auto}
  73.         .articles-dash-header{margin-bottom:18px}
  74.         .articles-dash-title{font-size:24px;font-weight:800;color:#1E1B2E;line-height:1.2;letter-spacing:-0.02em;margin:0 0 6px}
  75.         @media(min-width:768px){.articles-dash-title{font-size:28px}}
  76.         /* Liste cards (style identique aux jobs-card) */
  77.         .articles-list{display:flex;flex-direction:column;gap:10px}
  78.         .articles-card{background:#fff;border-radius:14px;padding:14px;box-shadow:0 0 16px 0 rgba(0,0,0,0.04);display:flex;align-items:center;gap:14px;text-decoration:none;color:inherit;transition:transform .15s,box-shadow .2s}
  79.         .articles-card:hover{transform:translateY(-1px);box-shadow:0 4px 20px rgba(108,58,237,.1);color:inherit}
  80.         .articles-card-logo{width:50px;height:50px;border-radius:12px;background:linear-gradient(135deg,#EDE9FE,#DDD6FE);display:flex;align-items:center;justify-content:center;color:var(--theme-color,#6C3AED);flex-shrink:0;overflow:hidden}
  81.         .articles-card-logo svg{width:24px;height:24px;opacity:.9}
  82.         .articles-card-info{flex:1;min-width:0}
  83.         .articles-card-title{font-size:14px;font-weight:700;color:#1E1B2E;line-height:1.3;margin:0 0 4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  84.         .articles-card-meta{font-size:12px;color:#6B7280;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:8px}
  85.         .articles-card-meta-sep{display:inline-block;width:3px;height:3px;border-radius:50%;background:#D1D5DB;flex-shrink:0}
  86.         .articles-card-badge{font-size:11px;font-weight:600;color:var(--theme-color,#6C3AED);background:#F5F3FF;padding:3px 9px;border-radius:100px;white-space:nowrap;flex-shrink:0;text-transform:uppercase;letter-spacing:.04em}
  87.         .articles-card-arrow{flex-shrink:0;color:#9CA3AF;transition:color .15s,transform .15s}
  88.         .articles-card:hover .articles-card-arrow{color:var(--theme-color,#6C3AED);transform:translateX(2px)}
  89.         .articles-card-arrow svg{width:18px;height:18px}
  90.         /* État vide */
  91.         .articles-empty{text-align:center;padding:40px 20px;background:#fff;border-radius:14px;box-shadow:0 0 16px 0 rgba(0,0,0,0.04)}
  92.         .articles-empty-icon{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:16px;background:#F5F3FF;color:var(--theme-color,#6C3AED);margin-bottom:14px}
  93.         .articles-empty-icon svg{width:24px;height:24px}
  94.         .articles-empty-title{font-size:16px;font-weight:700;color:#1E1B2E;margin:0 0 6px}
  95.         .articles-empty-text{font-size:13px;color:#6B7280;margin:0}
  96.         /* Pagination */
  97.         .articles-pagination{margin-top:18px}
  98.         /* ═══ CTA inline (entre articles) ═══ */
  99.         .articles-cta-inline{
  100.             position:relative;
  101.             border-radius:18px;
  102.             padding:24px;
  103.             margin:6px 0;
  104.             background:linear-gradient(135deg,#6C3AED 0%,#8B5CF6 50%,#A78BFA 100%);
  105.             overflow:hidden;
  106.             box-shadow:0 10px 30px -8px rgba(108,58,237,.35);
  107.         }
  108.         .articles-cta-inline::before{
  109.             content:"";
  110.             position:absolute;
  111.             top:-40px;right:-40px;
  112.             width:180px;height:180px;
  113.             background:radial-gradient(circle,rgba(255,255,255,.15) 0%,transparent 70%);
  114.             pointer-events:none;
  115.         }
  116.         .articles-cta-inline::after{
  117.             content:"";
  118.             position:absolute;
  119.             bottom:-60px;left:-60px;
  120.             width:200px;height:200px;
  121.             background:radial-gradient(circle,rgba(255,255,255,.08) 0%,transparent 70%);
  122.             pointer-events:none;
  123.         }
  124.         .articles-cta-eyebrow{
  125.             display:inline-flex;align-items:center;gap:6px;
  126.             font-size:11px;font-weight:700;
  127.             color:#fff;
  128.             text-transform:uppercase;letter-spacing:.1em;
  129.             background:rgba(255,255,255,.18);
  130.             padding:5px 12px;border-radius:100px;
  131.             margin-bottom:12px;
  132.             backdrop-filter:blur(10px);
  133.             -webkit-backdrop-filter:blur(10px);
  134.             position:relative;z-index:2;
  135.         }
  136.         .articles-cta-eyebrow svg{width:12px;height:12px}
  137.         .articles-cta-title{
  138.             font-size:20px;font-weight:800;
  139.             color:#fff;
  140.             line-height:1.25;letter-spacing:-0.01em;
  141.             margin:0 0 18px;
  142.             position:relative;z-index:2;
  143.         }
  144.         @media(min-width:768px){.articles-cta-title{font-size:24px}}
  145.         .articles-cta-grid{
  146.             display:grid;
  147.             grid-template-columns:1fr;
  148.             gap:12px;
  149.             position:relative;z-index:2;
  150.         }
  151.         @media(min-width:640px){.articles-cta-grid{grid-template-columns:1fr 1fr;gap:14px}}
  152.         .articles-cta-side{
  153.             background:rgba(255,255,255,.97);
  154.             border-radius:14px;
  155.             padding:18px;
  156.             display:flex;flex-direction:column;
  157.             transition:transform .2s,box-shadow .2s;
  158.         }
  159.         .articles-cta-side:hover{transform:translateY(-2px);box-shadow:0 12px 24px -8px rgba(0,0,0,.18)}
  160.         .articles-cta-side-head{
  161.             display:flex;align-items:center;gap:10px;
  162.             margin-bottom:10px;
  163.         }
  164.         .articles-cta-side-icon{
  165.             width:38px;height:38px;border-radius:10px;
  166.             display:inline-flex;align-items:center;justify-content:center;
  167.             background:linear-gradient(135deg,#EDE9FE,#DDD6FE);
  168.             color:var(--theme-color,#6C3AED);
  169.             flex-shrink:0;
  170.         }
  171.         .articles-cta-side-icon svg{width:18px;height:18px}
  172.         .articles-cta-side-label{
  173.             font-size:11px;font-weight:700;
  174.             color:var(--theme-color,#6C3AED);
  175.             text-transform:uppercase;letter-spacing:.08em;
  176.             margin:0;
  177.         }
  178.         .articles-cta-side-heading{
  179.             font-size:15px;font-weight:700;
  180.             color:#1E1B2E;
  181.             line-height:1.3;
  182.             margin:0 0 8px;
  183.         }
  184.         .articles-cta-side-text{
  185.             font-size:13px;color:#6B7280;
  186.             line-height:1.5;
  187.             margin:0 0 14px;
  188.             flex:1;
  189.         }
  190.         .articles-cta-side-btn{
  191.             display:inline-flex;align-items:center;justify-content:center;gap:6px;
  192.             background:var(--theme-color,#6C3AED);
  193.             color:#fff;text-decoration:none;
  194.             padding:11px 16px;
  195.             border-radius:10px;
  196.             font-size:13px;font-weight:700;
  197.             letter-spacing:.01em;
  198.             transition:background .15s,transform .15s;
  199.         }
  200.         .articles-cta-side-btn:hover{
  201.             background:#5B21B6;color:#fff;
  202.             transform:translateX(2px);
  203.         }
  204.         .articles-cta-side-btn svg{width:14px;height:14px;transition:transform .15s}
  205.         .articles-cta-side-btn:hover svg{transform:translateX(2px)}
  206.     </style>
  207. {% endblock css %}
  208. {% block body %}
  209.     <div class="articles-dash">
  210.         {# ═══ Header ═══ #}
  211.         <div class="articles-dash-header">
  212.             <h1 class="articles-dash-title">{{ page.title }}</h1>
  213.         </div>
  214.         {# ═══ Liste articles ═══ #}
  215.         {% if pagination|length > 0 %}
  216.             <div class="articles-list">
  217.                 {% for article in pagination %}
  218.                     {# ── URL article ── #}
  219.                     {% set prefix = "" %}
  220.                     {% set urlArticle = path('blog_article',{'slug': article.slug})  %}
  221.                     {% if app.request.locale != default_locale %}
  222.                         {% set urlArticle = path('locale_blog_article',{'_locale':app.request.locale,'slug': article.slug})  %}
  223.                         {% set prefix = "/" ~ app.request.locale %}
  224.                     {% endif %}
  225.                     {% if article.pageslug3 is not empty %}
  226.                         {% set urlArticle = prefix ~ '/' ~ article.pageslug ~ '/' ~  article.pageslug2 ~ '/' ~ article.pageslug3  %}
  227.                     {% elseif article.pageslug2 is not empty %}
  228.                         {% set urlArticle = prefix ~ '/' ~ article.pageslug ~ '/' ~  article.pageslug2  %}
  229.                     {% elseif article.pageslug is not empty %}
  230.                         {% set urlArticle = prefix ~ '/' ~ article.pageslug  %}
  231.                     {% endif %}
  232.                     <a href="{{ urlArticle }}" class="articles-card">
  233.                         <div class="articles-card-logo">
  234.                             <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  235.                                 <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/>
  236.                                 <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
  237.                             </svg>
  238.                         </div>
  239.                         <div class="articles-card-info">
  240.                             <h2 class="articles-card-title">{{ article.title }}</h2>
  241.                             <div class="articles-card-meta">
  242.                                 {#<span>{{ article.publishedAt|date("d M Y") }}</span> <span class="articles-card-meta-sep"></span>#}
  243.                                 {% if article.subtitle is not empty %}
  244.                                     <span>{{ article.subtitle|length > 60 ? article.subtitle|slice(0,60) ~ '…' : article.subtitle }}</span>
  245.                                 {% endif %}
  246.                             </div>
  247.                         </div>
  248.                         <span class="articles-card-badge">{{ "Je lis l'article"|translateLocale(arrayTranslate) }}</span>
  249.                         <span class="articles-card-arrow">
  250.                             <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  251.                                 <polyline points="9 18 15 12 9 6"/>
  252.                             </svg>
  253.                         </span>
  254.                     </a>
  255.                     {# ═══ CTA inline après le 3e article ═══ #}
  256.                     {% if loop.index == 3 and getEnv("KERNEL_APPLICATION") == "whileresume" and app.request.locale in ['fr','en'] %}
  257.                         {% if app.user is null %}
  258.                         {{ ctaMacro.cta_recruiter_candidate(app.request.locale) }}
  259.                         {% endif %}
  260.                     {% endif %}
  261.                 {% endfor %}
  262.             </div>
  263.             {# Pagination #}
  264.             <div class="articles-pagination">
  265.                 {{ knp_pagination_render(pagination,'application/whileresume/website/pagination/pagination.html.twig') }}
  266.             </div>
  267.         {% else %}
  268.             <div class="articles-empty">
  269.                 <div class="articles-empty-icon">
  270.                     <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  271.                         <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/>
  272.                         <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
  273.                     </svg>
  274.                 </div>
  275.                 <p class="articles-empty-title">{{ "Aucun article"|translateLocale(arrayTranslate) }}</p>
  276.             </div>
  277.         {% endif %}
  278.         {# ═══ CTA Recruteur / Candidat (en bas, si moins de 3 articles → fallback) ═══ #}
  279.         {% if pagination|length > 0 and pagination|length < 3 and getEnv("KERNEL_APPLICATION") == "whileresume" and app.request.locale in ['fr','en'] %}
  280.             {% if app.user is null %}
  281.             <div class="mt-3">
  282.                 {{ ctaMacro.cta_recruiter_candidate(app.request.locale) }}
  283.             </div>
  284.             {% endif %}
  285.         {% endif %}
  286.     </div>
  287. {% endblock body %}