Résultat Aix-en-Provence – Montauban: 29-7

Résultat Aix-en-Provence – Montauban

Au Stade Maurice-David Aix-en-Provence, Aix-en-Provence bat Montauban 29 à 7 (mi-temps: 24-7) pour le compte de la compétition prod2 – 25e-journée – Poule 1

Statistiques du match:

Aix-en-Provence:

  • Essais: 5
  • Pénalités: 0
  • Transformations: 2
  • Cartons jaunes: 0
  • Cartons rouges: 0

Montauban:

À lire aussi | Grégory Alldritt : « Je leur ai dit que j’étais fier du groupe »

  • Essais: 1
  • Pénalités: 0
  • Transformations: 1
  • Cartons jaunes: 1
  • Cartons rouges: 0

Les équipes:

Composition Aix-en-Provence:

(1) Federico Wegrzyn, (2) Lucas Martin, (3) Tomas Francis, (4) Jérôme Dufour, (5) Clément Chartier, (6) Teimana Harrison, (7) Charly Gambini, (8) Carl Axtens, (9) Joris Cazenave, (10) Jimmy Gopperth, (11) Sione Tui, (12) Inga Finau, (13) Eto Bainivalu, (14) Adrien Lapègue, (15) Léo Drouet, (16) Jean-Charles Orioli, (17) Gabriel Toth, (18) Andres Zafra, (19) Guillaume Piazzoli, (20) Arthur Coville, (21) Enzo Selponi, (22) Dorian Lavernhe, (23) Paul Mallez

Composition Montauban:

À lire aussi | Philippe Saint-André : « Ce club grandit et j’espère qu’on sera plus grands la saison prochaine »

(1) Malino Vanai, (2) Kevin Firmin, (3) Mirian Burduli, (4) Frank Bradshaw, (5) Lewis Bean, (6) Kyllian Ringuet, (7) Otar Giorgadze, (8) Quentin Witt, (9) Yoan Cottin, (10) Jérôme Bosviel, (11) Romain Fonnicola, (12) Maxime Mathy, (13) Simon Renda, (14) Josua Vici, (15) Semesa Rokoduguni, (16) German Kessler, (17) Nicolas Agnesi, (18) Kevin Gimeno, (19) Noa Kanika, (20) Lui Naeata, (21) Shaun Venter, (22) Thomas Larregain, (23) Victor Delmas


