George Williams 4 jaren geleden
bovenliggende
commit
2bd0931bf1
34 gewijzigde bestanden met toevoegingen van 1314 en 134 verwijderingen
  1. 8
    0
      package-lock.json
  2. 1
    0
      package.json
  3. 9
    3
      public/css/newStyle.css
  4. 35
    31
      public/index.html
  5. BIN
      public/webfonts/Muli-Black.woff
  6. BIN
      public/webfonts/Muli-BlackItalic.woff
  7. BIN
      public/webfonts/Muli-Bold.woff
  8. BIN
      public/webfonts/Muli-BoldItalic.woff
  9. BIN
      public/webfonts/Muli-ExtraBold.woff
  10. BIN
      public/webfonts/Muli-ExtraBoldItalic.woff
  11. BIN
      public/webfonts/Muli-ExtraLight.woff
  12. BIN
      public/webfonts/Muli-ExtraLightItalic.woff
  13. BIN
      public/webfonts/Muli-Italic.woff
  14. BIN
      public/webfonts/Muli-Light.woff
  15. BIN
      public/webfonts/Muli-LightItalic.woff
  16. BIN
      public/webfonts/Muli-Regular.woff
  17. BIN
      public/webfonts/Muli-SemiBold.woff
  18. BIN
      public/webfonts/Muli-SemiBoldItalic.woff
  19. 49
    0
      src/components/financial/OrderThankYou.vue
  20. 2
    2
      src/components/financial/paygate/paygateProcess.vue
  21. 91
    0
      src/components/property/ListProperty/contentSection.vue
  22. 19
    0
      src/components/property/ListProperty/listPropertyPage.vue
  23. 48
    26
      src/components/property/commercial/commercialSearchResults.vue
  24. 424
    0
      src/components/property/commercial/createProperty/commercialCreateNew.vue
  25. 41
    12
      src/components/property/commercial/singleView/contentSection.vue
  26. 477
    0
      src/components/property/residential/createProperty/residentialCreateNew.vue
  27. 44
    25
      src/components/property/residential/residentialSearchResults.vue
  28. 17
    5
      src/components/property/residential/singleView/contentSection.vue
  29. 3
    0
      src/components/shared/navBar.vue
  30. 16
    22
      src/components/timeshare/resort/unit/carouselSection.vue
  31. 13
    6
      src/components/timeshare/resort/unit/unitPage.vue
  32. 2
    0
      src/main.js
  33. 13
    0
      src/router/index.js
  34. 2
    2
      vue.config.js

+ 8
- 0
package-lock.json Bestand weergeven

@@ -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 Bestand weergeven

@@ -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",

+ 9
- 3
public/css/newStyle.css Bestand weergeven

@@ -12,7 +12,13 @@
12 12
   font-style: normal;
13 13
 }
14 14
 
15
-@import url("https://fonts.googleapis.com/css?family=Muli&display=swap");
15
+@font-face {
16
+  font-family: "Muli";
17
+  src: url("../webfonts//Muli-Regular.woff") format("woff");
18
+  font-weight: 500;
19
+}
20
+
21
+/* @import url("https://fonts.googleapis.com/css?family=Muli&display=swap"); */
16 22
 
