From 073543fc481732dc8a1d83ab1e55b89e3251130b Mon Sep 17 00:00:00 2001 From: cedrick2711 Date: Wed, 15 Jul 2026 13:31:26 -0400 Subject: [PATCH] =?UTF-8?q?ajout=20de=20d=C3=A9placement=20des=20carte=20a?= =?UTF-8?q?ffich=C3=A9es=20dans=20le=20dashboard=20et=20les=20tryouts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/app.cpython-312.pyc | Bin 2835 -> 2996 bytes instance/team_tryouts.db | Bin 126976 -> 126976 bytes routes/__pycache__/main.cpython-312.pyc | Bin 9633 -> 9670 bytes routes/__pycache__/matches.cpython-312.pyc | Bin 26154 -> 26191 bytes routes/__pycache__/tryouts.cpython-312.pyc | Bin 22604 -> 22641 bytes static/css/style.css | 116 ++++++- static/js/main.js | 302 +++++++++++++++++- templates/pages/view_tryout.html | 345 ++++++++++----------- 8 files changed, 578 insertions(+), 185 deletions(-) diff --git a/__pycache__/app.cpython-312.pyc b/__pycache__/app.cpython-312.pyc index ee6c872a5d86102b41e3c31301368ee51a6420b1..ef4b7f9a3e9c21936e36d1ae185ba6ca424f1c74 100644 GIT binary patch delta 705 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 z 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 Gs{bF-i1|$b diff --git a/routes/__pycache__/main.cpython-312.pyc b/routes/__pycache__/main.cpython-312.pyc index efb111b57dbc87ef30fb2a4ce1335c3361e15904..64de34a10976651911c809e2ea871bd7c12a5d85 100644 GIT binary patch delta 71 zcmZ4JeaxHtG%qg~0}$|chHvCfWYRTGwu%WYPAw{q@k!0gFUyZ{NiEJU$uEd0Nlnbv XEh(zZFD)sKDFTwI#W9;pm~@o^G$I(I delta 34 ocmX@+z0jNcG%qg~0}zyb2;0b=$i%@{lwVqsTCBf$CX=o*0JTR7SO5S3 diff --git a/routes/__pycache__/matches.cpython-312.pyc b/routes/__pycache__/matches.cpython-312.pyc index acfa273bf02e4b1e64c97394210476aef8a4b5a5..bb58558b066f0114e61346f5272808e19754b6c9 100644 GIT binary patch delta 73 zcmZ2=hVlFvM()$Ryj%=Gz~33Zk=vd{*DTp8CbT%Us5r(aH7~y`KgK1sIJ+djAf_ZW aF;};ws4~B_q&TJsNTwFYYz|_%kq7{OvKnOo delta 36 qcmX?qhH=#yM()$Ryj%=Gpz$qiBey*ZhhR~DX-R6a{^oL)8;Jnc5ew1) diff --git a/routes/__pycache__/tryouts.cpython-312.pyc b/routes/__pycache__/tryouts.cpython-312.pyc index a4a5ccd689f4c0474b716686b14953ec64c2f42f..8bbbef8a4a8abd02c9663408a720313d02cb6998 100644 GIT binary patch delta 73 zcmX@Jf$`%8M()$Ryj%=Gz~33Zk-LRO*DTp8CbT%Us5r(aH7~y`KgK1sIJ+djAf_ZW aF;};ws4~B_q&TJsNTwFYY@W`tH5dSqO&ZDo delta 36 qcmeykf$_`+M()$Ryj%=G;PWkPBXkL}} diff --git a/static/css/style.css b/static/css/style.css index 40ae852..65fda10 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -325,12 +325,30 @@ a:hover { color: var(--primary-dark); } /* Dashboard Grid */ .dashboard-grid { display: grid; - grid-template-columns: 1fr 1fr; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; } +/* Allow cards to span full width or be placed flexibly */ +.dashboard-grid .card { + min-width: 0; +} + +/* Card position control - can be set via data-position attribute */ +.dashboard-grid .card[data-position="right"] { + grid-column: 2 / -1; +} + +.dashboard-grid .card[data-position="left"] { + grid-column: 1 / -1; +} + @media (max-width: 900px) { .dashboard-grid { grid-template-columns: 1fr; } + .dashboard-grid .card[data-position="right"], + .dashboard-grid .card[data-position="left"] { + grid-column: auto; + } } /* Tables */ @@ -1499,3 +1517,99 @@ a:hover { color: var(--primary-dark); } background: var(--bg-tertiary); color: var(--text-primary); } + +/* Draggable Blocks */ +.drag-handle { + cursor: move; + padding: 8px; + margin-right: 8px; + border-radius: var(--radius-sm); + color: var(--gray-400); + transition: var(--transition); + display: flex; + align-items: center; + gap: 2px; +} + +.drag-handle:hover { + background: var(--gray-100); + color: var(--gray-600); +} + +.drag-handle:active { + cursor: grabbing; +} + +.card.dragging { + opacity: 0.5; + transform: scale(0.98); + transition: opacity 0.2s ease, transform 0.2s ease; +} + +/* Drop placeholder - shows where card will be inserted */ +.sortable-placeholder { + background: var(--primary-light); + border: 2px dashed var(--primary); + border-radius: var(--radius); + min-height: 100px; + opacity: 0.5; + width: 100%; + box-sizing: border-box; +} + +/* Dark mode placeholder */ +[data-theme="dark"] .sortable-placeholder { + background: var(--bg-tertiary); + border-color: var(--primary); +} + +/* Ghost is now controlled via inline styles in JS */ +.sortable-ghost { + opacity: 0.9; +} + +.sortable-chosen { + transform: scale(1.01); + box-shadow: var(--shadow-md); +} + +.card-header .drag-handle { + margin-left: auto; + margin-right: 0; +} + +.card-header .drag-handle:first-child { + margin-left: 0; +} + +/* Dark mode drag handle */ +[data-theme="dark"] .drag-handle { + color: var(--text-muted); +} + +[data-theme="dark"] .drag-handle:hover { + background: var(--bg-tertiary); + color: var(--text-secondary); +} + +/* Make cards draggable by header */ +.card-header { + cursor: default; +} + +.card-header.draggable { + position: relative; +} + +.card-header.draggable:hover .drag-handle { + opacity: 1; +} + +.card-header.draggable .drag-handle { + opacity: 0.4; + position: absolute; + right: 16px; + top: 50%; + transform: translateY(-50%); + margin: 0; +} diff --git a/static/js/main.js b/static/js/main.js index bfb9890..94f4546 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -45,11 +45,300 @@ document.addEventListener('click', function(event) { } }); -// Auto-dismiss flash messages +// Confirm delete actions +document.querySelectorAll('[data-confirm]').forEach(function(el) { + el.addEventListener('click', function(e) { + if (!confirm(this.getAttribute('data-confirm'))) { + e.preventDefault(); + } + }); +}); + +// Draggable Blocks Functionality +function initDraggableBlocks() { + const grids = document.querySelectorAll('.dashboard-grid'); + + grids.forEach(function(grid) { + const cards = grid.querySelectorAll('.card'); + + // Add drag handles to card headers + cards.forEach(function(card, index) { + const header = card.querySelector('.card-header'); + if (header) { + // Add unique ID to card if not present + if (!card.id) { + card.id = 'block-' + index; + } + + // Create drag handle + const dragHandle = document.createElement('div'); + dragHandle.className = 'drag-handle'; + dragHandle.innerHTML = ''; + dragHandle.title = 'Drag to reorder'; + + // Add draggable class to header + header.classList.add('draggable'); + header.prepend(dragHandle); + + // Make header draggable + makeHeaderDraggable(header, card, grid); + } + }); + + // Load saved layout + loadLayout(grid); + }); +} + +function makeHeaderDraggable(header, card, grid) { + let draggedElement = null; + let placeholder = null; + let ghost = null; + let animationFrame = null; + + header.addEventListener('mousedown', function(e) { + // Only start drag from drag handle + if (!e.target.closest('.drag-handle')) return; + + e.preventDefault(); + draggedElement = card; + + // Get card dimensions + const rect = card.getBoundingClientRect(); + const offsetX = e.clientX - rect.left; + const offsetY = e.clientY - rect.top; + + // Store original data-position to restore later + const originalDataPosition = card.getAttribute('data-position'); + + // Remove data-position during drag to allow free placement + if (originalDataPosition) { + card.removeAttribute('data-position'); + } + + // Create ghost element (floating preview) + ghost = document.createElement('div'); + ghost.className = 'sortable-ghost'; + ghost.style.position = 'fixed'; + ghost.style.pointerEvents = 'none'; + ghost.style.zIndex = '99999'; + ghost.style.width = rect.width + 'px'; + ghost.style.height = rect.height + 'px'; + ghost.style.backgroundColor = 'var(--card-bg, white)'; + ghost.style.border = '2px solid var(--primary)'; + ghost.style.borderRadius = 'var(--radius)'; + ghost.style.opacity = '0.9'; + ghost.style.boxShadow = 'var(--shadow-lg)'; + ghost.style.cursor = 'grabbing'; + document.body.appendChild(ghost); + + // Create placeholder element (shows drop position) + placeholder = document.createElement('div'); + placeholder.className = 'sortable-placeholder'; + placeholder.style.minHeight = rect.height + 'px'; + card.parentNode.insertBefore(placeholder, card); + + // Keep original card visible but add dragging style + card.classList.add('dragging'); + card.style.opacity = '0.5'; + card.style.transform = 'scale(0.98)'; + + // Initial position + ghost.style.top = (e.clientY - offsetY) + 'px'; + ghost.style.left = (e.clientX - offsetX) + 'px'; + + function updateGhostPosition(clientY, clientX) { + // Position ghost directly at cursor position + ghost.style.top = (clientY - offsetY) + 'px'; + ghost.style.left = (clientX - offsetX) + 'px'; + } + + // Get grid layout info for 2D position tracking + const gridRect = grid.getBoundingClientRect(); + const gridStyle = window.getComputedStyle(grid); + const gridGap = parseInt(gridStyle.gap) || 20; + + // Calculate column positions for 2D grid + function getColumnFromX(x) { + // Calculate which column the x position falls into + const relativeX = x - gridRect.left; + const colWidth = (gridRect.width + gridGap) / Math.max(1, Math.floor(gridRect.width / 300)); // Estimate columns based on min 300px width + return Math.floor(relativeX / (colWidth + gridGap)); + } + + function onMouseMove(e) { + e.preventDefault(); + + // Cancel any pending animation frame + if (animationFrame) { + cancelAnimationFrame(animationFrame); + } + + // Use requestAnimationFrame for smooth updates + animationFrame = requestAnimationFrame(function() { + updateGhostPosition(e.clientY, e.clientX); + + // Use a point slightly offset from cursor to avoid ghost interference + // This ensures we detect the card under the cursor, not the ghost + const checkX = e.clientX; + const checkY = e.clientY + 10; // 10px below cursor for better detection + + // Find the element under the offset point + const elementUnderCursor = document.elementFromPoint(checkX, checkY); + + // Check if we're directly over the placeholder (skip processing to avoid flicker) + if (elementUnderCursor && elementUnderCursor.closest('.sortable-placeholder')) { + return; // Already over placeholder, don't change position + } + + // Find the card that contains or is the element under cursor + let targetCard = null; + if (elementUnderCursor) { + targetCard = elementUnderCursor.closest('.card'); + // Make sure it's not the dragged card + if (targetCard && targetCard.classList.contains('dragging')) { + targetCard = null; + } + } + + // If we found a valid target card, determine insert position + if (targetCard) { + const targetRect = targetCard.getBoundingClientRect(); + const targetMiddleY = targetRect.top + targetRect.height / 2; + + // If cursor is above the card's middle, insert before it + // If cursor is below, insert after it + // Use checkY for consistent comparison with detection point + if (checkY < targetMiddleY) { + // Check if placeholder is already in the correct position + if (targetCard.nextElementSibling !== placeholder) { + grid.insertBefore(placeholder, targetCard); + } + } else { + // Insert after the target card + const nextCard = targetCard.nextElementSibling; + // If next sibling is the placeholder or the dragged element, it's already in the right position + if (nextCard === placeholder || nextCard === draggedElement) { + // Already in correct position, don't move + } else if (nextCard && nextCard.classList.contains('card')) { + grid.insertBefore(placeholder, nextCard); + } else { + grid.appendChild(placeholder); + } + } + } else { + // No target card found - check if we should move to end + // This handles the case where we're dragging over empty space or the grid background + // If cursor is within the grid bounds, move to end + if (e.clientX >= gridRect.left && e.clientX <= gridRect.right && + e.clientY >= gridRect.top && e.clientY <= gridRect.bottom) { + // Check if we're over the dragged element (which is hidden but still in DOM) + const isOverDraggedElement = elementUnderCursor && + (elementUnderCursor.closest('.card.dragging') || + elementUnderCursor.closest('.sortable-placeholder')); + + if (!isOverDraggedElement) { + // Move placeholder to end if not already there + const lastCard = grid.querySelector('.card:last-of-type'); + if (lastCard && lastCard.nextElementSibling !== placeholder) { + grid.appendChild(placeholder); + } + } + } + } + }); + } + + function onMouseUp(e) { + if (animationFrame) { + cancelAnimationFrame(animationFrame); + } + + if (draggedElement) { + draggedElement.classList.remove('dragging'); + // Restore original card styles + draggedElement.style.opacity = ''; + draggedElement.style.transform = ''; + + // Ensure the card is placed in the correct position + // The placeholder shows where the card should go + if (placeholder && placeholder.parentNode) { + // Move the dragged element to the placeholder position + placeholder.parentNode.replaceChild(draggedElement, placeholder); + } else { + // If no placeholder exists, append to the end + grid.appendChild(draggedElement); + } + + // Save layout + saveLayout(grid); + } + + if (ghost && ghost.parentNode) { + ghost.parentNode.removeChild(ghost); + } + + if (placeholder && placeholder.parentNode) { + placeholder.parentNode.removeChild(placeholder); + } + + document.removeEventListener('mousemove', onMouseMove); + document.removeEventListener('mouseup', onMouseUp); + } + + document.addEventListener('mousemove', onMouseMove); + document.addEventListener('mouseup', onMouseUp); + }); +} + +function saveLayout(grid) { + const pageKey = getPageKey(); + const cards = grid.querySelectorAll('.card'); + const order = Array.from(cards).map(card => card.id); + localStorage.setItem('blockLayout_' + pageKey, JSON.stringify(order)); +} + +function loadLayout(grid) { + const pageKey = getPageKey(); + const saved = localStorage.getItem('blockLayout_' + pageKey); + + if (saved) { + try { + const order = JSON.parse(saved); + const cards = Array.from(grid.querySelectorAll('.card')); + + // Sort cards according to saved order + order.forEach(function(id) { + const card = cards.find(c => c.id === id); + if (card) { + grid.appendChild(card); + } + }); + } catch (e) { + console.error('Failed to load layout:', e); + } + } +} + +function getPageKey() { + const path = window.location.pathname; + if (path.includes('/tryouts/')) { + return 'tryout'; + } + if (path.includes('/profile')) { + return 'profile'; + } + return 'dashboard'; +} + +// Initialize draggable blocks on DOM ready document.addEventListener('DOMContentLoaded', function() { // Load theme preference loadTheme(); + // Initialize draggable blocks + initDraggableBlocks(); + const alerts = document.querySelectorAll('.alert-dismissible'); alerts.forEach(function(alert) { setTimeout(function() { @@ -64,13 +353,4 @@ document.addEventListener('DOMContentLoaded', function() { } }, 5000); }); -}); - -// Confirm delete actions -document.querySelectorAll('[data-confirm]').forEach(function(el) { - el.addEventListener('click', function(e) { - if (!confirm(this.getAttribute('data-confirm'))) { - e.preventDefault(); - } - }); -}); +}); \ No newline at end of file diff --git a/templates/pages/view_tryout.html b/templates/pages/view_tryout.html index f6749a8..845359b 100644 --- a/templates/pages/view_tryout.html +++ b/templates/pages/view_tryout.html @@ -229,189 +229,188 @@ {% endfor %} - - {% if can_view_calendar %} -
-
-

Schedule

- {% if can_edit %} - - Schedule Match - - {% endif %} -
-
- {% if matches %} - -
- {% else %} - -
- -

No matches scheduled yet. Check back later!

+ {% if can_view_calendar %} +
+
+

Schedule

+ {% if can_edit %} + + Schedule Match + + {% endif %}
- {% endif %} - +
+ {% if matches %} + +
+ {% else %} + +
+ +

No matches scheduled yet. Check back later!

+
+ {% endif %} + {% if matches %} - -
- - - - - - - - - - {% if can_edit %} - - {% endif %} - - - - {% for item in match_data %} - {% set m = item.match %} - {% set participants = item.participants %} - - - - - - + + + {% for item in match_data %} + {% set m = item.match %} + {% set participants = item.participants %} + + + + + + + + {% if can_edit %} + + {% endif %} + + {% endfor %} + +
MatchTypeDateParticipantsTimeStatusActions
{{ m.title }} - - {% if m.match_type == 'team_vs_team' %} - Team vs Team - {% elif m.match_type == 'player_vs_player' %} - Player vs Player - {% else %} - Player Scrim - {% endif %} - - {{ m.date.strftime('%m/%d/%Y') }} - {% if m.match_type == 'team_vs_team' %} -
-
- {{ m.team1.name if m.team1 else 'Team 1' }} - {% if participants.team1_players %} -
    - {% for pl in participants.team1_players %} -
  • {{ pl.name }}{% if pl.position %} {{ pl.position }}{% endif %}
  • - {% endfor %} -
- {% endif %} -
-
vs
-
- {{ m.team2.name if m.team2 else 'Team 2' }} - {% if participants.team2_players %} -
    - {% for pl in participants.team2_players %} -
  • {{ pl.name }}{% if pl.position %} {{ pl.position }}{% endif %}
  • - {% endfor %} -
- {% endif %} -
-
- {% elif m.match_type == 'player_vs_player' %} -
-
- Team 1 - {% if participants.team1_players %} -
    - {% for pl in participants.team1_players %} -
  • {{ pl.name }}{% if pl.position %} {{ pl.position }}{% endif %}
  • - {% endfor %} -
- {% endif %} -
-
vs
-
- Team 2 - {% if participants.team2_players %} -
    - {% for pl in participants.team2_players %} -
  • {{ pl.name }}{% if pl.position %} {{ pl.position }}{% endif %}
  • - {% endfor %} -
- {% endif %} -
-
- {% else %} - {{ participants | join(', ') }} - {% endif %} -
- {% if m.start_time and m.end_time %} - {{ m.start_time.strftime('%H:%M') }} - {{ m.end_time.strftime('%H:%M') }} - {% else %} - TBD + +
+ + + + + + + + + + {% if can_edit %} + {% endif %} - - - {% if can_edit %} - - {% endif %} - - {% endfor %} - -
MatchTypeDateParticipantsTimeStatusActions - {{ m.status }} - - - Edit - -
+
{{ m.title }} + + {% if m.match_type == 'team_vs_team' %} + Team vs Team + {% elif m.match_type == 'player_vs_player' %} + Player vs Player + {% else %} + Player Scrim + {% endif %} + + {{ m.date.strftime('%m/%d/%Y') }} + {% if m.match_type == 'team_vs_team' %} +
+
+ {{ m.team1.name if m.team1 else 'Team 1' }} + {% if participants.team1_players %} +
    + {% for pl in participants.team1_players %} +
  • {{ pl.name }}{% if pl.position %} {{ pl.position }}{% endif %}
  • + {% endfor %} +
+ {% endif %} +
+
vs
+
+ {{ m.team2.name if m.team2 else 'Team 2' }} + {% if participants.team2_players %} +
    + {% for pl in participants.team2_players %} +
  • {{ pl.name }}{% if pl.position %} {{ pl.position }}{% endif %}
  • + {% endfor %} +
+ {% endif %} +
+
+ {% elif m.match_type == 'player_vs_player' %} +
+
+ Team 1 + {% if participants.team1_players %} +
    + {% for pl in participants.team1_players %} +
  • {{ pl.name }}{% if pl.position %} {{ pl.position }}{% endif %}
  • + {% endfor %} +
+ {% endif %} +
+
vs
+
+ Team 2 + {% if participants.team2_players %} +
    + {% for pl in participants.team2_players %} +
  • {{ pl.name }}{% if pl.position %} {{ pl.position }}{% endif %}
  • + {% endfor %} +
+ {% endif %} +
+
+ {% else %} + {{ participants | join(', ') }} + {% endif %} +
+ {% if m.start_time and m.end_time %} + {{ m.start_time.strftime('%H:%M') }} - {{ m.end_time.strftime('%H:%M') }} + {% else %} + TBD + {% endif %} + + {{ m.status }} + + + Edit + +
+
+ {% endif %}
- {% endif %}
-
- {% endif %} + {% endif %} -
-
-

Evaluation Summary

-
-
-
- - - - - - - - - - - - - - - - {% for eval in evaluations %} - - - - - - - - - - - - {% else %} - - - - {% endfor %} - -
PlayerEvaluatorSpeedAgilityTechniqueTeamworkAttitudeOverallRecommendation
{{ eval.player.full_name }}{{ eval.evaluator.full_name }}{{ eval.speed_score or '-' }}{{ eval.agility_score or '-' }}{{ eval.technique_score or '-' }}{{ eval.teamwork_score or '-' }}{{ eval.attitude_score or '-' }}{{ eval.overall_score or '-' }}{{ eval.position_recommendation or '-' }}
No evaluations yet.
+
+
+

Evaluation Summary

+
+
+
+ + + + + + + + + + + + + + + + {% for eval in evaluations %} + + + + + + + + + + + + {% else %} + + + + {% endfor %} + +
PlayerEvaluatorSpeedAgilityTechniqueTeamworkAttitudeOverallRecommendation
{{ eval.player.full_name }}{{ eval.evaluator.full_name }}{{ eval.speed_score or '-' }}{{ eval.agility_score or '-' }}{{ eval.technique_score or '-' }}{{ eval.teamwork_score or '-' }}{{ eval.attitude_score or '-' }}{{ eval.overall_score or '-' }}{{ eval.position_recommendation or '-' }}
No evaluations yet.
+
-