SyuanYu 1 år sedan
förälder
incheckning
9ff7ff740c

+ 52 - 3
src/assets/css/style.css

@@ -150,18 +150,18 @@ input:focus-visible {
   }
 }
 .college-content .main-block {
-  padding: 80px 80px 150px;
+  padding: 150px 80px;
   margin-top: -30%;
   background-color: #fff;
 }
 @media (max-width: 960px) {
   .college-content .main-block {
-    padding: 50px 50px 100px;
+    padding: 100px 50px;
   }
 }
 @media (max-width: 600px) {
   .college-content .main-block {
-    padding: 20px 20px 50px;
+    padding: 50px 20px;
   }
 }
 .college-content .main-block h2 {
@@ -198,4 +198,53 @@ input:focus-visible {
   .college-content .main-block .v-breadcrumbs {
     justify-content: center;
   }
+}
+
+.main-card {
+  letter-spacing: 1px;
+  border-radius: 10px;
+  box-shadow: 2px 2px 10px #aaaaaa;
+  background-color: var(--sub-color);
+}
+.main-card .card-title {
+  height: 80px;
+  padding: 15px;
+  margin-bottom: 15px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-bottom: 2px solid #fff;
+}
+.main-card .card-title h3 {
+  font-size: 20px;
+  font-weight: 400;
+  text-align: center;
+  line-height: 24px;
+}
+.main-card ul {
+  padding: 20px;
+}
+.main-card .card-title h3,
+.main-card .card-info p {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+  line-break: after-white-space;
+}
+.main-card .card-info {
+  padding: 0 15px;
+}
+.main-card .card-info .cover-img {
+  height: 220px;
+  width: 100%;
+  -o-object-fit: cover;
+     object-fit: cover;
+}
+.main-card .card-info span {
+  height: 60px;
+}
+.main-card .card-info span p {
+  line-height: 20px;
 }/*# sourceMappingURL=style.css.map */

+ 1 - 1
src/assets/css/style.css.map

@@ -1 +1 @@
-{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAA,cAAA;AAEA;;;;;;;;;;;;;;;;;;;;EAoBE,SAAA;EACA,UAAA;EACA,SAAA;EACA,eAAA;EACA,wBAAA;EACA,sBAAA;ACAF;;ADGA,sBAAA;AAEA;EACE,cAAA;ACDF;;ADIA;;EAEE,gBAAA;ACDF;;ADIA;EACE,eAAA;EACA,YAAA;ACDF;;ADIA;EACE,qBAAA;EACA,cAAA;ACDF;;ADIA,kBAAA;AAEA;EACE,qBAAA;EACA,oBAAA;ACFF;;ADKA;EACE,uCAAA;ACFF;;ADKA;EACE,mCAAA;ACFF;;ADKA;EACE,aAAA;EACA,sBAAA;EACA,qBAAA;EACA,oBAAA;EACA,kBAAA;ACFF;ADIE;EACE,kBAAA;ACFJ;ADKE;EACE,iBAAA;EACA,oBAAA;EACA,sBAAA;EACA,sBAAA;ACHJ;ADOE;EACE,kBAAA;EACA,WAAA;EACA,OAAA;EACA,QAAA;ACLJ;ADOI;EACE,WAAA;EACA,kBAAA;EACA,QAAA;EACA,QAAA;ACLN;ADSE;EACE,kBAAA;EACA,aAAA;ACPJ;;ADWA;EACE,YAAA;EACA,kEAAA;EACA,2BAAA;EACA,sBAAA;EACA,4BAAA;ACRF;;ADWA;EACE,aAAA;EACA,uBAAA;EACA,kBAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA;EACA,UAAA;ACRF;ADUE;EACE,WAAA;ACRJ;ADWE;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,eAAA;EACA,gBAAA;EACA,qBAAA;ACTJ;ADWI;EARF;IASI,eAAA;ECRJ;AACF;ADUI;EAZF;IAaI,eAAA;ECPJ;AACF;ADSI;EAhBF;IAiBI,eAAA;IACA,QAAA;IACA,QAAA;ECNJ;AACF;;ADUA;EACE,UAAA;EACA,wBAAA;ACPF;ADSE;EAJF;IAKI,UAAA;ECNF;AACF;ADQE;EACE,wBAAA;EACA,gBAAA;EACA,sBAAA;ACNJ;ADQI;EALF;IAMI,wBAAA;ECLJ;AACF;ADOI;EATF;IAUI,uBAAA;ECJJ;AACF;ADMI;EACE,eAAA;EACA,gBAAA;EACA,iBAAA;EACA,iBAAA;ACJN;ADMM;EANF;IAOI,eAAA;ECHN;AACF;ADKM;EAVF;IAWI,cAAA;IACA,mBAAA;ECFN;AACF;ADKI;EACE,cAAA;ACHN;ADKM;EAHF;IAII,cAAA;ECFN;AACF;ADKI;EACE,kBAAA;EACA,YAAA;EACA,2BAAA;ACHN;ADKM;EALF;IAMI,uBAAA;ECFN;AACF","file":"style.css"}
+{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAA,cAAA;AAEA;;;;;;;;;;;;;;;;;;;;EAoBE,SAAA;EACA,UAAA;EACA,SAAA;EACA,eAAA;EACA,wBAAA;EACA,sBAAA;ACAF;;ADGA,sBAAA;AAEA;EACE,cAAA;ACDF;;ADIA;;EAEE,gBAAA;ACDF;;ADIA;EACE,eAAA;EACA,YAAA;ACDF;;ADIA;EACE,qBAAA;EACA,cAAA;ACDF;;ADIA,kBAAA;AAEA;EACE,qBAAA;EACA,oBAAA;ACFF;;ADKA;EACE,uCAAA;ACFF;;ADKA;EACE,mCAAA;ACFF;;ADKA;EACE,aAAA;EACA,sBAAA;EACA,qBAAA;EACA,oBAAA;EACA,kBAAA;ACFF;ADIE;EACE,kBAAA;ACFJ;ADKE;EACE,iBAAA;EACA,oBAAA;EACA,sBAAA;EACA,sBAAA;ACHJ;ADOE;EACE,kBAAA;EACA,WAAA;EACA,OAAA;EACA,QAAA;ACLJ;ADOI;EACE,WAAA;EACA,kBAAA;EACA,QAAA;EACA,QAAA;ACLN;ADSE;EACE,kBAAA;EACA,aAAA;ACPJ;;ADWA;EACE,YAAA;EACA,kEAAA;EACA,2BAAA;EACA,sBAAA;EACA,4BAAA;ACRF;;ADWA;EACE,aAAA;EACA,uBAAA;EACA,kBAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA;EACA,UAAA;ACRF;ADUE;EACE,WAAA;ACRJ;ADWE;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,eAAA;EACA,gBAAA;EACA,qBAAA;ACTJ;ADWI;EARF;IASI,eAAA;ECRJ;AACF;ADUI;EAZF;IAaI,eAAA;ECPJ;AACF;ADSI;EAhBF;IAiBI,eAAA;IACA,QAAA;IACA,QAAA;ECNJ;AACF;;ADUA;EACE,UAAA;EACA,wBAAA;ACPF;ADSE;EAJF;IAKI,UAAA;ECNF;AACF;ADQE;EACE,mBAAA;EACA,gBAAA;EACA,sBAAA;ACNJ;ADQI;EALF;IAMI,mBAAA;ECLJ;AACF;ADOI;EATF;IAUI,kBAAA;ECJJ;AACF;ADMI;EACE,eAAA;EACA,gBAAA;EACA,iBAAA;EACA,iBAAA;ACJN;ADMM;EANF;IAOI,eAAA;ECHN;AACF;ADKM;EAVF;IAWI,cAAA;IACA,mBAAA;ECFN;AACF;ADKI;EACE,cAAA;ACHN;ADKM;EAHF;IAII,cAAA;ECFN;AACF;ADKI;EACE,kBAAA;EACA,YAAA;EACA,2BAAA;ACHN;ADKM;EALF;IAMI,uBAAA;ECFN;AACF;;ADOA;EACE,mBAAA;EACA,mBAAA;EACA,gCAAA;EACA,kCAAA;ACJF;ADME;EACE,YAAA;EACA,aAAA;EACA,mBAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,6BAAA;ACJJ;ADMI;EACE,eAAA;EACA,gBAAA;EACA,kBAAA;EACA,iBAAA;ACJN;ADQE;EACE,aAAA;ACNJ;ADSE;;EAGE,gBAAA;EACA,uBAAA;EACA,oBAAA;EACA,qBAAA;EACA,4BAAA;EACA,6BAAA;ACRJ;ADWE;EACE,eAAA;ACTJ;ADWI;EACE,aAAA;EACA,WAAA;EACA,oBAAA;KAAA,iBAAA;ACTN;ADYI;EACE,YAAA;ACVN;ADYM;EACE,iBAAA;ACVR","file":"style.css"}

+ 60 - 3
src/assets/css/style.scss

@@ -157,16 +157,16 @@ input:focus-visible {
   }
 
   .main-block {
-    padding: 80px 80px 150px;
+    padding: 150px 80px;
     margin-top: -30%;
     background-color: #fff;
 
     @media (max-width: 960px) {
-      padding: 50px 50px 100px;
+      padding: 100px 50px;
     }
 
     @media (max-width: 600px) {
-      padding: 20px 20px 50px;
+      padding: 50px 20px;
     }
 
     h2 {
@@ -203,4 +203,61 @@ input:focus-visible {
       }
     }
   }
+}
+
+.main-card {
+  letter-spacing: 1px;
+  border-radius: 10px;
+  box-shadow: 2px 2px 10px #aaaaaa;
+  background-color: var(--sub-color);
+
+  .card-title {
+    height: 80px;
+    padding: 15px;
+    margin-bottom: 15px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    border-bottom: 2px solid #fff;
+
+    h3 {
+      font-size: 20px;
+      font-weight: 400;
+      text-align: center;
+      line-height: 24px;
+    }
+  }
+
+  ul {
+    padding: 20px;
+  }
+
+  .card-title h3,
+  .card-info p {
+    // 超過兩行則省略
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    line-break: after-white-space;
+  }
+
+  .card-info {
+    padding: 0 15px;
+
+    .cover-img {
+      height: 220px;
+      width: 100%;
+      object-fit: cover;
+    }
+
+    span {
+      height: 60px;
+
+      p {
+        line-height: 20px;
+      }
+    }
+  }
 }

BIN
src/assets/img/college-group/cross/banner.png


BIN
src/assets/img/course/background.png


+ 1 - 1
src/components/Navbar.vue

@@ -62,7 +62,7 @@ function handleClose(value) {
               <router-link :to="'/college-group/repair'">修護工藝</router-link>
             </li>
             <li>
-              <router-link :to="'/college-group/craft'">跨域工藝</router-link>
+              <router-link :to="'/college-group/cross'">跨域工藝</router-link>
             </li>
             <li>
               <router-link :to="'/college-group/craft'">線上工藝</router-link>

+ 6 - 0
src/router/index.js

@@ -12,6 +12,7 @@ const Generation = defineAsyncComponent(() => import('@/views/CollegeGroup/Gener
 const Future = defineAsyncComponent(() => import('@/views/CollegeGroup/Future.vue'));
 const Repair = defineAsyncComponent(() => import('@/views/CollegeGroup/Repair.vue'));
 const Teenager = defineAsyncComponent(() => import('@/views/CollegeGroup/Teenager.vue'));
+const Cross = defineAsyncComponent(() => import('@/views/CollegeGroup/Cross.vue'));
 
 const routes = [
   {
@@ -69,6 +70,11 @@ const routes = [
     name: 'Teenager',
     component: Teenager
   },
+  {
+    path: '/college-group/cross',
+    name: 'Cross',
+    component: Cross
+  },
 ];
 
 const router = createRouter({

+ 126 - 58
src/views/CollegeGroup/Craft.vue

@@ -61,7 +61,7 @@ const testData = [
         <v-breadcrumbs
           :items="breadcrumbs"
           divider="/"
-          class="mt-10 p-0"
+          class="mt-10 pa-0"
         ></v-breadcrumbs>
 
         <div
@@ -98,24 +98,28 @@ const testData = [
             :key="index"
             class="pa-5"
           >
-            <div class="card">
-              <h3>{{ item.title }}</h3>
-              <img :src="item.img" alt="" class="cover-img" />
-              <ul>
-                <li class="d-flex align-center">
-                  <img src="@/assets/img/icon/date_icon.png" alt="" />
-                  <p class="mb-0 ms-3">
-                    {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }} -
-                    {{ moment(`${item.end_time}`).format("YYYY/MM/DD") }}
-                  </p>
-                </li>
-                <li class="d-flex align-center mt-3">
-                  <img src="@/assets/img/icon/location_icon.png" alt="" />
-                  <p class="mb-0 ms-3">
-                    {{ item.address }}
-                  </p>
-                </li>
-              </ul>
+            <div class="main-card">
+              <section class="card-title">
+                <h3>{{ item.title }}</h3>
+              </section>
+              <div class="card-info">
+                <img :src="item.img" alt="" class="cover-img" />
+                <ul>
+                  <li class="d-flex align-center">
+                    <img src="@/assets/img/icon/date_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }} -
+                      {{ moment(`${item.end_time}`).format("YYYY/MM/DD") }}
+                    </p>
+                  </li>
+                  <li class="d-flex align-center mt-3">
+                    <img src="@/assets/img/icon/location_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ item.address }}
+                    </p>
+                  </li>
+                </ul>
+              </div>
             </div>
           </v-col>
         </v-row>
@@ -154,24 +158,88 @@ const testData = [
             :key="index"
             class="pa-5"
           >
-            <div class="card">
-              <h3>{{ item.title }}</h3>
-              <img :src="item.img" alt="" class="cover-img" />
-              <ul>
-                <li class="d-flex align-center">
-                  <img src="@/assets/img/icon/date_icon.png" alt="" />
-                  <p class="mb-0 ms-3">
-                    {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }} -
-                    {{ moment(`${item.end_time}`).format("YYYY/MM/DD") }}
-                  </p>
-                </li>
-                <li class="d-flex align-center mt-3">
-                  <img src="@/assets/img/icon/location_icon.png" alt="" />
-                  <p class="mb-0 ms-3">
-                    {{ item.address }}
-                  </p>
-                </li>
-              </ul>
+            <div class="main-card">
+              <section class="card-title">
+                <h3>{{ item.title }}</h3>
+              </section>
+              <div class="card-info">
+                <img :src="item.img" alt="" class="cover-img" />
+                <ul>
+                  <li class="d-flex align-center">
+                    <img src="@/assets/img/icon/date_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }} -
+                      {{ moment(`${item.end_time}`).format("YYYY/MM/DD") }}
+                    </p>
+                  </li>
+                  <li class="d-flex align-center mt-3">
+                    <img src="@/assets/img/icon/location_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ item.address }}
+                    </p>
+                  </li>
+                </ul>
+              </div>
+            </div>
+          </v-col>
+        </v-row>
+
+        <div
+          class="d-flex flex-column flex-sm-row align-center justify-space-between title"
+        >
+          <h2>手作體驗課程</h2>
+          <div class="search">
+            <span>
+              <input
+                v-model="searchInput"
+                type="text"
+                @keyup.enter="search()"
+              />
+              <button @click="search()">
+                <img src="@/assets/img/news/news-search-icon.png" alt="" />
+              </button>
+            </span>
+            <div
+              v-if="searchError"
+              class="d-flex justify-center align-center error me-4"
+            >
+              <v-icon color="primary" icon="mdi-alert" class="me-2"></v-icon>
+              沒有符合搜尋條件的項目
+            </div>
+          </div>
+        </div>
+
+        <v-row>
+          <v-col
+            sm="6"
+            md="4"
+            cols="12"
+            v-for="(item, index) in testData"
+            :key="index"
+            class="pa-5"
+          >
+            <div class="main-card">
+              <section class="card-title">
+                <h3>{{ item.title }}</h3>
+              </section>
+              <div class="card-info">
+                <img :src="item.img" alt="" class="cover-img" />
+                <ul>
+                  <li class="d-flex align-center">
+                    <img src="@/assets/img/icon/date_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }} -
+                      {{ moment(`${item.end_time}`).format("YYYY/MM/DD") }}
+                    </p>
+                  </li>
+                  <li class="d-flex align-center mt-3">
+                    <img src="@/assets/img/icon/location_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ item.address }}
+                    </p>
+                  </li>
+                </ul>
+              </div>
             </div>
           </v-col>
         </v-row>
@@ -184,7 +252,7 @@ const testData = [
 .content {
   padding: 0;
   width: 90%;
-  
+
   @media (max-width: 600px) {
     width: 85%;
   }
@@ -233,24 +301,24 @@ const testData = [
   }
 }
 
-.card {
-      letter-spacing: 1px;
-      border-radius: 10px;
-      box-shadow: 2px 2px 10px #aaaaaa;
-      background-color: var(--sub-color);
-      h3 {
-        padding: 15px;
-        font-size: 22px;
-        font-weight: 400;
-        text-align: center;
-        margin-bottom: 15px;
-        border-bottom: 2px solid #fff;
-      }
-      ul {
-        padding: 20px;
-      }
-      .cover-img {
-        padding: 0 15px;
-      }
-    }
+// .main-card {
+//   letter-spacing: 1px;
+//   border-radius: 10px;
+//   box-shadow: 2px 2px 10px #aaaaaa;
+//   background-color: var(--sub-color);
+//   h3 {
+//     padding: 15px;
+//     font-size: 22px;
+//     font-weight: 400;
+//     text-align: center;
+//     margin-bottom: 15px;
+//     border-bottom: 2px solid #fff;
+//   }
+//   ul {
+//     padding: 20px;
+//   }
+//   .cover-img {
+//     padding: 0 15px;
+//   }
+// }
 </style>

+ 306 - 0
src/views/CollegeGroup/Cross.vue

@@ -0,0 +1,306 @@
+<script setup>
+import { ref, reactive } from "vue";
+import axios from "axios";
+import moment from "moment";
+import Navbar from "@/components/Navbar.vue";
+import { useMainStore } from "@/stores/store";
+
+const store = useMainStore();
+
+const breadcrumbs = reactive([
+  {
+    title: "首頁",
+    disabled: false,
+    href: "/",
+  },
+  {
+    title: "工藝學群",
+    disabled: false,
+    href: "/ntcri/college-group/craft",
+  },
+  {
+    title: "跨域工藝",
+    disabled: true,
+  },
+]);
+
+const testData = [
+  {
+    title: "種子教師研習",
+    start_time: "2023/06/15",
+    end_time: "2023/06/20",
+    address: "地方工藝館 工藝教室",
+    introduction: "為推動工藝融入學校教育,促進工藝美學校園扎根,透過手作體驗課程,培育學校教師成為種子教師,並回到教學現場發展工藝體驗課程,傳遞工藝所能帶來的生活連結與美好體驗,誘發學生「動手做工藝」的學習興趣,開啟工藝與教育融合共好的無限可能性! 以「綠工藝」核心理念~自然、循環、平衡、寬容、生命力,將工藝體驗課程引介進入教育系統,透過辦理工藝手作課程,培育校園工藝種子人才,發展手作體驗課程,讓工藝融入教學,傳遞工藝所能帶來的生活連結與美好體驗,達到臺灣工藝價值的社會實踐。",
+    img: store.getImageUrl("college-group/img.jpg"),
+  },
+  {
+    title: "種子教師研習",
+    start_time: "2023/06/15",
+    end_time: "2023/06/20",
+    address: "地方工藝館 工藝教室",
+     introduction: "為推動工藝融入學校教育,促進工藝美學校園扎根,透過手作體驗課程,培育學校教師成為種子教師,並回到教學現場發展工藝體驗課程,傳遞工藝所能帶來的生活連結與美好體驗,誘發學生「動手做工藝」的學習興趣,開啟工藝與教育融合共好的無限可能性! 以「綠工藝」核心理念~自然、循環、平衡、寬容、生命力,將工藝體驗課程引介進入教育系統,透過辦理工藝手作課程,培育校園工藝種子人才,發展手作體驗課程,讓工藝融入教學,傳遞工藝所能帶來的生活連結與美好體驗,達到臺灣工藝價值的社會實踐。",
+    img: store.getImageUrl("college-group/img.jpg"),
+  },
+  {
+    title: "種子教師研習",
+    start_time: "2023/06/15",
+    end_time: "2023/06/20",
+    address: "地方工藝館 工藝教室",
+     introduction: "為推動工藝融入學校教育,促進工藝美學校園扎根,透過手作體驗課程,培育學校教師成為種子教師,並回到教學現場發展工藝體驗課程,傳遞工藝所能帶來的生活連結與美好體驗,誘發學生「動手做工藝」的學習興趣,開啟工藝與教育融合共好的無限可能性! 以「綠工藝」核心理念~自然、循環、平衡、寬容、生命力,將工藝體驗課程引介進入教育系統,透過辦理工藝手作課程,培育校園工藝種子人才,發展手作體驗課程,讓工藝融入教學,傳遞工藝所能帶來的生活連結與美好體驗,達到臺灣工藝價值的社會實踐。",
+    img: store.getImageUrl("college-group/img.jpg"),
+  },
+];
+</script>
+
+<template>
+  <div class="college-bg-img">
+    <Navbar />
+    <v-container fluid class="college-content pb-16 px-sm-0">
+      <div class="college-banner">
+        <img src="@/assets/img/college-group/cross/banner.png" alt="" />
+        <h1>跨域工藝</h1>
+      </div>
+      <div class="main-block">
+        <v-breadcrumbs
+          :items="breadcrumbs"
+          divider="/"
+          class="mt-10 pa-0"
+        ></v-breadcrumbs>
+
+        <div
+          class="d-flex flex-column flex-sm-row align-center justify-space-between title"
+        >
+          <h2>智財</h2>
+          <div class="search">
+            <span>
+              <input
+                v-model="searchInput"
+                type="text"
+                @keyup.enter="search()"
+              />
+              <button @click="search()">
+                <img src="@/assets/img/news/news-search-icon.png" alt="" />
+              </button>
+            </span>
+            <div
+              v-if="searchError"
+              class="d-flex justify-center align-center error me-4"
+            >
+              <v-icon color="primary" icon="mdi-alert" class="me-2"></v-icon>
+              沒有符合搜尋條件的項目
+            </div>
+          </div>
+        </div>
+
+        <v-row>
+          <v-col
+            sm="6"
+            md="4"
+            cols="12"
+            v-for="(item, index) in testData"
+            :key="index"
+            class="pa-5"
+          >
+            <div class="main-card">
+              <section class="card-title">
+                <h3>{{ item.title }}</h3>
+              </section>
+              <div class="card-info">
+                <img :src="item.img" alt="" class="cover-img" />
+                <ul>
+                  <li class="d-flex align-center">
+                    <img src="@/assets/img/icon/date_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }} -
+                      {{ moment(`${item.end_time}`).format("YYYY/MM/DD") }}
+                    </p>
+                  </li>
+                  <li class="d-flex align-center mt-3">
+                    <img src="@/assets/img/icon/location_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ item.address }}
+                    </p>
+                  </li>
+                </ul>
+              </div>
+            </div>
+          </v-col>
+        </v-row>
+
+        <div
+          class="d-flex flex-column flex-sm-row align-center justify-space-between title"
+        >
+          <h2>法律</h2>
+          <div class="search">
+            <span>
+              <input
+                v-model="searchInput"
+                type="text"
+                @keyup.enter="search()"
+              />
+              <button @click="search()">
+                <img src="@/assets/img/news/news-search-icon.png" alt="" />
+              </button>
+            </span>
+            <div
+              v-if="searchError"
+              class="d-flex justify-center align-center error me-4"
+            >
+              <v-icon color="primary" icon="mdi-alert" class="me-2"></v-icon>
+              沒有符合搜尋條件的項目
+            </div>
+          </div>
+        </div>
+
+        <v-row>
+          <v-col
+            sm="6"
+            md="4"
+            cols="12"
+            v-for="(item, index) in testData"
+            :key="index"
+            class="pa-5"
+          >
+            <div class="main-card">
+              <section class="card-title">
+                <h3>{{ item.title }}</h3>
+              </section>
+              <div class="card-info">
+                <img :src="item.img" alt="" class="cover-img" />
+                <ul>
+                  <li class="d-flex align-center">
+                    <img src="@/assets/img/icon/date_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }} -
+                      {{ moment(`${item.end_time}`).format("YYYY/MM/DD") }}
+                    </p>
+                  </li>
+                  <li class="d-flex align-center mt-3">
+                    <img src="@/assets/img/icon/location_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ item.address }}
+                    </p>
+                  </li>
+                </ul>
+              </div>
+            </div>
+          </v-col>
+        </v-row>
+
+        <div
+          class="d-flex flex-column flex-sm-row align-center justify-space-between title"
+        >
+          <h2>商業</h2>
+          <div class="search">
+            <span>
+              <input
+                v-model="searchInput"
+                type="text"
+                @keyup.enter="search()"
+              />
+              <button @click="search()">
+                <img src="@/assets/img/news/news-search-icon.png" alt="" />
+              </button>
+            </span>
+            <div
+              v-if="searchError"
+              class="d-flex justify-center align-center error me-4"
+            >
+              <v-icon color="primary" icon="mdi-alert" class="me-2"></v-icon>
+              沒有符合搜尋條件的項目
+            </div>
+          </div>
+        </div>
+
+        <v-row>
+          <v-col
+            sm="6"
+            md="4"
+            cols="12"
+            v-for="(item, index) in testData"
+            :key="index"
+            class="pa-5"
+          >
+            <div class="main-card">
+              <section class="card-title">
+                <h3>{{ item.title }}</h3>
+              </section>
+              <div class="card-info">
+                <img :src="item.img" alt="" class="cover-img" />
+                <ul>
+                  <li class="d-flex align-center">
+                    <img src="@/assets/img/icon/date_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }} -
+                      {{ moment(`${item.end_time}`).format("YYYY/MM/DD") }}
+                    </p>
+                  </li>
+                  <li class="d-flex align-center mt-3">
+                    <img src="@/assets/img/icon/location_icon.png" alt="" />
+                    <p class="mb-0 ms-3">
+                      {{ item.address }}
+                    </p>
+                  </li>
+                </ul>
+              </div>
+            </div>
+          </v-col>
+        </v-row>
+      </div>
+    </v-container>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.content {
+  padding: 0;
+  width: 90%;
+
+  @media (max-width: 600px) {
+    width: 85%;
+  }
+  .main-block {
+    padding: 100px 80px;
+    margin-top: -30%;
+    background-color: #fff;
+
+    @media (max-width: 960px) {
+      padding: 100px 50px;
+    }
+
+    @media (max-width: 600px) {
+      padding: 100px 20px;
+    }
+
+    h2 {
+      font-size: 30px;
+      font-weight: 500;
+      line-height: 32px;
+      margin-left: 10px;
+
+      @media (max-width: 960px) {
+        font-size: 24px;
+      }
+
+      @media (max-width: 600px) {
+        margin-left: 0;
+        margin-bottom: 50px;
+      }
+    }
+    .title {
+      margin: 80px 0;
+      @media (max-width: 600px) {
+        margin: 50px 0;
+      }
+    }
+    .v-breadcrumbs {
+      position: relative;
+      z-index: 100;
+      justify-content: flex-start;
+      @media (max-width: 600px) {
+        justify-content: center;
+      }
+    }
+  }
+}
+</style>

+ 326 - 42
src/views/CourseDetail.vue

@@ -1,14 +1,34 @@
 <script setup>
-import { reactive } from "vue";
+import { ref, reactive, computed } from "vue";
 import { useRoute } from "vue-router";
 import axios from "axios";
-import Navbar from "@/components/NavbarSub.vue";
+import moment from "moment";
+import Navbar from "@/components/Navbar.vue";
 
 const route = useRoute();
 const courseId = route.params.id; // 網址參數
-const course = reactive({
+let groupName = ref("");
+let course = reactive({
   data: [],
 });
+let groupSort = ref("");
+
+const breadcrumbs = reactive([
+  {
+    title: "首頁",
+    disabled: false,
+    href: "/",
+  },
+  {
+    title: "探索課程",
+    disabled: false,
+    href: "/ntcri/course-list",
+  },
+  {
+    title: "課程清單",
+    disabled: true,
+  },
+]);
 
 // 取得資料
 (async function getData() {
@@ -17,36 +37,224 @@ const course = reactive({
       `https://cmm.ai:8088/api/get_class_name?class_name_id=${courseId}`
     );
     course.data = response.data.classes[0];
+    groupSort.value = course.data.group_sort;
+    console.log('groupSort.value',groupSort.value);
     console.log("courseData", course.data);
+
+    if (course.data.group_id === 1) {
+      groupName.value = "未來工藝學群";
+    } else if (course.data.group_id === 2) {
+      groupName.value = "技藝工藝學群";
+    } else if (course.data.group_id === 3) {
+      groupName.value = "生活工藝學群";
+    } else if (course.data.group_id === 4) {
+      groupName.value = "青年工藝學群";
+    } else if (course.data.group_id === 5) {
+      groupName.value = "世代工藝學群";
+    } else if (course.data.group_id === 6) {
+      groupName.value = "修護工藝學群";
+    } else if (course.data.group_id === 7) {
+      groupName.value = "跨域工藝學群";
+    } else if (course.data.group_id === 8) {
+      groupName.value = "線上工藝學群";
+    }
+  } catch (error) {
+    console.error(error);
+  }
+})();
+
+let session = reactive({
+  data: [],
+});
+
+// 取得場次
+(async () => {
+  try {
+    const response = await axios.get(
+      `https://cmm.ai:8088/api/get_event?class_name_id=${courseId}`
+    );
+    // course.data = response.data.classes[0];
+    session.data = response.data.classes;
+    console.log("response", response.data.classes[0]);
   } catch (error) {
     console.error(error);
   }
 })();
+
+let other = reactive({
+  classes: [],
+});
+
+// 取得清單
+(async () => {
+  try {
+    const response = await axios.get("https://cmm.ai:8088/api/get_class_name");
+    console.log("response.data.classes", response.data.classes);
+    // other.classes = response.data.classes;
+    // console.log('handleRandom(response.data.classes,3)',handleRandom(response.data.classes,3));
+    other.classes = handleRandom(response.data.classes, 3);
+    console.log("other.classes", other.classes);
+  } catch (error) {
+    console.error(error);
+  }
+})();
+
+// 隨機取值
+function handleRandom(arr, length) {
+  let newArr = [];
+  for (let i = 0; i < length; i++) {
+    let index = Math.floor(Math.random() * arr.length);
+    let item = arr[index];
+    newArr.push(item);
+    arr.splice(index, 1);
+  }
+  return newArr.reverse();
+}
+
+const dynamicCols = computed(() => {
+    return groupSort.value === "pinkoi" ? "5" : "8";
+  });
 </script>
 
 <template>
   <Navbar />
 
   <v-container class="mt-16 course-detail">
-    <v-row>
-      <v-col cols="12">
-        <img :src="`https://cmm.ai/ntcri/${course.data.cover_img}`" alt="" />
+    <v-breadcrumbs
+      :items="breadcrumbs"
+      divider="/"
+      class="mt-3 mb-16 pa-0"
+    ></v-breadcrumbs>
+    <v-row class="justify-center">
+      <v-col cols="3" class="title pa-0">
+        <img src="@/assets/img/course/background.png" alt="" class="bg-img" />
+        <h2>{{ course.data.name }}</h2>
+      </v-col>
+      <v-col :cols="dynamicCols" class="pa-0 d-flex justify-center">
+        <img :src="course.data.cover_img" alt="" class="cover-img" :class="{ 'small' : groupSort === 'pinkoi' }" />
       </v-col>
       <v-col cols="12">
-        <div class="h-100 d-flex flex-column">
-          <h2>{{ course.data.name }}</h2>
-          <section>
-            <h4 class="mb-5">課程簡介:</h4>
-            <p class="mb-5">
-              {{ course.data.introduction }}
-            </p>
-          </section>
+        <div class="info">
+          <table>
+            <thead>
+              <tr>
+                <th colspan="2">課程資訊</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr>
+                <td>課程簡介</td>
+                <td>{{ course.data.introduction }}</td>
+              </tr>
+              <tr v-show="course.data.category !== ''">
+                <td>課程類別</td>
+                <td>{{ course.data.category }}</td>
+              </tr>
+              <tr>
+                <td>主辦單位</td>
+                <td>{{ course.data.organizer }}-{{ course.data.school }}</td>
+              </tr>
+              <tr>
+                <td>所屬學群</td>
+                <td>{{ groupName }}</td>
+              </tr>
+              <!-- <tr>
+                <td>報名對象</td>
+                <td></td>
+              </tr>
+              <tr>
+                <td>收費方式</td>
+                <td></td>
+              </tr>
+              <tr>
+                <td>報名方式</td>
+                <td></td>
+              </tr>
+              <tr>
+                <td>聯絡方式</td>
+                <td></td>
+              </tr>
+              <tr>
+                <td>備註</td>
+                <td></td>
+              </tr> -->
+            </tbody>
+          </table>
+          <div class="d-flex justify-end">
+            <v-btn rounded="xl" color="brown">附件下載</v-btn>
+          </div>
         </div>
       </v-col>
       <v-col cols="12">
-        <p>
-          {{ course.data.content }}
-        </p>
+        <div class="sessions">
+          <table>
+            <thead>
+              <tr>
+                <th>場次名稱</th>
+                <th>開始/結束時間</th>
+                <th>課程地點</th>
+                <th>講師</th>
+                <th>報名截止日</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr v-for="(item, index) in session.data" :key="index">
+                <td>{{ item.class_name }}</td>
+                <td>
+                  {{ moment(`${item.start_time}`).format("YYYY/MM/DD H:mm") }}
+                  <br />
+                  ~ <br />
+                  {{ moment(`${item.end_time}`).format("YYYY/MM/DD H:mm") }}
+                </td>
+                <td></td>
+                <td></td>
+                <td></td>
+                <td style="width: 0; padding: 0; border: none">
+                  <div class="signup-btn">
+                    <v-btn rounded="xl" color="brown" :href="item.URL">
+                      點我報名
+                    </v-btn>
+                  </div>
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+      </v-col>
+      <v-col cols="12" class="my-16">
+        <p class="other-title">其他推薦課程</p>
+        <v-row>
+          <v-col
+            sm="6"
+            md="4"
+            cols="12"
+            v-for="(item, index) in other.classes"
+            :key="index"
+            class="pa-5"
+          >
+            <div class="main-card">
+              <section class="card-title">
+                <h3>{{ item.name }}</h3>
+              </section>
+              <div class="card-info">
+                <a
+                  :href="
+                    $router.resolve(`/course-detail/${item.class_name_id}`).href
+                  "
+                >
+                  <img :src="item.cover_img" alt="" class="cover-img" />
+                </a>
+                <!-- <img :src="item.cover_img" alt="" class="cover-img" /> -->
+                <span class="d-flex align-center py-3">
+                  <img src="@/assets/img/icon/location_icon.png" alt="" />
+                  <p class="mb-0 ms-3">
+                    {{ item.school }}
+                  </p>
+                </span>
+              </div>
+            </div>
+          </v-col>
+        </v-row>
       </v-col>
     </v-row>
   </v-container>
@@ -54,38 +262,114 @@ const course = reactive({
 
 <style lang="scss">
 .course-detail {
-  width: 1000px;
-
-  @media (max-width: 960px) {
+  .cover-img {
     width: 100%;
+    height: 500px;
+    object-fit: cover;
+    &.small {
+      width: auto;
+      height: auto;
+    }
   }
 
-  img {
-    width: 100%;
-    height: 100%;
-    object-fit: cover;
+  .title {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    h2 {
+      margin-top: -35px;
+      margin-left: 5px;
+      font-size: 24px;
+      font-weight: 500;
+      line-height: 32px;
+      letter-spacing: 1px;
+      color: #201715;
+    }
+    .bg-img {
+      width: 250px;
+      position: absolute;
+      z-index: -1;
+      right: -15px;
+      bottom: -100px;
+    }
   }
-  h2 {
-    padding: 20px;
-    margin-bottom: 20px;
-    font-size: 22px;
-    font-weight: 500;
-    text-align: center;
-    color: #fff;
-    background-color: var(--main-color);
-    letter-spacing: 2px;
+
+  .info {
+    margin: 50px auto;
+    padding: 25px 50px;
+    table {
+      td {
+        padding: 10px 20px;
+        line-height: 32px;
+        letter-spacing: 1px;
+        vertical-align: top;
+        &:first-child {
+          border-right: 1px solid #333;
+        }
+      }
+      th {
+        padding-bottom: 20px;
+        border-bottom: 1px solid #333;
+      }
+      th,
+      td:first-child {
+        width: 117px;
+        font-size: 18px;
+        font-weight: 500;
+      }
+    }
+  }
+
+  .info,
+  .sessions {
+    background-color: #f2f2f4;
+    table {
+      width: 100%;
+      border-collapse: collapse;
+      td {
+        line-height: 22px;
+      }
+    }
   }
-  section {
-    height: 100%;
-    padding: 30px;
-    border: 2px solid var(--main-color);
-    h4 {
-      font-weight: normal;
+
+  .sessions {
+    padding: 25px 50px 70px;
+    table {
+      position: relative;
+      th {
+        width: 117px;
+        font-size: 18px;
+        font-weight: 500;
+        padding-bottom: 20px;
+      }
+      td {
+        padding: 20px;
+        vertical-align: middle;
+      }
+      tbody {
+        background-color: #fff;
+      }
+    }
+
+    .signup-btn {
+      position: absolute;
+      bottom: -53px;
+      right: 0;
     }
   }
-  p {
-    line-height: 30px;
-    white-space: pre-line;
+
+  @media (max-width: 960px) {
+    width: 100%;
+  }
+
+  .other-title {
+    margin: 30px 0;
+    padding-bottom: 30px;
+    font-size: 26px;
+    text-align: center;
+    border-bottom: 1px solid;
   }
 }
 </style>

+ 71 - 54
src/views/NewsDetail.vue

@@ -29,46 +29,48 @@ const news = reactive({
   <Navbar />
   <div class="position-relative">
     <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
-    <v-container class="pa-0 position-relative">
-      <img
+    <v-container class="pa-0 pt-16 position-relative">
+      <!-- <img
         src="@/assets/img/news/news-detail-banner.png"
         alt=""
         class="bg-img"
-      />
+      /> -->
 
       <div class="content">
-        <v-row>
-          <v-col cols="12">
-            <div class="d-flex align-center mb-5">
-              <v-chip size="large" variant="elevated" class="px-8 me-3">
-                {{ news.data.category }}
-              </v-chip>
-              <p>
-                {{ moment(`${news.data.create_time}`).format("YYYY.MM.DD") }}
-              </p>
-            </div>
-            <h2>【{{ news.data.title }}】</h2>
-            <img src="@/assets/img/img-04.jpg" alt="" class="cover-img" />
-            <!-- <img :src="`https://cmm.ai/ntcri/${news.data.cover_img}`" alt="" /> -->
-          </v-col>
-          <v-col cols="12">
-            <section class="h-100 d-flex flex-column pa-0">
-              <p v-html="news.data.content"></p>
-            </section>
-          </v-col>
-        </v-row>
-      </div>
+        <div class="article">
+          <v-row>
+            <v-col cols="12">
+              <div class="d-flex align-center mb-5">
+                <v-chip size="large" variant="elevated" class="px-8 me-3">
+                  {{ news.data.category }}
+                </v-chip>
+                <p>
+                  {{ moment(`${news.data.create_time}`).format("YYYY.MM.DD") }}
+                </p>
+              </div>
+              <h2>【{{ news.data.title }}】</h2>
+              <img src="@/assets/img/img-04.jpg" alt="" class="cover-img" />
+              <!-- <img :src="`https://cmm.ai/ntcri/${news.data.cover_img}`" alt="" /> -->
+            </v-col>
+            <v-col cols="12">
+              <section class="d-flex flex-column pa-0">
+                <p v-html="news.data.content"></p>
 
-      <div class="btn-block">
-        <v-btn rounded="xl" color="grey-darken-2" class="px-7">
-          檔案下載
-        </v-btn>
-        <v-btn rounded="xl" color="grey-darken-2" class="px-7 ms-3">
-          前往連結
-        </v-btn>
+                <div class="btn-block mt-10">
+                <v-btn rounded="xl" color="grey-darken-2" class="px-7">
+                  檔案下載
+                </v-btn>
+                <v-btn rounded="xl" color="grey-darken-2" class="px-7 ms-3">
+                  前往連結
+                </v-btn>
+              </div>
+              </section>
+            </v-col>
+          </v-row>
+        </div>
       </div>
     </v-container>
-    <router-link to="/news" class="mt-10 back-link"
+    <router-link to="/news" class="mt-16 back-link"
       >< 返回最新消息</router-link
     >
     <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
@@ -77,30 +79,45 @@ const news = reactive({
 
 <style lang="scss" scoped>
 .btn-block {
-  position: absolute;
-  bottom: 80px;
-  right: 180px;
-  @media (max-width: 600px) {
-    bottom: 65px;
-    right: unset;
-    width: 100%;
-    display: flex;
-    justify-content: center;
-  }
+  display: flex;
+  justify-content: end;
+  // position: absolute;
+  // bottom: 80px;
+  // right: 180px;
+  // @media (max-width: 600px) {
+  //   bottom: 65px;
+  //   right: unset;
+  //   width: 100%;
+  //   display: flex;
+  //   justify-content: center;
+  // }
 }
+
 .content {
-  position: absolute;
-  right: 0;
-  left: 0;
-  top: 75px;
-  height: 780px;
-  overflow-y: scroll;
-  overflow-x: hidden;
-  display: flex;
+  padding: 20px;
+  background-image: url("@/assets/img/news/news-02.png");
+  background-position: center;
+  background-size: cover;
+  border-radius: 50px;
+}
+.article {
+  // position: absolute;
+  // right: 0;
+  // left: 0;
+  // top: 75px;
+  // height: 780px;
+  // overflow-y: scroll;
+  // overflow-x: hidden;
   margin: auto;
-  padding-top: 50px;
+  padding: 80px 50px;
+  display: flex;
   justify-content: center;
-  width: 75%;
+  border: 1px solid #d4d6d8;
+  border-radius: 50px;
+
+  // background-image: url('@/assets/img/news/news-detail-banner.png');
+  // background-position: center;
+  // background-size: cover;
 
   @media (max-width: 960px) {
     width: 80%;
@@ -123,8 +140,8 @@ const news = reactive({
     height: 100%;
     padding: 30px;
     p {
-      padding: 20px;
-      margin-bottom: 20px;
+      // padding: 20px;
+      // margin-bottom: 20px;
       font-size: 18px;
       font-weight: 400;
       line-height: 32px;