xukang 4 months ago
parent
commit
084a8bcbda

+ 4 - 1
newwisefitnessapp/angular.json

@@ -126,7 +126,10 @@
     }
   },
   "cli": {
-    "schematicCollections": ["@ionic/angular-toolkit"]
+    "schematicCollections": [
+      "@ionic/angular-toolkit"
+    ],
+    "analytics": false
   },
   "schematics": {
     "@ionic/angular-toolkit:component": {

+ 0 - 0
newwisefitnessapp/src/app/discount-banner/README.md


+ 8 - 0
newwisefitnessapp/src/app/discount-banner/discount-banner.component.html

@@ -0,0 +1,8 @@
+<ion-card>
+  <ion-card-header>
+    <ion-card-title>限时优惠活动</ion-card-title>
+  </ion-card-header>
+  <ion-card-content>
+    距离优惠结束还有 <span>{{ countdown }}</span>
+  </ion-card-content>
+</ion-card>

+ 49 - 0
newwisefitnessapp/src/app/discount-banner/discount-banner.component.scss

@@ -0,0 +1,49 @@
+ion-card {
+  background-color: #d8d7cc;
+  border-radius: 6px;
+  padding: 2px;
+  text-align: center;
+}
+
+ion-card-title {
+  color: #d32f2f;
+  font-size: 1.2em;
+  font-weight: bold;
+}
+ion-card-content
+{
+margin-top: 2px;
+}
+span {
+  color: #d32f2f;
+  font-size: 1em;
+  margin-top: 2px;
+}
+ion-card {
+  height: 40px; 
+  padding: 0; 
+  margin: 5px 0; 
+  display: flex;
+  flex-direction: column; 
+  justify-content: center; 
+}
+
+ion-card-header,
+ion-card-content {
+  padding: 0; 
+  margin: 0; 
+}
+
+ion-card-title {
+  font-size: 1.2em; 
+  line-height: 1.2; 
+  margin: 0; 
+}
+
+ion-card-content {
+  font-size: 10px; /* 减小内容的字体大小 */
+  line-height: 1.2; /* 调整内容行高 */
+}
+
+
+

+ 24 - 0
newwisefitnessapp/src/app/discount-banner/discount-banner.component.spec.ts

@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { DiscountBannerComponent } from './discount-banner.component';
+
+describe('DiscountBannerComponent', () => {
+  let component: DiscountBannerComponent;
+  let fixture: ComponentFixture<DiscountBannerComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      declarations: [ DiscountBannerComponent ],
+      imports: [IonicModule.forRoot()]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(DiscountBannerComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 36 - 0
newwisefitnessapp/src/app/discount-banner/discount-banner.component.ts

@@ -0,0 +1,36 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { IonicModule } from '@ionic/angular'; // 导入 IonicModule
+
+@Component({
+  selector: 'app-discount-banner',
+  templateUrl: './discount-banner.component.html',
+  styleUrls: ['./discount-banner.component.scss'],
+  standalone: true,  // 确保组件是独立组件
+  imports: [IonicModule],  // 引入 Ionic 模块
+})
+export class DiscountBannerComponent implements OnInit, OnDestroy {
+  countdown: string = '';  // 倒计时字符串
+  private countdownInterval: any;  // 保存计时器引用
+
+  ngOnInit() {
+    const endTime = new Date('2024-12-01T00:00:00');  // 活动结束时间
+    this.countdownInterval = setInterval(() => {
+      const now = new Date();
+      const diff = endTime.getTime() - now.getTime();
+      const days = Math.floor(diff / (1000 * 60 * 60 * 24));
+      const hours = Math.floor((diff / (1000 * 60 * 60)) % 24);
+      const minutes = Math.floor((diff / (1000 * 60)) % 60);
+      const seconds = Math.floor((diff / 1000) % 60);
+
+      // 更新倒计时字符串
+      this.countdown = `${days}天 ${hours}小时 ${minutes}分 ${seconds}秒`;
+    }, 1000);
+  }
+
+  ngOnDestroy() {
+    // 清除计时器
+    if (this.countdownInterval) {
+      clearInterval(this.countdownInterval);
+    }
+  }
+}

+ 4 - 6
newwisefitnessapp/src/app/tab1/tab1.page.html

@@ -96,10 +96,6 @@
     </ion-item>
     <ion-button fill="outline" slot="end" (click)="goToReviews()">查看更多推荐</ion-button>
   </ion-list>
-
-  <ion-button expand="block" color="success" (click)="goToPlanCreation()">立即定制我的健身计划</ion-button>
-  <ion-button expand="block" fill="outline" (click)="goToLogin()">登录/注册</ion-button>
-
   <ion-grid>
     <ion-row>
       <ion-col size="4">
@@ -115,7 +111,7 @@
         <ion-card>
           <ion-icon name="person-circle-outline" slot="icon-only"></ion-icon>
           <ion-card-header>
-            <ion-card-title>专业教练在线指导,随时为您答疑解惑</ion-card-title>
+            <ion-card-title>专业教练在线为您答疑解惑</ion-card-title>
           </ion-card-header>
         </ion-card>
       </ion-col>
@@ -130,7 +126,9 @@
       </ion-col>
     </ion-row>
   </ion-grid>
-
+  <app-discount-banner></app-discount-banner>
+  <ion-button expand="block" color="success" (click)="goToTestPage()">立即定制我的健身计划</ion-button>
+  <ion-button expand="block" fill="outline" (click)="goToLogin()">登录/注册</ion-button>
   <ion-footer>
     <ion-toolbar>
       <ion-label>© 20XX WisefitnessApp. All rights reserved.</ion-label>

+ 12 - 3
newwisefitnessapp/src/app/tab1/tab1.page.scss

@@ -41,8 +41,6 @@ ion-card {
   background: linear-gradient(#135, #5cb85c, #20c997) !important; /* 绿色到蓝色的渐变背景 */
   
 }
-
-
 .card-style {
   border-radius: 10px;
   box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2);
@@ -55,7 +53,19 @@ ion-card {
   height: auto;
   border-bottom: 2px solid #ddd;
 }
+.card-style:hover {
+  transform: scale(1.05);
+  box-shadow: 0px 6px 8px rgba(0, 0, 0, 0.3);
+  transition: all 0.3s ease-in-out;
+}
 
+ion-button {
+  transition: transform 0.2s ease, background-color 0.3s ease;
+}
+ion-button:active {
+  transform: scale(0.95);
+  background-color: #218838;
+}
 ion-card-header {
   background-color: rgba(255, 255, 255, 0.1);
   padding: 10px;
@@ -93,7 +103,6 @@ ion-button.outline {
 }
 
 ion-footer {
-  
   color: white;
   font-size: 10px;
 }

+ 39 - 20
newwisefitnessapp/src/app/tab1/tab1.page.ts

@@ -1,11 +1,15 @@
-import { Component, OnInit } from '@angular/core';
-import { IonList, IonImg, IonContent, IonHeader, IonToolbar, IonTitle, IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonAvatar, IonLabel, IonItem, IonButton, IonGrid, IonRow, IonCol, IonIcon, IonFooter, IonButtons } from '@ionic/angular/standalone';
+import { Component, OnInit, AfterViewInit, OnDestroy } from '@angular/core';
+import {
+  IonList, IonImg, IonContent, IonHeader, IonToolbar, IonTitle, IonCard, IonCardHeader, IonCardTitle,
+  IonCardContent, IonAvatar, IonLabel, IonItem, IonButton, IonGrid, IonRow, IonCol, IonIcon, IonFooter, IonButtons
+} from '@ionic/angular/standalone';
 import { addIcons } from 'ionicons';
 import { analyticsOutline, personCircleOutline, chatbubblesOutline, barbellOutline, ellipse, square } from 'ionicons/icons';
 import Swiper from 'swiper';
 import { Router } from '@angular/router';
 import { CommonModule } from '@angular/common';
-
+import { DiscountBannerComponent } from '../discount-banner/discount-banner.component';
+import { TagInputComponent } from '../tag-input/tag-input.component';
 @Component({
   selector: 'app-tab1',
   templateUrl: 'tab1.page.html',
@@ -32,10 +36,11 @@ import { CommonModule } from '@angular/common';
     IonIcon,
     IonFooter,
     IonButtons,
-    IonList
+    IonList,
+    DiscountBannerComponent,
   ],
 })
-export class Tab1Page implements OnInit {
+export class Tab1Page implements OnInit, AfterViewInit, OnDestroy {
   users = [
     {
       avatarUrl: '../assets/beautiful.jpg',
@@ -45,22 +50,12 @@ export class Tab1Page implements OnInit {
     // 可以添加更多用户数据
   ];
 
+  countdown: string = ''; // 倒计时字符串
+  private countdownInterval: any; // 保存计时器引用
+
   constructor(private router: Router) { }
 
   ngOnInit() {
-    // 初始化 Swiper
-    new Swiper('.swiper-container', {
-      loop: true,  // 开启循环
-      pagination: {
-        el: '.swiper-pagination',  // 分页器
-        clickable: true
-      },
-      autoplay: {
-        delay: 5000  // 自动切换时间间隔
-      }
-    });
-
-
     // 添加图标
     addIcons({
       analyticsOutline,
@@ -70,10 +65,34 @@ export class Tab1Page implements OnInit {
       ellipse,
       square
     });
+
+
+  }
+
+  ngAfterViewInit() {
+    // 初始化 Swiper
+    new Swiper('.swiper-container', {
+      loop: true, // 开启循环
+      pagination: {
+        el: '.swiper-pagination', // 分页器
+        clickable: true
+      },
+      autoplay: {
+        delay: 5000 // 自动切换时间间隔
+      }
+    });
+  }
+
+  ngOnDestroy() {
+    // 清除计时器
+    if (this.countdownInterval) {
+      clearInterval(this.countdownInterval);
+    }
   }
 
-  goToPlanCreation() {
-    this.router.navigate(['/body-data-input']);
+  // 页面导航功能
+  goToTestPage() {
+    this.router.navigate(['tabs/test-page']);  // 跳转到 Test 页面
   }
 
   goToLogin() {

+ 1 - 1
newwisefitnessapp/src/app/tab2/tab2.page.ts

@@ -11,6 +11,6 @@ import { ExploreContainerComponent } from '../explore-container/explore-containe
 })
 export class Tab2Page {
 
-  constructor() {}
+  constructor() { }
 
 }

+ 5 - 0
newwisefitnessapp/src/app/tabs/tabs.routes.ts

@@ -21,6 +21,11 @@ export const routes: Routes = [
         loadComponent: () =>
           import('../tab3/tab3.page').then((m) => m.Tab3Page),
       },
+      {
+        path: 'test-page',
+        loadComponent: () =>
+          import('../test-page/test-page.component').then((m) => m.TestPageComponent),
+      },
       {
         path: '',
         redirectTo: '/tabs/tab1',

+ 23 - 0
newwisefitnessapp/src/app/tag-input/tag-input.component.html

@@ -0,0 +1,23 @@
+<ion-card>
+  <ion-card-header>
+    <ion-card-title>添加标签</ion-card-title>
+  </ion-card-header>
+
+  <ion-card-content>
+    <div class="input-container">
+      <ion-input [(ngModel)]="tagInput" placeholder="输入标签" (keydown.enter)="addTag()"></ion-input>
+      <ion-button expand="full" (click)="addTag()">添加标签</ion-button>
+    </div>
+
+    <!-- 标签显示区域 -->
+    <div class="tag-container">
+      <ion-chip *ngFor="let tag of tags" class="tag-chip">
+        <ion-label>{{ tag }}</ion-label>
+        <!-- 删除按钮 -->
+        <ion-icon name="close" (click)="removeTag(tag)" class="close-icon"></ion-icon>
+      </ion-chip>
+    </div>
+
+    <p>{{tagInput}}</p>
+  </ion-card-content>
+</ion-card>

+ 36 - 0
newwisefitnessapp/src/app/tag-input/tag-input.component.scss

@@ -0,0 +1,36 @@
+.input-container {
+  display: flex;
+  align-items: center;
+  gap: 10px; 
+  margin-bottom: 10px; 
+}
+
+.tag-container {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+  margin-top: 10px;
+}
+
+.tag-chip {
+  display: flex;
+  align-items: center;
+  position: relative; 
+  background-color: var(--ion-color-light);
+}
+
+.close-icon {
+  position: absolute;
+  right: 5px; 
+  top: 50%; 
+  transform: translateY(-50%); 
+  cursor: pointer;
+  font-size: 12px; 
+  color: var(--ion-color-danger); 
+}
+
+ion-chip {
+  --padding-start: 10px;
+  --padding-end: 10px;
+  --border-radius: 20px;
+}

+ 24 - 0
newwisefitnessapp/src/app/tag-input/tag-input.component.spec.ts

@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { TagInputComponent } from './tag-input.component';
+
+describe('TagInputComponent', () => {
+  let component: TagInputComponent;
+  let fixture: ComponentFixture<TagInputComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      declarations: [ TagInputComponent ],
+      imports: [IonicModule.forRoot()]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(TagInputComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 32 - 0
newwisefitnessapp/src/app/tag-input/tag-input.component.ts

@@ -0,0 +1,32 @@
+import { Component } from '@angular/core';
+import { IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonInput, IonButton, IonChip, IonLabel, IonIcon } from '@ionic/angular/standalone';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { addIcons } from 'ionicons';
+import { close, barbellOutline, personOutline, square, alarmOutline } from 'ionicons/icons';
+@Component({
+  selector: 'app-tag-input',
+  templateUrl: './tag-input.component.html',
+  styleUrls: ['./tag-input.component.scss'],
+  standalone: true,
+  imports: [IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonInput, IonButton, IonChip, IonLabel, IonIcon, CommonModule, FormsModule]
+})
+
+export class TagInputComponent {
+  tagInput: string = '';
+  tags: string[] = [];
+
+  addTag() {
+    if (this.tagInput.trim()) {
+      this.tags.push(this.tagInput.trim());
+      this.tagInput = '';  // 清空输入框
+    }
+  }
+
+  removeTag(tag: string) {
+    this.tags = this.tags.filter(t => t !== tag);  // 删除指定标签
+  }
+  constructor() {
+    addIcons({ close, personOutline, barbellOutline, alarmOutline, square });
+  }
+}

+ 1 - 0
newwisefitnessapp/src/app/test-page/test-page.component.html

@@ -0,0 +1 @@
+<app-tag-input></app-tag-input>

+ 0 - 0
newwisefitnessapp/src/app/test-page/test-page.component.scss


+ 22 - 0
newwisefitnessapp/src/app/test-page/test-page.component.spec.ts

@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+
+import { TestPageComponent } from './test-page.component';
+
+describe('TestPageComponent', () => {
+  let component: TestPageComponent;
+  let fixture: ComponentFixture<TestPageComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      imports: [TestPageComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(TestPageComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 17 - 0
newwisefitnessapp/src/app/test-page/test-page.component.ts

@@ -0,0 +1,17 @@
+import { Component, OnInit } from '@angular/core';
+import { TagInputComponent } from '../tag-input/tag-input.component';
+
+@Component({
+  selector: 'app-test-page',
+  templateUrl: './test-page.component.html',
+  styleUrls: ['./test-page.component.scss'],
+  imports: [TagInputComponent],
+  standalone: true,
+})
+export class TestPageComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() { }
+
+}

+ 1 - 1
wisefitness-app/src/app/tab1/tab1.page.html

@@ -13,7 +13,7 @@
     <!-- 这里是swiper-slide元素,每个代表轮播图中的一屏 -->
     <div class="swiper-slide">
       <ion-card>
-        <img src="path-to-fitnes-result-image" alt="Fitness Result">
+        <img src="./" alt="Fitness Result">
         <ion-card-header>
           <ion-card-title>真实用户健身成果</ion-card-title>
         </ion-card-header>