diff --git a/website/css/style.css b/website/css/style.css
index 34f4c03..1c09b9c 100644
--- a/website/css/style.css
+++ b/website/css/style.css
@@ -1027,18 +1027,41 @@ table.data-table tbody tr.row-orphan-category td {
background: color-mix(in srgb, var(--surface-hover) 60%, transparent);
}
-/* Assignment page — client table sized to rows (max 50); coach panel matches */
+/* Assignment page — panels fill remaining viewport; lists scroll inside */
+.main-content:has(.assign-page) {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ min-height: 100dvh;
+}
+
+.main-content:has(.assign-page) .page-header {
+ flex-shrink: 0;
+}
+
+.main-content:has(.assign-page) #assignContent {
+ flex: 1 1 auto;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+}
+
.assign-page {
display: flex;
flex-direction: column;
+ flex: 1 1 auto;
+ min-height: 0;
gap: 16px;
}
.assign-layout {
display: grid;
grid-template-columns: minmax(260px, min(32vw, 380px)) minmax(0, 1fr);
+ grid-template-rows: minmax(0, 1fr);
gap: 16px;
- align-items: start;
+ align-items: stretch;
+ flex: 1 1 auto;
+ min-height: 0;
}
.assign-layout > .assign-coaches,
@@ -1047,6 +1070,16 @@ table.data-table tbody tr.row-orphan-category td {
flex-direction: column;
padding: 0;
overflow: hidden;
+ height: 100%;
+ max-height: 100%;
+ min-height: 0;
+}
+
+.assign-coaches .assign-panel-body {
+ flex: 1 1 0;
+ min-height: 0;
+ overflow-y: auto;
+ overflow-x: hidden;
}
.assign-panel-header {
@@ -1066,20 +1099,13 @@ table.data-table tbody tr.row-orphan-category td {
}
.assign-panel-body {
- flex: 0 0 auto;
+ flex: 1 1 auto;
min-height: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
padding: 6px 8px 10px;
}
-.assign-coaches .assign-panel-footer--align {
- flex-shrink: 0;
- margin-top: auto;
- visibility: hidden;
- pointer-events: none;
-}
-
.assign-clients-toolbar {
flex-shrink: 0;
padding: 14px 16px;
@@ -1129,16 +1155,18 @@ table.data-table tbody tr.row-orphan-category td {
}
.assign-table-panel {
- flex: 0 0 auto;
+ flex: 1 1 auto;
+ min-height: 0;
display: flex;
flex-direction: column;
}
.assign-table-panel .table-wrapper {
- flex: none;
+ flex: 1 1 auto;
+ min-height: 0;
+ max-height: none;
overflow: auto;
box-sizing: border-box;
- max-height: none;
}
.assign-panel-footer,
@@ -1195,6 +1223,7 @@ table.data-table tbody tr.row-orphan-category td {
@media (max-width: 900px) {
.assign-layout {
grid-template-columns: 1fr;
+ grid-template-rows: minmax(0, 38%) minmax(0, 1fr);
}
}
diff --git a/website/js/pages/assignments.js b/website/js/pages/assignments.js
index 211d52d..b7c3a96 100644
--- a/website/js/pages/assignments.js
+++ b/website/js/pages/assignments.js
@@ -10,8 +10,6 @@ let filterCoachSearch = '';
let clientsByCoach = {};
let clientPage = 0;
let selectedClientCodes = new Set();
-let assignResizeObserver = null;
-let assignClientRowHeight = 0;
export async function assignmentsPage() {
selectedCoachID = null;
@@ -76,7 +74,6 @@ function renderAssignments() {
-
@@ -199,78 +196,6 @@ function renderAssignments() {
renderCoachList();
renderClientRows();
- setupAssignPanelHeightSync();
-}
-
-function setupAssignPanelHeightSync() {
- assignResizeObserver?.disconnect();
- assignResizeObserver = null;
-
- const clientCard = document.querySelector('.assign-clients-card');
- if (!clientCard || typeof ResizeObserver === 'undefined') {
- syncAssignLayoutHeights();
- return;
- }
-
- assignResizeObserver = new ResizeObserver(() => syncAssignLayoutHeights());
- assignResizeObserver.observe(clientCard);
- syncAssignLayoutHeights();
-}
-
-function syncAssignClientTableHeight() {
- const wrapper = document.querySelector('.assign-table-panel .table-wrapper');
- const table = wrapper?.querySelector('table.data-table');
- if (!wrapper || !table) return;
-
- const headerH = table.querySelector('thead')?.offsetHeight ?? 40;
- const bodyRows = [...table.querySelectorAll('tbody tr')];
- const dataRows = bodyRows.filter(tr => !tr.querySelector('td[colspan]'));
-
- let rowH = assignClientRowHeight;
- if (dataRows.length) {
- rowH = dataRows[0].offsetHeight;
- assignClientRowHeight = rowH;
- } else if (bodyRows.length) {
- rowH = bodyRows[0].offsetHeight;
- } else if (!rowH) {
- rowH = 44;
- }
-
- const rowCount = dataRows.length || 1;
- const bodyH = rowH * Math.min(rowCount, CLIENT_PAGE_SIZE);
- const maxH = rowH * CLIENT_PAGE_SIZE;
-
- wrapper.style.height = `${headerH + bodyH}px`;
- wrapper.style.maxHeight = `${headerH + maxH}px`;
- wrapper.style.overflowY = 'auto';
-}
-
-function syncAssignCoachPanelHeight() {
- const coachCard = document.querySelector('.assign-coaches');
- const clientCard = document.querySelector('.assign-clients-card');
- const coachBody = document.querySelector('.assign-coaches .assign-panel-body');
- const clientTablePanel = document.querySelector('.assign-table-panel');
- const coachFooter = document.querySelector('.assign-coaches .assign-panel-footer--align');
- const clientFooter = document.querySelector('.assign-clients-footer');
-
- if (clientFooter && coachFooter) {
- coachFooter.style.height = `${clientFooter.offsetHeight}px`;
- }
- if (coachBody && clientTablePanel) {
- const h = clientTablePanel.offsetHeight;
- coachBody.style.height = `${h}px`;
- coachBody.style.maxHeight = `${h}px`;
- }
- if (coachCard && clientCard) {
- coachCard.style.minHeight = `${clientCard.offsetHeight}px`;
- }
-}
-
-function syncAssignLayoutHeights() {
- requestAnimationFrame(() => {
- syncAssignClientTableHeight();
- requestAnimationFrame(() => syncAssignCoachPanelHeight());
- });
}
function getFilteredCoaches() {
@@ -424,7 +349,6 @@ function renderClientRows() {
});
syncSelectAllCb();
updateSelectionInfo();
- syncAssignCoachPanelHeight();
return;
}
@@ -460,7 +384,6 @@ function renderClientRows() {
});
syncSelectAllCb(slice.map(c => c.clientCode));
updateSelectionInfo();
- syncAssignLayoutHeights();
}
function getSelectedCodes() {
@@ -488,7 +411,6 @@ function updateSelectionInfo() {
const sel = document.getElementById('targetCoachSelect');
if (sel) sel.value = selectedCoachID;
}
- syncAssignLayoutHeights();
}
async function doAssign() {