ソースを参照

product detail page

tum 2 年 前
コミット
09587f0164
共有7 個のファイルを変更した152 個の追加41 個の削除を含む
  1. 80 0
      package-lock.json
  2. 1 0
      package.json
  3. 42 21
      src/components/ProductDetail.vue
  4. 19 0
      src/components/TopBar.vue
  5. 6 3
      src/views/ProductListPage.vue
  6. 2 12
      src/views/Tab1Page.vue
  7. 2 5
      src/views/Tab2Page.vue

+ 80 - 0
package-lock.json

@@ -43,6 +43,7 @@
43 43
         "typescript": "^4.9.3",
44 44
         "vite": "^4.1.0",
45 45
         "vitest": "^0.29.2",
46
+        "vue-showdown": "^4.0.0",
46 47
         "vue-tsc": "^1.0.24"
47 48
       }
48 49
     },
@@ -1229,6 +1230,12 @@
1229 1230
       "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
1230 1231
       "dev": true
1231 1232
     },
1233
+    "node_modules/@types/showdown": {
1234
+      "version": "2.0.0",
1235
+      "resolved": "https://registry.npmjs.org/@types/showdown/-/showdown-2.0.0.tgz",
1236
+      "integrity": "sha512-70xBJoLv+oXjB5PhtA8vo7erjLDp9/qqI63SRHm4REKrwuPOLs8HhXwlZJBJaB4kC18cCZ1UUZ6Fb/PLFW4TCA==",
1237
+      "dev": true
1238
+    },
1232 1239
     "node_modules/@types/sinonjs__fake-timers": {
1233 1240
       "version": "8.1.1",
1234 1241
       "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
@@ -7439,6 +7446,31 @@
7439 7446
         "node": ">=8"
7440 7447
       }
7441 7448
     },
7449
+    "node_modules/showdown": {
7450
+      "version": "2.1.0",
7451
+      "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz",
7452
+      "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==",
7453
+      "dev": true,
7454
+      "dependencies": {
7455
+        "commander": "^9.0.0"
7456
+      },
7457
+      "bin": {
7458
+        "showdown": "bin/showdown.js"
7459
+      },
7460
+      "funding": {
7461
+        "type": "individual",
7462
+        "url": "https://www.paypal.me/tiviesantos"
7463
+      }
7464
+    },
7465
+    "node_modules/showdown/node_modules/commander": {
7466
+      "version": "9.5.0",
7467
+      "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
7468
+      "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
7469
+      "dev": true,
7470
+      "engines": {
7471
+        "node": "^12.20.0 || >=14"
7472
+      }
7473
+    },
7442 7474
     "node_modules/side-channel": {
7443 7475
       "version": "1.0.4",
7444 7476
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -8519,6 +8551,20 @@
8519 8551
         "vue": "^3.2.0"
8520 8552
       }
8521 8553
     },
8554
+    "node_modules/vue-showdown": {
8555
+      "version": "4.0.0",
8556
+      "resolved": "https://registry.npmjs.org/vue-showdown/-/vue-showdown-4.0.0.tgz",
8557
+      "integrity": "sha512-ZDO2IVJ4UUtVbl1IQAQzG0xq8lgnwolSqYOLyBkTqT2L/oAr00yb1lpsRIPruaIqsxHqGjAuijY+K3pGJ2z0QQ==",
8558
+      "dev": true,
8559
+      "dependencies": {
8560
+        "@types/showdown": "^2.0.0",
8561
+        "showdown": "^2.1.0",
8562
+        "vue": "^3.2.45"
8563
+      },
8564
+      "engines": {
8565
+        "node": ">=14.18.0"
8566
+      }
8567
+    },
8522 8568
     "node_modules/vue-template-compiler": {
8523 8569
       "version": "2.7.14",
8524 8570
       "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz",
@@ -9705,6 +9751,12 @@
9705 9751
       "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
9706 9752
       "dev": true
9707 9753
     },
9754
+    "@types/showdown": {
9755
+      "version": "2.0.0",
9756
+      "resolved": "https://registry.npmjs.org/@types/showdown/-/showdown-2.0.0.tgz",
9757
+      "integrity": "sha512-70xBJoLv+oXjB5PhtA8vo7erjLDp9/qqI63SRHm4REKrwuPOLs8HhXwlZJBJaB4kC18cCZ1UUZ6Fb/PLFW4TCA==",
9758
+      "dev": true
9759
+    },
9708 9760
     "@types/sinonjs__fake-timers": {
9709 9761
       "version": "8.1.1",
9710 9762
       "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
@@ -14405,6 +14457,23 @@
14405 14457
       "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
14406 14458
       "dev": true
14407 14459
     },
