George Williams 4 年前
父节点
当前提交
a3286bf02f
共有 29 个文件被更改,包括 2160 次插入140 次删除
  1. 34
    0
      public/css/newStyle.css
  2. 22
    0
      src/components/misc/Disclaimer/WebsiteDisclaimer.vue
  3. 46
    0
      src/components/misc/Disclaimer/carouselSection.vue
  4. 13
    17
      src/components/misc/Disclaimer/contentSection.vue
  5. 48
    0
      src/components/property/commercial/createProperty/carouselSection.vue
  6. 521
    0
      src/components/property/commercial/createProperty/commercialCreate.vue
  7. 46
    0
      src/components/property/commercial/enquireNow/carouselSection.vue
  8. 168
    0
      src/components/property/commercial/enquireNow/contentSection.vue
  9. 22
    0
      src/components/property/commercial/enquireNow/enquirenow.vue
  10. 28
    12
      src/components/property/commercial/singleView/contentSection.vue
  11. 106
    0
      src/components/property/mapSection.vue
  12. 35
    10
      src/components/property/propertyImage.vue
  13. 18
    15
      src/components/property/propertyUserField.vue
  14. 48
    0
      src/components/property/residential/createProperty/carouselSection.vue
  15. 533
    0
      src/components/property/residential/createProperty/residentialCreate.vue
  16. 2
    3
      src/components/property/residential/latestListings.vue
  17. 68
    29
      src/components/property/residential/singleView/contentSection.vue
  18. 11
    1
      src/components/property/residential/singleView/singleResidentialPage.vue
  19. 0
    37
      src/components/propertyManagement/ourServicesSection.vue
  20. 3
    3
      src/components/propertyManagement/rentalManagement/carouselSection.vue
  21. 86
    0
      src/components/propertyManagement/rentalManagement/contentSection.vue
  22. 34
    0
      src/components/propertyManagement/rentalManagement/rentalPropertyManagement.vue
  23. 64
    0
      src/components/propertyManagement/sectionalTitle/carouselSection.vue
  24. 113
    0
      src/components/propertyManagement/sectionalTitle/ourServicesSection.vue
  25. 1
    1
      src/components/propertyManagement/sectionalTitle/propertyManagement.vue
  26. 56
    6
      src/components/shared/navBar.vue
  27. 2
    0
      src/components/timeshare/resort/contentSection.vue
  28. 30
    4
      src/router/index.js
  29. 2
    2
      vue.config.js

+ 34
- 0
public/css/newStyle.css 查看文件

@@ -39,6 +39,40 @@
39 39
   font-family: "muli";
40 40
   font-size: 15px;
41 41
   color: rgb(118, 118, 118);
42
+  pointer-events: none;
43
+  text-transform: uppercase;
44
+}
45
+
46
+.quillWrapper .ql-snow.ql-toolbar {
47
+  border-left-width: 2px;
48
+  border-top-width: 2px;
49
+  border-right-width: 2px;
50
+  border-left-color: #1b75bb;
51
+  border-top-color: #1b75bb;
52
+  border-right-color: #1b75bb;
53
+  font-family: "Muli";
54
+}
55
+
56
+.ql-toolbar.ql-snow + .ql-container.ql-snow {
57
+  border-left-width: 2px;
58
+  border-bottom-width: 2px;
59
+  border-right-width: 2px;
60
+  border-left-color: #1b75bb;
61
+  border-bottom-color: #1b75bb;
62
+  border-right-color: #1b75bb;
63
+  font-family: "Muli";
64
+  font-size: 15px;
65
+  font-weight: 400;
66
+}
67
+
68
+.uniInput {
69
+  border-width: 2px;
70
+  border-color: #1b75bb;
71
+  padding: 10px 14px;
72
+  box-shadow: none;
73
+  font-size: 15px;
74
+  font-weight: 400;
75
+  font-family: "Muli";
42 76
 }
43 77
 
