Browse Source

feat: add project status badges with stalled and modification states

- Implemented visual status badges displaying stalled period and modification period information with icons, reasons, and metadata
- Added cancel action buttons with hover effects and animations for managing project states
- Included responsive design with mobile-specific layout adjustments for status badge display
徐福静0235668 14 hours ago
parent
commit
ffd8ed3103
1 changed files with 229 additions and 1 deletions
  1. 229 1
      src/modules/project/pages/project-detail/project-detail.component.scss

+ 229 - 1
src/modules/project/pages/project-detail/project-detail.component.scss

@@ -90,13 +90,18 @@
   background: var(--white);
   border-bottom: 1px solid var(--light-shade);
   padding: 12px 0;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 16px;
+  position: relative;
 
   .stage-navigation {
     display: flex;
     align-items: center;
     justify-content: space-between;
     padding: 0 16px;
-    max-width: 100%;
+    flex: 1;
     overflow-x: auto;
     -webkit-overflow-scrolling: touch;
 
@@ -1419,3 +1424,226 @@
     }
   }
 }
+
+// 🆕 停滞期和改图期状态标记(右上角显示)
+.project-status-badges {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+  padding-right: 16px;
+  flex-shrink: 0;
+  max-width: 300px;
+
+  .status-badge {
+    background: white;
+    border-radius: 10px;
+    padding: 8px 12px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1),
+                0 0 0 1px rgba(0, 0, 0, 0.05);
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    animation: slideInRight 0.3s ease-out;
+    transition: all 0.2s ease;
+
+    &:hover {
+      transform: scale(1.02);
+      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+    }
+
+    .badge-icon {
+      font-size: 20px;
+      flex-shrink: 0;
+      width: 32px;
+      height: 32px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      border-radius: 6px;
+    }
+
+    .badge-content {
+      flex: 1;
+      min-width: 0;
+
+      .badge-title {
+        font-size: 13px;
+        font-weight: 600;
+        margin-bottom: 2px;
+      }
+
+      .badge-reason {
+        font-size: 11px;
+        color: #64748b;
+        margin-bottom: 1px;
+      }
+
+      .badge-meta {
+        font-size: 10px;
+        color: #94a3b8;
+      }
+    }
+
+    .badge-action,
+    .badge-tip {
+      flex-shrink: 0;
+    }
+
+    .badge-action {
+      cursor: pointer;
+      padding: 6px 10px;
+      border-radius: 6px;
+      transition: all 0.2s;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      gap: 4px;
+      background: rgba(239, 68, 68, 0.08);
+      border: 1px solid rgba(239, 68, 68, 0.2);
+      
+      .icon {
+        width: 16px;
+        height: 16px;
+        color: #ef4444;
+        transition: all 0.2s;
+        pointer-events: none; // 让图标不拦截点击事件
+      }
+
+      // 添加"取消"文字
+      &::after {
+        content: '取消';
+        font-size: 11px;
+        font-weight: 600;
+        color: #ef4444;
+        transition: color 0.2s;
+      }
+
+      &:hover {
+        background: rgba(239, 68, 68, 0.15);
+        border-color: rgba(239, 68, 68, 0.4);
+        transform: translateY(-1px);
+        box-shadow: 0 2px 4px rgba(239, 68, 68, 0.2);
+        
+        .icon {
+          color: #dc2626;
+        }
+        
+        &::after {
+          color: #dc2626;
+        }
+      }
+      
+      &:active {
+        transform: translateY(0) scale(0.98);
+        box-shadow: 0 1px 2px rgba(239, 68, 68, 0.15);
+      }
+    }
+
+    .badge-tip {
+      font-size: 10px;
+      color: #94a3b8;
+      font-style: italic;
+    }
+
+    // 停滞期样式
+    &.stalled {
+      border-left: 4px solid #8b5cf6;
+
+      .badge-icon {
+        background: linear-gradient(135deg, #ede9fe 0%, #ddd6fe 100%);
+      }
+
+      .badge-title {
+        color: #7c3aed;
+      }
+    }
+
+    // 改图期样式
+    &.modification {
+      border-left: 4px solid #f59e0b;
+
+      .badge-icon {
+        background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
+      }
+
+      .badge-title {
+        color: #d97706;
+      }
+    }
+  }
+
+  @keyframes slideInRight {
+    from {
+      opacity: 0;
+      transform: translateX(100px);
+    }
+    to {
+      opacity: 1;
+      transform: translateX(0);
+    }
+  }
+}
+
+// 小屏幕适配
+@media (max-width: 768px) {
+  .stage-toolbar {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 8px;
+  }
+  
+  // 🔥 小屏幕下:先隐藏所有状态标记
+  .project-status-badges {
+    display: none !important;
+  }
+  
+  // 🔥 然后只显示顶部的(在 .stage-toolbar 内的)
+  .stage-toolbar .project-status-badges {
+    display: flex !important;
+    padding-right: 8px;
+    max-width: 100%;
+    width: 100%;
+
+    .status-badge {
+      padding: 10px 12px;
+      gap: 10px;
+
+      .badge-icon {
+        font-size: 24px;
+        width: 36px;
+        height: 36px;
+      }
+
+      .badge-content {
+        .badge-title {
+          font-size: 14px;
+        }
+
+        .badge-reason {
+          font-size: 12px;
+        }
+
+        .badge-meta {
+          font-size: 10px;
+        }
+      }
+
+      .badge-action {
+        padding: 8px 12px;
+        
+        .icon {
+          width: 18px;
+          height: 18px;
+        }
+        
+        &::after {
+          font-size: 12px;
+        }
+      }
+
+      .badge-tip {
+        font-size: 10px;
+      }
+    }
+  }
+}