14460
+    "showdown": {
14461
+      "version": "2.1.0",
14462
+      "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz",
14463
+      "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==",
14464
+      "dev": true,
14465
+      "requires": {
14466
+        "commander": "^9.0.0"
14467
+      },
14468
+      "dependencies": {
14469
+        "commander": {
14470
+          "version": "9.5.0",
14471
+          "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
14472
+          "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
14473
+          "dev": true
14474
+        }
14475
+      }
14476
+    },
14408 14477
     "side-channel": {
14409 14478
       "version": "1.0.4",
14410 14479
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -15177,6 +15246,17 @@
15177 15246
         "@vue/devtools-api": "^6.4.5"
15178 15247
       }
15179 15248
     },
15249
+    "vue-showdown": {
15250
+      "version": "4.0.0",
15251
+      "resolved": "https://registry.npmjs.org/vue-showdown/-/vue-showdown-4.0.0.tgz",
15252
+      "integrity": "sha512-ZDO2IVJ4UUtVbl1IQAQzG0xq8lgnwolSqYOLyBkTqT2L/oAr00yb1lpsRIPruaIqsxHqGjAuijY+K3pGJ2z0QQ==",
15253
+      "dev": true,
15254
+      "requires": {
15255
+        "@types/showdown": "^2.0.0",
15256
+        "showdown": "^2.1.0",
15257
+        "vue": "^3.2.45"
15258
+      }
15259
+    },
15180 15260
     "vue-template-compiler": {
15181 15261
       "version": "2.7.14",
15182 15262
       "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz",

+ 1 - 0
package.json

@@ -47,6 +47,7 @@
47 47
     "typescript": "^4.9.3",
48 48
     "vite": "^4.1.0",
49 49
     "vitest": "^0.29.2",
50
+    "vue-showdown": "^4.0.0",
50 51
     "vue-tsc": "^1.0.24"
51 52
   },
52 53
   "description": "An Ionic project"

+ 42 - 21
src/components/ProductDetail.vue

@@ -11,32 +11,50 @@
11 11
     </ion-toolbar>
12 12
   </ion-header>
13 13
   <ion-content class="ion-padding">
14
-    <ion-item>
15
-      <ion-label position="stacked">Your name</ion-label>
16
-      {{ name }}
17
-      <ion-input v-model="name" placeholder="Your name"></ion-input>
18
-    </ion-item>
14
+    <!--<ion-item>-->
15
+      <!--<ion-label position="stacked">Your name</ion-label>-->
16
+      <!--{{ name }}-->
17
+
18
+      <!--<strong>{{ pid }}</strong>-->
19
+      <!--<ion-input v-model="name" placeholder="Your name" label='xx'></ion-input>-->
20
+    <!--</ion-item>-->
21
+    <template v-if="product">
22
+      <ion-img :src="product.cover_image_str"></ion-img>
23
+      <ion-text>
24
+        <h1>{{ product.name }}</h1>
25
+        <vue-showdown :markdown="product.description" />
26
+ 
27
+      </ion-text>
28
+    </template>
19 29
   </ion-content>
20 30
 </template>
21 31
 
22 32
 <script setup lang="ts">
23
-  import {
24
-    IonContent,
25
-    IonHeader,
26
-    IonTitle,
27
-    IonToolbar,
28
-    IonButtons,
29
-    IonButton,
30
-    IonItem,
31
-    IonLabel,
32
-    IonInput,
33
-    modalController,
34
-    onIonViewWillEnter, 
35
-  } from '@ionic/vue';
36
-  import { ref, onMounted } from 'vue'
33
+import {
34
+  IonContent,
35
+  IonHeader,
36
+  IonTitle,
37
+  IonToolbar,
38
+  IonButtons,
39
+  IonButton,
40
+  IonItem,
41
+  IonLabel,
42
+  IonInput,
43
+  IonImg,
44
+  IonText,
45
+  modalController,
46
+  onIonViewWillEnter, 
47
+} from '@ionic/vue';
37 48
 
38
-const props = defineProps(['pid'])
49
+import { VueShowdown } from 'vue-showdown';
50
+import { ref, onMounted } from 'vue'
39 51
 
52
+import axios from 'axios';
53
+import { API_URL } from '@/api_config';
54
+
55
+const props = defineProps(['pid'])
56
+let pid = ref(0)
57
+let product = ref(null)
40 58
 //console.log(pid)
41 59
 
42 60
 let name = ref("xxx")