44 78
 body {

+ 22
- 0
src/components/misc/Disclaimer/WebsiteDisclaimer.vue 查看文件

@@ -0,0 +1,22 @@
1
+<template>
2
+  <div>
3
+    <carouselSection />
4
+    <main id="main" style="margin-top:-20px;padding-bottom:50px">
5
+      <contentSection />
6
+    </main>
7
+  </div>
8
+</template>
9
+
10
+<script>
11
+/* eslint-disable */
12
+import carouselSection from "./carouselSection";
13
+import contentSection from "./contentSection";
14
+export default {
15
+  components: {
16
+    carouselSection,
17
+    contentSection
18
+  }
19
+};
20
+</script>
21
+
22
+<style lang="scss" scoped></style>

+ 46
- 0
src/components/misc/Disclaimer/carouselSection.vue 查看文件

@@ -0,0 +1,46 @@
1
+<template>
2
+  <section id="intro">
3
+    <div class="container">
4
+      <div class="row">
5
+        <div align="left" class="col-sm-12 col-md-8">
6
+          <div class="intro-content box">
7
+            <h2>Website Dislcaimer</h2>
8
+          </div>
9
+        </div>
10
+      </div>
11
+    </div>
12
+
13
+    <carousel
14
+      :nav="false"
15
+      :dots="false"
16
+      :items="1"
17
+      :autoplay="true"
18
+      :loop="true"
19
+      id="intro-carousel"
20
+      style="margin-top:-50px"
21
+      :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
22
+    >
23
+      <img class="item" src="/img/intro-carousel/home-1.jpg" alt="" />
24
+      <img class="item" src="/img/intro-carousel/home-2.jpg" alt="" />
25
+      <img class="item" src="/img/intro-carousel/home-3.jpg" alt="" />
26
+      <img class="item" src="/img/intro-carousel/home-4.jpg" alt="" />
27
+      <img class="item" src="/img/intro-carousel/home-5.jpg" alt="" />
28
+      <img class="item" src="/img/intro-carousel/home-6.jpg" alt="" />
29
+    </carousel>
30
+
31
+    <div id="intro-carousel" class="owl-carousel"></div>
32
+  </section>
33
+</template>
34
+
35
+<script>
36
+/* eslint-disable */
37
+
38
+import carousel from "vue-owl-carousel";
39
+export default {
40
+  components: {
41
+    carousel
42
+  }
43
+};
44
+</script>
45
+
46
+<style lang="scss" scoped></style>

src/components/misc/WebsiteDisclaimer.vue → src/components/misc/Disclaimer/contentSection.vue 查看文件

@@ -1,31 +1,27 @@
1 1
 <template>
2
-  <!-- eslint-disable max-len -->
3
-  <main id="main" style="margin-top:-20px;padding-bottom:450px">
4
-    <div class="container">
5
-      <div class="row">
6
-        <div class="col-sm-12">
7
-          <div class="section-header">
8
-            <h2>Website Disclaimer</h2>
9
-          </div>
10
-        </div>
11
-        <div class="col-md-12 text-left">
12
-          <br />
13
-          <p style="text-align:left">
2
+  <div class="container pt-5">
3
+    <div class="row mb-3">
4
+      <div class="col-sm-12 col-md-6">
5
+        <p style="text-align:left">
14 6
             Since the Company has limited control over the information and variables provided by
15 7
             users the Company accepts no responsibility for any loss or damage of whatsoever nature
16 8
             that may be caused or brought about, directly or indirectly, by the use of this Website
17 9
             or reliance on any information contained therein.
18
-          </p>
19
-          <p class="text-left">
10
+        </p>
11
+      </div>
12
+      <div class="col-sm-12 col-md-6">
13
+        <p style="text-align:left">
20 14
             Any person who feels prejudiced by any information or variables contained on this
21 15
             Website shall look to the persons who provided such information in case of any action
22 16
             being taken.
23
-          </p>
24
-        </div>
17
+        </p>
25 18
       </div>
26 19
     </div>
27
-  </main>
20
+  </div>
28 21
 </template>
22
+
29 23
 <script>
30 24
 export default {};
31 25
 </script>
26
+
27
+<style lang="scss" scoped></style>

+ 48
- 0
src/components/property/commercial/createProperty/carouselSection.vue 查看文件

@@ -0,0 +1,48 @@
1
+<template>
2
+  <section id="intro">
3
+    <div class="container">
4
+      <div class="row">
5
+        <div align="left" class="col-sm-12 col-md-8">
6
+          <div class="intro-content">
7
+            <h2>List Commercial {{ salesType }} Property</h2>
8
+            <p>List the perfect commercial property</p>
9
+          </div>
10
+        </div>
11
+      </div>
12
+    </div>
13
+
14
+    <carousel
15
+      :nav="false"
16
+      :dots="false"
17
+      :items="1"
18
+      :autoplay="true"
19
+      :loop="true"
20
+      id="intro-carousel"
21
+      style="margin-top:-50px"
22
+      :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
23
+    >
24
+      <img class="item" src="img/intro-carousel/comm-1.jpg" alt="" />
25
+      <img class="item" src="img/intro-carousel/comm-2.jpg" alt="" />
26
+      <img class="item" src="img/intro-carousel/comm-3.jpg" alt="" />
27
+      <img class="item" src="img/intro-carousel/comm-4.jpg" alt="" />
28
+      <img class="item" src="img/intro-carousel/comm-5.jpg" alt="" />
29
+      <img class="item" src="img/intro-carousel/comm-6.jpg" alt="" />
30
+    </carousel>
31
+
32
+    <div id="intro-carousel" class="owl-carousel"></div>
33
+  </section>
34
+</template>
35
+
36
+<script>
37
+/* eslint-disable */
38
+import carousel from "vue-owl-carousel";
39
+
40
+export default {
41
+  components: {
42
+    carousel
43
+  },
44
+  props: ["salesType"]
45
+};
46
+</script>
47
+
48
+<style lang="scss" scoped></style>

+ 521
- 0
src/components/property/commercial/createProperty/commercialCreate.vue 查看文件

@@ -0,0 +1,521 @@
1
+<template>
2
+  <div>
3
+    <carouselSection :salesType="salesType" />
4
+
5
+    <main id="main" style="margin-top:-20px">
6
+      <div class="container pt-5 pb-5">
7
+        <div class="row">
8
+          <div class="col-md-5">
9
+            <div v-if="!property.propertyName">
10
+              <label for="propertyName" class="uniSelectLabel">PROPERTY NAME</label>
11
+            </div>
12
+            <input
13
+              class="form-control uniInput"
14
+              type="text"
15
+              name="propertyName"
16
+              v-model="property.propertyName"
17
+            />
18
+          </div>
19
+          <div class="col-md-5">
20
+            <select
21
+              class="form-control uniSelect"
22
+              name="propertyType"
23
+              id="propertyType"
24
+              v-model="property.propertyTypeId"
25
+              @change="PropertyTypeSelected"
26
+            >
27
+              <option value="0">Please select type *</option>
28
+              <option v-for="item in propertyTypes" :value="item.id" :key="item.id">
29
+                {{ item.description }}
30
+              </option>
31
+            </select>
32
+          </div>
33
+          <div v-if="propertyType === 'Commercial'" class="col-md-2">
34
+            <div v-if="!property.unit">
35
+              <label for="unit" class="uniSelectLabel">UNIT</label>
36
+            </div>
37
+            <input
38
+              class="form-control uniInput"
39
+              type="text"
40
+              name="unit"
41
+              id="unit"
42
+              v-model="property.unit"
43
+            />
44
+          </div>
45
+        </div>
46
+        <div class="row my-5">
47
+          <div class="col-md-6">
48
+            <mapSection v-on:map-location="updateLocation" />
49
+          </div>
50
+          <div class="col-md-6">
51
+            <div class="row">
52
+              <div class="col-md-6">
53
+                <div v-if="property.price < 1">
54
+                  <label
55
+                    for="price"
56
+                    class="uniSelectLabel"
57
+                    style="text-transform:uppercase; margin-left:17px; background-color:white"
58
+                    >{{ salesType }} Price</label
59
+                  >
60
+                </div>
61
+                <input
62
+                  class="form-control uniInput"
63
+                  type="number"
64
+                  name="price"
65
+                  id="price"
66
+                  v-model="property.price"
67
+                />
68
+              </div>
69
+              <div v-if="salesType === 'Rental'" class="col-md-6">
70
+                <select
71
+                  class="form-control uniSelect"
72
+                  name="propertyType"
73
+                  id="propertyType"
74
+                  v-model="property.pricePer"
75
+                >
76
+                  <option value>Please select</option>
77
+                  <option value="Month">Month</option>
78
+                  <option value="Day">Day</option>
79
+                </select>
80
+              </div>
81
+            </div>
82
+            <div class="row my-3">
83
+              <div class="col-md-12">
84
+                <input
85
+                  type="date"
86
+                  class="form-control uniInput"
87
+                  name="date"
88
+                  v-model="property.dateAvailable"
89
+                />
90
+              </div>
91
+            </div>
92
+            <div class="row">
93
+              <div class="col-md-12">
94
+                <label for="Property Description" style="font-family:'muli'">Description:</label>
95
+                <vue-editor v-model="property.description" :editor-toolbar="customToolbar" />
96
+                <br />
97
+                <p>
98
+                  * A listing fee of R380 including VAT is payable to list your Property on the
99
+                  Uni-Vate website
100
+                </p>
101
+              </div>
102
+            </div>
103
+          </div>
104
+        </div>
105
+        <div class="row">
106
+          <div class="col-md-12">
107
+            <div v-for="item in propertyFields" :key="item.id">
108
+              <div class="row">
109
+                <div class="col-sm-12">
110
+                  <div class="section-header">
111
+                    <h2>{{ item.name }}</h2>
112
+                  </div>
113
+                </div>
114
+              </div>
115
+              <UserField
116
+                :fields="item.fields"
117
+                :id="item.name"
118
+                @UpdateUserDefinedFields="UpdateUserDefinedFields"
119
+                :fieldValues="item.fields"
120
+              />
121
+            </div>
122
+          </div>
123
+        </div>
124
+        <div class="row">
125
+          <div class="col-sm-12">
126
+            <div class="section-header">
127
+              <h2>Media</h2>
128
+            </div>
129
+          </div>
130
+        </div>
131
+        <div class="form-group row">
132
+          <div class="col-md-12">
133
+            <label class="uniSelectLabel">Virtual Tour (URL)</label>
134
+            <div class="input-group-prepend">
135
+              <input
136
+                class="form-control uniInput"
137
+                type="link"
138
+                name="vtlink"
139
+                id="vtlink"
140
+                v-model="property.virtualTour"
141
+              />
142
+            </div>
143
+          </div>
144
+        </div>
145
+        <div class="row">
146
+          <div class="col-md-12">
147
+            <label class="uniSelectLabel">Video (URL)</label>
148
+            <div class="input-group-prepend">
149
+              <input
150
+                class="form-control uniInput"
151
+                type="link"
152
+                name="vlink"
153
+                id="vlink"
154
+                v-model="property.video"
155
+              />
156
+            </div>
157
+          </div>
158
+        </div>
159
+        <div class="row mt-3">
160
+          <div class="col-md-6">
161
+            <div class="content-header">
162
+              <h2>Images</h2>
163
+            </div>
164
+
165
+            <div class="input-group-prepend"></div>
166
+          </div>
167
+        </div>
168
+        <ImageLoad
169
+          :loadedImages="loadedImages"
170
+          :savedImages="propertyImages"
171
+          @DefaultImage="UpdateDefaultImage"
172
+        />
173
+        <button v-if="!wait" type="button" @click="SubmitData()" class="btn-solid-blue">
174
+          Save
175
+        </button>
176
+        <div v-if="showPropertyTypeError || showProvinceError || showCityError || showSuburbError">
177
+          <p class="alert myError">
178
+            Missing fields. Please fill in all required fields. Marked with *
179
+          </p>
180
+        </div>
181
+        <div v-if="wait" id="preloader"></div>
182
+        <!-- <div class="row">
183
+          <div class="col-md-6">
184
+            <div v-if="!property.addressLine1">
185
+              <label for="unit" class="uniSelectLabel">STREET NUMBER</label>
186
+            </div>
187
+            <input
188
+              class="form-control uniInput"
189
+              type="text"
190
+              name="streetnumber"
191
+              v-model="property.addressLine1"
192
+            />
193
+          </div>
194
+          <div class="col-md-6">
195
+            <div v-if="!property.addressLine2">
196
+              <label for="streetname" class="uniSelectLabel">STREET NAME</label>
197
+            </div>
198
+            <input
199
+              class="form-control uniInput"
200
+              type="text"
201
+              name="streetname"
202
+              id="streetname"
203
+              v-model="property.addressLine2"
204
+            />
205
+          </div>
206
+        </div>
207
+        <div class="row my-3">
208
+          <div class="col-md-6">
209
+            <div v-if="!property.provinceId">
210
+              <label for="province" class="uniSelectLabel">PROVINCE</label>
211
+            </div>
212
+            <input
213
+              class="form-control uniInput"
214
+              type="text"
215
+              name="province"
216
+              v-model="selectedProvince"
217
+            />
218
+          </div>
219
+          <div class="col-md-6">
220
+            <div v-if="!property.cityId">
221
+              <label for="city" class="uniSelectLabel">CITY</label>
222
+            </div>
223
+            <input
224
+              class="form-control uniInput"
225
+              type="text"
226
+              name="city"
227
+              id="city"
228
+              v-model="selectedCity"
229
+            />
230
+          </div>
231
+        </div>
232
+        <div class="row my-3">
233
+          <div class="col-md-6">
234
+            <div v-if="!property.suburbId">
235
+              <label for="suburb" class="uniSelectLabel">SUBURB</label>
236
+            </div>
237
+            <input
238
+              class="form-control uniInput"
239
+              type="text"
240
+              name="suburb"
241
+              v-model="selectedSuburb"
242
+            />
243
+          </div>
244
+          <div class="col-md-6">
245
+            <div v-if="!property.addressLine3">
246
+              <label for="code" class="uniSelectLabel">POSTAL CODE</label>
247
+            </div>
248
+            <input
249
+              class="form-control uniInput"
250
+              type="text"
251
+              name="code"
252
+              id="code"
253
+              v-model="property.addressLine3"
254
+            />
255
+          </div>
256
+        </div> -->
257
+      </div>
258
+    </main>
259
+  </div>
260
+</template>
261
+
262
+<script>
263
+/* eslint-disable */
264
+import { mapState, mapActions } from "vuex";
265
+import { VueEditor } from "vue2-editor";
266
+import UserField from "../../propertyUserField.vue";
267
+import ImageLoad from "../../propertyImage.vue";
268
+import Log from "../../../../assets/Log";
269
+import carouselSection from "./carouselSection";
270
+import mapSection from "../../mapSection";
271
+
272
+export default {
273
+  name: "PropertyCreate",
274
+  components: {
275
+    UserField,
276
+    ImageLoad,
277
+    VueEditor,
278
+    carouselSection,
279
+    mapSection
280
+  },
281
+  data() {
282
+    return {
283
+      propertyType: "Commercial",
284
+      salesType: "Rental",
285
+      selectedProvince: "",
286
+      selectedCity: "",
287
+      selectedSuburb: "",
288
+      images: [],
289
+      propertyFieldValues: [],
290
+      defaultImage: 0,
291
+      wait: false,
292
+      customToolbar: [
293
+        [{ header: [false, 1, 2, 3, 4, 5, 6] }],
294
+        ["bold", "italic", "underline", "strike"],
295
+        [{ align: "" }, { align: "center" }, { align: "right" }, { align: "justify" }],
296
+        [{ list: "ordered" }, { list: "bullet" }, { list: "check" }],
297
+        [{ script: "sub" }, { script: "super" }],
298
+        [{ indent: "-1" }, { indent: "+1" }]
299
+      ],
300
+      error: "",
301
+      showPropertyTypeError: false,
302
+      showProvinceError: false,
303
+      showCityError: false,
304
+      showSuburbError: false,
305
+      showDateError: false,
306
+      user: Log.getUser(),
307
+      mayEdit: Log.isLoggedIn()
308
+    };
309
+  },
310
+  methods: {
311
+    ...mapActions("searchTab", ["getProvince", "getCities", "getSuburbs"]),
312
+    ...mapActions("property", [
313
+      "getPropertyTypes",
314
+      "getPropertyOverviewFields",
315
+      "getPropertyFields",
316
+      "saveProperty",
317
+      "getProperty",
318
+      "getPropertyImages",
319
+      "clearProperty",
320
+      "clearPropertyImages",
321
+      "getPropertyEditDisplay",
322
+      "getPropertySavedOverviewFields",
323
+      "getPropertySavedFields",
324
+      "getSavedPropertyData"
325
+    ]),
326
+    updateLocation(place) {
327
+      this.property.addressLine1 = place.mapComponents[0].short_name;
328
+      this.property.addressLine2 = place.mapComponents[1].short_name;
329
+      this.property.addressLine3 = place.mapComponents[7].short_name;
330
+      this.property.provinceId = place.provinceId;
331
+      this.property.cityId = place.cityId;
332
+      this.property.suburbId = place.suburbId;
333
+      this.property.propertCoords = place.coords;
334
+    },
335
+    TypeChanged() {
336
+      this.property.propertyUsageType = this.propertyType;
337
+    },
338
+    SubmitData() {
339
+      if (this.property.propertyTypeId === 0) {
340
+        this.showPropertyTypeError = true;
341
+      }
342
+      if (this.property.provinceId === 0) {
343
+        this.showProvinceError = true;
344
+      }
345
+      if (this.property.cityId === 0) {
346
+        this.showCityError = true;
347
+      }
348
+      if (this.property.suburbId === 0) {
349
+        this.showSuburbError = true;
350
+      }
351
+
352
+      if (this.salesType === "Rental" && this.property.dateAvailable === "undef") {
353
+        this.showDateError = true;
354
+      }
355
+
356
+      if (
357
+        this.showPropertyTypeError ||
358
+        this.showProvinceError ||
359
+        this.showCityError ||
360
+        this.showSuburbError ||
361
+        this.showDateError
362
+      ) {
363
+        return;
364
+      }
365
+
366
+      this.wait = true;
367
+      if (this.salesType === "Sale") {
368
+        this.property.isSale = true;
369
+        this.property.dateAvailable = new Date();
370
+      }
371
+      // eslint-disable-next-line no-plusplus
372
+      for (let i = 0; i < this.images.length; i++) {
373
+        let setAsDefault = false;
374
+        if (i === this.defaultImage) {
375
+          setAsDefault = true;
376
+        }
377
+        this.property.propertyImages.push({
378
+          image: this.images[i],
379
+          isDefault: setAsDefault
380
+        });
381
+      }
382
+      this.property.propertyUserFields = this.propertyFieldValues;
383
+
384
+      if (this.user) {
385
+        this.property.userId = this.user.id;
386
+      }
387
+
388
+      this.saveProperty(this.property)
389
+        .then(fulfilled => {
390
+          this.$router.push(`/property/commercial/property/${fulfilled.data.id}`);
391
+        })
392
+        .catch(error => {
393
+          console.log(error.message);
394
+        });
395
+    },
396
+    Close() {
397
+      this.$router.push("/property/admin/list/my");
398
+    },
399
+    Login() {
400
+      this.$router.push("/user/login");
401
+    },
402
+    PropertyTypeSelected(item) {
403
+      if (item.target.options.selectedIndex > 0) {
404
+        this.showPropertyTypeError = false;
405
+      } else {
406
+        this.showPropertyTypeError = true;
407
+      }
408
+    },
409
+    ProvinceSelected(item) {
410
+      if (item.target.options.selectedIndex > 0) {
411
+        this.selectedProvince = this.provinces[item.target.options.selectedIndex - 1].description;
412
+        this.getCities(Object.assign({}, { province: this.selectedProvince }));
413
+        this.showProvinceError = false;
414
+      } else {
415
+        this.showProvinceError = true;
416
+      }
417
+    },
418
+    CitySelected(item) {
419
+      if (item.target.options.selectedIndex > 0) {
420
+        this.selectedCity = this.cities[item.target.options.selectedIndex - 1].description;
421
+        this.getSuburbs(
422
+          Object.assign({}, { province: this.selectedProvince, city: this.selectedCity })
423
+        );
424
+        this.showCityError = false;
425
+      } else {
426
+        this.showCityError = true;
427
+      }
428
+    },
429
+    getPostalCode(item) {
430
+      this.property.addressLine3 = this.suburbs[item.target.options.selectedIndex - 1].postalCode;
431
+      if (item.target.options.selectedIndex > 0) {
432
+        this.showSuburbError = false;
433
+      } else {
434
+        this.showSuburbError = true;
435
+      }
436
+    },
437
+    loadedImages(values) {
438
+      this.images = values;
439
+    },
440
+    UpdateUserDefinedFields(item) {
441
+      let update = false;
442
+      this.propertyFieldValues.forEach(element => {
443
+        if (element.userDefinedFieldId === item.userDefinedFieldId) {
444
+          element.value = item.value;
445
+          update = true;
446
+        }
447
+      });
448
+      if (!update) {
449
+        this.propertyFieldValues.push(item);
450
+      }
451
+    },
452
+    UpdateDefaultImage(item) {
453
+      this.defaultImage = item;
454
+    }
455
+  },
456
+  mounted() {
457
+    this.wait = false;
458
+    this.clearProperty();
459
+    this.clearPropertyImages();
460
+    this.images = [];
461
+    this.defaultImage = 0;
462
+
463
+    if (this.propertyOverviewFields.length > 0) {
464
+      this.propertyOverviewFields = [];
465
+    }
466
+    if (this.propertyFields.length > 0) {
467
+      this.propertyFields = [];
468
+    }
469
+    if (this.property.description !== "") {
470
+      this.property.description = "";
471
+    }
472
+
473
+    if (this.$route.params.propertyUsageType) {
474
+      this.propertyType = this.$route.params.propertyUsageType;
475
+    }
476
+    this.salesType = this.$route.params.saleType;
477
+
478
+    this.getPropertyTypes(this.propertyType);
479
+
480
+    this.getProvince();
481
+    this.getPropertyOverviewFields();
482
+    this.getPropertyFields(this.propertyType);
483
+  },
484
+  computed: {
485
+    ...mapState("searchTab", ["provinces", "cities", "suburbs"]),
486
+    ...mapState("property", [
487
+      "propertyTypes",
488
+      "propertyOverviewFields",
489
+      "propertyFields",
490
+      "property",
491
+      "propertyImages"
492
+    ]),
493
+    ...mapState("authentication", ["user"]),
494
+    SalesTypeChanged() {
495
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
496
+      // this.propertyType = this.$route.params.propType;
497
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
498
+      this.salesType = this.$route.params.saleType;
499
+      if (this.property && this.property.propertyUsageType) {
500
+        // eslint-disable-next-line vue/no-side-effects-in-computed-properties
501
+        this.propertyType = this.property.propertyUsageType;
502
+      }
503
+
504
+      if (!this.$route.query.id) {
505
+        this.getPropertyFields(this.propertyType);
506
+      }
507
+
508
+      this.getPropertyTypes(this.propertyType);
509
+
510
+      return this.propertyType;
511
+    }
512
+  },
513
+  watch: {
514
+    SalesTypeChanged() {
515
+      return null;
516
+    }
517
+  }
518
+};
519
+</script>
520
+
521
+<style lang="scss" scoped></style>

+ 46
- 0
src/components/property/commercial/enquireNow/carouselSection.vue 查看文件

@@ -0,0 +1,46 @@
1
+<template>
2
+  <section id="intro">
3
+    <div class="container">
4
+      <div class="row">
5
+        <div align="left" class="col-sm-12 col-md-8">
6
+          <div class="intro-content box">
7
+            <h2>More Info</h2>
8
+          </div>
9
+        </div>
10
+      </div>
11
+    </div>
12
+
13
+    <carousel
14
+      :nav="false"
15
+      :dots="false"
16
+      :items="1"
17
+      :autoplay="true"
18
+      :loop="true"
19
+      id="intro-carousel"
20
+      style="margin-top:-50px"
21
+      :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
22
+    >
23
+      <img class="item" src="/img/intro-carousel/home-1.jpg" alt="" />
24
+      <img class="item" src="/img/intro-carousel/home-2.jpg" alt="" />
25
+      <img class="item" src="/img/intro-carousel/home-3.jpg" alt="" />
26
+      <img class="item" src="/img/intro-carousel/home-4.jpg" alt="" />
27
+      <img class="item" src="/img/intro-carousel/home-5.jpg" alt="" />
28
+      <img class="item" src="/img/intro-carousel/home-6.jpg" alt="" />
29
+    </carousel>
30
+
31
+    <div id="intro-carousel" class="owl-carousel"></div>
32
+  </section>
33
+</template>
34
+
35
+<script>
36
+/* eslint-disable */
37
+
38
+import carousel from "vue-owl-carousel";
39
+export default {
40
+  components: {
41
+    carousel
42
+  }
43
+};
44
+</script>
45
+
46
+<style lang="scss" scoped></style>

+ 168
- 0
src/components/property/commercial/enquireNow/contentSection.vue 查看文件

@@ -0,0 +1,168 @@
1
+<template>
2
+  <div class="container pt-5">
3
+        <div class="row mb-8">
4
+          <div class="col-md-6">
5
+            <h3>Mooikloof Office Park</h3>
6
+            <p>
7
+              The cream of the crop, no costs were spared on the finishing touches of this beautiful office.  This 160m2 office is ideally situated in Pretoria East in the hub of business expansion for Pretoria.  Two superb, air-conditioned ground floor units divided only by glass and completed with two small recording studios.  The Space is currently used for corporate boardroom and training centre functions and can accommodate up to 25 delegates.  Stunning finishes y interior designer complete the unit with style and class.  The perfect address and office for the established professional for the training centre of your dreams! 
8
+            </p>
9
+            <p><strong>View by Appointment only!</strong></p>
10
+            <br/>
11
+              <p></p>
12
+              To arrange a viewing contact Mynie:
13
+              <div class="col-md-4">
14
+                <a href="mailto:info@univateproperties.co.za">info@univateproperties.co.za</a
15
+                  ><br />
16
+                  <a href="tel:0124921238">+27 (0) 12 492 1238</a>
17
+              </div>
18
+          </div>
19
+          <div class="col-md-6">
20
+            <form >
21
+              <div class="form-group row">
22
+        <div class="form-group col-md-6">
23
+          <input
24
+            type="text"
25
+            name="name"
26
+            class="form-control"
27
+            id="Unit"
28
+            placeholder="Unit"
29
+            data-rule="minlen:4"
30
+            v-model="Unit"
31
+          />
32
+          <div class="validation"></div>
33
+        </div>
34
+                <div class="form-group col-md-6">
35
+          <input
36
+            type="text"
37
+            name="name"
38
+            class="form-control"
39
+            id="Price"
40
+            placeholder="Price"
41
+            data-rule="minlen:4"
42
+            v-model="Price"
43
+          />
44
+          <div class="validation"></div>
45
+        </div>
46
+                <div class="form-group col-md-6">
47
+          <input
48
+            type="text"
49
+            name="name"
50
+            class="form-control"
51
+            id="Size"
52
+            placeholder="Size"
53
+            data-rule="minlen:4"
54
+            v-model="Size"
55
+          />
56
+          <div class="validation"></div>
57
+        </div>
58
+                <div class="form-group col-md-6">
59
+          <input
60
+            type="text"
61
+            name="name"
62
+            class="form-control"
63
+            id="Suburb"
64
+            placeholder="Suburb"
65
+            data-rule="minlen:4"
66
+            v-model="Suburb"
67
+          />
68
+          <div class="validation"></div>
69
+        </div>
70
+                <div class="form-group col-md-12">
71
+          <input
72
+            type="text"
73
+            name="name"
74
+            class="form-control"
75
+            id="Name"
76
+            placeholder="Name"
77
+            data-rule="minlen:4"
78
+            v-model="Name"
79
+          />
80
+          <div class="validation"></div>
81
+        </div>
82
+                <div class="form-group col-md-12">
83
+          <input
84
+            type="text"
85
+            name="name"
86
+            class="form-control"
87
+            id="ContactNumber"
88
+            placeholder="ContactNumber"
89
+            data-rule="minlen:4"
90
+            v-model="ContactNumber"
91
+          />
92
+          <div class="validation"></div>
93
+        </div>
94
+                <div class="form-group col-md-12">
95
+          <input
96
+            type="text"
97
+            name="name"
98
+            class="form-control"
99
+            id="Email"
100
+            placeholder="Email"
101
+            data-rule="minlen:4"
102
+            v-model="Email"
103
+          />
104
+          <div class="validation"></div>
105
+        </div>
106
+              </div>
107
+              <div class="text-center">
108
+        <button class="btn-solid-blue" @click="sendMail()">ENQUIRE NOW</button>
109
+      </div>
110
+      <div v-if="boolSent">
111
+        <alert :text="alertMsg" :type="'SUCCESS'" />
112
+      </div>
113
+            </form>
114
+          </div>
115
+        </div>
116
+  </div>
117
+</template>
118
+
119
+<script>
120
+import axios from 'axios';
121
+import alert from '../../../shared/alert';
122
+
123
+export default {
124
+  components: {
125
+    alert
126
+  },
127
+  data() {
128
+    return {
129
+      alertMsg: "Sent! You can expect a reply soon!",
130
+      name: null,
131
+      email: null,
132
+      phone: null,
133
+      property: null,
134
+      message: null,
135
+      boolSent: false
136
+    };
137
+  },
138
+  mounted() {
139
+    this.boolSent = false;
140
+  },
141
+  methods: {
142
+    async sendMail() {
143
+      var mailObj = {
144
+        toAddress: "lenes@provision-sa.com",
145
+        fromAddress: "jlouw365@gmail.com",
146
+        name: this.name,
147
+        email: this.email,
148
+        phone: this.phone,
149
+        property: this.property,
150
+        message: this.message
151
+      };
152
+
153
+      const response = await axios.post("/api/mail/1", mailObj);
154
+
155
+      if (response.status === 200) {
156
+        this.boolSent = true;
157
+      } else {
158
+        console.log("Error");
159
+      }
160
+    },
161
+    countDownChanged(dismissCountDown) {
162
+      this.dismissCountDown = dismissCountDown;
163
+    }
164
+  }
165
+};
166
+</script>
167
+
168
+<style lang="scss" scoped></style>

+ 22
- 0
src/components/property/commercial/enquireNow/enquirenow.vue 查看文件

@@ -0,0 +1,22 @@
1
+<template>
2
+  <div>
3
+    <carouselSection />
4
+    <main id="main" style="margin-top:-20px;padding-bottom:50px">
5
+      <contentSection />
6
+    </main>
7
+  </div>
8
+</template>
9
+
10
+<script>
11
+/* eslint-disable */
12
+import carouselSection from "./carouselSection";
13
+import contentSection from "./contentSection";
14
+export default {
15
+  components: {
16
+    carouselSection,
17
+    contentSection
18
+  }
19
+};
20
+</script>
21
+
22
+<style lang="scss" scoped></style>

+ 28
- 12
src/components/property/commercial/singleView/contentSection.vue 查看文件

@@ -27,21 +27,23 @@
27 27
 
28 28
           <div class="panel-left p-5" style="margin-top:140px; margin-bottom:50px">
29 29
             <h2>Property Detial</h2>
30
-            <p>{{ property.addressLine1 }}</p>
31
-            <p>Town, Suburb</p>
30
+            <p>{{ property.addressLine1 }} {{ property.addressLine2 }}</p>
31
+            <p>{{ property.city.description }}, {{ property.suburb.description }}</p>
32 32
             <p>{{ property.shortDescription }}</p>
33
-            <p>{{ property.price }}</p>
33
+            <p>{{ property.price | toCurrency }}</p>
34 34
             <div class="btn-white-border"><i class="fa fa-search"></i>BOOK A VIEWING</div>
35 35
           </div>
36 36
         </div>
37 37
         <div class="col-md-8 p-5 resort-profile">
38
-          <h2>{{ property.propertyName }} / {{ property.addressLine1 }}</h2>
38
+          <h2>
39
+            {{ property.propertyName }} / {{ property.addressLine1 }} {{ property.addressLine2 }}
40
+          </h2>
39 41
           <div>
40 42
             <table class="table table-striped">
41 43
               <thead>
42 44
                 <tr>
43 45
                   <th scope="col">Reference</th>
44
-                  <th scope="col">Size</th>
46
+                  <th scope="col">Unit</th>
45 47
                   <th scope="col">Location</th>
46 48
                   <th scope="col">Kitchen</th>
47 49
                   <th scope="col">Extras</th>
@@ -50,12 +52,23 @@
50 52
               </thead>
51 53
               <tbody>
52 54
                 <tr>
53
-                  <td>#123456</td>
54
-                  <td>#m2</td>
55
+                  <td>#{{ property.id }}</td>
56
+                  <td>#{{ property.unit }}</td>
55 57
                   <td>Second Floor</td>
56 58
                   <td>yes</td>
57
-                  <td>open plan</td>
59
+                  <td>
60
+                    <div class="row" v-for="(feat, i) in property.displayData[0].values" :key="i">
61
+                      <div class="col" v-if="feat.value.toUpperCase() !== 'NO'">
62
+                        <div></div>
63
+                        {{ feat.name }} ({{ feat.value }})
64
+                      </div>
65
+                    </div>
66
+                  </td>
58 67
                   <td><a href="#" class="btn-solid-blue">BOOK A VIEWING</a></td>
68
+                  <td>open plan</td>
69
+                  <td>
70
+                    <router-link to="/EnquireNow">More Info</router-link>
71
+                  </td>
59 72
                 </tr>
60 73
                 <tr>
61 74
                   <td>#123456</td>
@@ -63,25 +76,25 @@
63 76
                   <td>Top Floor</td>
64 77
                   <td>yes</td>
65 78
                   <td>open plan</td>
66
-                  <td><a href="#" class="btn-solid-blue">BOOK A VIEWING</a></td>
79
+                  <td><router-link to="/EnquireNow">More Info</router-link></td>
67 80
                 </tr>
68 81
               </tbody>
69 82
             </table>
70 83
           </div>
71 84
           <p></p>
72 85
 
73
-          <div class="d-flex mt-3">
86
+          <!-- <div class="d-flex mt-3">
74 87
             <iframe
75 88
               width="100%"
76 89
               height="200"
77 90
               id="gmap_canvas"
78
-              src="https://maps.google.com/maps?q=ngwenya%20lodge&t=&z=13&ie=UTF8&iwloc=&output=embed"
91
+              src=""
79 92
               frameborder="0"
80 93
               scrolling="no"
81 94
               marginheight="0"
82 95
               marginwidth="0"
83 96
             ></iframe>
84
-          </div>
97
+          </div> -->
85 98
         </div>
86 99
       </div>
87 100
     </div>
@@ -99,6 +112,9 @@ export default {
99 112
     property: {},
100 113
     propertyImages: {}
101 114
   },
115
+  mounted() {
116
+    console.log(this.property);
117
+  },
102 118
   data() {
103 119
     return {
104 120
       index: null,

+ 106
- 0
src/components/property/mapSection.vue 查看文件

@@ -0,0 +1,106 @@
1
+<template>
2
+  <div>
3
+    <gmap-autocomplete
4
+      class="form-control mb-3 uniInput"
5
+      @place_changed="setPlace"
6
+    ></gmap-autocomplete>
7
+    <GmapMap
8
+      :center="mapCenter"
9
+      :zoom="mapZoom"
10
+      map-type-id="terrain"
11
+      style="width: 100%; height: 500px"
12
+      ref="map"
13
+    >
14
+      <GmapMarker v-if="this.place" :position="mapCenter" :clickable="true" :draggable="false" />
15
+    </GmapMap>
16
+  </div>
17
+</template>
18
+
19
+<script>
20
+/* eslint-disable */
21
+import { mapState, mapActions } from "vuex";
22
+import { gmapApi } from "vue2-google-maps";
23
+export default {
24
+  computed: {
25
+    google: gmapApi,
26
+    ...mapState("searchTab", ["provinces", "cities", "suburbs"])
27
+  },
28
+  data() {
29
+    return {
30
+      place: null,
31
+      mapCenter: { lat: -26.195246, lng: 28.034088 },
32
+      mapZoom: 11,
33
+      selectedProvince: "",
34
+      selectedCity: "",
35
+      selectedSuburb: "",
36
+      mapObj: {
37
+        provinceId: "",
38
+        cityId: "",
39
+        suburbId: "",
40
+        mapComponents: null
41
+      }
42
+    };
43
+  },
44
+
45
+  methods: {
46
+    ...mapActions("searchTab", ["getProvince", "getCities", "getSuburbs"]),
47
+    async pullProvince(provinceParam) {
48
+      await this.provinces.forEach(province => {
49
+        if (province.code === provinceParam) {
50
+          this.mapObj.provinceId = province.id;
51
+          this.selectedProvince = province.description;
52
+        }
53
+      });
54
+      await this.getCities(Object.assign({}, { province: this.selectedProvince }));
55
+      return Promise.resolve();
56
+    },
57
+    async pullCities(cityParam) {
58
+      await this.cities.forEach(city => {
59
+        if (city.description === cityParam) {
60
+          this.mapObj.cityId = city.id;
61
+          this.selectedCity = city.description;
62
+        }
63
+      });
64
+      await this.getSuburbs(
65
+        Object.assign({}, { province: this.selectedProvince, city: this.selectedCity })
66
+      );
67
+      return Promise.resolve();
68
+    },
69
+    async pullSuburbs(suburbParam) {
70
+      await this.suburbs.forEach(suburb => {
71
+        if (suburb.description === suburbParam) {
72
+          this.mapObj.suburbId = suburb.id;
73
+          this.selectedSuburb = suburb.description;
74
+        }
75
+      });
76
+      return Promise.resolve();
77
+    },
78
+    setPlace(place) {
79
+      this.place = place;
80
+      this.mapCenter = place.geometry.location;
81
+      this.mapZoom = 17;
82
+      this.mapObj.mapComponents = place.address_components;
83
+
84
+      this.pullProvince(place.address_components[5].short_name).then(() => {
85
+        setTimeout(
86
+          () =>
87
+            this.pullCities(place.address_components[3].short_name).then(() => {
88
+              setTimeout(
89
+                () =>
90
+                  this.pullSuburbs(place.address_components[2].short_name).then(() => {
91
+                    var coords = place.geometry.viewport.Za.j + "," + place.geometry.viewport.Va.j;
92
+                    this.mapObj.coords = coords;
93
+                    this.$emit("map-location", this.mapObj);
94
+                  }),
95
+                500
96
+              );
97
+            }),
98
+          500
99
+        );
100
+      });
101
+    }
102
+  }
103
+};
104
+</script>
105
+
106
+<style lang="scss" scoped></style>

+ 35
- 10
src/components/property/propertyImage.vue 查看文件

@@ -1,7 +1,7 @@
1 1
 <template>
2 2
   <div>
3 3
     <div>
4
-      <label class="btn btn-b-n" style="width: 85px; height:40px;">
4
+      <label class="btn-solid-blue">
5 5
         Upload
6 6
         <input
7 7
           type="file"
@@ -28,9 +28,12 @@
28 28
         <label v-if="allowMultiple" for="checkbox" style="margin: 10px;">Main Image</label>
29 29
         <img :src="img" style="height:200px; width:150px; object-fit: cover;" />
30 30
         <br />
31
-        <span class="input-group-text" align="center" style="width:150px" @click="removeImage(key)">
31
+        <!-- <span class="input-group-text" align="center" style="width:150px" @click="removeImage(key)">
32 32
           <eva-icon name="trash-2-outline" fill="#60CBEB"></eva-icon>Delete
33
-        </span>
33
+        </span> -->
34
+        <button align="center" class="imageDeleteButton" @click="removeImage(key)">
35
+          <i class="fa fa-trash"></i>
36
+        </button>
34 37
       </div>
35 38
       <br />
36 39
     </div>
@@ -42,13 +45,13 @@ export default {
42 45
   props: {
43 46
     loadedImages: Function,
44 47
     mayEdit: { type: Boolean, default: () => true },
45
-    allowMultiple: { type: Boolean, default: () => true },
48
+    allowMultiple: { type: Boolean, default: () => true }
46 49
   },
47 50
   data() {
48 51
     return {
49 52
       images: {},
50 53
       image: [],
51
-      imagesDefault: [],
54
+      imagesDefault: []
52 55
     };
53 56
   },
54 57
   // Commented out for now.
@@ -81,7 +84,7 @@ export default {
81 84
         const reader = new FileReader();
82 85
         var vm = this;
83 86
 
84
-        reader.onload = (e) => {
87
+        reader.onload = e => {
85 88
           vm.image.push(e.target.result);
86 89
         };
87 90
         reader.readAsDataURL(file[i]);
@@ -93,7 +96,7 @@ export default {
93 96
       this.images.splice(key, 1);
94 97
 
95 98
       if (!this.image.length) {
96
-        this.$refs.im.value = '';
99
+        this.$refs.im.value = "";
97 100
       }
98 101
     },
99 102
 
@@ -104,9 +107,31 @@ export default {
104 107
             this.imagesDefault[i] = false;
105 108
           }
106 109
         }
107
-        this.$emit('DefaultImage', index);
110
+        this.$emit("DefaultImage", index);
108 111
       }
109
-    },
110
-  },
112
+    }
113
+  }
111 114
 };