17 23
 .uniSelect {
18 24
   border-color: rgb(27, 117, 187);
@@ -27,8 +33,8 @@
27 33
 
28 34
 .uniSelect option {
29 35
   color: rgb(118, 118, 118);
30
-  font-family: "Muli";
31
-  text-transform: uppercase;
36
+  font-family: inherit;
37
+  text-transform: inherit;
32 38
 }
33 39
 
34 40
 .uniSelectLabel {

+ 35
- 31
public/index.html Bestand weergeven

@@ -1,39 +1,43 @@
1 1
 <!DOCTYPE html>
2 2
 <html lang="en">
3 3
 
4
-<head>
5
-  <meta charset="utf-8">
6
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
-  <meta name="viewport" content="width=device-width,initial-scale=1.0">
8
-  <link rel="icon" href="<%= BASE_URL %>favicon.png">
9
-  <link href="img/univate.PNG" rel="apple-touch-icon">
10
-  <title>Uni-Vate Properties</title>
4
+  <head>
5
+    <meta charset="utf-8">
6
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
8
+    <link rel="icon" href="<%= BASE_URL %>favicon.png">
9
+    <link href="img/univate.PNG" rel="apple-touch-icon">
10
+    <title>Uni-Vate Properties</title>
11 11
 
12
-  <link href="https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700" rel="stylesheet">
13
-  <link href="lib/font-awesome/css/font-awesome.min.css" rel="stylesheet">
14
-  <link href="lib/animate/animate.min.css" rel="stylesheet">
15
-  <link href="lib/ionicons/css/ionicons.min.css" rel="stylesheet">
16
-  <link href="lib/owlcarousel/assets/owl.carousel.min.css" rel="stylesheet">
17
-  <link href="css/bootstrap.min.css" rel="stylesheet">
18
-  <link href="css/style.css" rel="stylesheet">
19
-  <link rel="stylesheet" href="css/dragndrop.table.columns.css" />
20
-</head>
12
+    <link
13
+      href="https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700"
14
+      rel="stylesheet">
15
+    <link href="https://fonts.googleapis.com/css?family=Muli&display=swap"
16
+      rel="stylesheet">
17
+    <link href="lib/font-awesome/css/font-awesome.min.css" rel="stylesheet">
18
+    <link href="lib/animate/animate.min.css" rel="stylesheet">
19
+    <link href="lib/ionicons/css/ionicons.min.css" rel="stylesheet">
20
+    <link href="lib/owlcarousel/assets/owl.carousel.min.css" rel="stylesheet">
21
+    <link href="css/bootstrap.min.css" rel="stylesheet">
22
+    <link href="css/style.css" rel="stylesheet">
23
+    <link rel="stylesheet" href="css/dragndrop.table.columns.css" />
24
+  </head>
21 25
 
22
-<body>
23
-  <noscript>
24
-    <strong>We're sorry but bootvue doesn't work properly without JavaScript
25
-      enabled. Please enable it to continue.</strong>
26
-  </noscript>
27
-  <div id="app"></div>
28
-</body>
29
-<script src="lib/jquery/jquery.min.js"></script>
30
-<script src="lib/jquery/jquery-migrate.min.js"></script>
31
-<script src="lib/popper/popper.min.js"></script>
32
-<script src="lib/bootstrap/js/bootstrap.min.js"></script>
33
-<script src="lib/easing/easing.min.js"></script>
34
-<script src="lib/owlcarousel/owl.carousel.min.js"></script>
35
-<script src="lib/scrollreveal/scrollreveal.min.js"></script>
36
-<script src="js/main.js"></script>
26
+  <body>
27
+    <noscript>
28
+      <strong>We're sorry but bootvue doesn't work properly without JavaScript
29
+        enabled. Please enable it to continue.</strong>
30
+    </noscript>
31
+    <div id="app"></div>
32
+  </body>
33
+  <script src="lib/jquery/jquery.min.js"></script>
34
+  <script src="lib/jquery/jquery-migrate.min.js"></script>
35
+  <script src="lib/popper/popper.min.js"></script>
36
+  <script src="lib/bootstrap/js/bootstrap.min.js"></script>
37
+  <script src="lib/easing/easing.min.js"></script>
38
+  <script src="lib/owlcarousel/owl.carousel.min.js"></script>
39
+  <script src="lib/scrollreveal/scrollreveal.min.js"></script>
40
+  <script src="js/main.js"></script>
37 41
 
38 42
 
39 43
 </html>

BIN
public/webfonts/Muli-Black.woff Bestand weergeven


BIN
public/webfonts/Muli-BlackItalic.woff Bestand weergeven


BIN
public/webfonts/Muli-Bold.woff Bestand weergeven


BIN
public/webfonts/Muli-BoldItalic.woff Bestand weergeven


BIN
public/webfonts/Muli-ExtraBold.woff Bestand weergeven


BIN
public/webfonts/Muli-ExtraBoldItalic.woff Bestand weergeven


BIN
public/webfonts/Muli-ExtraLight.woff Bestand weergeven


BIN
public/webfonts/Muli-ExtraLightItalic.woff Bestand weergeven


BIN
public/webfonts/Muli-Italic.woff Bestand weergeven


BIN
public/webfonts/Muli-Light.woff Bestand weergeven


BIN
public/webfonts/Muli-LightItalic.woff Bestand weergeven


BIN
public/webfonts/Muli-Regular.woff Bestand weergeven


BIN
public/webfonts/Muli-SemiBold.woff Bestand weergeven


BIN
public/webfonts/Muli-SemiBoldItalic.woff Bestand weergeven


+ 49
- 0
src/components/financial/OrderThankYou.vue Bestand weergeven

@@ -0,0 +1,49 @@
1
+<template>
2
+  <section id="intro">
3
+    <div class="container">
4
+      <div class="row">
5
+        <div class="col-md-6">
6
+          <div class="intro-content box text-center">
7
+            <h2>Thank you!</h2>
8
+            <p>Your payment has been received and your propery will be listed</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
+      :autoHeight="true"
21
+      id="intro-carousel"
22
+      style="margin-top:-50px;"
23
+      :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
24
+    >
25
+      <img class="item" src="/img/intro-carousel/home-1.jpg" alt="" />
26
+      <img class="item" src="/img/intro-carousel/16.jpg" alt="" />
27
+      <img class="item" src="/img/intro-carousel/comm-1.jpg" alt="" />
28
+      <img class="item" src="/img/intro-carousel/comm-4.jpg" alt="" />
29
+      <img class="item" src="/img/intro-carousel/3.jpg" alt="" />
30
+      <img class="item" src="/img/intro-carousel/home-5.jpg" alt="" />
31
+    </carousel>
32
+  </section>
33
+</template>
34
+
35
+<script>
36
+import carousel from "vue-owl-carousel";
37
+export default {
38
+  components: {
39
+    carousel
40
+  },
41
+  data() {
42
+    return {
43
+      boolLoaded: false
44
+    };
45
+  }
46
+};
47
+</script>
48
+
49
+<style lang="scss" scoped></style>

+ 2
- 2
src/components/financial/paygate/paygateProcess.vue Bestand weergeven

@@ -1,5 +1,5 @@
1 1
 <template>
2
-  <div class="container mt-3 headerAdjustment">
2
+  <div class="container" style="margin-bottom:30px">
3 3
     <div class="row" v-if="loaded">
4 4
       <div class="col"></div>
5 5
       <div class="col-sm-6" sm="6">
@@ -23,7 +23,7 @@
23 23
               ></iframe>
24 24
               <form
25 25
                 ref="form"
26
-                target="payment_frame"
26
+                target="_parent"
27 27
                 action="https://secure.paygate.co.za/payweb3/process.trans"
28 28
                 method="POST"
29 29
               >

+ 91
- 0
src/components/property/ListProperty/contentSection.vue Bestand weergeven

@@ -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 Bestand weergeven

@@ -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>

+ 48
- 26
src/components/property/commercial/commercialSearchResults.vue Bestand weergeven

@@ -1,12 +1,13 @@
1 1
 <template>
2 2
   <main id="main" style="margin-top:-20px; padding-bottom:50px">
3
-    <section>
3
+    <div v-if="wait" id="preloader"></div>
4
+    <section v-if="properties.length > 0">
4 5
       <div class="container">
5 6
         <div class="row pt-5 justify-content-md-center">
6 7
           <h3 v-if="propertySearch.salesType === 'Sale'">COMMERCIAL PROPERTIES FOR SALE</h3>
7 8
           <h3 v-else-if="propertySearch.salesType === 'Rent'">COMMERCIAL PROPERTIES FOR RENT</h3>
8 9
         </div>
9
-        <div v-if="properties.length > 0" class="row justify-content-md-center">
10
+        <div class="row justify-content-md-center">
10 11
           <div
11 12
             class="col-lg-3 col-md-6 col-sm-6"
12 13
             v-for="currentProperty in properties"
@@ -15,30 +16,52 @@
15 16
             <div>
16 17
               <div class="portfolio-item">
17 18
                 <img style="width:255px; height:255px" :src="currentProperty.displayImage" alt />
18
-
19
-                <h4 class="mt-3">{{ currentProperty.suburb }}</h4>
20
-                <p>{{currentProperty.shortDescription }}</p>
19
+                <h4>{{ currentProperty.displayPrice }}</h4>
20
+                <p>Address | 00m</p>
21
+                <p>{{ currentProperty.shortDescription }}</p>
21 22
                 <br />
22 23
 
23 24
                 <!-- <a href="commercialproperty-page.php" class="btn-white-border">VIEW</a> -->
24 25
                 <router-link
25 26
                   class="btn-white-border"
26 27
                   :to="`/property/commercial/property/${currentProperty.id}`"
27
-                >VIEW</router-link>
28
+                  >VIEW</router-link
29
+                >
28 30
               </div>
29 31
             </div>
30 32
           </div>
31 33
         </div>
32
-        <div v-else class="row">
33
-          <div align="center" class="col-md-12">
34
-            <img src="img/no-homes.png" />
35
-            <br />
36
-            <br />
37
-            <p>Sorry no listings where found matching your search</p>
34
+      </div>
35
+    </section>
36
+    <section v-else id="intro" style="margin-bottom:-50px">
37
+      <div class="container">
38
+        <div class="row d-flex justify-content-center">
39
+          <div class="col-md-8">
40
+            <div class="intro-content box text-center">
41
+              <h2>Sorry no listing where found matching your search</h2>
42
+              <a class="btn-white-border" href="javascript:history.back()">BACK TO SEARCH</a>
43
+            </div>
38 44
           </div>
39 45
         </div>
40
-        <div v-if="wait" id="preloader"></div>
41 46
       </div>
47
+
48
+      <carousel
49
+        :nav="false"
50
+        :dots="false"
51
+        :items="1"
52
+        :autoplay="true"
53
+        :loop="true"
54
+        id="intro-carousel"
55
+        style="margin-top:-50px"
56
+        :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
57
+      >
58
+        <img class="item" src="img/intro-carousel/comm-1.jpg" alt />
59
+        <img class="item" src="img/intro-carousel/comm-2.jpg" alt />
60
+        <img class="item" src="img/intro-carousel/comm-3.jpg" alt />
61
+        <img class="item" src="img/intro-carousel/comm-4.jpg" alt />
62
+        <img class="item" src="img/intro-carousel/comm-5.jpg" alt />
63
+        <img class="item" src="img/intro-carousel/comm-6.jpg" alt />
64
+      </carousel>
42 65
     </section>
43 66
   </main>
44 67
 </template>
@@ -47,15 +70,17 @@
47 70
 /* eslint-disable */
48 71
 import { mapState, mapActions } from "vuex";
49 72
 import propertyCard from "../propertyCard";
73
+import carousel from "vue-owl-carousel";
50 74
 
51 75
 export default {
52 76
   name: "propertysearch",
53 77
   components: {
54 78
     propertyCard,
79
+    carousel
55 80
   },
56 81
   data() {
57 82
     return {
58
-      wait: true,
83
+      wait: true
59 84
     };
60 85
   },
61 86
   mounted() {
@@ -69,15 +94,16 @@ export default {
69 94
       this.propertySearch.userName = this.user.username;
70 95
     }
71 96
 
72
-    this.searchProperties(this.propertySearch).then((fulfilled) => {
97
+    this.searchProperties(this.propertySearch).then(fulfilled => {
73 98
       this.wait = false;
74 99
     });
100
+    console.log(this.properties);
75 101
   },
76 102
   methods: {
77 103
     ...mapActions("propertySearch", [
78 104
       "searchProperties",
79 105
       "clearProperties",
80
-      "updateResultsShowing",
106
+      "updateResultsShowing"
81 107
     ]),
82 108
     SetType(item) {
83 109
       this.propertySearch.propertyUsageType = item;
@@ -85,14 +111,10 @@ export default {
85 111
     SearchPage() {
86 112
       this.clearProperties();
87 113
       this.$router.push("/property/search");
88
-    },
114
+    }
89 115
   },
90 116
   computed: {
91
-    ...mapState("propertySearch", [
92
-      "properties",
93
-      "propertySearch",
94
-      "resultsShowing",
95
-    ]),
117
+    ...mapState("propertySearch", ["properties", "propertySearch", "resultsShowing"]),
96 118
     ...mapState("authentication", ["user"]),
97 119
     ParamsChanged() {
98 120
       console.log(JSON.stringify(this.propertySearch));
@@ -100,17 +122,17 @@ export default {
100 122
         // eslint-disable-next-line vue/no-side-effects-in-computed-properties
101 123
         this.propertySearch.propertyUsageType = "Residential";
102 124
       }
103
-      this.searchProperties(this.propertySearch).then((fulfilled) => {
125
+      this.searchProperties(this.propertySearch).then(fulfilled => {
104 126
         this.wait = false;
105 127
       });
106 128
       return null;
107
-    },
129
+    }
108 130
   },
109 131
   watch: {
110 132
     ParamsChanged() {
111 133
       return null;
112
-    },
113
-  },
134
+    }
135
+  }
114 136
 };
115 137
 </script>
116 138
 

+ 424
- 0
src/components/property/commercial/createProperty/commercialCreateNew.vue Bestand weergeven

@@ -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>

+ 41
- 12
src/components/property/commercial/singleView/contentSection.vue Bestand weergeven

@@ -4,9 +4,21 @@
4 4
       <div class="row" id="resort-profile">
5 5
         <div class="col-md-4">
6 6
           <div class="resPortfolioSection" style="margin-top:-5px">
7
+            <iframe
8
+              width="100%"
9
+              src="https://www.youtube.com/embed/watch_popup?v=qKgHJYzWtVA"
10
+              frameborder="0"
11
+              allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
12
+              allowfullscreen
13
+              style="margin-bottom:-6px"
14
+            ></iframe>
7 15
             <div v-for="(image, i) in propertyImages" @click="index = i" :key="i">
8 16
               <div v-if="i < 3">
9
-                <img v-if="i === 0" style="width:100%; height:201px;object-fit: cover" :src="image" />
17
+                <img
18
+                  v-if="i === 0"
19
+                  style="width:100%; height:201px;object-fit: cover"
20
+                  :src="image"
21
+                />
10 22
                 <div v-else-if="i !== 0">
11 23
                   <img
12 24
                     v-if="i % 2 === 0"
@@ -21,21 +33,38 @@
21 33
             <gallery :images="propertyImages" :index="index" @close="index = null"></gallery>
22 34
           </div>
23 35
 
24
-          <div class="panel-left p-5" style="margin-top:140px; margin-bottom:50px">
36
+          <div class="panel-left p-5" style="margin-top:140px;">
25 37
             <h2>Property Detial</h2>
26 38
             <p v-if="property.showAddress">{{ property.streetNumber }} {{ property.streetName }}</p>
27 39
             <p>{{ property.suburb }}, {{ property.city }}</p>
28 40
             <p>{{ property.shortDescription }}</p>
29 41
             <p>{{ property.price | toCurrency }}</p>
30
-            <div class="btn-white-border">
31
-              <i class="fa fa-search"></i>BOOK A VIEWING
32
-            </div>
42
+            <div class="btn-white-border"><i class="fa fa-search"></i>BOOK A VIEWING</div>
43
+          </div>
44
+          <div class="panel-left px-5 pb-5 text-center">
45
+            <h4 class="text-white">Share this Property</h4>
46
+            <a
47
+              href="http://www.facebook.com/sharer.php?u=https://www.univateproperties.co.za/"
48
+              target="_blank"
49
+              ><img src="img/icon-facebook.svg" alt="Share on Facebook" class="col-3 p-1 mx-1"
50
+            /></a>
51
+            <a
52
+              href="mailto:?Subject=Simple Share Buttons&amp;Body=I%20saw%20this%20and%20thought%20of%20you!%20 https://www.univateproperties.co.za/"
53
+              ><img src="/img/icon-email.svg" alt="Share on email" class="col-3 p-1 mx-1"
54
+            /></a>
55
+            <a
56
+              href="whatsapp://send?text=Have a look at this property: https://www.univateproperties.co.za"
57
+              data-action="share/whatsapp/share"
58
+              target="_blank"
59
+            >
60
+              <img src="img/icon-whatsapp.svg" alt="Share on whatsapp" class="col-3 p-1 mx-1"
61
+            /></a>
33 62
           </div>
34 63
         </div>
35 64
         <div class="col-md-8 p-5 resort-profile">
36
-          <h2
37
-            v-if="property.showAddress"
38
-          >{{ property.propertyName }} / {{ property.streetNumber }} {{ property.streetName }}</h2>
65
+          <h2 v-if="property.showAddress">
66
+            {{ property.propertyName }} / {{ property.streetNumber }} {{ property.streetName }}
67
+          </h2>
39 68
           <h2>{{ property.propertyName }}</h2>
40 69
           <div>
41 70
             <table class="table table-striped">
@@ -94,11 +123,11 @@
94 123
 import gallery from "../../../shared/gallerySlideShow";
95 124
 export default {
96 125
   components: {
97
-    gallery,
126
+    gallery
98 127
   },
99 128
   props: {
100 129
     property: {},
101
-    propertyImages: {},
130
+    propertyImages: {}
102 131
   },
103 132
   mounted() {
104 133
     console.log(this.property);
@@ -106,9 +135,9 @@ export default {
106 135
   data() {
107 136
     return {
108 137
       index: null,
109
-      date: new Date(),
138
+      date: new Date()
110 139
     };
111
-  },
140
+  }
112 141
 };
113 142
 </script>
114 143
 

+ 477
- 0
src/components/property/residential/createProperty/residentialCreateNew.vue Bestand weergeven

@@ -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>

+ 44
- 25
src/components/property/residential/residentialSearchResults.vue Bestand weergeven

@@ -1,12 +1,13 @@
1 1
 <template>
2 2
   <main id="main" style="margin-top:-20px; padding-bottom:50px">
3
-    <section>
3
+    <div v-if="wait" id="preloader"></div>
4
+    <section v-if="properties.length > 0">
4 5
       <div class="container">
5 6
         <div class="row pt-5 justify-content-md-center">
6 7
           <h3 v-if="propertySearch.salesType === 'Sale'">RESIDENTIAL PROPERTIES FOR SALE</h3>
7 8
           <h3 v-else-if="propertySearch.salesType === 'Rent'">RESIDENTIAL PROPERTIES FOR RENT</h3>
8 9
         </div>
9
-        <div v-if="properties.length > 0" class="row justify-content-md-center">
10
+        <div class="row justify-content-md-center">
10 11
           <div
11 12
             class="col-lg-3 col-md-6 col-sm-6"
12 13
             v-for="currentProperty in properties"
@@ -17,28 +18,50 @@
17 18
                 <img style="width:255px; height:255px" :src="currentProperty.displayImage" alt />
18 19
 
19 20
                 <h4 class="mt-3">{{ currentProperty.suburb }}</h4>
20
-                <p>{{currentProperty.shortDescription }}</p>
21
+                <p>{{ currentProperty.shortDescription }}</p>
21 22
                 <br />
22 23
 
23 24
                 <!-- <a href="commercialproperty-page.php" class="btn-white-border">VIEW</a> -->
24 25
                 <router-link
25 26
                   class="btn-white-border"
26 27
                   :to="`/property/residential/property/${currentProperty.id}`"
27
-                >VIEW</router-link>
28
+                  >VIEW</router-link
29
+                >
28 30
               </div>
29 31
             </div>
30 32
           </div>
31 33
         </div>
32
-        <div v-else class="row">
33
-          <div align="center" class="col-md-12">
34
-            <img src="img/no-homes.png" />
35
-            <br />
36
-            <br />
37
-            <p>Sorry no listings where found matching your search</p>
34
+      </div>
35
+    </section>
36
+    <section v-else id="intro" style="margin-bottom:-50px">
37
+      <div class="container">
38
+        <div class="row d-flex justify-content-center">
39
+          <div class="col-md-8">
40
+            <div class="intro-content box text-center">
41
+              <h2>Sorry no listing where found matching your search</h2>
42
+              <a class="btn-white-border" href="javascript:history.back()">BACK TO SEARCH</a>
43
+            </div>
38 44
           </div>
39 45
         </div>
40
-        <div v-if="wait" id="preloader"></div>
41 46
       </div>
47
+
48
+      <carousel
49
+        :nav="false"
50
+        :dots="false"
51
+        :items="1"
52
+        :autoplay="true"
53
+        :loop="true"
54
+        id="intro-carousel"
55
+        style="margin-top:-50px"
56
+        :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
57
+      >
58
+        <img class="item" src="img/intro-carousel/comm-1.jpg" alt />
59
+        <img class="item" src="img/intro-carousel/comm-2.jpg" alt />
60
+        <img class="item" src="img/intro-carousel/comm-3.jpg" alt />
61
+        <img class="item" src="img/intro-carousel/comm-4.jpg" alt />
62
+        <img class="item" src="img/intro-carousel/comm-5.jpg" alt />
63
+        <img class="item" src="img/intro-carousel/comm-6.jpg" alt />
64
+      </carousel>
42 65
     </section>
43 66
   </main>
44 67
 </template>
@@ -51,11 +74,11 @@ import propertyCard from "../propertyCard";
51 74
 export default {
52 75
   name: "propertysearch",
53 76
   components: {
54
-    propertyCard,
77
+    propertyCard
55 78
   },
56 79
   data() {
57 80
     return {
58
-      wait: true,
81
+      wait: true
59 82
     };
60 83
   },
61 84
   mounted() {
@@ -69,7 +92,7 @@ export default {
69 92
       this.propertySearch.userName = this.user.username;
70 93
     }
71 94
 
72
-    this.searchProperties(this.propertySearch).then((fulfilled) => {
95
+    this.searchProperties(this.propertySearch).then(fulfilled => {
73 96
       this.wait = false;
74 97
     });
75 98
   },
@@ -77,7 +100,7 @@ export default {
77 100
     ...mapActions("propertySearch", [
78 101
       "searchProperties",
79 102
       "clearProperties",
80
-      "updateResultsShowing",
103
+      "updateResultsShowing"
81 104
     ]),
82 105
     SetType(item) {
83 106
       this.propertySearch.propertyUsageType = item;
@@ -85,14 +108,10 @@ export default {
85 108
     SearchPage() {
86 109
       this.clearProperties();
87 110
       this.$router.push("/property/search");
88
-    },
111
+    }
89 112
   },
90 113
   computed: {
91
-    ...mapState("propertySearch", [
92
-      "properties",
93
-      "propertySearch",
94
-      "resultsShowing",
95
-    ]),
114
+    ...mapState("propertySearch", ["properties", "propertySearch", "resultsShowing"]),
96 115
     ...mapState("authentication", ["user"]),
97 116
     ParamsChanged() {
98 117
       console.log(JSON.stringify(this.propertySearch));
@@ -100,17 +119,17 @@ export default {
100 119
         // eslint-disable-next-line vue/no-side-effects-in-computed-properties
101 120
         this.propertySearch.propertyUsageType = "Residential";
102 121
       }
103
-      this.searchProperties(this.propertySearch).then((fulfilled) => {
122
+      this.searchProperties(this.propertySearch).then(fulfilled => {
104 123
         this.wait = false;
105 124
       });
106 125
       return null;
107
-    },
126
+    }
108 127
   },
109 128
   watch: {
110 129
     ParamsChanged() {
111 130
       return null;
112
-    },
113
-  },
131
+    }
132
+  }
114 133
 };
115 134
 </script>
116 135
 

+ 17
- 5
src/components/property/residential/singleView/contentSection.vue Bestand weergeven

@@ -4,6 +4,14 @@
4 4
       <div class="row" id="resort-profile">
5 5
         <div class="col-md-4">
6 6
           <div class="resPortfolioSection">
7
+            <iframe
8
+              width="100%"
9
+              src="https://www.youtube.com/embed/watch_popup?v=qKgHJYzWtVA"
10
+              frameborder="0"
11
+              allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
12
+              allowfullscreen
13
+              style="margin-bottom:-6px"
14
+            ></iframe>
7 15
             <div v-for="(image, i) in propertyImages" @click="index = i" :key="i">
8 16
               <div v-if="i < 3">
9 17
                 <img v-if="i === 0" style="width:100%" :src="image" />
@@ -40,9 +48,7 @@
40 48
           </div>
41 49
           <div class="panel-left px-5 pb-5 text-center">
42 50
             <h4 class="text-white">Share this Property</h4>
43
-            <a
44
-              href="http://www.facebook.com/sharer.php?u=https://www.univateproperties.co.za/"
45
-              target="_blank"
51
+            <a id="fb_share" href="#" target="_blank"
46 52
               ><img src="img/icon-facebook.svg" alt="Share on Facebook" class="col-3 p-1 mx-1"
47 53
             /></a>
48 54
             <a
@@ -50,7 +56,7 @@
50 56
               ><img src="/img/icon-email.svg" alt="Share on email" class="col-3 p-1 mx-1"
51 57
             /></a>
52 58
             <a
53
-              href="whatsapp://send?text=Have a look at this property: https://www.univateproperties.co.za"
59
+              href="whatsapp://send?text=Check out this property!"
54 60
               data-action="share/whatsapp/share"
55 61
               target="_blank"
56 62
             >
@@ -139,9 +145,11 @@
139 145
 /* eslint-disable */
140 146
 import { mapState, mapActions } from "vuex";
141 147
 import gallery from "../../../shared/gallerySlideShow";
148
+import { ShareFacebook } from "vue-share-social";
142 149
 export default {
143 150
   components: {
144
-    gallery
151
+    gallery,
152
+    ShareFacebook
145 153
   },
146 154
   props: {
147 155
     property: {},
@@ -151,6 +159,10 @@ export default {
151 159
     //this.getListsForPropertyEdit(this.property.id);
152 160
     console.log(this.property.displayData);
153 161
   },
162
+  mounted() {
163
+    var facebookShare = document.getElementById("fb_share");
164
+    facebookShare.href = "http://www.facebook.com/share.php?u=" + encodeURIComponent(location.href);
165
+  },
154 166
   data() {
155 167
     return {
156 168
       index: null,

+ 3
- 0
src/components/shared/navBar.vue Bestand weergeven

@@ -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>

+ 16
- 22
src/components/timeshare/resort/unit/carouselSection.vue Bestand weergeven

@@ -1,22 +1,20 @@
1 1
 <template>
2 2
   <section id="intro">
3
-    <div v-if="loaded">
4
-      <carousel
5
-        :nav="false"
6
-        :dots="false"
7
-        :items="10"
8
-        :autoplay="true"
9
-        :loop="true"
10
-        :autoHeight="true"
11
-        id="intro-carousel"
12
-        style="margin-top:-50px;"
13
-        :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
14
-      >
15
-        <div v-for="(image, i) in resortImages" :key="i">
16
-          <img class="item" style="object-fit:cover" :src="image" :key="i" />
17
-        </div>
18
-      </carousel>
19
-    </div>
3
+    <carousel
4
+      :nav="false"
5
+      :dots="false"
6
+      :items="10"
7
+      :autoplay="true"
8
+      :loop="true"
9
+      :autoHeight="true"
10
+      id="intro-carousel"
11
+      style="margin-top:-50px;"
12
+      :responsive="{ 0: { items: 1, nav: false }, 600: { items: 1, nav: false } }"
13
+    >
14
+      <div v-for="(image, i) in resortImages" :key="i">
15
+        <img class="item" style="object-fit:cover" :src="image" :key="i" />
16
+      </div>
17
+    </carousel>
20 18
   </section>
21 19
 </template>
22 20
 
@@ -32,15 +30,11 @@ export default {
32 30
   },
33 31
   data() {
34 32
     return {
35
-      images: [],
36
-      loaded: false
33
+      images: []
37 34
     };
38 35
   },
39 36
   async created() {
40 37
     this.images = await this.resortImages;
41
-    setTimeout(() => {
42
-      this.loaded = true;
43
-    }, 500);
44 38
   }
45 39
 };
46 40
 </script>

+ 13
- 6
src/components/timeshare/resort/unit/unitPage.vue Bestand weergeven

@@ -1,6 +1,6 @@
1 1
 <template>
2 2
   <main id="main" style="padding-bottom:50px">
3
-    <carouselSection :resortImages="images" />
3
+    <carouselSection v-if="boolLoaded" :resortImages="images" />
4 4
     <summarySection :resortCode="resortCode" :unitNumber="unitNumber" />
5 5
     <div class="container">
6 6
       <div class="row mt-5">
@@ -38,14 +38,21 @@ export default {
38 38
     resortCode: {},
39 39
     unitNumber: {},
40 40
   },
41
-  mounted() {
42
-    this.initResort(this.resortCode);
41
+  data() {
42
+    return {
43
+      boolLoaded: false
44
+    };
45
+  },
46
+  async mounted() {
47
+    await this.initResort(this.resortCode);
43 48
     if (this.resortCode) {
44 49
       this.applyResortFilter(this.resortCode);
45 50
     }
46
-    this.layouts.push(this.layout);
47
-    this.getWeeks();
48
-    console.log(this.resort);
51
+    await this.layouts.push(this.layout);
52
+    await this.getWeeks();
53
+    setTimeout(() => {
54
+      this.boolLoaded = true;
55
+    }, 500);
49 56
   },
50 57
   computed: {
51 58
     ...mapState("resort", ["resort", "description", "images", "layout"]),

+ 2
- 0
src/main.js Bestand weergeven

@@ -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, {

+ 13
- 0
src/router/index.js Bestand weergeven

@@ -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";
@@ -72,6 +73,8 @@ import ResidentialSearchResults from "../components/property/residential/residen
72 73
 
73 74
 import PaymentGateway from "../components/financial/paygate/paygateProcess.vue";
74 75
 import Payments from "../components/financial/payments.vue";
76
+import PaymentSuccess from "../components/financial/OrderThankYou.vue";
77
+
75 78
 import LandingPages from "../components/marketing/landingPages.vue";
76 79
 import LandingPage from "../components/marketing/landingPage.vue";
77 80
 import LandingPageWeek from "../components/marketing/landingPageWeek.vue";
@@ -165,6 +168,11 @@ export default new Router({
165 168
       name: "PropertyPage",
166 169
       component: PropertyPage
167 170
     },
171
+    {
172
+      path: "/property/list",
173
+      name: "ListProperty",
174
+      component: ListProperty
175
+    },
168 176
     {
169 177
       path: "/property/search",
170 178
       name: "PropertySearchTab",
@@ -386,6 +394,11 @@ export default new Router({
386 394
       }),
387 395
       component: PaymentGateway
388 396
     },
397
+    {
398
+      path: "/payments/success",
399
+      name: "PaymentSuccess",
400
+      component: PaymentSuccess
401
+    },
389 402
     {
390 403
       path: "/payments",
391 404
       name: "Payments",

+ 2
- 2
vue.config.js Bestand weergeven

@@ -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": {

Laden…
Annuleren
Opslaan