ソースを参照

Merge remote-tracking branch 'origin/master'

master
Bruce Lywood 5年前
コミット
6fba7d5231

+ 874
- 182
package-lock.json
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 3
- 2
package.json ファイルの表示

@@ -15,13 +15,14 @@
15 15
     "datatables.net": "^1.10.19",
16 16
     "lodash": "^4.17.15",
17 17
     "material-design-icons-iconfont": "^3.0.3",
18
+    "node-sass": "^4.12.0",
18 19
     "roboto-fontface": "*",
19
-    "stylus": "^0.54.7",
20
+    "sass-loader": "^7.3.1",
20 21
     "stylus-loader": "^3.0.2",
21 22
     "vue": "^2.6.10",
22 23
     "vue-eva-icons": "^1.1.1",
23 24
     "vue-router": "^3.0.7",
24
-    "vuejs-datatable": "^1.7.0",
25
+    "vue-trix": "^1.0.0",
25 26
     "vuetify": "^1.5.5",
26 27
     "vuex": "^3.1.1"
27 28
   },

+ 37
- 0
public/img/ligthbox/close.svg ファイルの表示

@@ -0,0 +1,37 @@
1
+<?xml version="1.0" encoding="iso-8859-1"?>
2
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
3
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 47.971 47.971" style="enable-background:new 0 0 47.971 47.971;" xml:space="preserve">
4
+<g>
5
+	<path d="M28.228,23.986L47.092,5.122c1.172-1.171,1.172-3.071,0-4.242c-1.172-1.172-3.07-1.172-4.242,0L23.986,19.744L5.121,0.88   c-1.172-1.172-3.07-1.172-4.242,0c-1.172,1.171-1.172,3.071,0,4.242l18.865,18.864L0.879,42.85c-1.172,1.171-1.172,3.071,0,4.242   C1.465,47.677,2.233,47.97,3,47.97s1.535-0.293,2.121-0.879l18.865-18.864L42.85,47.091c0.586,0.586,1.354,0.879,2.121,0.879   s1.535-0.293,2.121-0.879c1.172-1.171,1.172-3.071,0-4.242L28.228,23.986z" fill="#FFFFFF"/>
6
+</g>
7
+<g>
8
+</g>
9
+<g>
10
+</g>
11
+<g>
12
+</g>
13
+<g>
14
+</g>
15
+<g>
16
+</g>
17
+<g>
18
+</g>
19
+<g>
20
+</g>
21
+<g>
22
+</g>
23
+<g>
24
+</g>
25
+<g>
26
+</g>
27
+<g>
28
+</g>
29
+<g>
30
+</g>
31
+<g>
32
+</g>
33
+<g>
34
+</g>
35
+<g>
36
+</g>
37
+</svg>

+ 49
- 0
public/img/ligthbox/next.svg ファイルの表示

@@ -0,0 +1,49 @@
1
+<?xml version="1.0" encoding="iso-8859-1"?>
2
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
3
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 240.823 240.823" style="enable-background:new 0 0 240.823 240.823;" xml:space="preserve">
4
+<g>
5
+	<path id="Chevron_Right_1_" d="M183.189,111.816L74.892,3.555c-4.752-4.74-12.451-4.74-17.215,0c-4.752,4.74-4.752,12.439,0,17.179   l99.707,99.671l-99.695,99.671c-4.752,4.74-4.752,12.439,0,17.191c4.752,4.74,12.463,4.74,17.215,0l108.297-108.261   C187.881,124.315,187.881,116.495,183.189,111.816z" fill="#FFFFFF"/>
6
+	<g>
7
+	</g>
8
+	<g>
9
+	</g>
10
+	<g>
11
+	</g>
12
+	<g>
13
+	</g>
14
+	<g>
15
+	</g>
16
+	<g>
17
+	</g>
18
+</g>
19
+<g>
20
+</g>
21
+<g>
22
+</g>
23
+<g>
24
+</g>
25
+<g>
26
+</g>
27
+<g>
28
+</g>
29
+<g>
30
+</g>
31
+<g>
32
+</g>
33
+<g>
34
+</g>
35
+<g>
36
+</g>
37
+<g>
38
+</g>
39
+<g>
40
+</g>
41
+<g>
42
+</g>
43
+<g>
44
+</g>
45
+<g>
46
+</g>
47
+<g>
48
+</g>
49
+</svg>

+ 49
- 0
public/img/ligthbox/prev.svg ファイルの表示

@@ -0,0 +1,49 @@
1
+<?xml version="1.0" encoding="iso-8859-1"?>
2
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
3
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 240.823 240.823" style="enable-background:new 0 0 240.823 240.823;" xml:space="preserve">
4
+<g>
5
+	<path id="Chevron_Right" d="M57.633,129.007L165.93,237.268c4.752,4.74,12.451,4.74,17.215,0c4.752-4.74,4.752-12.439,0-17.179   l-99.707-99.671l99.695-99.671c4.752-4.74,4.752-12.439,0-17.191c-4.752-4.74-12.463-4.74-17.215,0L57.621,111.816   C52.942,116.507,52.942,124.327,57.633,129.007z" fill="#FFFFFF"/>
6
+	<g>
7
+	</g>
8
+	<g>
9
+	</g>
10
+	<g>
11
+	</g>
12
+	<g>
13
+	</g>
14
+	<g>
15
+	</g>
16
+	<g>
17
+	</g>
18
+</g>
19
+<g>
20
+</g>
21
+<g>
22
+</g>
23
+<g>
24
+</g>
25
+<g>
26
+</g>
27
+<g>
28
+</g>
29
+<g>
30
+</g>
31
+<g>
32
+</g>
33
+<g>
34
+</g>
35
+<g>
36
+</g>
37
+<g>
38
+</g>
39
+<g>
40
+</g>
41
+<g>
42
+</g>
43
+<g>
44
+</g>
45
+<g>
46
+</g>
47
+<g>
48
+</g>
49
+</svg>

+ 15
- 15
src/components/home/carouselSection.vue ファイルの表示

@@ -13,16 +13,16 @@
13 13
                 <div class="col-lg-8">
14 14
                   <div class="intro-body">
15 15
                     <p class="intro-title-top">
16
-                      Doral, Florida
17
-                      <br />78345
16
+                      Mooikloof, Pretoria
17
+                      <br />0081
18 18
                     </p>
19 19
                     <h1 class="intro-title mb-4">
20
-                      <span class="color-b">204</span> Mount
21
-                      <br />Olive Road Two
20
+                      <span class="color-b">10</span> Jollify
21
+                      <br />Main Road
22 22
                     </h1>
23 23
                     <p class="intro-subtitle intro-price">
24 24
                       <a href="#">
25
-                        <span class="price-a">rent | $ 12.000</span>
25
+                        <span class="price-a">rent | R 12 000</span>
26 26
                       </a>
27 27
                     </p>
28 28
                   </div>
@@ -44,16 +44,16 @@
44 44
                 <div class="col-lg-8">
45 45
                   <div class="intro-body">
46 46
                     <p class="intro-title-top">
47
-                      Doral, Florida
48
-                      <br />78345
47
+                      R303, Koue Bokkeveld, Cederberg
48
+                      <br />6836
49 49
                     </p>
50 50
                     <h1 class="intro-title mb-4">
51
-                      <span class="color-b">204</span> Rino
52
-                      <br />Venda Road Five
51
+                      <span class="color-b">Kagga</span> Kamma
52
+                      <br />
53 53
                     </h1>
54 54
                     <p class="intro-subtitle intro-price">
55 55
                       <a href="#">
56
-                        <span class="price-a">rent | $ 12.000</span>
56
+                        <span class="price-a">rent | R 12 000</span>
57 57
                       </a>
58 58
                     </p>
59 59
                   </div>
@@ -75,16 +75,16 @@
75 75
                 <div class="col-lg-8">
76 76
                   <div class="intro-body">
77 77
                     <p class="intro-title-top">
78
-                      Doral, Florida
79
-                      <br />78345
78
+                      Farm Whisky, Tenbosch Road, Komatiepoort
79
+                      <br />1340
80 80
                     </p>
81 81
                     <h1 class="intro-title mb-4">
82
-                      <span class="color-b">204</span> Alira
83
-                      <br />Roan Road One
82
+                      <span class="color-b">Ngwenya</span> Lodge
83
+                      <br />
84 84
                     </h1>
85 85
                     <p class="intro-subtitle intro-price">
86 86
                       <a href="#">
87
-                        <span class="price-a">rent | $ 12.000</span>
87
+                        <span class="price-a">rent | R 12 000</span>
88 88
                       </a>
89 89
                     </p>
90 90
                   </div>

+ 12
- 3
src/components/property/propertyCard.vue ファイルの表示

@@ -19,6 +19,15 @@
19 19
                   class="link-a"
20 20
                 >{{ currentProperty.shortDescription }}</router-link>
21 21
               </h4>
22
+              <h4 class="card-title-c">
23
+                <router-link :to="`/property/property/${currentProperty.id}`" class="link-a">
24
+                  {{ currentProperty.province }}
25
+                  <br />
26
+                  {{ currentProperty.city }}
27
+                  <br />
28
+                  {{ currentProperty.suburb }}
29
+                </router-link>
30
+              </h4>
22 31
             </div>
23 32
             <div class="card-body-a">
24 33
               <div class="price-box d-flex">
@@ -67,7 +76,7 @@
67 76
 <script>
68 77
 export default {
69 78
   props: {
70
-    properties: Object
71
-  }
79
+    properties: Object,
80
+  },
72 81
 };
73
-</script>
82
+</script>

+ 11
- 7
src/components/property/propertyImage.vue ファイルの表示

@@ -15,7 +15,7 @@
15 15
     </div>
16 16
     <br />
17 17
     <div class="form-group row">
18
-      <div v-for="img in image" class="col-md-2">
18
+      <div v-for="(img, i) in image" class="col-md-2" :key="i">
19 19
         <img :src="img" style="height:200px; width:150px; object-fit: cover;" />
20 20
         <br />
21 21
         <a class="fa fa-times del" @click="removeImage(key)" />
@@ -27,10 +27,13 @@
27 27
 
28 28
 <script>
29 29
 export default {
30
+  props: {
31
+    loadedImages: Function,
32
+  },
30 33
   data() {
31 34
     return {
32 35
       images: {},
33
-      image: []
36
+      image: [],
34 37
     };
35 38
   },
36 39
 
@@ -43,6 +46,7 @@ export default {
43 46
       if (!this.images.length) return;
44 47
 
45 48
       this.createImage(this.images);
49
+      this.loadedImages(this.image);
46 50
     },
47 51
 
48 52
     createImage(file) {
@@ -50,7 +54,7 @@ export default {
50 54
         const reader = new FileReader();
51 55
         var vm = this;
52 56
 
53
-        reader.onload = e => {
57
+        reader.onload = (e) => {
54 58
           vm.image.push(e.target.result);
55 59
           console.log(vm.image);
56 60
         };
@@ -63,9 +67,9 @@ export default {
63 67
       this.images.splice(key, 1);
64 68
 
65 69
       if (!this.image.length) {
66
-        this.$refs.im.value = "";
70
+        this.$refs.im.value = '';
67 71
       }
68
-    }
69
-  }
72
+    },
73
+  },
70 74
 };
71
-</script>
75
+</script>

+ 180
- 282
src/components/property/propertyPage.vue ファイルの表示

@@ -1,63 +1,32 @@
1 1
 <template>
2
-  <div>
2
+  <!-- eslint-disable max-len -->
3
+  <div v-if="property">
3 4
     <section class="intro-single">
4 5
       <div class="container">
5 6
         <div class="row">
6 7
           <div class="col-md-12 col-lg-8">
7 8
             <div class="title-single-box">
8
-              <h1 class="title-single">{{ Property.shortDescription }}</h1>
9
-              <span class="color-text-a">{{ Property.suburb }}</span>
9
+              <h1 class="title-single">{{ property.shortDescription }}</h1>
10 10
             </div>
11 11
           </div>
12
-          <!-- <div class="col-md-12 col-lg-4">
13
-            <nav aria-label="breadcrumb" class="breadcrumb-box d-flex justify-content-lg-end">
14
-              <ol class="breadcrumb">
15
-                <li class="breadcrumb-item">
16
-                  <a href="index.html">Home</a>
17
-                </li>
18
-                <li class="breadcrumb-item">
19
-                  <a href="property-grid.html">Properties</a>
20
-                </li>
21
-                <li class="breadcrumb-item active" aria-current="page">304 Blaster Up</li>
22
-              </ol>
23
-            </nav>
24
-          </div>-->
25 12
         </div>