112 115
 </script>
116
+
117
+<style lang="scss" scoped>
118
+.imageDeleteButton {
119
+  background: #d9534f;
120
+  border-width: 0px;
121
+  width: 150px;
122
+  margin-left: 0;
123
+  font-family: "Muli";
124
+  font-size: 15px;
125
+  letter-spacing: 1px;
126
+  display: inline-block;
127
+  padding: 10px 32px;
128
+  border-radius: 2px;
129
+  transition-duration: 5s;
130
+  margin: 10px;
131
+  color: #fff;
132
+}
133
+
134
+.imageDeleteButton:hover i {
135
+  color: #000;
136
+}
137
+</style>

+ 18
- 15
src/components/property/propertyUserField.vue 查看文件

@@ -1,14 +1,17 @@
1 1
 <template>
2
-  <div class="form-group row">
2
+  <div class="row">
3 3
     <div class="col-md-4 mb-2" v-for="(currentField, i) in fields" :key="i">
4
-      <label>{{ currentField.name }}</label>
4
+      <div v-if="!setFields[i]">
5
+        <label class="uniSelectLabel">{{ currentField.name }}</label>
6
+      </div>
7
+
5 8
       <div class="input-group-prepend">
6
-        <span class="input-group-text" style="color: #60CBEB">
9
+        <!-- <span class="input-group-text" style="color: #60CBEB">
7 10
           <b>{{ GetFirstLetter(currentField.name) }}</b>
