SyuanYu 1 year ago
parent
commit
d6b4d2a487
61 changed files with 9890 additions and 2034 deletions
  1. 1310 1
      package-lock.json
  2. 0 1
      package.json
  3. 9 8
      src/App.vue
  4. 1596 0
      src/assets/TwCities.json
  5. 170 153
      src/assets/css/style.css
  6. 0 0
      src/assets/css/style.css.map
  7. 183 156
      src/assets/css/style.scss
  8. BIN
      src/assets/img/cfa-default.jpg
  9. BIN
      src/assets/img/college-group/cross.webp
  10. 17 16
      src/components/ArticleCard.vue
  11. 51 27
      src/components/CourseCard.vue
  12. 56 71
      src/components/CoursesTutorial.vue
  13. 5 4
      src/components/CraftsArticle.vue
  14. 8 8
      src/components/Footer.vue
  15. 32 17
      src/components/HomeList.vue
  16. 14 1
      src/components/Map.vue
  17. 95 49
      src/components/Navbar.vue
  18. 11 11
      src/components/NavbarSub.vue
  19. 1 1
      src/components/PDFViewer.vue
  20. 1 0
      src/components/SignUpCard.vue
  21. 5 5
      src/components/TermsList.vue
  22. 22 0
      src/router/index.js
  23. 61 9
      src/stores/store.js
  24. 29 28
      src/views/Article.vue
  25. 25 25
      src/views/ArticleDetail.vue
  26. 29 20
      src/views/CollegeGroup/Cfa.vue
  27. 59 47
      src/views/CollegeGroup/Craft.vue
  28. 54 23
      src/views/CollegeGroup/Cross.vue
  29. 47 44
      src/views/CollegeGroup/Future.vue
  30. 7 9
      src/views/CollegeGroup/Generation.vue
  31. 16 16
      src/views/CollegeGroup/Life.vue
  32. 1 1
      src/views/CollegeGroup/Life/Apprentice/About.vue
  33. 3 2
      src/views/CollegeGroup/Life/Apprentice/Contact.vue
  34. 1 1
      src/views/CollegeGroup/Life/Apprentice/Course.vue
  35. 5 5
      src/views/CollegeGroup/Life/Apprentice/FAQ.vue
  36. 11 11
      src/views/CollegeGroup/Life/Apprentice/Main.vue
  37. 2 2
      src/views/CollegeGroup/Life/Campus.vue
  38. 3 2
      src/views/CollegeGroup/Life/CraftJourney.vue
  39. 24 19
      src/views/CollegeGroup/Life/Shop.vue
  40. 12 12
      src/views/CollegeGroup/Main.vue
  41. 17 17
      src/views/CollegeGroup/Online.vue
  42. 36 36
      src/views/CollegeGroup/Proposal.vue
  43. 33 33
      src/views/CollegeGroup/Repair.vue
  44. 5 5
      src/views/CollegeGroup/Teenager.vue
  45. 414 88
      src/views/CourseDetail.vue
  46. 9 9
      src/views/CourseList.vue
  47. 616 328
      src/views/Courses/Create.vue
  48. 2198 0
      src/views/Courses/Proposal.vue
  49. 106 16
      src/views/Courses/SetUp.vue
  50. 2 2
      src/views/Courses/Tutorial.vue
  51. 80 77
      src/views/Crafts.vue
  52. 511 142
      src/views/Home.vue
  53. 13 13
      src/views/Login.vue
  54. 28 28
      src/views/News.vue
  55. 23 24
      src/views/NewsDetail.vue
  56. 1591 304
      src/views/User/Courses.vue
  57. 37 32
      src/views/User/Dashboard.vue
  58. 1 1
      src/views/User/FavoriteClass.vue
  59. 70 38
      src/views/User/Passport.vue
  60. 124 35
      src/views/User/Profile.vue
  61. 1 1
      src/views/User/Setting.vue

File diff suppressed because it is too large
+ 1310 - 1
package-lock.json


+ 0 - 1
package.json

@@ -9,7 +9,6 @@
     "preview": "vite preview"
     "preview": "vite preview"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@googlemaps/js-api-loader": "^1.16.2",
     "@mdi/font": "^7.2.96",
     "@mdi/font": "^7.2.96",
     "@vuepic/vue-datepicker": "^5.4.0",
     "@vuepic/vue-datepicker": "^5.4.0",
     "animate.css": "^4.1.1",
     "animate.css": "^4.1.1",

+ 9 - 8
src/App.vue

@@ -19,7 +19,7 @@ onMounted(() => {
   setTimeout(() => {
   setTimeout(() => {
     isMounted.value = true;
     isMounted.value = true;
   }, 500);
   }, 500);
-  
+
   window.addEventListener("scroll", checkScrollPosition);
   window.addEventListener("scroll", checkScrollPosition);
 
 
   // Start of HubSpot Embed Code
   // Start of HubSpot Embed Code
@@ -54,15 +54,16 @@ onBeforeUnmount(() => {
 
 
 <style lang="scss">
 <style lang="scss">
 .top-btn {
 .top-btn {
-  width: 60px !important;
-  height: 60px !important;
+  width: 3.75em !important;
+  height: 3.75em !important;
   position: fixed !important;
   position: fixed !important;
-  right: 16px;
-  bottom: 90px;
-  z-index: 100;
-  box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 4px, rgba(0, 0, 0, 0.2) 0px 2px 12px !important;
+  right: 1em;
+  bottom: 5.625em;
+  z-index: 1000;
+  box-shadow: rgba(0, 0, 0, 0.1) 0 0.0625em 0.25em,
+    rgba(0, 0, 0, 0.2) 0 0.125em 0.75em !important;
   .v-icon {
   .v-icon {
-    font-size: 33px;
+    font-size: 2.0625em;
   }
   }
 }
 }
 </style>
 </style>

+ 1596 - 0
src/assets/TwCities.json

@@ -0,0 +1,1596 @@
+[
+  {
+    "districts": [
+      {
+        "zip": "100",
+        "name": "中正區"
+      },
+      {
+        "zip": "103",
+        "name": "大同區"
+      },
+      {
+        "zip": "104",
+        "name": "中山區"
+      },
+      {
+        "zip": "105",
+        "name": "松山區"
+      },
+      {
+        "zip": "106",
+        "name": "大安區"
+      },
+      {
+        "zip": "108",
+        "name": "萬華區"
+      },
+      {
+        "zip": "110",
+        "name": "信義區"
+      },
+      {
+        "zip": "111",
+        "name": "士林區"
+      },
+      {
+        "zip": "112",
+        "name": "北投區"
+      },
+      {
+        "zip": "114",
+        "name": "內湖區"
+      },
+      {
+        "zip": "115",
+        "name": "南港區"
+      },
+      {
+        "zip": "116",
+        "name": "文山區"
+      }
+    ],
+    "name": "臺北市"
+  },
+  {
+    "districts": [
+      {
+        "zip": "200",
+        "name": "仁愛區"
+      },
+      {
+        "zip": "201",
+        "name": "信義區"
+      },
+      {
+        "zip": "202",
+        "name": "中正區"
+      },
+      {
+        "zip": "203",
+        "name": "中山區"
+      },
+      {
+        "zip": "204",
+        "name": "安樂區"
+      },
+      {
+        "zip": "205",
+        "name": "暖暖區"
+      },
+      {
+        "zip": "206",
+        "name": "七堵區"
+      }
+    ],
+    "name": "基隆市"
+  },
+  {
+    "districts": [
+      {
+        "zip": "207",
+        "name": "萬里區"
+      },
+      {
+        "zip": "208",
+        "name": "金山區"
+      },
+      {
+        "zip": "220",
+        "name": "板橋區"
+      },
+      {
+        "zip": "221",
+        "name": "汐止區"
+      },
+      {
+        "zip": "222",
+        "name": "深坑區"
+      },
+      {
+        "zip": "223",
+        "name": "石碇區"
+      },
+      {
+        "zip": "224",
+        "name": "瑞芳區"
+      },
+      {
+        "zip": "226",
+        "name": "平溪區"
+      },
+      {
+        "zip": "227",
+        "name": "雙溪區"
+      },
+      {
+        "zip": "228",
+        "name": "貢寮區"
+      },
+      {
+        "zip": "231",
+        "name": "新店區"
+      },
+      {
+        "zip": "232",
+        "name": "坪林區"
+      },
+      {
+        "zip": "233",
+        "name": "烏來區"
+      },
+      {
+        "zip": "234",
+        "name": "永和區"
+      },
+      {
+        "zip": "235",
+        "name": "中和區"
+      },
+      {
+        "zip": "236",
+        "name": "土城區"
+      },
+      {
+        "zip": "237",
+        "name": "三峽區"
+      },
+      {
+        "zip": "238",
+        "name": "樹林區"
+      },
+      {
+        "zip": "239",
+        "name": "鶯歌區"
+      },
+      {
+        "zip": "241",
+        "name": "三重區"
+      },
+      {
+        "zip": "242",
+        "name": "新莊區"
+      },
+      {
+        "zip": "243",
+        "name": "泰山區"
+      },
+      {
+        "zip": "244",
+        "name": "林口區"
+      },
+      {
+        "zip": "247",
+        "name": "蘆洲區"
+      },
+      {
+        "zip": "248",
+        "name": "五股區"
+      },
+      {
+        "zip": "249",
+        "name": "八里區"
+      },
+      {
+        "zip": "251",
+        "name": "淡水區"
+      },
+      {
+        "zip": "252",
+        "name": "三芝區"
+      },
+      {
+        "zip": "253",
+        "name": "石門區"
+      }
+    ],
+    "name": "新北市"
+  },
+  {
+    "districts": [
+      {
+        "zip": "260",
+        "name": "宜蘭市"
+      },
+      {
+        "zip": "263",
+        "name": "壯圍鄉"
+      },
+      {
+        "zip": "261",
+        "name": "頭城鎮"
+      },
+      {
+        "zip": "262",
+        "name": "礁溪鄉"
+      },
+      {
+        "zip": "264",
+        "name": "員山鄉"
+      },
+      {
+        "zip": "265",
+        "name": "羅東鎮"
+      },
+      {
+        "zip": "266",
+        "name": "三星鄉"
+      },
+      {
+        "zip": "267",
+        "name": "大同鄉"
+      },
+      {
+        "zip": "268",
+        "name": "五結鄉"
+      },
+      {
+        "zip": "269",
+        "name": "冬山鄉"
+      },
+      {
+        "zip": "270",
+        "name": "蘇澳鎮"
+      },
+      {
+        "zip": "272",
+        "name": "南澳鄉"
+      },
+      {
+        "zip": "290",
+        "name": "釣魚臺"
+      }
+    ],
+    "name": "宜蘭縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "209",
+        "name": "南竿鄉"
+      },
+      {
+        "zip": "210",
+        "name": "北竿鄉"
+      },
+      {
+        "zip": "211",
+        "name": "莒光鄉"
+      },
+      {
+        "zip": "212",
+        "name": "東引鄉"
+      }
+    ],
+    "name": "連江縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "300",
+        "name": "東區"
+      },
+      {
+        "zip": "300",
+        "name": "北區"
+      },
+      {
+        "zip": "300",
+        "name": "香山區"
+      }
+    ],
+    "name": "新竹市"
+  },
+  {
+    "districts": [
+      {
+        "zip": "308",
+        "name": "寶山鄉"
+      },
+      {
+        "zip": "302",
+        "name": "竹北市"
+      },
+      {
+        "zip": "303",
+        "name": "湖口鄉"
+      },
+      {
+        "zip": "304",
+        "name": "新豐鄉"
+      },
+      {
+        "zip": "305",
+        "name": "新埔鎮"
+      },
+      {
+        "zip": "306",
+        "name": "關西鎮"
+      },
+      {
+        "zip": "307",
+        "name": "芎林鄉"
+      },
+      {
+        "zip": "310",
+        "name": "竹東鎮"
+      },
+      {
+        "zip": "311",
+        "name": "五峰鄉"
+      },
+      {
+        "zip": "312",
+        "name": "橫山鄉"
+      },
+      {
+        "zip": "313",
+        "name": "尖石鄉"
+      },
+      {
+        "zip": "314",
+        "name": "北埔鄉"
+      },
+      {
+        "zip": "315",
+        "name": "峨眉鄉"
+      }
+    ],
+    "name": "新竹縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "320",
+        "name": "中壢區"
+      },
+      {
+        "zip": "324",
+        "name": "平鎮區"
+      },
+      {
+        "zip": "325",
+        "name": "龍潭區"
+      },
+      {
+        "zip": "326",
+        "name": "楊梅區"
+      },
+      {
+        "zip": "327",
+        "name": "新屋區"
+      },
+      {
+        "zip": "328",
+        "name": "觀音區"
+      },
+      {
+        "zip": "330",
+        "name": "桃園區"
+      },
+      {
+        "zip": "333",
+        "name": "龜山區"
+      },
+      {
+        "zip": "334",
+        "name": "八德區"
+      },
+      {
+        "zip": "335",
+        "name": "大溪區"
+      },
+      {
+        "zip": "336",
+        "name": "復興區"
+      },
+      {
+        "zip": "337",
+        "name": "大園區"
+      },
+      {
+        "zip": "338",
+        "name": "蘆竹區"
+      }
+    ],
+    "name": "桃園市"
+  },
+  {
+    "districts": [
+      {
+        "zip": "350",
+        "name": "竹南鎮"
+      },
+      {
+        "zip": "351",
+        "name": "頭份市"
+      },
+      {
+        "zip": "352",
+        "name": "三灣鄉"
+      },
+      {
+        "zip": "353",
+        "name": "南庄鄉"
+      },
+      {
+        "zip": "354",
+        "name": "獅潭鄉"
+      },
+      {
+        "zip": "356",
+        "name": "後龍鎮"
+      },
+      {
+        "zip": "357",
+        "name": "通霄鎮"
+      },
+      {
+        "zip": "358",
+        "name": "苑裡鎮"
+      },
+      {
+        "zip": "360",
+        "name": "苗栗市"
+      },
+      {
+        "zip": "361",
+        "name": "造橋鄉"
+      },
+      {
+        "zip": "362",
+        "name": "頭屋鄉"
+      },
+      {
+        "zip": "363",
+        "name": "公館鄉"
+      },
+      {
+        "zip": "364",
+        "name": "大湖鄉"
+      },
+      {
+        "zip": "365",
+        "name": "泰安鄉"
+      },
+      {
+        "zip": "366",
+        "name": "銅鑼鄉"
+      },
+      {
+        "zip": "367",
+        "name": "三義鄉"
+      },
+      {
+        "zip": "368",
+        "name": "西湖鄉"
+      },
+      {
+        "zip": "369",
+        "name": "卓蘭鎮"
+      }
+    ],
+    "name": "苗栗縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "400",
+        "name": "中區"
+      },
+      {
+        "zip": "401",
+        "name": "東區"
+      },
+      {
+        "zip": "402",
+        "name": "南區"
+      },
+      {
+        "zip": "403",
+        "name": "西區"
+      },
+      {
+        "zip": "404",
+        "name": "北區"
+      },
+      {
+        "zip": "406",
+        "name": "北屯區"
+      },
+      {
+        "zip": "407",
+        "name": "西屯區"
+      },
+      {
+        "zip": "408",
+        "name": "南屯區"
+      },
+      {
+        "zip": "411",
+        "name": "太平區"
+      },
+      {
+        "zip": "412",
+        "name": "大里區"
+      },
+      {
+        "zip": "413",
+        "name": "霧峰區"
+      },
+      {
+        "zip": "414",
+        "name": "烏日區"
+      },
+      {
+        "zip": "420",
+        "name": "豐原區"
+      },
+      {
+        "zip": "421",
+        "name": "后里區"
+      },
+      {
+        "zip": "422",
+        "name": "石岡區"
+      },
+      {
+        "zip": "423",
+        "name": "東勢區"
+      },
+      {
+        "zip": "424",
+        "name": "和平區"
+      },
+      {
+        "zip": "426",
+        "name": "新社區"
+      },
+      {
+        "zip": "427",
+        "name": "潭子區"
+      },
+      {
+        "zip": "428",
+        "name": "大雅區"
+      },
+      {
+        "zip": "429",
+        "name": "神岡區"
+      },
+      {
+        "zip": "432",
+        "name": "大肚區"
+      },
+      {
+        "zip": "433",
+        "name": "沙鹿區"
+      },
+      {
+        "zip": "434",
+        "name": "龍井區"
+      },
+      {
+        "zip": "435",
+        "name": "梧棲區"
+      },
+      {
+        "zip": "436",
+        "name": "清水區"
+      },
+      {
+        "zip": "437",
+        "name": "大甲區"
+      },
+      {
+        "zip": "438",
+        "name": "外埔區"
+      },
+      {
+        "zip": "439",
+        "name": "大安區"
+      }
+    ],
+    "name": "臺中市"
+  },
+  {
+    "districts": [
+      {
+        "zip": "500",
+        "name": "彰化市"
+      },
+      {
+        "zip": "502",
+        "name": "芬園鄉"
+      },
+      {
+        "zip": "503",
+        "name": "花壇鄉"
+      },
+      {
+        "zip": "504",
+        "name": "秀水鄉"
+      },
+      {
+        "zip": "505",
+        "name": "鹿港鎮"
+      },
+      {
+        "zip": "506",
+        "name": "福興鄉"
+      },
+      {
+        "zip": "507",
+        "name": "線西鄉"
+      },
+      {
+        "zip": "508",
+        "name": "和美鎮"
+      },
+      {
+        "zip": "509",
+        "name": "伸港鄉"
+      },
+      {
+        "zip": "510",
+        "name": "員林市"
+      },
+      {
+        "zip": "511",
+        "name": "社頭鄉"
+      },
+      {
+        "zip": "512",
+        "name": "永靖鄉"
+      },
+      {
+        "zip": "513",
+        "name": "埔心鄉"
+      },
+      {
+        "zip": "514",
+        "name": "溪湖鎮"
+      },
+      {
+        "zip": "515",
+        "name": "大村鄉"
+      },
+      {
+        "zip": "516",
+        "name": "埔鹽鄉"
+      },
+      {
+        "zip": "520",
+        "name": "田中鎮"
+      },
+      {
+        "zip": "521",
+        "name": "北斗鎮"
+      },
+      {
+        "zip": "522",
+        "name": "田尾鄉"
+      },
+      {
+        "zip": "523",
+        "name": "埤頭鄉"
+      },
+      {
+        "zip": "524",
+        "name": "溪州鄉"
+      },
+      {
+        "zip": "525",
+        "name": "竹塘鄉"
+      },
+      {
+        "zip": "526",
+        "name": "二林鎮"
+      },
+      {
+        "zip": "527",
+        "name": "大城鄉"
+      },
+      {
+        "zip": "528",
+        "name": "芳苑鄉"
+      },
+      {
+        "zip": "530",
+        "name": "二水鄉"
+      }
+    ],
+    "name": "彰化縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "540",
+        "name": "南投市"
+      },
+      {
+        "zip": "541",
+        "name": "中寮鄉"
+      },
+      {
+        "zip": "542",
+        "name": "草屯鎮"
+      },
+      {
+        "zip": "544",
+        "name": "國姓鄉"
+      },
+      {
+        "zip": "545",
+        "name": "埔里鎮"
+      },
+      {
+        "zip": "546",
+        "name": "仁愛鄉"
+      },
+      {
+        "zip": "551",
+        "name": "名間鄉"
+      },
+      {
+        "zip": "552",
+        "name": "集集鎮"
+      },
+      {
+        "zip": "553",
+        "name": "水里鄉"
+      },
+      {
+        "zip": "555",
+        "name": "魚池鄉"
+      },
+      {
+        "zip": "556",
+        "name": "信義鄉"
+      },
+      {
+        "zip": "557",
+        "name": "竹山鎮"
+      },
+      {
+        "zip": "558",
+        "name": "鹿谷鄉"
+      }
+    ],
+    "name": "南投縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "600",
+        "name": "西區"
+      },
+      {
+        "zip": "600",
+        "name": "東區"
+      }
+    ],
+    "name": "嘉義市"
+  },
+  {
+    "districts": [
+      {
+        "zip": "602",
+        "name": "番路鄉"
+      },
+      {
+        "zip": "603",
+        "name": "梅山鄉"
+      },
+      {
+        "zip": "604",
+        "name": "竹崎鄉"
+      },
+      {
+        "zip": "605",
+        "name": "阿里山鄉"
+      },
+      {
+        "zip": "606",
+        "name": "中埔鄉"
+      },
+      {
+        "zip": "607",
+        "name": "大埔鄉"
+      },
+      {
+        "zip": "608",
+        "name": "水上鄉"
+      },
+      {
+        "zip": "611",
+        "name": "鹿草鄉"
+      },
+      {
+        "zip": "612",
+        "name": "太保市"
+      },
+      {
+        "zip": "613",
+        "name": "朴子市"
+      },
+      {
+        "zip": "614",
+        "name": "東石鄉"
+      },
+      {
+        "zip": "615",
+        "name": "六腳鄉"
+      },
+      {
+        "zip": "616",
+        "name": "新港鄉"
+      },
+      {
+        "zip": "621",
+        "name": "民雄鄉"
+      },
+      {
+        "zip": "622",
+        "name": "大林鎮"
+      },
+      {
+        "zip": "623",
+        "name": "溪口鄉"
+      },
+      {
+        "zip": "624",
+        "name": "義竹鄉"
+      },
+      {
+        "zip": "625",
+        "name": "布袋鎮"
+      }
+    ],
+    "name": "嘉義縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "630",
+        "name": "斗南鎮"
+      },
+      {
+        "zip": "631",
+        "name": "大埤鄉"
+      },
+      {
+        "zip": "632",
+        "name": "虎尾鎮"
+      },
+      {
+        "zip": "633",
+        "name": "土庫鎮"
+      },
+      {
+        "zip": "634",
+        "name": "褒忠鄉"
+      },
+      {
+        "zip": "635",
+        "name": "東勢鄉"
+      },
+      {
+        "zip": "636",
+        "name": "臺西鄉"
+      },
+      {
+        "zip": "637",
+        "name": "崙背鄉"
+      },
+      {
+        "zip": "638",
+        "name": "麥寮鄉"
+      },
+      {
+        "zip": "640",
+        "name": "斗六市"
+      },
+      {
+        "zip": "643",
+        "name": "林內鄉"
+      },
+      {
+        "zip": "646",
+        "name": "古坑鄉"
+      },
+      {
+        "zip": "647",
+        "name": "莿桐鄉"
+      },
+      {
+        "zip": "648",
+        "name": "西螺鎮"
+      },
+      {
+        "zip": "649",
+        "name": "二崙鄉"
+      },
+      {
+        "zip": "651",
+        "name": "北港鎮"
+      },
+      {
+        "zip": "652",
+        "name": "水林鄉"
+      },
+      {
+        "zip": "653",
+        "name": "口湖鄉"
+      },
+      {
+        "zip": "654",
+        "name": "四湖鄉"
+      },
+      {
+        "zip": "655",
+        "name": "元長鄉"
+      }
+    ],
+    "name": "雲林縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "700",
+        "name": "中西區"
+      },
+      {
+        "zip": "701",
+        "name": "東區"
+      },
+      {
+        "zip": "702",
+        "name": "南區"
+      },
+      {
+        "zip": "704",
+        "name": "北區"
+      },
+      {
+        "zip": "708",
+        "name": "安平區"
+      },
+      {
+        "zip": "709",
+        "name": "安南區"
+      },
+      {
+        "zip": "710",
+        "name": "永康區"
+      },
+      {
+        "zip": "711",
+        "name": "歸仁區"
+      },
+      {
+        "zip": "712",
+        "name": "新化區"
+      },
+      {
+        "zip": "713",
+        "name": "左鎮區"
+      },
+      {
+        "zip": "714",
+        "name": "玉井區"
+      },
+      {
+        "zip": "715",
+        "name": "楠西區"
+      },
+      {
+        "zip": "716",
+        "name": "南化區"
+      },
+      {
+        "zip": "717",
+        "name": "仁德區"
+      },
+      {
+        "zip": "718",
+        "name": "關廟區"
+      },
+      {
+        "zip": "719",
+        "name": "龍崎區"
+      },
+      {
+        "zip": "720",
+        "name": "官田區"
+      },
+      {
+        "zip": "721",
+        "name": "麻豆區"
+      },
+      {
+        "zip": "722",
+        "name": "佳里區"
+      },
+      {
+        "zip": "723",
+        "name": "西港區"
+      },
+      {
+        "zip": "724",
+        "name": "七股區"
+      },
+      {
+        "zip": "725",
+        "name": "將軍區"
+      },
+      {
+        "zip": "726",
+        "name": "學甲區"
+      },
+      {
+        "zip": "727",
+        "name": "北門區"
+      },
+      {
+        "zip": "730",
+        "name": "新營區"
+      },
+      {
+        "zip": "731",
+        "name": "後壁區"
+      },
+      {
+        "zip": "732",
+        "name": "白河區"
+      },
+      {
+        "zip": "733",
+        "name": "東山區"
+      },
+      {
+        "zip": "734",
+        "name": "六甲區"
+      },
+      {
+        "zip": "735",
+        "name": "下營區"
+      },
+      {
+        "zip": "736",
+        "name": "柳營區"
+      },
+      {
+        "zip": "737",
+        "name": "鹽水區"
+      },
+      {
+        "zip": "741",
+        "name": "善化區"
+      },
+      {
+        "zip": "744",
+        "name": "新市區"
+      },
+      {
+        "zip": "742",
+        "name": "大內區"
+      },
+      {
+        "zip": "743",
+        "name": "山上區"
+      },
+      {
+        "zip": "745",
+        "name": "安定區"
+      }
+    ],
+    "name": "臺南市"
+  },
+  {
+    "districts": [
+      {
+        "zip": "800",
+        "name": "新興區"
+      },
+      {
+        "zip": "801",
+        "name": "前金區"
+      },
+      {
+        "zip": "802",
+        "name": "苓雅區"
+      },
+      {
+        "zip": "803",
+        "name": "鹽埕區"
+      },
+      {
+        "zip": "804",
+        "name": "鼓山區"
+      },
+      {
+        "zip": "805",
+        "name": "旗津區"
+      },
+      {
+        "zip": "806",
+        "name": "前鎮區"
+      },
+      {
+        "zip": "807",
+        "name": "三民區"
+      },
+      {
+        "zip": "811",
+        "name": "楠梓區"
+      },
+      {
+        "zip": "812",
+        "name": "小港區"
+      },
+      {
+        "zip": "813",
+        "name": "左營區"
+      },
+      {
+        "zip": "814",
+        "name": "仁武區"
+      },
+      {
+        "zip": "815",
+        "name": "大社區"
+      },
+      {
+        "zip": "817",
+        "name": "東沙群島"
+      },
+      {
+        "zip": "819",
+        "name": "南沙群島"
+      },
+      {
+        "zip": "820",
+        "name": "岡山區"
+      },
+      {
+        "zip": "821",
+        "name": "路竹區"
+      },
+      {
+        "zip": "822",
+        "name": "阿蓮區"
+      },
+      {
+        "zip": "823",
+        "name": "田寮區"
+      },
+      {
+        "zip": "824",
+        "name": "燕巢區"
+      },
+      {
+        "zip": "825",
+        "name": "橋頭區"
+      },
+      {
+        "zip": "826",
+        "name": "梓官區"
+      },
+      {
+        "zip": "827",
+        "name": "彌陀區"
+      },
+      {
+        "zip": "828",
+        "name": "永安區"
+      },
+      {
+        "zip": "829",
+        "name": "湖內區"
+      },
+      {
+        "zip": "830",
+        "name": "鳳山區"
+      },
+      {
+        "zip": "831",
+        "name": "大寮區"
+      },
+      {
+        "zip": "832",
+        "name": "林園區"
+      },
+      {
+        "zip": "833",
+        "name": "鳥松區"
+      },
+      {
+        "zip": "840",
+        "name": "大樹區"
+      },
+      {
+        "zip": "842",
+        "name": "旗山區"
+      },
+      {
+        "zip": "843",
+        "name": "美濃區"
+      },
+      {
+        "zip": "844",
+        "name": "六龜區"
+      },
+      {
+        "zip": "845",
+        "name": "內門區"
+      },
+      {
+        "zip": "846",
+        "name": "杉林區"
+      },
+      {
+        "zip": "847",
+        "name": "甲仙區"
+      },
+      {
+        "zip": "848",
+        "name": "桃源區"
+      },
+      {
+        "zip": "849",
+        "name": "那瑪夏區"
+      },
+      {
+        "zip": "851",
+        "name": "茂林區"
+      },
+      {
+        "zip": "852",
+        "name": "茄萣區"
+      }
+    ],
+    "name": "高雄市"
+  },
+  {
+    "districts": [
+      {
+        "zip": "900",
+        "name": "屏東市"
+      },
+      {
+        "zip": "901",
+        "name": "三地門鄉"
+      },
+      {
+        "zip": "902",
+        "name": "霧臺鄉"
+      },
+      {
+        "zip": "903",
+        "name": "瑪家鄉"
+      },
+      {
+        "zip": "904",
+        "name": "九如鄉"
+      },
+      {
+        "zip": "905",
+        "name": "里港鄉"
+      },
+      {
+        "zip": "906",
+        "name": "高樹鄉"
+      },
+      {
+        "zip": "907",
+        "name": "鹽埔鄉"
+      },
+      {
+        "zip": "908",
+        "name": "長治鄉"
+      },
+      {
+        "zip": "909",
+        "name": "麟洛鄉"
+      },
+      {
+        "zip": "911",
+        "name": "竹田鄉"
+      },
+      {
+        "zip": "912",
+        "name": "內埔鄉"
+      },
+      {
+        "zip": "913",
+        "name": "萬丹鄉"
+      },
+      {
+        "zip": "920",
+        "name": "潮州鎮"
+      },
+      {
+        "zip": "921",
+        "name": "泰武鄉"
+      },
+      {
+        "zip": "922",
+        "name": "來義鄉"
+      },
+      {
+        "zip": "923",
+        "name": "萬巒鄉"
+      },
+      {
+        "zip": "924",
+        "name": "崁頂鄉"
+      },
+      {
+        "zip": "925",
+        "name": "新埤鄉"
+      },
+      {
+        "zip": "926",
+        "name": "南州鄉"
+      },
+      {
+        "zip": "927",
+        "name": "林邊鄉"
+      },
+      {
+        "zip": "928",
+        "name": "東港鎮"
+      },
+      {
+        "zip": "929",
+        "name": "琉球鄉"
+      },
+      {
+        "zip": "931",
+        "name": "佳冬鄉"
+      },
+      {
+        "zip": "932",
+        "name": "新園鄉"
+      },
+      {
+        "zip": "940",
+        "name": "枋寮鄉"
+      },
+      {
+        "zip": "941",
+        "name": "枋山鄉"
+      },
+      {
+        "zip": "942",
+        "name": "春日鄉"
+      },
+      {
+        "zip": "943",
+        "name": "獅子鄉"
+      },
+      {
+        "zip": "944",
+        "name": "車城鄉"
+      },
+      {
+        "zip": "945",
+        "name": "牡丹鄉"
+      },
+      {
+        "zip": "946",
+        "name": "恆春鎮"
+      },
+      {
+        "zip": "947",
+        "name": "滿州鄉"
+      }
+    ],
+    "name": "屏東縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "950",
+        "name": "臺東市"
+      },
+      {
+        "zip": "951",
+        "name": "綠島鄉"
+      },
+      {
+        "zip": "952",
+        "name": "蘭嶼鄉"
+      },
+      {
+        "zip": "953",
+        "name": "延平鄉"
+      },
+      {
+        "zip": "954",
+        "name": "卑南鄉"
+      },
+      {
+        "zip": "955",
+        "name": "鹿野鄉"
+      },
+      {
+        "zip": "956",
+        "name": "關山鎮"
+      },
+      {
+        "zip": "957",
+        "name": "海端鄉"
+      },
+      {
+        "zip": "958",
+        "name": "池上鄉"
+      },
+      {
+        "zip": "959",
+        "name": "東河鄉"
+      },
+      {
+        "zip": "961",
+        "name": "成功鎮"
+      },
+      {
+        "zip": "962",
+        "name": "長濱鄉"
+      },
+      {
+        "zip": "963",
+        "name": "太麻里鄉"
+      },
+      {
+        "zip": "964",
+        "name": "金峰鄉"
+      },
+      {
+        "zip": "965",
+        "name": "大武鄉"
+      },
+      {
+        "zip": "966",
+        "name": "達仁鄉"
+      }
+    ],
+    "name": "臺東縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "970",
+        "name": "花蓮市"
+      },
+      {
+        "zip": "971",
+        "name": "新城鄉"
+      },
+      {
+        "zip": "972",
+        "name": "秀林鄉"
+      },
+      {
+        "zip": "973",
+        "name": "吉安鄉"
+      },
+      {
+        "zip": "974",
+        "name": "壽豐鄉"
+      },
+      {
+        "zip": "975",
+        "name": "鳳林鎮"
+      },
+      {
+        "zip": "976",
+        "name": "光復鄉"
+      },
+      {
+        "zip": "977",
+        "name": "豐濱鄉"
+      },
+      {
+        "zip": "978",
+        "name": "瑞穗鄉"
+      },
+      {
+        "zip": "979",
+        "name": "萬榮鄉"
+      },
+      {
+        "zip": "981",
+        "name": "玉里鎮"
+      },
+      {
+        "zip": "982",
+        "name": "卓溪鄉"
+      },
+      {
+        "zip": "983",
+        "name": "富里鄉"
+      }
+    ],
+    "name": "花蓮縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "880",
+        "name": "馬公市"
+      },
+      {
+        "zip": "881",
+        "name": "西嶼鄉"
+      },
+      {
+        "zip": "882",
+        "name": "望安鄉"
+      },
+      {
+        "zip": "883",
+        "name": "七美鄉"
+      },
+      {
+        "zip": "884",
+        "name": "白沙鄉"
+      },
+      {
+        "zip": "885",
+        "name": "湖西鄉"
+      }
+    ],
+    "name": "澎湖縣"
+  },
+  {
+    "districts": [
+      {
+        "zip": "890",
+        "name": "金沙鎮"
+      },
+      {
+        "zip": "891",
+        "name": "金湖鎮"
+      },
+      {
+        "zip": "892",
+        "name": "金寧鄉"
+      },
+      {
+        "zip": "893",
+        "name": "金城鎮"
+      },
+      {
+        "zip": "894",
+        "name": "烈嶼鄉"
+      },
+      {
+        "zip": "896",
+        "name": "烏坵鄉"
+      }
+    ],
+    "name": "金門縣"
+  }
+]

+ 170 - 153
src/assets/css/style.css

@@ -28,8 +28,22 @@ legend {
 }
 }
 
 
 /* Additional Resets */
 /* Additional Resets */
+#hubspot-conversations-inline-iframe,
+#hubspot-messages-iframe-container {
+  width: 300px;
+  height: 1000px;
+  border: none;
+}
+
+#hubspot-messages-iframe-container .hubspot {
+  width: 300px;
+  height: 1000px !important;
+  font-size: 1em !important;
+}
+
 body {
 body {
   line-height: 1;
   line-height: 1;
+  font-size: 1em;
 }
 }
 
 
 ol,
 ol,
@@ -58,6 +72,15 @@ a {
   --yellow: #E4B662;
   --yellow: #E4B662;
 }
 }
 
 
+html {
+  font-size: 1em;
+}
+
+.gm-style-mtc div {
+  font-size: 1em !important;
+  box-sizing: border-box;
+}
+
 * {
 * {
   font-family: "Noto Sans TC", sans-serif;
   font-family: "Noto Sans TC", sans-serif;
 }
 }
@@ -75,7 +98,7 @@ h2 {
 }
 }
 
 
 input:focus-visible {
 input:focus-visible {
-  outline: 2px solid var(--sub-color);
+  outline: 0.125em solid var(--sub-color);
 }
 }
 
 
 .v-enter-active,
 .v-enter-active,
@@ -98,18 +121,18 @@ input:focus-visible {
 
 
 .mark {
 .mark {
   display: inline-block;
   display: inline-block;
-  margin-left: 1px;
+  margin-left: 0.0625em;
   color: red;
   color: red;
 }
 }
 
 
 @media (min-width: 1920px) {
 @media (min-width: 1920px) {
   .v-container {
   .v-container {
-    max-width: 1300px !important;
+    max-width: 81.25em !important;
   }
   }
 }
 }
 @media (max-width: 1300px) {
 @media (max-width: 1300px) {
   .v-container {
   .v-container {
-    padding: 15px 30px !important;
+    padding: 0.9375em 1.875em !important;
   }
   }
 }
 }
 
 
@@ -129,30 +152,30 @@ input:focus-visible {
   }
   }
 }
 }
 .search input {
 .search input {
-  max-width: 250px;
-  padding: 5px 15px;
-  font-size: 16px;
-  border-radius: 100px;
-  border: 1px solid #ccc;
+  max-width: 15.625em;
+  padding: 0.3125em 0.9375em;
+  font-size: 1em;
+  border-radius: 6.25em;
+  border: 0.0625em solid #ccc;
   background-color: #fff;
   background-color: #fff;
 }
 }
 .search button {
 .search button {
   position: absolute;
   position: absolute;
-  right: 10px;
+  right: 0.625em;
   left: 0;
   left: 0;
-  top: 3px;
+  top: 0.1875em;
 }
 }
 .search button img {
 .search button img {
-  width: 25px;
+  width: 1.5625em;
   position: absolute;
   position: absolute;
-  top: 5px;
+  top: 0.1em;
   right: 0;
   right: 0;
 }
 }
 .search .error {
 .search .error {
   position: absolute;
   position: absolute;
-  right: 30px;
-  bottom: -30px;
-  font-size: 14px;
+  right: 1.875em;
+  bottom: -1.875em;
+  font-size: 0.875em;
 }
 }
 
 
 .college-bg-img {
 .college-bg-img {
@@ -165,7 +188,7 @@ input:focus-visible {
 }
 }
 
 
 .college-banner {
 .college-banner {
-  margin-top: 25px;
+  margin-top: 1.5625em;
   display: flex;
   display: flex;
   justify-content: center;
   justify-content: center;
   position: relative;
   position: relative;
@@ -178,17 +201,17 @@ input:focus-visible {
 }
 }
 @media (max-width: 475px) {
 @media (max-width: 475px) {
   .college-banner img {
   .college-banner img {
-    height: 300px;
+    height: 18.75em;
     -o-object-fit: cover;
     -o-object-fit: cover;
        object-fit: cover;
        object-fit: cover;
     -o-object-position: left;
     -o-object-position: left;
        object-position: left;
        object-position: left;
-    border-radius: 10px 10px 0 0;
+    border-radius: 0.625em 0.625em 0 0;
   }
   }
 }
 }
 .college-banner .description-item {
 .college-banner .description-item {
   position: absolute;
   position: absolute;
-  right: 15px;
+  right: 0.9375em;
   bottom: 28%;
   bottom: 28%;
   z-index: 1000;
   z-index: 1000;
 }
 }
@@ -209,67 +232,67 @@ input:focus-visible {
 }
 }
 .college-banner .description-item h1 {
 .college-banner .description-item h1 {
   text-align: end;
   text-align: end;
-  margin-bottom: 35px;
-  font-size: 40px;
+  margin-bottom: 2.1875em;
+  font-size: 2.5em;
   font-weight: 500;
   font-weight: 500;
-  text-shadow: 2px 2px 10px #333;
+  text-shadow: 0.125em 0.125em 0.625em #333;
   word-wrap: break-word;
   word-wrap: break-word;
 }
 }
 @media (max-width: 1280px) {
 @media (max-width: 1280px) {
   .college-banner .description-item h1 {
   .college-banner .description-item h1 {
-    margin-bottom: 20px;
-    font-size: 36px;
+    margin-bottom: 1.25em;
+    font-size: 2.25em;
   }
   }
 }
 }
 @media (max-width: 960px) {
 @media (max-width: 960px) {
   .college-banner .description-item h1 {
   .college-banner .description-item h1 {
-    font-size: 32px;
+    font-size: 2em;
   }
   }
 }
 }
 @media (max-width: 600px) {
 @media (max-width: 600px) {
   .college-banner .description-item h1 {
   .college-banner .description-item h1 {
-    font-size: 24px;
-    margin-bottom: 15px;
+    font-size: 1.5em;
+    margin-bottom: 0.9375em;
   }
   }
 }
 }
 .college-banner .description-item p {
 .college-banner .description-item p {
-  width: 515px;
-  font-size: 18px;
-  line-height: 30px;
-  text-shadow: 2px 2px 4px #333;
+  width: 32.1875em;
+  font-size: 1.125em;
+  line-height: 1.875em;
+  text-shadow: 0.125em 0.125em 0.25em #333;
 }
 }
 @media (max-width: 1280px) {
 @media (max-width: 1280px) {
   .college-banner .description-item p {
   .college-banner .description-item p {
-    font-size: 16px;
+    font-size: 1em;
   }
   }
 }
 }
 @media (max-width: 600px) {
 @media (max-width: 600px) {
   .college-banner .description-item p {
   .college-banner .description-item p {
-    width: 270px;
-    font-size: 16px;
-    line-height: 22px;
+    width: 16.875em;
+    font-size: 1em;
+    line-height: 1.375em;
   }
   }
 }
 }
 @media (max-width: 600px) {
 @media (max-width: 600px) {
   .college-banner .description-item p {
   .college-banner .description-item p {
-    font-size: 14px;
+    font-size: 0.875em;
   }
   }
 }
 }
 .college-banner .description-item h1,
 .college-banner .description-item h1,
 .college-banner .description-item p {
 .college-banner .description-item p {
   color: #fff;
   color: #fff;
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .cooming-soon {
 .cooming-soon {
-  font-size: 20px;
+  font-size: 1.25em;
   color: var(--gray);
   color: var(--gray);
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .college-content {
 .college-content {
   padding: 0;
   padding: 0;
-  width: 1300px !important;
+  width: 81.25em !important;
   position: relative;
   position: relative;
 }
 }
 @media (max-width: 600px) {
 @media (max-width: 600px) {
@@ -278,7 +301,7 @@ input:focus-visible {
   }
   }
 }
 }
 .college-content .main-block {
 .college-content .main-block {
-  padding: 150px 80px;
+  padding: 9.375em 5em;
   margin-top: -21%;
   margin-top: -21%;
   background-image: url("@/assets/img/course/background.png");
   background-image: url("@/assets/img/course/background.png");
   background-size: cover;
   background-size: cover;
@@ -289,34 +312,34 @@ input:focus-visible {
 }
 }
 @media (max-width: 960px) {
 @media (max-width: 960px) {
   .college-content .main-block {
   .college-content .main-block {
-    padding: 100px 50px;
+    padding: 6.25em 3.125em;
     margin-top: -22%;
     margin-top: -22%;
     background-position: 0 1vw;
     background-position: 0 1vw;
   }
   }
 }
 }
 @media (max-width: 600px) {
 @media (max-width: 600px) {
   .college-content .main-block {
   .college-content .main-block {
-    padding: 50px 20px;
+    padding: 3.125em 1.25em;
     margin-top: -24%;
     margin-top: -24%;
   }
   }
 }
 }
 .college-content .main-block.life {
 .college-content .main-block.life {
-  padding: 50px 80px;
-  margin-top: 20px;
+  padding: 3.125em 5em;
+  margin-top: 1.25em;
   background-image: none;
   background-image: none;
   background-color: #fff;
   background-color: #fff;
-  border-radius: 20px;
+  border-radius: 1.25em;
 }
 }
 .college-content .main-block .title {
 .college-content .main-block .title {
-  padding: 80px 0;
-  font-size: 30px;
-  line-height: 32px;
-  letter-spacing: 1px;
+  padding: 3em 0;
+  font-size: 1.875em;
+  line-height: 2em;
+  letter-spacing: 0.0625em;
 }
 }
 @media (max-width: 960px) {
 @media (max-width: 960px) {
   .college-content .main-block .title {
   .college-content .main-block .title {
-    padding: 50px 0;
-    font-size: 24px;
+    padding: 3.125em 0;
+    font-size: 1.5em;
   }
   }
 }
 }
 @media (max-width: 600px) {
 @media (max-width: 600px) {
@@ -336,8 +359,8 @@ input:focus-visible {
 }
 }
 
 
 .tab-btn button {
 .tab-btn button {
-  height: 45px !important;
-  font-size: 28px;
+  height: 2em !important;
+  font-size: 1.75em;
   font-weight: 500;
   font-weight: 500;
   color: #ccc;
   color: #ccc;
 }
 }
@@ -347,27 +370,27 @@ input:focus-visible {
 
 
 .main-card {
 .main-card {
   height: 100%;
   height: 100%;
-  letter-spacing: 1px;
-  border-radius: 10px;
-  box-shadow: 2px 2px 10px #aaaaaa;
+  letter-spacing: 0.0625em;
+  border-radius: 0.625em;
+  box-shadow: 0.125em 0.125em 0.625em #aaaaaa;
   background-color: var(--sub-color);
   background-color: var(--sub-color);
 }
 }
 .main-card .card-title {
 .main-card .card-title {
-  height: 15%;
-  padding: 15px;
+  height: 75px;
+  padding: 0.9375em;
   display: flex;
   display: flex;
   justify-content: center;
   justify-content: center;
   align-items: center;
   align-items: center;
-  border-bottom: 2px solid #fff;
+  border-bottom: 0.125em solid #fff;
 }
 }
 .main-card .card-title h3 {
 .main-card .card-title h3 {
-  font-size: 16px;
+  font-size: 1em;
   font-weight: 400;
   font-weight: 400;
   text-align: center;
   text-align: center;
 }
 }
 .main-card .card-title h3,
 .main-card .card-title h3,
 .main-card .card-info p {
 .main-card .card-info p {
-  line-height: 24px;
+  line-height: 1.5em;
   overflow: hidden;
   overflow: hidden;
   text-overflow: ellipsis;
   text-overflow: ellipsis;
   display: -webkit-box;
   display: -webkit-box;
@@ -385,8 +408,7 @@ input:focus-visible {
   font-weight: 400;
   font-weight: 400;
 }
 }
 .main-card .card-info {
 .main-card .card-info {
-  height: 85%;
-  padding: 15px;
+  padding: 0.9375em;
   display: flex;
   display: flex;
   flex-direction: column;
   flex-direction: column;
   position: relative;
   position: relative;
@@ -401,62 +423,56 @@ input:focus-visible {
   height: 100%;
   height: 100%;
   display: flex;
   display: flex;
   flex-direction: column;
   flex-direction: column;
-  padding: 10px;
+  padding: 0.625em;
 }
 }
 .main-card .card-info span {
 .main-card .card-info span {
-  height: 60px;
+  height: 3.75em;
 }
 }
 .main-card .card-info span p {
 .main-card .card-info span p {
-  line-height: 20px;
+  line-height: 1.25em;
 }
 }
 
 
 .dot-item span {
 .dot-item span {
   position: absolute;
   position: absolute;
   display: block;
   display: block;
-  width: 15px;
-  height: 15px;
-  border-radius: 100px;
+  width: 0.9375em;
+  height: 0.9375em;
+  border-radius: 6.25em;
   background-color: var(--blue);
   background-color: var(--blue);
 }
 }
 .dot-item .t-dot {
 .dot-item .t-dot {
-  top: 15px;
-  left: 15px;
+  top: 0.9375em;
+  left: 0.9375em;
 }
 }
 .dot-item .r-dot {
 .dot-item .r-dot {
-  top: 15px;
-  right: 15px;
+  top: 0.9375em;
+  right: 0.9375em;
 }
 }
 .dot-item .b-dot {
 .dot-item .b-dot {
-  bottom: 15px;
-  right: 15px;
+  bottom: 0.9375em;
+  right: 0.9375em;
 }
 }
 .dot-item .l-dot {
 .dot-item .l-dot {
-  bottom: 15px;
-  left: 15px;
+  bottom: 0.9375em;
+  left: 0.9375em;
 }
 }
 
 
 .hint-item {
 .hint-item {
   width: 100%;
   width: 100%;
-  max-width: 500px;
+  max-width: 31.25em;
   display: block;
   display: block;
-  padding: 20px;
-  margin: 30px auto 0;
-  border-radius: 10px;
-  box-shadow: 2px 2px 8px #ccc;
-  border: 1px solid var(--purple);
-  letter-spacing: 2px;
+  padding: 1.25em;
+  margin: 1.875em auto 0;
+  border-radius: 0.625em;
+  box-shadow: 0.125em 0.125em 0.5em #ccc;
+  border: 0.0625em solid var(--purple);
+  letter-spacing: 0.125em;
   text-align: center;
   text-align: center;
-  line-height: 26px;
+  line-height: 1.625em;
   transition: all 0.3s;
   transition: all 0.3s;
 }
 }
 .hint-item:hover {
 .hint-item:hover {
-  box-shadow: 2px 2px 12px #bcbcbc;
-}
-
-.favorites-btn {
-  position: absolute;
-  bottom: 15px;
-  right: 15px;
+  box-shadow: 0.125em 0.125em 0.75em #bcbcbc;
 }
 }
 
 
 .progress-item {
 .progress-item {
@@ -473,12 +489,12 @@ input:focus-visible {
   justify-content: center;
   justify-content: center;
   width: 100%;
   width: 100%;
   color: var(--purple);
   color: var(--purple);
-  border: 1px solid var(--purple);
-  border-radius: 10px;
+  border: 0.0625em solid var(--purple);
+  border-radius: 0.625em;
   text-align: center;
   text-align: center;
   transition: all 0.3s;
   transition: all 0.3s;
-  line-height: 24px;
-  letter-spacing: 1px;
+  line-height: 1.5em;
+  letter-spacing: 0.0625em;
 }
 }
 .tag-btn .item:hover {
 .tag-btn .item:hover {
   color: #fff;
   color: #fff;
@@ -486,45 +502,45 @@ input:focus-visible {
   background-color: var(--purple);
   background-color: var(--purple);
 }
 }
 .tag-btn .item h3 {
 .tag-btn .item h3 {
-  padding: 10px;
   font-weight: 500;
   font-weight: 500;
   word-break: keep-all;
   word-break: keep-all;
 }
 }
 
 
 .hint {
 .hint {
-  font-size: 14px;
+  display: block;
+  font-size: 0.875em;
   color: #919191;
   color: #919191;
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .total-item {
 .total-item {
-  margin-top: 15px;
+  margin-top: 0.9375em;
   display: block;
   display: block;
-  font-size: 14px;
-  letter-spacing: 2px;
+  font-size: 0.875em;
+  letter-spacing: 0.125em;
   text-align: center;
   text-align: center;
 }
 }
 
 
 .filter-list .v-select {
 .filter-list .v-select {
-  margin-bottom: 10px;
+  margin-bottom: 0.625em;
 }
 }
 .filter-list .v-select .v-field {
 .filter-list .v-select .v-field {
   overflow: hidden;
   overflow: hidden;
 }
 }
 .filter-list .v-select .v-field__overlay {
 .filter-list .v-select .v-field__overlay {
   opacity: 1 !important;
   opacity: 1 !important;
-  border: 1px solid #ccc;
+  border: 0.0625em solid #ccc;
   background-color: #fff;
   background-color: #fff;
-  border-radius: 100px !important;
+  border-radius: 6.25em !important;
 }
 }
 .filter-list .v-select .v-field__outline {
 .filter-list .v-select .v-field__outline {
   display: none;
   display: none;
 }
 }
 .filter-list .v-select .v-field__input {
 .filter-list .v-select .v-field__input {
-  padding-top: 15px;
+  padding-top: 0.9375em;
 }
 }
 .filter-list .v-select .v-field__field {
 .filter-list .v-select .v-field__field {
-  height: 45px;
+  height: 2.8125em;
 }
 }
 .filter-list .v-select .v-select__selection {
 .filter-list .v-select .v-select__selection {
   overflow: hidden;
   overflow: hidden;
@@ -533,7 +549,7 @@ input:focus-visible {
   white-space: nowrap;
   white-space: nowrap;
 }
 }
 .filter-list .v-select .v-label.v-field-label--floating {
 .filter-list .v-select .v-label.v-field-label--floating {
-  top: 3px !important;
+  top: 0.1875em !important;
 }
 }
 
 
 .trave-content .info,
 .trave-content .info,
@@ -548,7 +564,7 @@ input:focus-visible {
 .hope-content .info section {
 .hope-content .info section {
   margin: auto;
   margin: auto;
   position: absolute;
   position: absolute;
-  bottom: 15px;
+  bottom: 0.9375em;
   right: 0;
   right: 0;
   left: 0;
   left: 0;
 }
 }
@@ -565,7 +581,7 @@ input:focus-visible {
 .hope-content .info p,
 .hope-content .info p,
 .exhibit-content .info h3,
 .exhibit-content .info h3,
 .exhibit-content .info p {
 .exhibit-content .info p {
-  line-height: 20px;
+  line-height: 1.25em;
   overflow: hidden;
   overflow: hidden;
   text-overflow: ellipsis;
   text-overflow: ellipsis;
   display: -webkit-box;
   display: -webkit-box;
@@ -580,8 +596,8 @@ input:focus-visible {
 .trave-content .info p,
 .trave-content .info p,
 .hope-content .info p,
 .hope-content .info p,
 .exhibit-content .info p {
 .exhibit-content .info p {
-  max-width: 220px;
-  margin-top: 5px;
+  max-width: 13.75em;
+  margin-top: 0.3125em;
   -webkit-line-clamp: 2;
   -webkit-line-clamp: 2;
 }
 }
 
 
@@ -589,18 +605,18 @@ input:focus-visible {
 .hope-content h4,
 .hope-content h4,
 .exhibit-content h4,
 .exhibit-content h4,
 .campus-content h4 {
 .campus-content h4 {
-  margin-bottom: 20px;
+  margin-bottom: 1.25em;
   font-weight: 400;
   font-weight: 400;
-  font-size: 20px;
-  letter-spacing: 1px;
-  line-height: 32px;
+  font-size: 1.25em;
+  letter-spacing: 0.0625em;
+  line-height: 2em;
 }
 }
 .trave-content p,
 .trave-content p,
 .hope-content p,
 .hope-content p,
 .exhibit-content p,
 .exhibit-content p,
 .campus-content p {
 .campus-content p {
-  line-height: 28px;
-  letter-spacing: 1px;
+  line-height: 1.75em;
+  letter-spacing: 0.0625em;
 }
 }
 .trave-content .info section,
 .trave-content .info section,
 .hope-content .info section,
 .hope-content .info section,
@@ -609,53 +625,53 @@ input:focus-visible {
   display: flex;
   display: flex;
   flex-direction: column;
   flex-direction: column;
   align-items: center;
   align-items: center;
-  padding: 10px;
-  border-radius: 5px;
+  padding: 0.625em;
+  border-radius: 0.3125em;
   background: rgba(218, 182, 214, 0.8);
   background: rgba(218, 182, 214, 0.8);
 }
 }
 .trave-content .info section h3,
 .trave-content .info section h3,
 .hope-content .info section h3,
 .hope-content .info section h3,
 .exhibit-content .info section h3,
 .exhibit-content .info section h3,
 .campus-content .info section h3 {
 .campus-content .info section h3 {
-  margin: 5px;
+  margin: 0.3125em;
   font-weight: 400;
   font-weight: 400;
-  line-height: 22px;
-  letter-spacing: 1px;
+  line-height: 1.375em;
+  letter-spacing: 0.0625em;
 }
 }
 .trave-content .info section p,
 .trave-content .info section p,
 .hope-content .info section p,
 .hope-content .info section p,
 .exhibit-content .info section p,
 .exhibit-content .info section p,
 .campus-content .info section p {
 .campus-content .info section p {
-  font-size: 12px;
+  font-size: 0.75em;
 }
 }
 
 
 .link-btn {
 .link-btn {
   margin-top: auto;
   margin-top: auto;
   margin-left: auto;
   margin-left: auto;
   display: inline-block;
   display: inline-block;
-  padding: 8px 20px;
-  border-radius: 100px;
-  line-height: 24px;
+  padding: 0.5em 1.25em;
+  border-radius: 6.25em;
+  line-height: 1.5em;
   text-align: center;
   text-align: center;
   color: #fff;
   color: #fff;
   background-color: var(--brown);
   background-color: var(--brown);
-  border: 2px solid transparent;
+  border: 0.125em solid transparent;
   transition: all 0.5s;
   transition: all 0.5s;
 }
 }
 .link-btn:hover {
 .link-btn:hover {
   color: var(--brown);
   color: var(--brown);
-  border: 2px solid var(--brown);
+  border: 0.125em solid var(--brown);
   background-color: #fff;
   background-color: #fff;
 }
 }
 
 
 .download-link {
 .download-link {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
-  padding: 10px 20px;
-  font-size: 14px;
-  letter-spacing: 1px;
+  padding: 0.625em 1.25em;
+  font-size: 0.875em;
+  letter-spacing: 0.0625em;
   color: #fff;
   color: #fff;
-  border-radius: 100px;
+  border-radius: 6.25em;
   background-color: var(--brown);
   background-color: var(--brown);
   transition: all 0.3s;
   transition: all 0.3s;
 }
 }
@@ -665,11 +681,12 @@ input:focus-visible {
 
 
 .main-table {
 .main-table {
   overflow-x: auto;
   overflow-x: auto;
+  letter-spacing: 1px;
 }
 }
 .main-table .table-title {
 .main-table .table-title {
-  padding: 10px;
+  padding: 0.625em;
   color: #fff;
   color: #fff;
-  font-size: 20px;
+  font-size: 1.25em;
   font-weight: 400;
   font-weight: 400;
   text-align: center;
   text-align: center;
 }
 }
@@ -680,7 +697,7 @@ input:focus-visible {
 }
 }
 .main-table table {
 .main-table table {
   width: 100%;
   width: 100%;
-  margin-bottom: 20px;
+  margin-bottom: 1.25em;
   position: relative;
   position: relative;
   border-collapse: collapse;
   border-collapse: collapse;
 }
 }
@@ -690,36 +707,36 @@ input:focus-visible {
   }
   }
 }
 }
 .main-table table thead th {
 .main-table table thead th {
-  padding: 20px 0;
+  padding: 1.25em 0;
   font-weight: 500;
   font-weight: 500;
 }
 }
 .main-table table tbody td {
 .main-table table tbody td {
-  padding: 20px 0;
+  padding: 1.25em 0;
   text-align: center;
   text-align: center;
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .v-chip {
 .v-chip {
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .v-pagination {
 .v-pagination {
   margin: auto;
   margin: auto;
-  max-width: 500px;
+  max-width: 31.25em;
 }
 }
 
 
 ::-webkit-scrollbar {
 ::-webkit-scrollbar {
-  width: 10px;
+  width: 0.625em;
 }
 }
 
 
 ::-webkit-scrollbar-track {
 ::-webkit-scrollbar-track {
   background: #f1f1f1;
   background: #f1f1f1;
-  border-radius: 10px;
+  border-radius: 0.625em;
 }
 }
 
 
 ::-webkit-scrollbar-thumb {
 ::-webkit-scrollbar-thumb {
   background: #b6b6b6;
   background: #b6b6b6;
-  border-radius: 10px;
+  border-radius: 0.625em;
 }
 }
 
 
 ::-webkit-scrollbar-thumb:hover {
 ::-webkit-scrollbar-thumb:hover {
@@ -727,7 +744,7 @@ input:focus-visible {
 }
 }
 
 
 .dp__input {
 .dp__input {
-  padding: 15px 40px;
+  padding: 0.9375em 2.5em;
   background-color: #f5f5f5;
   background-color: #f5f5f5;
 }
 }
 
 
@@ -736,21 +753,21 @@ input:focus-visible {
 }
 }
 
 
 .dp__calendar_item {
 .dp__calendar_item {
-  padding: 5px;
+  padding: 0.3125em;
 }
 }
 
 
 .dp__calendar_header_item {
 .dp__calendar_header_item {
-  font-size: 14px;
+  font-size: 0.875em;
 }
 }
 
 
 .dp__action_button {
 .dp__action_button {
   height: auto;
   height: auto;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
-  padding: 10px !important;
-  margin: 0 5px;
-  font-size: 14px;
-  letter-spacing: 1px;
+  padding: 0.625em !important;
+  margin: 0 0.3125em;
+  font-size: 0.875em;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .v-breadcrumbs-item--link {
 .v-breadcrumbs-item--link {

File diff suppressed because it is too large
+ 0 - 0
src/assets/css/style.css.map


+ 183 - 156
src/assets/css/style.scss

@@ -30,8 +30,23 @@ legend {
 
 
 /* Additional Resets */
 /* Additional Resets */
 
 
+
+#hubspot-conversations-inline-iframe,
+#hubspot-messages-iframe-container {
+  width: 300px;
+  height: 1000px;
+  border: none;
+}
+
+#hubspot-messages-iframe-container .hubspot {
+  width: 300px;
+  height: 1000px !important;
+  font-size: 1em !important;
+}
+
 body {
 body {
   line-height: 1;
   line-height: 1;
+  font-size: 1em;
 }
 }
 
 
 ol,
 ol,
@@ -61,6 +76,16 @@ a {
   --yellow: #E4B662; // 大地黃
   --yellow: #E4B662; // 大地黃
 }
 }
 
 
+html {
+  font-size: 1em;
+}
+
+.gm-style-mtc div {
+  font-size: 1em !important;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box
+}
+
 * {
 * {
   font-family: 'Noto Sans TC', sans-serif;
   font-family: 'Noto Sans TC', sans-serif;
 }
 }
@@ -78,7 +103,7 @@ h2 {
 }
 }
 
 
 input:focus-visible {
 input:focus-visible {
-  outline: 2px solid (var(--sub-color));
+  outline: 0.125em solid (var(--sub-color));
 }
 }
 
 
 // Vue Transition
 // Vue Transition
@@ -103,17 +128,17 @@ input:focus-visible {
 
 
 .mark {
 .mark {
   display: inline-block;
   display: inline-block;
-  margin-left: 1px;
+  margin-left: 0.0625em;
   color: red;
   color: red;
 }
 }
 
 
 .v-container {
 .v-container {
   @media (min-width: 1920px) {
   @media (min-width: 1920px) {
-    max-width: 1300px !important;
+    max-width: 81.25em !important;
   }
   }
 
 
   @media (max-width: 1300px) {
   @media (max-width: 1300px) {
-    padding: 15px 30px !important;
+    padding: 0.9375em 1.875em !important;
   }
   }
 }
 }
 
 
@@ -133,33 +158,33 @@ input:focus-visible {
   }
   }
 
 
   input {
   input {
-    max-width: 250px;
-    padding: 5px 15px;
-    font-size: 16px;
-    border-radius: 100px;
-    border: 1px solid #ccc;
+    max-width: 15.625em;
+    padding: 0.3125em 0.9375em;
+    font-size: 1em;
+    border-radius: 6.25em;
+    border: 0.0625em solid #ccc;
     background-color: #fff;
     background-color: #fff;
   }
   }
 
 
   button {
   button {
     position: absolute;
     position: absolute;
-    right: 10px;
+    right: 0.625em;
     left: 0;
     left: 0;
-    top: 3px;
+    top: 0.1875em;
 
 
     img {
     img {
-      width: 25px;
+      width: 1.5625em;
       position: absolute;
       position: absolute;
-      top: 5px;
+      top: 0.1em;
       right: 0;
       right: 0;
     }
     }
   }
   }
 
 
   .error {
   .error {
     position: absolute;
     position: absolute;
-    right: 30px;
-    bottom: -30px;
-    font-size: 14px;
+    right: 1.875em;
+    bottom: -1.875em;
+    font-size: 0.875em;
   }
   }
 }
 }
 
 
@@ -173,7 +198,7 @@ input:focus-visible {
 }
 }
 
 
 .college-banner {
 .college-banner {
-  margin-top: 25px;
+  margin-top: 1.5625em;
   display: flex;
   display: flex;
   justify-content: center;
   justify-content: center;
   position: relative;
   position: relative;
@@ -185,16 +210,16 @@ input:focus-visible {
     width: 100%;
     width: 100%;
 
 
     @media (max-width: 475px) {
     @media (max-width: 475px) {
-      height: 300px;
+      height: 18.75em;
       object-fit: cover;
       object-fit: cover;
       object-position: left;
       object-position: left;
-      border-radius: 10px 10px 0 0;
+      border-radius: 0.625em 0.625em 0 0;
     }
     }
   }
   }
 
 
   .description-item {
   .description-item {
     position: absolute;
     position: absolute;
-    right: 15px;
+    right: 0.9375em;
     bottom: 28%;
     bottom: 28%;
     z-index: 1000;
     z-index: 1000;
 
 
@@ -212,65 +237,65 @@ input:focus-visible {
 
 
     h1 {
     h1 {
       text-align: end;
       text-align: end;
-      margin-bottom: 35px;
-      font-size: 40px;
+      margin-bottom: 2.1875em;
+      font-size: 2.5em;
       font-weight: 500;
       font-weight: 500;
-      text-shadow: 2px 2px 10px #333;
+      text-shadow: 0.125em 0.125em 0.625em #333;
       word-wrap: break-word;
       word-wrap: break-word;
 
 
       @media (max-width: 1280px) {
       @media (max-width: 1280px) {
-        margin-bottom: 20px;
-        font-size: 36px;
+        margin-bottom: 1.25em;
+        font-size: 2.25em;
       }
       }
 
 
       @media (max-width: 960px) {
       @media (max-width: 960px) {
-        font-size: 32px;
+        font-size: 2em;
       }
       }
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 24px;
-        margin-bottom: 15px;
+        font-size: 1.5em;
+        margin-bottom: 0.9375em;
       }
       }
     }
     }
 
 
     p {
     p {
-      width: 515px;
-      font-size: 18px;
-      line-height: 30px;
-      text-shadow: 2px 2px 4px #333;
+      width: 32.1875em;
+      font-size: 1.125em;
+      line-height: 1.875em;
+      text-shadow: 0.125em 0.125em 0.25em #333;
 
 
       @media (max-width: 1280px) {
       @media (max-width: 1280px) {
-        font-size: 16px;
+        font-size: 1em;
       }
       }
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        width: 270px;
-        font-size: 16px;
-        line-height: 22px;
+        width: 16.875em;
+        font-size: 1em;
+        line-height: 1.375em;
       }
       }
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 14px;
+        font-size: 0.875em;
       }
       }
     }
     }
 
 
     h1,
     h1,
     p {
     p {
       color: #fff;
       color: #fff;
-      letter-spacing: 1px;
+      letter-spacing: 0.0625em;
     }
     }
   }
   }
 }
 }
 
 
 .cooming-soon {
 .cooming-soon {
-  font-size: 20px;
+  font-size: 1.25em;
   color: var(--gray);
   color: var(--gray);
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .college-content {
 .college-content {
   padding: 0;
   padding: 0;
-  width: 1300px !important;
+  width: 81.25em !important;
   position: relative;
   position: relative;
 
 
   @media (max-width: 600px) {
   @media (max-width: 600px) {
@@ -278,7 +303,7 @@ input:focus-visible {
   }
   }
 
 
   .main-block {
   .main-block {
-    padding: 150px 80px;
+    padding: 9.375em 5em;
     margin-top: -21%;
     margin-top: -21%;
     background-image: url('@/assets/img/course/background.png');
     background-image: url('@/assets/img/course/background.png');
     background-size: cover;
     background-size: cover;
@@ -288,33 +313,33 @@ input:focus-visible {
     z-index: 10;
     z-index: 10;
 
 
     @media (max-width: 960px) {
     @media (max-width: 960px) {
-      padding: 100px 50px;
+      padding: 6.25em 3.125em;
       margin-top: -22%;
       margin-top: -22%;
       background-position: 0 1vw;
       background-position: 0 1vw;
     }
     }
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      padding: 50px 20px;
+      padding: 3.125em 1.25em;
       margin-top: -24%;
       margin-top: -24%;
     }
     }
 
 
     &.life {
     &.life {
-      padding: 50px 80px;
-      margin-top: 20px;
+      padding: 3.125em 5em;
+      margin-top: 1.25em;
       background-image: none;
       background-image: none;
       background-color: #fff;
       background-color: #fff;
-      border-radius: 20px;
+      border-radius: 1.25em;
     }
     }
 
 
     .title {
     .title {
-      padding: 80px 0;
-      font-size: 30px;
-      line-height: 32px;
-      letter-spacing: 1px;
+      padding: 3em 0;
+      font-size: 1.875em;
+      line-height: 2em;
+      letter-spacing: 0.0625em;
 
 
       @media (max-width: 960px) {
       @media (max-width: 960px) {
-        padding: 50px 0;
-        font-size: 24px;
+        padding: 3.125em 0;
+        font-size: 1.5em;
       }
       }
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
@@ -336,8 +361,8 @@ input:focus-visible {
 
 
 .tab-btn {
 .tab-btn {
   button {
   button {
-    height: 45px !important;
-    font-size: 28px;
+    height: 2em !important;
+    font-size: 1.75em;
     font-weight: 500;
     font-weight: 500;
     color: #ccc;
     color: #ccc;
 
 
@@ -349,21 +374,21 @@ input:focus-visible {
 
 
 .main-card {
 .main-card {
   height: 100%;
   height: 100%;
-  letter-spacing: 1px;
-  border-radius: 10px;
-  box-shadow: 2px 2px 10px #aaaaaa;
+  letter-spacing: 0.0625em;
+  border-radius: 0.625em;
+  box-shadow: 0.125em 0.125em 0.625em #aaaaaa;
   background-color: var(--sub-color);
   background-color: var(--sub-color);
 
 
   .card-title {
   .card-title {
-    height: 15%;
-    padding: 15px;
+    height: 75px;
+    padding: 0.9375em;
     display: flex;
     display: flex;
     justify-content: center;
     justify-content: center;
     align-items: center;
     align-items: center;
-    border-bottom: 2px solid #fff;
+    border-bottom: 0.125em solid #fff;
 
 
     h3 {
     h3 {
-      font-size: 16px;
+      font-size: 1em;
       font-weight: 400;
       font-weight: 400;
       text-align: center;
       text-align: center;
     }
     }
@@ -371,7 +396,7 @@ input:focus-visible {
 
 
   .card-title h3,
   .card-title h3,
   .card-info p {
   .card-info p {
-    line-height: 24px;
+    line-height: 1.5em;
     // 超過兩行則省略
     // 超過兩行則省略
     overflow: hidden;
     overflow: hidden;
     text-overflow: ellipsis;
     text-overflow: ellipsis;
@@ -394,8 +419,8 @@ input:focus-visible {
   }
   }
 
 
   .card-info {
   .card-info {
-    height: 85%;
-    padding: 15px;
+    // height: 85%;
+    padding: 0.9375em;
     display: flex;
     display: flex;
     flex-direction: column;
     flex-direction: column;
     position: relative;
     position: relative;
@@ -412,14 +437,14 @@ input:focus-visible {
       height: 100%;
       height: 100%;
       display: flex;
       display: flex;
       flex-direction: column;
       flex-direction: column;
-      padding: 10px;
+      padding: 0.625em;
     }
     }
 
 
     span {
     span {
-      height: 60px;
+      height: 3.75em;
 
 
       p {
       p {
-        line-height: 20px;
+        line-height: 1.25em;
       }
       }
     }
     }
   }
   }
@@ -429,59 +454,59 @@ input:focus-visible {
   span {
   span {
     position: absolute;
     position: absolute;
     display: block;
     display: block;
-    width: 15px;
-    height: 15px;
-    border-radius: 100px;
+    width: 0.9375em;
+    height: 0.9375em;
+    border-radius: 6.25em;
     background-color: var(--blue);
     background-color: var(--blue);
   }
   }
 
 
   .t-dot {
   .t-dot {
-    top: 15px;
-    left: 15px;
+    top: 0.9375em;
+    left: 0.9375em;
   }
   }
 
 
   .r-dot {
   .r-dot {
-    top: 15px;
-    right: 15px;
+    top: 0.9375em;
+    right: 0.9375em;
   }
   }
 
 
   .b-dot {
   .b-dot {
-    bottom: 15px;
-    right: 15px;
+    bottom: 0.9375em;
+    right: 0.9375em;
   }
   }
 
 
   .l-dot {
   .l-dot {
-    bottom: 15px;
-    left: 15px;
+    bottom: 0.9375em;
+    left: 0.9375em;
   }
   }
 }
 }
 
 
 .hint-item {
 .hint-item {
   width: 100%;
   width: 100%;
-  max-width: 500px;
+  max-width: 31.25em;
   display: block;
   display: block;
-  padding: 20px;
-  margin: 30px auto 0;
-  border-radius: 10px;
-  box-shadow: 2px 2px 8px #ccc;
-  border: 1px solid var(--purple);
-  letter-spacing: 2px;
+  padding: 1.25em;
+  margin: 1.875em auto 0;
+  border-radius: 0.625em;
+  box-shadow: 0.125em 0.125em 0.5em #ccc;
+  border: 0.0625em solid var(--purple);
+  letter-spacing: 0.125em;
   text-align: center;
   text-align: center;
-  line-height: 26px;
+  line-height: 1.625em;
   transition: all .3s;
   transition: all .3s;
 
 
   &:hover {
   &:hover {
     // color: #fff;
     // color: #fff;
     // background-color: var(--purple);
     // background-color: var(--purple);
-    box-shadow: 2px 2px 12px #bcbcbc;
+    box-shadow: 0.125em 0.125em 0.75em #bcbcbc;
   }
   }
 }
 }
 
 
-.favorites-btn {
-  position: absolute;
-  bottom: 15px;
-  right: 15px;
-}
+// .favorites-btn {
+//   position: absolute;
+//   bottom: 0.9375em;
+//   right: 0.9375em;
+// }
 
 
 .progress-item {
 .progress-item {
   position: fixed;
   position: fixed;
@@ -494,7 +519,7 @@ input:focus-visible {
 .tag-btn {
 .tag-btn {
   // @media (max-width: 960px) {
   // @media (max-width: 960px) {
   //   margin: auto !important;
   //   margin: auto !important;
-  //   max-width: 300px;
+  //   max-width: 18.75em;
   //   flex-direction: column;
   //   flex-direction: column;
   // }
   // }
 
 
@@ -505,12 +530,12 @@ input:focus-visible {
     width: 100%;
     width: 100%;
     // display: block;
     // display: block;
     color: var(--purple);
     color: var(--purple);
-    border: 1px solid var(--purple);
-    border-radius: 10px;
+    border: 0.0625em solid var(--purple);
+    border-radius: 0.625em;
     text-align: center;
     text-align: center;
     transition: all .3s;
     transition: all .3s;
-    line-height: 24px;
-    letter-spacing: 1px;
+    line-height: 1.5em;
+    letter-spacing: 0.0625em;
 
 
     &:hover {
     &:hover {
       color: #fff;
       color: #fff;
@@ -519,7 +544,7 @@ input:focus-visible {
     }
     }
 
 
     h3 {
     h3 {
-      padding: 10px;
+      // padding: 0.625em;
       font-weight: 500;
       font-weight: 500;
       word-break: keep-all;
       word-break: keep-all;
     }
     }
@@ -527,29 +552,30 @@ input:focus-visible {
     // a {
     // a {
     //   width: 100%;
     //   width: 100%;
     //   display: block;
     //   display: block;
-    //   line-height: 24px;
-    //   letter-spacing: 1px;
+    //   line-height: 1.5em;
+    //   letter-spacing: 0.0625em;
     // }
     // }
   }
   }
 }
 }
 
 
 .hint {
 .hint {
-  font-size: 14px;
+  display: block;
+  font-size: 0.875em;
   color: #919191;
   color: #919191;
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .total-item {
 .total-item {
-  margin-top: 15px;
+  margin-top: 0.9375em;
   display: block;
   display: block;
-  font-size: 14px;
-  letter-spacing: 2px;
+  font-size: 0.875em;
+  letter-spacing: 0.125em;
   text-align: center;
   text-align: center;
 }
 }
 
 
 .filter-list {
 .filter-list {
   .v-select {
   .v-select {
-    margin-bottom: 10px;
+    margin-bottom: 0.625em;
 
 
     .v-field {
     .v-field {
       overflow: hidden;
       overflow: hidden;
@@ -557,9 +583,9 @@ input:focus-visible {
 
 
     .v-field__overlay {
     .v-field__overlay {
       opacity: 1 !important;
       opacity: 1 !important;
-      border: 1px solid #ccc;
+      border: 0.0625em solid #ccc;
       background-color: #fff;
       background-color: #fff;
-      border-radius: 100px !important;
+      border-radius: 6.25em !important;
     }
     }
 
 
     .v-field__outline {
     .v-field__outline {
@@ -568,11 +594,11 @@ input:focus-visible {
 
 
 
 
     .v-field__input {
     .v-field__input {
-      padding-top: 15px;
+      padding-top: 0.9375em;
     }
     }
 
 
     .v-field__field {
     .v-field__field {
-      height: 45px;
+      height: 2.8125em;
     }
     }
 
 
     .v-select__selection {
     .v-select__selection {
@@ -584,7 +610,7 @@ input:focus-visible {
     }
     }
 
 
     .v-label.v-field-label--floating {
     .v-label.v-field-label--floating {
-      top: 3px !important;
+      top: 0.1875em !important;
     }
     }
   }
   }
 }
 }
@@ -602,7 +628,7 @@ input:focus-visible {
     section {
     section {
       margin: auto;
       margin: auto;
       position: absolute;
       position: absolute;
-      bottom: 15px;
+      bottom: 0.9375em;
       right: 0;
       right: 0;
       left: 0;
       left: 0;
     }
     }
@@ -614,14 +640,14 @@ input:focus-visible {
 .exhibit-content {
 .exhibit-content {
   .info {
   .info {
     section {
     section {
-      // max-width: 300px;
+      // max-width: 18.75em;
       width: 90%;
       width: 90%;
       justify-content: center;
       justify-content: center;
     }
     }
 
 
     h3,
     h3,
     p {
     p {
-      line-height: 20px;
+      line-height: 1.25em;
       overflow: hidden;
       overflow: hidden;
       text-overflow: ellipsis;
       text-overflow: ellipsis;
       display: -webkit-box;
       display: -webkit-box;
@@ -634,8 +660,8 @@ input:focus-visible {
     }
     }
 
 
     p {
     p {
-      max-width: 220px;
-      margin-top: 5px;
+      max-width: 13.75em;
+      margin-top: 0.3125em;
       -webkit-line-clamp: 2;
       -webkit-line-clamp: 2;
     }
     }
   }
   }
@@ -646,16 +672,16 @@ input:focus-visible {
 .exhibit-content,
 .exhibit-content,
 .campus-content {
 .campus-content {
   h4 {
   h4 {
-    margin-bottom: 20px;
+    margin-bottom: 1.25em;
     font-weight: 400;
     font-weight: 400;
-    font-size: 20px;
-    letter-spacing: 1px;
-    line-height: 32px;
+    font-size: 1.25em;
+    letter-spacing: 0.0625em;
+    line-height: 2em;
   }
   }
 
 
   p {
   p {
-    line-height: 28px;
-    letter-spacing: 1px;
+    line-height: 1.75em;
+    letter-spacing: 0.0625em;
   }
   }
 
 
   .info {
   .info {
@@ -663,19 +689,19 @@ input:focus-visible {
       display: flex;
       display: flex;
       flex-direction: column;
       flex-direction: column;
       align-items: center;
       align-items: center;
-      padding: 10px;
-      border-radius: 5px;
+      padding: 0.625em;
+      border-radius: 0.3125em;
       background: rgba(218, 182, 214, 0.8);
       background: rgba(218, 182, 214, 0.8);
 
 
       h3 {
       h3 {
-        margin: 5px;
+        margin: 0.3125em;
         font-weight: 400;
         font-weight: 400;
-        line-height: 22px;
-        letter-spacing: 1px;
+        line-height: 1.375em;
+        letter-spacing: 0.0625em;
       }
       }
 
 
       p {
       p {
-        font-size: 12px;
+        font-size: 0.75em;
       }
       }
     }
     }
   }
   }
@@ -685,18 +711,18 @@ input:focus-visible {
   margin-top: auto;
   margin-top: auto;
   margin-left: auto;
   margin-left: auto;
   display: inline-block;
   display: inline-block;
-  padding: 8px 20px;
-  border-radius: 100px;
-  line-height: 24px;
+  padding: 0.5em 1.25em;
+  border-radius: 6.25em;
+  line-height: 1.5em;
   text-align: center;
   text-align: center;
   color: #fff;
   color: #fff;
   background-color: var(--brown);
   background-color: var(--brown);
-  border: 2px solid transparent;
+  border: 0.125em solid transparent;
   transition: all 0.5s;
   transition: all 0.5s;
 
 
   &:hover {
   &:hover {
     color: var(--brown);
     color: var(--brown);
-    border: 2px solid var(--brown);
+    border: 0.125em solid var(--brown);
     background-color: #fff;
     background-color: #fff;
   }
   }
 }
 }
@@ -704,11 +730,11 @@ input:focus-visible {
 .download-link {
 .download-link {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
-  padding: 10px 20px;
-  font-size: 14px;
-  letter-spacing: 1px;
+  padding: 0.625em 1.25em;
+  font-size: 0.875em;
+  letter-spacing: 0.0625em;
   color: #fff;
   color: #fff;
-  border-radius: 100px;
+  border-radius: 6.25em;
   background-color: var(--brown);
   background-color: var(--brown);
   transition: all .3s;
   transition: all .3s;
 
 
@@ -719,11 +745,12 @@ input:focus-visible {
 
 
 .main-table {
 .main-table {
   overflow-x: auto;
   overflow-x: auto;
+  letter-spacing: 1px;
 
 
   .table-title {
   .table-title {
-    padding: 10px;
+    padding: 0.625em;
     color: #fff;
     color: #fff;
-    font-size: 20px;
+    font-size: 1.25em;
     font-weight: 400;
     font-weight: 400;
     text-align: center;
     text-align: center;
 
 
@@ -734,7 +761,7 @@ input:focus-visible {
 
 
   table {
   table {
     width: 100%;
     width: 100%;
-    margin-bottom: 20px;
+    margin-bottom: 1.25em;
     position: relative;
     position: relative;
     border-collapse: collapse;
     border-collapse: collapse;
 
 
@@ -744,43 +771,43 @@ input:focus-visible {
 
 
     thead {
     thead {
       th {
       th {
-        padding: 20px 0;
+        padding: 1.25em 0;
         font-weight: 500;
         font-weight: 500;
       }
       }
     }
     }
 
 
     tbody {
     tbody {
       td {
       td {
-        padding: 20px 0;
+        padding: 1.25em 0;
         text-align: center;
         text-align: center;
-        letter-spacing: 1px;
+        letter-spacing: 0.0625em;
       }
       }
     }
     }
   }
   }
 }
 }
 
 
 .v-chip {
 .v-chip {
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .v-pagination {
 .v-pagination {
   margin: auto;
   margin: auto;
-  max-width: 500px;
+  max-width: 31.25em;
 }
 }
 
 
 // scrollbar
 // scrollbar
 ::-webkit-scrollbar {
 ::-webkit-scrollbar {
-  width: 10px;
+  width: 0.625em;
 }
 }
 
 
 ::-webkit-scrollbar-track {
 ::-webkit-scrollbar-track {
   background: #f1f1f1;
   background: #f1f1f1;
-  border-radius: 10px;
+  border-radius: 0.625em;
 }
 }
 
 
 ::-webkit-scrollbar-thumb {
 ::-webkit-scrollbar-thumb {
   background: #b6b6b6;
   background: #b6b6b6;
-  border-radius: 10px;
+  border-radius: 0.625em;
 }
 }
 
 
 ::-webkit-scrollbar-thumb:hover {
 ::-webkit-scrollbar-thumb:hover {
@@ -789,7 +816,7 @@ input:focus-visible {
 
 
 // Vue DatePicker
 // Vue DatePicker
 .dp__input {
 .dp__input {
-  padding: 15px 40px;
+  padding: 0.9375em 2.5em;
   background-color: #f5f5f5;
   background-color: #f5f5f5;
 }
 }
 
 
@@ -798,21 +825,21 @@ input:focus-visible {
 }
 }
 
 
 .dp__calendar_item {
 .dp__calendar_item {
-  padding: 5px;
+  padding: 0.3125em;
 }
 }
 
 
 .dp__calendar_header_item {
 .dp__calendar_header_item {
-  font-size: 14px;
+  font-size: 0.875em;
 }
 }
 
 
 .dp__action_button {
 .dp__action_button {
   height: auto;
   height: auto;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
-  padding: 10px !important;
-  margin: 0 5px;
-  font-size: 14px;
-  letter-spacing: 1px;
+  padding: 0.625em !important;
+  margin: 0 0.3125em;
+  font-size: 0.875em;
+  letter-spacing: 0.0625em;
 }
 }
 
 
 .v-breadcrumbs-item--link {
 .v-breadcrumbs-item--link {

BIN
src/assets/img/cfa-default.jpg


BIN
src/assets/img/college-group/cross.webp


+ 17 - 16
src/components/ArticleCard.vue

@@ -35,6 +35,7 @@ const props = defineProps({
             class="mx-auto cover-img"
             class="mx-auto cover-img"
             :lazy-src="`https://ntcri.org/${data.cover_img}`"
             :lazy-src="`https://ntcri.org/${data.cover_img}`"
             :src="`https://ntcri.org/${data.cover_img}`"
             :src="`https://ntcri.org/${data.cover_img}`"
+            alt="臺灣工藝學校全球學習共享平台"
           >
           >
             <template v-slot:placeholder>
             <template v-slot:placeholder>
               <div class="d-flex align-center justify-center fill-height">
               <div class="d-flex align-center justify-center fill-height">
@@ -76,21 +77,21 @@ const props = defineProps({
 
 
 <style lang="scss">
 <style lang="scss">
 .v-card {
 .v-card {
-  padding: 15px;
-  border-radius: 10px;
+  padding: 0.9375em;
+  border-radius: 0.625em;
   border-color: var(--purple);
   border-color: var(--purple);
 
 
   .title-link {
   .title-link {
     display: block;
     display: block;
-    padding-bottom: 15px;
-    border-bottom: 1px solid #e0e0e0;
+    padding-bottom: 0.9375em;
+    border-bottom: 0.0625em solid #e0e0e0;
   }
   }
 
 
   h3 {
   h3 {
-    font-size: 22px;
+    font-size: 1.375em;
     font-weight: 500;
     font-weight: 500;
-    line-height: 32px;
-    letter-spacing: 1px;
+    line-height: 2em;
+    letter-spacing: 0.0625em;
   }
   }
 
 
   h3,
   h3,
@@ -114,13 +115,13 @@ const props = defineProps({
 
 
   section {
   section {
     -webkit-line-clamp: 4;
     -webkit-line-clamp: 4;
-    line-height: 28px;
-    letter-spacing: 1px;
+    line-height: 1.75em;
+    letter-spacing: 0.0625em;
   }
   }
 
 
   .cover-img {
   .cover-img {
-    height: 235px;
-    border-radius: 5px;
+    height: 14.6875em;
+    border-radius: 0.3125em;
   }
   }
 }
 }
 
 
@@ -128,14 +129,14 @@ const props = defineProps({
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   color: var(--purple);
   color: var(--purple);
-  text-shadow: 1px 1px 5px #fff;
+  text-shadow: 0.0625em 0.0625em 0.3125em #fff;
 
 
   span {
   span {
     display: block;
     display: block;
-    width: 8px;
-    height: 8px;
-    margin-right: 10px;
-    border-radius: 10px;
+    width: 0.5em;
+    height: 0.5em;
+    margin-right: 0.625em;
+    border-radius: 0.625em;
     background-color: var(--purple);
     background-color: var(--purple);
   }
   }
 }
 }

+ 51 - 27
src/components/CourseCard.vue

@@ -22,7 +22,7 @@ let favorites = reactive({
 async function setFavoriteClass(classId) {
 async function setFavoriteClass(classId) {
   let isLogin = store.checkToken();
   let isLogin = store.checkToken();
   if (!isLogin) {
   if (!isLogin) {
-    openLoginDialog();
+    store.openLoginDialog();
     return;
     return;
   }
   }
 
 
@@ -73,6 +73,22 @@ function isClassFavorite(classId) {
     return list.includes(classId);
     return list.includes(classId);
   }
   }
 }
 }
+
+// // 返回課程圖片網址
+// function getImageSrc(data) {
+//   console.log("data", data);
+//   if (data.is_inner === 0) {
+//     return data.cover_img;
+//   } else if (data.group_id === 9) {
+//     return store.getImageUrl("cfa-default.jpg");
+//   } else if (data.special_class_list_name === "one_day_class") {
+//     return store.getImageUrl("default.png");
+//   } else if (data.org === "Udemy") {
+//     return data.cover_img;
+//   } else {
+//     return `https://ntcri.org/${data.cover_img}`;
+//   }
+// }
 </script>
 </script>
 
 
 <template>
 <template>
@@ -93,26 +109,11 @@ function isClassFavorite(classId) {
         <div class="overflow-hidden">
         <div class="overflow-hidden">
           <v-img
           <v-img
             class="mx-auto cover-img"
             class="mx-auto cover-img"
-            :lazy-src="
-              data.is_inner === 0
-                ? data.cover_img
-                : data.special_class_list_name === 'one_day_class'
-                ? store.getImageUrl('default.png')
-                : data.org === 'Udemy'
-                ? data.cover_img
-                : `https://ntcri.org/${data.cover_img}`
-            "
-            height="220px"
+            :lazy-src="store.getImageSrc(data)"
+            height="13.75em"
             cover
             cover
-            :src="
-              data.is_inner === 0
-                ? data.cover_img
-                : data.special_class_list_name === 'one_day_class'
-                ? store.getImageUrl('default.png')
-                : data.org === 'Udemy'
-                ? data.cover_img
-                : `https://ntcri.org/${data.cover_img}`
-            "
+            :src="store.getImageSrc(data)"
+            alt="臺灣工藝學校全球學習共享平台"
           >
           >
             <template v-slot:placeholder>
             <template v-slot:placeholder>
               <div class="d-flex align-center justify-center fill-height">
               <div class="d-flex align-center justify-center fill-height">
@@ -125,6 +126,11 @@ function isClassFavorite(classId) {
           </v-img>
           </v-img>
         </div>
         </div>
       </a>
       </a>
+
+<div class="d-flex justify-end mt-3">
+  <small class="text-gray">編號:{{data.encode}}</small>
+</div>
+
       <!-- </router-link> -->
       <!-- </router-link> -->
       <ul v-if="data.org !== 'Udemy'">
       <ul v-if="data.org !== 'Udemy'">
         <li class="d-flex align-center mb-5">
         <li class="d-flex align-center mb-5">
@@ -138,14 +144,25 @@ function isClassFavorite(classId) {
             ></p>
             ></p>
           </div>
           </div>
         </li>
         </li>
-        <li class="d-flex align-center mt-auto">
+        <!-- <li class="d-flex align-center mt-auto">
           <v-icon color="primary" icon="mdi-map-marker" class="me-1"></v-icon>
           <v-icon color="primary" icon="mdi-map-marker" class="me-1"></v-icon>
-          <p class="mb-0 pe-5">
+          <p class="mb-0 pe-3">
             {{ data.location_name }}
             {{ data.location_name }}
           </p>
           </p>
-        </li>
-        <li>
-          <button class="favorites-btn">
+        </li> -->
+        <li class="d-flex align-center justify-space-between">
+          <div class="d-flex align-center">
+            <v-icon
+              color="primary"
+              icon="mdi-map-marker"
+              class="me-1 mt-1"
+            ></v-icon>
+            <p class="mb-0 pe-3 location-item">
+              {{ data.location_name }}
+            </p>
+          </div>
+
+          <button aria-label="收藏課程">
             <v-icon
             <v-icon
               v-if="isClassFavorite(data.class_name_id)"
               v-if="isClassFavorite(data.class_name_id)"
               @click="deleteFavoriteClass(data.class_name_id)"
               @click="deleteFavoriteClass(data.class_name_id)"
@@ -167,7 +184,10 @@ function isClassFavorite(classId) {
       <ul v-else class="justify-center">
       <ul v-else class="justify-center">
         <li>
         <li>
           <div class="description">
           <div class="description">
-            <p class="text-gray pt-3" v-html="store.formatString(data.content)"></p>
+            <p
+              class="text-gray pt-3"
+              v-html="store.formatString(data.content)"
+            ></p>
           </div>
           </div>
 
 
           <!-- <p class="text-gray pt-3">
           <!-- <p class="text-gray pt-3">
@@ -181,7 +201,11 @@ function isClassFavorite(classId) {
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .description {
 .description {
-  height: 105px;
+  height: 7em;
   overflow: hidden;
   overflow: hidden;
 }
 }
+
+.location-item {
+  -webkit-line-clamp: 2 !important;
+}
 </style>
 </style>

+ 56 - 71
src/components/CoursesTutorial.vue

@@ -34,7 +34,10 @@ const navigation = ref({
       >
       >
         <swiper-slide>
         <swiper-slide>
           <div class="main-item">
           <div class="main-item">
-            <img src="@/assets/img/setup-courses/tutorial/素材-13.png" alt="" />
+            <img
+              src="@/assets/img/setup-courses/tutorial/素材-13.png"
+              alt="臺灣工藝學校全球學習共享平台"
+            />
             <p class="ps-sm-10" v-html="t('tutorial.step')"></p>
             <p class="ps-sm-10" v-html="t('tutorial.step')"></p>
           </div>
           </div>
         </swiper-slide>
         </swiper-slide>
@@ -71,7 +74,7 @@ const navigation = ref({
             <div class="icon">
             <div class="icon">
               <img
               <img
                 src="@/assets/img/setup-courses/tutorial/素材-13.png"
                 src="@/assets/img/setup-courses/tutorial/素材-13.png"
-                alt=""
+                alt="臺灣工藝學校全球學習共享平台"
               />
               />
             </div>
             </div>
           </div>
           </div>
@@ -115,7 +118,7 @@ const navigation = ref({
             <div>
             <div>
               <img
               <img
                 src="@/assets/img/setup-courses/tutorial/素材-14.png"
                 src="@/assets/img/setup-courses/tutorial/素材-14.png"
-                alt=""
+                alt="臺灣工藝學校全球學習共享平台"
               />
               />
             </div>
             </div>
           </div>
           </div>
@@ -159,7 +162,7 @@ const navigation = ref({
             <div>
             <div>
               <img
               <img
                 src="@/assets/img/setup-courses/tutorial/素材-15.png"
                 src="@/assets/img/setup-courses/tutorial/素材-15.png"
-                alt=""
+                alt="臺灣工藝學校全球學習共享平台"
               />
               />
             </div>
             </div>
           </div>
           </div>
@@ -167,7 +170,10 @@ const navigation = ref({
 
 
         <swiper-slide>
         <swiper-slide>
           <div class="main-item">
           <div class="main-item">
-            <img src="@/assets/img/setup-courses/tutorial/素材-15.png" alt="" />
+            <img
+              src="@/assets/img/setup-courses/tutorial/素材-15.png"
+              alt="臺灣工藝學校全球學習共享平台"
+            />
             <section class="d-flex flex-column ps-sm-10">
             <section class="d-flex flex-column ps-sm-10">
               <h3 v-html="t('tutorial.step_4_title')"></h3>
               <h3 v-html="t('tutorial.step_4_title')"></h3>
               <p
               <p
@@ -204,15 +210,15 @@ const navigation = ref({
   right: 3%;
   right: 3%;
   bottom: 5%;
   bottom: 5%;
   z-index: 100;
   z-index: 100;
-  font-size: 20px;
-  letter-spacing: 2px;
+  font-size: 1.25em;
+  letter-spacing: 0.125em;
   color: #636363;
   color: #636363;
   transition: all 0.3s;
   transition: all 0.3s;
   &:hover {
   &:hover {
     opacity: 0.7;
     opacity: 0.7;
   }
   }
   @media (max-width: 600px) {
   @media (max-width: 600px) {
-    font-size: 16px;
+    font-size: 1em;
   }
   }
 }
 }
 
 
@@ -224,13 +230,13 @@ p {
 
 
 h3 {
 h3 {
   font-weight: 500;
   font-weight: 500;
-  font-size: 30px;
-  line-height: 40px;
-  letter-spacing: 2px;
+  font-size: 1.7em;
+  line-height: 2.5em;
+  letter-spacing: 0.125em;
 
 
   @media (max-width: 600px) {
   @media (max-width: 600px) {
-    font-size: 24px;
-    line-height: 36px;
+    font-size: 1.3em;
+    line-height: 1.5em;
   }
   }
 }
 }
 
 
@@ -241,11 +247,11 @@ h3 {
   overflow: hidden;
   overflow: hidden;
 
 
   @media (max-width: 960px) {
   @media (max-width: 960px) {
-    padding: 0 20px;
+    padding: 0 1.25em;
   }
   }
 
 
   @media (max-width: 490px) {
   @media (max-width: 490px) {
-    padding: 0 10px;
+    padding: 0 0.625em;
   }
   }
 
 
   video {
   video {
@@ -266,7 +272,7 @@ h3 {
     }
     }
 
 
     img {
     img {
-      max-width: 400px;
+      max-width: 25em;
 
 
       @media (max-width: 960px) {
       @media (max-width: 960px) {
         max-width: 30vw;
         max-width: 30vw;
@@ -274,7 +280,7 @@ h3 {
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
         max-width: 50vw;
         max-width: 50vw;
-        margin-bottom: 20px;
+        margin-bottom: 1.25em;
       }
       }
 
 
       @media (max-width: 490px) {
       @media (max-width: 490px) {
@@ -283,95 +289,85 @@ h3 {
     }
     }
 
 
     p {
     p {
-      max-width: 600px;
-      font-size: 20px;
-      line-height: 36px;
+      max-width: 37.5em;
+      font-size: 1.125em;
+      line-height: 2.25em;
       text-align: start;
       text-align: start;
       font-weight: 500;
       font-weight: 500;
-      letter-spacing: 1px;
+      letter-spacing: 0.0625em;
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 18px;
+        font-size: 1.125em;
         text-align: center;
         text-align: center;
       }
       }
 
 
       @media (max-width: 490px) {
       @media (max-width: 490px) {
-        font-size: 16px;
-        line-height: 28px;
+        font-size: 0.85em;
+        line-height: 1.75em;
       }
       }
     }
     }
   }
   }
 
 
   .step-item {
   .step-item {
     h3 {
     h3 {
-      margin-bottom: 60px;
+      margin-bottom: 3.75em;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        margin-bottom: 30px;
+        margin-bottom: 1.875em;
       }
       }
 
 
       @media (max-width: 490px) {
       @media (max-width: 490px) {
-        margin-bottom: 10px;
+        margin-bottom: 0.625em;
       }
       }
     }
     }
 
 
     p,
     p,
     li,
     li,
     strong {
     strong {
-      font-size: 20px;
-      line-height: 26px;
-      letter-spacing: 2px;
+      font-size: 1.125em;
+      line-height: 1.625em;
+      letter-spacing: 0.125em;
 
 
-      @media (max-width: 960px) {
-        font-size: 18px;
-      }
       @media (max-width: 490px) {
       @media (max-width: 490px) {
-        font-size: 16px;
-        line-height: 28px;
+        font-size: .85em;
+        line-height: 1.75em;
       }
       }
     }
     }
 
 
     strong {
     strong {
       display: block;
       display: block;
-      margin-top: 15px;
+      margin-top: 0.9375em;
       color: #779faa;
       color: #779faa;
       font-weight: 400;
       font-weight: 400;
     }
     }
 
 
     ul {
     ul {
-      max-width: 700px;
-      margin: 40px auto 80px;
+      max-width: 43.75em;
+      margin: 2.5em auto 5em;
       display: flex;
       display: flex;
       flex-wrap: wrap;
       flex-wrap: wrap;
       justify-content: center;
       justify-content: center;
 
 
       @media (max-width: 760px) {
       @media (max-width: 760px) {
-        margin: 40px auto;
+        margin: 2.5em auto;
       }
       }
 
 
       @media (max-width: 490px) {
       @media (max-width: 490px) {
-        margin: 20px auto;
+        margin: 1.25em auto;
       }
       }
 
 
       li {
       li {
-        margin: 10px 5px;
+        margin: 0.625em 0.3125em;
 
 
         @media (max-width: 960px) {
         @media (max-width: 960px) {
-          margin: 10px;
+          margin: 0.625em;
         }
         }
 
 
         p {
         p {
-          padding: 10px 15px;
+          padding: 0.625em 0.9375em;
           color: #fff;
           color: #fff;
-          border-radius: 5px;
+          border-radius: 0.3125em;
           background-color: var(--blue);
           background-color: var(--blue);
-          font-size: 18px;
-
-          @media (max-width: 960px) {
-            font-size: 16px;
-          }
-          @media (max-width: 490px) {
-            font-size: 14px;
-          }
+          font-size: 0.9em;
         }
         }
       }
       }
     }
     }
@@ -379,29 +375,18 @@ h3 {
     .icon {
     .icon {
       img {
       img {
         @media (max-width: 490px) {
         @media (max-width: 490px) {
-          max-width: 90px;
+          max-width: 5.625em;
         }
         }
       }
       }
     }
     }
 
 
     .list {
     .list {
-      max-width: 800px;
-      // li {
-      //   width: 180px;
-
-      //   @media (max-width: 960px) {
-      //     width: 155px;
-      //   }
-
-      //   @media (max-width: 490px) {
-      //     width: 145px;
-      //   }
-      // }
+      max-width: 50em;
     }
     }
 
 
     img {
     img {
-      max-width: 180px;
-      height: 100px;
+      max-width: 11.25em;
+      height: 6.25em;
       left: 5%;
       left: 5%;
       bottom: 10%;
       bottom: 10%;
       position: absolute;
       position: absolute;
@@ -413,8 +398,8 @@ h3 {
       }
       }
 
 
       @media (max-width: 490px) {
       @media (max-width: 490px) {
-        max-width: 70px;
-        bottom: 5px;
+        max-width: 4.375em;
+        bottom: 0.3125em;
       }
       }
     }
     }
   }
   }
@@ -423,7 +408,7 @@ h3 {
   .swiper-button-prev {
   .swiper-button-prev {
     left: 50%;
     left: 50%;
     color: #fff;
     color: #fff;
-    text-shadow: 1px 1px 5px #9b9b9b;
+    text-shadow: 0.0625em 0.0625em 0.3125em #9b9b9b;
     transform: rotate(90deg);
     transform: rotate(90deg);
   }
   }
 
 
@@ -459,7 +444,7 @@ h3 {
 
 
 .swiper-slide {
 .swiper-slide {
   text-align: center;
   text-align: center;
-  font-size: 18px;
+  font-size: 1.125em;
   display: flex;
   display: flex;
   justify-content: center;
   justify-content: center;
   align-items: center;
   align-items: center;

+ 5 - 4
src/components/CraftsArticle.vue

@@ -89,13 +89,14 @@ let data = reactive({
   <v-row v-else class="list">
   <v-row v-else class="list">
     <v-col cols="12" sm="6" v-for="(item, index) in data.list" :key="index">
     <v-col cols="12" sm="6" v-for="(item, index) in data.list" :key="index">
       <a :href="item.url" target="_blank">
       <a :href="item.url" target="_blank">
-        <!-- <img :src="`https://ntcri.org/${item.cover_img}`" alt="" /> -->
+        <!-- <img :src="`https://ntcri.org/${item.cover_img}`" alt="臺灣工藝學校全球學習共享平台" /> -->
         <div class="overflow-hidden">
         <div class="overflow-hidden">
           <v-img
           <v-img
             class="mx-auto cover-img"
             class="mx-auto cover-img"
             :lazy-src="`https://ntcri.org/${item.cover_img}`"
             :lazy-src="`https://ntcri.org/${item.cover_img}`"
             cover
             cover
             :src="`https://ntcri.org/${item.cover_img}`"
             :src="`https://ntcri.org/${item.cover_img}`"
+            alt="臺灣工藝學校全球學習共享平台"
           >
           >
             <template v-slot:placeholder>
             <template v-slot:placeholder>
               <div class="d-flex align-center justify-center fill-height">
               <div class="d-flex align-center justify-center fill-height">
@@ -121,18 +122,18 @@ let data = reactive({
   transition: all 0.5s;
   transition: all 0.5s;
 
 
   &:hover {
   &:hover {
-    transform: translate(0px, -10px);
+    transform: translate(0, -0.625em);
   }
   }
 }
 }
 .list {
 .list {
   p {
   p {
-    margin-bottom: 10px;
+    margin-bottom: 0.625em;
   }
   }
   h3,
   h3,
   p {
   p {
     font-weight: 500;
     font-weight: 500;
     text-align: center;
     text-align: center;
-    line-height: 30px;
+    line-height: 1.875em;
   }
   }
 }
 }
 </style>
 </style>

+ 8 - 8
src/components/Footer.vue

@@ -5,7 +5,7 @@
     </h1> -->
     </h1> -->
 
 
     <router-link to="/">
     <router-link to="/">
-      <img src="@/assets/img/logo.png" alt="" class="logo mt-3" />
+      <img src="@/assets/img/logo.png" alt="臺灣工藝學校全球學習共享平台" class="logo mt-3" />
     </router-link>
     </router-link>
 
 
     <ul class="ms-sm-13">
     <ul class="ms-sm-13">
@@ -37,18 +37,18 @@
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 footer {
 footer {
-  padding: 20px 40px;
+  padding: 1.25em 2.5em;
   background-color: #fff;
   background-color: #fff;
-  border-top: 25px solid var(--purple);
+  border-top: 1.5625em solid var(--purple);
   h1 {
   h1 {
-    margin: 20px 0;
-    font-size: 18px;
+    margin: 1.25em 0;
+    font-size: 1.125em;
     font-weight: 500;
     font-weight: 500;
   }
   }
   ul {
   ul {
     li {
     li {
-      margin: 15px 0;
-      letter-spacing: 1px;
+      margin: 0.9375em 0;
+      letter-spacing: 0.0625em;
       a {
       a {
         transition: all 0.3s;
         transition: all 0.3s;
         &:hover {
         &:hover {
@@ -58,7 +58,7 @@ footer {
     }
     }
   }
   }
   .logo {
   .logo {
-    width: 350px;
+    width: 21.875em;
   }
   }
 }
 }
 </style>
 </style>

+ 32 - 17
src/components/HomeList.vue

@@ -30,10 +30,12 @@ const props = defineProps({
     <v-row class="align-center">
     <v-row class="align-center">
       <!-- <v-col cols="12" sm="4">
       <!-- <v-col cols="12" sm="4">
         <router-link :to="`/news/${data.news_id}`" class="cover-img">
         <router-link :to="`/news/${data.news_id}`" class="cover-img">
-          <img src="@/assets/img/img-04.jpg" alt="" />
+          <img src="@/assets/img/img-04.jpg" alt="臺灣工藝學校全球學習共享平台" />
         </router-link>
         </router-link>
       </v-col> -->
       </v-col> -->
-      <v-col cols="12">
+
+      <!-- 新聞 -->
+      <v-col v-if="data.category !== '展覽'" cols="12">
         <router-link :to="`/news/${data.news_id}`" class="cover-img">
         <router-link :to="`/news/${data.news_id}`" class="cover-img">
           <section class="d-flex flex-column pa-3">
           <section class="d-flex flex-column pa-3">
             <h3>{{ data.title }}</h3>
             <h3>{{ data.title }}</h3>
@@ -41,6 +43,19 @@ const props = defineProps({
           </section>
           </section>
         </router-link>
         </router-link>
       </v-col>
       </v-col>
+
+      <!-- 展覽 -->
+      <v-col v-else cols="12">
+        <router-link
+          :to="`/course-detail/${data.class_name_id}`"
+          class="cover-img"
+        >
+          <section class="d-flex flex-column pa-3">
+            <h3>{{ data.name }}</h3>
+            <p v-html="data.introduction"></p>
+          </section>
+        </router-link>
+      </v-col>
     </v-row>
     </v-row>
   </v-card>
   </v-card>
 </template>
 </template>
@@ -48,16 +63,16 @@ const props = defineProps({
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .v-card {
 .v-card {
   border-color: var(--gray);
   border-color: var(--gray);
-  border-radius: 20px;
+  border-radius: 1.25em;
   background-image: url("@/assets/img/home/news-bg.png");
   background-image: url("@/assets/img/home/news-bg.png");
   h3 {
   h3 {
-    margin-bottom: 20px;
-    padding-bottom: 20px;
-    font-size: 22px !important;
+    margin-bottom: 1.25em;
+    padding-bottom: 1.25em;
+    font-size: 1.375em !important;
     font-weight: 500;
     font-weight: 500;
-    line-height: 32px;
-    letter-spacing: 1px;
-    border-bottom: 1px solid #ccc;
+    line-height: 2em;
+    letter-spacing: 0.0625em;
+    border-bottom: 0.0625em solid #ccc;
   }
   }
 
 
   h3,
   h3,
@@ -80,13 +95,13 @@ const props = defineProps({
 
 
   p {
   p {
     -webkit-line-clamp: 3;
     -webkit-line-clamp: 3;
-    line-height: 28px;
-    letter-spacing: 1px;
+    line-height: 1.75em;
+    letter-spacing: 0.0625em;
   }
   }
 
 
   .cover-img {
   .cover-img {
-    height: 235px;
-    border-radius: 5px;
+    height: 14.6875em;
+    border-radius: 0.3125em;
   }
   }
 }
 }
 
 
@@ -97,10 +112,10 @@ const props = defineProps({
 
 
   span {
   span {
     display: block;
     display: block;
-    width: 8px;
-    height: 8px;
-    margin-right: 10px;
-    border-radius: 10px;
+    width: 0.5em;
+    height: 0.5em;
+    margin-right: 0.625em;
+    border-radius: 0.625em;
     background-color: #000;
     background-color: #000;
   }
   }
 }
 }

+ 14 - 1
src/components/Map.vue

@@ -5,8 +5,8 @@ import "leaflet/dist/leaflet.css";
 import "leaflet.markercluster/dist/MarkerCluster.css";
 import "leaflet.markercluster/dist/MarkerCluster.css";
 import "leaflet.markercluster/dist/MarkerCluster.Default.css";
 import "leaflet.markercluster/dist/MarkerCluster.Default.css";
 import { ref, reactive, onMounted, getCurrentInstance } from "vue";
 import { ref, reactive, onMounted, getCurrentInstance } from "vue";
-import axios from "axios";
 import { useMainStore } from "@/stores/store";
 import { useMainStore } from "@/stores/store";
+import axios from "axios";
 
 
 const store = useMainStore();
 const store = useMainStore();
 const mapContainer = ref(null);
 const mapContainer = ref(null);
@@ -18,6 +18,19 @@ onMounted(() => {
     data: [],
     data: [],
   });
   });
 
 
+  // 監聽 Pinia 存儲中的值變化
+  store.$subscribe((item) => {
+    console.log("經緯度", item.events.target);
+
+    const newCenter = {
+      lat: item.events.target.lat,
+      lng: item.events.target.lng,
+    };
+    
+    // 將地圖中心設為指定的經緯度
+    map.setView([newCenter.lat, newCenter.lng], map.getZoom());
+  });
+
   (async function getData() {
   (async function getData() {
     try {
     try {
       const response = await axios.get("https://cmm.ai:8088/api/get_school");
       const response = await axios.get("https://cmm.ai:8088/api/get_school");

+ 95 - 49
src/components/Navbar.vue

@@ -120,24 +120,30 @@ function handleLogout() {
 <template>
 <template>
   <div class="d-flex justify-space-between align-center navbar">
   <div class="d-flex justify-space-between align-center navbar">
     <router-link :to="'/'">
     <router-link :to="'/'">
-      <img src="@/assets/img/logo.png" alt="" />
+      <img src="@/assets/img/logo.png" alt="臺灣工藝學校全球學習共享平台" />
     </router-link>
     </router-link>
     <ul class="menu align-center" :class="{ slider: menuShow }">
     <ul class="menu align-center" :class="{ slider: menuShow }">
       <li>
       <li>
         <router-link :to="'/crafts'">工藝學</router-link>
         <router-link :to="'/crafts'">工藝學</router-link>
       </li>
       </li>
+
       <li class="position-relative">
       <li class="position-relative">
         <a
         <a
           href="javascript:;"
           href="javascript:;"
           @mouseover="collegeMenuShow = true"
           @mouseover="collegeMenuShow = true"
           @mouseleave="collegeMenuShow = false"
           @mouseleave="collegeMenuShow = false"
           class="d-none d-lg-block"
           class="d-none d-lg-block"
-          >工藝學群</a
+          title="前往工藝學群頁面"
         >
         >
+          <span class="d-flex align-center">
+            工藝學群 <v-icon icon="mdi-chevron-down"></v-icon>
+          </span>
+        </a>
         <a
         <a
           href="javascript:;"
           href="javascript:;"
           @click="collegeMenuShow = !collegeMenuShow"
           @click="collegeMenuShow = !collegeMenuShow"
           class="d-block d-lg-none"
           class="d-block d-lg-none"
+          title="前往工藝學群頁面"
           >工藝學群
           >工藝學群
           <v-icon
           <v-icon
             icon="mdi-chevron-down"
             icon="mdi-chevron-down"
@@ -153,24 +159,35 @@ function handleLogout() {
         >
         >
           <ul>
           <ul>
             <li v-for="(item, index) in collegeList" :key="index">
             <li v-for="(item, index) in collegeList" :key="index">
-              <a href="javascript:;" @click="handleClick(item.url)">{{
-                item.title
-              }}</a>
+              <a
+                href="javascript:;"
+                @click="handleClick(item.url)"
+                :title="`前往${item.title}頁面`"
+                >{{ item.title }}</a
+              >
 
 
               <!-- <router-link :to="item.url">{{ item.title }}</router-link> -->
               <!-- <router-link :to="item.url">{{ item.title }}</router-link> -->
             </li>
             </li>
           </ul>
           </ul>
         </div>
         </div>
       </li>
       </li>
+
       <li>
       <li>
         <router-link :to="'/news'">重要訊息</router-link>
         <router-link :to="'/news'">重要訊息</router-link>
       </li>
       </li>
+
       <li>
       <li>
         <router-link :to="'/course-list'">探索課程</router-link>
         <router-link :to="'/course-list'">探索課程</router-link>
       </li>
       </li>
+
       <!-- <li>
       <!-- <li>
         <router-link :to="'/article'">知識文章</router-link>
         <router-link :to="'/article'">知識文章</router-link>
       </li> -->
       </li> -->
+
+      <li>
+        <router-link :to="'/setup-courses'">我要開課</router-link>
+      </li>
+
       <li class="position-relative">
       <li class="position-relative">
         <v-dialog
         <v-dialog
           v-model="store.loginDialog"
           v-model="store.loginDialog"
@@ -178,7 +195,9 @@ function handleLogout() {
           v-if="!store.loginState"
           v-if="!store.loginState"
         >
         >
           <template v-slot:activator="{ props }">
           <template v-slot:activator="{ props }">
-            <a href="javascript:;" v-bind="props">會員登入</a>
+            <a href="javascript:;" v-bind="props" title="點擊以開啟會員登入介面"
+              >會員登入</a
+            >
           </template>
           </template>
           <Login @close="handleClose" />
           <Login @close="handleClose" />
         </v-dialog>
         </v-dialog>
@@ -189,8 +208,11 @@ function handleLogout() {
             @mouseover="loginMenuShow = true"
             @mouseover="loginMenuShow = true"
             @mouseleave="loginMenuShow = false"
             @mouseleave="loginMenuShow = false"
             class="d-none d-lg-block"
             class="d-none d-lg-block"
-            >會員專區</router-link
           >
           >
+            <span class="d-flex align-center">
+              會員專區 <v-icon icon="mdi-chevron-down"></v-icon>
+            </span>
+          </router-link>
 
 
           <router-link :to="'/user/profile'" class="d-block d-lg-none"
           <router-link :to="'/user/profile'" class="d-block d-lg-none"
             >會員專區</router-link
             >會員專區</router-link
@@ -206,18 +228,29 @@ function handleLogout() {
         >
         >
           <ul>
           <ul>
             <li>
             <li>
-              <a href="javascript:;" @click="handleLogout()"> 登出 </a>
+              <router-link :to="'/user/profile'">個人檔案</router-link>
+            </li>
+            <li>
+              <router-link :to="'/user/passport'">學習護照</router-link>
+            </li>
+            <li>
+              <router-link :to="'/user/favorite-class'">我的收藏</router-link>
+            </li>
+            <li>
+              <a href="javascript:;" @click="handleLogout()" title="點擊以登出">
+                登出
+              </a>
             </li>
             </li>
           </ul>
           </ul>
         </div>
         </div>
 
 
         <!-- <router-link :to="'/user/profile'" v-else>會員專區</router-link> -->
         <!-- <router-link :to="'/user/profile'" v-else>會員專區</router-link> -->
       </li>
       </li>
+
       <li>
       <li>
-        <router-link :to="'/setup-courses'">我要開課</router-link>
-      </li>
-      <li>
-        <a href="javascript:;" @click="changeLang()">中/EN</a>
+        <a href="javascript:;" @click="changeLang()" title="點擊切換語言"
+          >中/EN</a
+        >
       </li>
       </li>
       <li class="d-none d-lg-block">
       <li class="d-none d-lg-block">
         <v-icon icon="mdi-magnify"></v-icon>
         <v-icon icon="mdi-magnify"></v-icon>
@@ -228,7 +261,9 @@ function handleLogout() {
           @mouseover="otherMenuShow = true"
           @mouseover="otherMenuShow = true"
           @mouseleave="otherMenuShow = false"
           @mouseleave="otherMenuShow = false"
           class="d-none d-lg-block"
           class="d-none d-lg-block"
+          title="查看選單"
         >
         >
+          <span class="d-none">查看選單</span>
           <v-icon icon="mdi-menu"></v-icon
           <v-icon icon="mdi-menu"></v-icon
         ></a>
         ></a>
         <div
         <div
@@ -239,9 +274,12 @@ function handleLogout() {
         >
         >
           <ul>
           <ul>
             <li v-for="(item, index) in otherList" :key="index">
             <li v-for="(item, index) in otherList" :key="index">
-              <a href="javascript:;" @click="handleClick(item.url)">{{
-                item.title
-              }}</a>
+              <a
+                href="javascript:;"
+                @click="handleClick(item.url)"
+                :title="`前往${item.title}頁面`"
+                >{{ item.title }}</a
+              >
             </li>
             </li>
           </ul>
           </ul>
         </div>
         </div>
@@ -251,14 +289,18 @@ function handleLogout() {
         :key="index"
         :key="index"
         class="d-block d-lg-none"
         class="d-block d-lg-none"
       >
       >
-        <a href="javascript:;" @click="handleClick(item.url)">{{
-          item.title
-        }}</a>
+        <a
+          href="javascript:;"
+          @click="handleClick(item.url)"
+          :title="`前往${item.title}頁面`"
+          >{{ item.title }}</a
+        >
         <!-- <router-link :to="item.url">{{ item.title }}</router-link> -->
         <!-- <router-link :to="item.url">{{ item.title }}</router-link> -->
       </li>
       </li>
     </ul>
     </ul>
 
 
-    <a href="javascript:;" class="icon" @click="toggleMenu()">
+    <a href="javascript:;" class="icon" @click="toggleMenu()" title="查看選單">
+      <span class="d-none">查看選單</span>
       <v-icon icon="mdi-menu" class="mx-2"></v-icon>
       <v-icon icon="mdi-menu" class="mx-2"></v-icon>
     </a>
     </a>
   </div>
   </div>
@@ -267,25 +309,28 @@ function handleLogout() {
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .navbar {
 .navbar {
   width: 90%;
   width: 90%;
-  max-width: 1300px;
-  margin: 0 auto 40px;
-  padding: 0 35px 0 15px;
-  border: 1px solid;
+  max-width: 81.25em;
+  margin: 0 auto 2.5em;
+  padding: 0 2.1875em 0 0.9375em;
+  border: 0.0625em solid;
   position: relative;
   position: relative;
   z-index: 1000;
   z-index: 1000;
   background: transparent;
   background: transparent;
-  top: 40px;
+  top: 2.5em;
   left: 0;
   left: 0;
   right: 0;
   right: 0;
 
 
   @media (max-width: 1280px) {
   @media (max-width: 1280px) {
-    padding: 10px 20px 10px 10px;
+    padding: 0.625em 1.25em 0.625em 0.625em;
   }
   }
 
 
   img {
   img {
     width: 100%;
     width: 100%;
-    max-width: 370px;
-    margin-top: 5px;
+    max-width: 400px;
+    margin-top: 0.3125em;
+    @media (max-width: 1400px) {
+      max-width: 330px;
+    }
     @media (max-width: 600px) {
     @media (max-width: 600px) {
       max-width: 300px;
       max-width: 300px;
     }
     }
@@ -298,7 +343,7 @@ function handleLogout() {
 
 
     @media (max-width: 1280px) {
     @media (max-width: 1280px) {
       position: absolute;
       position: absolute;
-      top: 81px;
+      top: 5.0625em;
       left: 0;
       left: 0;
       right: 0;
       right: 0;
       z-index: 100;
       z-index: 100;
@@ -306,7 +351,7 @@ function handleLogout() {
       flex-direction: column;
       flex-direction: column;
       max-height: 0;
       max-height: 0;
       transition: max-height 0.3s ease-in-out;
       transition: max-height 0.3s ease-in-out;
-      box-shadow: 1px 1px 15px #c8c8c8;
+      box-shadow: 0.0625em 0.0625em 0.9375em #c8c8c8;
     }
     }
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
@@ -314,21 +359,21 @@ function handleLogout() {
     }
     }
 
 
     &.slider {
     &.slider {
-      max-height: 700px;
+      max-height: 43.75em;
       overflow: initial;
       overflow: initial;
-      // border: 1px solid;
+      // border: 0.0625em solid;
       // border-top: none;
       // border-top: none;
     }
     }
 
 
     & > li {
     & > li {
-      margin-left: 27px;
+      margin-left: 1.6875em;
       font-weight: 400;
       font-weight: 400;
 
 
       @media (max-width: 1280px) {
       @media (max-width: 1280px) {
         width: 100%;
         width: 100%;
         margin-left: 0;
         margin-left: 0;
         background: #fff;
         background: #fff;
-        border-bottom: 1px solid #f0f0f0;
+        border-bottom: 0.0625em solid #f0f0f0;
         font-weight: 500;
         font-weight: 500;
         text-align: center;
         text-align: center;
       }
       }
@@ -336,7 +381,7 @@ function handleLogout() {
       a {
       a {
         width: 100%;
         width: 100%;
         display: block;
         display: block;
-        padding: 40px 0;
+        padding: 2.5em 0;
         color: #000;
         color: #000;
         text-decoration: none;
         text-decoration: none;
         transition: all 0.3s;
         transition: all 0.3s;
@@ -346,7 +391,7 @@ function handleLogout() {
         }
         }
 
 
         @media (max-width: 1280px) {
         @media (max-width: 1280px) {
-          padding: 20px 0;
+          padding: 1.25em 0;
         }
         }
       }
       }
     }
     }
@@ -354,12 +399,13 @@ function handleLogout() {
     .college-slider {
     .college-slider {
       display: none;
       display: none;
       position: absolute;
       position: absolute;
-      top: 80px;
-      left: -30px;
-      width: 130px;
+      top: 5em;
+      left: -1.875em;
+      width: 8.125em;
       background: #fff;
       background: #fff;
       text-align: center;
       text-align: center;
-      box-shadow: 1px 1px 15px #c8c8c8;
+      border-radius: 5px;
+      box-shadow: 0.0625em 0.0625em 0.9375em #c8c8c8;
       transition: all 0.3s;
       transition: all 0.3s;
 
 
       @media (max-width: 1280px) {
       @media (max-width: 1280px) {
@@ -372,13 +418,13 @@ function handleLogout() {
       }
       }
 
 
       // @media (max-width: 1280px) {
       // @media (max-width: 1280px) {
-      //   top: 30px;
+      //   top: 1.875em;
       //   left: 50vw;
       //   left: 50vw;
       // }
       // }
 
 
       // @media (max-width: 600px) {
       // @media (max-width: 600px) {
       //   left: 58vw;
       //   left: 58vw;
-      //   width: 100px;
+      //   width: 6.25em;
       // }
       // }
 
 
       &.slider {
       &.slider {
@@ -390,7 +436,7 @@ function handleLogout() {
 
 
       ul {
       ul {
         @media (max-width: 1280px) {
         @media (max-width: 1280px) {
-          padding-bottom: 15px;
+          padding-bottom: 0.9375em;
         }
         }
         li {
         li {
           transition: all 0.3s;
           transition: all 0.3s;
@@ -410,9 +456,9 @@ function handleLogout() {
           a {
           a {
             display: block;
             display: block;
             width: 100%;
             width: 100%;
-            padding: 15px 10px;
+            padding: 0.9375em 0.625em;
             @media (max-width: 1280px) {
             @media (max-width: 1280px) {
-              padding: 15px 10px 15px 40px;
+              padding: 0.9375em 0.625em 0.9375em 2.5em;
             }
             }
           }
           }
         }
         }
@@ -421,9 +467,9 @@ function handleLogout() {
   }
   }
 
 
   .toggle-icon {
   .toggle-icon {
-    margin-left: 5px;
+    margin-left: 0.3125em;
     position: absolute;
     position: absolute;
-    top: 17px;
+    top: 0.7em;
     transition: all 0.3s;
     transition: all 0.3s;
     &.slider {
     &.slider {
       transform: rotate(180deg);
       transform: rotate(180deg);
@@ -450,15 +496,15 @@ function handleLogout() {
   &::before {
   &::before {
     content: "";
     content: "";
     position: absolute;
     position: absolute;
-    top: 6px;
-    left: 6px;
+    top: 0.375em;
+    left: 0.375em;
     width: 99%;
     width: 99%;
     height: 88%;
     height: 88%;
     background-color: rgba(255, 255, 255, 0.5);
     background-color: rgba(255, 255, 255, 0.5);
     z-index: -1;
     z-index: -1;
 
 
     @media (max-width: 960px) {
     @media (max-width: 960px) {
-      top: 7px;
+      top: 0.4375em;
       left: 1.3vw;
       left: 1.3vw;
       width: 97%;
       width: 97%;
       height: 83%;
       height: 83%;

+ 11 - 11
src/components/NavbarSub.vue

@@ -11,7 +11,7 @@ function toggleMenu() {
 <template>
 <template>
   <div class="d-flex justify-space-between align-center navbar">
   <div class="d-flex justify-space-between align-center navbar">
     <router-link :to="'/'">
     <router-link :to="'/'">
-      <img src="@/assets/img/logo.png" alt="" />
+      <img src="@/assets/img/logo.png" alt="臺灣工藝學校全球學習共享平台" />
     </router-link>
     </router-link>
     <ul class="menu d-md-flex align-center" :class="{ slider: menuShow }">
     <ul class="menu d-md-flex align-center" :class="{ slider: menuShow }">
       <li>重要訊息</li>
       <li>重要訊息</li>
@@ -40,17 +40,17 @@ function toggleMenu() {
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .navbar {
 .navbar {
-  padding: 10px 50px 10px 30px;
-  border-top: 10px solid var(--main-color);
+  padding: 0.625em 3.125em 0.625em 1.875em;
+  border-top: 0.625em solid var(--main-color);
 
 
   @media (max-width: 1200px) {
   @media (max-width: 1200px) {
-    padding: 10px 20px 10px 10px;
+    padding: 0.625em 1.25em 0.625em 0.625em;
   }
   }
 
 
   img {
   img {
     width: 100%;
     width: 100%;
-    max-width: 400px;
-    margin-top: 5px;
+    max-width: 25em;
+    margin-top: 0.3125em;
   }
   }
 
 
   .menu {
   .menu {
@@ -62,7 +62,7 @@ function toggleMenu() {
       height: 0;
       height: 0;
       position: absolute;
       position: absolute;
       background: #fff;
       background: #fff;
-      top: 80px;
+      top: 5em;
       left: 0;
       left: 0;
       right: 0;
       right: 0;
       z-index: 100;
       z-index: 100;
@@ -72,20 +72,20 @@ function toggleMenu() {
     }
     }
 
 
     &.slider {
     &.slider {
-      height: 285px;
+      height: 17.8125em;
     }
     }
 
 
     li {
     li {
-      margin-left: 30px;
+      margin-left: 1.875em;
       font-weight: 500;
       font-weight: 500;
 
 
       @media (max-width: 1200px) {
       @media (max-width: 1200px) {
         margin-left: 0;
         margin-left: 0;
-        border-bottom: 1px solid #f0f0f0;
+        border-bottom: 0.0625em solid #f0f0f0;
         font-weight: 500;
         font-weight: 500;
         width: 100%;
         width: 100%;
         text-align: center;
         text-align: center;
-        padding: 20px 0;
+        padding: 1.25em 0;
       }
       }
       a {
       a {
         color: #000;
         color: #000;

+ 1 - 1
src/components/PDFViewer.vue

@@ -41,7 +41,7 @@ function setPDFUrl(pdf) {
       ref="pdfIframe"
       ref="pdfIframe"
       src="https://ntcri.org/pdf/Re_Ceramic.pdf"
       src="https://ntcri.org/pdf/Re_Ceramic.pdf"
       width="100%"
       width="100%"
-      height="700px"
+      height="43.75em"
       frameborder="0"
       frameborder="0"
       border="0"
       border="0"
       cellspacing="0"
       cellspacing="0"

+ 1 - 0
src/components/SignUpCard.vue

@@ -51,6 +51,7 @@ let currentTitle = computed(() => {
             contain
             contain
             height="128"
             height="128"
             src="https://cdn.vuetifyjs.com/images/logos/v.svg"
             src="https://cdn.vuetifyjs.com/images/logos/v.svg"
+            alt="臺灣工藝學校全球學習共享平台"
           ></v-img>
           ></v-img>
           <h3 class="text-h6 font-weight-light mb-2">Welcome to Vuetify</h3>
           <h3 class="text-h6 font-weight-light mb-2">Welcome to Vuetify</h3>
           <span class="text-caption text-grey">Thanks for signing up!</span>
           <span class="text-caption text-grey">Thanks for signing up!</span>

+ 5 - 5
src/components/TermsList.vue

@@ -97,13 +97,13 @@ li {
   text-indent: 2em; // 縮排
   text-indent: 2em; // 縮排
 }
 }
 h4 {
 h4 {
-  margin: 20px 0;
-  font-size: 18px;
+  margin: 1.25em 0;
+  font-size: 1.125em;
   font-weight: 500;
   font-weight: 500;
 }
 }
 li {
 li {
-  margin: 10px 0;
-  line-height: 30px;
-  letter-spacing: 1px;
+  margin: 0.625em 0;
+  line-height: 1.875em;
+  letter-spacing: 0.0625em;
 }
 }
 </style>
 </style>

+ 22 - 0
src/router/index.js

@@ -16,6 +16,7 @@ const CourseDetail = defineAsyncComponent(() => import('@/views/CourseDetail.vue
 const SetUpCourses = defineAsyncComponent(() => import('@/views/Courses/SetUp.vue'));
 const SetUpCourses = defineAsyncComponent(() => import('@/views/Courses/SetUp.vue'));
 const CreateCourses = defineAsyncComponent(() => import('@/views/Courses/Create.vue'));
 const CreateCourses = defineAsyncComponent(() => import('@/views/Courses/Create.vue'));
 const TutorialCourses = defineAsyncComponent(() => import('@/views/Courses/Tutorial.vue'));
 const TutorialCourses = defineAsyncComponent(() => import('@/views/Courses/Tutorial.vue'));
+const ProposalCourses = defineAsyncComponent(() => import('@/views/Courses/Proposal.vue'));
 
 
 // 八大學群
 // 八大學群
 const CollegeGroup = defineAsyncComponent(() => import('@/views/CollegeGroup/Main.vue'));
 const CollegeGroup = defineAsyncComponent(() => import('@/views/CollegeGroup/Main.vue'));
@@ -297,6 +298,7 @@ const routes = [
     path: '/setup-courses',
     path: '/setup-courses',
     name: 'SetUpCourses',
     name: 'SetUpCourses',
     component: SetUpCourses,
     component: SetUpCourses,
+    meta: { checkToken: true }, // 需驗證登入權限
   },
   },
   {
   {
     path: '/setup-courses/create',
     path: '/setup-courses/create',
@@ -308,6 +310,11 @@ const routes = [
     name: 'TutorialCourses',
     name: 'TutorialCourses',
     component: TutorialCourses,
     component: TutorialCourses,
   },
   },
+  {
+    path: '/setup-courses/proposal',
+    name: 'ProposalCourses',
+    component: ProposalCourses,
+  },
   // {
   // {
   //   path: '/college-group/craft',
   //   path: '/college-group/craft',
   //   name: 'Craft',
   //   name: 'Craft',
@@ -357,6 +364,7 @@ router.beforeEach((to, from, next) => {
     const haveToken = store.loginState;
     const haveToken = store.loginState;
     console.log('store token', store.token);
     console.log('store token', store.token);
     let isTokenExpired = store.checkTokenExpiration(); // 檢查 Token 是否過期
     let isTokenExpired = store.checkTokenExpiration(); // 檢查 Token 是否過期
+    console.log('token是否過期', isTokenExpired);
     if (haveToken) {
     if (haveToken) {
       if (!isTokenExpired) {
       if (!isTokenExpired) {
         next(); // 允許使用者訪問目標頁面
         next(); // 允許使用者訪問目標頁面
@@ -370,6 +378,20 @@ router.beforeEach((to, from, next) => {
       store.loginDialog = true; // 開啟登入視窗
       store.loginDialog = true; // 開啟登入視窗
       next('/'); // 若無 token 直接輸入網址前往時,將重定向至首頁
       next('/'); // 若無 token 直接輸入網址前往時,將重定向至首頁
     }
     }
+  } else if (to.meta.checkToken) {
+    const haveToken = store.loginState;
+    console.log('store token', store.token);
+    let isTokenExpired = store.checkTokenExpiration(); // 檢查 Token 是否過期
+    console.log('token是否過期', isTokenExpired);
+    // 已有 Token && 尚未過期
+    if (haveToken && !isTokenExpired) {
+      next();
+    } else {
+      console.log('無Token');
+      store.loginState = false;
+      localStorage.removeItem("token");
+      next();
+    }
   } else {
   } else {
     // 如果目標路由不需要驗證權限,直接允許使用者訪問
     // 如果目標路由不需要驗證權限,直接允許使用者訪問
     next();
     next();

+ 61 - 9
src/stores/store.js

@@ -1,4 +1,5 @@
 import { defineStore, } from 'pinia';
 import { defineStore, } from 'pinia';
+import axios from "axios";
 
 
 export const useMainStore = defineStore('mainStore', {
 export const useMainStore = defineStore('mainStore', {
   state: () => ({
   state: () => ({
@@ -7,6 +8,10 @@ export const useMainStore = defineStore('mainStore', {
     loginState: false, // 登入狀態
     loginState: false, // 登入狀態
     loginDialog: false, // 登入視窗
     loginDialog: false, // 登入視窗
     profile: {}, // 使用者資訊
     profile: {}, // 使用者資訊
+    mapLocation: { // 地圖經緯度
+      lat: "",
+      lng: ""
+    }
   }),
   }),
   getters: {
   getters: {
     isMobile: () => {
     isMobile: () => {
@@ -28,7 +33,7 @@ export const useMainStore = defineStore('mainStore', {
         this.token = null;
         this.token = null;
         this.loginState = false;
         this.loginState = false;
       }
       }
-
+      
       return this.loginState;
       return this.loginState;
     },
     },
     logout() {
     logout() {
@@ -44,6 +49,33 @@ export const useMainStore = defineStore('mainStore', {
     setProfile(data) {
     setProfile(data) {
       this.profile = data;
       this.profile = data;
     },
     },
+    async getProfile() {
+      try {
+        const response = await axios.get(
+          `https://cmm.ai:8088/api/information?token=${this.token}`
+        );
+        console.log('response', response);
+        if (!response.data.msg) {
+          store.logout();
+          return;
+        } else {
+          this.setProfile(response.data.msg);
+        }
+      } catch (error) {
+        console.error(error);
+      }
+    },
+    async getUserInfo() {
+      try {
+        const response = await axios.get(
+          `https://cmm.ai:8088/api/get_user_information?access_token=${this.token}`
+        );
+
+        return response;
+      } catch (error) {
+        console.error(error);
+      }
+    },
     // 將日期格式轉成純字串
     // 將日期格式轉成純字串
     formatDate(date) {
     formatDate(date) {
       const isTimestamp = !isNaN(date) && Number(date) >= 0; // 判斷是否為時間戳記
       const isTimestamp = !isNaN(date) && Number(date) >= 0; // 判斷是否為時間戳記
@@ -76,18 +108,38 @@ export const useMainStore = defineStore('mainStore', {
     // 開啟登入視窗
     // 開啟登入視窗
     openLoginDialog() {
     openLoginDialog() {
       this.loginDialog = true;
       this.loginDialog = true;
+      console.log('this.loginDialog',this.loginDialog);
     },
     },
     // 調整字串
     // 調整字串
     formatString(content) {
     formatString(content) {
-      if (content) {
-        content = content.replace(/&lt;/g, "<");
-        content = content.replace(/&gt;/g, ">");
-        content = content.replace(/&amp;nbsp;/g, " ");
-        content = content.replace(/&amp;times;/g, "×");
-        content = content.replace(/&amp;#39;/g, "'");
-        content = content.replace(/&middot;/g, "·");
+      const parser = new DOMParser();
+      const decodedText = parser.parseFromString(content, "text/html").body.textContent;
+
+      return decodedText;
+      
+      // if (content) {
+      //   content = content.replace(/&lt;/g, "<");
+      //   content = content.replace(/&gt;/g, ">");
+      //   content = content.replace(/&amp;nbsp;/g, " ");
+      //   content = content.replace(/&amp;times;/g, "×");
+      //   content = content.replace(/&amp;#39;/g, "'");
+      //   content = content.replace(/&middot;/g, "·");
 
 
-        return content;
+      //   return content;
+      // }
+    },
+    // 返回課程圖片網址
+    getImageSrc(data) {
+      const regex = /http/; // 檢查字串中是否包含 http
+
+      if (data.group_id === 9) {
+        return this.getImageUrl("cfa-default.jpg");
+      } else if (data.special_class_list_name === "one_day_class") {
+        return this.getImageUrl("default.png");
+      } else if (regex.test(data.cover_img)) {
+        return data.cover_img;
+      } else {
+        return `https://ntcri.org/${data.cover_img}`;
       }
       }
     },
     },
     checkTokenExpiration() {
     checkTokenExpiration() {

+ 29 - 28
src/views/Article.vue

@@ -237,7 +237,7 @@ function isAnchorLink(url) {
               placeholder="關鍵字搜尋"
               placeholder="關鍵字搜尋"
             />
             />
             <button @click="search()">
             <button @click="search()">
-              <img src="@/assets/img/news/news-search-icon.png" alt="" />
+              <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
             </button>
             </button>
           </span>
           </span>
           <div
           <div
@@ -257,7 +257,7 @@ function isAnchorLink(url) {
             :key="index"
             :key="index"
           >
           >
             <a :href="item.url" target="_blank">
             <a :href="item.url" target="_blank">
-              <img :src="item.img" alt="" />
+              <img :src="item.img" alt="臺灣工藝學校全球學習共享平台" />
             </a>
             </a>
             <section>
             <section>
               <p>{{ item.depiction }}</p>
               <p>{{ item.depiction }}</p>
@@ -282,18 +282,18 @@ function isAnchorLink(url) {
               :href="store.getPDF(item.fileName)"
               :href="store.getPDF(item.fileName)"
               target="_blank"
               target="_blank"
             >
             >
-              <img :src="item.img" alt="" />
+              <img :src="item.img" alt="臺灣工藝學校全球學習共享平台" />
             </a>
             </a>
 
 
             <img
             <img
               v-else
               v-else
               :src="item.img"
               :src="item.img"
-              alt=""
+              alt="臺灣工藝學校全球學習共享平台"
               @click="updatePDF(item.fileName)"
               @click="updatePDF(item.fileName)"
             />
             />
 
 
             <!-- <a :href="item.url" target="_blank">
             <!-- <a :href="item.url" target="_blank">
-              <img :src="item.img" alt="" />
+              <img :src="item.img" alt="臺灣工藝學校全球學習共享平台" />
             </a> -->
             </a> -->
             <section>
             <section>
               <h3 v-html="item.title"></h3>
               <h3 v-html="item.title"></h3>
@@ -317,7 +317,7 @@ function isAnchorLink(url) {
               placeholder="關鍵字搜尋"
               placeholder="關鍵字搜尋"
             />
             />
             <button @click="search()">
             <button @click="search()">
-              <img src="@/assets/img/news/news-search-icon.png" alt="" />
+              <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
             </button>
             </button>
           </span>
           </span>
           <div
           <div
@@ -345,6 +345,7 @@ function isAnchorLink(url) {
                   :lazy-src="item.img"
                   :lazy-src="item.img"
                   :src="item.img"
                   :src="item.img"
                   cover
                   cover
+                  alt="臺灣工藝學校全球學習共享平台"
                 >
                 >
                   <template v-slot:placeholder>
                   <template v-slot:placeholder>
                     <div class="d-flex align-center justify-center fill-height">
                     <div class="d-flex align-center justify-center fill-height">
@@ -359,7 +360,7 @@ function isAnchorLink(url) {
             </a>
             </a>
 
 
             <!-- <a :href="item.url" target="_blank">
             <!-- <a :href="item.url" target="_blank">
-              <img :src="item.img" alt="" />
+              <img :src="item.img" alt="臺灣工藝學校全球學習共享平台" />
             </a> -->
             </a> -->
             <section class="info">
             <section class="info">
               <p v-html="item.content"></p>
               <p v-html="item.content"></p>
@@ -380,8 +381,8 @@ function isAnchorLink(url) {
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 h2 {
 h2 {
-  padding-top: 100px;
-  font-size: 30px;
+  padding-top: 6.25em;
+  font-size: 1.875em;
   font-weight: 500;
   font-weight: 500;
   text-align: center;
   text-align: center;
 }
 }
@@ -400,61 +401,61 @@ h2 {
 .read-list,
 .read-list,
 .book-list {
 .book-list {
   p {
   p {
-    margin-bottom: 10px;
+    margin-bottom: 0.625em;
   }
   }
   h3,
   h3,
   p {
   p {
     font-weight: 500;
     font-weight: 500;
     text-align: center;
     text-align: center;
-    line-height: 30px;
+    line-height: 1.875em;
   }
   }
 }
 }
 
 
 .read-list {
 .read-list {
   img {
   img {
     width: 100%;
     width: 100%;
-    height: 450px;
+    height: 28.125em;
     object-fit: cover;
     object-fit: cover;
     cursor: pointer;
     cursor: pointer;
 
 
     @media (max-width: 1280px) {
     @media (max-width: 1280px) {
-      height: 300px;
+      height: 18.75em;
     }
     }
     @media (max-width: 960px) {
     @media (max-width: 960px) {
       height: auto;
       height: auto;
-      max-width: 300px;
+      max-width: 18.75em;
     }
     }
   }
   }
 
 
   p {
   p {
-    width: 290px;
+    width: 18.125em;
   }
   }
 }
 }
 
 
 .book-list {
 .book-list {
-  margin-bottom: 300px;
+  margin-bottom: 18.75em;
   .info {
   .info {
-    width: 430px;
-    padding: 10px 20px;
+    width: 26.875em;
+    padding: 0.625em 1.25em;
     position: absolute;
     position: absolute;
-    right: -40px;
-    bottom: -60px;
+    right: -2.5em;
+    bottom: -3.75em;
     z-index: 1;
     z-index: 1;
     background: rgba(255, 255, 255, 0.8);
     background: rgba(255, 255, 255, 0.8);
-    border: 2px solid #c8cbcc;
+    border: 0.125em solid #c8cbcc;
 
 
     @media (max-width: 1280px) {
     @media (max-width: 1280px) {
-      width: 400px;
+      width: 25em;
     }
     }
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      width: 330px;
-      right: -3px;
-      bottom: -80px;
+      width: 20.625em;
+      right: -0.1875em;
+      bottom: -5em;
     }
     }
 
 
     p {
     p {
-      width: 300px;
+      width: 18.75em;
       margin-bottom: 0;
       margin-bottom: 0;
       text-align: start;
       text-align: start;
     }
     }
@@ -462,8 +463,8 @@ h2 {
       display: block;
       display: block;
       margin-top: auto;
       margin-top: auto;
       position: absolute;
       position: absolute;
-      bottom: 15px;
-      right: 15px;
+      bottom: 0.9375em;
+      right: 0.9375em;
     }
     }
   }
   }
 }
 }

+ 25 - 25
src/views/ArticleDetail.vue

@@ -60,7 +60,7 @@ getArticle();
 <template>
 <template>
   <Navbar />
   <Navbar />
   <div class="position-relative mb-16">
   <div class="position-relative mb-16">
-    <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
+    <img src="@/assets/img/news/news-01.png" alt="臺灣工藝學校全球學習共享平台" class="material-img" />
     <v-container class="pa-0 pt-16 position-relative">
     <v-container class="pa-0 pt-16 position-relative">
       <div class="content">
       <div class="content">
         <div class="article">
         <div class="article">
@@ -79,6 +79,7 @@ getArticle();
                 class="cover-img my-10"
                 class="cover-img my-10"
                 :lazy-src="`https://ntcri.org/${list.data.cover_img}`"
                 :lazy-src="`https://ntcri.org/${list.data.cover_img}`"
                 :src="`https://ntcri.org/${list.data.cover_img}`"
                 :src="`https://ntcri.org/${list.data.cover_img}`"
+                alt="臺灣工藝學校全球學習共享平台"
               >
               >
                 <template v-slot:placeholder>
                 <template v-slot:placeholder>
                   <div class="d-flex align-center justify-center fill-height">
                   <div class="d-flex align-center justify-center fill-height">
@@ -129,7 +130,7 @@ getArticle();
     <a href="javascript:;" v-else @click="router.go(-1)" class="back-link"
     <a href="javascript:;" v-else @click="router.go(-1)" class="back-link"
       >< 回到上一頁</a
       >< 回到上一頁</a
     >
     >
-    <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
+    <img src="@/assets/img/news/news-01.png" alt="臺灣工藝學校全球學習共享平台" class="material-img" />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -140,8 +141,8 @@ p {
 
 
 ul {
 ul {
   a {
   a {
-    line-height: 24px;
-    letter-spacing: 1px;
+    line-height: 1.5em;
+    letter-spacing: 0.0625em;
     transition: all 0.3s;
     transition: all 0.3s;
     &:hover {
     &:hover {
       opacity: 0.8;
       opacity: 0.8;
@@ -154,11 +155,11 @@ ul {
 }
 }
 
 
 .content {
 .content {
-  padding: 20px;
+  padding: 1.25em;
   background-image: url("@/assets/img/news/news-02.png");
   background-image: url("@/assets/img/news/news-02.png");
   background-position: center;
   background-position: center;
   background-size: cover;
   background-size: cover;
-  border-radius: 50px;
+  border-radius: 3.125em;
   @media (max-width: 960px) {
   @media (max-width: 960px) {
     width: 90%;
     width: 90%;
     margin: auto;
     margin: auto;
@@ -166,63 +167,62 @@ ul {
 }
 }
 .article {
 .article {
   margin: auto;
   margin: auto;
-  padding: 80px 50px;
+  padding: 5em 3.125em;
   display: flex;
   display: flex;
   justify-content: center;
   justify-content: center;
-  border: 1px solid #d4d6d8;
-  border-radius: 50px;
+  border: 0.0625em solid #d4d6d8;
+  border-radius: 3.125em;
 
 
   // @media (max-width: 960px) {
   // @media (max-width: 960px) {
   //   width: 80%;
   //   width: 80%;
   // }
   // }
 
 
   @media (max-width: 600px) {
   @media (max-width: 600px) {
-    padding: 50px 0;
+    padding: 3.125em 0;
     border: none;
     border: none;
   }
   }
 
 
   h2 {
   h2 {
-    margin: 40px auto;
-    font-size: 28px;
+    font-size: 1.75em;
     font-weight: 500;
     font-weight: 500;
-    line-height: 38px;
-    letter-spacing: 2px;
+    line-height: 30.5em;
+    letter-spacing: 0.125em;
   }
   }
   section {
   section {
     height: 100%;
     height: 100%;
-    padding: 30px;
+    padding: 1.875em;
     p {
     p {
-      font-size: 18px;
+      font-size: 1.125em;
       font-weight: 400;
       font-weight: 400;
-      line-height: 32px;
-      letter-spacing: 1px;
+      line-height: 2em;
+      letter-spacing: 0.0625em;
       white-space: pre-line;
       white-space: pre-line;
     }
     }
   }
   }
 
 
   .cover-img {
   .cover-img {
     width: 100%;
     width: 100%;
-    max-height: 500px;
+    max-height: 31.25em;
     @media (max-width: 600px) {
     @media (max-width: 600px) {
       height: auto;
       height: auto;
     }
     }
   }
   }
 }
 }
 .bg-img {
 .bg-img {
-  height: 1000px;
+  height: 62.5em;
   position: relative;
   position: relative;
   z-index: -1;
   z-index: -1;
   @media (max-width: 600px) {
   @media (max-width: 600px) {
-    height: 650px;
+    height: 40.625em;
   }
   }
 }
 }
 
 
 .back-link {
 .back-link {
-  margin-top: 50px;
+  margin-top: 3.125em;
   display: block;
   display: block;
   text-align: center;
   text-align: center;
   transition: all 0.3s;
   transition: all 0.3s;
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 
 
   &:hover {
   &:hover {
     opacity: 0.8;
     opacity: 0.8;
@@ -236,12 +236,12 @@ ul {
   }
   }
 
 
   &:last-child {
   &:last-child {
-    bottom: -130px;
+    bottom: -8.125em;
     z-index: -5;
     z-index: -5;
     transform: scaleX(-1);
     transform: scaleX(-1);
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      bottom: -50px;
+      bottom: -3.125em;
     }
     }
   }
   }
 }
 }

+ 29 - 20
src/views/CollegeGroup/Cfa.vue

@@ -123,22 +123,30 @@ let coursePageNum = ref(1); // 頁數(預設第一頁)
 let coursePageAmount = ref(6); // 每頁顯示筆數
 let coursePageAmount = ref(6); // 每頁顯示筆數
 let courseTotalPages = ref(1); // 總頁數
 let courseTotalPages = ref(1); // 總頁數
 let courseLoading = ref(false);
 let courseLoading = ref(false);
+let courseList = ref(null);
 
 
 const courseData = reactive({
 const courseData = reactive({
   classes: [],
   classes: [],
 });
 });
 
 
+// 切換分頁時回到列表上方
+watch(coursePageNum, () => {
+  getClass();
+  courseList.value.scrollIntoView({ behavior: "smooth", block: "start" });
+});
+
+// group_sort 希望工程
 async function getClass() {
 async function getClass() {
   courseLoading.value = true;
   courseLoading.value = true;
 
 
   try {
   try {
     const response = await axios.get(
     const response = await axios.get(
-      `https://cmm.ai:8088/api/get_class_name?group_sort=希望工程&is_check=1&page_num=${coursePageNum.value}&page_amount=${coursePageAmount.value}`
+      `https://cmm.ai:8088/api/get_class_name?group_id=9&is_check=1&page_num=${coursePageNum.value}&page_amount=${coursePageAmount.value}`
     );
     );
     courseTotalPages.value = store.getTotalPages(response.data.total_num, 6);
     courseTotalPages.value = store.getTotalPages(response.data.total_num, 6);
     courseData.classes = response.data.classes;
     courseData.classes = response.data.classes;
     courseLoading.value = false;
     courseLoading.value = false;
-    console.log("getClass response", courseData.classes);
+    console.log("getClass 希望工程", courseData.classes);
   } catch (error) {
   } catch (error) {
     courseLoading.value = false;
     courseLoading.value = false;
     console.error(error);
     console.error(error);
@@ -174,7 +182,7 @@ getClass();
         <img
         <img
           class="img-fluid"
           class="img-fluid"
           src="@/assets/img/college-group/life/生活工藝素材-24.png"
           src="@/assets/img/college-group/life/生活工藝素材-24.png"
-          alt=""
+          alt="臺灣工藝學校全球學習共享平台"
         />
         />
       </div>
       </div>
     </v-col>
     </v-col>
@@ -200,8 +208,9 @@ getClass();
               class="mx-auto cover-img"
               class="mx-auto cover-img"
               :lazy-src="item.pic_url"
               :lazy-src="item.pic_url"
               :src="item.pic_url"
               :src="item.pic_url"
-              height="270px"
+              height="16.875em"
               cover
               cover
+              alt="臺灣工藝學校全球學習共享平台"
             >
             >
               <template v-slot:placeholder>
               <template v-slot:placeholder>
                 <div class="d-flex align-center justify-center fill-height">
                 <div class="d-flex align-center justify-center fill-height">
@@ -222,7 +231,7 @@ getClass();
 
 
       <!-- <div class="main-card">
       <!-- <div class="main-card">
         <div class="card-info">
         <div class="card-info">
-          <img :src="item.pic_url" alt="" class="cover-img" />
+          <img :src="item.pic_url" alt="臺灣工藝學校全球學習共享平台" class="cover-img" />
         </div>
         </div>
         <section class="card-title">
         <section class="card-title">
           <h3>{{ item.pic_name }}</h3>
           <h3>{{ item.pic_name }}</h3>
@@ -267,8 +276,8 @@ getClass();
     class="mt-16"
     class="mt-16"
   ></v-pagination>
   ></v-pagination>
 
 
-  <div class="title">
-    <h2>常見問題</h2>
+  <div>
+    <h2 class="title">常見問題</h2>
   </div>
   </div>
 
 
   <v-expansion-panels>
   <v-expansion-panels>
@@ -278,8 +287,8 @@ getClass();
     </v-expansion-panel>
     </v-expansion-panel>
   </v-expansion-panels>
   </v-expansion-panels>
 
 
-  <div class="title" ref="mediaList">
-    <h2>臺灣綠工藝希望工程-課程</h2>
+  <div ref="courseList">
+    <h2 class="title">臺灣綠工藝希望工程-課程</h2>
   </div>
   </div>
 
 
   <div class="d-flex justify-center mb-10" v-if="courseLoading">
   <div class="d-flex justify-center mb-10" v-if="courseLoading">
@@ -332,14 +341,14 @@ getClass();
 
 
 p {
 p {
   font-weight: 400;
   font-weight: 400;
-  letter-spacing: 1px;
-  line-height: 30px;
+  letter-spacing: 0.0625em;
+  line-height: 1.875em;
 }
 }
 
 
 .tgc-report {
 .tgc-report {
   li {
   li {
-    padding: 30px 0;
-    border-bottom: 1px solid #c9c9c9;
+    padding: 1.875em 0;
+    border-bottom: 0.0625em solid #c9c9c9;
     .info {
     .info {
       a {
       a {
         transition: all 0.3s;
         transition: all 0.3s;
@@ -359,20 +368,20 @@ p {
   }
   }
 }
 }
 .time-block {
 .time-block {
-  padding: 0 0 0 20px;
+  padding: 0 0 0 1.25em;
   span {
   span {
-    width: 90px;
+    width: 5.625em;
     display: block;
     display: block;
   }
   }
 }
 }
 .v-expansion-panel-title,
 .v-expansion-panel-title,
 .v-expansion-panel-text {
 .v-expansion-panel-text {
-  font-size: 16px;
-  line-height: 30px;
-  letter-spacing: 1px;
+  font-size: 1em;
+  line-height: 1.875em;
+  letter-spacing: 0.0625em;
 }
 }
 .v-expansion-panel-text {
 .v-expansion-panel-text {
-  padding: 15px 20px;
-  font-size: 16px;
+  padding: 0.9375em 1.25em;
+  font-size: 1em;
 }
 }
 </style>
 </style>

+ 59 - 47
src/views/CollegeGroup/Craft.vue

@@ -172,10 +172,10 @@ const articles = reactive({
   ></v-breadcrumbs>
   ></v-breadcrumbs>
 
 
   <div
   <div
-    class="d-flex flex-column flex-sm-row align-center justify-space-between title"
+    class="d-flex flex-column flex-sm-row align-center justify-space-between"
     id="lightCraft"
     id="lightCraft"
   >
   >
-    <h2>專業工藝課程</h2>
+    <h2 class="title">專業工藝課程</h2>
     <div class="search">
     <div class="search">
       <span>
       <span>
         <input
         <input
@@ -185,7 +185,10 @@ const articles = reactive({
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="search()">
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img
+            src="@/assets/img/news/news-search-icon.png"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
         </button>
         </button>
       </span>
       </span>
       <div
       <div
@@ -239,7 +242,7 @@ const articles = reactive({
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="search()">
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
         </button>
         </button>
       </span>
       </span>
       <div
       <div
@@ -263,7 +266,10 @@ const articles = reactive({
                 $router.resolve(`/course-detail/${item.class_name_id}`).href
                 $router.resolve(`/course-detail/${item.class_name_id}`).href
               "
               "
             >
             >
-              <img :src="`https://ntcri.org/${item.cover_img}`" alt="" />
+              <img
+                :src="`https://ntcri.org/${item.cover_img}`"
+                alt="臺灣工藝學校全球學習共享平台"
+              />
             </a>
             </a>
           </v-col>
           </v-col>
           <v-col cols="12" md="8">
           <v-col cols="12" md="8">
@@ -387,7 +393,10 @@ const articles = reactive({
       md="6"
       md="6"
       class="v-col-md-6 v-col-12 d-flex flex-column flex-md-row align-center justify-md-center"
       class="v-col-md-6 v-col-12 d-flex flex-column flex-md-row align-center justify-md-center"
     >
     >
-      <img src="@/assets/img/college-group/repair/修護-12.png" alt="" />
+      <img
+        src="@/assets/img/college-group/repair/修護-12.png"
+        alt="臺灣工藝學校全球學習共享平台"
+      />
       <section class="mt-5 mt-md-0 ms-md-5">
       <section class="mt-5 mt-md-0 ms-md-5">
         <h3>廖偉淇</h3>
         <h3>廖偉淇</h3>
         <span class="d-block mt-3 mb-5">金工木印工作室</span>
         <span class="d-block mt-3 mb-5">金工木印工作室</span>
@@ -404,7 +413,10 @@ const articles = reactive({
       md="6"
       md="6"
       class="v-col-md-6 v-col-12 d-flex flex-column flex-md-row align-center justify-md-center"
       class="v-col-md-6 v-col-12 d-flex flex-column flex-md-row align-center justify-md-center"
     >
     >
-      <img src="@/assets/img/college-group/repair/修護-13.png" alt="" />
+      <img
+        src="@/assets/img/college-group/repair/修護-13.png"
+        alt="臺灣工藝學校全球學習共享平台"
+      />
       <section class="mt-5 mt-md-0 ms-md-5">
       <section class="mt-5 mt-md-0 ms-md-5">
         <h3>陳高登</h3>
         <h3>陳高登</h3>
         <span class="d-block mt-3 mb-5">金工木印工作室</span>
         <span class="d-block mt-3 mb-5">金工木印工作室</span>
@@ -438,7 +450,7 @@ const articles = reactive({
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="search()">
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
         </button>
         </button>
       </span>
       </span>
       <div
       <div
@@ -493,7 +505,7 @@ const articles = reactive({
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="search()">
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
         </button>
         </button>
       </span>
       </span>
       <div
       <div
@@ -555,28 +567,28 @@ h3 {
 
 
 p {
 p {
   font-weight: 400;
   font-weight: 400;
-  letter-spacing: 1px;
-  line-height: 28px;
+  letter-spacing: 0.0625em;
+  line-height: 1.75em;
 }
 }
 
 
 .article-block {
 .article-block {
   h4 {
   h4 {
-    font-size: 26px;
+    font-size: 1.625em;
     font-weight: 400;
     font-weight: 400;
-    line-height: 40px;
+    line-height: 2.5em;
   }
   }
 
 
   .v-btn {
   .v-btn {
-    height: 70px;
+    height: 4.375em;
     color: #fff;
     color: #fff;
     font-weight: 400;
     font-weight: 400;
-    border-radius: 100px;
+    border-radius: 6.25em;
     background-color: var(--brown);
     background-color: var(--brown);
     @media (max-width: 960px) {
     @media (max-width: 960px) {
-      font-size: 14px;
+      font-size: 0.875em;
     }
     }
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      font-size: 16px;
+      font-size: 1em;
     }
     }
   }
   }
 }
 }
@@ -584,23 +596,23 @@ p {
 .course-list {
 .course-list {
   .v-card {
   .v-card {
     border: none;
     border: none;
-    border-radius: 20px;
+    border-radius: 1.25em;
     background-color: #e9f1f4;
     background-color: #e9f1f4;
     h2 {
     h2 {
       width: 100%;
       width: 100%;
-      font-size: 24px;
-      line-height: 30px;
-      letter-spacing: 1px;
-      border-bottom: 3px solid #fff;
+      font-size: 1.5em;
+      line-height: 1.875em;
+      letter-spacing: 0.0625em;
+      border-bottom: 0.1875em solid #fff;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 22px;
+        font-size: 1.375em;
       }
       }
     }
     }
     .content {
     .content {
-      padding: 20px 0;
+      padding: 1.25em 0;
       p:first-child {
       p:first-child {
         font-weight: 400;
         font-weight: 400;
-        line-height: 28px;
+        line-height: 1.75em;
         color: #606064;
         color: #606064;
       }
       }
     }
     }
@@ -611,7 +623,7 @@ p {
 .story-list {
 .story-list {
   img {
   img {
     width: 100%;
     width: 100%;
-    max-width: 300px;
+    max-width: 18.75em;
     object-fit: cover;
     object-fit: cover;
     @media (max-width: 960px) {
     @media (max-width: 960px) {
       max-width: 100%;
       max-width: 100%;
@@ -619,10 +631,10 @@ p {
     }
     }
   }
   }
   h3 {
   h3 {
-    font-size: 24px;
+    font-size: 1.5em;
     font-weight: 500;
     font-weight: 500;
-    line-height: 30px;
-    letter-spacing: 1px;
+    line-height: 1.875em;
+    letter-spacing: 0.0625em;
   }
   }
   p {
   p {
     // 超過兩行則省略
     // 超過兩行則省略
@@ -635,72 +647,72 @@ p {
   }
   }
 
 
   .date {
   .date {
-    font-size: 20px;
+    font-size: 1.25em;
     font-weight: 400;
     font-weight: 400;
   }
   }
 }
 }
 
 
 .master-list {
 .master-list {
   img {
   img {
-    width: 250px;
-    height: 250px;
+    width: 15.625em;
+    height: 15.625em;
     object-fit: cover;
     object-fit: cover;
   }
   }
   h3 {
   h3 {
-    font-size: 20px;
+    font-size: 1.25em;
     color: #000;
     color: #000;
   }
   }
   section {
   section {
     text-align: center;
     text-align: center;
     color: #606064;
     color: #606064;
     li {
     li {
-      line-height: 28px;
+      line-height: 1.75em;
     }
     }
   }
   }
 }
 }
 
 
 .past-btn {
 .past-btn {
-  padding: 15px 40px;
+  padding: 0.9375em 2.5em;
   color: #606064;
   color: #606064;
-  border-radius: 100px;
-  border: 2px solid #569f33;
+  border-radius: 6.25em;
+  border: 0.125em solid #569f33;
 }
 }
 
 
 .content {
 .content {
   padding: 0;
   padding: 0;
   width: 90%;
   width: 90%;
   .main-block {
   .main-block {
-    padding: 100px 80px;
+    padding: 6.25em 5em;
     margin-top: -30%;
     margin-top: -30%;
     background-color: #fff;
     background-color: #fff;
 
 
     @media (max-width: 960px) {
     @media (max-width: 960px) {
-      padding: 100px 50px;
+      padding: 6.25em 3.125em;
     }
     }
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      padding: 100px 20px;
+      padding: 6.25em 1.25em;
     }
     }
 
 
     h2 {
     h2 {
-      font-size: 30px;
+      font-size: 1.875em;
       font-weight: 500;
       font-weight: 500;
-      line-height: 32px;
-      margin-left: 10px;
+      line-height: 2em;
+      margin-left: 0.625em;
 
 
       @media (max-width: 960px) {
       @media (max-width: 960px) {
-        font-size: 24px;
+        font-size: 1.5em;
       }
       }
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
         margin-left: 0;
         margin-left: 0;
-        margin-bottom: 50px;
+        margin-bottom: 3.125em;
       }
       }
     }
     }
     .title {
     .title {
-      margin: 80px 0;
+      margin: 5em 0;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        margin: 50px 0;
+        margin: 3.125em 0;
       }
       }
     }
     }
     .v-breadcrumbs {
     .v-breadcrumbs {

+ 54 - 23
src/views/CollegeGroup/Cross.vue

@@ -171,9 +171,9 @@ async function handleSearch() {
 
 
   <div
   <div
     ref="listLocation"
     ref="listLocation"
-    class="d-flex flex-column flex-sm-row align-center justify-space-between title"
+    class="d-flex flex-column flex-sm-row align-center justify-space-between"
   >
   >
-    <h2>所有課程</h2>
+    <h2 class="title">所有課程</h2>
     <div class="search">
     <div class="search">
       <span>
       <span>
         <input
         <input
@@ -183,7 +183,10 @@ async function handleSearch() {
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="handleSearch()">
         <button @click="handleSearch()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img
+            src="@/assets/img/news/news-search-icon.png"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
         </button>
         </button>
       </span>
       </span>
       <div
       <div
@@ -288,27 +291,37 @@ async function handleSearch() {
     >總筆數:{{ totalNum }}</span
     >總筆數:{{ totalNum }}</span
   >
   >
 
 
-  <div class="title mt-16">
-    <h2>工藝中心開課</h2>
+  <div class="mt-16">
+    <h2 class="title">工藝中心開課</h2>
   </div>
   </div>
 
 
   <p class="cooming-soon">「籌備中 cooming soon」</p>
   <p class="cooming-soon">「籌備中 cooming soon」</p>
+
+  <h2 class="title">臺灣工藝數位鏈</h2>
+
+  <a
+    href="https://craftplus.ksi.com.tw/"
+    target="_blank"
+    class="craftplus-item"
+  >
+    <!-- <img src="@/assets/img/college-group/cross.webp" alt="臺灣工藝數位鏈" /> -->
+  </a>
 </template>
 </template>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .main-block {
 .main-block {
   h2 {
   h2 {
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      margin-bottom: 30px;
+      margin-bottom: 1.875em;
     }
     }
   }
   }
 }
 }
 
 
 .v-input {
 .v-input {
   @media (max-width: 600px) {
   @media (max-width: 600px) {
-    max-width: 250px;
+    max-width: 15.625em;
     margin: auto;
     margin: auto;
-    margin-top: -20px;
+    margin-top: -1.25em;
   }
   }
 }
 }
 
 
@@ -318,7 +331,7 @@ async function handleSearch() {
       height: 40%;
       height: 40%;
 
 
       h3 {
       h3 {
-        font-size: 18px;
+        font-size: 1.125em;
         font-weight: 500;
         font-weight: 500;
       }
       }
     }
     }
@@ -331,11 +344,11 @@ async function handleSearch() {
         justify-content: center;
         justify-content: center;
 
 
         li:first-child {
         li:first-child {
-          margin-bottom: 5px;
+          margin-bottom: 0.3125em;
         }
         }
 
 
         p {
         p {
-          font-size: 14px;
+          font-size: 0.875em;
         }
         }
       }
       }
     }
     }
@@ -343,38 +356,56 @@ async function handleSearch() {
 }
 }
 
 
 .list {
 .list {
-  max-width: 850px;
-  margin: 100px auto 50px;
+  max-width: 53.125em;
+  margin: 6.25em auto 3.125em;
   @media (max-width: 600px) {
   @media (max-width: 600px) {
-    margin: 50px auto;
+    margin: 3.125em auto;
   }
   }
   section {
   section {
-    margin-bottom: 50px;
+    margin-bottom: 3.125em;
     text-align: center;
     text-align: center;
     h3 {
     h3 {
-      margin-left: -20px;
-      margin-bottom: 25px;
+      margin-left: -1.25em;
+      margin-bottom: 1.5625em;
       list-style: disc;
       list-style: disc;
-      font-size: 28px;
+      font-size: 1.75em;
       font-weight: 500;
       font-weight: 500;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 22px;
+        font-size: 1.375em;
       }
       }
       &::before {
       &::before {
         content: "\2022"; /* Unicode 編碼 */
         content: "\2022"; /* Unicode 編碼 */
         font-size: 1.2em;
         font-size: 1.2em;
         color: #bca2b5;
         color: #bca2b5;
         position: relative;
         position: relative;
-        top: 3px;
+        top: 0.1875em;
       }
       }
     }
     }
     p {
     p {
-      line-height: 28px;
-      letter-spacing: 1px;
+      line-height: 1.75em;
+      letter-spacing: 0.0625em;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 14px;
+        font-size: 0.875em;
       }
       }
     }
     }
   }
   }
 }
 }
+
+.craftplus-item {
+  display: block;
+  height: 380px;
+  // 透明度 0.6 的黑色半透明遮罩
+  background-color: rgba(0, 0, 0, 0.2);
+  // 設置背景混和模式為相乘模式
+  background-blend-mode: multiply;
+  background-image: url("@/assets/img/college-group/cross.webp");
+  background-size: cover;
+  background-position: center center;
+  border-radius: 10px;
+  transition: all 0.3s;
+
+  &:hover {
+    background-color: transparent;
+  }
+}
 </style>
 </style>

+ 47 - 44
src/views/CollegeGroup/Future.vue

@@ -46,13 +46,14 @@ let read = reactive({
     class="mt-10 p-0"
     class="mt-10 p-0"
   ></v-breadcrumbs>
   ></v-breadcrumbs>
 
 
-  <div class="title">
-    <h2 class="mb-0">研發補助</h2>
-  </div>
+  <h2 class="mb-0 title">研發補助</h2>
 
 
   <v-container class="pa-0 pa-sm-3">
   <v-container class="pa-0 pa-sm-3">
     <div class="content">
     <div class="content">
-      <img src="@/assets/img/college-group/future/素材-07.png" alt="" />
+      <img
+        src="@/assets/img/college-group/future/素材-07.png"
+        alt="臺灣工藝學校全球學習共享平台"
+      />
       <section>
       <section>
         <h3 class="mb-10">工藝跨域研創補助計畫【徵件至9月28日止】</h3>
         <h3 class="mb-10">工藝跨域研創補助計畫【徵件至9月28日止】</h3>
         <span class="d-flex align-center mb-2">
         <span class="d-flex align-center mb-2">
@@ -93,14 +94,12 @@ let read = reactive({
       <img
       <img
         class="mt-16"
         class="mt-16"
         src="@/assets/img/college-group/future/素材-08.png"
         src="@/assets/img/college-group/future/素材-08.png"
-        alt=""
+        alt="臺灣工藝學校全球學習共享平台"
       />
       />
     </div>
     </div>
   </v-container>
   </v-container>
 
 
-  <div class="title">
-    <h2>研究計畫</h2>
-  </div>
+  <h2 class="title">研究計畫</h2>
 
 
   <v-container class="book-block">
   <v-container class="book-block">
     <v-row
     <v-row
@@ -115,7 +114,10 @@ let read = reactive({
           target="_blank"
           target="_blank"
           class="cover-img"
           class="cover-img"
         >
         >
-          <img :src="`https://ntcri.org/${item.cover_img}`" alt="" />
+          <img
+            :src="`https://ntcri.org/${item.cover_img}`"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
           <button class="read-btn">點我閱讀</button>
           <button class="read-btn">點我閱讀</button>
         </a>
         </a>
 
 
@@ -125,7 +127,10 @@ let read = reactive({
           :to="`/college-group/future/proposal/${item.article_id}`"
           :to="`/college-group/future/proposal/${item.article_id}`"
           class="cover-img"
           class="cover-img"
         >
         >
-          <img :src="`https://ntcri.org/${item.cover_img}`" alt="" />
+          <img
+            :src="`https://ntcri.org/${item.cover_img}`"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
           <button class="read-btn">點我閱讀</button>
           <button class="read-btn">點我閱讀</button>
         </router-link>
         </router-link>
         <h3 v-html="item.title"></h3>
         <h3 v-html="item.title"></h3>
@@ -136,58 +141,56 @@ let read = reactive({
     </v-row>
     </v-row>
   </v-container>
   </v-container>
 
 
-  <div class="title">
-    <h2>國際工藝村</h2>
+  <div>
+    <h2 class="title">國際工藝村</h2>
+    <p class="cooming-soon">「籌備中 cooming soon」</p>
   </div>
   </div>
 
 
-  <p class="cooming-soon">「籌備中 cooming soon」</p>
-
-  <div class="title">
-    <h2>青年工藝</h2>
+  <div>
+    <h2 class="title">青年工藝</h2>
+    <p class="cooming-soon">「籌備中 cooming soon」</p>
   </div>
   </div>
 
 
-  <p class="cooming-soon">「籌備中 cooming soon」</p>
-
   <!-- <button class="sloped-btn">點我閱讀</button> -->
   <!-- <button class="sloped-btn">點我閱讀</button> -->
 </template>
 </template>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .content {
 .content {
   margin: auto;
   margin: auto;
-  max-width: 800px;
-  letter-spacing: 1px;
+  max-width: 50em;
+  letter-spacing: 0.0625em;
 
 
   p {
   p {
-    line-height: 28px;
+    line-height: 1.75em;
   }
   }
 
 
   section {
   section {
-    padding: 50px;
-    margin-top: 20px;
-    border: 1px solid #ccc;
-    border-radius: 5px;
+    padding: 3.125em;
+    margin-top: 1.25em;
+    border: 0.0625em solid #ccc;
+    border-radius: 0.3125em;
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      padding: 25px;
+      padding: 1.5625em;
     }
     }
 
 
     h3 {
     h3 {
       font-weight: 500;
       font-weight: 500;
-      font-size: 28px;
-      line-height: 36px;
+      font-size: 1.75em;
+      line-height: 2.25em;
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 22px;
+        font-size: 1.375em;
       }
       }
     }
     }
 
 
     a,
     a,
     span {
     span {
-      line-height: 22px;
+      line-height: 1.375em;
     }
     }
 
 
     .sub-title {
     .sub-title {
-      font-size: 18px;
+      font-size: 1.125em;
     }
     }
 
 
     li {
     li {
@@ -204,8 +207,8 @@ let read = reactive({
 }
 }
 
 
 .book-block {
 .book-block {
-  line-height: 30px;
-  letter-spacing: 1px;
+  line-height: 1.875em;
+  letter-spacing: 0.0625em;
 
 
   @media (max-width: 600px) {
   @media (max-width: 600px) {
     padding: 0 !important;
     padding: 0 !important;
@@ -216,7 +219,7 @@ let read = reactive({
     font-weight: 500;
     font-weight: 500;
   }
   }
   h4 {
   h4 {
-    font-size: 18px;
+    font-size: 1.125em;
     font-weight: 400;
     font-weight: 400;
   }
   }
   .cover-img {
   .cover-img {
@@ -225,7 +228,7 @@ let read = reactive({
 
 
     img {
     img {
       @media (max-width: 960px) {
       @media (max-width: 960px) {
-        max-height: 500px;
+        max-height: 31.25em;
       }
       }
     }
     }
 
 
@@ -235,13 +238,13 @@ let read = reactive({
       }
       }
     }
     }
     .read-btn {
     .read-btn {
-      padding: 8px 50px;
+      padding: 0.5em 3.125em;
       position: absolute;
       position: absolute;
-      right: -50px;
-      bottom: 45px;
-      font-size: 18px;
-      letter-spacing: 2px;
-      text-shadow: 1px 1px 3px #939393;
+      right: -3.125em;
+      bottom: 2.8125em;
+      font-size: 1.125em;
+      letter-spacing: 0.125em;
+      text-shadow: 0.0625em 0.0625em 0.1875em #939393;
       background-color: #a7c2cd;
       background-color: #a7c2cd;
       color: white;
       color: white;
       cursor: pointer;
       cursor: pointer;
@@ -252,9 +255,9 @@ let read = reactive({
       }
       }
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        padding: 8px 35px;
-        right: -15px;
-        font-size: 16px;
+        padding: 0.5em 2.1875em;
+        right: -0.9375em;
+        font-size: 1em;
       }
       }
     }
     }
   }
   }

+ 7 - 9
src/views/CollegeGroup/Generation.vue

@@ -71,13 +71,11 @@ const breadcrumbs = reactive([
     class="mt-10 p-0"
     class="mt-10 p-0"
   ></v-breadcrumbs>
   ></v-breadcrumbs>
 
 
-  <div class="title">
-    <h2>人間國寶</h2>
-  </div>
+  <h2 class="title">人間國寶</h2>
 
 
   <v-row>
   <v-row>
     <v-col md="6" cols="12" v-for="(item, index) in data" :key="index">
     <v-col md="6" cols="12" v-for="(item, index) in data" :key="index">
-      <img :src="item.img" alt="" />
+      <img :src="item.img" alt="臺灣工藝學校全球學習共享平台" />
       <h3>{{ item.name }}</h3>
       <h3>{{ item.name }}</h3>
       <h4 v-if="item.title !== ''" class="mt-2">{{ item.title }}</h4>
       <h4 v-if="item.title !== ''" class="mt-2">{{ item.title }}</h4>
     </v-col>
     </v-col>
@@ -91,7 +89,7 @@ const breadcrumbs = reactive([
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .v-row {
 .v-row {
-  padding-bottom: 30px;
+  padding-bottom: 1.875em;
 }
 }
 
 
 h3,
 h3,
@@ -101,11 +99,11 @@ h4 {
 }
 }
 
 
 small {
 small {
-  font-size: 18px;
-  letter-spacing: 1px;
+  font-size: 1.125em;
+  letter-spacing: 0.0625em;
   @media (max-width: 960px) {
   @media (max-width: 960px) {
-    font-size: 16px;
-    padding-bottom: 5px;
+    font-size: 1em;
+    padding-bottom: 0.3125em;
   }
   }
 }
 }
 </style>
 </style>

+ 16 - 16
src/views/CollegeGroup/Life.vue

@@ -50,7 +50,7 @@ const breadcrumbs = reactive([
     <router-link to="/college-group/life/shop">
     <router-link to="/college-group/life/shop">
       <v-row>
       <v-row>
         <v-col cols="12" md="4" lg="5" class="pa-0 overflow-hidden">
         <v-col cols="12" md="4" lg="5" class="pa-0 overflow-hidden">
-          <img src="@/assets/img/college-group/life/cover-01.png" alt="" />
+          <img src="@/assets/img/college-group/life/cover-01.png" alt="臺灣工藝學校全球學習共享平台" />
         </v-col>
         </v-col>
         <v-col cols="12" md="8" lg="7" class="content">
         <v-col cols="12" md="8" lg="7" class="content">
           <h3 class="mb-5">旅物 SHOP</h3>
           <h3 class="mb-5">旅物 SHOP</h3>
@@ -74,7 +74,7 @@ const breadcrumbs = reactive([
           </p>
           </p>
         </v-col>
         </v-col>
         <v-col cols="12" md="4" lg="5" class="pa-0 overflow-hidden">
         <v-col cols="12" md="4" lg="5" class="pa-0 overflow-hidden">
-          <img src="@/assets/img/college-group/life/cover-02.png" alt="" />
+          <img src="@/assets/img/college-group/life/cover-02.png" alt="臺灣工藝學校全球學習共享平台" />
         </v-col>
         </v-col>
       </v-row>
       </v-row>
     </router-link>
     </router-link>
@@ -92,7 +92,7 @@ const breadcrumbs = reactive([
           </p>
           </p>
         </v-col>
         </v-col>
         <v-col cols="12" md="4" lg="5" class="pa-0 overflow-hidden">
         <v-col cols="12" md="4" lg="5" class="pa-0 overflow-hidden">
-          <img src="@/assets/img/college-group/life/cover-03.png" alt="" />
+          <img src="@/assets/img/college-group/life/cover-03.png" alt="臺灣工藝學校全球學習共享平台" />
         </v-col>
         </v-col>
       </v-row>
       </v-row>
     </router-link>
     </router-link>
@@ -100,7 +100,7 @@ const breadcrumbs = reactive([
     <router-link to="/college-group/life/campus">
     <router-link to="/college-group/life/campus">
       <v-row>
       <v-row>
         <v-col cols="12" md="4" lg="5" class="pa-0 overflow-hidden">
         <v-col cols="12" md="4" lg="5" class="pa-0 overflow-hidden">
-          <img src="@/assets/img/college-group/life/cover-04.png" alt="" />
+          <img src="@/assets/img/college-group/life/cover-04.png" alt="臺灣工藝學校全球學習共享平台" />
         </v-col>
         </v-col>
         <v-col cols="12" md="8" lg="7" class="content">
         <v-col cols="12" md="8" lg="7" class="content">
           <h3 class="mb-10">校園扎根</h3>
           <h3 class="mb-10">校園扎根</h3>
@@ -117,7 +117,7 @@ const breadcrumbs = reactive([
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .life-list {
 .life-list {
-  margin-top: 100px;
+  margin-top: 6.25em;
 
 
   @media (max-width: 600px) {
   @media (max-width: 600px) {
     margin-top: 0;
     margin-top: 0;
@@ -125,9 +125,9 @@ const breadcrumbs = reactive([
 
 
   a {
   a {
     display: block;
     display: block;
-    margin: 50px 0;
-    border: 2px solid var(--purple);
-    border-radius: 20px;
+    margin: 3.125em 0;
+    border: 0.125em solid var(--purple);
+    border-radius: 1.25em;
     overflow: hidden;
     overflow: hidden;
     &:hover {
     &:hover {
       img {
       img {
@@ -137,37 +137,37 @@ const breadcrumbs = reactive([
   }
   }
 
 
   h3 {
   h3 {
-    font-size: 24px;
+    font-size: 1.5em;
     font-weight: 500;
     font-weight: 500;
   }
   }
 
 
   img {
   img {
     width: 100%;
     width: 100%;
-    height: 330px;
+    height: 20.625em;
     min-height: 100%;
     min-height: 100%;
     object-fit: cover;
     object-fit: cover;
     transition: all 0.5s;
     transition: all 0.5s;
     @media (max-width: 1280px) {
     @media (max-width: 1280px) {
-      height: 370px;
+      height: 23.125em;
     }
     }
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      height: 200px;
+      height: 12.5em;
     }
     }
   }
   }
 
 
   .content {
   .content {
-    padding: 35px 60px;
+    padding: 2.1875em 3.75em;
     display: flex;
     display: flex;
     flex-direction: column;
     flex-direction: column;
     justify-content: center;
     justify-content: center;
     @media (max-width: 1280px) {
     @media (max-width: 1280px) {
-      padding: 40px;
+      padding: 2.5em;
     }
     }
   }
   }
 }
 }
 
 
 p {
 p {
-  line-height: 28px;
-  letter-spacing: 1px;
+  line-height: 1.75em;
+  letter-spacing: 0.0625em;
 }
 }
 </style>
 </style>

+ 1 - 1
src/views/CollegeGroup/Life/Apprentice/About.vue

@@ -3,7 +3,7 @@
     <h3 class="sub-title">關於一日學徒</h3>
     <h3 class="sub-title">關於一日學徒</h3>
     <img
     <img
       src="@/assets/img/college-group/life/apprentice/about.jpg"
       src="@/assets/img/college-group/life/apprentice/about.jpg"
-      alt=""
+      alt="臺灣工藝學校全球學習共享平台"
       class="mb-10"
       class="mb-10"
     />
     />
     <p class="mb-10">「一日學徒」,一個推廣全民工藝教育概念之倡議平台。</p>
     <p class="mb-10">「一日學徒」,一個推廣全民工藝教育概念之倡議平台。</p>

+ 3 - 2
src/views/CollegeGroup/Life/Apprentice/Contact.vue

@@ -38,14 +38,15 @@ a {
 }
 }
 
 
 h4 {
 h4 {
-  font-size: 24px;
+  font-size: 1.5em;
   font-weight: 500;
   font-weight: 500;
   color: var(--purple);
   color: var(--purple);
 }
 }
 
 
 li {
 li {
-  margin: 15px 0;
+  margin: 0.9375em 0;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
+  letter-spacing: 0.1em;
 }
 }
 </style>
 </style>

+ 1 - 1
src/views/CollegeGroup/Life/Apprentice/Course.vue

@@ -60,7 +60,7 @@ getClasses();
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="search()">
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
         </button>
         </button>
       </span>
       </span>
       <div
       <div

+ 5 - 5
src/views/CollegeGroup/Life/Apprentice/FAQ.vue

@@ -65,12 +65,12 @@ const faqList = [
 
 
 <style scoped>
 <style scoped>
 .v-expansion-panel-title {
 .v-expansion-panel-title {
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 }
 }
 .v-expansion-panel-text {
 .v-expansion-panel-text {
-  padding: 20px;
-  font-size: 16px;
-  line-height: 30px;
-  letter-spacing: 1px;
+  padding: 1.25em;
+  font-size: 1em;
+  line-height: 1.875em;
+  letter-spacing: 0.0625em;
 }
 }
 </style>
 </style>

+ 11 - 11
src/views/CollegeGroup/Life/Apprentice/Main.vue

@@ -76,29 +76,29 @@ const categoryList = reactive([
 .apprentice-content {
 .apprentice-content {
   p,
   p,
   .sub-title {
   .sub-title {
-    line-height: 30px;
-    letter-spacing: 1px;
+    line-height: 1.875em;
+    letter-spacing: 0.0625em;
   }
   }
   .sub-title {
   .sub-title {
-    margin-bottom: 30px;
-    font-size: 20px;
+    margin-bottom: 1.875em;
+    font-size: 1.25em;
     font-weight: 500;
     font-weight: 500;
   }
   }
   .category-list {
   .category-list {
     display: grid;
     display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(145px, max-content));
+    grid-template-columns: repeat(auto-fit, minmax(9.0625em, max-content));
     justify-content: center;
     justify-content: center;
     padding: initial;
     padding: initial;
     li {
     li {
       list-style-type: none;
       list-style-type: none;
       a {
       a {
         display: block;
         display: block;
-        padding: 8px 20px;
-        margin-bottom: 20px;
-        border: 1px solid #b8b8b8;
-        border-radius: 5px;
-        letter-spacing: 1px;
-        line-height: 22px;
+        padding: 0.5em 1.25em;
+        margin-bottom: 1.25em;
+        border: 0.0625em solid #b8b8b8;
+        border-radius: 0.3125em;
+        letter-spacing: 0.0625em;
+        line-height: 1.375em;
         text-align: center;
         text-align: center;
         transition: all 0.3s;
         transition: all 0.3s;
         &:hover {
         &:hover {

+ 2 - 2
src/views/CollegeGroup/Life/Campus.vue

@@ -75,7 +75,7 @@ const breadcrumbs = reactive([
           $router.resolve(`/article-detail/${item.article_id}`).href
           $router.resolve(`/article-detail/${item.article_id}`).href
         "
         "
       >
       >
-        <img :src="`https://ntcri.org/${item.cover_img}`" alt="" />
+        <img :src="`https://ntcri.org/${item.cover_img}`" alt="臺灣工藝學校全球學習共享平台" />
       </a>
       </a>
       <section class="mt-4">
       <section class="mt-4">
         <h3>{{ item.title }}</h3>
         <h3>{{ item.title }}</h3>
@@ -87,7 +87,7 @@ const breadcrumbs = reactive([
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .info {
 .info {
   img {
   img {
-    height: 250px;
+    height: 15.625em;
     width: 100%;
     width: 100%;
     object-fit: cover;
     object-fit: cover;
   }
   }

+ 3 - 2
src/views/CollegeGroup/Life/CraftJourney.vue

@@ -76,6 +76,7 @@ const breadcrumbs = reactive([
           :lazy-src="`https://ntcri.org/${item.cover_img}`"
           :lazy-src="`https://ntcri.org/${item.cover_img}`"
           :src="`https://ntcri.org/${item.cover_img}`"
           :src="`https://ntcri.org/${item.cover_img}`"
           cover
           cover
+          alt="臺灣工藝學校全球學習共享平台"
         >
         >
           <template v-slot:placeholder>
           <template v-slot:placeholder>
             <div class="d-flex align-center justify-center fill-height">
             <div class="d-flex align-center justify-center fill-height">
@@ -86,7 +87,7 @@ const breadcrumbs = reactive([
             </div>
             </div>
           </template>
           </template>
         </v-img>
         </v-img>
-        <!-- <img :src="`https://ntcri.org/${item.cover_img}`" alt="" /> -->
+        <!-- <img :src="`https://ntcri.org/${item.cover_img}`" alt="臺灣工藝學校全球學習共享平台" /> -->
         <section>
         <section>
           <h3>{{ item.title }}</h3>
           <h3>{{ item.title }}</h3>
           <p>{{ item.depiction }}</p>
           <p>{{ item.depiction }}</p>
@@ -99,7 +100,7 @@ const breadcrumbs = reactive([
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .info {
 .info {
   .v-img {
   .v-img {
-    height: 215px;
+    height: 13.4375em;
     width: 100%;
     width: 100%;
     object-fit: cover;
     object-fit: cover;
   }
   }

+ 24 - 19
src/views/CollegeGroup/Life/Shop.vue

@@ -114,7 +114,12 @@ const youthImgs = [
     <v-slide-group center-active show-arrows>
     <v-slide-group center-active show-arrows>
       <v-slide-group-item v-for="item in shopImgs" :key="item">
       <v-slide-group-item v-for="item in shopImgs" :key="item">
         <div class="ma-3">
         <div class="ma-3">
-          <v-img :src="item.img" height="200px" cover></v-img>
+          <v-img
+            :src="item.img"
+            height="12.5em"
+            cover
+            alt="臺灣工藝學校全球學習共享平台"
+          ></v-img>
         </div>
         </div>
       </v-slide-group-item>
       </v-slide-group-item>
     </v-slide-group>
     </v-slide-group>
@@ -129,7 +134,7 @@ const youthImgs = [
       <v-col cols="12" md="6" lg="5">
       <v-col cols="12" md="6" lg="5">
         <img
         <img
           src="@/assets/img/college-group/life/shop/旅物shop位置圖.jpg"
           src="@/assets/img/college-group/life/shop/旅物shop位置圖.jpg"
-          alt=""
+          alt="臺灣工藝學校全球學習共享平台"
         />
         />
       </v-col>
       </v-col>
       <v-col cols="12" md="6" lg="7" class="d-flex flex-column">
       <v-col cols="12" md="6" lg="7" class="d-flex flex-column">
@@ -162,7 +167,7 @@ const youthImgs = [
       <h3 class="block-title">臺灣綠工藝 Taiwan Green Craft</h3>
       <h3 class="block-title">臺灣綠工藝 Taiwan Green Craft</h3>
       <img
       <img
         src="@/assets/img/college-group/life/shop/旅物shop-03.png"
         src="@/assets/img/college-group/life/shop/旅物shop-03.png"
-        alt=""
+        alt="臺灣工藝學校全球學習共享平台"
         class="my-7"
         class="my-7"
       />
       />
       <div class="content d-flex flex-column">
       <div class="content d-flex flex-column">
@@ -202,7 +207,7 @@ const youthImgs = [
           v-for="(item, index) in youthImgs"
           v-for="(item, index) in youthImgs"
           :key="index"
           :key="index"
         >
         >
-          <img :src="item.img" alt="" />
+          <img :src="item.img" alt="臺灣工藝學校全球學習共享平台" />
           <h4>{{ item.title }}</h4>
           <h4>{{ item.title }}</h4>
         </v-col>
         </v-col>
       </v-row>
       </v-row>
@@ -212,7 +217,7 @@ const youthImgs = [
       <h3 class="block-title">品工藝 Museum Shop of NTCRI</h3>
       <h3 class="block-title">品工藝 Museum Shop of NTCRI</h3>
       <img
       <img
         src="@/assets/img/college-group/life/shop/品工藝.jpg"
         src="@/assets/img/college-group/life/shop/品工藝.jpg"
-        alt=""
+        alt="臺灣工藝學校全球學習共享平台"
         class="my-7"
         class="my-7"
       />
       />
       <div class="content">
       <div class="content">
@@ -229,7 +234,7 @@ const youthImgs = [
       <h3 class="block-title">一日咖啡 A Day Coffee</h3>
       <h3 class="block-title">一日咖啡 A Day Coffee</h3>
       <img
       <img
         src="@/assets/img/college-group/life/shop/一日咖啡.jpg"
         src="@/assets/img/college-group/life/shop/一日咖啡.jpg"
-        alt=""
+        alt="臺灣工藝學校全球學習共享平台"
         class="my-7"
         class="my-7"
       />
       />
       <div class="content">
       <div class="content">
@@ -247,20 +252,20 @@ const youthImgs = [
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 p,
 p,
 li {
 li {
-  line-height: 30px;
-  letter-spacing: 1px;
+  line-height: 1.875em;
+  letter-spacing: 0.0625em;
 }
 }
 .block {
 .block {
-  margin: 100px 0;
+  margin: 6.25em 0;
   .content {
   .content {
-    padding: 25px;
-    border-radius: 20px;
-    border: 2px solid var(--purple);
+    padding: 1.5625em;
+    border-radius: 1.25em;
+    border: 0.125em solid var(--purple);
   }
   }
   .youth-imgs {
   .youth-imgs {
     img {
     img {
       width: 100%;
       width: 100%;
-      height: 220px;
+      height: 13.75em;
       object-fit: cover;
       object-fit: cover;
       @media (max-width: 1280px) {
       @media (max-width: 1280px) {
         height: 15vw;
         height: 15vw;
@@ -273,20 +278,20 @@ li {
       }
       }
     }
     }
     h4 {
     h4 {
-      margin-top: 20px;
-      line-height: 24px;
+      margin-top: 1.25em;
+      line-height: 1.5em;
     }
     }
   }
   }
   .block-title,
   .block-title,
   .youth-imgs h4 {
   .youth-imgs h4 {
     font-weight: 500;
     font-weight: 500;
     text-align: center;
     text-align: center;
-    letter-spacing: 1px;
+    letter-spacing: 0.0625em;
   }
   }
   .block-title {
   .block-title {
-    padding: 20px;
-    font-size: 20px;
-    line-height: 28px;
+    padding: 1.25em;
+    font-size: 1.25em;
+    line-height: 1.75em;
     color: #fff;
     color: #fff;
     background: var(--purple);
     background: var(--purple);
   }
   }

+ 12 - 12
src/views/CollegeGroup/Main.vue

@@ -102,12 +102,12 @@ async function getGroup(id) {
         <img
         <img
           class="d-none d-md-block"
           class="d-none d-md-block"
           src="@/assets/img/college-group/banner.png"
           src="@/assets/img/college-group/banner.png"
-          alt=""
+          alt="臺灣工藝學校全球學習共享平台"
         />
         />
         <img
         <img
           class="d-block d-md-none"
           class="d-block d-md-none"
           src="@/assets/img/college-group/banner-mb.png"
           src="@/assets/img/college-group/banner-mb.png"
-          alt=""
+          alt="臺灣工藝學校全球學習共享平台"
         />
         />
         <div class="description-item">
         <div class="description-item">
           <h1>{{ groupName }}</h1>
           <h1>{{ groupName }}</h1>
@@ -136,37 +136,37 @@ async function getGroup(id) {
     width: 85%;
     width: 85%;
   }
   }
   .main-block {
   .main-block {
-    padding: 100px 80px;
+    padding: 6.25em 5em;
     margin-top: -30%;
     margin-top: -30%;
     background-color: #fff;
     background-color: #fff;
 
 
     @media (max-width: 960px) {
     @media (max-width: 960px) {
-      padding: 100px 50px;
+      padding: 6.25em 3.125em;
     }
     }
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      padding: 100px 20px;
+      padding: 6.25em 1.25em;
     }
     }
 
 
     h2 {
     h2 {
-      font-size: 30px;
+      font-size: 1.875em;
       font-weight: 500;
       font-weight: 500;
-      line-height: 32px;
-      margin-left: 10px;
+      line-height: 2em;
+      margin-left: 0.625em;
 
 
       @media (max-width: 960px) {
       @media (max-width: 960px) {
-        font-size: 24px;
+        font-size: 1.5em;
       }
       }
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
         margin-left: 0;
         margin-left: 0;
-        margin-bottom: 50px;
+        margin-bottom: 3.125em;
       }
       }
     }
     }
     .title {
     .title {
-      margin: 80px 0;
+      margin: 5em 0;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        margin: 50px 0;
+        margin: 3.125em 0;
       }
       }
     }
     }
     .v-breadcrumbs {
     .v-breadcrumbs {

+ 17 - 17
src/views/CollegeGroup/Online.vue

@@ -140,7 +140,7 @@ async function selectFilter(type, val) {
     class="mt-10 p-0"
     class="mt-10 p-0"
   ></v-breadcrumbs>
   ></v-breadcrumbs>
 
 
-  <div class="d-flex flex-column flex-sm-row align-center justify-end title">
+  <div class="d-flex flex-column flex-sm-row align-center justify-end my-16">
     <div class="search">
     <div class="search">
       <span>
       <span>
         <input
         <input
@@ -150,7 +150,7 @@ async function selectFilter(type, val) {
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="search()">
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
         </button>
         </button>
       </span>
       </span>
       <div
       <div
@@ -200,9 +200,9 @@ async function selectFilter(type, val) {
 
 
   <div
   <div
     ref="listLocation"
     ref="listLocation"
-    class="d-flex flex-column flex-sm-row align-center justify-space-between title"
+    class="d-flex flex-column flex-sm-row align-center justify-space-between"
   >
   >
-    <h2>線上體驗課程</h2>
+    <h2 class="title">線上體驗課程</h2>
     <div class="search">
     <div class="search">
       <span>
       <span>
         <input
         <input
@@ -212,7 +212,7 @@ async function selectFilter(type, val) {
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="search()">
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
         </button>
         </button>
       </span>
       </span>
       <div
       <div
@@ -277,22 +277,22 @@ async function selectFilter(type, val) {
 .main-block {
 .main-block {
   h2 {
   h2 {
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      margin-bottom: 30px;
+      margin-bottom: 1.875em;
     }
     }
   }
   }
 }
 }
 
 
 .v-input {
 .v-input {
   @media (max-width: 600px) {
   @media (max-width: 600px) {
-    max-width: 250px;
+    max-width: 15.625em;
     margin: auto;
     margin: auto;
-    margin-top: -20px;
+    margin-top: -1.25em;
   }
   }
 }
 }
 
 
 .btn-list {
 .btn-list {
   display: grid;
   display: grid;
-  grid-template-columns: repeat(auto-fit, minmax(110px, max-content));
+  grid-template-columns: repeat(auto-fit, minmax(6.875em, max-content));
   justify-content: center;
   justify-content: center;
   padding: initial;
   padding: initial;
 
 
@@ -301,17 +301,17 @@ async function selectFilter(type, val) {
   }
   }
 
 
   .v-btn {
   .v-btn {
-    width: 100px;
+    width: 6.25em;
     border-color: var(--purple);
     border-color: var(--purple);
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      width: 150px;
+      width: 9.375em;
     }
     }
   }
   }
 }
 }
 .video-list {
 .video-list {
   h3 {
   h3 {
-    margin: 20px 0;
-    font-size: 18px;
+    margin: 1.25em 0;
+    font-size: 1.125em;
     font-weight: 500;
     font-weight: 500;
   }
   }
   p {
   p {
@@ -326,14 +326,14 @@ async function selectFilter(type, val) {
   h3,
   h3,
   p,
   p,
   span {
   span {
-    line-height: 24px;
-    letter-spacing: 1px;
+    line-height: 1.5em;
+    letter-spacing: 0.0625em;
   }
   }
   span {
   span {
-    font-size: 14px;
+    font-size: 0.875em;
   }
   }
 }
 }
 video {
 video {
-  border-radius: 20px;
+  border-radius: 1.25em;
 }
 }
 </style>
 </style>

+ 36 - 36
src/views/CollegeGroup/Proposal.vue

@@ -122,7 +122,7 @@ function setPDFUrl(pdf) {
         <img
         <img
           class="cover-img"
           class="cover-img"
           src="@/assets/img/college-group/future/素材-10.png"
           src="@/assets/img/college-group/future/素材-10.png"
-          alt=""
+          alt="臺灣工藝學校全球學習共享平台"
         />
         />
         <span class="caption my-5">本書資訊</span>
         <span class="caption my-5">本書資訊</span>
         <ul>
         <ul>
@@ -139,12 +139,12 @@ function setPDFUrl(pdf) {
             <ul>
             <ul>
               <li v-for="(item, index) in buyWay.list" :key="index">
               <li v-for="(item, index) in buyWay.list" :key="index">
                 <a :href="item.url" target="_blank">
                 <a :href="item.url" target="_blank">
-                  <img :src="handlerBuyImg(item.title)" alt="" />
+                  <img :src="handlerBuyImg(item.title)" alt="臺灣工藝學校全球學習共享平台" />
                 </a>
                 </a>
                 <!-- <a href="">
                 <!-- <a href="">
                   <img
                   <img
                     src="@/assets/img/college-group/future/proposal/購買連結-2.png"
                     src="@/assets/img/college-group/future/proposal/購買連結-2.png"
-                    alt=""
+                    alt="臺灣工藝學校全球學習共享平台"
                   />
                   />
                 </a> -->
                 </a> -->
               </li>
               </li>
@@ -163,100 +163,100 @@ function setPDFUrl(pdf) {
   }
   }
 
 
   .proposal-title {
   .proposal-title {
-    padding: 40px 10px;
-    margin-bottom: 40px;
+    padding: 2.5em 0.625em;
+    margin-bottom: 2.5em;
     text-align: center;
     text-align: center;
-    font-size: 24px;
-    letter-spacing: 2px;
-    line-height: 36px;
-    border-left: 15px solid var(--blue);
+    font-size: 1.5em;
+    letter-spacing: 0.125em;
+    line-height: 2.25em;
+    border-left: 0.9375em solid var(--blue);
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      font-size: 20px;
+      font-size: 1.25em;
     }
     }
   }
   }
 
 
   ul {
   ul {
     width: 100%;
     width: 100%;
-    line-height: 24px;
+    line-height: 1.5em;
     li {
     li {
-      margin-bottom: 5px;
-      line-height: 28px;
-      letter-spacing: 1px;
+      margin-bottom: 0.3125em;
+      line-height: 1.75em;
+      letter-spacing: 0.0625em;
       a {
       a {
         display: block;
         display: block;
-        margin-bottom: -10px;
+        margin-bottom: -0.625em;
       }
       }
     }
     }
   }
   }
 
 
   .cover-img {
   .cover-img {
     width: 100%;
     width: 100%;
-    height: 350px;
+    height: 21.875em;
     object-fit: contain;
     object-fit: contain;
   }
   }
 
 
   .caption {
   .caption {
     display: block;
     display: block;
     width: 100%;
     width: 100%;
-    padding: 12px 30px;
+    padding: 0.75em 1.875em;
     color: #fff;
     color: #fff;
-    letter-spacing: 1px;
+    letter-spacing: 0.0625em;
     background-color: var(--blue);
     background-color: var(--blue);
-    border-radius: 10px;
-    text-shadow: 1px 1px 3px #939393;
+    border-radius: 0.625em;
+    text-shadow: 0.0625em 0.0625em 0.1875em #939393;
   }
   }
 
 
   .store-list {
   .store-list {
     display: flex;
     display: flex;
     p {
     p {
-      width: 65px;
+      width: 4.0625em;
       white-space: nowrap;
       white-space: nowrap;
     }
     }
     img {
     img {
-      width: 200px;
+      width: 12.5em;
     }
     }
   }
   }
 
 
   .content {
   .content {
-    padding: 50px;
-    border: 1px solid var(--blue);
-    border-radius: 10px;
+    padding: 3.125em;
+    border: 0.0625em solid var(--blue);
+    border-radius: 0.625em;
 
 
     h2 {
     h2 {
-      font-size: 20px;
+      font-size: 1.25em;
     }
     }
 
 
     p {
     p {
-      letter-spacing: 1px;
+      letter-spacing: 0.0625em;
     }
     }
 
 
     img {
     img {
-      padding: 10px 15px;
+      padding: 0.625em 0.9375em;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        padding: 0 0 15px;
+        padding: 0 0 0.9375em;
       }
       }
     }
     }
 
 
     .read-btn {
     .read-btn {
       display: flex;
       display: flex;
       justify-content: end;
       justify-content: end;
-      margin-top: 50px;
+      margin-top: 3.125em;
 
 
       a {
       a {
-        padding: 15px 40px;
-        font-size: 18px;
-        letter-spacing: 2px;
-        text-shadow: 1px 1px 3px #939393;
+        padding: 0.9375em 2.5em;
+        font-size: 1.125em;
+        letter-spacing: 0.125em;
+        text-shadow: 0.0625em 0.0625em 0.1875em #939393;
         background-color: #a7c2cd;
         background-color: #a7c2cd;
         color: white;
         color: white;
         cursor: pointer;
         cursor: pointer;
-        border-radius: 100px;
+        border-radius: 6.25em;
         transition: all 0.3s;
         transition: all 0.3s;
         &:hover {
         &:hover {
           background-color: #99b1bb;
           background-color: #99b1bb;
         }
         }
         @media (max-width: 600px) {
         @media (max-width: 600px) {
-          font-size: 16px;
+          font-size: 1em;
         }
         }
       }
       }
     }
     }

+ 33 - 33
src/views/CollegeGroup/Repair.vue

@@ -135,7 +135,7 @@ const testData = [
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="search()">
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
         </button>
         </button>
       </span>
       </span>
       <div
       <div
@@ -154,7 +154,7 @@ const testData = [
         <h2 class="text-center ma-0 pa-3">{{ item.title }}</h2>
         <h2 class="text-center ma-0 pa-3">{{ item.title }}</h2>
 
 
         <div class="d-flex flex-column flex-sm-row align-center content">
         <div class="d-flex flex-column flex-sm-row align-center content">
-          <img src="@/assets/img/img-04.jpg" alt="" />
+          <img src="@/assets/img/img-04.jpg" alt="臺灣工藝學校全球學習共享平台" />
           <section
           <section
             class="d-flex flex-column justify-space-between px-0 px-sm-10 pt-5 pt-md-0"
             class="d-flex flex-column justify-space-between px-0 px-sm-10 pt-5 pt-md-0"
           >
           >
@@ -200,7 +200,7 @@ const testData = [
       md="6"
       md="6"
       class="v-col-md-6 v-col-12 d-flex flex-column flex-md-row align-center justify-md-center"
       class="v-col-md-6 v-col-12 d-flex flex-column flex-md-row align-center justify-md-center"
     >
     >
-      <img src="@/assets/img/college-group/repair/修護-12.png" alt="" />
+      <img src="@/assets/img/college-group/repair/修護-12.png" alt="臺灣工藝學校全球學習共享平台" />
       <section class="mt-5 mt-md-0 ms-md-5">
       <section class="mt-5 mt-md-0 ms-md-5">
         <h3>廖偉淇</h3>
         <h3>廖偉淇</h3>
         <span class="d-block mt-3 mb-5">金工木印工作室</span>
         <span class="d-block mt-3 mb-5">金工木印工作室</span>
@@ -217,7 +217,7 @@ const testData = [
       md="6"
       md="6"
       class="v-col-md-6 v-col-12 d-flex flex-column flex-md-row align-center justify-md-center"
       class="v-col-md-6 v-col-12 d-flex flex-column flex-md-row align-center justify-md-center"
     >
     >
-      <img src="@/assets/img/college-group/repair/修護-13.png" alt="" />
+      <img src="@/assets/img/college-group/repair/修護-13.png" alt="臺灣工藝學校全球學習共享平台" />
       <section class="mt-5 mt-md-0 ms-md-5">
       <section class="mt-5 mt-md-0 ms-md-5">
         <h3>陳高登</h3>
         <h3>陳高登</h3>
         <span class="d-block mt-3 mb-5">金工木印工作室</span>
         <span class="d-block mt-3 mb-5">金工木印工作室</span>
@@ -258,28 +258,28 @@ h3 {
 
 
 p {
 p {
   font-weight: 400;
   font-weight: 400;
-  letter-spacing: 1px;
-  line-height: 28px;
+  letter-spacing: 0.0625em;
+  line-height: 1.75em;
 }
 }
 
 
 .article-block {
 .article-block {
   h4 {
   h4 {
-    font-size: 26px;
+    font-size: 1.625em;
     font-weight: 400;
     font-weight: 400;
-    line-height: 40px;
+    line-height: 2.5em;
   }
   }
 
 
   .v-btn {
   .v-btn {
-    height: 65px;
+    height: 4.0625em;
     color: #fff;
     color: #fff;
     font-weight: 400;
     font-weight: 400;
-    border-radius: 100px;
+    border-radius: 6.25em;
     background-color: #569f33;
     background-color: #569f33;
     @media (max-width: 960px) {
     @media (max-width: 960px) {
-      font-size: 14px;
+      font-size: 0.875em;
     }
     }
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      font-size: 16px;
+      font-size: 1em;
     }
     }
   }
   }
 }
 }
@@ -287,23 +287,23 @@ p {
 .course-list {
 .course-list {
   .v-card {
   .v-card {
     border: none;
     border: none;
-    border-radius: 20px;
+    border-radius: 1.25em;
     background-color: #e9f1f4;
     background-color: #e9f1f4;
     h2 {
     h2 {
       width: 100%;
       width: 100%;
-      font-size: 24px;
-      line-height: 30px;
-      letter-spacing: 1px;
-      border-bottom: 3px solid #fff;
+      font-size: 1.5em;
+      line-height: 1.875em;
+      letter-spacing: 0.0625em;
+      border-bottom: 0.1875em solid #fff;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 22px;
+        font-size: 1.375em;
       }
       }
     }
     }
     .content {
     .content {
-      padding: 20px;
+      padding: 1.25em;
       p:first-child {
       p:first-child {
         font-weight: 400;
         font-weight: 400;
-        line-height: 28px;
+        line-height: 1.75em;
         color: #606064;
         color: #606064;
       }
       }
     }
     }
@@ -314,18 +314,18 @@ p {
 .story-list {
 .story-list {
   img {
   img {
     width: 100%;
     width: 100%;
-    max-width: 300px;
-    height: 220px;
+    max-width: 18.75em;
+    height: 13.75em;
     object-fit: cover;
     object-fit: cover;
     @media (max-width: 600px) {
     @media (max-width: 600px) {
       max-width: 100%;
       max-width: 100%;
     }
     }
   }
   }
   h3 {
   h3 {
-    font-size: 24px;
+    font-size: 1.5em;
     font-weight: 500;
     font-weight: 500;
-    line-height: 30px;
-    letter-spacing: 1px;
+    line-height: 1.875em;
+    letter-spacing: 0.0625em;
   }
   }
   p {
   p {
     // 超過兩行則省略
     // 超過兩行則省略
@@ -338,34 +338,34 @@ p {
   }
   }
 
 
   .date {
   .date {
-    font-size: 20px;
+    font-size: 1.25em;
     font-weight: 400;
     font-weight: 400;
   }
   }
 }
 }
 
 
 .master-list {
 .master-list {
   img {
   img {
-    width: 250px;
-    height: 250px;
+    width: 15.625em;
+    height: 15.625em;
     object-fit: cover;
     object-fit: cover;
   }
   }
   h3 {
   h3 {
-    font-size: 20px;
+    font-size: 1.25em;
     color: #000;
     color: #000;
   }
   }
   section {
   section {
     text-align: center;
     text-align: center;
     color: #606064;
     color: #606064;
     li {
     li {
-      line-height: 28px;
+      line-height: 1.75em;
     }
     }
   }
   }
 }
 }
 
 
 .past-btn {
 .past-btn {
-  padding: 15px 40px;
+  padding: 0.9375em 2.5em;
   color: #606064;
   color: #606064;
-  border-radius: 100px;
-  border: 2px solid #569f33;
+  border-radius: 6.25em;
+  border: 0.125em solid #569f33;
 }
 }
 </style>
 </style>

+ 5 - 5
src/views/CollegeGroup/Teenager.vue

@@ -93,7 +93,7 @@ const categoryList = reactive([
           placeholder="關鍵字搜尋"
           placeholder="關鍵字搜尋"
         />
         />
         <button @click="search()">
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="" />
+          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
         </button>
         </button>
       </span>
       </span>
       <div
       <div
@@ -159,7 +159,7 @@ const categoryList = reactive([
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .btn-list {
 .btn-list {
   display: grid;
   display: grid;
-  grid-template-columns: repeat(auto-fit, minmax(110px, max-content));
+  grid-template-columns: repeat(auto-fit, minmax(6.875em, max-content));
   justify-content: center;
   justify-content: center;
   padding: initial;
   padding: initial;
   li {
   li {
@@ -167,13 +167,13 @@ const categoryList = reactive([
   }
   }
 
 
   .v-btn {
   .v-btn {
-    width: 100px;
+    width: 6.25em;
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      width: 150px;
+      width: 9.375em;
     }
     }
   }
   }
 }
 }
 .post-item {
 .post-item {
-  margin-bottom: 30px;
+  margin-bottom: 1.875em;
 }
 }
 </style>
 </style>

+ 414 - 88
src/views/CourseDetail.vue

@@ -80,6 +80,8 @@ let courseNameId = ref(null);
       groupName.value = "跨域工藝學群";
       groupName.value = "跨域工藝學群";
     } else if (course.data.group_id === 8) {
     } else if (course.data.group_id === 8) {
       groupName.value = "線上工藝學群";
       groupName.value = "線上工藝學群";
+    } else if (course.data.group_id === 9) {
+      groupName.value = "綠工藝希望工程";
     }
     }
   } catch (error) {
   } catch (error) {
     console.error(error);
     console.error(error);
@@ -196,10 +198,10 @@ async function signUpSubmit(id) {
 
 
   if (!user.birthday || user.birthday === "") {
   if (!user.birthday || user.birthday === "") {
     birthdayError.value = true;
     birthdayError.value = true;
-    isSignUpLoading.value = false;
+    // isSignUpLoading.value = false;
   } else {
   } else {
     birthdayError.value = false;
     birthdayError.value = false;
-    isSignUpLoading.value = false;
+    // isSignUpLoading.value = false;
   }
   }
 
 
   // 檢查欄位是否有空值
   // 檢查欄位是否有空值
@@ -222,22 +224,40 @@ async function signUpSubmit(id) {
     );
     );
     console.log("確認報名", response);
     console.log("確認報名", response);
     isSignUpLoading.value = false;
     isSignUpLoading.value = false;
-    if (response.data.msg === "already registrate") {
-      resultCard.text = "此課程已報名";
+
+    if (response.data.msg === "success") {
+      resultCard.text = "報名成功!";
+      resultCard.icon = "mdi-check-circle";
+      resultCard.color = "success";
+      step.value++;
+    } else if (response.data.msg === "already registrate") {
+      resultCard.text = "已報名過此課程";
       resultCard.icon = "mdi-information";
       resultCard.icon = "mdi-information";
       resultCard.color = "info";
       resultCard.color = "info";
       step.value++;
       step.value++;
-    } else if (response.data.msg === "class is full") {
-      resultCard.text = "報名已額滿";
+    } else {
+      resultCard.text = response.data.msg;
       resultCard.icon = "mdi-information";
       resultCard.icon = "mdi-information";
       resultCard.color = "info";
       resultCard.color = "info";
       step.value++;
       step.value++;
-    } else if (response.data.code === 200) {
-      resultCard.text = "報名成功!";
-      resultCard.icon = "mdi-check-circle";
-      resultCard.color = "success";
-      step.value++;
     }
     }
+
+    // if (response.data.msg === "already registrate") {
+    //   resultCard.text = "此課程已報名";
+    //   resultCard.icon = "mdi-information";
+    //   resultCard.color = "info";
+    //   step.value++;
+    // } else if (response.data.msg === "class is full") {
+    //   resultCard.text = "報名已額滿";
+    //   resultCard.icon = "mdi-information";
+    //   resultCard.color = "info";
+    //   step.value++;
+    // } else if (response.data.code === 200) {
+    //   resultCard.text = "報名成功!";
+    //   resultCard.icon = "mdi-check-circle";
+    //   resultCard.color = "success";
+    //   step.value++;
+    // }
   } catch (error) {
   } catch (error) {
     console.error(error);
     console.error(error);
   }
   }
@@ -272,21 +292,15 @@ let currentTitle = computed(() => {
       <v-col cols="3" class="title pa-0">
       <v-col cols="3" class="title pa-0">
         <img
         <img
           src="@/assets/img/course/detail-background.png"
           src="@/assets/img/course/detail-background.png"
-          alt=""
+          alt="臺灣工藝學校全球學習共享平台"
           class="bg-img"
           class="bg-img"
         />
         />
         <h2>{{ course.data.name }}</h2>
         <h2>{{ course.data.name }}</h2>
       </v-col>
       </v-col>
       <v-col :cols="dynamicCols" class="pa-0 d-flex justify-center">
       <v-col :cols="dynamicCols" class="pa-0 d-flex justify-center">
         <img
         <img
-          :src="
-            isInner === 0
-              ? course.data.cover_img
-              : course.data.special_class_list_name === 'one_day_class'
-              ? store.getImageUrl('default.png')
-              : `https://ntcri.org/${course.data.cover_img}`
-          "
-          alt=""
+          :src="store.getImageSrc(course.data)"
+          alt="臺灣工藝學校全球學習共享平台"
           class="cover-img"
           class="cover-img"
           :class="{ small: isInner === 0 }"
           :class="{ small: isInner === 0 }"
         />
         />
@@ -310,16 +324,28 @@ let currentTitle = computed(() => {
               </tr>
               </tr>
               <tr v-show="course.data.category !== ''">
               <tr v-show="course.data.category !== ''">
                 <td>課程類別</td>
                 <td>課程類別</td>
-                <td>{{ course.data.category }}</td>
+                <td>
+                  {{
+                    course.data.group_id === 9
+                      ? course.data.group_sort
+                      : course.data.category
+                  }}
+                </td>
               </tr>
               </tr>
               <tr v-if="course.data.organizer !== ''">
               <tr v-if="course.data.organizer !== ''">
                 <td>主辦單位</td>
                 <td>主辦單位</td>
-                <td>{{ course.data.organizer }}</td>
+                <td>
+                  {{
+                    course.data.group_id === 9
+                      ? course.data.location_name
+                      : course.data.organizer
+                  }}
+                </td>
               </tr>
               </tr>
-              <tr>
+              <!-- <tr>
                 <td>課程地點</td>
                 <td>課程地點</td>
                 <td>{{ course.data.address }}</td>
                 <td>{{ course.data.address }}</td>
-              </tr>
+              </tr> -->
               <tr>
               <tr>
                 <td>所屬學群</td>
                 <td>所屬學群</td>
                 <td>{{ groupName }}</td>
                 <td>{{ groupName }}</td>
@@ -340,12 +366,31 @@ let currentTitle = computed(() => {
                 v-if="
                 v-if="
                   isInner !== 0 &&
                   isInner !== 0 &&
                   session.data.length &&
                   session.data.length &&
-                  session.data[0]?.contact !== ''
+                  session.data[0]?.contact !== '' &&
+                  course.data.group_id !== 9
                 "
                 "
               >
               >
                 <td>聯絡方式</td>
                 <td>聯絡方式</td>
                 <td>{{ session.data[0]?.contact }}</td>
                 <td>{{ session.data[0]?.contact }}</td>
               </tr>
               </tr>
+              <tr
+                v-if="
+                  isInner !== 0 &&
+                  session.data.length &&
+                  session.data[0]?.fee_payment !== null
+                "
+              >
+                <td>繳費方式</td>
+                <td>
+                  {{ session.data[0]?.fee_payment }}
+                  <span
+                    v-if="session.data[0]?.fee_payment === '匯款'"
+                    class="text-red"
+                  >
+                    (匯款後請主動來電告知姓名與帳號後五碼)
+                  </span>
+                </td>
+              </tr>
               <tr v-if="isInner === 0">
               <tr v-if="isInner === 0">
                 <td>備註</td>
                 <td>備註</td>
                 <td>此課程不會登錄至學習護照中</td>
                 <td>此課程不會登錄至學習護照中</td>
@@ -358,7 +403,7 @@ let currentTitle = computed(() => {
                 >觀看課程資訊與報名</a
                 >觀看課程資訊與報名</a
               >
               >
             </v-btn>
             </v-btn>
-            <v-btn v-else rounded="xl" color="brown">附件下載</v-btn>
+            <!-- <v-btn v-else rounded="xl" color="brown">附件下載</v-btn> -->
           </div>
           </div>
         </div>
         </div>
       </v-col>
       </v-col>
@@ -369,7 +414,7 @@ let currentTitle = computed(() => {
           hide: course.data.special_class_list_name === 'one_day_class',
           hide: course.data.special_class_list_name === 'one_day_class',
         }"
         }"
       >
       >
-        <div class="sessions">
+        <div class="sessions mb-16">
           <table>
           <table>
             <thead>
             <thead>
               <tr>
               <tr>
@@ -377,6 +422,7 @@ let currentTitle = computed(() => {
                 <th>開始/結束時間</th>
                 <th>開始/結束時間</th>
                 <th>課程地點</th>
                 <th>課程地點</th>
                 <th>課程費用</th>
                 <th>課程費用</th>
+                <th>課程名額</th>
                 <th>講師</th>
                 <th>講師</th>
                 <th>報名截止日</th>
                 <th>報名截止日</th>
                 <th></th>
                 <th></th>
@@ -391,10 +437,11 @@ let currentTitle = computed(() => {
                   ~ <br />
                   ~ <br />
                   {{ moment(`${item.end_time}`).format("YYYY/MM/DD H:mm") }}
                   {{ moment(`${item.end_time}`).format("YYYY/MM/DD H:mm") }}
                 </td>
                 </td>
-                <td>
+                <td width="20%">
                   {{ isInner === 0 ? course.data.school : item.location }}
                   {{ isInner === 0 ? course.data.school : item.location }}
                 </td>
                 </td>
                 <td>{{ item.fee_method }}</td>
                 <td>{{ item.fee_method }}</td>
+                <td>{{ item.number_limit }}</td>
                 <td>{{ item.lecturer }}</td>
                 <td>{{ item.lecturer }}</td>
                 <td>
                 <td>
                   <span
                   <span
@@ -409,7 +456,286 @@ let currentTitle = computed(() => {
                   <span v-else>無</span>
                   <span v-else>無</span>
                 </td>
                 </td>
                 <td>
                 <td>
-                  <v-btn rounded="xl" color="brown">
+                  <v-btn v-if="isInner === 0" rounded="xl" color="brown">
+                    <a :href="item.URL" target="_blank">報名</a>
+                  </v-btn>
+
+                  <v-dialog
+                    v-else
+                    width="auto"
+                    class="pa-0 signup-dialog"
+                    scrollable
+                    persistent
+                  >
+                    <template v-slot:activator="{ props }">
+                      <v-btn
+                        @click="signUp(index)"
+                        v-bind="props"
+                        text="報名"
+                        rounded="xl"
+                        color="brown"
+                      >
+                      </v-btn>
+                    </template>
+
+                    <template v-slot:default="{ isActive }">
+                      <v-card class="mx-auto pa-3" max-width="1000">
+                        <v-card-title
+                          class="text-h6 font-weight-regular justify-space-between"
+                        >
+                          <v-avatar
+                            v-if="step !== 3"
+                            color="primary"
+                            size="26"
+                            v-text="step"
+                            class="me-3"
+                          ></v-avatar>
+                          <span>{{ currentTitle }}</span>
+                        </v-card-title>
+
+                        <v-window v-model="step">
+                          <v-window-item :value="1">
+                            <v-card-text>
+                              <section class="consent">
+                                <h4 class="text-center">個人資料使用同意書</h4>
+                                <p>
+                                  國立臺灣工藝研究發展中心〈以下簡稱工藝中心〉因辦理
+                                  <span class="font-weight-medium"
+                                    >【{{ item.class_name }}】</span
+                                  >
+                                  業務而獲取您的個人資料:姓名、身分證字號、連絡方式〈包括但不限於電話號碼、E-MAIL、居住或工作地址〉等得以直接或間接識別您個人之資料。若您所提供之個人資料,經檢舉或工藝中心發現不足以確認您的身分真實性或其他個人資料冒用、盜用、資料不實等情形,工藝中心有權暫時停止提供對您的服務。
+                                </p>
+
+                                <p>
+                                  工藝中心將基於個人資料保護法及相關法令之規定下,依隱私權保護政策,蒐集、處理及利用您的個人資料。您同意工藝中心以您所提供的個人資料確認您的身份、與您進行連絡、提供您相關服務及資訊,以及其他隱私權保護政策規範之使用方式。工藝中心針對您的個人資料利用之期間,自您簽署同意起至您請求刪除個資為止。
+                                </p>
+
+                                <p>
+                                  您可依個人資料保護法,就您的個人資料向工藝中心進行查詢或請求閱覽、請求給複製本、請求補充或更正、請求停止蒐集及處理與利用、請求刪除。但因您行使上述權利而導致工藝中心相關業務對您的權益產生減損時,工藝中心不負相關賠償責任。
+                                </p>
+                              </section>
+
+                              <v-checkbox
+                                v-model="checkConsent"
+                                label="我已完全閱讀並同意以上內容"
+                                color="brown"
+                              ></v-checkbox>
+                            </v-card-text>
+                          </v-window-item>
+
+                          <v-window-item :value="2">
+                            <v-card-text class="pa-0">
+                              <v-sheet class="mx-auto user-form">
+                                <v-form @submit.prevent>
+                                  <h2
+                                    class="text-center font-weight-medium mb-8"
+                                  >
+                                    【{{ item.class_name }}】
+                                  </h2>
+                                  <v-label class="d-block">
+                                    <p class="d-flex mb-5">
+                                      真實姓名<span class="mark">*</span>
+                                    </p>
+                                    <v-text-field
+                                      v-model="user.name"
+                                      :rules="[
+                                        (v) => !!v || '請輸入您的真實姓名',
+                                      ]"
+                                      density="compact"
+                                      variant="outlined"
+                                    ></v-text-field>
+                                  </v-label>
+
+                                  <v-label class="mt-1">
+                                    <p class="d-flex mb-5">
+                                      生日<span class="mark">*</span>
+                                    </p>
+                                  </v-label>
+
+                                  <VueDatePicker
+                                    v-model="user.birthday"
+                                    :format="store.datePickerFormat"
+                                    :enable-time-picker="false"
+                                    :max-date="new Date()"
+                                    locale="cn"
+                                  ></VueDatePicker>
+
+                                  <span
+                                    v-if="birthdayError"
+                                    class="birthday-error"
+                                    >請選擇您的生日</span
+                                  >
+
+                                  <v-label class="d-block mt-5">
+                                    <p class="d-flex mb-5">
+                                      手機號碼<span class="mark">*</span>
+                                    </p>
+                                    <v-text-field
+                                      v-model="user.phone"
+                                      :rules="[
+                                        (v) => !!v || '請輸入您的手機號碼',
+                                      ]"
+                                      density="compact"
+                                      variant="outlined"
+                                    ></v-text-field>
+                                  </v-label>
+
+                                  <v-label class="d-block mt-1">
+                                    <p class="d-flex mb-3">
+                                      性別<span class="mark">*</span>
+                                    </p>
+
+                                    <v-radio-group v-model="user.gender" inline>
+                                      <v-radio
+                                        label="男"
+                                        value="男"
+                                        color="brown"
+                                      ></v-radio>
+                                      <v-radio
+                                        label="女"
+                                        value="女"
+                                        class="mx-2"
+                                        color="brown"
+                                      ></v-radio>
+                                      <v-radio
+                                        label="多元"
+                                        value="多元"
+                                        color="brown"
+                                      ></v-radio>
+                                    </v-radio-group>
+                                  </v-label>
+
+                                  <v-label class="d-block">
+                                    <p class="d-flex mb-5">
+                                      地址<span class="mark">*</span>
+                                    </p>
+                                    <v-text-field
+                                      v-model="user.address"
+                                      :rules="[(v) => !!v || '請輸入您的地址']"
+                                      density="compact"
+                                      variant="outlined"
+                                    ></v-text-field>
+                                  </v-label>
+
+                                  <v-label class="d-block">
+                                    <p class="d-flex mb-5">備註</p>
+
+                                    <v-textarea
+                                      placeholder="如有特殊需求或有需攜伴,請在備註欄告知老師"
+                                      variant="outlined"
+                                      rows="2"
+                                    ></v-textarea>
+                                  </v-label>
+
+                                  <v-row class="mt-3">
+                                    <v-col cols="6">
+                                      <v-btn
+                                        rounded
+                                        class="w-100"
+                                        variant="outlined"
+                                        color="brown"
+                                        @click="
+                                          isActive.value = false;
+                                          step = 1;
+                                        "
+                                        >取消</v-btn
+                                      >
+                                    </v-col>
+                                    <v-col cols="6">
+                                      <v-btn
+                                        rounded
+                                        type="submit"
+                                        class="w-100"
+                                        variant="flat"
+                                        color="brown"
+                                        :loading="isSignUpLoading"
+                                        @click="signUpSubmit(item.event_id)"
+                                        >確定報名</v-btn
+                                      >
+                                    </v-col>
+                                  </v-row>
+                                </v-form>
+                              </v-sheet>
+                            </v-card-text>
+                          </v-window-item>
+
+                          <v-window-item :value="3">
+                            <v-card-text class="px-0 px-sm-2">
+                              <v-sheet
+                                width="300"
+                                class="text-center mx-auto result-card"
+                              >
+                                <v-icon
+                                  class="mb-5"
+                                  :color="resultCard.color"
+                                  :icon="resultCard.icon"
+                                  size="112"
+                                ></v-icon>
+
+                                <h2 class="text-h5 mb-6">
+                                  {{ resultCard.text }}
+                                </h2>
+
+                                <v-divider class="mb-7"></v-divider>
+
+                                <v-btn
+                                  class="text-none me-3"
+                                  rounded
+                                  width="90"
+                                  color="brown"
+                                  variant="outlined"
+                                  @click="
+                                    isActive.value = false;
+                                    step = 1;
+                                  "
+                                >
+                                  關閉
+                                </v-btn>
+                                <v-btn
+                                  color="brown"
+                                  class="text-none"
+                                  rounded
+                                  @click="isActive.value = false"
+                                >
+                                  <router-link to="/user/passport"
+                                    >前往會員專區</router-link
+                                  >
+                                </v-btn>
+                              </v-sheet>
+                            </v-card-text>
+                          </v-window-item>
+                        </v-window>
+
+                        <v-divider v-if="step === 1"></v-divider>
+
+                        <v-card-actions v-if="step === 1" class="mt-2">
+                          <!-- <v-btn v-if="step > 1" variant="text" @click="step--">
+                            上一步
+                          </v-btn> -->
+                          <v-spacer></v-spacer>
+                          <v-btn
+                            class="me-2 px-5"
+                            color="brown"
+                            variant="outlined"
+                            @click="isActive.value = false"
+                          >
+                            不同意
+                          </v-btn>
+                          <v-btn
+                            class="px-5"
+                            color="brown"
+                            variant="flat"
+                            :disabled="!checkConsent"
+                            @click="step++"
+                          >
+                            我同意
+                          </v-btn>
+                        </v-card-actions>
+                      </v-card>
+                    </template>
+                  </v-dialog>
+
+                  <!-- <v-btn rounded="xl" color="brown">
                     <a v-if="isInner === 0" :href="item.URL" target="_blank"
                     <a v-if="isInner === 0" :href="item.URL" target="_blank"
                       >報名</a
                       >報名</a
                     >
                     >
@@ -657,13 +983,6 @@ let currentTitle = computed(() => {
                           <v-divider v-if="step === 1"></v-divider>
                           <v-divider v-if="step === 1"></v-divider>
 
 
                           <v-card-actions v-if="step === 1" class="mt-2">
                           <v-card-actions v-if="step === 1" class="mt-2">
-                            <!-- <v-btn
-                                v-if="step > 1"
-                                variant="text"
-                                @click="step--"
-                              >
-                                上一步
-                              </v-btn> -->
                             <v-spacer></v-spacer>
                             <v-spacer></v-spacer>
                             <v-btn
                             <v-btn
                               class="me-2 px-5"
                               class="me-2 px-5"
@@ -686,7 +1005,7 @@ let currentTitle = computed(() => {
                         </v-card>
                         </v-card>
                       </template>
                       </template>
                     </v-dialog>
                     </v-dialog>
-                  </v-btn>
+                  </v-btn> -->
                 </td>
                 </td>
                 <!-- <td style="width: 0; padding: 0; border: none">
                 <!-- <td style="width: 0; padding: 0; border: none">
                   <div class="signup-btn">
                   <div class="signup-btn">
@@ -700,7 +1019,7 @@ let currentTitle = computed(() => {
           </table>
           </table>
         </div>
         </div>
       </v-col>
       </v-col>
-      <v-col v-if="other.classes.length" cols="12" class="my-16">
+      <v-col v-if="other.classes.length" cols="12" class="mb-16">
         <p class="other-title">其他推薦課程</p>
         <p class="other-title">其他推薦課程</p>
         <div class="d-flex justify-center mb-10" v-if="isLoading">
         <div class="d-flex justify-center mb-10" v-if="isLoading">
           <v-progress-circular
           <v-progress-circular
@@ -738,7 +1057,7 @@ let currentTitle = computed(() => {
   .cover-img {
   .cover-img {
     // width: 100%;
     // width: 100%;
     height: 100%;
     height: 100%;
-    max-height: 400px;
+    max-height: 25em;
     object-fit: cover;
     object-fit: cover;
     &.small {
     &.small {
       width: auto;
       width: auto;
@@ -753,35 +1072,35 @@ let currentTitle = computed(() => {
     align-items: center;
     align-items: center;
     justify-content: center;
     justify-content: center;
     h2 {
     h2 {
-      margin-top: -35px;
-      margin-left: 5px;
-      font-size: 24px;
+      margin-top: -2.1875em;
+      margin-left: 0.3125em;
+      font-size: 1.5em;
       font-weight: 500;
       font-weight: 500;
-      line-height: 32px;
-      letter-spacing: 1px;
+      line-height: 2em;
+      letter-spacing: 0.0625em;
       color: #201715;
       color: #201715;
     }
     }
     .bg-img {
     .bg-img {
-      width: 250px;
+      width: 15.625em;
       position: absolute;
       position: absolute;
       z-index: -1;
       z-index: -1;
-      right: -15px;
-      bottom: -100px;
+      right: -0.9375em;
+      bottom: -6.25em;
     }
     }
   }
   }
 
 
   .info {
   .info {
-    margin: 50px auto;
-    padding: 25px 50px;
+    margin: 3.125em auto;
+    padding: 1.5625em 3.125em;
     table {
     table {
       td {
       td {
-        padding: 10px 20px;
-        line-height: 32px;
-        letter-spacing: 1px;
+        padding: 25px 25px 0;
+        line-height: 2em;
+        letter-spacing: 0.0625em;
         vertical-align: top;
         vertical-align: top;
         white-space: pre-line; // 顯示換行標籤
         white-space: pre-line; // 顯示換行標籤
         &:first-child {
         &:first-child {
-          border-right: 1px solid #333;
+          border-right: 0.0625em solid #333;
         }
         }
 
 
         strong {
         strong {
@@ -789,13 +1108,13 @@ let currentTitle = computed(() => {
         }
         }
       }
       }
       th {
       th {
-        padding-bottom: 20px;
-        border-bottom: 1px solid #333;
+        padding-bottom: 1.25em;
+        border-bottom: 0.0625em solid #333;
       }
       }
       th,
       th,
       td:first-child {
       td:first-child {
-        width: 117px;
-        font-size: 18px;
+        width: 7.3125em;
+        font-size: 1.125em;
         font-weight: 500;
         font-weight: 500;
       }
       }
     }
     }
@@ -808,24 +1127,31 @@ let currentTitle = computed(() => {
       width: 100%;
       width: 100%;
       border-collapse: collapse;
       border-collapse: collapse;
       td {
       td {
-        line-height: 30px;
+        line-height: 1.875em;
       }
       }
     }
     }
   }
   }
 
 
   .sessions {
   .sessions {
-    padding: 25px 50px 50px;
-    letter-spacing: 1px;
+    padding: 1.5625em 3.125em 3.125em;
+    letter-spacing: 0.0625em;
+    overflow-x: scroll;
     table {
     table {
+      width: 100%;
       position: relative;
       position: relative;
+
+      @media (max-width: 1280px) {
+        width: 1000px;
+      }
+
       th {
       th {
-        width: 117px;
-        font-size: 18px;
+        width: 7.3125em;
+        font-size: 1.125em;
         font-weight: 500;
         font-weight: 500;
-        padding-bottom: 20px;
+        padding-bottom: 1.25em;
       }
       }
       td {
       td {
-        padding: 20px;
+        padding: 1.25em;
         vertical-align: middle;
         vertical-align: middle;
       }
       }
       tbody {
       tbody {
@@ -835,7 +1161,7 @@ let currentTitle = computed(() => {
 
 
     .signup-btn {
     .signup-btn {
       position: absolute;
       position: absolute;
-      bottom: -53px;
+      bottom: -3.3125em;
       right: 0;
       right: 0;
     }
     }
   }
   }
@@ -845,20 +1171,20 @@ let currentTitle = computed(() => {
   }
   }
 
 
   .other-title {
   .other-title {
-    margin: 30px 0;
-    padding-bottom: 30px;
-    font-size: 26px;
+    margin: 1.875em 0;
+    padding-bottom: 1.875em;
+    font-size: 1.625em;
     text-align: center;
     text-align: center;
-    border-bottom: 1px solid;
+    border-bottom: 0.0625em solid;
   }
   }
 }
 }
 
 
 .user-form {
 .user-form {
-  width: 600px;
-  padding: 0 30px 30px;
-  // box-shadow: 1px 1px 8px #ccc;
-  // border-radius: 5px;
-  // margin: 0 15px 15px;
+  width: 37.5em;
+  padding: 0 1.875em 1.875em;
+  // box-shadow: 0.0625em 0.0625em 0.5em #ccc;
+  // border-radius: 0.3125em;
+  // margin: 0 0.9375em 0.9375em;
 
 
   @media (max-width: 600px) {
   @media (max-width: 600px) {
     width: 100%;
     width: 100%;
@@ -866,7 +1192,7 @@ let currentTitle = computed(() => {
   }
   }
 
 
   h2 {
   h2 {
-    font-size: 18px;
+    font-size: 1.125em;
   }
   }
 
 
   .result-card {
   .result-card {
@@ -878,10 +1204,10 @@ let currentTitle = computed(() => {
 
 
   .birthday-error {
   .birthday-error {
     display: block;
     display: block;
-    font-size: 12px;
+    font-size: 0.75em;
     color: #b00020;
     color: #b00020;
-    margin-left: 15px;
-    padding-top: 5px;
+    margin-left: 0.9375em;
+    padding-top: 0.3125em;
   }
   }
 }
 }
 
 
@@ -889,25 +1215,25 @@ let currentTitle = computed(() => {
   .v-card-text {
   .v-card-text {
     @media (max-width: 600px) {
     @media (max-width: 600px) {
       overflow-y: auto;
       overflow-y: auto;
-      max-height: 500px;
+      max-height: 31.25em;
     }
     }
   }
   }
 }
 }
 
 
 .consent {
 .consent {
-  max-width: 800px;
-  padding: 30px 20px;
-  border: 1px solid #909090;
-  border-radius: 5px;
+  max-width: 50em;
+  padding: 1.875em 1.25em;
+  border: 0.0625em solid #909090;
+  border-radius: 0.3125em;
   h4 {
   h4 {
-    font-size: 18px;
+    font-size: 1.125em;
     font-weight: 400;
     font-weight: 400;
-    margin-bottom: 20px;
+    margin-bottom: 1.25em;
   }
   }
   p {
   p {
-    margin-top: 20px;
-    font-size: 16px;
-    line-height: 26px;
+    margin-top: 1.25em;
+    font-size: 1em;
+    line-height: 1.625em;
   }
   }
 }
 }
 </style>
 </style>

+ 9 - 9
src/views/CourseList.vue

@@ -170,7 +170,7 @@ watch(selectCategory, (val) => {
     ></v-breadcrumbs> -->
     ></v-breadcrumbs> -->
 
 
     <!-- <div class="banner">
     <!-- <div class="banner">
-        <img src="@/assets/img/course/banner.png" alt="" />
+        <img src="@/assets/img/course/banner.png" alt="臺灣工藝學校全球學習共享平台" />
       </div> -->
       </div> -->
     <v-row class="main-block">
     <v-row class="main-block">
       <v-col cols="12">
       <v-col cols="12">
@@ -259,7 +259,7 @@ watch(selectCategory, (val) => {
       <v-col cols="12" md="9" lg="10">
       <v-col cols="12" md="9" lg="10">
         <div>
         <div>
           <div
           <div
-            class="d-flex flex-column flex-md-row align-center justify-space-between title"
+            class="d-flex flex-column flex-md-row align-center justify-space-between mb-14"
             ref="listLocation"
             ref="listLocation"
           >
           >
             <div class="d-flex tab-btn mb-8 mb-md-0">
             <div class="d-flex tab-btn mb-8 mb-md-0">
@@ -288,7 +288,7 @@ watch(selectCategory, (val) => {
                   placeholder="關鍵字搜尋"
                   placeholder="關鍵字搜尋"
                 />
                 />
                 <button @click="search()">
                 <button @click="search()">
-                  <img src="@/assets/img/news/news-search-icon.png" alt="" />
+                  <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
                 </button>
                 </button>
               </span>
               </span>
             </div>
             </div>
@@ -334,7 +334,7 @@ watch(selectCategory, (val) => {
         </div>
         </div>
       </v-col>
       </v-col>
       <v-col cols="12" class="my-16">
       <v-col cols="12" class="my-16">
-        <img src="@/assets/img/course/banner.png" alt="" />
+        <img src="@/assets/img/course/banner.png" alt="臺灣工藝學校全球學習共享平台" />
       </v-col>
       </v-col>
     </v-row>
     </v-row>
   </v-container>
   </v-container>
@@ -354,19 +354,19 @@ watch(selectCategory, (val) => {
     margin-top: 0;
     margin-top: 0;
     padding: 0;
     padding: 0;
     @media (max-width: 1400px) {
     @media (max-width: 1400px) {
-      padding: 0 70px;
+      padding: 0 4.375em;
     }
     }
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      padding: 0 20px;
+      padding: 0 1.25em;
     }
     }
     .title {
     .title {
-      padding: 0 0 80px;
+      padding: 0 0 5em;
     }
     }
   }
   }
   .filter-list {
   .filter-list {
-    margin-top: 130px;
+    margin-top: 8.125em;
     @media (max-width: 960px) {
     @media (max-width: 960px) {
-      margin: 20px 0;
+      margin: 1.25em 0;
     }
     }
   }
   }
 }
 }

File diff suppressed because it is too large
+ 616 - 328
src/views/Courses/Create.vue


+ 2198 - 0
src/views/Courses/Proposal.vue

@@ -0,0 +1,2198 @@
+<script setup>
+import { ref, reactive, watch, computed, onMounted } from "vue";
+import { useMainStore } from "@/stores/store";
+// import { Loader } from "@googlemaps/js-api-loader";
+// import VueDatePicker from "@vuepic/vue-datepicker";
+import "@vuepic/vue-datepicker/dist/main.css";
+import axios from "axios";
+import moment from "moment";
+import Navbar from "@/components/Navbar.vue";
+// import { LatLngBounds } from "leaflet";
+
+const store = useMainStore();
+const token = store.token;
+console.log("token", token);
+
+let step = ref(1);
+let stepTitle = ref("");
+let stepDescription = ref("");
+let loading = ref(false);
+
+const computedTitle = computed(() => {
+  switch (step.value) {
+    case 1:
+      stepTitle.value = "Step1 填寫基本資料";
+      stepDescription.value = "創建課程之前,請先新增您的據點(上課地址)";
+      break;
+    case 2:
+      stepTitle.value = "Step2 指派工藝家";
+      stepDescription.value =
+        "開始打造屬於您的工藝履歷,讓學徒對你印象深刻吧!";
+      break;
+    case 3:
+      stepTitle.value = "Step3 規劃開課內容";
+      stepDescription.value =
+        "完整且清楚的課程建立,是連接工藝老師與學徒的重要橋梁!";
+      break;
+    case 4:
+      stepTitle.value = "恭喜您完成課程提案!";
+      stepDescription.value = "";
+      break;
+  }
+  return { stepTitle: stepTitle.value, stepDescription: stepDescription.value };
+});
+
+const breadcrumbs = reactive([
+  {
+    title: "首頁",
+    disabled: false,
+    href: "/",
+  },
+  {
+    title: "我要開課",
+    disabled: false,
+    href: "/setup-courses",
+  },
+  {
+    title: "工藝家提案",
+    disabled: true,
+  },
+]);
+
+// // Google Map
+// const states = reactive({
+//   google: null,
+//   map: null,
+//   markers: null,
+// });
+
+// const initMap = async () => {
+//   const loader = new Loader({
+//     apiKey: "AIzaSyClxiB7zcQDyGaB1r3Ww_VQG950AtjVoAk",
+//     version: "weekly",
+//     libraries: ["places"],
+//     language: "zh-TW",
+//   });
+//   states.google = await loader.load();
+//   states.map = new states.google.maps.Map(document.getElementById("map"), {
+//     center: { lat: 25.0425, lng: 121.5468 },
+//     zoom: 11,
+//     mapTypeControl: false,
+//     fullscreenControl: false,
+//   });
+// };
+
+// onMounted(async () => {
+//   await initMap();
+// });
+
+// const getCoordinates = async () => {
+//   const geocoder = new states.google.maps.Geocoder();
+//   geocoder.geocode({ address: location.address }, (results, status) => {
+//     if (status === states.google.maps.GeocoderStatus.OK) {
+//       location.Lat = results[0].geometry.location.lat();
+//       location.Lng = results[0].geometry.location.lng();
+//     }
+
+//     // 將地圖中心設為取得的經緯度,並調整縮放等級
+//     // states.map.setCenter({ lat: location.Lat, lng: location.Lng });
+//     // states.map.setZoom(15);
+
+//     // 設定地址圖標
+//     // const marker = new google.maps.Marker({
+//     //   position: { lat: location.Lat, lng: location.Lng },
+//     //   map: states.map,
+//     //   title: location.address,
+//     //   icon: store.getImageUrl("map-icon/icon_house05.png"),
+//     // });
+//   });
+// };
+
+let location = reactive({
+  location_name: "",
+  Lng: "",
+  Lat: "",
+  address: "",
+  school_introduction: "",
+  email: "",
+  phone: "",
+  access_token: token,
+  teachers_list: [], // 指派工藝家
+  is_pass_proposal: 0, // 是否通過提案
+  principal_user_email: "", // 負責人 email
+});
+
+let locationId = ref("");
+
+// 新增履歷
+let resume = reactive({
+  teacher_name: "", // 老師姓名
+  work_type: "", // 工作性質
+  experience: "", // 教學經驗
+  expertise: "", // 專長工藝技能
+  license: "", // 工藝相關證照
+  media: "", // 社群媒體
+  // files: [], // 作品集
+  introduction: "", // 老師介紹
+});
+
+let resumeList = ref([]);
+let createDialog = ref(false);
+
+// 新增工藝家履歷
+async function insertUserResume() {
+  const validationResult = await resumeForm.value.validate();
+
+  // 驗證表單
+  if (validationResult.valid) {
+    resumeList.value.push(JSON.parse(JSON.stringify(resume)));
+    alert("新增成功!");
+    createDialog.value = false;
+
+    // 清空表單的值
+    for (const key in resume) {
+      if (resume.hasOwnProperty(key)) {
+        resume[key] = "";
+      }
+    }
+  } else {
+    return;
+  }
+}
+
+// 新增課程
+let course = reactive({
+  name: "", // 課程名稱
+  location_id: "", // 據點編號
+  category: "", // 工藝類別
+  introduction: "", // 課程簡介
+  organizer: "", // 主辦單位
+  cover_img_file: "", // 課程圖片
+  group_id: 2, // 學群編號(技藝)
+  group_sort: "", // 學群細分
+  special_class_list_name: "",
+  recommend: 0, // 是否推薦
+  is_inner: 1, // 內課課程
+  is_check: 0, // 審核結果
+  teachers_resume: [], // 指派工藝家
+  access_token: token,
+});
+
+watch(location, (data) => {
+  course.organizer = data.location_name; // 據點名稱 = 主辦單位
+});
+
+// 新增場次
+let event = reactive({
+  name_id: "", // 課程名稱編號(需先新增課程取得Id)
+  event: "", // 場次名稱
+  start_time: "", // 課程起始日
+  end_time: "", // 課程結束日
+  contact: "", // 聯絡資訊
+  lecturer: "", // 課程講師
+  location: "",
+  content: "", // 課程內容
+  URL: "", // 外部連結
+  people: "不拘", // 對象
+  fee_method: "", // 課程價格
+  fee_payment: "", // 收費方式
+  registration_way: "", // 報名方式
+  registration_start: "", // 報名起始日
+  registration_end: "", // 報名截止日
+  number_limit: "", // 課程名額
+  remark: "", // 備註
+  ATM_address: "", // 匯款帳號(銀行代碼+帳號)
+  access_token: token,
+  files: [],
+});
+
+function insertSchool() {
+  location.teachers_list = JSON.stringify(resumeList.value);
+  console.log("提案據點", location);
+
+  const formData = new FormData();
+  for (const key in location) {
+    formData.append(key, location[key]);
+  }
+
+  return axios.post("https://cmm.ai:8088/api/insert_school", formData);
+}
+
+function insertClassName(id) {
+  course.location_id = id;
+
+  if (coverImg.value !== "") {
+    course.cover_img_file = coverImg.value;
+  }
+
+  const formData = new FormData();
+  for (const key in course) {
+    formData.append(key, course[key]);
+  }
+
+  return axios.post("https://cmm.ai:8088/api/insert_class_name", formData);
+}
+
+function insertEvent(id) {
+  if (id) {
+    event.name_id = id;
+  }
+
+  console.log("insertEvent", event);
+
+  const formData = new FormData();
+  for (const key in event) {
+    if (key === "files") {
+      event.files.forEach((file) => {
+        console.log("file", file);
+        formData.append("files", file);
+      });
+    } else {
+      formData.append(key, event[key]);
+    }
+  }
+
+  return axios.post("https://cmm.ai:8088/api/insert_event", formData);
+}
+
+async function create() {
+  loading.value = true;
+
+  insertSchool()
+    .then((schoolResponse) => {
+      console.log("新增據點", schoolResponse);
+
+      if (schoolResponse.data.code === 200) {
+        locationId.value = schoolResponse.data.location_id;
+        console.log("locationId.value", locationId.value);
+
+        return insertClassName(schoolResponse.data.location_id); // 新增課程
+      }
+      return Promise.reject("新增據點失败");
+    })
+    .then((classResponse) => {
+      console.log("新增課程", classResponse);
+      return insertEvent(classResponse.data.new_class_name_id); // 新增場次
+    })
+    .then((eventResult) => {
+      console.log("新增場次", eventResult);
+      loading.value = false;
+    })
+    .then(() => {
+      step.value++;
+    })
+    .catch((error) => {
+      console.log("error", error);
+    });
+}
+
+// 上傳圖片 Input
+const portfolioImgRef = ref(null);
+const coverImgRef = ref(null);
+
+const fileInputClick = (ref) => {
+  if (ref === "portfolio") {
+    portfolioImgRef.value.click();
+  } else if (ref === "cover") {
+    coverImgRef.value.click();
+  }
+};
+
+// 作品集圖片
+let portfolioImg = ref([]);
+let portfolioImgList = ref([]);
+
+const handlePortfolioImg = (files) => {
+  console.log("files", files);
+  // portfolioImgList.value = []; // 清空陣列
+  for (let index = 0; index < files.length; index++) {
+    const file = files[index];
+    console.log("file", file);
+    let url = URL.createObjectURL(file);
+    portfolioImgList.value.push(url);
+    console.log("portfolioImgList", portfolioImgList.value);
+  }
+};
+
+watch(portfolioImg, (newFiles) => {
+  if (newFiles.length > 0) {
+    handlePortfolioImg(newFiles);
+  }
+});
+
+// 封面圖片
+let coverImg = ref("");
+let coverImgUrl = ref("");
+
+const handleCoverImg = (event) => {
+  const file = event.target.files[0];
+  console.log("選擇檔案", file);
+  if (file) {
+    coverImg.value = file;
+    coverImgUrl.value = URL.createObjectURL(file); // 設定圖片預覽 URL
+  }
+};
+
+const requiredRule = (value) => !!value || "此欄位為必填";
+
+let schoolSelect = reactive({
+  list: [],
+});
+
+let schoolId = ref("");
+
+// 取得已有據點
+(async () => {
+  let token = store.token;
+  try {
+    const response = await axios.get(
+      `https://cmm.ai:8088/api/get_school?access_token=${token}`
+    );
+
+    schoolSelect.list = response.data.schools;
+    console.log("取得使用者據點", schoolSelect.list);
+  } catch (error) {
+    console.error(error);
+  }
+})();
+
+// 監聽據點 Select
+watch(schoolId, (id) => {
+  console.log("schoolId", id);
+  // locationId.value = id;
+  handleSchoolData(id);
+});
+
+let schools = reactive({
+  list: [],
+});
+
+// 帶入據點資料
+async function handleSchoolData(id) {
+  console.log("handleSchoolData", id);
+  try {
+    const response = await axios.get(
+      `https://cmm.ai:8088/api/get_school?location_id=${id}`
+    );
+
+    schools.list = response.data.schools;
+    console.log("取得已有據點", schools.list);
+
+    for (const key in schools.list[0]) {
+      if (location.hasOwnProperty(key) && schools.list[0][key] !== undefined) {
+        location[key] = schools.list[0][key];
+      }
+    }
+  } catch (error) {
+    console.error(error);
+  }
+}
+
+const schoolForm = ref(null); // Step1 表單
+const resumeForm = ref(null); // Step2 表單
+const courseForm = ref(null); // Step3 表單
+
+let errorField = ref(false);
+
+function checkField(num) {
+  console.log("checkField", num);
+  // step.value++;
+  if (num === 1) {
+    console.log("location", location);
+    schoolForm.value.validate();
+    for (const key in location) {
+      // 判斷是否有空值
+      if (key !== "Lat" && key !== "Lng" && key !== "is_pass_proposal") {
+        if (!location[key]) {
+          console.log("!location[key]", key);
+          errorField.value = true;
+
+          setTimeout(() => {
+            errorField.value = false;
+          }, 3000);
+          return;
+        } else {
+          errorField.value = false;
+        }
+      }
+    }
+  } else if (num === 2) {
+    // resumeForm.value.validate();
+
+    if (!resumeList.value.length) {
+      errorField.value = true;
+
+      setTimeout(() => {
+        errorField.value = false;
+      }, 3000);
+
+      return;
+    }
+  }
+
+  step.value++;
+}
+
+let teacherName = ref("");
+let teacherList = ref([]);
+let isLoading = ref(false);
+
+let result = reactive({
+  show: false,
+  color: "",
+  text: "",
+});
+
+function closeResult() {
+  setTimeout(() => {
+    result.show = false;
+  }, 2000);
+}
+
+function handleResponse(show, color, text) {
+  result.show = show;
+  result.color = color;
+  result.text = text;
+
+  closeResult();
+}
+
+// async function assignTeacher() {
+//   console.log(teacherName.value);
+
+//   if (teacherName.value === "") {
+//     resumeForm.value.validate();
+//     return;
+//   }
+
+//   isLoading.value = true;
+
+//   // 判斷 list 內是否已有相同 email
+//   const found = teacherList.value.some((item) => {
+//     return item === teacherName.value;
+//   });
+
+//   if (found) {
+//     console.log("重複輸入");
+//     isLoading.value = false;
+//     handleResponse(true, "error", "此 Email 已指派");
+//     return;
+//   } else {
+//     try {
+//       const response = await axios.post(
+//         `https://cmm.ai:8088/api/check_is_user?email=${teacherName.value}`
+//       );
+
+//       if (response.data.msg === "success") {
+//         handleResponse(true, "success", response.data.result);
+//         teacherList.value.push(teacherName.value);
+//         teacherName.value = null;
+//       } else if (response.data.msg === "error") {
+//         handleResponse(true, "error", response.data.result);
+//       }
+
+//       isLoading.value = false;
+
+//       console.log("response", response);
+//       console.log("response.data.msg", response.data.msg);
+//     } catch (error) {
+//       console.error(error);
+//     }
+//   }
+// }
+
+function removeTeacher(index) {
+  console.log("index", index);
+  resumeList.value.splice(index, 1);
+  // teacherList.value.splice(index, 1);
+}
+</script>
+
+<template>
+  <Navbar />
+
+  <v-container class="mb-16 pb-16 proposal-container">
+    <v-breadcrumbs
+      :items="breadcrumbs"
+      divider="/"
+      class="py-10"
+    ></v-breadcrumbs>
+
+    <v-card class="mx-auto pa-5 pa-sm-10">
+      <v-card-title class="step-title mb-5">
+        <h5>{{ computedTitle.stepTitle }}</h5>
+        <p class="mt-5">{{ computedTitle.stepDescription }}</p>
+      </v-card-title>
+
+      <v-window v-model="step">
+        <v-window-item :value="1">
+          <v-card-text>
+            <v-form ref="schoolForm" lazy-validation @submit.prevent>
+              <!-- <div v-if="schoolSelect.list.length" class="mb-10 school-list">
+                <v-label class="d-flex align-center w-100 overflow-visible">
+                  <p class="pe-3">已經有據點?</p>
+                  <v-select
+                    v-model="schoolId"
+                    label="請選擇據點"
+                    :items="schoolSelect.list"
+                    item-title="location_name"
+                    item-value="location_id"
+                    hide-details
+                    density="compact"
+                    variant="outlined"
+                  ></v-select>
+                </v-label>
+              </div> -->
+
+              <v-row class="justify-center">
+                <v-col cols="12" md="6">
+                  <v-label class="d-block mb-5">
+                    <p class="d-flex mb-5">
+                      工坊名稱<span class="mark">*</span>
+                    </p>
+                    <v-text-field
+                      v-model="location.location_name"
+                      :rules="[requiredRule]"
+                      title="工坊名稱"
+                      placeholder="可以是您的工作室或品牌名稱/教學單位/您的姓名"
+                      density="compact"
+                      variant="outlined"
+                      counter
+                      maxlength="60"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="d-flex mb-5">
+                      工坊地址<span class="mark">*</span>
+                    </p>
+                    <v-text-field
+                      v-model="location.address"
+                      :rules="[requiredRule]"
+                      title="工坊地址"
+                      density="compact"
+                      variant="outlined"
+                      placeholder="需在安全且便於學徒到達之地點開課"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="d-flex mb-5">
+                      工坊 Email<span class="mark">*</span>
+                    </p>
+                    <v-text-field
+                      v-model="location.email"
+                      :rules="[requiredRule]"
+                      density="compact"
+                      variant="outlined"
+                      placeholder="請填寫 Email"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="d-flex mb-5">
+                      負責人 Email<span class="mark">*</span>
+                    </p>
+                    <v-text-field
+                      v-model="location.principal_user_email"
+                      :rules="[requiredRule]"
+                      title="負責人 Email"
+                      density="compact"
+                      variant="outlined"
+                      placeholder="請填寫 Email"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <div class="d-flex">
+                      <p class="d-flex mb-5">
+                        公開電話<span class="mark">*</span>
+                      </p>
+                      <span class="d-block ms-3 hint"
+                        >會顯示於課程介紹中,想了解課程資訊者聯繫用途
+                      </span>
+                    </div>
+
+                    <v-text-field
+                      v-model="location.phone"
+                      :rules="[requiredRule]"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block">
+                    <p class="d-flex mb-5">
+                      工坊簡介<span class="mark">*</span>
+                    </p>
+                    <v-textarea
+                      v-model="location.school_introduction"
+                      :rules="[requiredRule]"
+                      rows="5"
+                      variant="outlined"
+                      placeholder="請輸入工坊簡介"
+                    ></v-textarea>
+                  </v-label>
+                </v-col>
+
+                <v-col cols="12" md="6"> </v-col>
+
+                <!-- <v-col cols="12" md="6" class="px-0">
+                  <v-label class="d-block">
+                    <p class="d-flex mb-5">負責人<span class="mark">*</span></p>
+                    <v-text-field
+                      :rules="[requiredRule]"
+                      title="負責人"
+                      density="compact"
+                      variant="outlined"
+                      counter
+                      maxlength="60"
+                    ></v-text-field>
+                  </v-label>
+                </v-col>
+
+                <v-col cols="12" md="11" class="px-4">
+                  <v-label class="d-block">
+                    <p class="d-flex mb-5">
+                      工坊地址<span class="mark">*</span>
+                    </p>
+                    <v-text-field
+                      v-model="location.address"
+                      :rules="[requiredRule]"
+                      title="工坊地址"
+                      density="compact"
+                      variant="outlined"
+                      placeholder="需在安全且便於學徒到達之地點開課"
+                    ></v-text-field>
+                  </v-label>
+                </v-col>
+
+                <v-col cols="12" md="5" class="px-0">
+                  <v-label class="d-block">
+                    <p class="d-flex mb-5">
+                      據點 Email<span class="mark">*</span>
+                    </p>
+                    <v-text-field
+                      v-model="location.email"
+                      :rules="[requiredRule]"
+                      density="compact"
+                      variant="outlined"
+                      placeholder="請填寫 Email"
+                    ></v-text-field>
+                  </v-label>
+                </v-col>
+
+                <v-col cols="12" md="5" class="px-0">
+                  <v-label class="d-block">
+                    <div class="d-flex">
+                      <p class="d-flex mb-5">
+                        公開電話<span class="mark">*</span>
+                      </p>
+                      <span class="d-block ms-3 hint"
+                        >會顯示於課程介紹中,想了解課程資訊者聯繫用途
+                      </span>
+                    </div>
+
+                    <v-text-field
+                      v-model="location.phone"
+                      :rules="[requiredRule]"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+                </v-col>
+
+                <v-col cols="12" md="11">
+                  <v-label class="d-block">
+                    <p class="d-flex mb-5">
+                      據點簡介<span class="mark">*</span>
+                    </p>
+                    <v-textarea
+                      v-model="location.school_introduction"
+                      :rules="[requiredRule]"
+                      rows="5"
+                      variant="outlined"
+                    ></v-textarea>
+                  </v-label>
+                </v-col> -->
+              </v-row>
+
+              <!-- <div class="d-flex flex-column justify-end ms-md-16 ps-md-5">
+                <div
+                  class="map"
+                  id="map"
+                  style="width: 100%; height: 31.25em"
+                ></div>
+
+                <v-row>
+                  <v-col cols="12" md="6">
+                    <v-label class="d-flex align-center">
+                      <p class="pb-5 pe-3">經度</p>
+                      <v-text-field
+                        v-model="location.Lng"
+                        density="compact"
+                        variant="outlined"
+                        disabled
+                      ></v-text-field>
+                    </v-label>
+                  </v-col>
+                  <v-col cols="12" md="6" class="py-0 py-md-3">
+                    <v-label class="d-flex align-center">
+                      <p class="pb-5 pe-3">緯度</p>
+                      <v-text-field
+                        v-model="location.Lat"
+                        density="compact"
+                        variant="outlined"
+                        disabled
+                      ></v-text-field>
+                    </v-label>
+                  </v-col>
+                </v-row>
+              </div> -->
+            </v-form>
+          </v-card-text>
+        </v-window-item>
+
+        <v-window-item :value="2">
+          <v-card-text
+            class="d-flex flex-column align-center justify-center mb-16"
+          >
+            <!-- <button class="resume-btn">
+                    <p class="d-flex flex-column align-center">
+                      <v-icon icon="mdi-plus"></v-icon>
+                      新增工藝家
+                    </p>
+                  </button> -->
+
+            <button class="resume-btn">
+              <p class="d-flex flex-column align-center">
+                <v-icon icon="mdi-plus" size="x-large"></v-icon>
+                新增工藝家
+              </p>
+
+              <v-dialog v-model="createDialog" activator="parent" width="700">
+                <v-card class="pa-5">
+                  <v-card-title>工藝家履歷</v-card-title>
+                  <v-card-text>
+                    <v-form ref="resumeForm" lazy-validation @submit.prevent>
+                      <v-row>
+                        <v-col cols="12">
+                          <v-label class="d-flex align-center">
+                            <p class="pb-5 pe-3">
+                              老師姓名<span class="mark">*</span>
+                            </p>
+                            <v-text-field
+                              v-model="resume.teacher_name"
+                              :rules="[requiredRule]"
+                              density="compact"
+                              variant="outlined"
+                            ></v-text-field>
+                          </v-label>
+                        </v-col>
+
+                        <!-- <v-col cols="6"></v-col> -->
+
+                        <v-col cols="12">
+                          <v-label class="d-block">
+                            <p class="pb-5 pe-3">
+                              工作性質<span class="mark">*</span>
+                            </p>
+                            <v-radio-group v-model="resume.work_type" inline>
+                              <v-radio label="全職" value="全職"></v-radio>
+                              <v-radio
+                                label="兼職"
+                                value="兼職"
+                                class="ps-3"
+                              ></v-radio>
+                            </v-radio-group>
+                          </v-label>
+                        </v-col>
+
+                        <v-col cols="12" class="py-0">
+                          <v-label class="d-block">
+                            <p class="pb-5 pe-3">教學經驗</p>
+                            <v-radio-group v-model="resume.experience" inline>
+                              <v-radio label="0-5 年" value="0-5 年"></v-radio>
+                              <v-radio
+                                label="5-10 年"
+                                value="5-10 年"
+                                class="ps-3"
+                              ></v-radio>
+                              <v-radio
+                                label="10-20 年"
+                                value="10-20 年"
+                                class="ps-3"
+                              ></v-radio>
+                              <v-radio
+                                label="20 年以上"
+                                value="20 年以上"
+                                class="ps-3"
+                              ></v-radio>
+                            </v-radio-group>
+                          </v-label>
+                        </v-col>
+
+                        <v-col cols="12">
+                          <v-label class="d-block pb-3">
+                            <p class="pb-5 pe-3">
+                              專長工藝技能<span class="mark">*</span>
+                            </p>
+                            <v-text-field
+                              v-model="resume.expertise"
+                              :rules="[requiredRule]"
+                              density="compact"
+                              variant="outlined"
+                            ></v-text-field>
+                          </v-label>
+
+                          <v-label class="d-block pb-3">
+                            <p class="pb-5 pe-3">工藝相關證照</p>
+                            <v-text-field
+                              v-model="resume.license"
+                              density="compact"
+                              variant="outlined"
+                            ></v-text-field>
+                          </v-label>
+
+                          <v-label class="d-block">
+                            <p class="d-flex">社群媒體</p>
+                            <span class="d-block py-3 hint"
+                              >工藝老師經營之網站或社群媒體,可貼網址</span
+                            >
+                            <v-text-field
+                              v-model="resume.media"
+                              density="compact"
+                              variant="outlined"
+                            ></v-text-field>
+                          </v-label>
+                        </v-col>
+
+                        <!-- <v-col cols="12">
+                                <v-label class="d-block">
+                                  <p class="d-flex">講師作品集</p>
+
+                                  <v-file-input
+                                    multiple
+                                    v-model="portfolioImg"
+                                    ref="portfolioImgRef"
+                                    label="File input"
+                                    variant="outlined"
+                                    placeholder="選擇相片上傳"
+                                    @change="handlePortfolioImg"
+                                    style="display: none"
+                                  ></v-file-input>
+                                </v-label>
+
+                                <v-btn
+                                  @click="fileInputClick('portfolio')"
+                                  color="purple"
+                                  class="my-5"
+                                  >選擇相片上傳</v-btn
+                                >
+
+                                <v-row class="img-list">
+                                  <v-col
+                                    cols="4"
+                                    v-for="(item, index) in 6"
+                                    :key="index"
+                                  >
+                                    <div
+                                      v-if="!portfolioImgList.length"
+                                      class="item"
+                                    ></div>
+                                    <div
+                                      v-else
+                                      class="item"
+                                      :style="{
+                                        backgroundImage: `url('${portfolioImgList[index]}')`,
+                                      }"
+                                    ></div>
+                                  </v-col>
+                                </v-row>
+                              </v-col> -->
+
+                        <v-col cols="12">
+                          <v-label class="d-block">
+                            <p class="d-flex mb-5">工藝家介紹</p>
+                            <v-textarea
+                              v-model="resume.introduction"
+                              rows="5"
+                              variant="outlined"
+                            ></v-textarea>
+                          </v-label>
+                        </v-col>
+                      </v-row>
+                    </v-form>
+                  </v-card-text>
+
+                  <v-card-actions class="justify-center">
+                    <v-spacer></v-spacer>
+
+                    <v-btn text="取消" @click="isActive.value = false"></v-btn>
+
+                    <v-btn
+                      @click="insertUserResume()"
+                      color="purple"
+                      variant="flat"
+                    >
+                      新增
+                    </v-btn>
+                  </v-card-actions>
+                </v-card>
+              </v-dialog>
+            </button>
+
+            <div class="main-table mt-10">
+              <h6 data-v-bbf03f1f="" class="table-title">工藝家履歷</h6>
+
+              <table>
+                <thead>
+                  <tr>
+                    <th>姓名</th>
+                    <th>工作性質</th>
+                    <th>教學經驗</th>
+                    <th>專長工藝技能</th>
+                    <th>工藝相關證照</th>
+                    <th>社群媒體</th>
+                    <th>老師介紹</th>
+                    <th></th>
+                    <!-- <th width="15%">繳款資訊</th> -->
+                  </tr>
+                </thead>
+                <tbody v-if="resumeList.length">
+                  <!-- <tr v-if="!register.list.length">
+                <p class="hint-item">
+                  目前沒有報名紀錄喔!點擊開始探索您的專屬課程!
+                </p>
+              </tr> -->
+                  <tr v-for="(item, index) in resumeList" :key="index">
+                    <td>{{ item.teacher_name }}</td>
+                    <td>{{ item.work_type }}</td>
+                    <td>{{ item.experience }}</td>
+                    <td>{{ item.expertise }}</td>
+                    <td>{{ item.license }}</td>
+                    <td>{{ item.media }}</td>
+                    <td>{{ item.introduction }}</td>
+                    <td>
+                      <v-btn
+                        @click="removeTeacher(index)"
+                        icon="mdi-close"
+                        color="red"
+                        variant="text"
+                      ></v-btn>
+                      <!-- <v-icon icon="mdi-close" color="red"></v-icon> -->
+                    </td>
+
+                    <!-- <td>{{ item.class_name }}</td>
+                <td>
+                  {{ moment(`${item.create_time}`).format("YYYY/MM/DD") }}
+                </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>{{ item.hours }} 小時</td>
+                <td>
+                  <span class="finish-icon" v-if="item.reg_confirm">
+                    <v-icon icon="mdi-check" class="pb-1"></v-icon>
+                  </span>
+
+                  <span v-else class="d-flex align-center">
+                    <p style="width: 55px" class="text-grey-lighten-1">審核中</p>
+                  </span>
+                </td> -->
+                  </tr>
+                </tbody>
+              </table>
+            </div>
+
+            <!-- <v-form ref="resumeForm" lazy-validation @submit.prevent>
+              <v-row>
+                <v-col cols="12" sm="6">
+                  <v-label class="d-flex align-center pb-3">
+                    <p class="pb-5 pe-3">老師姓名<span class="mark">*</span></p>
+                    <v-text-field
+                      v-model="resume.teacher_name"
+                      :rules="[requiredRule]"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+                </v-col>
+
+                <v-col cols="6"></v-col>
+
+                <v-col cols="12" lg="3">
+                  <v-label class="d-block">
+                    <p class="pb-5 pe-3">工作性質<span class="mark">*</span></p>
+                    <v-radio-group v-model="resume.work_type" inline>
+                      <v-radio label="全職" value="全職"></v-radio>
+                      <v-radio label="兼職" value="兼職" class="ps-3"></v-radio>
+                    </v-radio-group>
+                  </v-label>
+                </v-col>
+
+                <v-col cols="12" lg="9">
+                  <v-label class="d-block">
+                    <p class="pb-5 pe-3">教學經驗</p>
+                    <v-radio-group v-model="resume.experience" inline>
+                      <v-radio label="0-5 年" value="0-5 年"></v-radio>
+                      <v-radio
+                        label="5-10 年"
+                        value="5-10 年"
+                        class="ps-3"
+                      ></v-radio>
+                      <v-radio
+                        label="10-20 年"
+                        value="10-20 年"
+                        class="ps-3"
+                      ></v-radio>
+                      <v-radio
+                        label="20 年以上"
+                        value="20 年以上"
+                        class="ps-3"
+                      ></v-radio>
+                    </v-radio-group>
+                  </v-label>
+                </v-col>
+
+                <v-col cols="12" md="6">
+                  <v-label class="d-block pb-3">
+                    <p class="pb-5 pe-3">
+                      專長工藝技能<span class="mark">*</span>
+                    </p>
+                    <v-text-field
+                      v-model="resume.expertise"
+                      :rules="[requiredRule]"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block pb-3">
+                    <p class="pb-5 pe-3">工藝相關證照</p>
+                    <v-text-field
+                      v-model="resume.license"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block">
+                    <p class="d-flex">社群媒體</p>
+                    <span class="d-block py-3 hint"
+                      >工藝老師經營之網站或社群媒體,可貼網址</span
+                    >
+                    <v-text-field
+                      v-model="resume.media"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+                </v-col>
+
+                <v-col cols="12" md="6">
+                  <v-label class="d-block">
+                    <p class="d-flex">講師作品集</p>
+
+                    <v-file-input
+                      multiple
+                      v-model="portfolioImg"
+                      ref="portfolioImgRef"
+                      label="File input"
+                      variant="outlined"
+                      placeholder="選擇相片上傳"
+                      @change="handlePortfolioImg"
+                      style="display: none"
+                    ></v-file-input>
+                  </v-label>
+
+                  <v-btn
+                    @click="fileInputClick('portfolio')"
+                    color="purple"
+                    class="my-5"
+                    >選擇相片上傳</v-btn
+                  >
+
+                  <v-row class="img-list">
+                    <v-col cols="4" v-for="(item, index) in 6" :key="index">
+                      <div v-if="!portfolioImgList.length" class="item"></div>
+                      <div
+                        v-else
+                        class="item"
+                        :style="{
+                          backgroundImage: `url('${portfolioImgList[index]}')`,
+                        }"
+                      ></div>
+                    </v-col>
+                  </v-row>
+                </v-col>
+
+                <v-col cols="12">
+                  <v-label class="d-block">
+                    <p class="d-flex mb-5">老師自我介紹</p>
+                    <v-textarea
+                      v-model="resume.introduction"
+                      rows="5"
+                      variant="outlined"
+                    ></v-textarea>
+                  </v-label>
+                </v-col>
+              </v-row>
+            </v-form> -->
+          </v-card-text>
+        </v-window-item>
+
+        <v-window-item :value="3">
+          <v-card-text class="mb-7">
+            <v-form ref="courseForm" lazy-validation @submit.prevent>
+              <v-row class="justify-space-evenly">
+                <v-col cols="12" md="7">
+                  <v-label class="d-block mb-5">
+                    <p class="pb-5 pe-3">課程名稱<span class="mark">*</span></p>
+                    <v-text-field
+                      v-model="course.name"
+                      :rules="[requiredRule]"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="pb-5 pe-3">工藝類別<span class="mark">*</span></p>
+                    <v-select
+                      v-model="course.category"
+                      placeholder="請選擇類別"
+                      :items="[
+                        '樹藝',
+                        '漆藝',
+                        '藍染',
+                        '蠟雕',
+                        '竹工藝籃',
+                        '金工/飾品',
+                        '蠟燭/香氛/調香',
+                        '植栽/花藝',
+                        '插畫/繪畫/寫字',
+                        '皮件/皮革',
+                        '木工/竹藝',
+                        '陶藝/玻璃',
+                        '編織/羊毛氈/縫紉',
+                        '其他',
+                      ]"
+                      :rules="[requiredRule]"
+                      density="compact"
+                      variant="outlined"
+                    ></v-select>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="pb-5 pe-3">上課地點</p>
+                    <v-text-field
+                      v-model="location.address"
+                      label="自動帶入據點地址"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="pb-5 pe-3">主辦單位</p>
+                    <v-text-field
+                      v-model="location.location_name"
+                      label="自動帶入據點名稱"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="d-flex">課程簡介<span class="mark">*</span></p>
+                    <small class="my-2 hint"
+                      >內容不得少於 100 字元,且不得含有工藝無關之資訊</small
+                    >
+                    <v-textarea
+                      v-model="course.introduction"
+                      rows="5"
+                      variant="outlined"
+                      :rules="[requiredRule]"
+                    ></v-textarea>
+                  </v-label>
+
+                  <!-- <v-label class="d-block mb-5">
+                    <p class="pb-5 pe-3">課程時長<span class="mark">*</span></p>
+                    <v-text-field
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label> -->
+
+                  <v-label class="d-block mb-5">
+                    <p class="pb-5 pe-3">課程價位<span class="mark">*</span></p>
+                    <v-text-field
+                      v-model="event.fee_method"
+                      type="number"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="pb-5 pe-3">課程名額<span class="mark">*</span></p>
+                    <v-text-field
+                      v-model="event.number_limit"
+                      density="compact"
+                      variant="outlined"
+                      placeholder="請輸入報名人數上限"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="pb-5 pe-3">
+                      最低開課人數<span class="mark">*</span>
+                    </p>
+                    <v-text-field
+                      density="compact"
+                      variant="outlined"
+                      placeholder="請輸入開課門檻人數"
+                    ></v-text-field>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="pb-5 pe-3">適合對象<span class="mark">*</span></p>
+                    <v-textarea
+                      v-model="event.people"
+                      rows="2"
+                      variant="outlined"
+                      placeholder="ex. 不拘、18-65 歲、大專院校工藝、美術、設計科系學生、從事木作相關之業者或個人工作室"
+                      :rules="[requiredRule]"
+                    ></v-textarea>
+                  </v-label>
+
+                  <v-label class="d-block mb-5">
+                    <p class="d-flex">上傳課程簡報 (ex. 講義、簡介)</p>
+                    <small class="my-3 hint" style="letter-spacing: 1px"
+                      >檔案格式:.ppt|.pptx|.pdf</small
+                    >
+                    <v-file-input
+                      v-model="event.files"
+                      accept="image/*"
+                      label="上傳檔案"
+                      variant="outlined"
+                      prepend-icon="mdi-cloud-upload"
+                      class="upload-input"
+                    ></v-file-input>
+                  </v-label>
+
+                  <v-label class="d-block">
+                    <p class="d-flex">
+                      上傳課程封面<span class="mark">*</span>
+                    </p>
+
+                    <v-file-input
+                      multiple
+                      v-model="coverImg"
+                      ref="coverImgRef"
+                      label="File input"
+                      variant="outlined"
+                      placeholder="選擇相片上傳"
+                      @change="handleCoverImg"
+                      style="display: none"
+                    ></v-file-input>
+                  </v-label>
+
+                  <v-btn
+                    @click="fileInputClick('cover')"
+                    color="purple"
+                    class="my-5"
+                    >選擇相片上傳</v-btn
+                  >
+
+                  <div class="step-01 image-preview">
+                    <img
+                      v-if="coverImg"
+                      :src="coverImgUrl"
+                      alt="上傳圖片預覽"
+                    />
+                  </div>
+                </v-col>
+
+                <v-col cols="12" md="5">
+                  <div class="notes-block">
+                    <p class="mb-5">課程審核標準:</p>
+                    <ul>
+                      <li>
+                        ◆
+                        課程內容正確合宜,無錯誤與誇大不實、不含與課程無關的推銷廣告、內容無抄襲侵權、無涉及任何色情、血腥暴力、人身攻擊、歧視(包含性別、種族、性傾向等)。
+                      </li>
+                      <li>◆ 提供圖片需與課程內容相符。</li>
+                      <li>◆ 教學內容符合邏輯。</li>
+                    </ul>
+                  </div>
+                </v-col>
+
+                <!-- <v-col cols="12" md="5">
+                  <v-label class="d-block pb-3">
+                    <p class="pb-5 pe-3">課程價格<span class="mark">*</span></p>
+                    <v-text-field
+                      :rules="[requiredRule]"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+                </v-col> -->
+
+                <!-- <v-col cols="12" md="5">
+                  <v-label class="d-block pb-3">
+                    <p class="pb-5 pe-3">工藝類別<span class="mark">*</span></p>
+                    <v-select
+                      v-model="course.category"
+                      placeholder="請選擇類別"
+                      :items="[
+                        '樹藝',
+                        '漆藝',
+                        '藍染',
+                        '蠟雕',
+                        '竹工藝籃',
+                        '金工/飾品',
+                        '蠟燭/香氛/調香',
+                        '植栽/花藝',
+                        '插畫/繪畫/寫字',
+                        '皮件/皮革',
+                        '木工/竹藝',
+                        '陶藝/玻璃',
+                        '編織/羊毛氈/縫紉',
+                        '其他',
+                      ]"
+                      :rules="[requiredRule]"
+                      hide-details
+                      density="compact"
+                      variant="outlined"
+                    ></v-select>
+                  </v-label>
+                </v-col> -->
+
+                <!-- <v-col cols="12" md="5">
+                <v-label class="d-block pb-3">
+                  <p class="pb-5 pe-3">
+                    適合報名對象(年紀)<span class="mark">*</span>
+                  </p>
+
+                  <v-select
+                    v-model="age"
+                    :items="[
+                      '不拘',
+                      '7 歲以下',
+                      '7-18 歲',
+                      '18-65 歲',
+                      '65 歲以上',
+                    ]"
+                    :rules="[requiredRule]"
+                    density="compact"
+                    variant="outlined"
+                    outlined
+                  ></v-select>
+                </v-label>
+              </v-col> -->
+
+                <!-- <v-col cols="12" md="5">
+                  <v-label class="d-block pb-3">
+                    <p class="pb-5 pe-3">上課地點</p>
+                    <v-text-field
+                      v-model="location.address"
+                      label="自動帶入據點地址"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+                </v-col> -->
+
+                <!-- <v-col cols="12" md="5">
+                  <v-label class="d-block pb-3">
+                    <p class="pb-5 pe-3">主辦單位</p>
+                    <v-text-field
+                      v-model="location.location_name"
+                      label="自動帶入據點名稱"
+                      density="compact"
+                      variant="outlined"
+                    ></v-text-field>
+                  </v-label>
+                </v-col> -->
+
+                <!-- <v-col cols="12" md="11" class="px-md-7">
+                  <v-label class="d-block">
+                    <p class="d-flex">課程時間<span class="mark">*</span></p>
+
+                    <v-dialog v-model="sessionsDialog" persistent width="800">
+                      <template v-slot:activator="{ props }">
+                        <v-btn class="my-5" color="purple" v-bind="props">
+                          <v-icon icon="mdi-plus" class="me-1"></v-icon>
+                          建立新場次
+                        </v-btn>
+                      </template>
+                      <v-card class="sessions-card pb-3">
+                        <v-card-title>
+                          <span class="d-block ps-10 py-5">建立新場次</span>
+                        </v-card-title>
+                        <v-card-text class="pt-0 px-8">
+                          <v-form
+                            ref="eventForm"
+                            lazy-validation
+                            @submit.prevent
+                          >
+                            <v-container class="py-0">
+                              <v-row>
+                                <v-col cols="12" sm="6" class="date-item">
+                                  <p class="mb-0 pe-3">
+                                    起始日期<span class="mark">*</span>
+                                  </p>
+                                  <VueDatePicker
+                                    v-model="date.start_date"
+                                    :min-date="new Date()"
+                                    :enable-time-picker="false"
+                                    :format="store.datePickerFormat"
+                                    locale="cn"
+                                  ></VueDatePicker>
+                                </v-col>
+
+                                <v-col cols="12" sm="6" class="date-item">
+                                  <p class="mb-0 pe-3">
+                                    起始時間<span class="mark">*</span>
+                                  </p>
+                                  <VueDatePicker
+                                    v-model="date.start_time"
+                                    time-picker
+                                  />
+                                </v-col>
+
+                                <v-col cols="12" sm="6" class="date-item">
+                                  <p class="mb-0 pe-3">
+                                    結束日期<span class="mark">*</span>
+                                  </p>
+                                  <VueDatePicker
+                                    v-model="date.end_date"
+                                    :min-date="new Date()"
+                                    :enable-time-picker="false"
+                                    :format="store.datePickerFormat"
+                                    locale="cn"
+                                  ></VueDatePicker>
+                                </v-col>
+
+                                <v-col cols="12" sm="6" class="date-item">
+                                  <p class="mb-0 pe-3">
+                                    結束時間<span class="mark">*</span>
+                                  </p>
+                                  <VueDatePicker
+                                    v-model="date.end_time"
+                                    time-picker
+                                  />
+                                </v-col>
+
+                                <v-divider class="mt-5 mb-8"></v-divider>
+
+                                <v-col cols="12" sm="6" class="py-0">
+                                  <v-label class="d-flex align-center py-2">
+                                    <p class="pb-5 pe-3">
+                                      場次名稱<span class="mark">*</span>
+                                    </p>
+                                    <v-text-field
+                                      v-model="event.event"
+                                      :rules="[requiredRule]"
+                                      density="compact"
+                                      variant="outlined"
+                                    ></v-text-field>
+                                  </v-label>
+                                </v-col>
+
+                                <v-col cols="12" sm="6" class="py-0">
+                                  <v-label class="d-flex align-center py-2">
+                                    <p class="pb-5 pe-3">
+                                      課程講師<span class="mark">*</span>
+                                    </p>
+                                    <v-text-field
+                                      v-model="event.lecturer"
+                                      :rules="[requiredRule]"
+                                      density="compact"
+                                      variant="outlined"
+                                    ></v-text-field>
+                                  </v-label>
+                                </v-col>
+
+                                <v-col cols="12" sm="6" class="py-0">
+                                  <v-label class="d-flex align-center py-2">
+                                    <p class="pb-5 pe-3">
+                                      聯絡資訊<span class="mark">*</span>
+                                    </p>
+                                    <v-text-field
+                                      v-model="event.contact"
+                                      :rules="[requiredRule]"
+                                      density="compact"
+                                      variant="outlined"
+                                    ></v-text-field>
+                                  </v-label>
+                                </v-col>
+
+                                <v-col cols="12" sm="6" class="py-0">
+                                  <v-label class="d-flex align-center py-2">
+                                    <p class="pb-5 pe-3">
+                                      課程名額<span class="mark">*</span>
+                                    </p>
+                                    <v-text-field
+                                      v-model="event.number_limit"
+                                      :rules="[requiredRule]"
+                                      density="compact"
+                                      variant="outlined"
+                                      type="number"
+                                      hint="請設定報名人數上限"
+                                    ></v-text-field>
+                                  </v-label>
+                                </v-col>
+
+                                <v-col cols="12" class="py-0">
+                                  <v-label class="d-flex align-center py-2">
+                                    <p class="pb-5 pe-3">
+                                      收費方式<span class="mark">*</span>
+                                    </p>
+
+                                    <v-select
+                                      v-model="event.fee_payment"
+                                      :items="['現場收費', '匯款']"
+                                      :rules="[requiredRule]"
+                                      density="compact"
+                                      variant="outlined"
+                                      outlined
+                                    ></v-select>
+                                  </v-label>
+                                </v-col>
+
+                                <v-col cols="12" class="py-0">
+                                  <v-label
+                                    v-if="isRemit"
+                                    class="d-flex align-center py-2"
+                                  >
+                                    <p class="pb-5 pe-3">
+                                      匯款資訊<span class="mark">*</span>
+                                    </p>
+
+                                    <div class="d-flex w-100">
+                                      <v-text-field
+                                        v-model="bankCode"
+                                        label="銀行代碼"
+                                        :rules="[requiredRule]"
+                                        density="compact"
+                                        variant="outlined"
+                                        style="width: 30%"
+                                        class="me-3"
+                                      ></v-text-field>
+                                      <v-text-field
+                                        v-model="bankAccount"
+                                        label="匯款帳號 (10-16 碼)"
+                                        :rules="[requiredRule]"
+                                        density="compact"
+                                        variant="outlined"
+                                        style="width: 70%"
+                                      ></v-text-field>
+                                    </div>
+                                  </v-label>
+                                </v-col>
+
+                                <v-col cols="12" class="py-0">
+                                  <v-label class="d-flex align-center py-2">
+                                    <p class="pb-5 pe-3">
+                                      課程價格<span class="mark">*</span>
+                                    </p>
+                                    <v-text-field
+                                      v-model="event.fee_method"
+                                      :rules="[requiredRule]"
+                                      density="compact"
+                                      variant="outlined"
+                                    ></v-text-field>
+                                  </v-label>
+                                </v-col>
+
+                                <v-col cols="12" class="py-0">
+                                  <v-label class="d-flex align-center">
+                                    <p class="pb-3 pe-3">
+                                      適合對象<span class="mark pb-4">*</span>
+                                    </p>
+                                    <v-textarea
+                                      rows="2"
+                                      variant="outlined"
+                                      placeholder="ex. 不拘、18-65 歲、大專院校工藝、美術、設計科系學生、從事木作相關之業者或個人工作室"
+                                      :rules="[requiredRule]"
+                                    ></v-textarea>
+                                  </v-label>
+                                </v-col>
+
+                                <v-col cols="12" class="py-0 position-relative">
+                                  <v-label class="d-flex align-center py-2">
+                                    <p class="pb-3 pe-3">
+                                      課程類型<span class="mark pb-4">*</span>
+                                    </p>
+                                    <v-select
+                                      v-model="eventType"
+                                      :items="[
+                                        '一日課程(例:2023/10/2 週一上課)',
+                                        '週期課程(例:2023/10/1~2023/10/30 每週一三上課)',
+                                      ]"
+                                      :rules="[requiredRule]"
+                                      density="compact"
+                                      variant="outlined"
+                                      outlined
+                                    ></v-select>
+                                  </v-label>
+                                </v-col>
+
+                                <v-col
+                                  v-if="!isOneDay"
+                                  cols="12"
+                                  class="d-flex py-0"
+                                >
+                                  <p class="pt-1 pe-3">
+                                    重複週期<span class="mark pb-4">*</span>
+                                  </p>
+
+                                  <ul class="week-list">
+                                    <li
+                                      v-for="(item, index) in weekList"
+                                      :key="index"
+                                      @click="toggleSelected(index)"
+                                      :class="{ active: selectedWeek[index] }"
+                                      class="d-flex"
+                                    >
+                                      <button class="item">
+                                        {{ item }}
+                                      </button>
+
+                                      <div
+                                        v-if="selectedWeek[index]"
+                                        class="d-flex w-100 ms-5"
+                                      >
+                                        <VueDatePicker
+                                          v-model="
+                                            sessionTime.start_week_time[index]
+                                          "
+                                          time-picker
+                                        />
+                                        <span class="d-flex align-center mx-2"
+                                          >~</span
+                                        >
+                                        <VueDatePicker
+                                          v-model="
+                                            sessionTime.end_week_time[index]
+                                          "
+                                          time-picker
+                                        />
+                                      </div>
+                                    </li>
+                                  </ul>
+                                </v-col>
+
+                                <v-col cols="12" class="py-0">
+                                  <v-label class="d-flex align-center py-2">
+                                    <p class="pe-3">備註</p>
+                                    <v-text-field
+                                      v-model="event.remark"
+                                      density="compact"
+                                      variant="outlined"
+                                      hide-details
+                                    ></v-text-field>
+                                  </v-label>
+                                </v-col>
+
+                                <v-divider class="my-8"></v-divider>
+
+                                <v-col cols="12" sm="6" class="date-item">
+                                  <p class="mb-0 pe-3">
+                                    報名日期<span class="mark pb-4">*</span>
+                                  </p>
+                                  <VueDatePicker
+                                    v-model="date.registration_start_date"
+                                    :min-date="new Date()"
+                                    :enable-time-picker="false"
+                                    :format="store.datePickerFormat"
+                                    locale="cn"
+                                  ></VueDatePicker>
+                                </v-col>
+
+                                <v-col cols="12" sm="6" class="date-item">
+                                  <p class="mb-0 pe-3">
+                                    報名時間<span class="mark pb-4">*</span>
+                                  </p>
+                                  <VueDatePicker
+                                    v-model="date.registration_start_time"
+                                    time-picker
+                                  />
+                                </v-col>
+
+                                <v-col cols="12" sm="6" class="date-item">
+                                  <p class="mb-0 pe-3">
+                                    報名截止<span class="mark pb-4">*</span>
+                                  </p>
+                                  <VueDatePicker
+                                    v-model="date.registration_end_date"
+                                    :min-date="new Date()"
+                                    :enable-time-picker="false"
+                                    :format="store.datePickerFormat"
+                                    locale="cn"
+                                  ></VueDatePicker>
+                                </v-col>
+
+                                <v-col cols="12" sm="6" class="date-item">
+                                  <p class="mb-0 pe-3">
+                                    截止時間<span class="mark pb-4">*</span>
+                                  </p>
+                                  <VueDatePicker
+                                    v-model="date.registration_end_time"
+                                    time-picker
+                                  />
+                                </v-col>
+                              </v-row>
+                            </v-container>
+                          </v-form>
+                        </v-card-text>
+
+                        <v-card-actions class="justify-center pt-10 pb-5">
+                          <v-btn
+                            color="gray"
+                            variant="tonal"
+                            class="me-3 px-10"
+                            @click="sessionsDialog = false"
+                          >
+                            取消
+                          </v-btn>
+                          <v-btn
+                            color="purple"
+                            variant="flat"
+                            @click="addEventData()"
+                            class="px-10"
+                          >
+                            新增
+                          </v-btn>
+                        </v-card-actions>
+                      </v-card>
+                    </v-dialog>
+
+                    <div v-if="eventData.list.length" class="main-table">
+                      <h6 class="table-title">場次資訊</h6>
+                      <table>
+                        <thead>
+                          <tr>
+                            <th>名稱</th>
+                            <th>日期</th>
+                            <th width="20%">課程講師</th>
+                            <th width="20%">收費方式</th>
+                          </tr>
+                        </thead>
+                        <tbody>
+                          <tr
+                            v-for="(item, index) in eventData.list"
+                            :key="index"
+                          >
+                            <td>{{ item.event }}</td>
+                            <td>
+                              {{
+                                moment(`${item.start_time}`).format(
+                                  "YYYY/MM/DD"
+                                )
+                              }}
+                              <br />
+                              ~
+                              <br />
+                              {{
+                                moment(`${item.end_time}`).format("YYYY/MM/DD")
+                              }}
+                            </td>
+                            <td>{{ item.lecturer }}</td>
+                            <td>{{ item.fee_method }}</td>
+                          </tr>
+                        </tbody>
+                      </table>
+                    </div>
+                  </v-label>
+                </v-col> -->
+
+                <!-- <v-col cols="12" md="11" class="px-md-7">
+                  <v-label class="d-block">
+                    <p class="d-flex">課程簡介<span class="mark">*</span></p>
+                    <small class="d-block text-gray my-2"
+                      >內容不得少於 100 字元,且不得含有工藝無關之資訊</small
+                    >
+                    <v-textarea
+                      v-model="course.introduction"
+                      rows="5"
+                      variant="outlined"
+                      :rules="[requiredRule]"
+                    ></v-textarea>
+                  </v-label>
+                </v-col> -->
+
+                <!-- <v-col cols="12" md="5" class="me-auto ms-3 ps-16">
+                  <v-label class="d-block">
+                    <p class="d-flex">
+                      上傳課程封面<span class="mark">*</span>
+                    </p>
+
+                    <v-file-input
+                      multiple
+                      v-model="coverImg"
+                      ref="coverImgRef"
+                      label="File input"
+                      variant="outlined"
+                      placeholder="選擇相片上傳"
+                      @change="handleCoverImg"
+                      style="display: none"
+                    ></v-file-input>
+                  </v-label>
+
+                  <v-btn
+                    @click="fileInputClick('cover')"
+                    color="purple"
+                    class="my-5"
+                    >選擇相片上傳</v-btn
+                  >
+
+                  <div class="step-01 image-preview">
+                    <img
+                      v-if="coverImg"
+                      :src="coverImgUrl"
+                      alt="上傳圖片預覽"
+                    />
+                  </div>
+                </v-col> -->
+              </v-row>
+            </v-form>
+          </v-card-text>
+        </v-window-item>
+
+        <v-window-item :value="4">
+          <v-card-text class="mb-7 finish-step">
+            <p>
+              請等待後台人員確認您的課程資訊 <br />
+              您可以前往
+              <router-link to="/user/courses">【我的開課】</router-link>
+              觀看及修改您的
+            </p>
+            <ul>
+              <li>(1) 據點資訊</li>
+              <li>(2) 工藝家履歷</li>
+              <li>(3) 課程清單</li>
+            </ul>
+          </v-card-text>
+        </v-window-item>
+      </v-window>
+
+      <v-divider></v-divider>
+
+      <v-card-actions
+        class="justify-center flex-column flex-sm-row mt-5 mt-sm-7"
+      >
+        <v-btn
+          v-if="step > 1 && step !== 4"
+          color="gray"
+          variant="outlined"
+          @click="step--"
+          class="px-7 me-2"
+        >
+          上一步
+        </v-btn>
+        <v-spacer></v-spacer>
+
+        <v-btn
+          v-if="step < 3"
+          color="purple"
+          variant="flat"
+          @click="checkField(step)"
+          class="px-7 ms-2"
+        >
+          下一步
+        </v-btn>
+        <!-- <div
+            v-if="errorField"
+            class="d-flex align-center text-error mt-3 position-absolute"
+            style="bottom: 15px"
+          >
+            <v-icon icon="mdi-alert"></v-icon>
+            <span class="ms-2"> 尚有欄位未填寫 </span>
+          </div> -->
+        <v-btn
+          v-if="step === 3"
+          color="purple"
+          variant="flat"
+          @click="create()"
+          :loading="loading"
+          class="px-7"
+        >
+          送出提案
+        </v-btn>
+        <div
+          v-if="errorField"
+          class="d-flex align-center text-error mt-3 position-absolute"
+          style="bottom: 15px"
+        >
+          <v-icon icon="mdi-alert"></v-icon>
+          <span class="ms-2"> 尚有欄位未填寫 </span>
+        </div>
+        <!-- <div
+          v-if="errorEventField"
+          class="d-flex align-center text-error mt-3 position-absolute"
+          style="bottom: 15px"
+        >
+          <v-icon icon="mdi-alert"></v-icon>
+          <span class="ms-2"> 尚未填寫課程時間 </span>
+        </div> -->
+        <v-btn
+          v-if="step === 4"
+          color="purple"
+          variant="outlined"
+          class="mb-5 mb-sm-0 me-sm-3"
+        >
+          <router-link to="/" class="px-7">回到首頁</router-link>
+        </v-btn>
+        <v-btn v-if="step === 4" color="purple" variant="flat">
+          <router-link to="/user/courses" class="px-7"
+            >前往開課專區</router-link
+          >
+        </v-btn>
+      </v-card-actions>
+    </v-card>
+  </v-container>
+</template>
+
+<style lang="scss">
+.proposal-container {
+  .step-title {
+    text-align: center;
+    h5 {
+      font-size: 1.75em;
+      font-weight: 500;
+      letter-spacing: 0.125em;
+      @media (max-width: 600px) {
+        font-size: 1em;
+      }
+    }
+    p {
+      font-size: 0.8em;
+      font-weight: 400;
+      letter-spacing: 0.0625em;
+      color: #919191;
+      white-space: normal;
+      @media (max-width: 600px) {
+        font-size: 0.7em;
+        line-height: 1.5em;
+      }
+    }
+  }
+
+  .step-01 {
+    &.image-preview {
+      height: 17.8125em;
+    }
+  }
+
+  .step-02 {
+    &.image-preview {
+      height: 14.6875em;
+    }
+  }
+
+  .image-preview {
+    img {
+      height: 100%;
+      object-fit: contain;
+    }
+  }
+
+  .flex-grow-1 {
+    display: none !important;
+  }
+
+  .img-list {
+    .item {
+      height: 10em;
+      border-radius: 0.3125em;
+      background-color: #ccc; // 預設灰底
+      background-repeat: no-repeat;
+      background-position: center;
+      background-size: cover;
+
+      @media (max-width: 960px) {
+        height: 20vw;
+      }
+    }
+  }
+
+  .sessions-card {
+    border-radius: 1.875em 0.3125em 0.3125em 1.875em !important;
+
+    .v-label {
+      p {
+        width: 5.9375em;
+        text-align: end;
+        line-height: 1.375em;
+        @media (max-width: 600px) {
+          width: 7.6875em;
+        }
+      }
+    }
+  }
+
+  .date-item {
+    display: flex;
+    margin-bottom: 0.625em;
+    p {
+      width: 7.125em;
+      display: flex;
+      align-items: center;
+      justify-content: end;
+      white-space: nowrap;
+      line-height: 1.375em;
+      @media (max-width: 600px) {
+        width: 7.8125em;
+      }
+    }
+  }
+
+  .main-table {
+    width: 1000px;
+    margin: 3.125em 0;
+
+    .table-title {
+      font-size: 1.3em;
+      background-color: var(--purple);
+    }
+
+    table {
+      font-size: 1em;
+      thead {
+        border-bottom: 0.125em solid var(--purple);
+      }
+      tbody {
+        td {
+          border-bottom: 0.0625em solid var(--purple);
+        }
+      }
+    }
+  }
+
+  .finish-step {
+    line-height: 3.125em !important;
+    font-size: 1.375em;
+    text-align: center;
+    letter-spacing: 0.0625em;
+
+    @media (max-width: 600px) {
+      padding: 0;
+      line-height: 2em;
+      font-size: 1em;
+    }
+  }
+
+  .type-hint {
+    width: 100%;
+    display: block;
+    position: absolute;
+    bottom: 0.0625em;
+    left: 6.5625em;
+    color: var(--gray);
+  }
+
+  .week-list {
+    height: 70%;
+    align-items: center;
+    li {
+      margin: 0.9375em 0;
+      .item {
+        color: var(--purple);
+        padding: 0.625em;
+        border-radius: 6.25em;
+        border: 0.0625em solid var(--purple);
+        transition: all 0.3s;
+        &:hover {
+          color: #fff;
+          background-color: var(--purple);
+        }
+      }
+      &.active {
+        .item {
+          color: #fff;
+          background-color: var(--purple);
+        }
+      }
+    }
+  }
+
+  .time-item {
+    display: flex;
+    align-items: center;
+    p {
+      width: 6.0625em;
+      flex-wrap: nowrap;
+      display: flex;
+      white-space: nowrap;
+    }
+  }
+
+  .school-list {
+    width: 21.875em;
+    margin: auto;
+
+    @media (max-width: 600px) {
+      width: 100%;
+    }
+  }
+
+  .notes-block {
+    padding: 30px;
+    font-size: 1.15em;
+    color: #9b9b9b;
+    background-color: #f9f9f9;
+    border-radius: 5px;
+    p,
+    li {
+      letter-spacing: 0.05em;
+    }
+    li {
+      margin-bottom: 10px;
+      line-height: 1.8em;
+      &:last-child {
+        margin-bottom: 0;
+      }
+    }
+  }
+
+  .upload-input {
+    .v-label {
+      opacity: 0.5 !important;
+    }
+  }
+
+  .assign-list {
+    padding: 20px;
+    border-radius: 5px;
+    border: 1px solid #ccc;
+    li {
+      padding: 10px 0;
+      border-top: 1px solid #ddd;
+      &:first-child {
+        border: none;
+      }
+    }
+  }
+
+  .v-card .v-card-title {
+    @media (max-width: 600px) {
+      white-space: normal;
+      line-height: 2em;
+    }
+  }
+
+  .resume-btn {
+    width: 120px;
+    height: 120px;
+    border-radius: 100px;
+    background-color: #f6f6f6;
+  }
+}
+</style>

+ 106 - 16
src/views/Courses/SetUp.vue

@@ -1,5 +1,5 @@
 <script setup>
 <script setup>
-import { ref, reactive, watch } from "vue";
+import { ref, reactive, watch, onMounted } from "vue";
 import { useMainStore } from "@/stores/store";
 import { useMainStore } from "@/stores/store";
 import axios from "axios";
 import axios from "axios";
 import Navbar from "@/components/Navbar.vue";
 import Navbar from "@/components/Navbar.vue";
@@ -13,37 +13,127 @@ const store = useMainStore();
 let isLogin = store.checkToken();
 let isLogin = store.checkToken();
 console.log("isLogin", isLogin);
 console.log("isLogin", isLogin);
 
 
+let userInfo = ref([]);
+let isLoading = ref(true);
+let isCrafts = ref(false); // 身份是否為工藝家
+
+onMounted(async () => {
+  let response = await store.getUserInfo();
+  console.log(response);
+  console.log("response.data.msg", response.data.msg);
+  if (response.data.msg !== "no access") {
+    userInfo.value = response.data.user_inform[0];
+
+    let position = userInfo.value.position;
+    console.log("position", position);
+    if (position) {
+      if (position["開課工藝家"]) {
+        isCrafts.value = true;
+        isLoading.value = false;
+        console.log("isCrafts.value", isCrafts.value);
+      }
+    } else {
+      isCrafts.value = false;
+      isLoading.value = false;
+    }
+  } else {
+    console.log("尚未登入");
+    store.openLoginDialog();
+  }
+  // userInfo.value = response.data.user_inform[0];
+
+  console.log("userInfo.value", userInfo.value);
+});
+
 const modules = [Pagination];
 const modules = [Pagination];
 </script>
 </script>
 
 
 <template>
 <template>
   <Navbar />
   <Navbar />
 
 
-  <v-container class="my-16 py-16">
-    <v-row>
+  <div v-if="isLoading" class="d-flex justify-center py-16">
+    <v-progress-circular
+      color="grey-lighten-4"
+      indeterminate
+    ></v-progress-circular>
+  </div>
+
+  <v-container v-else class="my-16 py-16">
+    <v-row v-if="isCrafts">
       <v-col cols="12" md="6">
       <v-col cols="12" md="6">
         <div class="options">
         <div class="options">
-          <img src="@/assets/img/setup-courses/素材-01.png" alt="" />
+          <img
+            src="@/assets/img/setup-courses/素材-01.png"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
           <router-link to="/setup-courses/tutorial">觀看開課教學</router-link>
           <router-link to="/setup-courses/tutorial">觀看開課教學</router-link>
         </div>
         </div>
       </v-col>
       </v-col>
       <v-col cols="12" md="6" class="mt-16 mt-md-0">
       <v-col cols="12" md="6" class="mt-16 mt-md-0">
         <div v-if="!isLogin" class="options">
         <div v-if="!isLogin" class="options">
-          <img src="@/assets/img/setup-courses/素材-02.png" alt="" />
+          <img
+            src="@/assets/img/setup-courses/素材-02.png"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
           <button @click="store.openLoginDialog()">登入會員開課</button>
           <button @click="store.openLoginDialog()">登入會員開課</button>
         </div>
         </div>
         <div v-else class="options">
         <div v-else class="options">
-          <img src="@/assets/img/setup-courses/素材-03.png" alt="" />
+          <img
+            src="@/assets/img/setup-courses/素材-03.png"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
           <router-link to="/setup-courses/create">開始創建課程</router-link>
           <router-link to="/setup-courses/create">開始創建課程</router-link>
         </div>
         </div>
       </v-col>
       </v-col>
     </v-row>
     </v-row>
+
+    <v-row v-else>
+      <v-col cols="12" class="px-0">
+        <v-card class="text-center px-0 py-8 crafts-card">
+          <v-card-item>
+            <v-card-title>歡迎加入工藝家的行列</v-card-title>
+
+            <v-card-subtitle class="my-5"
+              >讓我們一步一步完成提案吧!</v-card-subtitle
+            >
+          </v-card-item>
+
+          <v-card-text>
+            <v-btn
+              :loading="isLoading"
+              variant="flat"
+              color="purple"
+              class="px-8"
+              size="large"
+            >
+              <router-link to="/setup-courses/proposal">開始提案</router-link>
+            </v-btn>
+          </v-card-text>
+        </v-card>
+
+        <!-- <v-card
+          class="text-center crafts-card"
+          title="歡迎加入工藝家的行列"
+          subtitle="讓我們一步一步完成提案吧!"
+          text="..."
+        ></v-card> -->
+        <!-- <h3>歡迎加入工藝家的行列</h3> -->
+      </v-col>
+    </v-row>
   </v-container>
   </v-container>
 </template>
 </template>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
+.crafts-card {
+  .v-card-title {
+    font-size: 1.8em;
+  }
+  .v-card-subtitle {
+    font-size: 1em;
+  }
+}
 .swiper-slide {
 .swiper-slide {
-  height: 500px !important;
+  height: 31.25em !important;
 }
 }
 .options {
 .options {
   display: flex;
   display: flex;
@@ -52,24 +142,24 @@ const modules = [Pagination];
   a,
   a,
   button {
   button {
     display: block;
     display: block;
-    padding: 20px 80px;
-    font-size: 20px;
-    letter-spacing: 2px;
-    border: 2px solid var(--purple);
-    border-radius: 15px;
+    padding: 1.25em 5em;
+    font-size: 1.25em;
+    letter-spacing: 0.125em;
+    border: 0.125em solid var(--purple);
+    border-radius: 0.9375em;
     transition: all 0.3s;
     transition: all 0.3s;
 
 
     &:hover {
     &:hover {
-      box-shadow: 0 0 8px var(--purple);
+      box-shadow: 0 0 0.5em var(--purple);
     }
     }
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      font-size: 18px;
+      font-size: 1.125em;
     }
     }
   }
   }
   img {
   img {
     width: 100%;
     width: 100%;
-    max-width: 500px;
+    max-width: 31.25em;
   }
   }
 }
 }
 
 
@@ -90,7 +180,7 @@ const modules = [Pagination];
 
 
 .swiper-slide {
 .swiper-slide {
   text-align: center;
   text-align: center;
-  font-size: 18px;
+  font-size: 1em;
 
 
   /* Center slide text vertically */
   /* Center slide text vertically */
   display: flex;
   display: flex;

+ 2 - 2
src/views/Courses/Tutorial.vue

@@ -33,9 +33,9 @@ const breadcrumbs = reactive([
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .breadcrumbs-item {
 .breadcrumbs-item {
-  padding: 30px 0 30px 16vw;
+  padding: 1.875em 0 1.875em 16vw;
   @media (max-width: 1800px) {
   @media (max-width: 1800px) {
-    padding: 30px 0 30px 5vw;
+    padding: 1.875em 0 1.875em 5vw;
   }
   }
 }
 }
 </style>
 </style>

+ 80 - 77
src/views/Crafts.vue

@@ -224,7 +224,7 @@ function handlePdfUrl(pdf) {
           class="my-5"
           class="my-5"
         ></v-breadcrumbs>
         ></v-breadcrumbs>
 
 
-        <v-row class="px-10 pb-3 tag-btn">
+        <v-row class="px-sm-10 pb-3 tag-btn">
           <v-col
           <v-col
             v-for="(item, index) in tagList"
             v-for="(item, index) in tagList"
             :key="index"
             :key="index"
@@ -234,7 +234,7 @@ function handlePdfUrl(pdf) {
             <a
             <a
               v-if="isAnchorLink(item.url)"
               v-if="isAnchorLink(item.url)"
               :href="item.url"
               :href="item.url"
-              class="py-3 py-lg-6 item"
+              class="py-3 py-sm-6 item"
             >
             >
               <!-- 錨點 -->
               <!-- 錨點 -->
               <h3>{{ item.title }}</h3>
               <h3>{{ item.title }}</h3>
@@ -257,7 +257,7 @@ function handlePdfUrl(pdf) {
               placeholder="關鍵字搜尋"
               placeholder="關鍵字搜尋"
             />
             />
             <button @click="search()">
             <button @click="search()">
-              <img src="@/assets/img/news/news-search-icon.png" alt="" />
+              <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
             </button>
             </button>
           </span>
           </span>
           <div
           <div
@@ -291,6 +291,7 @@ function handlePdfUrl(pdf) {
                 class="mx-auto cover-img"
                 class="mx-auto cover-img"
                 :lazy-src="`https://ntcri.org/${item.cover_img}`"
                 :lazy-src="`https://ntcri.org/${item.cover_img}`"
                 :src="`https://ntcri.org/${item.cover_img}`"
                 :src="`https://ntcri.org/${item.cover_img}`"
+                alt="臺灣工藝學校全球學習共享平台"
               >
               >
                 <template v-slot:placeholder>
                 <template v-slot:placeholder>
                   <div class="d-flex align-center justify-center fill-height">
                   <div class="d-flex align-center justify-center fill-height">
@@ -301,13 +302,13 @@ function handlePdfUrl(pdf) {
                   </div>
                   </div>
                 </template>
                 </template>
               </v-img>
               </v-img>
-              <!-- <img :src="item.img" alt="" /> -->
+              <!-- <img :src="item.img" alt="臺灣工藝學校全球學習共享平台" /> -->
             </a>
             </a>
 
 
             <!-- <img
             <!-- <img
               v-else
               v-else
               :src="item.img"
               :src="item.img"
-              alt=""
+              alt="臺灣工藝學校全球學習共享平台"
               @click="updatePDF(item.fileName)"
               @click="updatePDF(item.fileName)"
             /> -->
             /> -->
 
 
@@ -317,6 +318,7 @@ function handlePdfUrl(pdf) {
               :lazy-src="`https://ntcri.org/${item.cover_img}`"
               :lazy-src="`https://ntcri.org/${item.cover_img}`"
               :src="`https://ntcri.org/${item.cover_img}`"
               :src="`https://ntcri.org/${item.cover_img}`"
               @click="updatePDF(item.files)"
               @click="updatePDF(item.files)"
+              alt="臺灣工藝學校全球學習共享平台"
             >
             >
               <template v-slot:placeholder>
               <template v-slot:placeholder>
                 <div class="d-flex align-center justify-center fill-height">
                 <div class="d-flex align-center justify-center fill-height">
@@ -329,7 +331,7 @@ function handlePdfUrl(pdf) {
             </v-img>
             </v-img>
 
 
             <!-- <a :href="item.url" target="_blank">
             <!-- <a :href="item.url" target="_blank">
-              <img :src="item.img" alt="" />
+              <img :src="item.img" alt="臺灣工藝學校全球學習共享平台" />
             </a> -->
             </a> -->
             <section>
             <section>
               <h3 v-html="item.title"></h3>
               <h3 v-html="item.title"></h3>
@@ -353,7 +355,7 @@ function handlePdfUrl(pdf) {
               placeholder="關鍵字搜尋"
               placeholder="關鍵字搜尋"
             />
             />
             <button @click="search()">
             <button @click="search()">
-              <img src="@/assets/img/news/news-search-icon.png" alt="" />
+              <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
             </button>
             </button>
           </span>
           </span>
           <div
           <div
@@ -383,6 +385,7 @@ function handlePdfUrl(pdf) {
                   :lazy-src="`https://ntcri.org/${item.cover_img}`"
                   :lazy-src="`https://ntcri.org/${item.cover_img}`"
                   cover
                   cover
                   :src="`https://ntcri.org/${item.cover_img}`"
                   :src="`https://ntcri.org/${item.cover_img}`"
+                  alt="臺灣工藝學校全球學習共享平台"
                 >
                 >
                   <template v-slot:placeholder>
                   <template v-slot:placeholder>
                     <div class="d-flex align-center justify-center fill-height">
                     <div class="d-flex align-center justify-center fill-height">
@@ -397,7 +400,7 @@ function handlePdfUrl(pdf) {
             </a>
             </a>
 
 
             <!-- <a :href="item.url" target="_blank">
             <!-- <a :href="item.url" target="_blank">
-              <img :src="item.img" alt="" />
+              <img :src="item.img" alt="臺灣工藝學校全球學習共享平台" />
             </a> -->
             </a> -->
             <section class="info">
             <section class="info">
               <p v-html="filteredContent(item.content)"></p>
               <p v-html="filteredContent(item.content)"></p>
@@ -492,12 +495,12 @@ function handlePdfUrl(pdf) {
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .article-content {
 .article-content {
-  margin-bottom: 150px;
+  margin-bottom: 9.375em;
 }
 }
 
 
 h2 {
 h2 {
-  padding-top: 100px;
-  font-size: 30px;
+  padding-top: 6.25em;
+  font-size: 1.875em;
   font-weight: 500;
   font-weight: 500;
   text-align: center;
   text-align: center;
 }
 }
@@ -515,13 +518,13 @@ h2 {
 .read-list,
 .read-list,
 .book-list {
 .book-list {
   p {
   p {
-    margin-bottom: 10px;
+    margin-bottom: 0.625em;
   }
   }
   h3,
   h3,
   p {
   p {
     font-weight: 500;
     font-weight: 500;
     text-align: center;
     text-align: center;
-    line-height: 30px;
+    line-height: 1.875em;
   }
   }
 }
 }
 
 
@@ -529,7 +532,7 @@ h2 {
   .v-img {
   .v-img {
     width: 100%;
     width: 100%;
     // height: 100%;
     // height: 100%;
-    max-height: 400px;
+    max-height: 25em;
     object-fit: cover;
     object-fit: cover;
     cursor: pointer;
     cursor: pointer;
 
 
@@ -541,13 +544,13 @@ h2 {
   @media (max-width: 600px) {
   @media (max-width: 600px) {
     section {
     section {
       width: 50%;
       width: 50%;
-      padding: 0 10px;
-      font-size: 14px;
+      padding: 0 0.625em;
+      font-size: 0.875em;
     }
     }
   }
   }
 
 
   p {
   p {
-    width: 290px;
+    width: 18.125em;
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
       width: auto;
       width: auto;
@@ -556,29 +559,29 @@ h2 {
 }
 }
 
 
 .book-list {
 .book-list {
-  margin-bottom: 100px;
+  margin-bottom: 6.25em;
   .info {
   .info {
-    width: 430px;
-    padding: 10px 20px;
+    width: 26.875em;
+    padding: 0.625em 1.25em;
     position: absolute;
     position: absolute;
-    right: -40px;
-    bottom: -60px;
+    right: -2.5em;
+    bottom: -3.75em;
     z-index: 1;
     z-index: 1;
     background: rgba(255, 255, 255, 0.8);
     background: rgba(255, 255, 255, 0.8);
-    border: 2px solid #c8cbcc;
+    border: 0.125em solid #c8cbcc;
 
 
     @media (max-width: 1280px) {
     @media (max-width: 1280px) {
-      width: 400px;
+      width: 25em;
     }
     }
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      width: 330px;
-      right: -3px;
-      bottom: -80px;
+      width: 20.625em;
+      right: -0.1875em;
+      bottom: -5em;
     }
     }
 
 
     p {
     p {
-      width: 300px;
+      width: 18.75em;
       margin-bottom: 0;
       margin-bottom: 0;
       text-align: start;
       text-align: start;
     }
     }
@@ -586,99 +589,99 @@ h2 {
       display: block;
       display: block;
       margin-top: auto;
       margin-top: auto;
       position: absolute;
       position: absolute;
-      bottom: 15px;
-      right: 15px;
+      bottom: 0.9375em;
+      right: 0.9375em;
     }
     }
   }
   }
 }
 }
 
 
 .pdf-list {
 .pdf-list {
   display: flex;
   display: flex;
-  margin: 100px 0;
+  margin: 6.25em 0;
   .side-title {
   .side-title {
-    padding: 70px 0 70px 10px;
+    padding: 4.375em 0 4.375em 0.625em;
     display: flex;
     display: flex;
     flex-direction: column;
     flex-direction: column;
     justify-content: space-between;
     justify-content: space-between;
-    border-radius: 5px;
+    border-radius: 0.3125em;
     background-color: var(--purple);
     background-color: var(--purple);
     h5 {
     h5 {
-      padding: 20px 10px;
+      padding: 1.25em 0.625em;
       position: relative;
       position: relative;
-      font-size: 26px;
+      font-size: 1.625em;
       font-weight: 400;
       font-weight: 400;
       writing-mode: vertical-rl; // 垂直
       writing-mode: vertical-rl; // 垂直
       color: var(--purple);
       color: var(--purple);
-      letter-spacing: 2px;
+      letter-spacing: 0.125em;
       background-color: #fff;
       background-color: #fff;
 
 
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 20px;
+        font-size: 1.25em;
       }
       }
 
 
       &::after,
       &::after,
       &::before {
       &::before {
         content: "";
         content: "";
         display: block;
         display: block;
-        height: 15px;
+        height: 0.9375em;
         width: 105%;
         width: 105%;
         background: #fff;
         background: #fff;
         position: absolute;
         position: absolute;
       }
       }
 
 
       &::after {
       &::after {
-        top: -7px;
-        right: -4px;
+        top: -0.4375em;
+        right: -0.25em;
         transform: rotate(-15deg);
         transform: rotate(-15deg);
 
 
         @media (max-width: 1200px) {
         @media (max-width: 1200px) {
-          top: -8px;
-          right: -3px;
+          top: -0.5em;
+          right: -0.1875em;
         }
         }
       }
       }
       &::before {
       &::before {
-        bottom: -7px;
-        right: -4px;
+        bottom: -0.4375em;
+        right: -0.25em;
         transform: rotate(15deg);
         transform: rotate(15deg);
 
 
         @media (max-width: 1200px) {
         @media (max-width: 1200px) {
-          bottom: -8px;
-          right: -3px;
+          bottom: -0.5em;
+          right: -0.1875em;
         }
         }
       }
       }
     }
     }
   }
   }
   ul {
   ul {
     background-color: #fff;
     background-color: #fff;
-    padding: 50px 50px 0 50px;
+    padding: 3.125em 3.125em 0 3.125em;
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      padding: 25px 25px 0 25px;
+      padding: 1.5625em 1.5625em 0 1.5625em;
     }
     }
 
 
     li {
     li {
-      margin-bottom: 25px;
-      padding-bottom: 25px;
-      border-bottom: 1px dashed #ccc;
+      margin-bottom: 1.5625em;
+      padding-bottom: 1.5625em;
+      border-bottom: 0.0625em dashed #ccc;
 
 
       &:last-child {
       &:last-child {
         margin-bottom: 0;
         margin-bottom: 0;
         // padding-bottom: 0;
         // padding-bottom: 0;
       }
       }
       h3 {
       h3 {
-        font-size: 22px;
-        line-height: 30px;
+        font-size: 1.375em;
+        line-height: 1.875em;
         @media (max-width: 600px) {
         @media (max-width: 600px) {
-          font-size: 18px;
+          font-size: 1.125em;
         }
         }
       }
       }
       h4 {
       h4 {
-        margin: 15px 0;
-        font-size: 18px;
-        line-height: 26px;
+        margin: 0.9375em 0;
+        font-size: 1.125em;
+        line-height: 1.625em;
         color: var(--gray);
         color: var(--gray);
         @media (max-width: 600px) {
         @media (max-width: 600px) {
-          font-size: 16px;
+          font-size: 1em;
         }
         }
       }
       }
       h3,
       h3,
@@ -688,19 +691,19 @@ h2 {
       h3,
       h3,
       h4,
       h4,
       p {
       p {
-        letter-spacing: 1px;
+        letter-spacing: 0.0625em;
       }
       }
       p {
       p {
-        font-size: 14px;
+        font-size: 0.875em;
         color: var(--gray);
         color: var(--gray);
       }
       }
       a {
       a {
         display: inline-block;
         display: inline-block;
-        padding: 5px 10px;
-        margin-top: 20px;
-        font-size: 14px;
-        border-radius: 5px;
-        border: 2px solid var(--gray);
+        padding: 0.3125em 0.625em;
+        margin-top: 1.25em;
+        font-size: 0.875em;
+        border-radius: 0.3125em;
+        border: 0.125em solid var(--gray);
         transition: all 0.3s;
         transition: all 0.3s;
 
 
         &:hover {
         &:hover {
@@ -717,17 +720,17 @@ h2 {
 }
 }
 
 
 .journal-content {
 .journal-content {
-  margin-top: 80px;
+  margin-top: 5em;
   p {
   p {
-    line-height: 28px;
+    line-height: 1.75em;
   }
   }
   .list {
   .list {
-    letter-spacing: 1px;
+    letter-spacing: 0.0625em;
     .title {
     .title {
-      margin-top: 100px;
-      padding-bottom: 20px;
-      font-size: 20px;
-      border-bottom: 2px solid var(--purple);
+      margin-top: 6.25em;
+      padding-bottom: 1.25em;
+      font-size: 1.25em;
+      border-bottom: 0.125em solid var(--purple);
     }
     }
 
 
     .title,
     .title,
@@ -737,13 +740,13 @@ h2 {
     }
     }
 
 
     ul {
     ul {
-      margin-top: 20px;
+      margin-top: 1.25em;
       li {
       li {
-        margin-top: 10px;
-        padding-bottom: 10px;
-        border-bottom: 2px dashed #dddddd;
+        margin-top: 0.625em;
+        padding-bottom: 0.625em;
+        border-bottom: 0.125em dashed #dddddd;
         // &:first-child {
         // &:first-child {
-        //   border-bottom: 2px dashed #ccc;
+        //   border-bottom: 0.125em dashed #ccc;
         // }
         // }
         p {
         p {
           font-weight: 400;
           font-weight: 400;

File diff suppressed because it is too large
+ 511 - 142
src/views/Home.vue


+ 13 - 13
src/views/Login.vue

@@ -216,7 +216,7 @@ function toggleLoginInput() {
   <!-- <v-container class="pa-0">
   <!-- <v-container class="pa-0">
     <v-row>
     <v-row>
       <v-col cols="6">
       <v-col cols="6">
-        <img src="@/assets/img/img-08.jpg" alt="">
+        <img src="@/assets/img/img-08.jpg" alt="臺灣工藝學校全球學習共享平台">
       </v-col>
       </v-col>
       <v-col cols="6"></v-col>
       <v-col cols="6"></v-col>
     </v-row>
     </v-row>
@@ -369,30 +369,30 @@ function toggleLoginInput() {
 
 
 <style lang="scss">
 <style lang="scss">
 .login-btn {
 .login-btn {
-  width: 190px;
-  margin-top: 20px;
+  width: 11.875em;
+  margin-top: 1.25em;
 }
 }
 .login-card {
 .login-card {
   .v-tab {
   .v-tab {
-    padding-bottom: 20px;
-    font-size: 28px;
+    padding-bottom: 1.25em;
+    font-size: 1.75em;
   }
   }
   .v-form {
   .v-form {
     width: 100%;
     width: 100%;
   }
   }
   .tab {
   .tab {
     button {
     button {
-      margin: 0 20px;
-      padding-bottom: 20px;
-      font-size: 28px;
+      margin: 0 1.25em;
+      padding-bottom: 1.25em;
+      font-size: 1.75em;
       font-weight: 500;
       font-weight: 500;
       text-align: center;
       text-align: center;
       color: #d9d9d9;
       color: #d9d9d9;
-      border-bottom: 3px solid transparent;
+      border-bottom: 0.1875em solid transparent;
       transition: all 0.3s;
       transition: all 0.3s;
       &.active {
       &.active {
         color: var(--main-color);
         color: var(--main-color);
-        border-bottom: 3px solid var(--main-color);
+        border-bottom: 0.1875em solid var(--main-color);
       }
       }
     }
     }
   }
   }
@@ -401,12 +401,12 @@ function toggleLoginInput() {
     color: #595959;
     color: #595959;
   }
   }
   .google-btn {
   .google-btn {
-    width: 130px;
+    width: 8.125em;
     margin: auto;
     margin: auto;
   }
   }
   .v-text-field .v-input__details {
   .v-text-field .v-input__details {
     position: relative;
     position: relative;
-    top: -4px;
+    top: -0.25em;
   }
   }
   .forget {
   .forget {
     a,
     a,
@@ -428,7 +428,7 @@ function toggleLoginInput() {
     .v-alert {
     .v-alert {
       color: var(--main-color);
       color: var(--main-color);
       background-color: #fff;
       background-color: #fff;
-      letter-spacing: 1px;
+      letter-spacing: 0.0625em;
     }
     }
   }
   }
 }
 }

+ 28 - 28
src/views/News.vue

@@ -115,13 +115,13 @@ const categoryList = reactive([
 <template>
 <template>
   <Navbar />
   <Navbar />
   <div class="position-relative">
   <div class="position-relative">
-    <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
+    <img src="@/assets/img/news/news-01.png" alt="臺灣工藝學校全球學習共享平台" class="material-img" />
     <v-container>
     <v-container>
-      <img src="@/assets/img/news/news-banner.png" alt="" />
+      <img src="@/assets/img/news/news-banner.png" alt="臺灣工藝學校全球學習共享平台" />
 
 
       <div class="content py-10 mt-16">
       <div class="content py-10 mt-16">
         <div class="bg-img">
         <div class="bg-img">
-          <img src="@/assets/img/news/news-02.png" alt="" />
+          <img src="@/assets/img/news/news-02.png" alt="臺灣工藝學校全球學習共享平台" />
         </div>
         </div>
 
 
         <v-breadcrumbs
         <v-breadcrumbs
@@ -152,7 +152,7 @@ const categoryList = reactive([
               placeholder="關鍵字搜尋"
               placeholder="關鍵字搜尋"
             />
             />
             <button @click="search()">
             <button @click="search()">
-              <img src="@/assets/img/news/news-search-icon.png" alt="" />
+              <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
             </button>
             </button>
           </span>
           </span>
           <div
           <div
@@ -192,7 +192,7 @@ const categoryList = reactive([
               <v-row class="align-center">
               <v-row class="align-center">
                 <v-col cols="12" sm="4">
                 <v-col cols="12" sm="4">
                   <router-link :to="`/news/${item.news_id}`" class="cover-img">
                   <router-link :to="`/news/${item.news_id}`" class="cover-img">
-                    <img src="@/assets/img/img-04.jpg" alt="" />
+                    <img src="@/assets/img/img-04.jpg" alt="臺灣工藝學校全球學習共享平台" />
                   </router-link>
                   </router-link>
                 </v-col>
                 </v-col>
                 <v-col cols="12">
                 <v-col cols="12">
@@ -219,7 +219,7 @@ const categoryList = reactive([
         </div>
         </div>
       </div>
       </div>
     </v-container>
     </v-container>
-    <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
+    <img src="@/assets/img/news/news-01.png" alt="臺灣工藝學校全球學習共享平台" class="material-img" />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -237,7 +237,7 @@ const categoryList = reactive([
     transform: scaleX(-1);
     transform: scaleX(-1);
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      bottom: 10px;
+      bottom: 0.625em;
     }
     }
   }
   }
 }
 }
@@ -248,16 +248,16 @@ const categoryList = reactive([
   justify-content: center;
   justify-content: center;
 
 
   .v-btn {
   .v-btn {
-    width: 130px;
+    width: 8.125em;
   }
   }
 }
 }
 
 
 .content {
 .content {
   position: relative;
   position: relative;
-  margin-bottom: 200px;
+  margin-bottom: 12.5em;
 
 
   @media (max-width: 960px) {
   @media (max-width: 960px) {
-    margin-bottom: 100px;
+    margin-bottom: 6.25em;
   }
   }
 
 
   .bg-img {
   .bg-img {
@@ -268,10 +268,10 @@ const categoryList = reactive([
     top: 0;
     top: 0;
     right: 0;
     right: 0;
     left: 0;
     left: 0;
-    bottom: -110px;
+    bottom: -6.875em;
 
 
     @media (max-width: 960px) {
     @media (max-width: 960px) {
-      bottom: -30px;
+      bottom: -1.875em;
     }
     }
 
 
     img {
     img {
@@ -280,27 +280,27 @@ const categoryList = reactive([
   }
   }
 
 
   ul {
   ul {
-    padding: 0 80px;
+    padding: 0 5em;
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      padding: 0 20px;
+      padding: 0 1.25em;
     }
     }
 
 
     li {
     li {
-      letter-spacing: 1px;
+      letter-spacing: 0.0625em;
 
 
       .v-card {
       .v-card {
         background-color: #fff;
         background-color: #fff;
 
 
         section {
         section {
           h2 {
           h2 {
-            margin-bottom: 20px;
-            font-size: 26px;
+            margin-bottom: 1.25em;
+            font-size: 1.625em;
             font-weight: 500;
             font-weight: 500;
-            line-height: 36px;
+            line-height: 2.25em;
             @media (max-width: 600px) {
             @media (max-width: 600px) {
-              font-size: 22px;
-              line-height: 30px;
+              font-size: 1.375em;
+              line-height: 1.875em;
             }
             }
           }
           }
 
 
@@ -312,7 +312,7 @@ const categoryList = reactive([
             -webkit-line-clamp: 3;
             -webkit-line-clamp: 3;
             -webkit-box-orient: vertical;
             -webkit-box-orient: vertical;
             line-break: after-white-space;
             line-break: after-white-space;
-            line-height: 22px;
+            line-height: 1.375em;
           }
           }
         }
         }
 
 
@@ -321,7 +321,7 @@ const categoryList = reactive([
           overflow: hidden;
           overflow: hidden;
           img {
           img {
             width: 100%;
             width: 100%;
-            height: 200px;
+            height: 12.5em;
             object-fit: cover;
             object-fit: cover;
             transition: all 0.5s;
             transition: all 0.5s;
             &:hover {
             &:hover {
@@ -330,7 +330,7 @@ const categoryList = reactive([
 
 
             @media (max-width: 960px) {
             @media (max-width: 960px) {
               width: 100%;
               width: 100%;
-              height: 300px;
+              height: 18.75em;
             }
             }
 
 
             @media (max-width: 600px) {
             @media (max-width: 600px) {
@@ -347,10 +347,10 @@ const categoryList = reactive([
 
 
         span {
         span {
           display: block;
           display: block;
-          width: 8px;
-          height: 8px;
-          margin-right: 10px;
-          border-radius: 10px;
+          width: 0.5em;
+          height: 0.5em;
+          margin-right: 0.625em;
+          border-radius: 0.625em;
           background-color: #000;
           background-color: #000;
         }
         }
       }
       }
@@ -359,7 +359,7 @@ const categoryList = reactive([
 
 
   .pagination-item {
   .pagination-item {
     margin: auto;
     margin: auto;
-    max-width: 500px;
+    max-width: 31.25em;
   }
   }
 }
 }
 </style>
 </style>

+ 23 - 24
src/views/NewsDetail.vue

@@ -30,7 +30,7 @@ let loading = ref(false);
 <template>
 <template>
   <Navbar />
   <Navbar />
   <div class="position-relative">
   <div class="position-relative">
-    <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
+    <img src="@/assets/img/news/news-01.png" alt="臺灣工藝學校全球學習共享平台" class="material-img" />
     <v-container class="pa-0 py-16 position-relative">
     <v-container class="pa-0 py-16 position-relative">
       <div class="content">
       <div class="content">
         <div v-if="loading" class="d-flex justify-center my-10">
         <div v-if="loading" class="d-flex justify-center my-10">
@@ -52,8 +52,8 @@ let loading = ref(false);
                 </p>
                 </p>
               </div>
               </div>
               <h2>{{ news.data.title }}</h2>
               <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="" /> -->
+              <!-- <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>
             <v-col cols="12" class="mt-10">
             <v-col cols="12" class="mt-10">
               <section
               <section
@@ -77,7 +77,7 @@ let loading = ref(false);
         >< 返回重要訊息</router-link
         >< 返回重要訊息</router-link
       >
       >
     </v-container>
     </v-container>
-    <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
+    <img src="@/assets/img/news/news-01.png" alt="臺灣工藝學校全球學習共享平台" class="material-img" />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -88,11 +88,11 @@ let loading = ref(false);
 }
 }
 
 
 .content {
 .content {
-  padding: 20px;
+  padding: 1.25em;
   background-image: url("@/assets/img/news/news-02.png");
   background-image: url("@/assets/img/news/news-02.png");
   background-position: center;
   background-position: center;
   background-size: cover;
   background-size: cover;
-  border-radius: 50px;
+  border-radius: 3.125em;
   @media (max-width: 960px) {
   @media (max-width: 960px) {
     width: 90%;
     width: 90%;
     margin: auto;
     margin: auto;
@@ -100,41 +100,40 @@ let loading = ref(false);
 }
 }
 .article {
 .article {
   margin: auto;
   margin: auto;
-  padding: 80px 50px;
+  padding: 5em 3.125em;
   display: flex;
   display: flex;
   justify-content: center;
   justify-content: center;
-  border: 1px solid #d4d6d8;
-  border-radius: 50px;
+  border: 0.0625em solid #d4d6d8;
+  border-radius: 3.125em;
 
 
   @media (max-width: 600px) {
   @media (max-width: 600px) {
-    padding-top: 50px;
+    padding-top: 3.125em;
     border: none;
     border: none;
   }
   }
 
 
   h2 {
   h2 {
-    margin: 40px auto;
-    font-size: 28px;
+    font-size: 1.75em;
     font-weight: 500;
     font-weight: 500;
-    line-height: 40px;
-    letter-spacing: 2px;
+    line-height: 2.5em;
+    letter-spacing: 0.125em;
   }
   }
   section {
   section {
     height: 100%;
     height: 100%;
-    padding: 30px;
+    padding: 1.875em;
   }
   }
 
 
   p,
   p,
   section {
   section {
-    font-size: 18px;
+    font-size: 1.125em;
     font-weight: 400;
     font-weight: 400;
-    line-height: 36px;
-    letter-spacing: 1px;
+    line-height: 2.25em;
+    letter-spacing: 0.0625em;
     white-space: pre-line;
     white-space: pre-line;
   }
   }
 
 
   .cover-img {
   .cover-img {
     width: 100%;
     width: 100%;
-    height: 500px;
+    height: 31.25em;
     object-fit: cover;
     object-fit: cover;
     @media (max-width: 600px) {
     @media (max-width: 600px) {
       height: auto;
       height: auto;
@@ -142,11 +141,11 @@ let loading = ref(false);
   }
   }
 }
 }
 .bg-img {
 .bg-img {
-  height: 1000px;
+  height: 62.5em;
   position: relative;
   position: relative;
   z-index: -1;
   z-index: -1;
   @media (max-width: 600px) {
   @media (max-width: 600px) {
-    height: 650px;
+    height: 40.625em;
   }
   }
 }
 }
 
 
@@ -154,7 +153,7 @@ let loading = ref(false);
   display: block;
   display: block;
   text-align: center;
   text-align: center;
   transition: all 0.3s;
   transition: all 0.3s;
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
 
 
   &:hover {
   &:hover {
     opacity: 0.8;
     opacity: 0.8;
@@ -168,12 +167,12 @@ let loading = ref(false);
   }
   }
 
 
   &:last-child {
   &:last-child {
-    bottom: -150px;
+    bottom: -9.375em;
     z-index: -5;
     z-index: -5;
     transform: scaleX(-1);
     transform: scaleX(-1);
 
 
     @media (max-width: 600px) {
     @media (max-width: 600px) {
-      bottom: -50px;
+      bottom: -3.125em;
     }
     }
   }
   }
 }
 }

File diff suppressed because it is too large
+ 1591 - 304
src/views/User/Courses.vue


+ 37 - 32
src/views/User/Dashboard.vue

@@ -1,29 +1,34 @@
 <script setup>
 <script setup>
-import { ref, reactive, computed } from "vue";
+import { ref, reactive, computed, onMounted } from "vue";
 import { useMainStore } from "@/stores/store";
 import { useMainStore } from "@/stores/store";
-import axios from "axios";
+// import axios from "axios";
 import Navbar from "@/components/Navbar.vue";
 import Navbar from "@/components/Navbar.vue";
 
 
 const store = useMainStore();
 const store = useMainStore();
-let token = localStorage.getItem("token");
+// let token = localStorage.getItem("token");
 let username = ref("");
 let username = ref("");
 
 
-(async () => {
-  try {
-    const response = await axios.get(
-      `https://cmm.ai:8088/api/information?token=${token}`
-    );
-    console.log("response", response.data.msg);
-    if (!response.data.msg) {
-      store.logout();
-      return;
-    }
-    store.setProfile(response.data.msg);
-    username.value = response.data.msg.username;
-  } catch (error) {
-    console.error(error);
-  }
-})();
+onMounted(async () => {
+  await store.getProfile();
+  username.value = store.profile.username;
+});
+
+// (async () => {
+//   try {
+//     const response = await axios.get(
+//       `https://cmm.ai:8088/api/information?token=${token}`
+//     );
+//     console.log("response", response.data.msg);
+//     if (!response.data.msg) {
+//       store.logout();
+//       return;
+//     }
+//     store.setProfile(response.data.msg);
+//     username.value = response.data.msg.username;
+//   } catch (error) {
+//     console.error(error);
+//   }
+// })();
 
 
 const firstName = computed(() => {
 const firstName = computed(() => {
   const firstChar = username.value.charAt(0);
   const firstChar = username.value.charAt(0);
@@ -114,18 +119,18 @@ let items = [
 
 
 <style lang="scss">
 <style lang="scss">
 .dashboard-container {
 .dashboard-container {
-  letter-spacing: 1px;
+  letter-spacing: 0.0625em;
   .title {
   .title {
     display: flex;
     display: flex;
     justify-content: center;
     justify-content: center;
     h4 {
     h4 {
-      margin: 20px 0;
-      padding-bottom: 20px;
+      margin: 1.25em 0;
+      padding-bottom: 1.25em;
       display: inline-block;
       display: inline-block;
-      font-size: 22px;
+      font-size: 1.375em;
       font-weight: 500;
       font-weight: 500;
       text-align: center;
       text-align: center;
-      border-bottom: 3px solid var(--purple);
+      border-bottom: 0.1875em solid var(--purple);
     }
     }
   }
   }
 
 
@@ -134,29 +139,29 @@ let items = [
     flex-direction: column;
     flex-direction: column;
     align-items: center;
     align-items: center;
     .img {
     .img {
-      width: 70px;
-      height: 70px;
+      width: 4.375em;
+      height: 4.375em;
       background-color: var(--purple);
       background-color: var(--purple);
       display: flex;
       display: flex;
       align-items: center;
       align-items: center;
       justify-content: center;
       justify-content: center;
-      border-radius: 100px;
+      border-radius: 6.25em;
       span {
       span {
         color: #fff;
         color: #fff;
-        font-size: 34px;
+        font-size: 2.125em;
         font-weight: 500;
         font-weight: 500;
       }
       }
     }
     }
     .name {
     .name {
-      font-size: 28px;
-      margin-top: 15px;
+      font-size: 1.75em;
+      margin-top: 0.9375em;
     }
     }
   }
   }
 
 
   .v-card {
   .v-card {
-    padding: 25px;
+    padding: 1.5625em;
     .v-btn {
     .v-btn {
-      font-size: 18px;
+      font-size: 1.125em;
     }
     }
   }
   }
 
 

+ 1 - 1
src/views/User/FavoriteClass.vue

@@ -132,6 +132,6 @@ const handleSearch = () => {
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .error {
 .error {
-  height: 25px;
+  height: 1.5625em;
 }
 }
 </style>
 </style>

+ 70 - 38
src/views/User/Passport.vue

@@ -44,10 +44,17 @@ console.log("profile", store.profile);
             自 2023 年起至今 <br />
             自 2023 年起至今 <br />
             完成課程時數
             完成課程時數
           </p>
           </p>
-          <img src="@/assets/img/passport/icon-01.png" alt="" class="icon" />
+          <img
+            src="@/assets/img/passport/icon-01.png"
+            alt="臺灣工藝學校全球學習共享平台"
+            class="icon"
+          />
         </div>
         </div>
         <div class="record-item">
         <div class="record-item">
-          <img src="@/assets/img/passport/icon-03.png" alt="" />
+          <img
+            src="@/assets/img/passport/icon-03.png"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
           <p>
           <p>
             總共 <br />
             總共 <br />
             <strong> {{ store.profile.points }} </strong> <small>小時</small>
             <strong> {{ store.profile.points }} </strong> <small>小時</small>
@@ -61,10 +68,17 @@ console.log("profile", store.profile);
             累積 20 點即可兌換 1 份 <br />
             累積 20 點即可兌換 1 份 <br />
             工藝材料包
             工藝材料包
           </p>
           </p>
-          <img src="@/assets/img/passport/icon-02.png" alt="" class="icon" />
+          <img
+            src="@/assets/img/passport/icon-02.png"
+            alt="臺灣工藝學校全球學習共享平台"
+            class="icon"
+          />
         </div>
         </div>
         <div class="record-item">
         <div class="record-item">
-          <img src="@/assets/img/passport/icon-03.png" alt="" />
+          <img
+            src="@/assets/img/passport/icon-03.png"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
           <p>
           <p>
             總共 <br />
             總共 <br />
             <!-- 小數點無條件捨去 -->
             <!-- 小數點無條件捨去 -->
@@ -73,16 +87,18 @@ console.log("profile", store.profile);
           </p>
           </p>
         </div>
         </div>
       </v-col>
       </v-col>
-      <v-col cols="12" class="my-16">
+      <v-col cols="12" class="mt-16">
         <div class="main-table">
         <div class="main-table">
           <h6 class="table-title">報名中課程</h6>
           <h6 class="table-title">報名中課程</h6>
           <table>
           <table>
             <thead>
             <thead>
               <tr>
               <tr>
                 <th>名稱</th>
                 <th>名稱</th>
-                <th width="30%">日期</th>
-                <th width="15%">時數</th>
-                <th width="15%">報名完成</th>
+                <th>報名日期</th>
+                <th width="30%">課程時間</th>
+                <th width="110px">時數</th>
+                <th width="10%">報名狀態</th>
+                <!-- <th width="15%">繳款資訊</th> -->
               </tr>
               </tr>
             </thead>
             </thead>
             <tbody v-if="register.list.length">
             <tbody v-if="register.list.length">
@@ -93,17 +109,33 @@ console.log("profile", store.profile);
               </tr> -->
               </tr> -->
               <tr v-for="(item, index) in register.list" :key="index">
               <tr v-for="(item, index) in register.list" :key="index">
                 <td>{{ item.class_name }}</td>
                 <td>{{ item.class_name }}</td>
+                <td>
+                  {{ moment(`${item.create_time}`).format("YYYY/MM/DD") }}
+                </td>
                 <td>
                 <td>
                   {{ moment(`${item.start_time}`).format("YYYY/MM/DD H:mm") }}
                   {{ moment(`${item.start_time}`).format("YYYY/MM/DD H:mm") }}
                   <br />
                   <br />
                   ~ <br />
                   ~ <br />
                   {{ moment(`${item.end_time}`).format("YYYY/MM/DD H:mm") }}
                   {{ moment(`${item.end_time}`).format("YYYY/MM/DD H:mm") }}
                 </td>
                 </td>
-                <td>3 小時</td>
+                <td>{{ item.hours }} 小時</td>
                 <td>
                 <td>
                   <span class="finish-icon" v-if="item.reg_confirm">
                   <span class="finish-icon" v-if="item.reg_confirm">
                     <v-icon icon="mdi-check" class="pb-1"></v-icon>
                     <v-icon icon="mdi-check" class="pb-1"></v-icon>
                   </span>
                   </span>
+
+                  <span v-else class="d-flex align-center">
+                    <p style="width: 55px" class="text-grey-lighten-1">審核中</p>
+                  </span>
+
+                  <!-- <div v-if="item.reg_confirm" class="d-flex align-center">
+                    <v-icon
+                      color="blue"
+                      icon="mdi-check-circle-outline"
+                      class="me-1"
+                    ></v-icon>
+                    <p style="width: 70px">報名成功</p>
+                  </div> -->
                 </td>
                 </td>
               </tr>
               </tr>
             </tbody>
             </tbody>
@@ -150,51 +182,51 @@ console.log("profile", store.profile);
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 p {
 p {
-  line-height: 30px;
+  line-height: 1.875em;
 }
 }
 
 
 .main-info {
 .main-info {
-  margin: 30px;
-  padding: 50px;
+  margin: 1.875em;
+  padding: 3.125em;
   position: relative;
   position: relative;
-  border: 2px solid var(--blue);
-  border-radius: 20px;
+  border: 0.125em solid var(--blue);
+  border-radius: 1.25em;
 
 
   @media (max-width: 600px) {
   @media (max-width: 600px) {
     margin: 0;
     margin: 0;
-    padding: 50px 20px 100px;
+    padding: 3.125em 1.25em 6.25em;
   }
   }
 
 
   h5 {
   h5 {
     display: flex;
     display: flex;
     flex-direction: column;
     flex-direction: column;
     align-items: center;
     align-items: center;
-    font-size: 20px;
+    font-size: 1.25em;
     font-weight: 500;
     font-weight: 500;
-    letter-spacing: 1px;
+    letter-spacing: 0.0625em;
     span {
     span {
       display: block;
       display: block;
-      margin: 5px 0 15px;
-      font-size: 36px;
+      margin: 0.3em 0;
+      font-size: 2.25em;
     }
     }
   }
   }
 
 
   p {
   p {
     text-align: center;
     text-align: center;
-    line-height: 22px;
+    line-height: 1.375em;
     @media (max-width: 490px) {
     @media (max-width: 490px) {
-      font-size: 14px;
+      font-size: 0.875em;
     }
     }
   }
   }
 
 
   .icon {
   .icon {
-    width: 50px;
+    width: 3.125em;
     position: absolute;
     position: absolute;
-    right: -50px;
+    right: -3.125em;
   }
   }
 
 
   .record-item {
   .record-item {
-    margin-top: 20px;
+    margin-top: 1.25em;
     position: relative;
     position: relative;
     p {
     p {
       width: 100%;
       width: 100%;
@@ -204,24 +236,24 @@ p {
       left: 50%;
       left: 50%;
       transform: translate(-50%, -50%);
       transform: translate(-50%, -50%);
       color: #fff;
       color: #fff;
-      font-size: 30px;
+      font-size: 1.875em;
     }
     }
     strong {
     strong {
       display: inline-block;
       display: inline-block;
-      margin: 25px 0;
-      font-size: 56px;
+      margin: 0.1em 0 0.5em;
+      font-size: 2em;
       font-weight: 500;
       font-weight: 500;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        font-size: 50px;
+        font-size: 3.125em;
       }
       }
     }
     }
     small {
     small {
-      font-size: 20px;
+      font-size: 1.25em;
     }
     }
     img {
     img {
-      max-width: 260px;
+      max-width: 16.25em;
       @media (max-width: 600px) {
       @media (max-width: 600px) {
-        max-width: 220px;
+        max-width: 13.75em;
       }
       }
     }
     }
   }
   }
@@ -233,19 +265,19 @@ p {
 
 
 table {
 table {
   thead {
   thead {
-    border-bottom: 2px solid var(--blue);
+    border-bottom: 0.125em solid var(--blue);
   }
   }
   tbody {
   tbody {
     td {
     td {
-      border-bottom: 1px solid var(--blue);
-      line-height: 24px;
-      padding: 15px;
+      border-bottom: 0.0625em solid var(--blue);
+      line-height: 1.5em;
+      padding: 0.9375em;
     }
     }
   }
   }
   .finish-icon {
   .finish-icon {
-    padding: 8px;
-    border: 2px solid var(--blue);
-    border-radius: 100px;
+    padding: 0.5em;
+    border: 0.125em solid var(--blue);
+    border-radius: 6.25em;
     .v-icon {
     .v-icon {
       color: var(--blue);
       color: var(--blue);
     }
     }

+ 124 - 35
src/views/User/Profile.vue

@@ -17,9 +17,11 @@ let user = reactive({
   phone: "",
   phone: "",
   address: "",
   address: "",
   position: [], // 身份
   position: [], // 身份
+  identity: [], // 類別
 });
 });
 
 
 let positionList = ref([]);
 let positionList = ref([]);
+let identityList = ref([]);
 let email = ref("");
 let email = ref("");
 let phoneCode = ref("+886");
 let phoneCode = ref("+886");
 let phone = ref("");
 let phone = ref("");
@@ -38,7 +40,9 @@ async function saveUserInfo() {
   user.phone = `${phoneCode.value} ${phone.value}`;
   user.phone = `${phoneCode.value} ${phone.value}`;
   user.address = city.value + address.value;
   user.address = city.value + address.value;
   user.birthday = store.formatDate(user.birthday);
   user.birthday = store.formatDate(user.birthday);
-  user.position = `[${positionList.value.join(",")}]`; // 陣列轉字串
+  // 陣列轉字串
+  user.position = `[${positionList.value.join(",")}]`;
+  user.identity = `[${identityList.value.join(",")}]`;
 
 
   console.log("user", user);
   console.log("user", user);
 
 
@@ -66,7 +70,8 @@ async function addUserInfo(formData) {
       getUserInfo;
       getUserInfo;
     }
     }
     isLoading.value = false;
     isLoading.value = false;
-    handlerAlert();
+    alert("儲存成功!");
+    // handlerAlert();
   } catch (error) {
   } catch (error) {
     console.error(error);
     console.error(error);
   }
   }
@@ -89,29 +94,54 @@ async function updateUserInfo(formData) {
     );
     );
     console.log("更新 response", response);
     console.log("更新 response", response);
     isLoading.value = false;
     isLoading.value = false;
-    handlerAlert();
+    alert("儲存成功!");
+    // handlerAlert();
   } catch (error) {
   } catch (error) {
     console.error(error);
     console.error(error);
   }
   }
 }
 }
 
 
+let isCrafts = ref(false); // 身份是否為工藝家
+
 // 取得使用者資料
 // 取得使用者資料
 async function getUserInfo() {
 async function getUserInfo() {
   try {
   try {
-    const response = await axios.get(
-      `https://cmm.ai:8088/api/get_user_information?access_token=${token}`
-    );
-    console.log("getUserInfo response", response);
+    let response = await store.getUserInfo();
+    console.log("取得使用者資料", response);
+
+    // const response = await axios.get(
+    //   `https://cmm.ai:8088/api/get_user_information?access_token=${token}`
+    // );
+    // console.log("getUserInfo response", response);
+    // console.log("response.data.msg", response.data.msg);
+
+    // 無法訪問
+    if (response.data.msg === "no access") {
+      console.log("no access");
+      store.loginState = false;
+      localStorage.removeItem("token");
+      window.location.reload();
+      return;
+    }
 
 
     let position = response.data.user_inform[0].position;
     let position = response.data.user_inform[0].position;
+    console.log("user.position", position);
+
     // 判斷身份
     // 判斷身份
     if (position["學員"]) {
     if (position["學員"]) {
       positionList.value.push("1");
       positionList.value.push("1");
     }
     }
     if (position["開課工藝家"]) {
     if (position["開課工藝家"]) {
+      isCrafts.value = true;
       positionList.value.push("2");
       positionList.value.push("2");
     }
     }
 
 
+    let identifyStr = response.data.user_inform[0].identify.substring(
+      1,
+      response.data.user_inform[0].identify.length - 1
+    ); // 移除 [] 後將字串轉為陣列
+    identityList.value = identifyStr.split(",");
+
     email.value = response.data.user_inform[0].email;
     email.value = response.data.user_inform[0].email;
     user.user_name = response.data.user_inform[0].user_name;
     user.user_name = response.data.user_inform[0].user_name;
 
 
@@ -142,6 +172,8 @@ async function getUserInfo() {
       address.value = response.data.user_inform[0].address.substring(3);
       address.value = response.data.user_inform[0].address.substring(3);
     }
     }
   } catch (error) {
   } catch (error) {
+    store.loginState = false;
+    localStorage.removeItem("token");
     console.error(error);
     console.error(error);
   }
   }
 }
 }
@@ -173,12 +205,14 @@ let resume = reactive({
     );
     );
     console.log("工藝家", response.data.user_resume);
     console.log("工藝家", response.data.user_resume);
 
 
-    // 遍歷物件屬性
-    Object.keys(response.data.user_resume).forEach((key) => {
-      if (resume[key] !== undefined) {
-        resume[key] = response.data.user_resume[key];
-      }
-    });
+    if (response.data.user_resume) {
+      // 遍歷物件屬性
+      Object.keys(response.data.user_resume).forEach((key) => {
+        if (resume[key] !== undefined) {
+          resume[key] = response.data.user_resume[key];
+        }
+      });
+    }
 
 
     console.log("resume", resume);
     console.log("resume", resume);
   } catch (error) {
   } catch (error) {
@@ -219,18 +253,44 @@ watch(portfolioImg, (newFiles) => {
     handlePortfolioImg(newFiles);
     handlePortfolioImg(newFiles);
   }
   }
 });
 });
+
+// 身份類別
+let selectType = ref([]);
+let typeList = [
+  "系統管理者",
+  "職能治療師",
+  "設計師",
+  "藝術家",
+  "跨域工藝師",
+  "協槓青年",
+  "傳統工藝守護者",
+  "加工製造者",
+  "修復師",
+  "評論家",
+  "策展人",
+  "鑑賞師",
+  "收藏家",
+];
 </script>
 </script>
 
 
 <template>
 <template>
   <v-card class="h-100 profile-card">
   <v-card class="h-100 profile-card">
-    <v-tabs v-model="tab" color="purple" align-tabs="center">
+    <v-tabs v-model="tab" color="purple" align-tabs="center" class="mb-16">
       <v-tab :value="1">關於我</v-tab>
       <v-tab :value="1">關於我</v-tab>
-      <v-tab :value="2">工藝家履歷</v-tab>
+      <v-tab v-if="isCrafts" :value="2">工藝家履歷</v-tab>
     </v-tabs>
     </v-tabs>
     <v-window v-model="tab">
     <v-window v-model="tab">
       <v-window-item :value="1">
       <v-window-item :value="1">
         <v-form @submit.prevent>
         <v-form @submit.prevent>
-          <v-label>
+          <p class="mb-5">身份</p>
+          <div class="d-flex">
+            <v-chip color="purple"> 學員 </v-chip>
+            <v-chip v-if="isCrafts" color="purple" class="ms-2">
+              開課工藝家
+            </v-chip>
+          </div>
+
+          <!-- <v-label>
             <p class="d-flex mb-5">身份<span class="mark">*</span></p>
             <p class="d-flex mb-5">身份<span class="mark">*</span></p>
           </v-label>
           </v-label>
           <v-checkbox
           <v-checkbox
@@ -246,13 +306,32 @@ watch(portfolioImg, (newFiles) => {
             value="2"
             value="2"
             color="purple"
             color="purple"
             hide-details
             hide-details
-          ></v-checkbox>
+          ></v-checkbox> -->
 
 
-          <v-label class="mt-5">
+          <v-label class="mt-10">
+            <p class="d-flex mb-5">類別</p>
+
+            <v-select
+              v-model="identityList"
+              :items="typeList"
+              multiple
+              hide-details
+              variant="outlined"
+              density="compact"
+            >
+              <template #selection="{ item }">
+                <v-chip color="purple" class="me-1">{{ item.title }}</v-chip>
+              </template>
+            </v-select>
+          </v-label>
+
+          <v-label class="mt-10">
             <p class="d-flex mb-5">顯示名稱<span class="mark">*</span></p>
             <p class="d-flex mb-5">顯示名稱<span class="mark">*</span></p>
             <v-text-field
             <v-text-field
               v-model="user.user_name"
               v-model="user.user_name"
               :rules="[(v) => !!v || '請輸入您的名稱']"
               :rules="[(v) => !!v || '請輸入您的名稱']"
+              variant="outlined"
+              density="comfortable"
               class="d-block"
               class="d-block"
             ></v-text-field>
             ></v-text-field>
           </v-label>
           </v-label>
@@ -263,10 +342,12 @@ watch(portfolioImg, (newFiles) => {
           <!-- <p class="text-gray">{{ email }}(欲變更帳號或密碼,請至帳號設定)</p> -->
           <!-- <p class="text-gray">{{ email }}(欲變更帳號或密碼,請至帳號設定)</p> -->
 
 
           <v-label>
           <v-label>
-            <p class="d-flex mb-5">真實姓名<span class="mark">*</span></p>
+            <p class="d-flex my-5">真實姓名<span class="mark">*</span></p>
             <v-text-field
             <v-text-field
               v-model="user.name"
               v-model="user.name"
               :rules="[(v) => !!v || '請輸入您的姓名']"
               :rules="[(v) => !!v || '請輸入您的姓名']"
+              variant="outlined"
+              density="comfortable"
               class="d-block"
               class="d-block"
             ></v-text-field>
             ></v-text-field>
           </v-label>
           </v-label>
@@ -284,7 +365,7 @@ watch(portfolioImg, (newFiles) => {
           ></VueDatePicker>
           ></VueDatePicker>
 
 
           <v-label>
           <v-label>
-            <p class="d-flex mb-3">性別</p>
+            <p class="d-flex mt-5 mb-3">性別</p>
 
 
             <v-chip-group
             <v-chip-group
               v-model="user.gender"
               v-model="user.gender"
@@ -303,7 +384,7 @@ watch(portfolioImg, (newFiles) => {
           </v-label>
           </v-label>
 
 
           <v-label>
           <v-label>
-            <p class="d-flex mb-5">手機號碼<span class="mark">*</span></p>
+            <p class="d-flex my-5">手機號碼<span class="mark">*</span></p>
             <v-container class="pa-0">
             <v-container class="pa-0">
               <v-row>
               <v-row>
                 <v-col cols="12" md="3">
                 <v-col cols="12" md="3">
@@ -312,6 +393,8 @@ watch(portfolioImg, (newFiles) => {
                     :items="phoneCodes"
                     :items="phoneCodes"
                     :item-title="displayText"
                     :item-title="displayText"
                     item-value="code"
                     item-value="code"
+                    variant="outlined"
+                    density="comfortable"
                   >
                   >
                   </v-select>
                   </v-select>
                 </v-col>
                 </v-col>
@@ -320,6 +403,8 @@ watch(portfolioImg, (newFiles) => {
                   <v-text-field
                   <v-text-field
                     v-model="phone"
                     v-model="phone"
                     :rules="[(v) => !!v || '請輸入您的號碼']"
                     :rules="[(v) => !!v || '請輸入您的號碼']"
+                    variant="outlined"
+                    density="comfortable"
                     required
                     required
                   ></v-text-field>
                   ></v-text-field>
                 </v-col>
                 </v-col>
@@ -337,6 +422,8 @@ watch(portfolioImg, (newFiles) => {
                     :items="taiwanCities"
                     :items="taiwanCities"
                     item-title="name"
                     item-title="name"
                     item-value="name"
                     item-value="name"
+                    variant="outlined"
+                    density="comfortable"
                   >
                   >
                   </v-select>
                   </v-select>
                 </v-col>
                 </v-col>
@@ -346,6 +433,8 @@ watch(portfolioImg, (newFiles) => {
                     v-model="address"
                     v-model="address"
                     required
                     required
                     placeholder="詳細地址"
                     placeholder="詳細地址"
+                    variant="outlined"
+                    density="comfortable"
                   ></v-text-field>
                   ></v-text-field>
                 </v-col>
                 </v-col>
               </v-row>
               </v-row>
@@ -505,13 +594,13 @@ watch(portfolioImg, (newFiles) => {
 <style lang="scss">
 <style lang="scss">
 .profile-card {
 .profile-card {
   p {
   p {
-    letter-spacing: 1px;
+    letter-spacing: 0.0625em;
   }
   }
 
 
   .img-list {
   .img-list {
     .item {
     .item {
-      height: 170px;
-      border-radius: 5px;
+      height: 10.625em;
+      border-radius: 0.3125em;
       background-color: #ccc; // 預設灰底
       background-color: #ccc; // 預設灰底
       background-repeat: no-repeat;
       background-repeat: no-repeat;
       background-position: center;
       background-position: center;
@@ -520,11 +609,11 @@ watch(portfolioImg, (newFiles) => {
   }
   }
 
 
   .v-btn {
   .v-btn {
-    font-size: 16px !important;
+    font-size: 1em !important;
   }
   }
 
 
   .v-label {
   .v-label {
-    margin-top: 30px;
+    margin-top: 1.875em;
     flex-direction: column;
     flex-direction: column;
     align-items: flex-start;
     align-items: flex-start;
     justify-content: center;
     justify-content: center;
@@ -537,22 +626,22 @@ watch(portfolioImg, (newFiles) => {
     }
     }
   }
   }
 
 
-  .v-chip__content {
-    padding: 0 8px;
-  }
+  // .v-chip__content {
+  //   padding: 0 0.5em;
+  // }
 
 
   .v-alert {
   .v-alert {
     position: absolute;
     position: absolute;
-    padding: 3px 10px;
-    right: 223px;
+    padding: 0.1875em 0.625em;
+    right: 13.9375em;
     transition: all 0.3s;
     transition: all 0.3s;
   }
   }
 
 
   .v-tabs {
   .v-tabs {
-    margin: 20px 0;
+    margin: 1.25em 0;
 
 
     .v-tab__slider {
     .v-tab__slider {
-      height: 3px;
+      height: 0.1875em;
     }
     }
 
 
     .v-slide-group__container {
     .v-slide-group__container {
@@ -560,12 +649,12 @@ watch(portfolioImg, (newFiles) => {
     }
     }
 
 
     .v-btn__content {
     .v-btn__content {
-      font-size: 22px;
+      font-size: 1.375em;
     }
     }
   }
   }
 
 
   .v-tabs--density-default {
   .v-tabs--density-default {
-    --v-tabs-height: 65px;
+    --v-tabs-height: 4.0625em;
   }
   }
 }
 }
 </style>
 </style>

+ 1 - 1
src/views/User/Setting.vue

@@ -83,6 +83,6 @@ const handleSearch = () => {
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .error {
 .error {
-  height: 25px;
+  height: 1.5625em;
 }
 }
 </style>
 </style>

Some files were not shown because too many files changed in this diff