0235711 пре 1 дан
родитељ
комит
5de90f7cf2

+ 3 - 3
src/app/app.config.ts

@@ -1,12 +1,12 @@
-import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';
-
+import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
 import { provideRouter } from '@angular/router';
+import { provideHttpClient } from '@angular/common/http';
 
 import { routes } from './app.routes';
 
 export const appConfig: ApplicationConfig = {
   providers: [
-    provideBrowserGlobalErrorListeners(),
+    provideHttpClient(),
     provideZoneChangeDetection({ eventCoalescing: true }),
     provideRouter(routes)
   ]

+ 23 - 15
src/app/app.html

@@ -1,4 +1,12 @@
 <div class="app-container">
+  <!-- 根据当前路由显示不同的导航 -->
+@if (isDesignerRoute) {
+  <!-- 设计师导航 -->
+  <app-designer-nav userName="设计师用户" [onlineHours]="4.8">
+    <router-outlet></router-outlet>
+  </app-designer-nav>
+} @else {
+  <!-- 客服导航 -->
   <!-- 顶部导航栏 -->
   <header class="top-navbar">
     <div class="navbar-left">
@@ -17,7 +25,7 @@
         <input 
           type="text" 
           [(ngModel)]="searchTerm"
-          placeholder="搜索项目、客户或动态..." 
+          placeholder="搜索客户、订单或项目..." 
           class="search-input"
         />
         <button class="search-button">
@@ -37,8 +45,8 @@
         <span class="notification-badge">3</span>
       </button>
       <div class="user-profile">
-        <img src="https://picsum.photos/id/64/40/40" alt="用户头像" class="user-avatar">
-        <span class="user-name">客服小</span>
+        <img src="https://picsum.photos/id/823/40/40" alt="用户头像" class="user-avatar">
+        <span class="user-name">客服小</span>
       </div>
     </div>
   </header>
@@ -48,30 +56,29 @@
     <!-- 左侧侧边栏 -->
     <aside class="sidebar" [class.collapsed]="!sidebarOpen">
       <nav class="sidebar-nav">
-        <a href="/customer-service/dashboard" class="nav-item" routerLinkActive="active">
+        <a href="/dashboard" class="nav-item" routerLinkActive="active">
           <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
             <path d="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z"></path>
           </svg>
           <span>工作台</span>
         </a>
-        <a href="/customer-service/consultation-order" class="nav-item" routerLinkActive="active">
+        <a href="/customer-consultation" class="nav-item" routerLinkActive="active">
           <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
             <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
           </svg>
           <span>客户咨询</span>
         </a>
-        <a href="/customer-service/project-list" class="nav-item" routerLinkActive="active">
+        <a href="/project-list" class="nav-item" routerLinkActive="active">
           <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
-            <line x1="8" y1="6" x2="21" y2="6"></line>
-            <line x1="8" y1="12" x2="21" y2="12"></line>
-            <line x1="8" y1="18" x2="21" y2="18"></line>
-            <line x1="3" y1="6" x2="3.01" y2="6"></line>
-            <line x1="3" y1="12" x2="3.01" y2="12"></line>
-            <line x1="3" y1="18" x2="3.01" y2="18"></line>
+            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
+            <polyline points="14 2 14 8 20 8"></polyline>
+            <line x1="16" y1="13" x2="8" y2="13"></line>
+            <line x1="16" y1="17" x2="8" y2="17"></line>
+            <polyline points="10 9 9 9 8 9"></polyline>
           </svg>
           <span>项目列表</span>
         </a>
-        <a href="/customer-service/case-library" class="nav-item" routerLinkActive="active">
+        <a href="/case-library" class="nav-item" routerLinkActive="active">
           <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
             <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path>
             <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path>
@@ -82,7 +89,7 @@
       
       <div class="sidebar-footer">
         <div class="storage-info">
-          <span>在线时长: 4.5h</span>
+          <span>存储空间: 2.5GB / 10GB</span>
         </div>
         <button class="logout-btn">
           <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
@@ -97,7 +104,8 @@
 
     <!-- 中间内容区 -->
     <div class="content-wrapper" [class.expanded]="!sidebarOpen">
-      <router-outlet />
+      <router-outlet></router-outlet>
     </div>
   </main>
+}
 </div>

+ 1 - 1
src/app/app.scss

@@ -36,7 +36,7 @@ body {
   display: flex;
   flex-direction: column;
   height: 100vh;
-  overflow: hidden;
+  overflow-y: auto;
 }
 
 // 顶部导航栏

+ 23 - 3
src/app/app.ts

@@ -1,19 +1,39 @@
 import { Component, signal } from '@angular/core';
-import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
+import { OnInit } from '@angular/core';
+import { Router, RouterOutlet, RouterLinkActive } from '@angular/router';
 import { FormsModule } from '@angular/forms';
+import { DesignerNavComponent } from './shared/components/designer-nav/designer-nav';
 
 @Component({
   selector: 'app-root',
   standalone: true,
-  imports: [RouterOutlet, RouterLink, RouterLinkActive, FormsModule],
+  imports: [RouterOutlet, RouterLinkActive, FormsModule, DesignerNavComponent],
   templateUrl: './app.html',
   styleUrl: './app.scss'
 })
-export class App {
+export class App implements OnInit {
   protected readonly title = signal('yss-project');
   sidebarOpen = true;
   searchTerm = '';
   currentDate = new Date();
+  isDesignerRoute = false;
+
+  constructor(private router: Router) {}
+
+  ngOnInit() {
+    // 初始化时检查当前路由
+    this.checkIfDesignerRoute();
+    
+    // 监听路由变化
+    this.router.events.subscribe(() => {
+      this.checkIfDesignerRoute();
+    });
+  }
+
+  checkIfDesignerRoute() {
+    // 检查当前路径是否包含'designer'
+    this.isDesignerRoute = this.router.url.includes('designer');
+  }
 
   toggleSidebar() {
     this.sidebarOpen = !this.sidebarOpen;

+ 101 - 0
src/app/shared/components/designer-nav/designer-nav.html

@@ -0,0 +1,101 @@
+<!-- 设计师顶部导航栏 -->
+<header class="top-navbar">
+  <div class="navbar-left">
+    <button class="menu-toggle" (click)="toggleSidebar()">
+      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor">
+        <line x1="3" y1="12" x2="21" y2="12"></line>
+        <line x1="3" y1="6" x2="21" y2="6"></line>
+        <line x1="3" y1="18" x2="21" y2="18"></line>
+      </svg>
+    </button>
+    <h1 class="app-title">设计师工作台</h1>
+  </div>
+  
+  <div class="navbar-center">
+    <div class="search-container">
+      <input 
+        type="text" 
+        [(ngModel)]="searchTerm"
+        placeholder="搜索项目、客户或案例..." 
+        class="search-input"
+      />
+      <button class="search-button">
+        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
+          <circle cx="11" cy="11" r="8"></circle>
+          <path d="m21 21-4.35-4.35"></path>
+        </svg>
+      </button>
+    </div>
+  </div>
+  
+  <div class="navbar-right">
+    <button class="notification-btn">
+      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor">
+        <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
+      </svg>
+      <span class="notification-badge">3</span>
+    </button>
+    <div class="user-profile">
+      <img src="https://picsum.photos/id/65/40/40" alt="用户头像" class="user-avatar">
+      <span class="user-name">{{userName}}</span>
+    </div>
+  </div>
+</header>
+
+<!-- 主要内容区 -->
+<main class="main-content">
+  <!-- 左侧侧边栏 -->
+  <aside class="sidebar" [class.collapsed]="!sidebarOpen">
+    <nav class="sidebar-nav">
+      <a routerLink="/designer/dashboard" class="nav-item" routerLinkActive="active">
+        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
+          <path d="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z"></path>
+        </svg>
+        <span>工作台</span>
+      </a>
+      <a routerLink="/designer/personal-board" class="nav-item" routerLinkActive="active">
+        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
+          <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
+          <circle cx="12" cy="7" r="4"></circle>
+        </svg>
+        <span>个人看板</span>
+      </a>
+      <a routerLink="/designer/project-detail/1" class="nav-item" routerLinkActive="active">
+        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
+          <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
+          <polyline points="14 2 14 8 20 8"></polyline>
+          <line x1="16" y1="13" x2="8" y2="13"></line>
+          <line x1="16" y1="17" x2="8" y2="17"></line>
+          <polyline points="10 9 9 9 8 9"></polyline>
+        </svg>
+        <span>项目详情</span>
+      </a>
+      <a routerLink="/designer/case-library" class="nav-item" routerLinkActive="active">
+        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
+          <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path>
+          <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path>
+        </svg>
+        <span>案例库</span>
+      </a>
+    </nav>
+    
+    <div class="sidebar-footer">
+      <div class="storage-info">
+        <span>在线时长: {{onlineHours}}h</span>
+      </div>
+      <button class="logout-btn">
+        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
+          <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
+          <polyline points="16 17 21 12 16 7"></polyline>
+          <line x1="21" y1="12" x2="9" y2="12"></line>
+        </svg>
+        <span>退出登录</span>
+      </button>
+    </div>
+  </aside>
+
+  <!-- 中间内容区 -->
+  <div class="content-wrapper" [class.expanded]="!sidebarOpen">
+    <ng-content></ng-content>
+  </div>
+</main>

+ 311 - 0
src/app/shared/components/designer-nav/designer-nav.scss

@@ -0,0 +1,311 @@
+// 设计师导航组件样式
+
+$primary-color: #165DFF;
+$primary-dark: #0E42CB;
+$secondary-color: #4E5BA6;
+$success-color: #00B42A;
+$warning-color: #FF7D00;
+$danger-color: #F53F3F;
+$text-primary: #1D2129;
+$text-secondary: #4E5969;
+$text-tertiary: #86909C;
+$border-color: #E5E6EB;
+$background-primary: #FFFFFF;
+$background-secondary: #F2F3F5;
+$background-tertiary: #F7F8FA;
+$shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
+$shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
+$shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.1);
+$border-radius: 8px;
+$transition: all 0.3s ease;
+
+// 顶部导航栏
+.top-navbar {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 24px;
+  height: 64px;
+  background-color: $background-primary;
+  border-bottom: 1px solid $border-color;
+  box-shadow: $shadow-sm;
+  position: sticky;
+  top: 0;
+  z-index: 1000;
+
+  .navbar-left {
+    display: flex;
+    align-items: center;
+    gap: 16px;
+  }
+
+  .menu-toggle {
+    display: none;
+    background: none;
+    border: none;
+    cursor: pointer;
+    color: $text-primary;
+    padding: 8px;
+    transition: $transition;
+
+    &:hover {
+      color: $primary-color;
+    }
+  }
+
+  .app-title {
+    font-size: 20px;
+    font-weight: 600;
+    color: $text-primary;
+  }
+
+  .navbar-center {
+    flex: 1;
+    max-width: 500px;
+    margin: 0 20px;
+  }
+
+  .search-container {
+    display: flex;
+    align-items: center;
+    background-color: $background-tertiary;
+    border-radius: $border-radius;
+    padding: 6px 12px;
+    border: 1px solid $border-color;
+
+    .search-input {
+      flex: 1;
+      background: none;
+      border: none;
+      outline: none;
+      padding: 6px 8px;
+      font-size: 14px;
+      color: $text-primary;
+
+      &::placeholder {
+        color: $text-tertiary;
+      }
+    }
+
+    .search-button {
+      background: none;
+      border: none;
+      cursor: pointer;
+      color: $text-secondary;
+      padding: 4px;
+      transition: $transition;
+
+      &:hover {
+        color: $primary-color;
+      }
+    }
+  }
+
+  .navbar-right {
+    display: flex;
+    align-items: center;
+    gap: 16px;
+  }
+
+  .notification-btn {
+    position: relative;
+    background: none;
+    border: none;
+    cursor: pointer;
+    color: $text-secondary;
+    padding: 8px;
+    transition: $transition;
+
+    &:hover {
+      color: $primary-color;
+    }
+
+    .notification-badge {
+      position: absolute;
+      top: 2px;
+      right: 2px;
+      background-color: $danger-color;
+      color: white;
+      font-size: 10px;
+      font-weight: 500;
+      padding: 2px 6px;
+      border-radius: 10px;
+      min-width: 18px;
+      text-align: center;
+    }
+  }
+
+  .user-profile {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+
+    .user-avatar {
+      width: 36px;
+      height: 36px;
+      border-radius: 50%;
+      object-fit: cover;
+    }
+
+    .user-name {
+      font-size: 14px;
+      font-weight: 500;
+      color: $text-primary;
+    }
+  }
+}
+
+// 主要内容区
+.main-content {
+  display: flex;
+  flex: 1;
+  min-height: 0; // 确保flex子元素能够正确计算高度
+}
+
+// 左侧侧边栏
+.sidebar {
+  width: 220px;
+  background-color: $background-primary;
+  border-right: 1px solid $border-color;
+  display: flex;
+  flex-direction: column;
+  transition: $transition;
+
+  .sidebar-nav {
+    flex: 1;
+    padding: 16px 0;
+
+    .nav-item {
+      display: flex;
+      align-items: center;
+      gap: 12px;
+      padding: 12px 24px;
+      color: $text-secondary;
+      text-decoration: none;
+      border-left: 3px solid transparent;
+      transition: $transition;
+
+      &:hover {
+        background-color: $background-tertiary;
+        color: $primary-color;
+      }
+
+      &.active {
+        color: $primary-color;
+        background-color: color-mix(in srgb, $primary-color 5%, transparent);
+        border-left-color: $primary-color;
+        font-weight: 500;
+      }
+    }
+  }
+
+  .sidebar-footer {
+    padding: 16px 24px;
+    border-top: 1px solid $border-color;
+
+    .storage-info {
+      margin-bottom: 16px;
+      font-size: 12px;
+      color: $text-tertiary;
+    }
+
+    .logout-btn {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+      padding: 8px 12px;
+      background: none;
+      border: 1px solid $border-color;
+      border-radius: $border-radius;
+      color: $text-secondary;
+      cursor: pointer;
+      font-size: 14px;
+      transition: $transition;
+
+      &:hover {
+        background-color: $background-tertiary;
+        border-color: $danger-color;
+        color: $danger-color;
+      }
+    }
+  }
+
+  &.collapsed {
+    width: 0;
+    overflow: hidden;
+  }
+}
+
+// 中间内容区
+.content-wrapper {
+  flex: 1;
+  overflow-y: auto;
+  padding: 24px;
+  transition: $transition;
+
+  &.expanded {
+    width: 100%;
+  }
+}
+
+// 响应式设计
+@media (max-width: 1024px) {
+  .sidebar {
+    width: 200px;
+  }
+}
+
+@media (max-width: 768px) {
+  .top-navbar {
+    padding: 0 16px;
+
+    .menu-toggle {
+      display: block;
+    }
+
+    .app-title {
+      font-size: 18px;
+    }
+
+    .navbar-center {
+      display: none;
+    }
+  }
+
+  .sidebar {
+    position: fixed;
+    top: 64px;
+    left: 0;
+    height: calc(100vh - 64px);
+    z-index: 900;
+    transform: translateX(0);
+
+    &.collapsed {
+      transform: translateX(-100%);
+    }
+  }
+
+  .content-wrapper {
+    padding: 16px;
+    margin-left: 0;
+  }
+}
+
+@media (max-width: 480px) {
+  .top-navbar {
+    height: 56px;
+
+    .navbar-right {
+      gap: 12px;
+    }
+  }
+
+  .sidebar {
+    top: 56px;
+    height: calc(100vh - 56px);
+  }
+
+  .content-wrapper {
+    padding: 12px;
+  }
+}

+ 24 - 0
src/app/shared/components/designer-nav/designer-nav.ts

@@ -0,0 +1,24 @@
+import { Component, Input } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { RouterLink, RouterLinkActive } from '@angular/router';
+
+@Component({
+  selector: 'app-designer-nav',
+  standalone: true,
+  imports: [CommonModule, FormsModule, RouterLink, RouterLinkActive],
+  templateUrl: './designer-nav.html',
+  styleUrl: './designer-nav.scss'
+})
+export class DesignerNavComponent {
+  @Input() userName: string = '设计师用户';
+  @Input() onlineHours: number = 4.8;
+  
+  sidebarOpen = true;
+  searchTerm = '';
+  currentDate = new Date();
+
+  toggleSidebar() {
+    this.sidebarOpen = !this.sidebarOpen;
+  }
+}