8
-        </span>
11
+        </span> -->
9 12
         <input
10 13
           v-if="currentField.type === 'number'"
11
-          class="form-control"
14
+          class="form-control uniInput"
12 15
           type="number"
13 16
           name="currentField.name"
14 17
           id="currentField.id"
@@ -17,7 +20,7 @@
17 20
         />
18 21
         <input
19 22
           v-if="currentField.type === 'text'"
20
-          class="form-control"
23
+          class="form-control uniInput"
21 24
           type="text"
22 25
           name="currentField.name"
23 26
           id="currentField.id"
@@ -26,7 +29,7 @@
26 29
         />
27 30
         <select
28 31
           v-if="currentField.type === 'yesno'"
29
-          class="form-control"
32
+          class="form-control uniSelect"
30 33
           id="currentField.id"
31 34
           v-model="setFields[i]"
32 35
           @change="UpdateSetFields(currentField, i)"
@@ -41,29 +44,29 @@
41 44
 
42 45
 <script>
43 46
 export default {
44
-  name: 'UserDefinedField',
47
+  name: "UserDefinedField",
45 48
   props: {
46
-    fields: { type: Array, default: () => [] },
49
+    fields: { type: Array, default: () => [] }
47 50
   },
48 51
   data() {
49 52
     return {
50
-      setFields: [],
53
+      setFields: []
51 54
     };
52 55
   },
53 56
   methods: {
54 57
     UpdateSetFields(field, index) {
55 58
       const item = {
56 59
         userDefinedFieldId: field.id,
57
-        value: this.setFields[index],
60
+        value: this.setFields[index]
58 61
       };
59
-      this.$emit('UpdateUserDefinedFields', item);
62
+      this.$emit("UpdateUserDefinedFields", item);
60 63
     },
61 64
     GetFirstLetter(value) {
62 65
       if (value) {
63 66
         return value.slice(0, 1);
64 67
       }
65
-      return '';
66
-    },
67
-  },
68
+      return "";
69
+    }
70
+  }
68 71
 };
69 72
 </script>

+ 48
- 0
src/components/property/residential/createProperty/carouselSection.vue 查看文件

@@ -0,0 +1,48 @@
1
+<template>
2
+  <section id="intro">
3
+    <div class="container">
4
+      <div class="row">
5
+        <div align="left" class="col-sm-12 col-md-8">
6
+          <div class="intro-content">
7
+            <h2>List Residential {{ salesType }} Property</h2>
8
+            <p>Make a house home</p>
9
+          </div>
10
+        </div>
11
+      </div>
12
+    </div>
13
+
14
+    <carousel
15
+      :nav="false"
16
+      :dots="false"
17
+      :items="1"
18
+      :autoplay="true"
19
+      :loop="true"
20
+      id="intro-carousel"
21
+      style="margin-top:-50px"
22
+      :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
23
+    >
24
+      <img class="item" src="img/intro-carousel/comm-1.jpg" alt="" />
25
+      <img class="item" src="img/intro-carousel/comm-2.jpg" alt="" />
26
+      <img class="item" src="img/intro-carousel/comm-3.jpg" alt="" />
27
+      <img class="item" src="img/intro-carousel/comm-4.jpg" alt="" />
28
+      <img class="item" src="img/intro-carousel/comm-5.jpg" alt="" />
29
+      <img class="item" src="img/intro-carousel/comm-6.jpg" alt="" />
30
+    </carousel>
31
+
32
+    <div id="intro-carousel" class="owl-carousel"></div>
33
+  </section>
34
+</template>
35
+
36
+<script>
37
+/* eslint-disable */
38
+import carousel from "vue-owl-carousel";
39
+
40
+export default {
41
+  components: {
42
+    carousel
43
+  },
44
+  props: ["salesType"]
45
+};
46
+</script>
47
+
48
+<style lang="scss" scoped></style>

+ 533
- 0
src/components/property/residential/createProperty/residentialCreate.vue 查看文件