26 13
       </div>
27 14
     </section>
28 15
     <!--/ Intro Single End /-->
29 16
 
30
-    <!--/ Property Single Star /-->
17
+    <!--/ property Single Star /-->
31 18
     <section class="property-single nav-arrow-b">
32 19
       <div class="container">
20
+        <div class="row">
21
+          <lightBox
22
+            :thumbnails="propertyImages"
23
+            :largeImages="propertyImages"
24
+            :caption="false"
25
+            class="lightBox"
26
+          />
27
+        </div>
33 28
         <div class="row">
34 29
           <div class="col-sm-12">
35
-            <div id="property-single-carousel" class="owl-carousel owl-arrow gallery-property">
36
-              <div class="carousel-item-b">
37
-                <img
38
-                  :src="propertyImages[0]"
39
-                  style="height:800px; width:1200px; object-fit: cover;"
40
-                />
41
-              </div>
42
-              <div class="carousel-item-b">
43
-                <img
44
-                  :src="propertyImages[1]"
45
-                  style="height:800px; width:1200px; object-fit: cover;"
46
-                />
47
-              </div>
48
-              <div class="carousel-item-b">
49
-                <img
50
-                  :src="propertyImages[2]"
51
-                  style="height:800px; width:1200px; object-fit: cover;"
52
-                />
53
-              </div>
54
-              <div class="carousel-item-b">
55
-                <img
56
-                  :src="propertyImages[3]"
57
-                  style="height:800px; width:1200px; object-fit: cover;"
58
-                />
59
-              </div>
60
-            </div>
61 30
             <div class="row justify-content-between">
62 31
               <div class="col-md-7 col-lg-7 section-md-t3">
63 32
                 <div class="row">
@@ -67,8 +36,8 @@
67 36
                     </div>
68 37
                   </div>
69 38
                 </div>
70
-                <div class="property-description" v-html="Property.description" />
71
-                <div v-for="display in Property.displayData">
39
+                <div class="property-description" v-html="property.description" />
40
+                <div v-for="display in property.displayData" :key="display.id">
72 41
                   <div class="row section-t3">
73 42
                     <div class="col-sm-12">
74 43
                       <div class="title-box-d">
@@ -77,7 +46,7 @@
77 46
                     </div>
78 47
                   </div>
79 48
                   <div class="summary-list">
80
-                    <ul class="list" v-for="item in display.values">
49
+                    <ul class="list" v-for="item in display.values" :key="item.id">
81 50
                       <li class="d-flex justify-content-between">
82 51
                         <strong>{{ item.name }}:</strong>
83 52
                         <span v-html="item.value"></span>
@@ -93,15 +62,15 @@
93 62
                       <span class="ion-money">R</span>
94 63
                     </div>
95 64
                     <div class="card-title-c align-self-center">
96
-                      <h5 class="title-c">{{ Property.price }}</h5>
65
+                      <h5 class="title-c">{{ formatPrice(property.price) }}</h5>
97 66
                     </div>
98 67
                   </div>
99 68
                 </div>
100 69
                 <div class="property-summary">
101
-                  <!-- <div class="row">
70
+                  <div class="row">
102 71
                     <div class="col-sm-12">
103 72
                       <div class="title-box-d section-t4">
104
-                        <h3 class="title-d">Quick Summary</h3>
73
+                        <h3 class="title-d">Summary</h3>
105 74
                       </div>
106 75
                     </div>
107 76
                   </div>
@@ -109,236 +78,142 @@
109 78
                     <ul class="list">
110 79
                       <li class="d-flex justify-content-between">
111 80
                         <strong>Property ID:</strong>
112
-                        <span>1134</span>
113
-                      </li>
114
-                      <li class="d-flex justify-content-between">
115
-                        <strong>Location:</strong>
116
-                        <span>Chicago, IL 606543</span>
117
-                      </li>
118
-                      <li class="d-flex justify-content-between">
119
-                        <strong>Property Type:</strong>
120
-                        <span>House</span>
81
+                        <span>{{ property.id }}</span>
121 82
                       </li>
122 83
                       <li class="d-flex justify-content-between">
123 84
                         <strong>Status:</strong>
124
-                        <span>Sale</span>
125
-                      </li>
126
-                      <li class="d-flex justify-content-between">
127
-                        <strong>Area:</strong>
128
-                        <span>
129
-                          340m
130
-                          <sup>2</sup>
131
-                        </span>
132
-                      </li>
133
-                      <li class="d-flex justify-content-between">
134
-                        <strong>Beds:</strong>
135
-                        <span>4</span>
85
+                        <span v-if="property.isSale">Sale</span>
86
+                        <span v-else>Rental</span>
136 87
                       </li>
137 88
                       <li class="d-flex justify-content-between">
138
-                        <strong>Baths:</strong>
139
-                        <span>2</span>
140
-                      </li>
141
-                      <li class="d-flex justify-content-between">
142
-                        <strong>Garage:</strong>
143
-                        <span>1</span>
144
-                      </li>
145
-                    </ul>
146
-                  </div>-->
147
-                </div>
148
-              </div>
149
-            </div>
150
-          </div>
151
-          <div class="col-md-10 offset-md-1">
152
-            <ul class="nav nav-pills-a nav-pills mb-3 section-t3" id="pills-tab" role="tablist">
153
-              <li class="nav-item">
154
-                <a
155
-                  class="nav-link active"
156
-                  id="pills-video-tab"
157
-                  data-toggle="pill"
158
-                  href="#pills-video"
159
-                  role="tab"
160
-                  aria-controls="pills-video"
161
-                  aria-selected="true"
162
-                >Video</a>
163
-              </li>
164
-              <li class="nav-item">
165
-                <a
166
-                  class="nav-link"
167
-                  id="pills-plans-tab"
168
-                  data-toggle="pill"
169
-                  href="#pills-plans"
170
-                  role="tab"
171
-                  aria-controls="pills-plans"
172
-                  aria-selected="false"
173
-                >Floor Plans</a>
174
-              </li>
175
-              <li class="nav-item">
176
-                <a
177
-                  class="nav-link"
178
-                  id="pills-map-tab"
179
-                  data-toggle="pill"
180
-                  href="#pills-map"
181
-                  role="tab"
182
-                  aria-controls="pills-map"
183
-                  aria-selected="false"
184
-                >Ubication</a>
185
-              </li>
186
-            </ul>
187
-            <div class="tab-content" id="pills-tabContent">
188
-              <div
189
-                class="tab-pane fade show active"
190
-                id="pills-video"
191
-                role="tabpanel"
192
-                aria-labelledby="pills-video-tab"
193
-              >
194
-                <iframe
195
-                  src="https://player.vimeo.com/video/73221098"
196
-                  width="100%"
197
-                  height="460"
198
-                  frameborder="0"
199
-                  webkitallowfullscreen
200
-                  mozallowfullscreen
201
-                  allowfullscreen
202
-                ></iframe>
203
-              </div>
204
-              <div
205
-                class="tab-pane fade"
206
-                id="pills-plans"
207
-                role="tabpanel"
208
-                aria-labelledby="pills-plans-tab"
209
-              >
210
-                <img src="img/plan2.jpg" alt class="img-fluid" />
211
-              </div>
212
-              <div
213
-                class="tab-pane fade"
214
-                id="pills-map"
215
-                role="tabpanel"
216
-                aria-labelledby="pills-map-tab"
217
-              >
218
-                <iframe
219
-                  src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3022.1422937950147!2d-73.98731968482413!3d40.75889497932681!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x89c25855c6480299%3A0x55194ec5a1ae072e!2sTimes+Square!5e0!3m2!1ses-419!2sve!4v1510329142834"
220
-                  width="100%"
221
-                  height="460"
222
-                  frameborder="0"
223
-                  style="border:0"
224
-                  allowfullscreen
225
-                ></iframe>
226
-              </div>
227
-            </div>
228
-          </div>
229
-          <div class="col-md-12">
230
-            <div class="row section-t3">
231
-              <div class="col-sm-12">
232
-                <div class="title-box-d">
233
-                  <h3 class="title-d">Contact Agent</h3>
234
-                </div>
235
-              </div>
236
-            </div>
237
-            <div class="row">
238
-              <div class="col-md-6 col-lg-4">
239
-                <img src="img/agent-4.jpg" alt class="img-fluid" />
240
-              </div>
241
-              <div class="col-md-6 col-lg-4">
242
-                <div class="property-agent">
243
-                  <h4 class="title-agent">Anabella Geller</h4>
244
-                  <p class="color-text-a">
245
-                    Nulla porttitor accumsan tincidunt. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet
246
-                    dui. Quisque velit nisi,
247
-                    pretium ut lacinia in, elementum id enim.
248
-                  </p>
249
-                  <ul class="list-unstyled">
250
-                    <li class="d-flex justify-content-between">
251
-                      <strong>Phone:</strong>
252
-                      <span class="color-text-a">(222) 4568932</span>
253
-                    </li>
254
-                    <li class="d-flex justify-content-between">
255
-                      <strong>Mobile:</strong>
256
-                      <span class="color-text-a">777 287 378 737</span>
257
-                    </li>
258
-                    <li class="d-flex justify-content-between">
259
-                      <strong>Email:</strong>
260
-                      <span class="color-text-a">annabella@example.com</span>
261
-                    </li>
262
-                    <li class="d-flex justify-content-between">
263
-                      <strong>Skype:</strong>
264
-                      <span class="color-text-a">Annabela.ge</span>
265
-                    </li>
266
-                  </ul>
267
-                  <div class="socials-a">
268
-                    <ul class="list-inline">
269
-                      <li class="list-inline-item">
270
-                        <a href="#">
271
-                          <i class="fa fa-facebook" aria-hidden="true"></i>
272
-                        </a>
273
-                      </li>
274
-                      <li class="list-inline-item">
275
-                        <a href="#">
276
-                          <i class="fa fa-twitter" aria-hidden="true"></i>
277
-                        </a>
278
-                      </li>
279
-                      <li class="list-inline-item">
280
-                        <a href="#">
281
-                          <i class="fa fa-instagram" aria-hidden="true"></i>
282
-                        </a>
283
-                      </li>
284
-                      <li class="list-inline-item">
285
-                        <a href="#">
286
-                          <i class="fa fa-pinterest-p" aria-hidden="true"></i>
287
-                        </a>
288
-                      </li>
289
-                      <li class="list-inline-item">
290
-                        <a href="#">
291
-                          <i class="fa fa-dribbble" aria-hidden="true"></i>
292
-                        </a>
89
+                        <strong>Address:</strong>
90
+                        <span
91
+                          v-html="formatAddress(property.addressLine1) + formatAddress(property.addressLine2) + formatAddress(property.addressLine3) + formatAddress(property.suburb.description) + formatAddress(property.city.description) + formatAddress(property.province.description) "
92
+                        ></span>
293 93
                       </li>
294 94
                     </ul>
295 95
                   </div>
296 96
                 </div>
297
-              </div>
298
-              <div class="col-md-12 col-lg-4">
299
-                <div class="property-contact">
300
-                  <form class="form-a">
301
-                    <div class="row">
302
-                      <div class="col-md-12 mb-1">
303
-                        <div class="form-group">
304
-                          <input
305
-                            type="text"
306
-                            class="form-control form-control-lg form-control-a"
307
-                            id="inputName"
308
-                            placeholder="Name *"
309
-                            required
310
-                          />
311
-                        </div>
312
-                      </div>
313
-                      <div class="col-md-12 mb-1">
314
-                        <div class="form-group">
315
-                          <input
316
-                            type="email"
317
-                            class="form-control form-control-lg form-control-a"
318
-                            id="inputEmail1"
319
-                            placeholder="Email *"
320
-                            required
321
-                          />
322
-                        </div>
97
+                <div class="col-md-12">
98
+                  <div class="row section-t3">
99
+                    <div class="col-sm-12">
100
+                      <div class="title-box-d">
101
+                        <h3 class="title-d">Contact Agent</h3>
323 102
                       </div>
