+
@@ -290,6 +370,7 @@ function handlePreviewDragEnd() {
'planning-board__cell--selectable': scheduleSelectionMode && resolveEvent(header.dayOfWeek, slot.order)?.type !== 'empty',
'planning-board__cell--selected': resolveEvent(header.dayOfWeek, slot.order) && isSelected(resolveEvent(header.dayOfWeek, slot.order)!.id),
'planning-board__cell--draggable': isWholeCellDraggable(resolveEvent(header.dayOfWeek, slot.order)),
+ 'planning-board__cell--suggested': isSuggestedPreviewEvent(resolveEvent(header.dayOfWeek, slot.order)),
'planning-board__cell--dragging': draggingCellKey === buildCellKey(header.dayOfWeek, slot.order),
'planning-board__cell--dragover': dragOverCellKey === buildCellKey(header.dayOfWeek, slot.order),
},
@@ -302,10 +383,13 @@ function handlePreviewDragEnd() {
@dragend="handlePreviewDragEnd"
>
@@ -333,6 +417,14 @@ function handlePreviewDragEnd() {
+
+ {{ resolveCellTitle(resolveEvent(header.dayOfWeek, slot.order)) }}
+ {{ resolveCellMeta(resolveEvent(header.dayOfWeek, slot.order)) }}
+
+
+
+
+
+
+
@@ -465,81 +576,89 @@ function handlePreviewDragEnd() {
}
.planning-board__cell--course {
- background: #e0f2fe;
+ background: #f0f7ff;
}
.planning-board__cell--course-embedded {
- background: #b9e6fe;
+ background: #f0f7ff;
align-items: stretch;
padding: 8px;
}
+.planning-board__cell--suggested {
+ outline: 2px dashed #3b82f6;
+ outline-offset: -2px;
+ background: #ffffff !important;
+ box-shadow: inset 0 0 0 100px #eff6ffaa;
+}
+
+.planning-board__cell--course-embedded.planning-board__cell--suggested {
+ outline-color: #0284c7;
+ background: #f0f9ff !important;
+}
+
.planning-board__cell--course .planning-board__cell-main strong,
.planning-board__cell--course .planning-board__cell-main span {
- color: #0284c7;
+ color: #0369a1;
}
.planning-board__embedded-shell {
- display: grid;
- grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
- gap: 8px;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
width: 100%;
height: 100%;
min-height: 0;
- text-align: center;
- overflow: hidden;
-}
-
-.planning-board__embedded-course,
-.planning-board__embedded-task {
- display: flex;
- align-items: center;
- justify-content: center;
- min-width: 0;
- min-height: 0;
- overflow: hidden;
}
.planning-board__embedded-course {
- padding: 6px 4px;
+ padding: 2px 4px;
+ font-size: 13px;
color: #0369a1;
-}
-
-.planning-board__embedded-course strong,
-.planning-board__embedded-task strong {
- min-width: 0;
+ font-weight: 800;
+ white-space: nowrap;
overflow: hidden;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- white-space: normal;
- overflow-wrap: anywhere;
+ text-overflow: ellipsis;
text-align: center;
}
-.planning-board__embedded-course strong {
- width: 100%;
- font-size: 13px;
- line-height: 1.28;
- font-weight: 800;
- -webkit-line-clamp: 2;
-}
-
.planning-board__embedded-task {
- padding: 6px 8px;
- border-radius: 10px;
+ flex: 1;
background: #ffffff;
+ border-radius: 12px;
+ box-shadow: 0 4px 12px rgba(15, 23, 42, 0.08);
+ border: 1px solid rgba(15, 23, 42, 0.04);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 6px;
+ min-height: 0;
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
-.planning-board__embedded-task strong {
- color: #0369a1;
- font-size: 11px;
- line-height: 1.24;
- font-weight: 800;
- -webkit-line-clamp: 2;
+.planning-board__embedded-task:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 6px 16px rgba(15, 23, 42, 0.12);
+ border-color: #3b82f6;
}
.planning-board__embedded-task-dragger {
+ font-size: 12px;
+ color: #334155;
+ font-weight: 700;
+ text-align: center;
+ padding: 2px 4px;
+ cursor: grab;
width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+}
+
+.planning-board__embedded-task-dragger--active {
+ color: #3b82f6;
}
.planning-board__embedded-task-dragger--active {
@@ -646,6 +765,60 @@ function handlePreviewDragEnd() {
box-shadow: inset 0 0 0 3px #ffffff;
}
+.planning-board__checkbox--hidden {
+ display: none !important;
+}
+
+/* 悬浮删除区样式 */
+.planning-board__delete-zone {
+ position: absolute;
+ left: 50%;
+ bottom: 80px;
+ transform: translateX(-50%);
+ z-index: 100;
+ width: 280px;
+ height: 64px;
+ border-radius: 32px;
+ background: rgba(239, 68, 68, 0.9);
+ backdrop-filter: blur(8px);
+ border: 2px dashed rgba(255, 255, 255, 0.4);
+ color: #ffffff;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 12px;
+ box-shadow: 0 12px 32px rgba(239, 68, 68, 0.3);
+ transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
+}
+
+.planning-board__delete-zone--active {
+ background: #ef4444;
+ transform: translateX(-50%) scale(1.1);
+ box-shadow: 0 16px 48px rgba(239, 68, 68, 0.45);
+ border-style: solid;
+}
+
+.delete-zone-icon {
+ animation: delete-icon-shake 1.5s infinite;
+}
+
+@keyframes delete-icon-shake {
+ 0%, 100% { transform: rotate(0deg); }
+ 25% { transform: rotate(-10deg); }
+ 75% { transform: rotate(10deg); }
+}
+
+.delete-zone-enter-active,
+.delete-zone-leave-active {
+ transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
+}
+
+.delete-zone-enter-from,
+.delete-zone-leave-to {
+ opacity: 0;
+ transform: translateX(-50%) translateY(40px) scale(0.8);
+}
+
@keyframes board-item-spring {
0% { opacity: 0; transform: scale(0.6) translateY(20px); }
60% { opacity: 1; transform: scale(1.05) translateY(-2px); }
diff --git a/frontend/src/views/DashboardView.vue b/frontend/src/views/DashboardView.vue
index 394c05d..f4ef3a4 100644
--- a/frontend/src/views/DashboardView.vue
+++ b/frontend/src/views/DashboardView.vue
@@ -218,6 +218,10 @@ async function handleLogout() {
finally { logoutLoading.value = false; await router.push('/auth') }
}
+function handleCourseImportEntry() {
+ void router.push('/schedule')
+}
+
function syncDashboardMainScale() {
const main = dashboardMainRef.value
const inner = dashboardMainInnerRef.value
diff --git a/frontend/src/views/ScheduleView.vue b/frontend/src/views/ScheduleView.vue
index 8f5008d..6ea76b5 100644
--- a/frontend/src/views/ScheduleView.vue
+++ b/frontend/src/views/ScheduleView.vue
@@ -1,6 +1,6 @@