@@ -0,0 +1,533 @@
1
+<template>
2
+  <div>
3
+    <carouselSection :salesType="salesType" />
4
+
5
+    <main id="main" style="margin-top:-20px">
6
+      <div class="container pt-5 pb-5">
7
+        <div class="row">
8
+          <div class="col-md-5">
9
+            <div v-if="!property.propertyName">
10
+              <label for="propertyName" class="uniSelectLabel">PROPERTY NAME</label>
11
+            </div>
12
+            <input
13
+              class="form-control uniInput"
14
+              type="text"
15
+              name="propertyName"
16
+              v-model="property.propertyName"
17
+            />
18
+          </div>
19
+          <div class="col-md-5">
20
+            <select
21
+              class="form-control uniSelect"
22
+              name="propertyType"
23
+              id="propertyType"
24
+              v-model="property.propertyTypeId"
25
+              @change="PropertyTypeSelected"
26
+            >
27
+              <option value="0">Please select type *</option>
28
+              <option v-for="item in propertyTypes" :value="item.id" :key="item.id">
29
+                {{ item.description }}
30
+              </option>
31
+            </select>
32
+          </div>
33
+          <div v-if="propertyType === 'Commercial'" class="col-md-2">
34
+            <div v-if="!property.unit">
35
+              <label for="unit" class="uniSelectLabel">UNIT</label>
36
+            </div>
37
+            <input
38
+              class="form-control uniInput"
39
+              type="text"
40
+              name="unit"
41
+              id="unit"
42
+              v-model="property.unit"
43
+            />
44
+          </div>
45
+        </div>
46
+        <div class="row my-5">
47
+          <div class="col-md-6">
48
+            <mapSection v-on:map-location="updateLocation" />
49
+          </div>
50
+          <div class="col-md-6">
51
+            <div class="row">
52
+              <div class="col-md-6">
53
+                <div v-if="property.price < 1">
54
+                  <label
55
+                    for="price"
56
+                    class="uniSelectLabel"
57
+                    style="text-transform:uppercase; margin-left:17px; background-color:white"
58
+                    >{{ salesType }} Price</label
59
+                  >
60
+                </div>
61
+                <input
62
+                  class="form-control uniInput"
63
+                  type="number"
64
+                  name="price"
65
+                  id="price"
66
+                  v-model="property.price"
67
+                />
68
+              </div>
69
+              <div v-if="salesType === 'Rental'" class="col-md-6">
70
+                <select
71
+                  class="form-control uniSelect"
72
+                  name="propertyType"
73
+                  id="propertyType"
74
+                  v-model="property.pricePer"
75
+                >
76
+                  <option value>Please select</option>
77
+                  <option value="Month">Month</option>
78
+                  <option value="Day">Day</option>
79
+                </select>
80
+              </div>
81
+            </div>
82
+            <div class="row my-3">
83
+              <div class="col-md-12">
84
+                <input
85
+                  type="date"
86
+                  class="form-control uniInput"
87
+                  name="date"
88
+                  v-model="property.dateAvailable"
89
+                />
90
+              </div>
91
+            </div>
92
+            <div class="row">
93
+              <div class="col-md-12">
94
+                <label for="Property Description" style="font-family:'muli'">Description:</label>
95
+                <vue-editor v-model="property.description" :editor-toolbar="customToolbar" />
96
+                <br />
97
+                <p>
98
+                  * A listing fee of R380 including VAT is payable to list your Property on the
99
+                  Uni-Vate website
100
+                </p>
101
+              </div>
102
+            </div>
103
+          </div>
104
+        </div>
105
+        <div class=" row" />
106
+
107
+        <div class="section-header">
108
+          <h2>Extra Information</h2>
109
+        </div>
110
+
111
+        <UserField
112
+          v-if="propertyOverviewFields.length > 0"
113
+          :fields="propertyOverviewFields[0].fields"
114
+          @UpdateUserDefinedFields="UpdateUserDefinedFields"
115
+          :id="1"
116
+        ></UserField>
117
+        <div class="row">
118
+          <div class="col-md-12">
119
+            <div v-for="item in propertyFields" :key="item.id">
120
+              <div class="row">
121
+                <div class="col-sm-12">
122
+                  <div class="section-header">
123
+                    <h2>{{ item.name }}</h2>
124
+                  </div>
125
+                </div>
126
+              </div>
127
+              <UserField
128
+                :fields="item.fields"
129
+                :id="item.name"
130
+                @UpdateUserDefinedFields="UpdateUserDefinedFields"
131
+                :fieldValues="item.fields"
132
+              />
133
+            </div>
134
+          </div>
135
+        </div>
136
+        <div class="row">
137
+          <div class="col-sm-12">
138
+            <div class="section-header">
139
+              <h2>Media</h2>
140
+            </div>
141
+          </div>
142
+        </div>
143
+        <div class="form-group row">
144
+          <div class="col-md-12">
145
+            <label class="uniSelectLabel">Virtual Tour (URL)</label>
146
+            <div class="input-group-prepend">
147
+              <input
148
+                class="form-control uniInput"
149
+                type="link"
150
+                name="vtlink"
151
+                id="vtlink"
152
+                v-model="property.virtualTour"
153
+              />
154
+            </div>
155
+          </div>
156
+        </div>
157
+        <div class="row">
158
+          <div class="col-md-12">
159
+            <label class="uniSelectLabel">Video (URL)</label>
160
+            <div class="input-group-prepend">
161
+              <input
162
+                class="form-control uniInput"
163
+                type="link"
164
+                name="vlink"
165
+                id="vlink"
166
+                v-model="property.video"
167
+              />
168
+            </div>
169
+          </div>
170
+        </div>
171
+        <div class="row mt-3">
172
+          <div class="col-md-6">
173
+            <div class="content-header">
174
+              <h2>Images</h2>
175
+            </div>
176
+
177
+            <div class="input-group-prepend"></div>
178
+          </div>
179
+        </div>
180
+        <ImageLoad
181
+          :loadedImages="loadedImages"
182
+          :savedImages="propertyImages"
183
+          @DefaultImage="UpdateDefaultImage"
184
+        />
185
+        <button v-if="!wait" type="button" @click="SubmitData()" class="btn-solid-blue">
186
+          Save
187
+        </button>
188
+        <div v-if="showPropertyTypeError || showProvinceError || showCityError || showSuburbError">
189
+          <p class="alert myError">
190
+            Missing fields. Please fill in all required fields. Marked with *
191
+          </p>
192
+        </div>
193
+        <div v-if="wait" id="preloader"></div>
194
+        <!-- <div class="row">
195
+          <div class="col-md-6">
196
+            <div v-if="!property.addressLine1">
197
+              <label for="unit" class="uniSelectLabel">STREET NUMBER</label>
198
+            </div>
199
+            <input
200
+              class="form-control uniInput"
201
+              type="text"
202
+              name="streetnumber"
203
+              v-model="property.addressLine1"
204
+            />
205
+          </div>
206
+          <div class="col-md-6">
207
+            <div v-if="!property.addressLine2">
208
+              <label for="streetname" class="uniSelectLabel">STREET NAME</label>
209
+            </div>
210
+            <input
211
+              class="form-control uniInput"
212
+              type="text"
213
+              name="streetname"
214
+              id="streetname"
215
+              v-model="property.addressLine2"
216
+            />
217
+          </div>
218
+        </div>
219
+        <div class="row my-3">
220
+          <div class="col-md-6">
221
+            <div v-if="!property.provinceId">
222
+              <label for="province" class="uniSelectLabel">PROVINCE</label>
223
+            </div>
224
+            <input
225
+              class="form-control uniInput"
226
+              type="text"
227
+              name="province"
228
+              v-model="selectedProvince"
229
+            />
230
+          </div>
231
+          <div class="col-md-6">
232
+            <div v-if="!property.cityId">
233
+              <label for="city" class="uniSelectLabel">CITY</label>
234
+            </div>
235
+            <input
236
+              class="form-control uniInput"
237
+              type="text"
238
+              name="city"
239
+              id="city"
240
+              v-model="selectedCity"
241
+            />
242
+          </div>
243
+        </div>
244
+        <div class="row my-3">
245
+          <div class="col-md-6">
246
+            <div v-if="!property.suburbId">
247
+              <label for="suburb" class="uniSelectLabel">SUBURB</label>
248
+            </div>
249
+            <input
250
+              class="form-control uniInput"
251
+              type="text"
252
+              name="suburb"
253
+              v-model="selectedSuburb"
254
+            />
255
+          </div>
256
+          <div class="col-md-6">
257
+            <div v-if="!property.addressLine3">
258
+              <label for="code" class="uniSelectLabel">POSTAL CODE</label>
259
+            </div>
260
+            <input
261
+              class="form-control uniInput"
262
+              type="text"
263
+              name="code"
264
+              id="code"
265
+              v-model="property.addressLine3"
266
+            />
267
+          </div>
268
+        </div> -->
269
+      </div>
270
+    </main>
271
+  </div>
272
+</template>
273
+
274
+<script>
275
+/* eslint-disable */
276
+import { mapState, mapActions } from "vuex";
277
+import { VueEditor } from "vue2-editor";
278
+import UserField from "../../propertyUserField.vue";
279
+import ImageLoad from "../../propertyImage.vue";
280
+import Log from "../../../../assets/Log";
281
+import carouselSection from "./carouselSection";
282
+import mapSection from "../../mapSection";
283
+
284
+export default {
285
+  name: "PropertyCreate",
286
+  components: {
287
+    UserField,
288
+    ImageLoad,
289
+    VueEditor,
290
+    carouselSection,
291
+    mapSection
292
+  },
293
+  data() {
294
+    return {
295
+      propertyType: "Residential",
296
+      salesType: "Rental",
297
+      selectedProvince: "",
298
+      selectedCity: "",
299
+      selectedSuburb: "",
300
+      images: [],
301
+      propertyFieldValues: [],
302
+      defaultImage: 0,
303
+      wait: false,
304
+      customToolbar: [
305
+        [{ header: [false, 1, 2, 3, 4, 5, 6] }],
306
+        ["bold", "italic", "underline", "strike"],
307
+        [{ align: "" }, { align: "center" }, { align: "right" }, { align: "justify" }],
308
+        [{ list: "ordered" }, { list: "bullet" }, { list: "check" }],
309
+        [{ script: "sub" }, { script: "super" }],
310
+        [{ indent: "-1" }, { indent: "+1" }]
311
+      ],
312
+      error: "",
313
+      showPropertyTypeError: false,
314
+      showProvinceError: false,
315
+      showCityError: false,
316
+      showSuburbError: false,
317
+      showDateError: false,
318
+      user: Log.getUser(),
319
+      mayEdit: Log.isLoggedIn()
320
+    };
321
+  },
322
+  methods: {
323
+    ...mapActions("searchTab", ["getProvince", "getCities", "getSuburbs"]),
324
+    ...mapActions("property", [
325
+      "getPropertyTypes",
326
+      "getPropertyOverviewFields",
327
+      "getPropertyFields",
328
+      "saveProperty",
329
+      "getProperty",
330
+      "getPropertyImages",
331
+      "clearProperty",
332
+      "clearPropertyImages",
333
+      "getPropertyEditDisplay",
334
+      "getPropertySavedOverviewFields",
335
+      "getPropertySavedFields",
336
+      "getSavedPropertyData"
337
+    ]),
338
+    updateLocation(place) {
339
+      this.property.addressLine1 = place.mapComponents[0].short_name;
340
+      this.property.addressLine2 = place.mapComponents[1].short_name;
341
+      this.property.addressLine3 = place.mapComponents[7].short_name;
342
+      this.property.provinceId = place.provinceId;
343
+      this.property.cityId = place.cityId;
344
+      this.property.suburbId = place.suburbId;
345
+      this.property.propertCoords = place.coords;
346
+    },
347
+    TypeChanged() {
348
+      this.property.propertyUsageType = this.propertyType;
349
+    },
350
+    SubmitData() {
351
+      if (this.property.propertyTypeId === 0) {
352
+        this.showPropertyTypeError = true;
353
+      }
354
+      if (this.property.provinceId === 0) {
355
+        this.showProvinceError = true;
356
+      }
357
+      if (this.property.cityId === 0) {
358
+        this.showCityError = true;
359
+      }
360
+      if (this.property.suburbId === 0) {
361
+        this.showSuburbError = true;
362
+      }
363
+
364
+      if (this.salesType === "Rental" && this.property.dateAvailable === "undef") {
365
+        this.showDateError = true;
366
+      }
367
+
368
+      if (
369
+        this.showPropertyTypeError ||
370
+        this.showProvinceError ||
371
+        this.showCityError ||
372
+        this.showSuburbError ||
373
+        this.showDateError
374
+      ) {
375
+        return;
376
+      }
377
+
378
+      this.wait = true;
379
+      if (this.salesType === "Sale") {
380
+        this.property.isSale = true;
381
+        this.property.dateAvailable = new Date();
382
+      }
383
+      // eslint-disable-next-line no-plusplus
384
+      for (let i = 0; i < this.images.length; i++) {
385
+        let setAsDefault = false;
386
+        if (i === this.defaultImage) {
387
+          setAsDefault = true;
388
+        }
389
+        this.property.propertyImages.push({
390
+          image: this.images[i],
391
+          isDefault: setAsDefault
392
+        });
393
+      }
394
+      this.property.propertyUserFields = this.propertyFieldValues;
395
+
396
+      if (this.user) {
397
+        this.property.userId = this.user.id;
398
+      }
399
+
400
+      this.saveProperty(this.property)
401
+        .then(fulfilled => {
402
+          this.$router.push(`/property/residential/property/${fulfilled.data.id}`);
403
+        })
404
+        .catch(error => {
405
+          console.log(error.message);
406
+        });
407
+    },
408
+    Close() {
409
+      this.$router.push("/property/admin/list/my");
410
+    },
411
+    Login() {
412
+      this.$router.push("/user/login");
413
+    },
414
+    PropertyTypeSelected(item) {
415
+      if (item.target.options.selectedIndex > 0) {
416
+        this.showPropertyTypeError = false;
417
+      } else {
418
+        this.showPropertyTypeError = true;
419
+      }
420
+    },
421
+    ProvinceSelected(item) {
422
+      if (item.target.options.selectedIndex > 0) {
423
+        this.selectedProvince = this.provinces[item.target.options.selectedIndex - 1].description;
424
+        this.getCities(Object.assign({}, { province: this.selectedProvince }));
425
+        this.showProvinceError = false;
426
+      } else {
427
+        this.showProvinceError = true;
428
+      }
429
+    },
430
+    CitySelected(item) {
431
+      if (item.target.options.selectedIndex > 0) {
432
+        this.selectedCity = this.cities[item.target.options.selectedIndex - 1].description;
433
+        this.getSuburbs(
434
+          Object.assign({}, { province: this.selectedProvince, city: this.selectedCity })
435
+        );
436
+        this.showCityError = false;
437
+      } else {
438
+        this.showCityError = true;
439
+      }
440
+    },
441
+    getPostalCode(item) {
442
+      this.property.addressLine3 = this.suburbs[item.target.options.selectedIndex - 1].postalCode;
443
+      if (item.target.options.selectedIndex > 0) {
444
+        this.showSuburbError = false;
445
+      } else {
446
+        this.showSuburbError = true;
447
+      }
448
+    },
449
+    loadedImages(values) {
450
+      this.images = values;
451
+    },
452
+    UpdateUserDefinedFields(item) {
453
+      let update = false;
454
+      this.propertyFieldValues.forEach(element => {
455
+        if (element.userDefinedFieldId === item.userDefinedFieldId) {
456
+          element.value = item.value;
457
+          update = true;
458
+        }
459
+      });
460
+      if (!update) {
461
+        this.propertyFieldValues.push(item);
462
+      }
463
+    },
464
+    UpdateDefaultImage(item) {
465
+      this.defaultImage = item;
466
+    }
467
+  },
468
+  mounted() {
469
+    this.wait = false;
470
+    this.clearProperty();
471
+    this.clearPropertyImages();
472
+    this.images = [];
473
+    this.defaultImage = 0;
474
+
475
+    if (this.propertyOverviewFields.length > 0) {
476
+      this.propertyOverviewFields = [];
477
+    }
478
+    if (this.propertyFields.length > 0) {
479
+      this.propertyFields = [];
480
+    }
481
+    if (this.property.description !== "") {
482
+      this.property.description = "";
483
+    }
484
+
485
+    if (this.$route.params.propertyUsageType) {
486
+      this.propertyType = this.$route.params.propertyUsageType;
487
+    }
488
+    this.salesType = this.$route.params.saleType;
489
+
490
+    this.getPropertyTypes(this.propertyType);
491
+
492
+    this.getProvince();
493
+    this.getPropertyOverviewFields();
494
+    this.getPropertyFields(this.propertyType);
495
+  },
496
+  computed: {
497
+    ...mapState("searchTab", ["provinces", "cities", "suburbs"]),
498
+    ...mapState("property", [
499
+      "propertyTypes",
500
+      "propertyOverviewFields",
501
+      "propertyFields",
502
+      "property",
503
+      "propertyImages"
504
+    ]),
505
+    ...mapState("authentication", ["user"]),
506
+    SalesTypeChanged() {
507
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
508
+      // this.propertyType = this.$route.params.propType;
509
+      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
510
+      this.salesType = this.$route.params.saleType;
511
+      if (this.property && this.property.propertyUsageType) {
512
+        // eslint-disable-next-line vue/no-side-effects-in-computed-properties
513
+        this.propertyType = this.property.propertyUsageType;
514
+      }
515
+
516
+      if (!this.$route.query.id) {
517
+        this.getPropertyFields(this.propertyType);
518
+      }
519
+
520
+      this.getPropertyTypes(this.propertyType);
521
+
522
+      return this.propertyType;
523
+    }
524
+  },
525
+  watch: {
526
+    SalesTypeChanged() {
527
+      return null;
528
+    }
529
+  }
530
+};
531
+</script>
532
+
533
+<style lang="scss" scoped></style>