324
-                      <div class="col-md-12 mb-1">
325
-                        <div class="form-group">
326
-                          <textarea
327
-                            id="textMessage"
328
-                            class="form-control"
329
-                            placeholder="Comment *"
330
-                            name="message"
331
-                            cols="45"
332
-                            rows="8"
333
-                            required
334
-                          ></textarea>
103
+                    </div>
104
+                  </div>
105
+                  <div class="row">
106
+                    <div class="col-md-12">
107
+                      <img src="img/agent-4.jpg" alt class="img-fluid" />
108
+                    </div>
109
+                  </div>
110
+                  <div class="row">
111
+                    <div class="col-md-12">
112
+                      <div class="property-agent">
113
+                        <h4 class="title-agent">Anabella Geller</h4>
114
+                        <p class="color-text-a">
115
+                          Nulla porttitor accumsan tincidunt. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet
116
+                          dui. Quisque velit nisi,
117
+                          pretium ut lacinia in, elementum id enim.
118
+                        </p>
119
+                        <ul class="list-unstyled">
120
+                          <li class="d-flex justify-content-between">
121
+                            <strong>Phone:</strong>
122
+                            <span class="color-text-a">(222) 4568932</span>
123
+                          </li>
124
+                          <li class="d-flex justify-content-between">
125
+                            <strong>Mobile:</strong>
126
+                            <span class="color-text-a">777 287 378 737</span>
127
+                          </li>
128
+                          <li class="d-flex justify-content-between">
129
+                            <strong>Email:</strong>
130
+                            <span class="color-text-a">annabella@example.com</span>
131
+                          </li>
132
+                          <li class="d-flex justify-content-between">
133
+                            <strong>Skype:</strong>
134
+                            <span class="color-text-a">Annabela.ge</span>
135
+                          </li>
136
+                        </ul>
137
+                        <div class="socials-a">
138
+                          <ul class="list-inline">
139
+                            <li class="list-inline-item">
140
+                              <a href="#">
141
+                                <i class="fa fa-facebook" aria-hidden="true"></i>
142
+                              </a>
143
+                            </li>
144
+                            <li class="list-inline-item">
145
+                              <a href="#">
146
+                                <i class="fa fa-twitter" aria-hidden="true"></i>
147
+                              </a>
148
+                            </li>
149
+                            <li class="list-inline-item">
150
+                              <a href="#">
151
+                                <i class="fa fa-instagram" aria-hidden="true"></i>
152
+                              </a>
153
+                            </li>
154
+                            <li class="list-inline-item">
155
+                              <a href="#">
156
+                                <i class="fa fa-pinterest-p" aria-hidden="true"></i>
157
+                              </a>
158
+                            </li>
159
+                            <li class="list-inline-item">
160
+                              <a href="#">
161
+                                <i class="fa fa-dribbble" aria-hidden="true"></i>
162
+                              </a>
163
+                            </li>
164
+                          </ul>
335 165
                         </div>
336 166
                       </div>
337
-                      <div class="col-md-12">
338
-                        <button type="submit" class="btn btn-a">Send Message</button>
167
+                    </div>
168
+                  </div>
169
+                  <div class="row">
170
+                    <div class="col-md-12">
171
+                      <div class="property-contact">
172
+                        <form class="form-a">
173
+                          <div class="row">
174
+                            <div class="col-md-12 mb-1">
175
+                              <div class="form-group">
176
+                                <input
177
+                                  type="text"
178
+                                  class="form-control form-control-lg form-control-a"
179
+                                  id="inputName"
180
+                                  placeholder="Name *"
181
+                                  required
182
+                                />
183
+                              </div>
184
+                            </div>
185
+                            <div class="col-md-12 mb-1">
186
+                              <div class="form-group">
187
+                                <input
188
+                                  type="email"
189
+                                  class="form-control form-control-lg form-control-a"
190
+                                  id="inputEmail1"
191
+                                  placeholder="Email *"
192
+                                  required
193
+                                />
194
+                              </div>
195
+                            </div>
196
+                            <div class="col-md-12 mb-1">
197
+                              <div class="form-group">
198
+                                <textarea
199
+                                  id="textMessage"
200
+                                  class="form-control"
201
+                                  placeholder="Comment *"
202
+                                  name="message"
203
+                                  cols="45"
204
+                                  rows="8"
205
+                                  required
206
+                                ></textarea>
207
+                              </div>
208
+                            </div>
209
+                            <div class="col-md-12">
210
+                              <button type="submit" class="btn btn-a">Send Message</button>
211
+                            </div>
212
+                          </div>
213
+                        </form>
339 214
                       </div>
340 215
                     </div>
341
-                  </form>
216
+                  </div>
342 217
                 </div>
343 218
               </div>
344 219
             </div>
@@ -350,25 +225,48 @@
350 225
 </template>
351 226
 
352 227
 <script>
228
+import { mapState, mapActions } from 'vuex';
229
+import lightBox from '../shared/lightBoxGallery.vue';
230
+
353 231
 export default {
354
-  name: "Property",
232
+  name: 'property',
233
+  components: {
234
+    lightBox,
235
+  },
355 236
   data() {
356
-    return {
357
-      Property: {},
358
-      propertyImages: []
359
-    };
237
+    return {};
238
+  },
239
+  mounted() {
240
+    this.getProperty(Object.assign({}, { id: this.$route.params.id }));
241
+    this.getPropertyImages(Object.assign({}, { id: this.$route.params.id }));
242
+  },
243
+  computed: {
244
+    ...mapState('property', ['property', 'propertyImages']),
245
+  },
246
+  methods: {
247
+    ...mapActions('property', ['getProperty', 'getPropertyImages']),
248
+    formatPrice(value) {
249
+      const val = (value / 1).toFixed(2);
250
+      return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
251
+    },
252
+    formatAddress(value) {
253
+      if (value !== '') {
254
+        return `${value}<br/>`;
255
+      }
256
+      return '';
257
+    },
360 258
   },
361
-  created() {
362
-    const axios = require("axios");
363
-    axios
364
-      .get(`http://localhost:57260/Property/Property/${this.$route.params.id}`)
365
-      .then(response => (this.Property = response.data));
366
-
367
-    axios
368
-      .get(
369
-        `http://localhost:57260/property/PropertyImage/getpropertyimages/${this.$route.params.id}`
370
-      )
371
-      .then(response => (this.propertyImages = response.data));
372
-  }
373 259
 };
374 260
 </script>
261
+
262
+<style lang ="scss">
263
+.light-box {
264
+  &__thumbnail {
265
+    margin: 20px;
266
+    width: 200px;
267
+  }
268
+}
269
+img {
270
+  max-width: 100%;
271
+}
272
+</style>

+ 148
- 0
src/components/property/propertySearchFields.vue ファイルの表示

@@ -0,0 +1,148 @@
1
+<template>
2
+  <div>
3
+    <div class="col-md-6 mb-2">
4
+      <div class="form-group">
5
+        <label for="city">For:</label>
6
+        <select
7
+          class="form-control form-control-lg form-control-a"
8
+          id="forSelector"
9
+          v-model="selectedType"
10
+          @change="TypeSelected"
11
+        >
12
+          <option value="Sale">Sale</option>
13
+          <option value="Rent">Rent</option>
14
+        </select>
15
+      </div>
16
+      <div class="form-group" v-if="propertyType === 'Residential'">
17
+        <label for="city">Property Type</label>
18
+        <select
19
+          class="form-control form-control-lg form-control-a"
20
+          id="forSelector"
21
+          v-model="selectedPropertyTypeRes"
22
+          @change="PropertyTypeSelected"
23
+        >
24
+          <option>All</option>
25
+          <option
26
+            v-for="(propertyType, i) in propertyTypesRes"
27
+            :key="i"
28
+          >{{ propertyType.description }}</option>
29
+        </select>
30
+      </div>
31
+      <div v-else class="form-group">
32
+        <label for="city">Property Type</label>
33
+        <select
34
+          class="form-control form-control-lg form-control-a"
35
+          id="forSelector"
36
+          v-model="selectedPropertyTypeCom"
37
+          @change="PropertyTypeSelected"
38
+        >
39
+          <option>All</option>
40
+          <option
41
+            v-for="(propertyType, i) in propertyTypesCom"
42
+            :key="i"
43
+          >{{ propertyType.description }}</option>
44
+        </select>
45
+      </div>
46
+      <div class="form-group">
47
+        <label for="city">Provice</label>
48
+        <select
49
+          class="form-control form-control-lg form-control-a"
50
+          id="provinceselector"
51
+          @change="ProvinceSelected"
52
+          v-model="selectedProvince"
53
+        >
54
+          <option>All</option>
55
+          <option v-for="(province, i) in provinces" :key="i">{{ province.description }}</option>
56
+        </select>
57
+      </div>
58
+    </div>
59
+    <div class="col-md-6 mb-2">
60
+      <div class="form-group">
61
+        <label for="city">City</label>
62
+        <select
63
+          class="form-control form-control-lg form-control-a"
64
+          id="cityselector"
65
+          @change="CitySelected"
66
+          v-model="selectedCity"
67
+        >
68
+          <option>All</option>
69
+          <option v-for="(city, i) in cities" :key="i">{{ city.description }}</option>
70
+        </select>
71
+      </div>
72
+    </div>
73
+    <div class="col-md-6 mb-2">
74
+      <div class="form-group">
75
+        <label for="city">Suburb</label>
76
+        <select
77
+          class="form-control form-control-lg form-control-a"
78
+          id="suburbselector"
79
+          v-model="selectedSuburb"
80
+          @change="SuburbSelected"
81
+        >
82
+          <option>All</option>
83
+          <option v-for="(suburb, i) in suburbs" :key="i">{{ suburb.description }}</option>
84
+        </select>
85
+      </div>
86
+    </div>
87
+  </div>
88
+</template>
89
+
90
+<script>
91
+import { mapState, mapActions } from 'vuex';
92
+
93
+export default {
94
+  props: {
95
+    propertyType: String,
96
+  },
97
+  data() {
98
+    return {
99
+      selectedType: 'Sale',
100
+      selectedProvince: 'All',
101
+      selectedCity: 'All',
102
+      selectedSuburb: 'All',
103
+      selectedPropertyTypeRes: 'All',
104
+      selectedPropertyTypeCom: 'All',
105
+    };
106
+  },
107
+  mounted() {
108
+    this.getProvince();
109
+    this.$emit('TypeSelectedUpdated', this.selectedType);
110
+    this.getPropertyTypesRes();
111
+    this.getPropertyTypesCom();
112
+  },
113
+  computed: {
114
+    ...mapState('searchTab', ['provinces', 'cities', 'suburbs']),
115
+    ...mapState('property', ['propertyTypesRes', 'propertyTypesCom']),
116
+  },
117
+  methods: {
118
+    ...mapActions('searchTab', ['getProvince', 'getCities', 'getSuburbs']),
119
+    ...mapActions('property', ['getPropertyTypesRes', 'getPropertyTypesCom']),
120
+    TypeSelected(item) {
121
+      this.$emit('TypeSelectedUpdated', item.target.value);
122
+    },
123
+    PropertyTypeSelected(item) {
124
+      this.$emit('PropertyTypeSelectedUpdated', item.target.value);
125
+    },
126
+    ProvinceSelected(item) {
127
+      if (item.target.value !== 'All') {
128
+        this.getCities(Object.assign({}, { province: this.selectedProvince }));
129
+      }
130
+      this.$emit('ProvinceSelectedUpdated', item.target.value);
131
+    },
132
+    CitySelected(item) {
133
+      if (item.target.value !== 'All') {
134
+        this.getSuburbs(
135
+          Object.assign(
136
+            {},
137
+            { province: this.selectedProvince, city: this.selectedCity },
138
+          ),
139
+        );
140
+      }
141
+      this.$emit('CitySelectedUpdated', item.target.value);
142
+    },
143
+    SuburbSelected(item) {
144
+      this.$emit('SuburbSelectedUpdated', item.target.value);
145
+    },
146
+  },
147
+};
148
+</script>

+ 62
- 37
src/components/property/propertySearchPage.vue ファイルの表示

@@ -8,12 +8,12 @@
8 8
     <br />
9 9
     <div>
10 10
       <propertyCard
11
-        v-if="Properties.length > 0"
11
+        v-if="properties.length > 0"
12 12
         name="propertyholder"
13
-        :properties="Properties"
13
+        :properties="properties"
14 14
         :key="propertysearch"
15 15
       />