@@ -46,10 +64,13 @@ function cancel(){
46 64
 function confirm(){
47 65
   return modalController.dismiss(name.value, 'confirm');
48 66
 }
49
-onMounted(() => {
67
+onMounted(async () => {
50 68
 //onIonViewWillEnter(() => {
51 69
   console.log("on mounted")
52 70
   console.log(props.pid)
71
+  const res = await axios.get(API_URL + `fn_products/${props.pid}/?format=json`)
72
+  product.value = res.data
73
+  pid.value  = props.pid
53 74
 })
54 75
 
55 76
 </script>

+ 19 - 0
src/components/TopBar.vue

@@ -0,0 +1,19 @@
1
+<template>
2
+  <ion-toolbar>
3
+    <ion-searchbar></ion-searchbar>
4
+    <ion-buttons slot="end">
5
+      <ion-button>
6
+        <ion-icon slot="icon-only" :icon="heart"></ion-icon>
7
+      </ion-button>
8
+      <ion-button id='cartBtn'>
9
+        <ion-icon  :icon="cart" slot='start'></ion-icon>
10
+        <ion-badge slot="end" id='bd'>22</ion-badge>
11
+      </ion-button>
12
+    </ion-buttons>
13
+  </ion-toolbar>
14
+</template>
15
+
16
+<script setup lang="ts">
17
+import {  IonToolbar, IonButton, IonItem, IonIcon, IonSearchbar, IonButtons, IonBadge } from '@ionic/vue';
18
+import { star, heart, cart } from 'ionicons/icons';
19
+</script>

+ 6 - 3
src/views/ProductListPage.vue

@@ -16,7 +16,7 @@
16 16
     </ion-header>
17 17
     <ion-grid>
18 18
       <ion-row>
19
-        <ion-col size="6" v-for="(c, index) in prods"  :key="index" @click="openModal">
19
+        <ion-col size="6" v-for="(c, index) in prods"  :key="c.id" @click="openModal($event, c)">
20 20
           <ion-img :src="c.cover_image_str"></ion-img>
21 21
           <ion-label class="ion-text-wrap">
22 22
             {{ c.name }} {{ message }}
@@ -30,6 +30,7 @@
30 30
 <script setup lang="ts">
31 31
 import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonBackButton, IonButtons, onIonViewWillEnter, IonCard, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCardContent, IonRow, IonGrid, IonCol, IonImg, IonButton, IonLabel, modalController} from '@ionic/vue';
32 32
 
33
+
33 34
 import ProductDetail from '@/components/ProductDetail.vue'
34 35
 
35 36
 import axios from 'axios';
@@ -51,10 +52,12 @@ onMounted( async() => {
51 52
   console.log(prods)
52 53
 })
53 54
 
54
-const openModal = async () => {
55
+const openModal = async (event, obj) => {
56
+  console.log(event)
57
+  console.log(obj)
55 58
   const modal = await modalController.create({
56 59
     component: ProductDetail,
57
-    componentProps: {pid: 5}, 
60
+    componentProps: {pid: obj.id}, 
58 61
   });
59 62
   modal.present();
60 63
 

+ 2 - 12
src/views/Tab1Page.vue

@@ -1,18 +1,7 @@
1 1
 <template>
2 2
   <ion-page>
3 3
     <ion-header>
4
-      <ion-toolbar>
5
-        <ion-searchbar></ion-searchbar>
6
-        <ion-buttons slot="end">
7
-          <ion-button>
8
-             <ion-icon slot="icon-only" :icon="heart"></ion-icon>
9
-          </ion-button>
10
-          <ion-button id='cartBtn'>
11
-             <ion-icon  :icon="cart" slot='start'></ion-icon>
12
-             <ion-badge slot="end" id='bd'>22</ion-badge>
13
-          </ion-button>
14
-        </ion-buttons>
15
-      </ion-toolbar>
4
+      <top-bar></top-bar>
16 5
     </ion-header>
17 6
     <ion-content :fullscreen="true" id="content">
18 7
          <swiper>
@@ -42,6 +31,7 @@
42 31
 <script setup lang="ts">
43 32
 import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonButton, IonItem, IonLabel, IonList, IonIcon, IonSearchbar, onIonViewDidEnter, onIonViewWillLeave, onIonViewWillEnter, IonThumbnail, IonImg, IonCard, IonCardContent, IonButtons, IonBadge } from '@ionic/vue';
44 33
 import ExploreContainer from '@/components/ExploreContainer.vue';
34
+import TopBar from '@/components/TopBar.vue'
45 35
 import { logoAndroid, logoApple, star, heart, cart } from 'ionicons/icons';
46 36
 import axios from 'axios';
47 37
 

+ 2 - 5
src/views/Tab2Page.vue

@@ -1,11 +1,7 @@
1 1
 <template>
2 2
   <ion-page>
3 3
     <ion-header>
4
-      <ion-toolbar>
5
-        <ion-title>
6
-          <img src="@/assets/img/kacee-logo.png">
7
-        </ion-title>
8
-      </ion-toolbar>
4
+      <top-bar></top-bar>
9 5
     </ion-header>
10 6
     <ion-content class='ion-padding' :fullscreen="true">
11 7
       <ion-grid>
@@ -23,6 +19,7 @@
23 19
 <script setup lang="ts">
24 20
 import { IonPage, IonHeader, IonToolbar, IonTitle, IonButton, IonContent, IonBackButton, IonButtons, IonRow, IonCol, IonGrid, onIonViewWillEnter, IonLabel, IonImg } from '@ionic/vue';
25 21
 import ExploreContainer from '@/components/ExploreContainer.vue';
22
+import TopBar from '@/components/TopBar.vue'
26 23
 import { useRouter } from 'vue-router';
27 24
 
28 25
 import { ref, onMounted } from 'vue'