+ 2
- 3
src/components/property/residential/latestListings.vue 查看文件

@@ -37,10 +37,9 @@ export default {
37 37
   methods: {
38 38
     ...mapActions("propertySearch", ["searchProperties"])
39 39
   },
40
-  mounted() {
40
+  async mounted() {
41 41
     this.propertySearch.propertyUsageType = "Residential";
42
-
43
-    this.searchProperties(this.propertySearch);
42
+    await this.searchProperties(this.propertySearch);
44 43
   },
45 44
   computed: {
46 45
     ...mapState("propertySearch", ["properties", "propertySearch"])

+ 68
- 29
src/components/property/residential/singleView/contentSection.vue 查看文件

@@ -8,66 +8,85 @@
8 8
               <div v-if="i < 3">
9 9
                 <img v-if="i === 0" style="width:100%" :src="image" />
10 10
                 <div v-else-if="i !== 0">
11
-                  <img v-if="i % 2 === 0" style="width:50%; float:right;" :src="image" />
12
-                  <img v-else style="width:50%; float:left" :src="image" />
11
+                  <img
12
+                    v-if="i % 2 === 0"
13
+                    style="width:50%; height:140px; float:right;"
14
+                    :src="image"
15
+                  />
16
+                  <img v-else style="width:50%; height:140px; float:left" :src="image" />
13 17
                 </div>
14 18
               </div>
15 19
             </div>
16 20
 
17 21
             <gallery :images="propertyImages" :index="index" @close="index = null"></gallery>
18 22
           </div>
19
-
20
-          <div class="panel-left p-5" style="margin-top:95px">
23
+          <div class="panel-left p-5" style="margin-top:130px">
21 24
             <h2>Property Detial</h2>
22
-            <p>{{ property.addressLine1 }}</p>
23
-            <p>Town, Suburb</p>
25
+            <p>{{ property.addressLine1 }} {{ property.addressLine2 }}</p>
26
+
27
+            <p>{{ property.city.description }}, {{ property.suburb.description }}</p>
24 28
             <p>{{ property.shortDescription }}</p>
25
-            <p>{{ property.price }}</p>
29
+            <p>{{ property.price | toCurrency }}</p>
26 30
             <div class="btn-white-border"><i class="fa fa-search"></i>BOOK A VIEWING</div>
27 31
           </div>
28 32
         </div>
29 33
         <div class="col-md-8 p-5 resort-profile">
30
-          <h2>{{ property.propertyName }} / {{ property.addressLine1 }}</h2>
34
+          <h2>
35
+            {{ property.propertyName }} / {{ property.addressLine1 }} {{ property.addressLine2 }}
36
+          </h2>
31 37
           <div>
32
-            <table class="table table-striped">
38
+            <!-- <table class="table table-striped">
33 39
               <thead>
34 40
                 <tr>
35 41
                   <th scope="col">Reference</th>
36 42
                   <th scope="col">Size</th>
37
-                  <th scope="col">Location</th>
38
-                  <th scope="col">Kitchen</th>
39
-                  <th scope="col">Extras</th>
43
+                  <th scope="col">Rooms</th>
44
+                  <th scope="col">Bathrooms</th>
45
+                  <th scope="col">Garages</th>
40 46
                   <th scope="col"></th>
41 47
                 </tr>
42 48
               </thead>
49
+
43 50
               <tbody>
44 51
                 <tr>
45
-                  <td>#123456</td>
46
-                  <td>#m2</td>
47
-                  <td>Second Floor</td>
48
-                  <td>yes</td>
49
-                  <td>open plan</td>
50
-                  <td><a href="#" class="btn-solid-blue">BOOK A VIEWING</a></td>
51
-                </tr>
52
-                <tr>
53
-                  <td>#123456</td>
54
-                  <td>#m2</td>
55
-                  <td>Top Floor</td>
56
-                  <td>yes</td>
57
-                  <td>open plan</td>
52
+                  <td>#{{ property.id }}</td>
53
+                  <td>{{ property.displayData[0].values[2].value }}M<sup>2</sup></td>
54
+                  <td>{{ property.displayData[1].values[0].value }}</td>
55
+                  <td>{{ property.displayData[1].values[1].value }}</td>
56
+                  <td>{{ property.displayData[2].values[0].value }}</td>
58 57
                   <td><a href="#" class="btn-solid-blue">BOOK A VIEWING</a></td>
59 58
                 </tr>
60 59
               </tbody>
61
-            </table>
60
+            </table> -->
61
+            <div v-for="(data, i) in property.displayData" :key="i">
62
+              <div class="content-header">
63
+                <h2>{{ data.groupName }}</h2>
64
+              </div>
65
+              <table class="table table-striped">
66
+                <thead>
67
+                  <tr>
68
+                    <th v-for="(tableHead, j) in data.values" :key="j" scope="col">
69
+                      {{ tableHead.name }}
70
+                    </th>
71
+                  </tr>
72
+                </thead>
73
+                <tbody>
74
+                  <tr>
75
+                    <td v-for="(tableVal, k) in data.values" :key="k" scope="col">
76
+                      {{ tableVal.value }}
77
+                    </td>
78
+                  </tr>
79
+                </tbody>
80
+              </table>
81
+            </div>
62 82
           </div>
63 83
           <p></p>
64
-
65 84
           <div class="d-flex mt-3">
66 85
             <iframe
67 86
               width="100%"
68 87
               height="200"
69 88
               id="gmap_canvas"
70
-              src="https://maps.google.com/maps?q=ngwenya%20lodge&t=&z=13&ie=UTF8&iwloc=&output=embed"
89
+              :src="propertyMap"
71 90
               frameborder="0"
72 91
               scrolling="no"
73 92
               marginheight="0"
@@ -82,6 +101,7 @@
82 101
 
83 102
 <script>
84 103
 /* eslint-disable */
104
+import { mapState, mapActions } from "vuex";
85 105
 import gallery from "../../../shared/gallerySlideShow";
86 106
 export default {
87 107
   components: {
@@ -92,13 +112,32 @@ export default {
92 112
     propertyImages: {}
93 113
   },
94 114
   created() {
95
-    console.log(this.property);
115
+    this.getListsForPropertyEdit(this.property.id);
116
+    console.log(this.property.displayData);
96 117
   },
97 118
   data() {
98 119
     return {
99 120
       index: null,
100 121
       date: new Date()
101 122
     };
123
+  },
124
+  methods: {
125
+    ...mapActions("searchTab", ["getListsForPropertyEdit"])
126
+  },
127
+  computed: {
128
+    ...mapState("searchTab", ["provinces", "cities", "suburbs"]),
129
+    propertyMap() {
130
+      var lat = this.property.propertCoords.split(",")[0];
131
+      var lng = this.property.propertCoords.split(",")[1];
132
+      // var url =
133
+      //   "https://maps.google.com/maps?q=" +
134
+      //   lat.replace(".", ",") +
135
+      //   "," +
136
+      //   lng.replace(".", ",") +
137
+      //   "&hl=es&z=14&amp;output=embed";
138
+      var url = "";
139
+      return url;
140
+    }
102 141
   }
103 142
 };
104 143
 </script>

+ 11
- 1
src/components/property/residential/singleView/singleResidentialPage.vue 查看文件

@@ -29,12 +29,21 @@ export default {
29 29
   data() {
30 30
     return {
31 31
       index: null,
32
-      date: new Date()
32
+      date: new Date(),
33
+      boolLoaded: false
33 34
     };
34 35
   },
35 36
   async mounted() {
37
+    console.log(this.$route.params.id);
38
+
36 39
     await this.getProperty(this.$route.params.id);
37 40
     await this.getPropertyImages(this.$route.params.id);
41
+    setTimeout(() => {
42
+      if (this.propertyImages.length > 0) {
43
+        this.boolLoaded = true;
44
+      }
45
+    }, 100);
46
+
38 47
     this.mayEditProperty(this.$route.params.id);
39 48
   },
40 49
   computed: {
@@ -44,6 +53,7 @@ export default {
44 53
   methods: {
45 54
     ...mapActions("property", ["getProperty", "getPropertyImages", "clearPropertyImages"]),
46 55
     ...mapActions("propertyEdit", ["mayEditProperty"]),
56
+
47 57
     formatPrice(value) {
48 58
       const val = (value / 1).toFixed(2);
49 59
       return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");

+ 0
- 37
src/components/propertyManagement/ourServicesSection.vue 查看文件

@@ -1,37 +0,0 @@
1
-<template>
2
-  <section id="services">
3
-    <div class="container" style="margin-top:-15px">
4
-      <div class="row">
5
-        <div align="left" class="col-lg-4">
6
-          <p>Our Services:</p>
7
-          <a class="btn-white-border" style="min-width:270px; cursor: context-menu;"
8
-            >Rent / Levy Collection</a
9
-          >
10
-          <a class="btn-white-border" style="min-width:270px; cursor: context-menu;"
11
-            >Occupancy Management</a
12
-          >
13
-          <a class="btn-white-border" style="min-width:270px; cursor: context-menu;">Maintenance</a>
14
-          <a class="btn-white-border" style="min-width:270px; cursor: context-menu;"
15
-            >Administration</a
16
-          >
17
-        </div>
18
-        <div align="left" class="col-lg-8">
19
-          <p>Information about what is Property Management and why UVP is the preferred option.</p>
20
-          <p>
21
-            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
22
-            incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
23
-            exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
24
-            dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
25
-          </p>
26
-          <h4>Contact us for a quote</h4>
27
-        </div>
28
-      </div>
29
-    </div>
30
-  </section>
31
-</template>
32
-
33
-<script>
34
-export default {};
35
-</script>
36
-
37
-<style lang="scss" scoped></style>

src/components/propertyManagement/carouselSection.vue → src/components/propertyManagement/rentalManagement/carouselSection.vue 查看文件

@@ -6,8 +6,8 @@
6 6
           <div class="intro-content box">
7 7
             <h2>Let us manage your property</h2>
8 8
             <p>
9
-              Uni-Vate Properties found that there was a desperate need for a reputable source for
10
-              buyers and sellers to turn to with their timeshare needs in South Africa.
9
+              At Uni-Vate we appreciate the significant and positive relationship between effective Property Management and property prices.  We understand that effective management not only relies on administrative processes being intact, but also on a clear plan and good communication with our clients based on respect, trust understanding, openness and accountability.  We have access to a comprehensive set of human and other resources to ensure that your property is proactively managed to protect your investment and to ensure the contentedness of occupants.
10
+              We offer comprehensive property management services, whether it being Sectional Title Management, HOA Management or Rental Property Portfolio Management.  
11 11
             </p>
12 12
             <a href="#" class="btn-solid-blue">LIST YOUR PROPERTY WITH UNI-VATE PROPERTIES</a>
13 13
             <router-link v-if="!isLoggedIn" to="/user/login" class="btn-white-border"
@@ -44,7 +44,7 @@
44 44
 <script>
45 45
 /* eslint-disable */
46 46
 import { mapState, mapActions } from "vuex";
47
-import Log from "../../assets/Log";
47
+import Log from "../../../assets/Log";
48 48
 import carousel from "vue-owl-carousel";
49 49
 export default {
50 50
   components: {

+ 86
- 0
src/components/propertyManagement/rentalManagement/contentSection.vue 查看文件

@@ -0,0 +1,86 @@
1
+<template>
2
+  <section id="services">
3
+    <div class="container" style="margin-top:-15px">
4
+      <div class="row">
5
+        <div class="col-lg-12">
6
+          <p>Uni-Vate offers a comprehensive rental property management and letting service for residential and commercial property portfolios.  Our exceptional financial and facility management processes ensure that we are a cut above the rest and provides a competitive advantage.</p>
7
+          <p>We pride ourselves on offering tailored solutions to property owners increasing the returns to our clients.</p>
8
+          <p>Our rental property management and letting services include the following:</p>
9
+        </div>
10
+        <p></p>
11
+        <div class="row">
12
+          <div class="col-md-6">
13
+            
14
+          </div>
15
+          <div class="col-md-6">
16
+            <h4>Contact us for a quote</h4>
17
+          </div>
18
+        </div>
19
+        <div align="left" class="col-lg-12">
20
+          <p>Our Services:</p>
21
+          <ul class="nav nav-tabs" id="myTab" role="tablist">
22
+            <li class="nav-item">
23
+              <a class="nav-link-active" id="tenant-tab" data-toggle="tab" href="#tenant" role="tab" aria-controls="tenant" aria-selected="true">Tenant Selection and Vacancy Management</a>
24
+            </li>
25
+            <li class="nav-item">
26
+              <a class="nav-link-active" id="rent-tab" data-toggle="tab" href="#rent" role="tab" aria-controls="rent" aria-selected="false">Rent Collection</a>
27
+            </li>
28
+            <li class="nav-item">
29
+              <a class="nav-link-active" id="financial-tab" data-toggle="tab" href="#financial" role="tab" aria-controls="financial" aria-selected="false">Financial Management</a>
30
+            </li>
31
+            <li class="nav-item">
32
+              <a class="nav-link-active" id="admin-tab" data-toggle="tab" href="#admin" role="tab" aria-controls="admin" aria-selected="false">Administration, Secretarial and Advisor</a>
33
+            </li>
34
+            <li class="nav-item">
35
+              <a class="nav-link-active" id="maintenance-tab" data-toggle="tab" href="#maintenance" role="tab" aria-controls="maintenance" aria-selected="false">Property Mainenance Management</a>
36
+            </li>
37
+          </ul>
38
+
39
+          <div class="tab-content">
40
+            <div class="tab-pane active" id="tenant" role="tabpanel" aria-labelledby="tenant-tab">
41
+              <p></p>
42
+              <p>•	Advertising and Marketing</p>
43
+              <p>•	Financial and character screening of potential tenants</p>
44
+              <p>•	Showing</p>
45
+              <p>•	Determining affordability</p>
46
+              <p>•	Conclusion of contract and ensuring that any suspensive conditions are met</p>
47
+            </div>
48
+            <hr/>
49
+            <div class="tab-pane" id="rent" role="tabpanel" aria-labelledby="rent-tab">
50
+              <p>•	Monthly invoicing and collection via debit order</p>
51
+              <p>•	Credit Control including soft collections</p>
52
+              <p>•	Attorney Collections liaison</p>
53
+              <p>•	Liaison with metering companies </p>
54
+            </div>
55
+            <div class="tab-pane" id="financial" role="tabpanel" aria-labelledby="financial-tab">
56
+              <p>•	Account reconciliation and payment of net rental after approved operating expenses </p>
57
+              <p>•	Payment of approved expenses on behalf of Landlord.</p>
58
+              <p>•	Preparation and submission of monthly reports.</p>
59
+              <p>•	Monthly accounting of receipts and expenses.</p>
60
+              <p>•	Preparation of annual property budget.</p>
61
+              <p>•	Management of deposits in trust account.</p>
62
+            </div>
63
+            <div class="tab-pane" id="admin" role="tabpanel" aria-labelledby="admin-tab">
64
+              <p>•	Preparation and circulation of correspondence and notices to tenants</p>
65
+              <p>•	Preparation and conclusion of lease agreements, debit order forms and other legal documentation</p>
66
+              <p>•	Record maintenance</p>
67
+            </div>
68
+            <div class="tab-pane" id="maintenance" role="tabpanel" aria-labelledby="maintenance-tab">
69
+              <p>•	Attending to maintenance issues</p>
70
+              <p>•	Procurement quotations </p>
71
+              <p>•	Allocating approved repair work to approved sub-contractors</p>
72
+              <p>•	Processing insurance claims, on request.</p>
73
+            </div>
74
+          </div>
75
+        </div>
76
+        
77
+      </div>
78
+    </div>
79
+  </section>
80
+</template>
81
+
82
+<script>
83
+export default {};
84
+</script>
85
+
86
+<style lang="scss" scoped></style>

+ 34
- 0
src/components/propertyManagement/rentalManagement/rentalPropertyManagement.vue 查看文件

@@ -0,0 +1,34 @@
1
+<template>
2
+  <div>
3
+    <CarouselSection />
4
+    <main id="main">
5
+      <ServicesSection data-aos="fade-down" data-aos-anchor-placement="top-bottom" />
6
+      <TestimonialSection
7
+        data-aos="fade-up"
8
+        data-aos-anchor-placement="top-bottom"
9
+        data-aos-delay="150"
10
+      />
11
+    </main>
12
+  </div>
13
+</template>
14
+
15
+<script>
16
+/* eslint-disable */
17
+import CarouselSection from "./carouselSection";
18
+import ServicesSection from "../sectionalTitle/ourServicesSection";
19
+import TestimonialSection from "../testimonialSection";
20
+import AOS from "aos";
21
+import "aos/dist/aos.css";
22
+export default {
23
+  created() {
24
+    AOS.init();
25
+  },
26
+  components: {
27
+    CarouselSection,
28
+    ServicesSection,
29
+    TestimonialSection
30
+  }
31
+};
32
+</script>
33
+
34
+<style lang="scss" scoped></style>

+ 64
- 0
src/components/propertyManagement/sectionalTitle/carouselSection.vue 查看文件

@@ -0,0 +1,64 @@
1
+<template>
2
+  <section id="intro">
3
+    <div class="container">
4
+      <div class="row">
5
+        <div align="left" class="col-sm-12 col-md-8">
6
+          <div class="intro-content box">
7
+            <h2>Let us manage your property</h2>
8
+            <p>
9
+              At Uni-Vate we appreciate the significant and positive relationship between effective Property Management and property prices.  We understand that effective management not only relies on administrative processes being intact, but also on a clear plan and good communication with our clients based on respect, trust understanding, openness and accountability.  We have access to a comprehensive set of human and other resources to ensure that your property is proactively managed to protect your investment and to ensure the contentedness of occupants.
10
+              We offer comprehensive property management services, whether it being Sectional Title Management, HOA Management or Rental Property Portfolio Management.  
11
+
12
+            </p>
13
+            <a href="#" class="btn-solid-blue">LIST YOUR PROPERTY WITH UNI-VATE PROPERTIES</a>
14
+            <router-link v-if="!isLoggedIn" to="/user/login" class="btn-white-border"
15
+              >LOGIN TO OWNERS PORTAL</router-link
16
+            >
17
+          </div>
18
+        </div>
19
+      </div>
20
+    </div>
21
+
22
+    <carousel
23
+      :nav="false"
24
+      :dots="false"
25
+      :items="1"
26
+      :autoplay="true"
27
+      :loop="true"
28
+      :autoHeight="true"
29
+      id="intro-carousel"
30
+      style="margin-top:-50px;"
31
+      :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
32
+    >
33
+      <img class="item" src="/img/intro-carousel/home-1.jpg" alt="" />
34
+      <img class="item" src="/img/intro-carousel/16.jpg" alt="" />
35
+      <img class="item" src="/img/intro-carousel/comm-1.jpg" alt="" />
36
+      <img class="item" src="/img/intro-carousel/comm-4.jpg" alt="" />
37
+      <img class="item" src="/img/intro-carousel/3.jpg" alt="" />
38
+      <img class="item" src="/img/intro-carousel/home-5.jpg" alt="" />
39
+    </carousel>
40
+
41
+    <div id="intro-carousel" class="owl-carousel"></div>
42
+  </section>
43
+</template>
44
+
45
+<script>
46
+/* eslint-disable */
47
+import { mapState, mapActions } from "vuex";
48
+import Log from "../../../assets/Log";
49
+import carousel from "vue-owl-carousel";
50
+export default {
51
+  components: {
52
+    carousel
53
+  },
54
+  computed: {
55
+    ...mapState("authentication", ["user", "flag", "status", "person", "token"]),
56
+    isLoggedIn() {
57
+      console.log(Log.isLoggedIn());
58
+      return Log.isLoggedIn();
59
+    }
60
+  }
61
+};
62
+</script>
63
+
64
+<style lang="scss" scoped></style>

+ 113
- 0
src/components/propertyManagement/sectionalTitle/ourServicesSection.vue 查看文件

@@ -0,0 +1,113 @@
1
+<template>
2
+  <section id="services">
3
+    <div class="container" style="margin-top:-15px">
4
+      <div class="row">
5
+        <div class="col-lg-12">
6
+          <p>Whether residential, commercial, hybrid schemes or home owners associations – we offer a complete property management solution tailored for the needs of the individual community scheme.</p>
7
+          <p>We are proud members of the National Association of Managing Agents and registered Estate Agents and Debt Collectors offering the following valuable functions to the residents and corporate bodies alike: </p>
8
+        </div>
9
+        <p></p>
10
+        <div class="row">
11
+          <div class="col-md-6">
12
+            
13
+          </div>
14
+          <div class="col-md-6">
15
+            <h4>Contact us for a quote</h4>
16
+          </div>
17
+        </div>
18
+        <div align="left" class="col-lg-12">
19
+          <p>Our Services:</p>
20
+          <ul class="nav nav-tabs" id="myTab" role="tablist">
21
+            <li class="nav-item">
22
+              <a class="nav-link-active" id="takeOn-tab" data-toggle="tab" href="#takeOn" role="tab" aria-controls="takeOn" aria-selected="true">Take-on Audit</a>
23
+            </li>
24
+            <li class="nav-item">
25
+              <a class="nav-link-active" id="levy-tab" data-toggle="tab" href="#levy" role="tab" aria-controls="levy" aria-selected="false">Levy, Billing and Collections</a>
26
+            </li>
27
+            <li class="nav-item">
28
+              <a class="nav-link-active" id="financial-tab" data-toggle="tab" href="#financial" role="tab" aria-controls="financial" aria-selected="false">Financial Management and Accounting</a>
29
+            </li>
30
+            <li class="nav-item">
31
+              <a class="nav-link-active" id="advisory-tab" data-toggle="tab" href="#advisory" role="tab" aria-controls="advisory" aria-selected="false">Advisory and Secretarial functions</a>
32
+            </li>
33
+            <li class="nav-item">
34
+              <a class="nav-link-active" id="admin-tab" data-toggle="tab" href="#admin" role="tab" aria-controls="admin" aria-selected="false">Administrative functions</a>
35
+            </li>
36
+          </ul>
37
+
38
+          <div class="tab-content">
39
+            <div class="tab-pane active" id="takeOn" role="tabpanel" aria-labelledby="takeOn-tab">
40
+              On appointment of company as managing agent, we perform a take-on audit which entails:
41
+              <p></p>
42
+              <p>•	Deeds search to confirm that correct owners and their details are loaded for levy billing and communication purposes.</p>
43
+              <p>•	Validation of sectional tile plans, PQ and levy schedule.</p>
44
+              <p>•	Levy Budget review, identification of risks and formulation of recommendations.</p>
45
+              <p>•	Accounting quality assessment from last financial statements to date.</p>
46
+              <p>•	Confirmation that the adjusting journals and opening balance adjustments agree to the auditor’s report.</p>
47
+              <p>•	Assessment of 10 MAP Plan and CSOS compliance.</p>
48
+              <p>•	Assessment of insurance cover.</p>
49
+              <p>•	Assessment of firefighting equipment.</p>
50
+              <p>•	Confirmation of conduct rules lodged with CSOS.</p>
51
+              <p>•	Assessment of owner arrear levies, credit control procedures, and legal report.</p>
52
+              <p>•	Assessment of compliance to relevant legislation.</p>
53
+              <p>•	Compilation of a report and action log to address identified gaps</p>
54
+              <p>•	Compilation of a property management control schedule demonstrating required monthly operational activities to be managed.</p>
55
+            </div>
56
+            <hr/>
57
+            <div class="tab-pane" id="levy" role="tabpanel" aria-labelledby="levy-tab">
58
+              <p>•	Distribution of monthly levy statements to owners by email</p>
59
+              <p>•	Collection of monthly levies and charges due to CSOS</p>
60
+              <p>•	Credit Control of outstanding levies</p>
61
+              <p>•	Billing of interest on arrears</p>
62
+              <p>•	Soft Collections</p>
63
+              <p>•	Attorney Collections liaison</p>
64
+              <p>•	Liaison with metering companies </p>
65
+              <p>•	Issuing of levy clearance certificates</p>
66
+            </div>
67
+            <div class="tab-pane" id="financial" role="tabpanel" aria-labelledby="financial-tab">
68
+              <p>•	Payment of approved operational and capital expenditure as per the approved budget and on sign-off in accordance with scheme executive instructions.</p>
69
+              <p>•	To open and / or operate a bank account in the name of the community scheme or a trust account which include current, savings and investment accounts in the name of the Scheme.</p>
70
+              <p>•	To keep books of account and records in accordance with standard accounting principles.</p>
71
+              <p>•	Preparing the annual audit file for the appointed auditors.</p>
72
+              <p>•	Preparing the annual budget and levy schedule for approval by the members at the AGM.</p>
73
+              <p>•	To compile and distribute a monthly management report to scheme executives which will include an income and expenditure statement detailing actual expenses versus budgeted expenses, a balance sheet, a debtor and supplier age analysis and any such supplementary information as the scheme executives may require.</p>
74
+              <p>•	Invest surplus funds after payment of creditors.</p>
75
+            </div>
76
+            <div class="tab-pane" id="advisory" role="tabpanel" aria-labelledby="advisory-tab">
77
+              <p>•	Managing the owners’ register</p>
78
+              <p>•	Consulting and providing advice on risk, compliance and governance matters where required.</p>
79
+              <p>•	Preparation and distribution of notices of meetings, agendas and minutes in respect of executives and owners’ meetings</p>
80
+              <p>•	Attending limited scheme executive meetings and the annual Annual General Meeting.</p>
81
+              <p>•	Attending Special General Meetings on request.</p>
82
+              <p>•	Arrange property valuation in terms of PMR 23(3).</p>
83
+              <p>•	Arrange competitive comprehensive property and fidelity insurance cover.</p>
84
+              <p>•	Submission and management of all insurance claims.</p>
85
+              <p>•	Maintenance management for common property to arrange quotes, booking contractors and facilitating approval and payment.  </p>
86
+              <p>•	Maintenance of statutory records.</p>
87
+              <p>•	Assisting with queries from management and owners.</p>
88
+              <p>•	Assisting executives with CSOS disputes.</p>
89
+            </div>
90
+            <div class="tab-pane" id="admin" role="tabpanel" aria-labelledby="admin-tab">
91
+              <p>•	Managing the owners’ register.</p>
92
+              <p>•	Safekeeping of the governance documents such as the conduct rules.</p>
93
+              <p>•	Issuing clearance and insurance certificates as and when required.</p>
94
+              <p>•	Performing general secretarial duties.</p>
95
+              <p>•	Recording, preparing and circulating the minutes of the trustee meetings and the AGM’s.</p>
96
+              <p>•	The preparing and circulation of all correspondence to owners and residents</p>
97
+              <p>•	Safekeeping of the minute books in perpetuity.</p>
98
+              <p>•	Provision of a legal address domicilium citandi et executandi for the body corporate.</p>
99
+              <p>•	Archiving and safekeeping of all body corporate records, as required by current legislation.</p>
100
+            </div>
101
+          </div>
102
+        </div>
103
+        
104
+      </div>
105
+    </div>
106
+  </section>
107
+</template>
108
+
109
+<script>
110
+export default {};
111
+</script>
112
+
113
+<style lang="scss" scoped></style>

src/components/propertyManagement/propertyManagement.vue → src/components/propertyManagement/sectionalTitle/propertyManagement.vue 查看文件

@@ -16,7 +16,7 @@
16 16
 /* eslint-disable */
17 17
 import CarouselSection from "./carouselSection";
18 18
 import ServicesSection from "./ourServicesSection";
19
-import TestimonialSection from "./testimonialSection";
19
+import TestimonialSection from "../testimonialSection";
20 20
 import AOS from "aos";
21 21
 import "aos/dist/aos.css";
22 22
 export default {

+ 56
- 6
src/components/shared/navBar.vue 查看文件

@@ -65,11 +65,47 @@
65 65
                       </li>
66 66
                     </ul>
67 67
                   </li>
68
-                  <li>
69
-                    <router-link to="/property/commercial">Commercial</router-link>
68
+                  <li class="menu-has-children">
69
+                    <div
70
+                      @mouseover="commercialClass = 'ts-display'"
71
+                      @mouseleave="commercialClass = 'no-display'"
72
+                    ></div>
73
+                    <a href="#" class="sf-with-ul">
74
+                      Commercial
75
+                    </a>
76
+                    <ul style="margin-top:-10px; text-align:left" :class="commercialClass">
77
+                      <li>
78
+                        <router-link to="/property/commercial">To Buy / To Rent</router-link>
79
+                      </li>
80
+                      <hr />
81
+                      <li>
82
+                        <a @click="routerGoTo('/property/commercial/new/Sale')">To Sell</a>
83
+                      </li>
84
+                      <li>
85
+                        <a @click="routerGoTo('/property/commercial/new/Rental')">To Rent</a>
86
+                      </li>
87
+                    </ul>
70 88
                   </li>
71
-                  <li>
72
-                    <router-link to="/property/residential">Residential</router-link>
89
+                  <li class="menu-has-children">
90
+                    <div
91
+                      @mouseover="residentialClass = 'ts-display'"
92
+                      @mouseleave="residentialClass = 'no-display'"
93
+                    ></div>
94
+                    <a href="#" class="sf-with-ul">
95
+                      Residential
96
+                    </a>
97
+                    <ul style="margin-top:-10px; text-align:left" :class="residentialClass">
98
+                      <li>
99
+                        <router-link to="/property/residential">To Buy / To Rent</router-link>
100
+                      </li>
101
+                      <hr />
102
+                      <li>
103
+                        <a @click="routerGoTo('/property/residential/new/Sale')">To Sell</a>
104
+                      </li>
105
+                      <li>
106
+                        <a @click="routerGoTo('/property/residential/new/Rental')">To Rent</a>
107
+                      </li>
108
+                    </ul>
73 109
                   </li>
74 110
                   <!-- <li class="menu-has-children">
75 111
                     <div
@@ -95,8 +131,22 @@
95 131
                       </li>
96 132
                     </ul>
97 133
                   </li> -->
98
-                  <li>
99
-                    <router-link to="/propertyManagement">Property Management</router-link>
134
+                  <li class="menu-has-children">
135
+                    <div
136
+                      @mouseover="propManClass = 'ts-display'"
137
+                      @mouseleave="propManClass = 'no-display'"
138
+                    ></div>
139
+                    <a href="#" class="sf-with-ul">
140
+                      Property Management
141
+                    </a>
142
+                    <ul style="margin-top:-10px; text-align:left" :class="propManClass">
143
+                      <li>
144
+                        <router-link to="/propertyManagement">Sectional Title and HOA Management</router-link>
145
+                      </li>
146
+                      <li>
147
+                        <router-link to="/rentalPropertyManagement">Rental Property Portfolio Management</router-link>
148
+                      </li>
149
+                    </ul>
100 150
                   </li>
101 151
                   <li class="menu-has-children">
102 152
                     <div

+ 2
- 0
src/components/timeshare/resort/contentSection.vue 查看文件

@@ -127,6 +127,8 @@ export default {
127 127
   computed: {
128 128
     ...mapState("resort", ["resort", "description", "images", "layout"]),
129 129
     mapUrl() {
130
+      console.log(this.resort.prLatitude);
131
+
130 132
       return this.resort
131 133
         ? `http://maps.google.com/maps?q=${this.resort.prLatitude},${this.resort.prLongitude}&z=15&output=embed`
132 134
         : "";

+ 30
- 4
src/router/index.js 查看文件

@@ -18,13 +18,18 @@ import UpdateInfo from "../components/user/updateProfileInfo.vue";
18 18
 import PropertySearch from "../components/property/propertySearchPage.vue";
19 19
 import PropertyPage from "../components/property/propertyPage.vue";
20 20
 import PropertyEdit from "../components/property/propertyeditPage.vue";
21
+
21 22
 import PropertyCreate from "../components/property/propertyCreate.vue";
23
+import CommercialCreate from "../components/property/commercial/createProperty/commercialCreate.vue";
24
+import ResidentialCreate from "../components/property/residential/createProperty/residentialCreate.vue";
25
+
22 26
 import PropertyList from "../components/property/propertyList.vue";
23 27
 import PropertyTypeList from "../components/admin/property/propertyTypeList.vue";
24 28
 import PropertyType from "../components/admin/property/propertyTypeEdit.vue";
25 29
 import UserDefinedGroups from "../components/admin/property/userDefinedGroupsPage.vue";
26 30
 import UserDefinedGroup from "../components/admin/property/userDefinedGroupPage.vue";
27
-import PropertyManagement from "../components/propertyManagement/propertyManagement.vue";
31
+import PropertyManagement from "../components/propertyManagement/sectionalTitle/propertyManagement.vue";
32
+import RentalPropertyManagement from '../components/propertyManagement/rentalManagement/contentSection.vue'
28 33
 
29 34
 import ResidentialPage from "../components/property/residential/residentialPage.vue";
30 35
 import CommercialPage from "../components/property/commercial/commercialPage.vue";
@@ -49,7 +54,7 @@ import ToBuySearch from "../components/timeshare/buy/toBuySearchResults.vue";
49 54
 
50 55
 import ContactUs from "../components/misc/contactUs.vue";
51 56
 import PrivacyPolicy from "../components/misc//privacyPolicy/privacyPolicyPage.vue";
52
-import WebsiteDisclaimer from "../components/misc/WebsiteDisclaimer.vue";
57
+import WebsiteDisclaimer from "../components/misc/Disclaimer/WebsiteDisclaimer.vue";
53 58
 
54 59
 import MakeOffer from "../components/processFlow/makeOffer.vue";
55 60
 import Offer from "../components/processFlow/offers.vue";
@@ -72,6 +77,7 @@ import LandingPage from "../components/marketing/landingPage.vue";
72 77
 import LandingPageWeek from "../components/marketing/landingPageWeek.vue";
73 78
 import MarketingPage from "../components/marketing/clientView.vue";
74 79
 import MarketingPageExp from "../components/marketing/landingPageExpired.vue";
80
+import EnquireNow from '../components/property/commercial/enquireNow/enquirenow.vue';
75 81
 
76 82
 Vue.use(Router);
77 83
 
@@ -209,6 +215,11 @@ export default new Router({
209 215
       name: "PropertyManagement",
210 216
       component: PropertyManagement
211 217
     },
218
+    {
219
+      path: '/rentalPropertyManagement',
220
+      name: 'RentalPropertyManagement',
221
+      component: RentalPropertyManagement
222
+    },
212 223
     {
213 224
       path: "/property/residential",
214 225
       name: "ResidentialPage",
@@ -234,6 +245,16 @@ export default new Router({
234 245
       name: "SingleCommercialPage",
235 246
       component: SingleCommercialPage
236 247
     },
248
+    {
249
+      path: "/property/commercial/new/:saleType",
250
+      name: "CommercialCreate",
251
+      component: CommercialCreate
252
+    },
253
+    {
254
+      path: "/property/residential/new/:saleType",
255
+      name: "ResidentialCreate",
256
+      component: ResidentialCreate
257
+    },
237 258
     {
238 259
       path: "/property/residential/property/:id",
239 260
       name: "SingleResidentialPage",
@@ -395,10 +416,15 @@ export default new Router({
395 416
       name: "CampaignExpired",
396 417
       component: MarketingPageExp
397 418
     },
419
+    {
420
+      path: "/EnquireNow",
421
+      name: "EnquireNow",
422
+      component: EnquireNow
423
+    },
398 424
     {
399 425
       path: "/toBuyResults",
400 426
       name: "ToBuySearch",
401 427
       component: ToBuySearch
402
-    }
403
-  ]
428
+    },
429
+  ],
404 430
 });

+ 2
- 2
vue.config.js 查看文件

@@ -2,8 +2,8 @@ module.exports = {
2 2
   devServer: {
3 3
     proxy: {
4 4
       "/api": {
5
-        //target: "http://localhost:57260/",
6
-        target: "http://training.provision-sa.com:82",
5
+        target: "http://localhost:57260/",
6
+        //target: "http://training.provision-sa.com:82",
7 7
         changeOrigin: true
8 8
       },
9 9
       "/nph-srep": {

正在加载...
取消
保存