ソースを参照

Styles & List New Prop

master
30117125 4年前
コミット
3b53b7a164

+ 8
- 0
package-lock.json ファイルの表示

@@ -12427,6 +12427,14 @@
12427 12427
       "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.5.tgz",
12428 12428
       "integrity": "sha512-BszkPvhl7I9h334GjckCh7sVFyjTPMMJFJ4Bsrem/Ik+B/9gt5tgrk8k4gGLO4ZpdvciVdg7O41gW4DisQWurg=="
12429 12429
     },
12430
+    "vue-share-social": {
12431
+      "version": "0.3.2",
12432
+      "resolved": "https://registry.npmjs.org/vue-share-social/-/vue-share-social-0.3.2.tgz",
12433
+      "integrity": "sha512-8YEm2Kkl756bhqSfXPtQqnOOItz7/DQWU6E4L+vC4dgT4rp0+XnqsgJAr4OXVQRRUNDO7TS8W0W79+zhfvh4pQ==",
12434
+      "requires": {
12435
+        "vue": "^2.5.16"
12436
+      }
12437
+    },
12430 12438
     "vue-style-loader": {
12431 12439
       "version": "4.1.2",
12432 12440
       "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",

+ 1
- 0
package.json ファイルの表示

@@ -34,6 +34,7 @@
34 34
     "vue-json-excel": "^0.2.98",
35 35
     "vue-owl-carousel": "^2.0.3",
36 36
     "vue-router": "^3.1.5",
37
+    "vue-share-social": "^0.3.2",
37 38
     "vue-trix": "^1.1.7",
38 39
     "vue2-editor": "^2.10.2",
39 40
     "vue2-google-maps": "^0.10.7",

+ 91
- 0
src/components/property/ListProperty/contentSection.vue ファイルの表示

@@ -0,0 +1,91 @@
1
+<template>
2
+  <section id="services">
3
+    <div class="container">
4
+      <div class="col-12">
5
+        <h1>List your property</h1>
6
+      </div>
7
+      <div class="col-12">
8
+        <strong>Type of Property</strong><br />
9
+        <ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
10
+          <li class="nav-item">
11
+            <a
12
+              class="nav-link btn-solid-blue"
13
+              id="pills-residential-tab"
14
+              data-toggle="pill"
15
+              href="#pills-residential"
16
+              role="tab"
17
+              aria-controls="pills-residential"
18
+              aria-selected="true"
19
+              @click="getPropTypeResidential"
20
+              >RESIDENTIAL</a
21
+            >
22
+          </li>
23
+          <li class="nav-item">
24
+            <a
25
+              class="nav-link btn-solid-blue"
26
+              id="pills-commercial-tab"
27
+              data-toggle="pill"
28
+              href="#pills-commercial"
29
+              role="tab"
30
+              aria-controls="pills-commercial"
31
+              aria-selected="false"
32
+              @click="getPropTypeCommercial"
33
+              >COMMERCIAL</a
34
+            >
35
+          </li>
36
+        </ul>
37
+      </div>
38
+
39
+      <div class="col-12 py-5">
40
+        <div class="tab-content" id="pills-tabContent">
41
+          <div
42
+            class="tab-pane fade show active"
43
+            id="pills-residential"
44
+            role="tabpanel"
45
+            aria-labelledby="pills-residential-tab"
46
+          >
47
+            <ResidentialCreate />
48
+          </div>
49
+          <div
50
+            class="tab-pane fade"
51
+            id="pills-commercial"
52
+            role="tabpanel"
53
+            aria-labelledby="pills-commercial-tab"
54
+          >
55
+            <CommercialCreate />
56
+          </div>
57
+        </div>
58
+      </div>
59
+    </div>
60
+  </section>
61
+</template>
62
+
63
+<script>
64
+/* eslint-disable */
65
+import ResidentialCreate from "../residential/createProperty/residentialCreateNew";
66
+import CommercialCreate from "../commercial/createProperty/commercialCreateNew";
67
+import { mapState, mapActions } from "vuex";
68
+export default {
69
+  components: {
70
+    ResidentialCreate,
71
+    CommercialCreate
72
+  },
73
+  methods: {
74
+    ...mapActions("property", ["getPropertyTypes"]),
75
+    getPropTypeResidential() {
76
+      this.getPropertyTypes("Residential");
77
+    },
78
+    getPropTypeCommercial() {
79
+      this.getPropertyTypes("Commercial");
80
+    }
81
+  },
82
+  mounted() {
83
+    this.getPropertyTypes("Residential");
84
+  },
85
+  computed: {
86
+    ...mapState("property", ["propertyTypes"])
87
+  }
88
+};
89
+</script>
90
+
91
+<style lang="scss" scoped></style>

+ 19
- 0
src/components/property/ListProperty/listPropertyPage.vue ファイルの表示

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

+ 424
- 0
src/components/property/commercial/createProperty/commercialCreateNew.vue ファイルの表示

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

+ 477
- 0
src/components/property/residential/createProperty/residentialCreateNew.vue ファイルの表示

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

+ 9
- 5
src/components/property/residential/singleView/contentSection.vue ファイルの表示

@@ -48,9 +48,7 @@
48 48
           </div>
49 49
           <div class="panel-left px-5 pb-5 text-center">
50 50
             <h4 class="text-white">Share this Property</h4>
51
-            <a
52
-              href="http://www.facebook.com/sharer.php?u=https://www.univateproperties.co.za/"
53
-              target="_blank"
51
+            <a id="fb_share" href="#" target="_blank"
54 52
               ><img src="img/icon-facebook.svg" alt="Share on Facebook" class="col-3 p-1 mx-1"
55 53
             /></a>
56 54
             <a
@@ -58,7 +56,7 @@
58 56
               ><img src="/img/icon-email.svg" alt="Share on email" class="col-3 p-1 mx-1"
59 57
             /></a>
60 58
             <a
61
-              href="whatsapp://send?text=Have a look at this property: https://www.univateproperties.co.za"
59
+              href="whatsapp://send?text=Check out this property!"
62 60
               data-action="share/whatsapp/share"
63 61
               target="_blank"
64 62
             >
@@ -147,9 +145,11 @@
147 145
 /* eslint-disable */
148 146
 import { mapState, mapActions } from "vuex";
149 147
 import gallery from "../../../shared/gallerySlideShow";
148
+import { ShareFacebook } from "vue-share-social";
150 149
 export default {
151 150
   components: {
152
-    gallery
151
+    gallery,
152
+    ShareFacebook
153 153
   },
154 154
   props: {
155 155
     property: {},
@@ -159,6 +159,10 @@ export default {
159 159
     //this.getListsForPropertyEdit(this.property.id);
160 160
     console.log(this.property.displayData);
161 161
   },
162
+  mounted() {
163
+    var facebookShare = document.getElementById("fb_share");
164
+    facebookShare.href = "http://www.facebook.com/share.php?u=" + encodeURIComponent(location.href);
165
+  },
162 166
   data() {
163 167
     return {
164 168
       index: null,

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

@@ -186,6 +186,9 @@
186 186
                       {{ NAME }}
187 187
                     </a>
188 188
                     <ul style="margin-top:-10px;text-align:left" :class="userClass">
189
+                      <li>
190
+                        <router-link to="/property/list">List Property</router-link>
191
+                      </li>
189 192
                       <li>
190 193
                         <router-link to="/status/list">Status</router-link>
191 194
                       </li>

+ 2
- 0
src/main.js ファイルの表示

@@ -8,7 +8,9 @@ import router from "./router";
8 8
 import store from "./store";
9 9
 import * as VueGoogleMaps from "vue2-google-maps";
10 10
 import Vuetify from "vuetify";
11
+import VueShareSocial from "vue-share-social";
11 12
 
13
+Vue.use(VueShareSocial);
12 14
 Vue.use(EvaIcons);
13 15
 Vue.use(Vuetify);
14 16
 Vue.use(VueGoogleMaps, {

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

@@ -22,6 +22,7 @@ import PropertyEdit from "../components/property/propertyeditPage.vue";
22 22
 import PropertyCreate from "../components/property/propertyCreate.vue";
23 23
 import CommercialCreate from "../components/property/commercial/createProperty/commercialCreate.vue";
24 24
 import ResidentialCreate from "../components/property/residential/createProperty/residentialCreate.vue";
25
+import ListProperty from "../components/property/ListProperty/listPropertyPage.vue";
25 26
 
26 27
 import PropertyList from "../components/property/propertyList.vue";
27 28
 import PropertyTypeList from "../components/admin/property/propertyTypeList.vue";
@@ -167,6 +168,11 @@ export default new Router({
167 168
       name: "PropertyPage",
168 169
       component: PropertyPage
169 170
     },
171
+    {
172
+      path: "/property/list",
173
+      name: "ListProperty",
174
+      component: ListProperty
175
+    },
170 176
     {
171 177
       path: "/property/search",
172 178
       name: "PropertySearchTab",

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