Codex commited on
Commit
9d12b14
·
1 Parent(s): d3b98cb

Fix admin alignment and refine UI

Browse files
Files changed (2) hide show
  1. static/admin-v020.js +32 -8
  2. static/v020.css +88 -2
static/admin-v020.js CHANGED
@@ -221,16 +221,40 @@
221
  const startMinutes = segments[0].startMinutes;
222
  const endMinutes = segments[segments.length - 1].endMinutes;
223
  const totalMinutes = Math.max(endMinutes - startMinutes, 1);
224
- const height = Math.max(Math.round(totalMinutes * getEditorPixelsPerMinute()), 980);
 
 
225
 
226
  scheduleEditorAxis.innerHTML = "";
227
  scheduleEditorTrack.innerHTML = "";
228
  scheduleEditorAxis.style.height = `${height}px`;
229
  scheduleEditorTrack.style.height = `${height}px`;
230
 
231
- buildScheduleAxisMarks().forEach((minute, index, marks) => {
 
 
232
  const top = Math.round((minute - startMinutes) * getEditorPixelsPerMinute());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
 
 
 
 
 
 
234
  const tick = document.createElement("div");
235
  tick.className = "schedule-editor-tick";
236
  if (index === 0) {
@@ -241,18 +265,16 @@
241
  tick.style.top = `${top}px`;
242
  tick.textContent = minutesToTime(minute);
243
  scheduleEditorAxis.appendChild(tick);
244
-
245
- const line = document.createElement("div");
246
- line.className = "schedule-editor-line";
247
- line.style.top = `${top}px`;
248
- scheduleEditorTrack.appendChild(line);
249
  });
250
 
251
  segments.forEach((segment, index) => {
252
  const block = document.createElement("article");
 
253
  block.className = `schedule-editor-segment ${segment.kind}`;
254
  block.style.top = `${Math.round((segment.startMinutes - startMinutes) * getEditorPixelsPerMinute())}px`;
255
- block.style.height = `${Math.max(Math.round(segment.durationMinutes * getEditorPixelsPerMinute()), 36)}px`;
 
 
256
  block.innerHTML = `
257
  <div class="schedule-editor-segment-copy">
258
  <strong>${segment.label}</strong>
@@ -265,6 +287,8 @@
265
  scheduleEditorTrack.appendChild(block);
266
  });
267
 
 
 
268
  scheduleEditorTrack.appendChild(scheduleEditorDropzone);
269
  if (scheduleSegmentCount) {
270
  scheduleSegmentCount.textContent = `${segments.length} 段`;
 
221
  const startMinutes = segments[0].startMinutes;
222
  const endMinutes = segments[segments.length - 1].endMinutes;
223
  const totalMinutes = Math.max(endMinutes - startMinutes, 1);
224
+ const contentHeight = Math.max(Math.round(totalMinutes * getEditorPixelsPerMinute()), 980);
225
+ const dropzoneTop = contentHeight + 20;
226
+ const height = dropzoneTop + 96;
227
 
228
  scheduleEditorAxis.innerHTML = "";
229
  scheduleEditorTrack.innerHTML = "";
230
  scheduleEditorAxis.style.height = `${height}px`;
231
  scheduleEditorTrack.style.height = `${height}px`;
232
 
233
+ const marks = buildScheduleAxisMarks();
234
+ const visibleMarks = [];
235
+ marks.forEach((minute, index) => {
236
  const top = Math.round((minute - startMinutes) * getEditorPixelsPerMinute());
237
+ const line = document.createElement("div");
238
+ line.className = "schedule-editor-line";
239
+ line.style.top = `${top}px`;
240
+ scheduleEditorTrack.appendChild(line);
241
+ });
242
+
243
+ marks.forEach((minute, index) => {
244
+ const top = Math.round((minute - startMinutes) * getEditorPixelsPerMinute());
245
+ const isEdge = index === 0 || index === marks.length - 1;
246
+ const previous = visibleMarks[visibleMarks.length - 1];
247
+
248
+ if (isEdge && previous && top - previous.top < 30) {
249
+ visibleMarks.pop();
250
+ }
251
 
252
+ if (!previous || isEdge || top - (visibleMarks[visibleMarks.length - 1]?.top ?? -Infinity) >= 30) {
253
+ visibleMarks.push({ minute, top, index });
254
+ }
255
+ });
256
+
257
+ visibleMarks.forEach(({ minute, top, index }) => {
258
  const tick = document.createElement("div");
259
  tick.className = "schedule-editor-tick";
260
  if (index === 0) {
 
265
  tick.style.top = `${top}px`;
266
  tick.textContent = minutesToTime(minute);
267
  scheduleEditorAxis.appendChild(tick);
 
 
 
 
 
268
  });
269
 
270
  segments.forEach((segment, index) => {
271
  const block = document.createElement("article");
272
+ const height = Math.max(Math.round(segment.durationMinutes * getEditorPixelsPerMinute()), 36);
273
  block.className = `schedule-editor-segment ${segment.kind}`;
274
  block.style.top = `${Math.round((segment.startMinutes - startMinutes) * getEditorPixelsPerMinute())}px`;
275
+ block.style.height = `${height}px`;
276
+ block.classList.toggle("is-compact", height < 88);
277
+ block.classList.toggle("is-tight", height < 56);
278
  block.innerHTML = `
279
  <div class="schedule-editor-segment-copy">
280
  <strong>${segment.label}</strong>
 
287
  scheduleEditorTrack.appendChild(block);
288
  });
289
 
290
+ scheduleEditorDropzone.style.top = `${dropzoneTop}px`;
291
+ scheduleEditorDropzone.style.bottom = "auto";
292
  scheduleEditorTrack.appendChild(scheduleEditorDropzone);
293
  if (scheduleSegmentCount) {
294
  scheduleSegmentCount.textContent = `${segments.length} 段`;
static/v020.css CHANGED
@@ -978,12 +978,29 @@ body.planner-interacting .page-planner {
978
  width: min(1480px, calc(100% - 28px));
979
  }
980
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
981
  .admin-page-nav {
982
  display: inline-flex;
983
  gap: 8px;
984
  padding: 6px;
985
  border-radius: 999px;
986
  background: rgba(255, 255, 255, 0.05);
 
987
  }
988
 
989
  .admin-page-tab {
@@ -1057,6 +1074,7 @@ body.planner-interacting .page-planner {
1057
 
1058
  .course-row-head {
1059
  align-items: start;
 
1060
  }
1061
 
1062
  .course-row-actions {
@@ -1072,11 +1090,26 @@ body.planner-interacting .page-planner {
1072
  }
1073
 
1074
  .course-card {
1075
- padding: 16px 18px;
 
 
 
 
 
1076
  }
1077
 
1078
  .course-card .admin-card-copy {
1079
- margin: 4px 0 0;
 
 
 
 
 
 
 
 
 
 
1080
  }
1081
 
1082
  .admin-schedule-grid {
@@ -1218,6 +1251,50 @@ body.planner-interacting .page-planner {
1218
  right: 14px;
1219
  }
1220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1221
  .schedule-editor-delete {
1222
  position: absolute;
1223
  right: 14px;
@@ -1313,6 +1390,15 @@ body.planner-interacting .page-planner {
1313
  flex-wrap: wrap;
1314
  }
1315
 
 
 
 
 
 
 
 
 
 
1316
  .page-viewport,
1317
  .page-track,
1318
  .page-slide,
 
978
  width: min(1480px, calc(100% - 28px));
979
  }
980
 
981
+ .admin-layout-v2 .admin-hero {
982
+ display: grid;
983
+ grid-template-columns: minmax(0, 1fr) auto;
984
+ align-items: start;
985
+ gap: 18px 24px;
986
+ }
987
+
988
+ .admin-layout-v2 .admin-hero > div:first-child {
989
+ max-width: 760px;
990
+ }
991
+
992
+ .admin-layout-v2 .action-group {
993
+ justify-self: end;
994
+ align-self: start;
995
+ }
996
+
997
  .admin-page-nav {
998
  display: inline-flex;
999
  gap: 8px;
1000
  padding: 6px;
1001
  border-radius: 999px;
1002
  background: rgba(255, 255, 255, 0.05);
1003
+ justify-self: end;
1004
  }
1005
 
1006
  .admin-page-tab {
 
1074
 
1075
  .course-row-head {
1076
  align-items: start;
1077
+ margin-bottom: 2px;
1078
  }
1079
 
1080
  .course-row-actions {
 
1090
  }
1091
 
1092
  .course-card {
1093
+ padding: 10px 12px;
1094
+ border-radius: 20px;
1095
+ }
1096
+
1097
+ .course-card h2 {
1098
+ font-size: 1.12rem;
1099
  }
1100
 
1101
  .course-card .admin-card-copy {
1102
+ margin: 1px 0 0;
1103
+ font-size: 0.78rem;
1104
+ line-height: 1.18;
1105
+ }
1106
+
1107
+ .course-row-actions .secondary-button,
1108
+ .course-row-actions .danger-button,
1109
+ .course-row-actions .task-count {
1110
+ min-height: 34px;
1111
+ padding: 0 10px;
1112
+ font-size: 0.82rem;
1113
  }
1114
 
1115
  .admin-schedule-grid {
 
1251
  right: 14px;
1252
  }
1253
 
1254
+ .schedule-editor-segment.is-compact .schedule-editor-segment-copy {
1255
+ padding: 9px 12px 15px;
1256
+ gap: 4px;
1257
+ }
1258
+
1259
+ .schedule-editor-segment.is-compact .schedule-editor-segment-copy strong {
1260
+ font-size: 0.88rem;
1261
+ }
1262
+
1263
+ .schedule-editor-segment.is-compact .schedule-editor-segment-kind {
1264
+ font-size: 0.72rem;
1265
+ }
1266
+
1267
+ .schedule-editor-segment.is-compact .schedule-editor-delete {
1268
+ top: 10px;
1269
+ bottom: auto;
1270
+ }
1271
+
1272
+ .schedule-editor-segment.is-tight .schedule-editor-segment-copy {
1273
+ padding: 7px 10px 12px;
1274
+ gap: 2px;
1275
+ }
1276
+
1277
+ .schedule-editor-segment.is-tight .schedule-editor-segment-copy strong {
1278
+ font-size: 0.8rem;
1279
+ }
1280
+
1281
+ .schedule-editor-segment.is-tight .schedule-editor-segment-copy span {
1282
+ font-size: 0.7rem;
1283
+ }
1284
+
1285
+ .schedule-editor-segment.is-tight .schedule-editor-segment-kind,
1286
+ .schedule-editor-segment.is-tight .schedule-editor-delete {
1287
+ display: none;
1288
+ }
1289
+
1290
+ .schedule-editor-segment.break.is-tight .schedule-editor-segment-copy span {
1291
+ display: none;
1292
+ }
1293
+
1294
+ .schedule-editor-segment.break.is-tight .schedule-editor-segment-copy strong {
1295
+ display: none;
1296
+ }
1297
+
1298
  .schedule-editor-delete {
1299
  position: absolute;
1300
  right: 14px;
 
1390
  flex-wrap: wrap;
1391
  }
1392
 
1393
+ .admin-layout-v2 .admin-hero {
1394
+ grid-template-columns: 1fr;
1395
+ }
1396
+
1397
+ .admin-layout-v2 .action-group,
1398
+ .admin-page-nav {
1399
+ justify-self: stretch;
1400
+ }
1401
+
1402
  .page-viewport,
1403
  .page-track,
1404
  .page-slide,