16
-      <div v-if="Properties.length === 0">
16
+      <div v-if="properties.length === 0">
17 17
         <img src="../../../public/img/no-homes.gif" />
18 18
         <br />
19 19
         <br />
@@ -96,26 +96,35 @@
96 96
   </div>
97 97
 </template>
98 98
 <script>
99
-import propertyCard from "../property/propertyCard.vue";
100
-import { isNull } from "util";
99
+import { mkdir } from 'fs';
100
+import { mapState, mapActions } from 'vuex';
101
+import propertyCard from './propertyCard.vue';
101 102
 
102 103
 export default {
103
-  name: "propertysearch",
104
+  name: 'propertysearch',
104 105
   components: {
105
-    propertyCard
106
+    propertyCard,
106 107
   },
107 108
   data() {
108 109
     return {
109
-      Properties: [],
110
-      type: "",
111
-      propertyType: "",
112
-      propertyTypeparam: "",
113
-      province: "",
114
-      city: "",
115
-      suburb: ""
110
+      type: '',
111
+      propertyType: '',
112
+      propertyTypeparam: '',
113
+      province: '',
114
+      city: '',
115
+      suburb: '',
116
+      proptype: '',
117
+      keyword: '',
116 118
     };
117 119
   },
120
+  methods: {
121
+    ...mapActions('property', [
122
+      'searchPropertiesParams',
123
+      'searchPropertiesKeyword',
124
+    ]),
125
+  },
118 126
   computed: {
127
+    ...mapState('property', ['properties']),
119 128
     ParamsChanged() {
120 129
       this.propertyTypeparam = this.$route.params.propertyType;
121 130
       this.type = this.$route.query.type;
@@ -123,42 +132,58 @@ export default {
123 132
       this.province = this.$route.query.province;
124 133
       this.city = this.$route.query.city;
125 134
       this.suburb = this.$route.query.suburb;
135
+      this.proptype = this.$route.query.propType;
136
+      this.keyword = this.$route.query.keyword;
126 137
 
127
-      if (typeof this.propertyType === "undefined") {
138
+      if (typeof this.propertyType === 'undefined') {
128 139
         this.propertyType = this.propertyTypeparam;
129 140
       }
130 141
 
131
-      let search = "";
132
-      if (this.type !== "") {
133
-        search = search + "type:" + this.type;
142
+      if (this.type === '') {
143
+        this.type = 'undefined';
134 144
       }
135
-      if (this.propertyType !== "") {
136
-        search = search + "|propertyType:" + this.propertyType;
145
+      if (this.propertyType === '') {
146
+        this.propertyType = 'undefined';
137 147
       }
138
-      if (this.province !== "") {
139
-        search = search + "|province:" + this.province;
148
+      if (this.province === '') {
149
+        this.province = 'undefined';
140 150
       }
141
-      if (this.city !== "") {
142
-        search = search + "|city:" + this.city;
151
+      if (this.city === '') {
152
+        this.city = 'undefined';
143 153
       }
144
-      if (this.suburb !== "") {
145
-        search = search + "|suburb:" + this.suburb;
154
+      if (this.suburb === '') {
155
+        this.suburb = 'undefined';
156
+      }
157
+      if (this.proptype === '') {
158
+        this.propType = 'undefined';
159
+      }
160
+      if (typeof this.keyword === 'undefined' || this.keyword === '') {
161
+        this.searchPropertiesParams(
162
+          Object.assign(
163
+            {},
164
+            {
165
+              type: this.type,
166
+              propertyType: this.propertyType,
167
+              province: this.province,
168
+              city: this.city,
169
+              suburb: this.suburb,
170
+              propType: this.proptype,
171
+            },
172
+          ),
173
+        );
174
+      } else {
175
+        this.searchPropertiesKeyword(
176
+          Object.assign({}, { keyword: this.keyword }),
177
+        );
146 178
       }
147 179
 
148
-      console.log(search);
149
-
150
-      const axios = require("axios");
151
-      axios
152
-        .get(
153
-          `http://localhost:57260/Property/Property/Search/${this.type}/${this.propertyType}/${this.province}/${this.city}/${this.suburb}`
154
-        )
155
-        .then(response => (this.Properties = response.data));
156
-    }
180
+      return null;
181
+    },
157 182
   },
158 183
   watch: {
159 184
     ParamsChanged() {
160 185
       console.log(JSON.stringify(this.$route.query));
161
-    }
162
-  }
186
+    },
187
+  },
163 188
 };
164 189
 </script>

+ 27
- 3
src/components/property/propertyUserField.vue ファイルの表示

@@ -1,6 +1,6 @@
1 1
 <template>
2 2
   <div class="form-group row">
3
-    <div class="col-md-4 mb-2" v-for="currentField in fields">
3
+    <div class="col-md-4 mb-2" v-for="(currentField, i) in fields" :key="i">
4 4
       <label>{{ currentField.name }}</label>
5 5
       <input
6 6
         v-if="currentField.type === 'number'"
@@ -8,6 +8,8 @@
8 8
         type="number"
9 9
         name="currentField.name"
10 10
         id="currentField.id"
11
+        v-model="setFields[i]"
12
+        @change="UpdateSetFields(currentField, i)"
11 13
       />
12 14
       <input
13 15
         v-if="currentField.type === 'text'"
@@ -15,10 +17,16 @@
15 17
         type="text"
16 18
         name="currentField.name"
17 19
         id="currentField.id"
20
+        v-model="setFields[i]"
21
+        @change="UpdateSetFields(currentField, i)"
18 22
       />
19 23
       <div v-if="currentField.type === 'yesno'">
20
-        <select class="form-control form-control-lg form-control-a" id="currentField.id">
21
-          <option>Please Select</option>
24
+        <select
25
+          class="form-control form-control-lg form-control-a"
26
+          id="currentField.id"
27
+          v-model="setFields[i]"
28
+          @change="UpdateSetFields(currentField, i)"
29
+        >
22 30
           <option value="yes">Yes</option>
23 31
           <option value="no">No</option>
24 32
         </select>
@@ -29,8 +37,24 @@
29 37
 
30 38
 <script>
31 39
 export default {
40
+  name: 'UserDefinedField',
32 41
   props: {
33 42
     fields: [],
43
+    SetFieldValue: Function,
44
+  },
45
+  data() {
46
+    return {
47
+      setFields: [],
48
+    };
49
+  },
50
+  methods: {
51
+    UpdateSetFields(field, index) {
52
+      const item = {
53
+        userDefinedFieldId: field.id,
54
+        value: this.setFields[index],
55
+      };
56
+      this.$emit('UpdateUserDefinedFields', item);
57
+    },
34 58
   },
35 59
 };
36 60
 </script>

+ 94
- 117
src/components/property/propertyeditPage.vue ファイルの表示

@@ -41,19 +41,21 @@
41 41
                 </select>
42 42
               </div>
43 43
               <div v-if="propertyType === 'Commercial'" class="col-md-4">
44
-                <label>Property Name</label>
44
+                <label for="Property Name"></label>
45 45
                 <input
46
-                  class="form-control form-control-lg form-control-a"
46
+                  class="form-control"
47 47
                   type="text"
48
+                  placeholder="Property Name"
48 49
                   name="propertyName"
49 50
                   id="propertyName"
50 51
                   v-model="property.propertyName"
51 52
                 />
52 53
               </div>
53 54
               <div v-if="propertyType === 'Commercial'" class="col-md-4">
54
-                <label>Unit</label>
55
+                <label for="Unit"></label>
55 56
                 <input
56
-                  class="form-control form-control-lg form-control-a"
57
+                  class="form-control"
58
+                  placeholder="Unit"
57 59
                   type="text"
58 60
                   name="unit"
59 61
                   id="unit"
@@ -178,26 +180,20 @@
178 180
             <div class="form-group row">
179 181
               <div class="col-md-12">
180 182
                 <label for="Property Description"></label>
181
-                <textarea
182
-                  class="form-control editor"
183
-                  placeholder="Property Description"
184
-                  name="description"
185
-                  v-model="property.description"
186
-                  id="description"
187
-                ></textarea>
183
+                <TextEditor name="description" v-model="property.description" id="description" />
188 184
                 <br />
189 185
                 <p>* A listing fee of R380 including VAT is payable to list your Property on the Uni-Vate website</p>
190 186
               </div>
191 187
             </div>
192 188
             <div class="form-group row" />
193 189
             <UserField
194
-              v-if="ApiRunning & propertyType === 'Residential'"
195
-              :fields="propValuesProp[0].fields"
190
+              v-if="propertyType === 'Residential' & propertyOverviewFields.length > 0"
191
+              :fields="propertyOverviewFields[0].fields"
196 192
               :id="overviewProps"
197 193
               @UpdateUserDefinedFields="UpdateUserDefinedFields"
198 194
             ></UserField>
199 195
             <div class="form-group row" />
200
-            <div v-for="item in propertyValues" :key="item.id">
196
+            <div v-for="item in propertyFields" :key="item.id">
201 197
               <div class="row">
202 198
                 <div class="col-sm-12">
203 199
                   <div class="title-box-d">
@@ -220,13 +216,12 @@
220 216
               </div>
221 217
             </div>
222 218
             <ImageLoad :loadedImages="loadedImages" />
223
-            <button type="button" @click="SubmitData()" class="btn btn-a">Save</button>
224
-            <!-- <router-link
225
-              to="/property/search"
226
-              @click.stop.prevent="SubmitData()"
227
-              class="btn btn-b"
228
-              tag="button"
229
-            >Save</router-link>-->
219
+            <button
220
+              type="button"
221
+              @click="SubmitData()"
222
+              class="btn btn-b-n"
223
+              style="width: 85px; height:40px;"
224
+            >Save</button>
230 225
           </form>
231 226
         </div>
232 227
       </div>
@@ -235,75 +230,69 @@
235 230
 </template>
236 231
 
237 232
 <script>
238
-import UserField from "./propertyUserField.vue";
239
-import ImageLoad from "./propertyImage.vue";
240
-// https://vuejsexamples.com/a-vue-wrapper-around-the-trix-rich-text-editor/
233
+import { mapState, mapActions } from 'vuex';
234
+import TextEditor from 'vue-trix';
235
+import UserField from './propertyUserField.vue';
236
+import ImageLoad from './propertyImage.vue';
237
+
241 238
 export default {
242
-  name: "PropertyEdit",
239
+  name: 'PropertyEdit',
243 240
   components: {
244 241
     UserField,
245
-    ImageLoad
242
+    ImageLoad,
243
+    TextEditor,
246 244
   },
247 245
   data() {
248 246
     return {
249
-      ApiRunning: true,
250
-      propertyType: "Residential",
251
-      salesType: "Rental",
252
-      imageFile: "",
253
-      provinces: [],
254
-      cities: [],
255
-      suburbs: [],
256
-      propertyValues: [],
257
-      propValuesProp: [],
258
-      propertyTypes: [],
259
-      selectedProvince: "",
260
-      selectedCity: "",
247
+      propertyType: 'Residential',
248
+      salesType: 'Rental',
249
+      selectedProvince: '',
250
+      selectedCity: '',
261 251
       property: {
262 252
         propertyTypeId: 0,
263
-        propertyName: "",
264
-        unit: "",
265
-        addressLine1: "",
266
-        addressLine2: "",
267
-        addressLine3: "",
253
+        propertyName: '',
254
+        unit: '',
255
+        addressLine1: '',
256
+        addressLine2: '',
257
+        addressLine3: '',
268 258
         suburbId: 0,
269 259
         cityId: 0,
270 260
         provinceId: 0,
271
-        price: "",
272
-        per: "",
273
-        description: "",
261
+        price: '',
262
+        per: '',
263
+        description: '',
274 264
         isSale: false,
275 265
         propertyUserFields: [],
276
-        propertyImages: []
266
+        propertyImages: [],
277 267
       },
278 268
       images: [],
279
-      propertyFieldValues: []
269
+      propertyFieldValues: [],
280 270
     };
281 271
   },
282 272
   methods: {
273
+    ...mapActions('searchTab', ['getProvince', 'getCities', 'getSuburbs']),
274
+    ...mapActions('property', [
275
+      'getPropertyTypes',
276
+      'getPropertyOverviewFields',
277
+      'getPropertyFields',
278
+      'saveProperty',
279
+    ]),
283 280
     SubmitData() {
284
-      // let isDefault = true;
285
-      // this.images.forEach((imagedata) => {
286
-      //   this.property.propertyImages.push({
287
-      //     image: imagedata,
288
-      //     isDefault,
289
-      //   });
290
-      //   isDefault = false;
291
-      // });
292
-
293
-      // this.property.propertyUserFields = this.propertyFieldValues;
281
+      let isDefault = true;
282
+      this.images.forEach((imagedata) => {
283
+        this.property.propertyImages.push({
284
+          image: imagedata,
285
+          isDefault,
286
+        });
287
+        isDefault = false;
288
+      });
289
+      this.property.propertyUserFields = this.propertyFieldValues;
294 290
 
295
-      // const axios = require('axios');
296
-      // axios
297
-      //   .post('http://localhost:57260/Property/Property', this.property)
298
-      //   .then((response) => {})
299
-      //   .catch((e) => {
300
-      //     alert(e);
301
-      //   });
291
+      this.saveProperty(Object.assign({}, { newProperty: this.property }));
302 292
 
303
-      // this.$router.push("/property/search");
304 293
       this.$router.push({
305
-        path: "/property/search",
306
-        query: { type: this.salesType, propertyType: this.propertyType }
294
+        path: '/property/search',
295
+        query: { type: this.salesType, propertyType: this.propertyType },
307 296
       });
308 297
     },
309 298
     ProvinceSelected(item) {
@@ -311,12 +300,7 @@ export default {
311 300
         this.selectedProvince = this.provinces[
312 301
           item.target.options.selectedIndex - 1
313 302
         ].description;
314
-        const axios = require("axios");
315
-        axios
316
-          .get(
317
-            `http://localhost:57260/region/city/getby/${this.selectedProvince}`
318
-          )
319
-          .then(response => (this.cities = response.data));
303
+        this.getCities(Object.assign({}, { province: this.selectedProvince }));
320 304
       }
321 305
     },
322 306
     CitySelected(item) {
@@ -324,12 +308,12 @@ export default {
324 308
         this.selectedCity = this.cities[
325 309
           item.target.options.selectedIndex - 1
326 310
         ].description;
327
-        const axios = require("axios");
328
-        axios
329
-          .get(
330
-            `http://localhost:57260/region/Suburb/${this.selectedProvince}/${this.selectedCity}`
331
-          )
332
-          .then(response => (this.suburbs = response.data));
311
+        this.getSuburbs(
312
+          Object.assign(
313
+            {},
314
+            { province: this.selectedProvince, city: this.selectedCity },
315
+          ),
316
+        );
333 317
       }
334 318
     },
335 319
     loadedImages(values) {
@@ -337,7 +321,7 @@ export default {
337 321
     },
338 322
     UpdateUserDefinedFields(item) {
339 323
       let update = false;
340
-      this.propertyFieldValues.forEach(element => {
324
+      this.propertyFieldValues.forEach((element) => {
341 325
         if (element.userDefinedFieldId === item.userDefinedFieldId) {
342 326
           element.value = item.value;
343 327
           update = true;
@@ -346,56 +330,49 @@ export default {
346 330
       if (!update) {
347 331
         this.propertyFieldValues.push(item);
348 332
       }
349
-    }
333
+    },
350 334
   },
351 335
   mounted() {
352 336
     this.propertyType = this.$route.params.propType;
353 337
     this.salesType = this.$route.params.saleType;
354 338
 
355
-    const axios = require("axios");
356
-    axios
357
-      .get("http://localhost:57260/Property/PropertyFields/Property Overview")
358
-      .then(response => (this.propValuesProp = response.data));
359
-
360
-    axios
361
-      .get(
362
-        `http://localhost:57260/property/propertyfields/Propertytype/${this.propertyType}`
363
-      )
364
-      .then(response => (this.propertyValues = response.data));
365
-
366
-    axios
367
-      .get(
368
-        `http://localhost:57260/Property/PropertyType/type/${this.propertyType}`
369
-      )
370
-      .then(response => (this.propertyTypes = response.data));
371
-
372
-    axios
373
-      .get("http://localhost:57260/region/province")
374
-      .then(response => (this.provinces = response.data));
339
+    this.getProvince();
340
+    this.getPropertyTypes(
341
+      Object.assign({}, { propertyType: this.$route.params.propType }),
342
+    );
343
+    this.getPropertyOverviewFields();
344
+    this.getPropertyFields(
345
+      Object.assign({}, { propertyType: this.$route.params.propType }),
346
+    );
375 347
   },
376 348
   computed: {
349
+    ...mapState('searchTab', ['provinces', 'cities', 'suburbs']),
350
+    ...mapState('property', [
351
+      'propertyTypes',
352
+      'propertyOverviewFields',
353
+      'propertyFields',
354
+    ]),
377 355
     SalesTypeChanged() {
356
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
378 357
       this.propertyType = this.$route.params.propType;
358
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
379 359
       this.salesType = this.$route.params.saleType;
380 360
 
381
-      const axios = require("axios");
382
-      axios
383
-        .get(
384
-          `http://localhost:57260/Property/PropertyType/type/${this.propertyType}`
385
-        )
386
-        .then(response => (this.propertyTypes = response.data));
361
+      this.getPropertyTypes(
362
+        Object.assign({}, { propertyType: this.$route.params.propType }),
363
+      );
364
+
365
+      this.getPropertyFields(
366
+        Object.assign({}, { propertyType: this.$route.params.propType }),
367
+      );
387 368
 
388
-      axios
389
-        .get(
390
-          `http://localhost:57260/property/propertyfields/Propertytype/${this.propertyType}`
391
-        )
392
-        .then(response => (this.propertyValues = response.data));
393
-    }
369
+      return this.propertyType;
370
+    },
394 371
   },
395 372
   watch: {
396 373
     SalesTypeChanged() {
397 374
       console.log(this.salesType);
398
-    }
399
-  }
375
+    },
376
+  },
400 377
 };
401
-</script>
378
+</script>

+ 201
- 0
src/components/shared/lightBoxGallery.vue ファイルの表示

@@ -0,0 +1,201 @@
1
+<template>
2
+  <div class="scrolling-wrapper">
3
+    <img
4
+      @click="lightboxEffect(index)"
5
+      v-for="(thumbnail, index) in thumbnails"
6
+      :key="thumbnail"
7
+      :src="thumbnail"
8
+      style="height:150px; width:150px; object-fit: cover;"
9
+      class="light-box__thumbnail"
10
+    />
11
+    <transition name="fade" mode="out-in">
12
+      <div @click.stop="bg = !bg" class="light-box__bg" v-if="bg"></div>
13
+    </transition>
14
+
15
+    <div v-if="bg">
16
+      <div class="light-box__close" @click.stop="bg = !bg"></div>
17
+      <p class="light-box__count" v-if="count">
18
+        {{currentImage + 1 }}/
19
+        <span>{{ thumbnails.length}}</span>
20
+      </p>
21
+      <div @click="prev" class="light-box__prev light-box__btn"></div>
22
+
23
+      <div v-if="bg" class="light-box__container">
24
+        <transition name="fade" mode="out-in">
25
+          <img
26
+            :key="currentImage"
27
+            :src="largeImages[currentImage]"
28
+            class="light-box__container__img"
29
+          />
30
+        </transition>
31
+      </div>
32
+
33
+      <div class="light-box__caption" v-if="caption">
34
+        <p v-if="captions[currentImage]">{{ captions[currentImage]}}</p>
35
+      </div>
36
+
37
+      <div @click="next" class="light-box__next light-box__btn"></div>
38
+    </div>
39
+  </div>
40
+</template>
41
+
42
+<script>
43
+export default {
44
+  data() {
45
+    return {
46
+      bg: false,
47
+      currentImage: 0,
48
+      count: true
49
+    };
50
+  },
51
+  props: {
52
+    thumbnails: {
53
+      type: Array,
54
+      required: true
55
+    },
56
+    largeImages: {
57
+      type: Array,
58
+      required: true
59
+    },
60
+    captions: {
61
+      type: Array,
62
+      required: true
63
+    },
64
+    thumbnailsPath: {
65
+      type: String,
66
+      required: true
67
+    },
68
+    largePath: {
69
+      type: String,
70
+      required: true
71
+    },
72
+    caption: true
73
+  },
74
+  methods: {
75
+    lightboxEffect(curr) {
76
+      this.currentImage = curr;
77
+      this.bg = !this.bg;
78
+    },
79
+    next() {
80
+      if (this.currentImage < this.largeImages.length - 1) {
81
+        // eslint-disable-next-line no-plusplus
82
+        this.currentImage++;
83
+      } else {
84
+        this.currentImage = 0;
85
+      }
86
+    },
87
+    prev() {
88
+      if (this.currentImage > 0) {
89
+        // eslint-disable-next-line no-plusplus
90
+        this.currentImage--;
91
+      } else {
92
+        this.currentImage = this.largeImages.length - 1;
93
+      }
94
+    }
95
+  }
96
+};
97
+</script>
98
+
99
+<style lang="scss">
100
+.fade-enter-active,
101
+.fade-leave-active {
102
+  transition: opacity 0.2s;
103
+}
104
+.fade-enter,
105
+.fade-leave-to {
106
+  opacity: 0;
107
+}
108
+.light-box {
109
+  &__bg {
110
+    position: fixed;
111
+    left: 0;
112
+    top: 0;
113
+    right: 0;
114
+    bottom: 0;
115
+    background-color: rgba(0, 0, 0, 0.89);
116
+    z-index: 1000;
117
+  }
118
+
119
+  &__thumbnail {
120
+    cursor: pointer;
121
+  }
122
+
123
+  &__close {
124
+    padding: 10px;
125
+    position: absolute;
126
+    right: 5px;
127
+    top: 10px;
128
+    background-image: url(../../../public/img/ligthbox/close.svg);
129
+    background-size: contain;
130
+    background-position: center;
131
+  }
132
+  &__container {
133
+    position: absolute;
134
+    z-index: 2000;
135
+    display: flex;
136
+    justify-content: center;
137
+    align-items: center;
138
+    max-width: 700px;
139
+    left: 50%;
140
+    top: 50%;
141
+    transform: translate(-50%, -50%);
142
+    min-height: 800px;
143
+    img {
144
+      align-self: center;
145
+    }
146
+  }
147
+  &__btn {
148
+    background-size: contain;
149
+    background-position: center;
150
+    align-self: center;
151
+    padding: 15px;
152
+  }
153
+
154
+  &__close,
155
+  &__btn {
156
+    cursor: pointer;
157
+  }
158
+
159
+  &__close,
160
+  &__btn,
161
+  &__caption,
162
+  &__count {
163
+    position: absolute;
164
+    z-index: 3000;
165
+  }
166
+
167
+  &__next {
168
+    background-image: url(../../../public/img/ligthbox/next.svg);
169
+    right: 20px;
170
+  }
171
+  &__prev {
172
+    background-image: url(../../../public/img/ligthbox/prev.svg);
173
+    left: 20px;
174
+  }
175
+  &__next,
176
+  &__prev {
177
+    top: 50%;
178
+    transform: translateY(-50%);
179
+  }
180
+
181
+  &__caption {
182
+    bottom: 0;
183
+    width: 100%;
184
+    height: 50px;
185
+    display: flex;
186
+    align-items: center;
187
+    color: #fff;
188
+    font-size: 20px;
189
+    justify-content: center;
190
+  }
191
+
192
+  &__count {
193
+    left: 20px;
194
+    font-size: 16px;
195
+    color: #fff;
196
+    top: 14px;
197
+    padding: 0;
198
+    margin: 0;
199
+  }
200
+}
201
+</style>

+ 117
- 92
src/components/shared/searchTab.vue ファイルの表示

@@ -5,7 +5,7 @@
5 5
       <h3 class="title-d">Search</h3>
6 6
     </div>
7 7
     <span class="close-box-collapse right-boxed ion-ios-close"></span>
8
-    <div class="box-collapse-wrap form">
8
+    <div class="box-collapse-wrap">
9 9
       <form class="form-a">
10 10
         <div class="row">
11 11
           <div class="col-md-12 mb-2">
@@ -15,123 +15,148 @@
15 15
                 type="text"
16 16
                 class="form-control form-control-lg form-control-a"
17 17
                 placeholder="Keyword"
18
+                v-model="keyword"
18 19
               />
19 20
             </div>
20 21
           </div>
21
-          <div class="col-md-4 mb-2">
22
-            <div class="form-group">
23
-              <input class="form-check-input" type="radio" name="paid" value="Yes" />
24
-              <label class="form-check-label" for="paid">Timeshare</label>
25
-            </div>
26
-          </div>
27
-          <div class="col-md-4 mb-2">
28
-            <div class="form-group">
29
-              <input class="form-check-input" type="radio" name="paid" value="Yes" />
30
-              <label class="form-check-label" for="paid">Residential</label>
31
-            </div>
32
-          </div>
33
-          <div class="col-md-4 mb-2">
34
-            <div class="form-group">
35
-              <input class="form-check-input" type="radio" name="paid" value="Yes" />
36
-              <label class="form-check-label" for="paid">Commercial</label>
37
-            </div>
38
-          </div>
39
-          <div class="col-md-6 mb-2">
40
-            <div class="form-group">
41
-              <input class="form-check-input" type="radio" name="paid" value="Yes" />
42
-              <label class="form-check-label" for="paid">Sale</label>
43
-            </div>
44
-          </div>
45
-          <div class="col-md-6 mb-2">
46
-            <div class="form-group">
47
-              <input class="form-check-input" type="radio" name="paid" value="Yes" />
48
-              <label class="form-check-label" for="paid">Rent</label>
49
-            </div>
50
-          </div>
51
-          <div class="col-md-6 mb-2">
52
-            <div class="form-group">
53
-              <label for="city">Provice</label>
54
-              <select
55
-                class="form-control form-control-lg form-control-a"
56
-                id="provinceselector"
57
-                @change="ProvinceSelected"
58
-                v-model="selectedProvince"
59
-              >
60
-                <option>All</option>
61
-                <option v-for="(province, i) in provinces" :key="i">{{ province.description }}</option>
62
-              </select>
63
-            </div>
64
-          </div>
65
-          <div class="col-md-6 mb-2">
66
-            <div class="form-group">
67
-              <label for="city">City</label>
68
-              <select
69
-                class="form-control form-control-lg form-control-a"
70
-                id="cityselector"
71
-                @change="CitySelected"
72
-                v-model="selectedCity"
22
+          <div class="col-md-12">
23
+            <ul class="nav nav-pills-a nav-pills mb-3 section-t3" id="pills-tab" role="tablist">
24
+              <li class="nav-item">
25
+                <a
26
+                  class="nav-link active"
27
+                  id="pills-video-tab"
28
+                  data-toggle="pill"
29
+                  href="#pills-video"
30
+                  role="tab"
31
+                  aria-controls="pills-video"
32
+                  aria-selected="true"
33
+                  v-on:click="updateType('Timeshare')"
34
+                >Timeshare</a>
35
+              </li>
36
+              <li class="nav-item">
37
+                <a
38
+                  class="nav-link"
39
+                  id="pills-plans-tab"
40
+                  data-toggle="pill"
41
+                  href="#pills-plans"
42
+                  role="tab"
43
+                  aria-controls="pills-plans"
44
+                  aria-selected="false"
45
+                  v-on:click="updateType('Residential')"
46
+                >Residential</a>
47
+              </li>
48
+              <li class="nav-item">
49
+                <a
50
+                  class="nav-link"
51
+                  id="pills-map-tab"
52
+                  data-toggle="pill"
53
+                  href="#pills-map"
54
+                  role="tab"
55
+                  aria-controls="pills-map"
56
+                  aria-selected="false"
57
+                  v-on:click="updateType('Commercial')"
58
+                >Commercial</a>
59
+              </li>
60
+            </ul>
61
+            <div class="tab-content" id="pills-tabContent">
62
+              <div
63
+                class="tab-pane fade show active"
64
+                id="pills-video"
65
+                role="tabpanel"
66
+                aria-labelledby="pills-video-tab"
67
+              >timeshare search</div>
68
+              <div
69
+                class="tab-pane fade"
70
+                id="pills-plans"
71
+                role="tabpanel"
72
+                aria-labelledby="pills-plans-tab"
73 73
               >
74
-                <option>All</option>
75
-                <option v-for="(city, i) in cities" :key="i">{{ city.description }}</option>
76
-              </select>
77
-            </div>
78
-          </div>
79
-          <div class="col-md-6 mb-2">
80
-            <div class="form-group">
81
-              <label for="city">Suburb</label>
82
-              <select
83
-                class="form-control form-control-lg form-control-a"
84
-                id="suburbselector"
85
-                v-model="selectedSuburb"
74
+                <propertySearch
75
+                  propertyType="Residential"
76
+                  @TypeSelectedUpdated="TypeSelectedUpdated"
77
+                  @ProvinceSelectedUpdated="ProvinceSelectedUpdated"
78
+                  @CitySelectedUpdated="CitySelectedUpdated"
79
+                  @SuburbSelectedUpdated="SuburbSelectedUpdated"
80
+                  @PropertyTypeSelectedUpdated="PropertyTypeSelectedUpdated"
81
+                />
82
+              </div>
83
+              <div
84
+                class="tab-pane fade"
85
+                id="pills-map"
86
+                role="tabpanel"
87
+                aria-labelledby="pills-map-tab"
86 88
               >
87
-                <option>All</option>
88
-                <option v-for="(suburb, i) in suburbs" :key="i">{{ suburb.description }}</option>
89
-              </select>
89
+                <propertySearch
90
+                  propertyType="Commercial"
91
+                  @TypeSelectedUpdated="TypeSelectedUpdated"
92
+                  @ProvinceSelectedUpdated="ProvinceSelectedUpdated"
93
+                  @CitySelectedUpdated="CitySelectedUpdated"
94
+                  @SuburbSelectedUpdated="SuburbSelectedUpdated"
95
+                  @PropertyTypeSelectedUpdated="PropertyTypeSelectedUpdated"
96
+                />
97
+              </div>
90 98
             </div>
91 99
           </div>
92
-
93 100
           <div class="col-md-12">
94
-            <!-- <button type="submit" class="btn btn-b">Search</button> -->
95
-            <router-link to="/property/search" class="btn btn-b" tag="button">Search</router-link>
101
+            <button type="submit" class="btn btn-b" @click="Search">Search</button>
96 102
           </div>
97 103
         </div>
98 104
       </form>
99 105
     </div>
100 106
   </div>
101 107
 </template>
108
+
102 109
 <script>
103
-import { mapState, mapActions } from 'vuex';
110
+import propertySearch from '../property/propertySearchFields.vue';
104 111
 
105 112
 export default {
113
+  components: {
114
+    propertySearch,
115
+  },
106 116
   data() {
107 117
     return {
118
+      selectedPropertyType: 'timeshare',
119
+      selectedType: '',
108 120
       selectedProvince: '',
109 121
       selectedCity: '',
110 122
       selectedSuburb: '',
123
+      selectedPropType: '',
124
+      keyword: '',
111 125
     };
112 126
   },
113
-  mounted() {
114
-    this.getProvince();
115
-  },
116
-  computed: {
117
-    ...mapState('searchTab', ['provinces', 'cities', 'suburbs']),
118
-  },
119 127
   methods: {
120
-    ...mapActions('searchTab', ['getProvince', 'getCities', 'getSuburbs']),
121
-    ProvinceSelected(item) {
122
-      if (item.target.value !== 'All') {
123
-        this.getCities(Object.assign({}, this.selectedProvince));
124
-      }
128
+    updateType(item) {
129
+      this.selectedPropertyType = item;
130
+    },
131
+    TypeSelectedUpdated(item) {
132
+      this.selectedType = item;
133
+    },
134
+    PropertyTypeSelectedUpdated(item) {
135
+      this.selectedPropType = item;
136
+    },
137
+    ProvinceSelectedUpdated(item) {
138
+      this.selectedProvince = item;
139
+    },
140
+    CitySelectedUpdated(item) {
141
+      this.selectedCity = item;
142
+    },
143
+    SuburbSelectedUpdated(item) {
144
+      this.selectedSuburb = item;
125 145
     },
126
-    CitySelected(item) {
127
-      if (item.target.value !== 'All') {
128
-        this.getSuburbs(
129
-          Object.assign(
130
-            {},
131
-            { province: this.selectedProvince, city: this.city },
132
-          ),
133
-        );
134
-      }
146
+    Search() {
147
+      // need to see how to differenciate between properties and timeshare.
148
+      this.$router.push({
149
+        path: '/property/search',
150
+        query: {
151
+          type: this.selectedType,
152
+          propertyType: this.selectedPropertyType,
153
+          province: this.selectedProvince,
154
+          city: this.selectedCity,
155
+          suburb: this.selectedSuburb,
156
+          propType: this.propertyType,
157
+          keyword: this.keyword,
158
+        },
159
+      });
135 160
     },
136 161
   },
137 162
 };

+ 6
- 2
src/components/timeshare/buy/buyPage.vue ファイルの表示

@@ -38,7 +38,7 @@
38 38
           <div class="row mb-4">
39 39
             <div class="col-md-8">
40 40
               <div class="accordion" id="accordionExample">
41
-                <div class="card" v-for="(region, r) in detailedRegion" :key="r">
41
+                <div class="card" v-for="(region, r) in regions" :key="r">
42 42
                   <a
43 43
                     class="btn btn-b-n"
44 44
                     type="button"
@@ -60,7 +60,8 @@
60 60
                     <div class="card-body">
61 61
                       <p class="mb-0" v-for="(resort, i) in region.resorts" :key="i">
62 62
                         <a
63
-                          class="text-capitalize"
63
+                          class="cursor-pointer"
64
+                          href="#"
64 65
                           @click="routerGoTo('/resort/' + resort.resortCode)"
65 66
                         >{{resort.resortName}}</a>
66 67
                         <br />
@@ -86,6 +87,9 @@ export default {
86 87
   },
87 88
   computed: {
88 89
     ...mapState('timeshareBuy', ['detailedRegion']),
90
+    regions() {
91
+      return _.sortBy(this.detailedRegion, r => r.regionName);
92
+    },
89 93
   },
90 94
   methods: {
91 95
     ...mapActions('timeshareBuy', ['getRegions']),

+ 16
- 23
src/components/timeshare/resort/resortPage.vue ファイルの表示

@@ -15,7 +15,7 @@
15 15
       <div class="myMargin">
16 16
         <div class="row">
17 17
           <div class="col-md-3">
18
-            <h2>Filter Resorts</h2>
18
+            <h3>Filter Resort</h3>
19 19
             <form
20 20
               id="mainForm"
21 21
               method="POST"
@@ -68,33 +68,19 @@
68 68
               </div>
69 69
               <div class="form-group">
70 70
                 <label>Filter Arrival Date From</label>
71
-                <input
72
-                  style="color: white;"
73
-                  class="form-control"
74
-                  type="date"
75
-                  id="fromDate"
76
-                  name="fromDate"
77
-                  placeholder="Arrival Date"
78
-                />
71
+                <input type="date" class="form-control" name="arrivaldate" value />
79 72
               </div>
80 73
               <div class="form-group">
81 74
                 <label>Filter Arrival Date To</label>
82
-                <input
83
-                  style="color: white;"
84
-                  class="form-control"
85
-                  type="date"
86
-                  id="toDate"
87
-                  name="toDate"
88
-                  placeholder="Departure Date"
89
-                />
75
+                <input type="date" class="form-control" name="arrivaldate" value />
90 76
               </div>
91 77
 
92 78
               <br />
93 79
 
94
-              <button class="btn btn-blue" type="submit">SEARCH</button>
80
+              <button class="btn btn-b-n" type="submit">Search</button>
95 81
             </form>
96 82
             <div class="col-md-12 blue-bg p-2 p-md-4">
97
-              <h2>Facilities</h2>
83
+              <h3>Facilities</h3>
98 84
               <ul>
99 85
                 <li v-for="(item, i) in resort.prUnitFacilities.split('\n')" :key="i">{{item}}</li>
100 86
               </ul>
@@ -130,10 +116,10 @@
130 116
               </tbody>
131 117
             </table>
132 118
             <div>
133
-              <div class="btn btn-primary" @click="routerGoTo('/timeshare/buy')">Back to Region</div>
119
+              <div class="btn btn-b-n" @click="routerGoTo('/timeshare/buy')">Back to Region</div>
134 120
               <hr />
135 121
             </div>
136
-            {{resort.prNotes}}
122
+            {{description}}
137 123
             <hr />
138 124
             <div class="row mb-4">
139 125
               <div class="col-md-4">
@@ -192,7 +178,7 @@
192 178
                     <small>
193 179
                       <a
194 180
                         :href="mapUrl"
195
-                        style="color:#0000FF;text-align:left"
181
+                        style="color:#60CBEB;text-align:left"
196 182
                         target="_blank"
197 183
                       >See map bigger</a>
198 184
                     </small>
@@ -225,7 +211,14 @@ export default {
225 211
     this.initResort(this.resortCode);
226 212
   },
227 213
   computed: {
228
-    ...mapState('resort', ['resort', 'image1', 'image2', 'image3', 'layout']),
214
+    ...mapState('resort', [
215
+      'resort',
216
+      'description',
217
+      'image1',
218
+      'image2',
219
+      'image3',
220
+      'layout',
221
+    ]),
229 222
     mapUrl() {
230 223
       return this.resort
231 224
         ? 'http://maps.google.com/maps?q='

+ 180
- 0
src/components/timeshare/resort/unitPage.vue ファイルの表示

@@ -0,0 +1,180 @@
1
+<template>
2
+  <section>
3
+    <section class="intro-single">
4
+      <div class="container">
5
+        <div class="row">
6
+          <div class="col-md-12 col-lg-8">
7
+            <div class="title-single-box">
8
+              <h1 class="title-single" style="text-align:left;">{{resort.prName}}</h1>
9
+            </div>
10
+          </div>
11
+        </div>
12
+      </div>
13
+    </section>
14
+    <div class="container">
15
+      <div class="row mb-4">
16
+        <div class="col-md-6">
17
+          <p>{{description}}</p>
18
+        </div>
19
+        <div class="col-md-6">
20
+          <form
21
+            id="mainForm"
22
+            method="POST"
23
+            action="/interested-timeshare/"
24
+            accept-charset="UTF-8"
25
+            enctype="multipart/form-data"
26
+          >
27
+            <div class="form-row">
28
+              <div class="col-md-6">
29
+                <label for="resortunit">Unit</label>
30
+                <input
31
+                  class="form-control"
32
+                  type="text"
33
+                  id="resort"
34
+                  name="resortunit"
35
+                  :value="week.unit"
36
+                  disabled
37
+                />
38
+              </div>
39
+              <div class="col-md-6">
40
+                <label for="resortWeek">Week</label>
41
+                <input
42
+                  class="form-control"
43
+                  type="text"
44
+                  id="week"
45
+                  name="resortWeek"
46
+                  :value="week.week"
47
+                  disabled
48
+                />
49
+              </div>
50
+            </div>
51
+            <br />
52
+            <div class="form-row">
53
+              <div class="col-md-6">
54
+                <label for="resortModule">Module</label>
55
+                <input
56
+                  class="form-control"
57
+                  type="text"
58
+                  id="module"
59
+                  name="resortModule"
60
+                  :value="week.module"
61
+                  disabled
62
+                />
63
+              </div>
64
+              <div class="col-md-6">
65
+                <label for="price">Price</label>
66
+                <input
67
+                  class="form-control"
68
+                  type="text"
69
+                  name="price"
70
+                  id="price"
71
+                  :value="'R ' + week.price"
72
+                  disabled
73
+                />
74
+              </div>
75
+            </div>
76
+            <br />
77
+            <div class="form-row">
78
+              <div class="col-md-6">
79
+                <label for="resortModule">Current Year Levy</label>
80
+                <input
81
+                  class="form-control"
82
+                  type="text"
83
+                  id="levy"
84
+                  name="levy"
85
+                  :value="'R ' + week.currentLevy"
86
+                  disabled
87
+                />
88
+              </div>
89
+            </div>
90
+            <br />
91
+            <div class="form-row">
92
+              <div class="col-md-12">
93
+                <input class="form-control" type="text" name="name" placeholder="Name" />
94
+              </div>
95
+            </div>
96
+            <br />
97
+            <div class="form-row">
98
+              <div class="col-md-12">
99
+                <input
100
+                  class="form-control"
101
+                  type="number"
102
+                  name="mobile"
103
+                  placeholder="Contact Number"
104
+                />
105
+              </div>
106
+            </div>
107
+            <br />
108
+            <div class="form-row">
109
+              <div class="col-md-12">
110
+                <input class="form-control" type="email" name="email" placeholder="Email" />
111
+              </div>
112
+            </div>
113
+            <br />
114
+
115
+            <button class="btn btn-b-c even-width mr-auto" type="submit">Enquire Now</button>
116
+
117
+            <a
118
+              class="btn btn-b-n even-width mr-auto"
119
+              href="/share-transfer-initiation-for-purchaser/"
120
+            >Make an Offer</a>
121
+
122
+            <a class="btn btn-b-c even-width mr-auto" href="javascript:history.back()">Back</a>
123
+          </form>
124
+        </div>
125
+      </div>
126
+      <div class="row mb-4">
127
+        <div class="col-md-4">
128
+          <img class="img-fluid" :src="image1" alt="Resort Image" />
129
+        </div>
130
+        <div class="col-md-4">
131
+          <img class="img-fluid" :src="image2" alt="Resort Image" />
132
+        </div>
133
+        <div class="col-md-4">
134
+          <img class="img-fluid" :src="image3" alt="Resort Image" />
135
+        </div>
136
+      </div>
137
+    </div>
138
+  </section>
139
+</template>
140
+
141
+<script>
142
+import { mapState, mapActions } from 'vuex';
143
+
144
+export default {
145
+  props: {
146
+    resortCode: {},
147
+    weekId: {},
148
+  },
149
+  mounted() {
150
+    this.initResort(this.resortCode);
151
+    this.initWeek(this.weekId);
152
+  },
153
+  computed: {
154
+    ...mapState('resort', [
155
+      'resort',
156
+      'description',
157
+      'image1',
158
+      'image2',
159
+      'image3',
160
+    ]),
161
+    ...mapState('week', ['week', 'contactDetails']),
162
+  },
163
+  methods: {
164
+    ...mapActions('resort', ['initResort']),
165
+    ...mapActions('week', ['initWeek']),
166
+  },
167
+};
168
+</script>
169
+<style scoped>
170
+.btn.btn-b-c {
171
+  background-color: #ffffff;
172
+  color: #60cbeb;
173
+  border-radius: 0;
174
+}
175
+
176
+.btn.btn-b-c:hover {
177
+  background-color: #089bf0;
178
+  color: #ffffff;
179
+}
180
+</style>

+ 52
- 8
src/components/user/registerAgencySection.vue ファイルの表示

@@ -1,6 +1,6 @@
1 1
 <template>
2 2
   <!-- eslint-disable max-len -->
3
-  <form method="POST">
3
+  <form>
4 4
     <div class="container" style="text-align:left">
5 5
       <div class="reg-page">
6 6
         <div class="regform" style="text-align:left">
@@ -10,7 +10,7 @@
10 10
             <input class="form-control" type="text" name="agencyname" placeholder="Agency Name" />
11 11
           </div>
12 12
           <div class="col-md-8" style="margin-bottom: 1em">
13
-            <eva-icon name="book" fill="lightgrey"></eva-icon>
13
+            <eva-icon name="book" fill="#60CBEB"></eva-icon>
14 14
             <input
15 15
               class="form-control"
16 16
               type="text"
@@ -19,7 +19,7 @@
19 19
             />
20 20
           </div>
21 21
           <div class="col-md-8">
22
-            <eva-icon name="clipboard" fill="lightgrey"></eva-icon>
22
+            <eva-icon name="clipboard" fill="#60CBEB"></eva-icon>
23 23
             <input
24 24
               class="form-control"
25 25
               type="text"
@@ -43,13 +43,13 @@
43 43
 
44 44
             <div class="row" style="text-align:left">
45 45
               <div class="col-md-8">
46
-                <eva-icon name="email" fill="lightgrey"></eva-icon>
46
+                <eva-icon name="email" fill="#60CBEB"></eva-icon>
47 47
                 <input class="form-control" type="text" name="email" placeholder="Email Address" />
48 48
                 <div class="form-group row"></div>
49 49
               </div>
50 50
 
51 51
               <div class="col-md-6" style="text-align:left">
52
-                <eva-icon name="smartphone" fill="lightgrey"></eva-icon>
52
+                <eva-icon name="smartphone" fill="#60CBEB"></eva-icon>
53 53
                 <input
54 54
                   class="form-control"
55 55
                   type="text"
@@ -66,16 +66,36 @@
66 66
               </div>
67 67
               <div class="col-md-7" style="margin-bottom: 1em">
68 68
                 <eva-icon name="lock" fill="#60CBEB"></eva-icon>
69
-                <input class="form-control" type="text" name="password" placeholder="Password" />
69
+                <input
70
+                  class="form-control"
71
+                  :type="isPasswordShown"
72
+                  v-model="password"
73
+                  id="password"
74
+                  placeholder="Password"
75
+                  name="password"
76
+                  value
77
+                />
70 78
               </div>
71 79
               <div class="col-md-7" style="margin-bottom: 1em">
72 80
                 <eva-icon name="lock" fill="#60CBEB"></eva-icon>
73 81
                 <input
74 82
                   class="form-control"
75
-                  type="text"
76
-                  name="confirmpassword"
83
+                  :type="isPasswordShown"
84
+                  v-model="password"
85
+                  id="password"
77 86
                   placeholder="Confirm Password"
87
+                  name="confirmpassword"
88
+                  value
78 89
                 />
90
+                <div>
91
+                  <eva-icon
92
+                    v-if="!showPassword"
93
+                    name="eye-off"
94
+                    fill="#60CBEB"
95
+                    @click="togglePassword()"
96
+                  ></eva-icon>
97
+                  <eva-icon v-else name="eye" fill="#60CBEB" @click="passwordToggled()"></eva-icon>
98
+                </div>
79 99
               </div>
80 100
             </div>
81 101
           </div>
@@ -105,6 +125,30 @@ export default {
105 125
   },
106 126
   name: 'Agency',
107 127
   components: { RegisterPage },
128
+  data() {
129
+    return {
130
+      username: '',
131
+      user: null,
132
+      isPasswordShown: 'password',
133
+      selectItems: [{ text: 'password', value: 0 }],
134
+      selectErrors: 'Some error with the field',
135
+      select: null,
136
+      textErrors: 'Some error with the field',
137
+      text: '',
138
+      showPassword: false,
139
+      password: '',
140
+    };
141
+  },
142
+  methods: {
143
+    togglePassword() {
144
+      this.showPassword = true;
145
+      this.isPasswordShown = 'text';
146
+    },
147
+    passwordToggled() {
148
+      this.showPassword = false;
149
+      this.isPasswordShown = 'password';
150
+    },
151
+  },
108 152
 };
109 153
 </script>
110 154
 

+ 50
- 6
src/components/user/registerPage.vue ファイルの表示

@@ -1,5 +1,5 @@
1 1
 <template>
2
-  <form method="POST">
2
+  <form>
3 3
     <!-- eslint-disable max-len -->
4 4
     <div class="reg-page">
5 5
       <div class="regform">
@@ -18,13 +18,13 @@
18 18
 
19 19
           <div class="row" style="text-align:left">
20 20
             <div class="col-md-8">
21
-              <eva-icon name="email" fill="lightgrey"></eva-icon>
21
+              <eva-icon name="email" fill="#60CBEB"></eva-icon>
22 22
               <input class="form-control" type="text" name="email" placeholder="Email Address" />
23 23
               <div class="form-group row"></div>
24 24
             </div>
25 25
 
26 26
             <div class="col-md-6" style="text-align:left">
27
-              <eva-icon name="smartphone" fill="lightgrey"></eva-icon>
27
+              <eva-icon name="smartphone" fill="#60CBEB"></eva-icon>
28 28
               <input
29 29
                 class="form-control"
30 30
                 type="text"
@@ -41,16 +41,36 @@
41 41
             </div>
42 42
             <div class="col-md-7" style="margin-bottom: 1em">
43 43
               <eva-icon name="lock" fill="#60CBEB"></eva-icon>
44
-              <input class="form-control" type="text" name="password" placeholder="Password" />
44
+              <input
45
+                class="form-control"
46
+                :type="isPasswordShown"
47
+                v-model="password"
48
+                id="password"
49
+                placeholder="Password"
50
+                name="password"
51
+                value
52
+              />
45 53
             </div>
46 54
             <div class="col-md-7" style="margin-bottom: 1em">
47 55
               <eva-icon name="lock" fill="#60CBEB"></eva-icon>
48 56
               <input
49 57
                 class="form-control"
50
-                type="text"
51
-                name="confirmpassword"
58
+                :type="isPasswordShown"
59
+                v-model="password"
60
+                id="password"
52 61
                 placeholder="Confirm Password"
62
+                name="confirmpassword"
63
+                value
53 64
               />
65
+              <div>
66
+                <eva-icon
67
+                  v-if="!showPassword"
68
+                  name="eye-off"
69
+                  fill="#60CBEB"
70
+                  @click="togglePassword()"
71
+                ></eva-icon>
72
+                <eva-icon v-else name="eye" fill="#60CBEB" @click="passwordToggled()"></eva-icon>
73
+              </div>
54 74
             </div>
55 75
           </div>
56 76
         </div>
@@ -74,6 +94,20 @@ export default {
74 94
     RegisterHeader: { type: String, default: undefined },
75 95
   },
76 96
   name: 'PrivateIndividual',
97
+  data() {
98
+    return {
99
+      username: '',
100
+      user: null,
101
+      isPasswordShown: 'password',
102
+      selectItems: [{ text: 'password', value: 0 }],
103
+      selectErrors: 'Some error with the field',
104
+      select: null,
105
+      textErrors: 'Some error with the field',
106
+      text: '',
107
+      showPassword: false,
108
+      password: '',
109
+    };
110
+  },
77 111
   computed: {
78 112
     Header() {
79 113
       return this.RegisterHeader
@@ -81,6 +115,16 @@ export default {
81 115
         : 'Private Individual';
82 116
     },
83 117
   },
118
+  methods: {
119
+    togglePassword() {
120
+      this.showPassword = true;
121
+      this.isPasswordShown = 'text';
122
+    },
123
+    passwordToggled() {
124
+      this.showPassword = false;
125
+      this.isPasswordShown = 'password';
126
+    },
127
+  },
84 128
 };
85 129
 </script>
86 130
 

+ 7
- 0
src/router/index.js ファイルの表示

@@ -26,6 +26,7 @@ import changeLogPage from '../components/admin/status/changeLogPage.vue';
26 26
 import UnitConfiguration from '../components/admin/unitConfiguration/unitConfigurationPage.vue';
27 27
 
28 28
 import ResortPage from '../components/timeshare/resort/resortPage.vue';
29
+import UnitPage from '../components/timeshare/resort/unitPage.vue';
29 30
 
30 31
 import ContactUs from '../components/misc/contactUs.vue';
31 32
 
@@ -139,5 +140,11 @@ export default new Router({
139 140
     component: ResortPage,
140 141
     props: true,
141 142
   },
143
+  {
144
+    path: '/resort/:resortCode/:weekId',
145
+    name: 'UnitPage',
146
+    component: UnitPage,
147
+    props: true,
148
+  },
142 149
   ],
143 150
 });

+ 4
- 0
src/store/index.js ファイルの表示

@@ -8,6 +8,8 @@ import UnitConfigurationModule from './modules/timeshare/unitConfiguration';
8 8
 import TimeshareBuyModule from './modules/timeshare/buyPage';
9 9
 import SearchTabModule from './modules/searchTab';
10 10
 import ResortModule from './modules/timeshare/resort';
11
+import PropertyModule from './modules/property/property';
12
+import WeekModule from './modules/timeshare/week';
11 13
 
12 14
 Vue.use(Vuex);
13 15
 /* eslint no-param-reassign: ["error", { "props": false }] */
@@ -20,5 +22,7 @@ export default new Vuex.Store({
20 22
     timeshareBuy: TimeshareBuyModule,
21 23
     searchTab: SearchTabModule,
22 24
     resort: ResortModule,
25
+    property: PropertyModule,
26
+    week: WeekModule,
23 27
   },
24 28
 });

+ 107
- 0
src/store/modules/property/property.js ファイルの表示

@@ -0,0 +1,107 @@
1
+import axios from 'axios';
2
+
3
+export default {
4
+  namespaced: true,
5
+  state: {
6
+    property: null,
7
+    propertyImages: [],
8
+    propertyTypes: [],
9
+    propertyTypesRes: [],
10
+    propertyTypesCom: [],
11
+    propertyOverviewFields: [],
12
+    propertyFields: [],
13
+    properties: [],
14
+  },
15
+  mutations: {
16
+    setProperty(state, property) {
17
+      state.property = property;
18
+    },
19
+    setPropertyImages(state, images) {
20
+      state.propertyImages = images;
21
+    },
22
+    setPropertyTypes(state, types) {
23
+      state.propertyTypes = types;
24
+    },
25
+    setPropertyTypesRes(state, types) {
26
+      state.propertyTypesRes = types;
27
+    },
28
+    setPropertyTypesCom(state, types) {
29
+      state.propertyTypesCom = types;
30
+    },
31
+    setPropertyOverviewFields(state, fields) {
32
+      state.propertyOverviewFields = fields;
33
+    },
34
+    setPropertyFields(state, fields) {
35
+      state.propertyFields = fields;
36
+    },
37
+    updateCurrentProperty(state, property) {
38
+      state.property = property;
39
+    },
40
+    updateSearch(state, propertySearch) {
41
+      state.properties = propertySearch;
42
+    },
43
+  },
44
+  getters: {},
45
+  actions: {
46
+    getProperty({ commit }, item) {
47
+      axios
48
+        .get(`http://localhost:57260/Property/Property/${item.id}`)
49
+        .then(result => commit('setProperty', result.data))
50
+        .catch(console.error);
51
+    },
52
+    getPropertyImages({ commit }, item) {
53
+      axios
54
+        .get(`http://localhost:57260/property/PropertyImage/getpropertyimages/${item.id}`)
55
+        .then(result => commit('setPropertyImages', result.data))
56
+        .catch(console.error);
57
+    },
58
+    getPropertyTypes({ commit }, item) {
59
+      axios
60
+        .get(`http://localhost:57260/Property/PropertyType/type/${item.propertyType}`)
61
+        .then(result => commit('setPropertyTypes', result.data))
62
+        .catch(console.error);
63
+    },
64
+    getPropertyTypesRes({ commit }) {
65
+      axios
66
+        .get('http://localhost:57260/Property/PropertyType/type/Residential')
67
+        .then(result => commit('setPropertyTypesRes', result.data))
68
+        .catch(console.error);
69
+    },
70
+    getPropertyTypesCom({ commit }) {
71
+      axios
72
+        .get('http://localhost:57260/Property/PropertyType/type/Commercial')
73
+        .then(result => commit('setPropertyTypesCom', result.data))
74
+        .catch(console.error);
75
+    },
76
+    getPropertyOverviewFields({ commit }) {
77
+      axios
78
+        .get('http://localhost:57260/Property/PropertyFields/Property Overview')
79
+        .then(response => commit('setPropertyOverviewFields', response.data));
80
+    },
81
+    getPropertyFields({ commit }, item) {
82
+      axios
83
+        .get(`http://localhost:57260/property/propertyfields/Propertytype/${item.propertyType}`)
84
+        .then(response => commit('setPropertyFields', response.data));
85
+    },
86
+    saveProperty({ commit }, item) {
87
+      axios
88
+        .post('http://localhost:57260/Property/Property', item.newProperty)
89
+        .then(result => commit('updateCurrentProperty', result.data))
90
+        .catch(console.error);
91
+    },
92
+    searchPropertiesParams({ commit }, item) {
93
+      axios
94
+        .get(
95
+          `http://localhost:57260/Property/Property/Search/${item.type}/${item.propertyType}/${item.province}/${item.city}/${item.suburb}/${item.propType}`,
96
+        )
97
+        .then(response => commit('updateSearch', response.data))
98
+        .catch(console.error);
99
+    },
100
+    searchPropertiesKeyword({ commit }, item) {
101
+      axios
102
+        .get(`http://localhost:57260/Property/Property/Search/Keyword/${item.keyword}`)
103
+        .then(response => commit('updateSearch', response.data))
104
+        .catch(console.error);
105
+    },
106
+  },
107
+};

+ 7
- 14
src/store/modules/searchTab.js ファイルの表示

@@ -20,27 +20,20 @@ export default {
20 20
   },
21 21
   getters: {},
22 22
   actions: {
23
-    getProvince({
24
-      commit,
25
-    }) {
26
-      axios.get('http://localhost:57260/region/province')
23
+    getProvince({ commit }) {
24
+      axios
25
+        .get('http://localhost:57260/region/province')
27 26
         .then(result => commit('setProvince', result.data))
28 27
         .catch(console.error);
29 28
     },
30
-    getCities({
31
-      commit,
32
-    }, province) {
29
+    getCities({ commit }, item) {
33 30
       axios
34
-        .get(`http://localhost:57260/region/city/getby/${province}`)
31
+        .get(`http://localhost:57260/region/city/getby/${item.province}`)
35 32
         .then(result => commit('setCities', result.data));
36 33
     },
37
-    getSuburbs({
38
-      commit,
39
-    }, item) {
34
+    getSuburbs({ commit }, item) {
40 35
       axios
41
-        .get(
42
-          `http://localhost:57260/region/Suburb/${item.province}/${item.city}`,
43
-        )
36
+        .get(`http://localhost:57260/region/Suburb/${item.province}/${item.city}`)
44 37
         .then(result => commit('setSuburbs', result.data));
45 38
     },
46 39
   },

+ 1
- 0
src/store/modules/timeshare/buyPage.js ファイルの表示

@@ -1,6 +1,7 @@
1 1
 /* eslint-disable no-restricted-syntax */
2 2
 /* eslint-disable guard-for-in */
3 3
 import axios from 'axios';
4
+import _ from 'lodash';
4 5
 
5 6
 export default {
6 7
   namespaced: true,

+ 16
- 0
src/store/modules/timeshare/resort.js ファイルの表示

@@ -10,11 +10,15 @@ export default {
10 10
     image2: '',
11 11
     image3: '',
12 12
     layout: '',
13
+    description: '',
13 14
   },
14 15
   mutations: {
15 16
     setResort(state, resort) {
16 17
       state.resort = resort;
17 18
     },
19
+    setDescription(state, description) {
20
+      state.description = description;
21
+    },
18 22
     clear(state) {
19 23
       state.resort = {};
20 24
       state.image1 = '';
@@ -43,11 +47,23 @@ export default {
43 47
     }, resortCode) {
44 48
       commit('clear');
45 49
       dispatch('getResort', resortCode);
50
+      dispatch('getDescription', resortCode);
46 51
       dispatch('getImage1', resortCode);
47 52
       dispatch('getImage2', resortCode);
48 53
       dispatch('getImage3', resortCode);
49 54
       dispatch('getLayout', resortCode);
50 55
     },
56
+    getDescription({
57
+      commit,
58
+    }, resortCode) {
59
+      axios.get(
60
+        `https://www.tradeunipoint.com/unibackend/seam/resource/rest/products/${resortCode}/dsc`,
61
+      )
62
+        .then((result) => {
63
+          commit('setDescription', result.data);
64
+        })
65
+        .catch(console.error);
66
+    },
51 67
     getResort({
52 68
       commit,
53 69
     }, resortCode) {

+ 42
- 0
src/store/modules/timeshare/week.js ファイルの表示

@@ -0,0 +1,42 @@
1
+/* eslint-disable no-restricted-syntax */
2
+/* eslint-disable guard-for-in */
3
+import axios from 'axios';
4
+
5
+export default {
6
+  namespaced: true,
7
+  state: {
8
+    week: {
9
+      id: '',
10
+      unit: '',
11
+      week: '',
12
+      module: '',
13
+      price: '',
14
+      currentLevy: '',
15
+    },
16
+    contactDetails: {
17
+      name: '',
18
+      number: '',
19
+      email: '',
20
+    },
21
+  },
22
+  mutations: {
23
+    setWeek(state, week) {
24
+      state.week = week;
25
+    },
26
+  },
27
+  getters: {},
28
+  actions: {
29
+    initWeek({
30
+      commit,
31
+    }, weekId) {
32
+      commit('setWeek', {
33
+        id: weekId,
34
+        unit: '359',
35
+        week: 'N18',
36
+        module: '359/N18 River View',
37
+        price: 85000,
38
+        currentLevy: 5455,
39
+      });
40
+    },
41
+  },
42
+};

読み込み中…
キャンセル
保存