* { margin: 0; padding: 0; box-sizing: border-box; }body { font-family: ‘Poppins’, -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; background-color: #f8fafc; }.competition-container { max-width: 1000px; margin: 0 auto; padding: 20px; }.loader { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); z-index: 1000; }.loader.active { display: block; }/* Styles communs avec nouveau thème */ .competition-header { background: linear-gradient(135deg, #374151 0%, #1f2937 100%); color: white; padding: 15px 20px; border-radius: 8px; margin-bottom: 20px; text-align: center; box-shadow: 0 4px 16px rgba(31, 41, 55, 0.3); }.competition-header h1 { font-size: 1.5rem; margin: 0; font-weight: 600; }.view-toggle { display: flex; justify-content: center; gap: 10px; margin-bottom: 20px; }.toggle-btn { padding: 10px 20px; background: white; border: 2px solid #e5e7eb; border-radius: 25px; cursor: pointer; transition: all 0.3s ease; font-weight: 500; color: #374151; }.toggle-btn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.1); }.toggle-btn.active { background: #475569; color: white; border-color: #475569; box-shadow: 0 2px 8px rgba(71, 85, 105, 0.3); }.navigation-tabs { display: flex; gap: 10px; margin-bottom: 20px; overflow-x: auto; padding: 10px 0; }.tab { padding: 10px 20px; background: white; border: 2px solid #e5e7eb; border-radius: 5px; cursor: pointer; transition: all 0.3s ease; white-space: nowrap; color: #374151; }.tab:hover { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(0,0,0,0.1); }.tab.active { background: #475569; color: white; border-color: #475569; box-shadow: 0 2px 8px rgba(71, 85, 105, 0.2); }/* Cup/Tournament Styles */ .cup-view .phase-container { margin-bottom: 40px; } .championship-view .phase-container, .tournament-view .phase-container { margin-bottom: 40px; }.phase-header { background: linear-gradient(135deg, #374151 0%, #1f2937 100%); color: white; padding: 15px; border-radius: 5px 5px 0 0; font-weight: bold; display: flex; justify-content: space-between; align-items: center; }.phase-type-badge { background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 12px; font-size: 12px; text-transform: uppercase; }/* Header tab buttons */ .header-tab-btn { padding: 8px 16px !important; font-size: 13px !important; font-weight: 500; transition: all 0.3s ease !important; } .header-tab-btn:hover { background: rgba(255,255,255,0.3) !important; color: white !important; transform: translateY(-1px); }.header-tab-btn.active:hover { background: rgba(255,255,255,0.25) !important; }/* Match Cards – Simplified */ .match-card { background: white; border: 2px solid #e5e7eb; border-radius: 10px; margin-bottom: 12px; overflow: hidden; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 1px 3px rgba(0,0,0,0.1); position: relative; }.match-card:hover { transform: translateY(-2px) scale(1.02); box-shadow: 0 4px 12px rgba(0,0,0,0.15); border-color: #475569; }.match-card.finished { border-color: #1e40af; }.match-card.finished::before { content: ‘✓’; position: absolute; top: 8px; right: 8px; color: #1e40af; font-weight: bold; font-size: 14px; }.match-card.live { border-color: #d62243; animation: pulse-border 2s infinite; }.match-card.live::before { content: ‘● LIVE’; position: absolute; top: 8px; right: 8px; color: #d62243; font-weight: bold; font-size: 11px; animation: pulse 2s infinite; }@keyframes pulse-border { 0% { border-color: #d62243; } 50% { border-color: #e85a75; } 100% { border-color: #d62243; } }/* Desktop layout */ @media (min-width: 769px) { .match-team { display: flex; align-items: center; padding: 12px 15px; border-bottom: 1px solid #f3f4f6; transition: all 0.2s; position: relative; }.match-team:last-child { border-bottom: none; }.match-team.winner { background: linear-gradient(to right, #dbeafe 0%, #eff6ff 100%); font-weight: 600; }.match-team.winner::before { content:  »; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: #1e40af; }.match-team.loser { opacity: 0.7; }.match-team-logo { width: 32px; height: 32px; object-fit: contain; margin-right: 12px; border-radius: 4px; background: #f9fafb; padding: 2px; }.match-team-name { flex: 1; font-size: 14px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #374151; font-family: ‘Poppins’, sans-serif; }.match-team-score { font-size: 18px; font-weight: bold; color: #475569; min-width: 30px; text-align: center; background: #f1f5f9; padding: 4px 10px; border-radius: 6px; } }/* Mobile layout – simplified */ @media (max-width: 768px) { .match-card { padding: 15px; display: flex; align-items: center; justify-content: space-between; gap: 15px; position: relative; }.match-team { display: flex; flex-direction: column; align-items: center; text-align: center; flex: 1; padding: 0; border: none; background: none !important; }.match-team::before { display: none; }.match-team-logo { width: 40px; height: 40px; margin-bottom: 6px; border-radius: 4px; }.match-team-name { font-size: 11px; font-weight: 600; max-width: 80px; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #374151; font-family: ‘Poppins’, sans-serif; }/* Center content (score or date) */ .match-center-score { font-size: 20px; font-weight: bold; color: #475569; background: #f1f5f9; padding: 10px 15px; border-radius: 8px; text-align: center; min-width: 70px; }.match-center-score.live { background: #d62243; color: white; animation: pulse 2s infinite; }.match-center-date { text-align: center; padding: 5px 10px; }.match-date-day { font-size: 12px; font-weight: 600; color: #475569; margin-bottom: 2px; }.match-date-time { font-size: 11px; color: #6b7280; font-weight: 500; }.match-info { display: none; }.match-status { position: absolute; top: 0; left: 0; right: 0; height: 4px; border-radius: 4px 4px 0 0; }.match-card.finished .match-status { background: #1e40af; }.match-card.live .match-status { background: #d62243; animation: pulse 2s infinite; } }.bracket-match-info { background: #f9fafb; padding: 6px 12px; text-align: center; font-size: 11px; color: #6b7280; border-top: 1px solid #e5e7eb; }.bracket-match-date { font-weight: 500; color: #374151; }.bracket-match-location { margin-top: 1px; font-size: 10px; }/* Match Status Indicator */ .match-status { position: absolute; top: 0; left: 0; right: 0; height: 3px; background: #e5e7eb; }.bracket-match.finished .match-status { background: #1e40af; }.bracket-match.live .match-status { background: #d62243; animation: pulse 2s infinite; }/* Bracket Navigation for Mobile */ .bracket-navigation { display: none; position: sticky; top: 0; background: white; padding: 10px; border-bottom: 2px solid #e5e7eb; margin-bottom: 15px; z-index: 100; }@media (max-width: 768px) { .bracket-navigation { display: flex; gap: 10px; overflow-x: auto; -webkit-overflow-scrolling: touch; }.bracket-nav-btn { padding: 8px 16px; background: #f1f5f9; border: 2px solid #475569; border-radius: 20px; color: #475569; font-size: 12px; font-weight: 600; white-space: nowrap; cursor: pointer; transition: all 0.3s ease; }.bracket-nav-btn:hover { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(71, 85, 105, 0.2); }.bracket-nav-btn.active { background: #475569; color: white; } }/* List View for Groups */ .matches-list { background: white; border-radius: 0 0 5px 5px; padding: 20px; }.match-row { display: grid; grid-template-columns: 1fr auto 1fr; gap: 15px; padding: 15px; background: #f9fafb; border-radius: 8px; margin-bottom: 10px; cursor: pointer; transition: all 0.3s ease; align-items: center; border: 2px solid transparent; }.match-row:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.1); border-color: #475569; }.team-info { display: flex; align-items: center; gap: 10px; }.team-info.away { flex-direction: row-reverse; text-align: right; }.team-logo { width: 40px; height: 40px; object-fit: contain; }.match-center { text-align: center; min-width: 120px; }.score-box { background: #374151; color: white; padding: 8px 16px; border-radius: 5px; font-weight: bold; display: inline-block; }.score-box.live { background: #d62243; animation: pulse 2s infinite; }@keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.8; } 100% { opacity: 1; } }.match-datetime { font-size: 14px; color: #6b7280; line-height: 1.4; }.match-time { display: block; font-weight: bold; color: #374151; margin-top: 4px; }/* Enhanced Responsive Design */ @media (max-width: 1200px) { .bracket-container { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 20px; } }@media (max-width: 768px) { .competition-container { padding: 10px; }.tournament-bracket { padding: 0; }.match-row { grid-template-columns: 1fr; gap: 8px; padding: 12px; }.team-info { justify-content: center; }.team-info.away { flex-direction: row; text-align: left; }.view-toggle { width: 100%; justify-content: stretch; }.toggle-btn { flex: 1; padding: 12px 10px; font-size: 14px; }.competition-header { padding: 15px; }.competition-header h1 { font-size: 20px; }.phase-header { padding: 12px; font-size: 14px; }.match-center { min-width: 80px; }.score-box { padding: 6px 12px; font-size: 14px; } }/* Ultra small devices */ @media (max-width: 480px) { .bracket-match { margin-bottom: 8px; }.team-logo { width: 30px; height: 30px; }.rounds-dropdown-btn { padding: 10px 15px; font-size: 14px; } }/* Phase type specific styling */ .phase-container.knockout .phase-header { background: linear-gradient(135deg, #ea580c 0%, #dc2626 100%); }.phase-container.group .phase-header { background: linear-gradient(135deg, #004382 0%, #003770 100%); }/* Dropdown selector styles */ .rounds-dropdown-btn:hover { background: #1f2937 !important; transform: translateY(-2px); box-shadow: 0 6px 16px rgba(31, 41, 55, 0.3); }.rounds-dropdown-option:hover { background-color: #f9fafb !important; }.rounds-dropdown-option:first-child { border-radius: 6px 6px 0 0; }.rounds-dropdown-option:last-child { border-radius: 0 0 6px 6px; border-bottom: none !important; }/* Responsive dropdown */ @media (max-width: 768px) { .rounds-dropdown-btn { min-width: 100% !important; justify-content: center !important; } .rounds-dropdown-menu { left: 0 !important; right: 0 !important; } }/* Bracket Card View for Complex Brackets on Mobile */ .bracket-cards-view { display: none; }@media (max-width: 768px) { .bracket-cards-view { display: block; padding: 15px; }.bracket-phase-card { background: white; border-radius: 12px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); overflow: hidden; }.bracket-phase-card-header { background: linear-gradient(135deg, #374151 0%, #1f2937 100%); color: white; padding: 15px; font-weight: 600; font-size: 16px; text-align: center; }.bracket-phase-card-content { padding: 15px; }.bracket-phase-card.final .bracket-phase-card-header { background: linear-gradient(135deg, #d97706 0%, #f59e0b 100%); }.bracket-phase-card.semifinal .bracket-phase-card-header { background: linear-gradient(135deg, #ea580c 0%, #dc2626 100%); } }
Chargement…

Chargement de la compétition…

class CompetitionManager { constructor() { this.competitionId = this.getCompetitionIdFromUrl(); this.apiBase = ‘https://rugby-app-4ebacff10fda.herokuapp.com’; this.currentData = null; this.updateInterval = null; this.cable = null; this.competitionChannel = null; }getCompetitionIdFromUrl() { const urlParams = new URLSearchParams(window.location.search); return urlParams.get(‘competition’) || ‘pro-d2’; }async init() { await this.loadCompetitionData(); this.setupResponsiveHandler(); this.setupWebSocket(); this.startAutoUpdate(); }setupResponsiveHandler() { let resizeTimeout; window.addEventListener(‘resize’, () => { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { this.render(); }, 250); }); }setupWebSocket() { try { // Configuration basique du WebSocket const wsUrl = this.apiBase.replace(‘http://’, ‘ws://’).replace(‘https://’, ‘wss://’) + ‘/cable’; console.log(‘Tentative de connexion WebSocket à:’, wsUrl); this.cable = new WebSocket(wsUrl); this.cable.onopen = () => { console.log(‘WebSocket connecté avec succès’); this.subscribeToCompetition(); };this.cable.onmessage = (event) => { try { const data = JSON.parse(event.data); this.handleWebSocketMessage(data); } catch (parseError) { console.warn(‘Erreur parsing message WebSocket:’, parseError); } };this.cable.onclose = (event) => { console.log(‘WebSocket fermé:’, event.code, event.reason); console.log(‘Tentative de reconnexion dans 5 secondes…’); setTimeout(() => this.setupWebSocket(), 5000); };this.cable.onerror = (error) => { console.error(‘Erreur WebSocket:’, error); }; } catch (error) { console.warn(‘WebSocket non disponible, utilisation du polling seulement:’, error); // Fallback: augmenter la fréquence du polling si WebSocket échoue this.startAutoUpdate(10000); // Polling toutes les 10 secondes } }subscribeToCompetition() { if (this.cable && this.cable.readyState === WebSocket.OPEN) { const subscription = { command: ‘subscribe’, identifier: JSON.stringify({ channel: ‘CompetitionChannel’, competition_id: this.competitionId }) }; this.cable.send(JSON.stringify(subscription)); } }handleWebSocketMessage(data) { if (data.type === ‘ping’) return; console.log(‘Message WebSocket reçu:’, data); if (data.message) { const message = data.message; switch (message.type) { case ‘score_update’: case ‘live_score_update’: this.updateMatchInUI(message.rencontre); this.showNotification(`Score mis à jour: ${message.rencontre.local_team.name} vs ${message.rencontre.visitor_team.name}`); break; case ‘state_change’: this.updateMatchStateInUI(message.rencontre_id, message.state); this.showNotification(`État du match changé: ${message.state}`); break; } } }updateMatchInUI(rencontreData) { console.log(‘Updating match UI for:’, rencontreData); // Trouver et mettre à jour les éléments de match dans l’interface const matchElements = document.querySelectorAll(`[data-match-id= »${rencontreData.id} »]`); console.log(‘Found match elements:’, matchElements.length); matchElements.forEach(element => { const homeScore = rencontreData.score_locale || 0; const awayScore = rencontreData.score_visiteuse || 0; const isLive = rencontreData.etat === ‘endirect’ || rencontreData.etat === ‘mi-temps’; const isFinished = rencontreData.etat === ‘termine’; console.log(‘Updating element with scores:’, homeScore, awayScore, ‘state:’, rencontreData.etat); // Mobile layout if (window.innerWidth <= 768) { let centerElement = element.querySelector('.match-center-score, .match-center-date'); if (isLive || isFinished) { // Si le match est live ou terminé, on doit afficher le score if (!element.querySelector('.match-center-score')) { // Remplacer le container de date par le container de score const dateElement = element.querySelector('.match-center-date'); if (dateElement) { const scoreElement = document.createElement('div'); scoreElement.className = `match-center-score ${isLive ? 'live' : ''}`; scoreElement.textContent = `${homeScore} – ${awayScore}`; dateElement.parentNode.replaceChild(scoreElement, dateElement); } } else { // Mettre à jour le score existant const centerScore = element.querySelector('.match-center-score'); if (centerScore) { centerScore.textContent = `${homeScore} – ${awayScore}`; if (isLive) { centerScore.classList.add('live'); } else { centerScore.classList.remove('live'); } } } } } else { // Desktop layout const matchCenter = element.querySelector('.match-center'); if (matchCenter) { if (isLive || isFinished) { // Si le match est live ou terminé, remplacer par score-box if (!element.querySelector('.score-box')) { matchCenter.innerHTML = `
${homeScore} – ${awayScore}
`; } else { // Mettre à jour le score existant const scoreBox = element.querySelector(‘.score-box’); if (scoreBox) { scoreBox.textContent = `${homeScore} – ${awayScore}`; if (isLive) { scoreBox.classList.add(‘live’); } else { scoreBox.classList.remove(‘live’); } } } } } } // Mettre à jour l’état visuel de la card element.classList.remove(‘finished’, ‘live’); if (isFinished) { element.classList.add(‘finished’); } else if (isLive) { element.classList.add(‘live’); } console.log(‘Updated match state classes’); }); }updateMatchStateInUI(rencontreId, newState) { const matchElements = document.querySelectorAll(`[data-match-id= »${rencontreId} »]`); matchElements.forEach(element => { // Réinitialiser les classes d’état element.className = element.className.replace(/\b(finished|live|scheduled)\b/g,  »); // Ajouter la nouvelle classe selon l’état switch (newState) { case ‘termine’: element.classList.add(‘finished’); break; case ‘endirect’: case ‘mi-temps’: element.classList.add(‘live’); break; case ‘programme’: element.classList.add(‘scheduled’); break; } }); }showNotification(message) { // Créer une notification simple const notification = document.createElement(‘div’); notification.style.cssText = ` position: fixed; top: 20px; right: 20px; background: #374151; color: white; padding: 15px 20px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); z-index: 10000; font-size: 14px; max-width: 300px; transition: all 0.3s ease; `; notification.textContent = message; document.body.appendChild(notification); // Animation d’apparition setTimeout(() => { notification.style.transform = ‘translateX(0)’; notification.style.opacity = ‘1’; }, 100); // Supprimer après 5 secondes setTimeout(() => { notification.style.transform = ‘translateX(100%)’; notification.style.opacity = ‘0’; setTimeout(() => { if (notification.parentNode) { notification.parentNode.removeChild(notification); } }, 300); }, 5000); }showLoader() { document.getElementById(‘loader’).classList.add(‘active’); }hideLoader() { document.getElementById(‘loader’).classList.remove(‘active’); }async loadCompetitionData() { this.showLoader(); try { const response = await fetch(`${this.apiBase}/competitions/${this.competitionId}/adaptive`); this.currentData = await response.json(); this.render(); } catch (error) { console.error(‘Erreur lors du chargement:’, error); this.showError(‘Erreur lors du chargement des données’); } finally { this.hideLoader(); } }render() { if (!this.currentData) return;// Update header (only title, no date) document.getElementById(‘competitionTitle’).textContent = this.currentData.competition.display_name; document.getElementById(‘competitionInfo’).textContent =  »;// Store competition date for inline display this.competitionDate = this.currentData.competition.years ||  »;// Render based on competition type const mainContent = document.getElementById(‘mainContent’); mainContent.innerHTML =  »;switch (this.currentData.type) { case ‘championship’: this.renderChampionship(mainContent); break; case ‘cup’: this.renderCup(mainContent); break; case ‘tournament’: this.renderTournament(mainContent); break; default: this.renderDefault(mainContent); }// Update inline competition dates after rendering this.updateInlineCompetitionDates(); }updateInlineCompetitionDates() { // Update all inline competition date elements const inlineDateElements = document.querySelectorAll(‘.competition-date-inline’); inlineDateElements.forEach(element => { element.textContent = this.competitionDate; }); }renderCup(container) { const view = document.createElement(‘div’); view.className = ‘cup-view’;// Render all phases as list this.renderListView(view, this.currentData.phases);container.appendChild(view); }groupPhasesByType(phases) { const grouped = { group: [], knockout: [] };phases.forEach(phase => { if (phase.type === ‘knockout’) { grouped.knockout.push(phase); } else { grouped.group.push(phase); } });return grouped; }renderListView(container, phases) { phases.forEach(phase => { const phaseContainer = this.createPhaseContainer(phase, false); container.appendChild(phaseContainer); }); }createPhaseContainer(phase) { const phaseContainer = document.createElement(‘div’); phaseContainer.className = `phase-container ${phase.type}`;const phaseHeader = document.createElement(‘div’); phaseHeader.className = ‘phase-header’; phaseHeader.innerHTML = `
${phase.name} Choisir une journée…
${phase.type === ‘group’ ? ‘‘ :  »} ${phase.type === ‘group’ ? ‘‘ :  »}
`; phaseContainer.appendChild(phaseHeader);// Add event listeners to header buttons const headerBtns = phaseHeader.querySelectorAll(‘.header-tab-btn’); headerBtns.forEach(btn => { btn.addEventListener(‘click’, (e) => { e.stopPropagation(); const tabType = btn.dataset.tab; // Update button styles for all tabs headerBtns.forEach(b => { b.classList.remove(‘active’); b.style.background = ‘transparent’; b.style.color = ‘rgba(255,255,255,0.7)’; }); btn.classList.add(‘active’); btn.style.background = ‘rgba(255,255,255,0.2)’; btn.style.color = ‘white’; this.showPhaseTab(phaseContainer, phase, tabType); }); });// Initial content const contentContainer = document.createElement(‘div’); contentContainer.className = ‘phase-content’; phaseContainer.appendChild(contentContainer); // Show rounds by default (matches) this.showPhaseTab(phaseContainer, phase, ’rounds’);return phaseContainer; }showPhaseTab(container, phase, tab) { // Update content const contentArea = container.querySelector(‘.phase-content’); contentArea.innerHTML =  »; if (tab === ’rounds’) { const matchesContainer = this.createMatchesListGrouped(phase.matches); contentArea.appendChild(matchesContainer); // Initialize header selector with journée data const headerSelector = container.querySelector(‘.journee-selector-header’); if (headerSelector && matchesContainer.journeeData) { const { sortedJournees, defaultJournee } = matchesContainer.journeeData; // Clear existing options headerSelector.innerHTML =  »; // Add journée options console.log(‘Initializing selector with default journée:’, defaultJournee); sortedJournees.forEach(journee => { const option = document.createElement(‘option’); option.value = journee; option.textContent = journee; if (journee === defaultJournee) { option.selected = true; console.log(‘Selected option:’, journee); } headerSelector.appendChild(option); }); // Set the selected value explicitly headerSelector.value = defaultJournee; console.log(‘Set selector value to:’, headerSelector.value); // Remove existing event listeners and add new one const newHeaderSelector = headerSelector.cloneNode(true); newHeaderSelector.value = defaultJournee; // Ensure value is maintained after cloning headerSelector.parentNode.replaceChild(newHeaderSelector, headerSelector); newHeaderSelector.addEventListener(‘change’, (e) => { if (matchesContainer.showJourneeMatches) { matchesContainer.showJourneeMatches(e.target.value); } }); // Show the selector newHeaderSelector.style.display = ‘block’; console.log(‘Final selector value:’, newHeaderSelector.value); } } else if (tab === ‘standings’) { // Keep header selector visible const headerSelector = container.querySelector(‘.journee-selector-header’); if (headerSelector) { headerSelector.style.display = ‘block’; } this.renderPhaseStandings(contentArea, phase); } }renderPhaseStandings(container, phase) { const standingsContainer = document.createElement(‘div’); standingsContainer.className = ‘standings-table’; standingsContainer.style.cssText = ‘background: white; border-radius: 5px; overflow: hidden; margin-top: 20px;’; if (phase.standings && phase.standings.length > 0) { const table = document.createElement(‘table’); table.style.cssText = ‘width: 100%; border-collapse: collapse;’; // Header const thead = document.createElement(‘thead’); const headerRow = document.createElement(‘tr’); headerRow.style.cssText = ‘background: #f3f4f6; border-bottom: 2px solid #e5e7eb;’; headerRow.innerHTML = `ÉquipeJVD+/-Pts `; thead.appendChild(headerRow); table.appendChild(thead); // Body const tbody = document.createElement(‘tbody’); phase.standings.forEach((team, index) => { const row = document.createElement(‘tr’); row.style.cssText = `border-bottom: 1px solid #e5e7eb; ${index % 2 === 0 ? ‘background: #f9fafb;’ :  »} transition: background-color 0.2s ease;`; row.innerHTML = `
${team.rank || index + 1}. ${team.team_name} ${team.team_name}
${team.matchs_joues}${team.matchs_gagnes}${team.matchs_perdus}= 0 ? ‘#059669’ : ‘#dc2626’}; font-weight: 500; »>${team.diff_buts >= 0 ? ‘+’ :  »}${team.diff_buts} ${team.points} `; tbody.appendChild(row); }); table.appendChild(tbody); standingsContainer.appendChild(table); } else { const noStandings = document.createElement(‘p’); noStandings.textContent = ‘Aucun classement disponible’; noStandings.style.cssText = ‘color: #6b7280; text-align: center; padding: 40px;’; standingsContainer.appendChild(noStandings); } container.appendChild(standingsContainer); }renderChampionship(container) { const view = document.createElement(‘div’); view.className = ‘championship-view’;// Render each group this.currentData.groups.forEach(group => { const groupContainer = this.createGroupContainer(group); view.appendChild(groupContainer); });container.appendChild(view); }createGroupContainer(group) { const groupContainer = document.createElement(‘div’); groupContainer.className = ‘phase-container group’;const groupHeader = document.createElement(‘div’); groupHeader.className = ‘phase-header’; groupHeader.innerHTML = `
${group.name === ‘1’ ? ‘Top 14’ : `Groupe ${group.name}`}
`; groupContainer.appendChild(groupHeader);// Add event listeners to header buttons const headerBtns = groupHeader.querySelectorAll(‘.header-tab-btn’); headerBtns.forEach(btn => { btn.addEventListener(‘click’, (e) => { e.stopPropagation(); const tabType = btn.dataset.tab; // Update button styles with smooth transition headerBtns.forEach(b => { b.classList.remove(‘active’); b.style.transition = ‘all 0.3s ease’; b.style.background = ‘transparent’; b.style.color = ‘rgba(255,255,255,0.7)’; }); btn.classList.add(‘active’); btn.style.transition = ‘all 0.3s ease’; btn.style.background = ‘rgba(255,255,255,0.2)’; btn.style.color = ‘white’; this.switchGroupTab(groupContainer, tabType, group); // Update inline dates after tab switch setTimeout(() => this.updateInlineCompetitionDates(), 50); }); });// Content area const contentArea = document.createElement(‘div’); contentArea.className = ‘group-content’; groupContainer.appendChild(contentArea);// Initially show rounds this.renderGroupRounds(contentArea, group);return groupContainer; }switchGroupTab(container, tab, group) { // Update tab styles const tabs = container.querySelectorAll(‘.tab’); tabs.forEach(t => t.classList.remove(‘active’)); const activeTab = Array.from(tabs).find(t => (tab === ’rounds’ && t.textContent === ‘Journées’) || (tab === ‘standings’ && t.textContent === ‘Classement’) ); if (activeTab) activeTab.classList.add(‘active’);// Update content const contentArea = container.querySelector(‘.group-content’); contentArea.innerHTML =  »; if (tab === ’rounds’) { this.renderGroupRounds(contentArea, group); } else { this.renderGroupStandings(contentArea, group); } }renderGroupRounds(container, group) { const roundsContainer = document.createElement(‘div’); roundsContainer.className = ‘matches-list’; if (group.rounds && group.rounds.length > 0) { group.rounds.forEach(round => { const roundHeader = document.createElement(‘h3’); roundHeader.textContent = round.name; roundHeader.style.cssText = ‘margin: 20px 0 10px 0; color: #475569;’; roundsContainer.appendChild(roundHeader); if (round.matches && round.matches.length > 0) { round.matches.forEach(match => { const matchCard = this.createMatchCard(match); roundsContainer.appendChild(matchCard); }); } else { const noMatches = document.createElement(‘p’); noMatches.textContent = ‘Aucun match programmé’; noMatches.style.cssText = ‘color: #6b7280; font-style: italic; margin-bottom: 20px; padding-left: 20px;’; roundsContainer.appendChild(noMatches); } }); } else { const noRounds = document.createElement(‘p’); noRounds.textContent = ‘Aucune journée disponible’; noRounds.style.cssText = ‘color: #6b7280; text-align: center; padding: 40px;’; roundsContainer.appendChild(noRounds); } container.appendChild(roundsContainer); }renderGroupStandings(container, group) { const standingsContainer = document.createElement(‘div’); standingsContainer.className = ‘standings-table’; standingsContainer.style.cssText = ‘background: white; border-radius: 5px; overflow: hidden; margin-top: 20px;’; if (group.standings && group.standings.length > 0) { const table = document.createElement(‘table’); table.style.cssText = ‘width: 100%; border-collapse: collapse;’; // Header const header = document.createElement(‘thead’); header.innerHTML = `PosÉquipeJGNP+/-Pts `; table.appendChild(header); // Body const tbody = document.createElement(‘tbody’); group.standings.forEach((team, index) => { const row = document.createElement(‘tr’); row.style.cssText = `border-bottom: 1px solid #e5e7eb; ${index % 2 === 0 ? ‘background: #f9fafb;’ :  »} transition: background-color 0.2s ease;`; row.innerHTML = `${index + 1}
${team.team_name} ${team.team_name}
${team.matchs_joues || 0}${team.matchs_gagnes || 0}${team.matchs_nuls || 0}${team.matchs_perdus || 0}${team.diff_buts || 0}${team.points || 0} `; tbody.appendChild(row); }); table.appendChild(tbody); standingsContainer.appendChild(table); } else { const noStandings = document.createElement(‘p’); noStandings.textContent = ‘Aucun classement disponible’; noStandings.style.cssText = ‘color: #6b7280; text-align: center; padding: 40px;’; standingsContainer.appendChild(noStandings); } container.appendChild(standingsContainer); }renderTournament(container) { const view = document.createElement(‘div’); view.className = ‘tournament-view’;// Group phases by type for better organization const groupedPhases = this.groupPhasesByType(this.currentData.phases);// Render championship phase with rounds navigation if (groupedPhases.group.length > 0) { const championshipPhase = groupedPhases.group[0]; this.renderChampionshipPhase(view, championshipPhase); }// Render knockout phases as list if (groupedPhases.knockout.length > 0) { this.renderListView(view, groupedPhases.knockout); }container.appendChild(view); }renderChampionshipPhase(container, phase) { const phaseContainer = document.createElement(‘div’); phaseContainer.className = ‘phase-container group’;const phaseHeader = document.createElement(‘div’); phaseHeader.className = ‘phase-header’; phaseHeader.innerHTML = `
${phase.name}
`; phaseContainer.appendChild(phaseHeader);// Add event listeners to header buttons const headerBtns = phaseHeader.querySelectorAll(‘.header-tab-btn’); headerBtns.forEach(btn => { btn.addEventListener(‘click’, (e) => { e.stopPropagation(); const tabType = btn.dataset.tab; // Update button styles with smooth transition headerBtns.forEach(b => { b.classList.remove(‘active’); b.style.transition = ‘all 0.3s ease’; b.style.background = ‘transparent’; b.style.color = ‘rgba(255,255,255,0.7)’; }); btn.classList.add(‘active’); btn.style.transition = ‘all 0.3s ease’; btn.style.background = ‘rgba(255,255,255,0.2)’; btn.style.color = ‘white’; this.switchChampionshipTab(phaseContainer, tabType, phase); // Update inline dates after tab switch setTimeout(() => this.updateInlineCompetitionDates(), 50); }); });// Setup rounds dropdown in header this.setupHeaderRoundsDropdown(phaseHeader, phase, phaseContainer);// Content area const contentArea = document.createElement(‘div’); contentArea.className = ‘championship-content’; phaseContainer.appendChild(contentArea);// Initially show rounds with navigation this.renderChampionshipRounds(contentArea, phase);container.appendChild(phaseContainer); }switchChampionshipTab(container, tab, phase) { // Update tab styles const tabs = container.querySelectorAll(‘.tab’); tabs.forEach(t => t.classList.remove(‘active’)); const activeTab = Array.from(tabs).find(t => (tab === ’rounds’ && t.textContent === ‘Journées’) || (tab === ‘standings’ && t.textContent === ‘Classement’) ); if (activeTab) activeTab.classList.add(‘active’);// Update content const contentArea = container.querySelector(‘.championship-content’); contentArea.innerHTML =  »; if (tab === ’rounds’) { this.renderChampionshipRounds(contentArea, phase); } else { this.renderChampionshipStandings(contentArea, phase); } }renderChampionshipRounds(container, phase) { // Matches container only – selector is now in header const matchesContainer = document.createElement(‘div’); matchesContainer.className = ’round-matches’; container.appendChild(matchesContainer);// Show first round by default if (phase.rounds && phase.rounds.length > 0) { this.loadRoundMatches(matchesContainer, phase.rounds[0]); } }setupHeaderRoundsDropdown(phaseHeader, phase, phaseContainer) { const dropdownBtn = phaseHeader.querySelector(‘.rounds-dropdown-btn-header’); const dropdownMenu = phaseHeader.querySelector(‘.rounds-dropdown-menu-header’); if (!dropdownBtn || !dropdownMenu) return;// Populate dropdown menu with rounds if (phase.rounds && phase.rounds.length > 0) { phase.rounds.forEach((round, index) => { const option = document.createElement(‘div’); option.className = ’rounds-dropdown-option-header’; option.style.cssText = ` padding: 8px 12px; cursor: pointer; border-bottom: 1px solid #e5e7eb; transition: all 0.3s ease; font-size: 12px; color: #374151; `; option.textContent = round.name;// Hover effects option.onmouseenter = () => { option.style.backgroundColor = ‘#f9fafb’; }; option.onmouseleave = () => { option.style.backgroundColor = ‘transparent’; };// Click handler option.onclick = () => { // Update button text dropdownBtn.querySelector(‘span:first-child’).textContent = round.name; // Hide dropdown dropdownMenu.style.display = ‘none’; dropdownBtn.querySelector(‘span:last-child’).textContent = ‘▼’; // Load round matches const matchesContainer = phaseContainer.querySelector(‘.round-matches’); if (matchesContainer) { this.loadRoundMatches(matchesContainer, round); } };if (index === phase.rounds.length – 1) { option.style.borderBottom = ‘none’; }dropdownMenu.appendChild(option); }); }// Toggle dropdown on button click dropdownBtn.onclick = (e) => { e.stopPropagation(); const isVisible = dropdownMenu.style.display === ‘block’; dropdownMenu.style.display = isVisible ? ‘none’ : ‘block’; dropdownBtn.querySelector(‘span:last-child’).textContent = isVisible ? ‘▼’ : ‘▲’; };// Close dropdown when clicking outside document.addEventListener(‘click’, (e) => { if (!phaseHeader.querySelector(‘.rounds-selector-header’).contains(e.target)) { dropdownMenu.style.display = ‘none’; dropdownBtn.querySelector(‘span:last-child’).textContent = ‘▼’; } }); }async selectRoundById(container, round, selectedOption) { // Display matches for selected round const matchesContainer = container.querySelector(‘.round-matches’); this.loadRoundMatches(matchesContainer, round); }async loadRoundMatches(container, round) { // Show loading container.innerHTML = ‘
Chargement…
‘;try { const response = await fetch(`${this.apiBase}/competitions/${this.competitionId}/rounds/${round.id}`); const data = await response.json(); this.displayRoundMatches(container, data.matches); } catch (error) { console.error(‘Error loading round matches:’, error); container.innerHTML = ‘
Erreur lors du chargement des matches
‘; } }groupMatchesByRound(matches) { const grouped = {}; matches.forEach(match => { const roundName = this.extractRoundName(match); if (!grouped[roundName]) { grouped[roundName] = []; } grouped[roundName].push(match); }); return grouped; }extractRoundName(match) { // Try to extract round name from match data if (match.phase_name) { return match.phase_name; } // Fallback to date-based grouping const date = new Date(match.date); return `Journée du ${date.toLocaleDateString(‘fr-FR’, { day: ‘numeric’, month: ‘short’ })}`; }selectRound(container, roundName, matchesByRound, selectedBtn) { // Update button styles const buttons = container.querySelectorAll(‘.round-btn’); buttons.forEach(btn => { btn.style.background = ‘white’; btn.style.color = ‘#374151’; btn.style.borderColor = ‘#e5e7eb’; btn.classList.remove(‘active’); }); selectedBtn.style.background = ‘#475569’; selectedBtn.style.color = ‘white’; selectedBtn.style.borderColor = ‘#475569’; selectedBtn.classList.add(‘active’);// Display matches for selected round const matchesContainer = container.querySelector(‘.round-matches’); this.displayRoundMatches(matchesContainer, matchesByRound[roundName]); }displayRoundMatches(container, matches) { container.innerHTML =  »; const matchesList = document.createElement(‘div’); matchesList.className = ‘matches-list’; matches.forEach(match => { const matchCard = this.createMatchCard(match); matchesList.appendChild(matchCard); }); container.appendChild(matchesList); }renderChampionshipStandings(container, phase) { const standingsContainer = document.createElement(‘div’); standingsContainer.className = ‘standings-table’; standingsContainer.style.cssText = ‘background: white; border-radius: 5px; overflow: hidden; margin-top: 20px;’; if (phase.standings && phase.standings.length > 0) { const table = document.createElement(‘table’); table.style.cssText = ‘width: 100%; border-collapse: collapse;’; // Header const header = document.createElement(‘thead’); header.innerHTML = `PosÉquipeJGNP+/-Pts `; table.appendChild(header); // Body const tbody = document.createElement(‘tbody’); phase.standings.forEach((team, index) => { const row = document.createElement(‘tr’); row.style.cssText = `border-bottom: 1px solid #e5e7eb; ${index % 2 === 0 ? ‘background: #f9fafb;’ :  »} transition: background-color 0.2s ease;`; row.innerHTML = `${index + 1}
${team.team_name} ${team.team_name}
${team.matchs_joues || 0}${team.matchs_gagnes || 0}${team.matchs_nuls || 0}${team.matchs_perdus || 0}${team.diff_buts || 0}${team.points || 0} `; tbody.appendChild(row); }); table.appendChild(tbody); standingsContainer.appendChild(table); } else { const noStandings = document.createElement(‘p’); noStandings.textContent = ‘Aucun classement disponible’; noStandings.style.cssText = ‘color: #6b7280; text-align: center; padding: 40px;’; standingsContainer.appendChild(noStandings); } container.appendChild(standingsContainer); }renderDefault(container) { // Fallback rendering const matchesList = this.createMatchesList(this.currentData.matches || []); container.appendChild(matchesList); }createMatchesListGrouped(matches) { const container = document.createElement(‘div’); container.className = ‘matches-list-grouped’;// Group matches by journée (phase_name) const matchesByJournee = {}; matches.forEach(match => { const journee = match.phase_name || ‘Matches’; if (!matchesByJournee[journee]) { matchesByJournee[journee] = []; } matchesByJournee[journee].push(match); });// Sort journées chronologically const sortedJournees = Object.keys(matchesByJournee).sort((a, b) => { // Extract number from « 1re journée », « 2e journée », etc. const getJourneeNumber = (str) => { const match = str.match(/(\d+)[re]+\s+journ/i); return match ? parseInt(match[1]) : 999; }; return getJourneeNumber(a) – getJourneeNumber(b); });if (sortedJournees.length === 0) { const noMatches = document.createElement(‘div’); noMatches.style.cssText = ‘text-align: center; padding: 40px; color: #6b7280; background: white; border-radius: 8px;’; noMatches.innerHTML = `

Aucun match disponible

`; container.appendChild(noMatches); return container; }// Find the closest journée to current date const getCurrentClosestJournee = () => { const today = new Date(); today.setHours(0, 0, 0, 0); // Reset time to compare only dates let closestJournee = sortedJournees[0]; let minDiff = Infinity;console.log(‘Looking for closest journée to today:’, today.toDateString());sortedJournees.forEach(journee => { const journeeMatches = matchesByJournee[journee]; if (journeeMatches.length > 0) { // Get the earliest match date in this journée const earliestMatch = journeeMatches.reduce((earliest, match) => { const matchDate = new Date(match.date); const earliestDate = new Date(earliest.date); return matchDate < earliestDate ? match : earliest; }); const matchDate = new Date(earliestMatch.date); matchDate.setHours(0, 0, 0, 0); // Reset time to compare only dates const diff = Math.abs(matchDate – today); console.log(`Journée "${journee}": earliest match ${matchDate.toDateString()}, diff: ${diff} days`); if (diff { contentArea.innerHTML =  »; if (!matchesByJournee[selectedJournee]) return;const journeeSection = document.createElement(‘div’); journeeSection.className = ‘journee-section’;// Matches container (sans header vert) const matchesContainer = document.createElement(‘div’); matchesContainer.className = ‘journee-matches’; matchesContainer.style.cssText = ‘background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);’; matchesByJournee[selectedJournee].forEach((match, index) => { const matchCard = this.createMatchCard(match); matchCard.style.borderRadius = ‘0’; matchCard.style.marginBottom = ‘0’; if (index { const matchCard = this.createMatchCard(match); container.appendChild(matchCard); });return container; }createMatchCard(match) { const isFinished = match.etat === ‘termine’; const isLive = match.etat === ‘endirect’; const card = document.createElement(‘div’); card.className = `match-card ${isFinished ? ‘finished’ :  »} ${isLive ? ‘live’ :  »}`; card.setAttribute(‘data-match-id’, match.id); card.onclick = () => window.location.href = `https://vibrez-rugby.com/live-en-direct/?id=${match.id}`;// Add status indicator const statusBar = document.createElement(‘div’); statusBar.className = ‘match-status’; card.appendChild(statusBar);// Determine winner if match is finished let homeWinner = false, awayWinner = false; if (isFinished && match.score_locale !== null && match.score_visiteuse !== null) { const homeScore = parseInt(match.score_locale) || 0; const awayScore = parseInt(match.score_visiteuse) || 0; if (homeScore > awayScore) { homeWinner = true; } else if (awayScore > homeScore) { awayWinner = true; } }// Mobile layout (default) if (window.innerWidth <= 768) { // Determine what to show in center (score or date) let centerContent; if (isFinished || isLive) { // Show score const homeScore = match.score_locale || '0'; const awayScore = match.score_visiteuse || '0'; centerContent = `
${homeScore} – ${awayScore}
`; } else { // Show date/time const matchDate = new Date(match.date); centerContent = `
${matchDate.toLocaleDateString(‘fr-FR’, { day: ‘numeric’, month: ‘short’ })}
${matchDate.toLocaleTimeString(‘fr-FR’, { hour: ‘2-digit’, minute: ‘2-digit’ })}
`; }card.innerHTML += `
${match.local_team.name}
${centerContent}
${match.visitor_team.name}
`; } else { // Desktop layout – back to original row format card.className = ‘match-row’; card.setAttribute(‘data-match-id’, match.id); card.innerHTML = `
${match.local_team.name}
${(isFinished || isLive) ? `
${match.score_locale || 0} – ${match.score_visiteuse || 0}
` : `
${new Date(match.date).toLocaleDateString(‘fr-FR’, { day: ‘numeric’, month: ‘long’, year: ‘numeric’ })} ${new Date(match.date).toLocaleTimeString(‘fr-FR’, { hour: ‘2-digit’, minute: ‘2-digit’ })}
` }
${match.visitor_team.name}
`; }return card; }createMatchRow(match) { const row = document.createElement(‘div’); row.className = ‘match-row’; row.onclick = () => window.location.href = `https://vibrez-rugby.com/live-en-direct/?id=${match.id}`;// Home team const homeTeam = document.createElement(‘div’); homeTeam.className = ‘team-info’; homeTeam.innerHTML = ` ${match.local_team.display_name} `; row.appendChild(homeTeam);// Center (score or datetime) const center = document.createElement(‘div’); center.className = ‘match-center’; if (match.etat === ‘termine’ || match.etat === ‘endirect’) { const scoreBox = document.createElement(‘div’); scoreBox.className = ‘score-box’ + (match.etat === ‘endirect’ ? ‘ live’ :  »); scoreBox.textContent = `${match.score_locale || 0} – ${match.score_visiteuse || 0}`; center.appendChild(scoreBox); } else { const datetime = new Date(match.date); center.innerHTML = `
${datetime.toLocaleDateString(‘fr-FR’, { day: ‘numeric’, month: ‘long’, year: ‘numeric’ })} ${datetime.toLocaleTimeString(‘fr-FR’, { hour: ‘2-digit’, minute: ‘2-digit’ })}
`; } row.appendChild(center);// Away team const awayTeam = document.createElement(‘div’); awayTeam.className = ‘team-info away’; awayTeam.innerHTML = ` ${match.visitor_team.display_name} `; row.appendChild(awayTeam);return row; }startAutoUpdate() { // Update scores every 30 seconds this.updateInterval = setInterval(() => { this.updateLiveScores(); }, 30000); }async updateLiveScores() { // Only update if there are live matches if (!this.hasLiveMatches()) return;try { const response = await fetch(`${this.apiBase}/competitions/${this.competitionId}/live_scores`); const liveData = await response.json(); // Update UI with new scores this.updateScoresInUI(liveData); } catch (error) { console.error(‘Erreur lors de la mise à jour des scores:’, error); } }hasLiveMatches() { // Check if any match is live return true; // Simplified }updateScoresInUI(liveData) { // Update scores without full re-render // Implementation depends on your needs }showError(message) { const mainContent = document.getElementById(‘mainContent’); mainContent.innerHTML = `

Erreur

${message}

`; }destroy() { if (this.updateInterval) { clearInterval(this.updateInterval); } if (this.cable) { this.cable.close(); } } }// Initialize on page load document.addEventListener(‘DOMContentLoaded’, () => { const manager = new CompetitionManager(); manager.init();// Cleanup on page unload window.addEventListener(‘beforeunload’, () => { manager.destroy(); }); });

Résultats PRO D2

Résultats Pro D2 et tout le calendrier de ce championnat.

Matchs de Pro D2 en direct, cliquez sur le club ou le match de votre choix pour suivre la rencontre en direct/live, voir ou revoir les actions du match, les joueurs qui ont marqué, ainsi que la composition des équipes. Vous pouvez également conserver cette page afin de suivre l’évolution des scores de chaque équipe, y compris les Résultats PRO D2.

Résultats PRO D2 : suivez l’action palpitante du championnat

La PRO D2 est la deuxième division du rugby français. Elle offre une plateforme compétitive aux clubs aspirant à intégrer l’élite du rugby. Ce championnat, à travers ses Résultats PRO D2, est un pilier essentiel du développement du rugby en France. Découvrons ensemble les grandes lignes de cette compétition, son format, et les équipes qui l’animent.

Le format de la PRO D2

Le championnat PRO D2 regroupe 16 équipes professionnelles. Ces clubs s’affrontent au cours d’une saison régulière, où chaque équipe joue à domicile et à l’extérieur. Les Résultats PRO D2 reflètent la lutte acharnée entre ces formations, avec pour objectif ultime de terminer parmi les meilleures et ainsi rêver de promotion.

L’enjeu de la promotion vers le TOP 14

La promotion est au cœur de la compétition. Pour chaque équipe, l’objectif principal est d’accéder au TOP 14, le sommet du rugby français. Les Résultats PRO D2 jouent un rôle crucial dans ce parcours, car ils déterminent les équipes qui se qualifieront pour les phases finales, menant potentiellement à la montée.

Les clubs emblématiques de la PRO D2

Des clubs prestigieux comme l’US Oyonnax, le SU Agen ou le Biarritz Olympique sont des noms bien connus du rugby français. Ces équipes, souvent en quête de promotion, contribuent à rendre la compétition plus intense. Les Résultats PRO D2 témoignent de leur ambition et de leur lutte pour atteindre les sommets.

Le rôle de la PRO D2 dans le développement des talents

La PRO D2 est une véritable pépinière de jeunes talents. De nombreux joueurs font leurs débuts dans cette compétition avant d’atteindre l’élite. Les Résultats PRO D2 permettent aux recruteurs et observateurs de repérer ces futurs stars du rugby, qui gagnent en expérience au fil des matchs.

Des matchs sous haute intensité

Les rencontres de la PRO D2 sont souvent intenses, et chaque point compte dans la course à la promotion. Les équipes rivalisent d’efforts pour grimper au classement, et les Résultats PRO D2 reflètent cette détermination. Que ce soit lors des matchs à domicile ou à l’extérieur, les équipes donnent tout sur le terrain.

Suivre les Résultats PRO D2 en direct

Pour les passionnés de rugby, il est désormais facile de suivre les Résultats PRO D2 en direct. Grâce à une couverture complète, que ce soit à la radio, en ligne ou via des applications dédiées, vous ne manquerez rien des exploits de vos équipes préférées. Chaque essai, transformation et pénalité est commenté en direct pour enrichir votre expérience.

Conclusion

La PRO D2 n’est pas seulement une compétition de rugby, c’est un vivier de talents et une bataille féroce pour la promotion vers le TOP 14. Grâce aux Résultats PRO D2, les amateurs peuvent suivre de près l’évolution de leurs équipes favorites. Ne manquez aucun moment fort de cette compétition captivante et plongez dans l’univers du rugby avec passion.


Pour Résumer : La PRO D2 est un championnat clé du rugby français. Les Résultats permettent aux fans de suivre l’évolution de la saison et d’observer la lutte des équipes pour la promotion vers le TOP 14.

Résultats Pro D2
Résultats Pro D2
Partager :