소스 검색

Clean up of search. added property type & keywords search

master
George Williams 5 년 전
부모
커밋
5bfbd1c60f

+ 13
- 0
package-lock.json 파일 보기

@@ -11425,6 +11425,11 @@
11425 11425
       "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
11426 11426
       "dev": true
11427 11427
     },
11428
+    "trix": {
11429
+      "version": "1.2.0",
11430
+      "resolved": "https://registry.npmjs.org/trix/-/trix-1.2.0.tgz",
11431
+      "integrity": "sha512-gJ7edoWzcnc9DBjsgeGkmotVpyVhFQTlSOmUYjwFn71NlGixAhNgsu8pVIq/jkIkbk6om0PSetc9cRJm+qU3+A=="
11432
+    },
11428 11433
     "true-case-path": {
11429 11434
       "version": "1.0.3",
11430 11435
       "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
@@ -11917,6 +11922,14 @@
11917 11922
       "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
11918 11923
       "dev": true
11919 11924
     },
11925
+    "vue-trix": {
11926
+      "version": "1.0.0",
11927
+      "resolved": "https://registry.npmjs.org/vue-trix/-/vue-trix-1.0.0.tgz",
11928
+      "integrity": "sha512-rLt2kJurCGhdw3ovsGLuhCxjvASFijkyXXd8QsuPFZ7TGXQ+8xN7buIxXNGXne0r7es81Mks0+/E5IdPCN8zXQ==",
11929
+      "requires": {
11930
+        "trix": "^1.1.1"
11931
+      }
11932
+    },
11920 11933
     "vuetify": {
11921 11934
       "version": "1.5.16",
11922 11935
       "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-1.5.16.tgz",

+ 1
- 0
package.json 파일 보기

@@ -21,6 +21,7 @@
21 21
     "vue": "^2.6.10",
22 22
     "vue-eva-icons": "^1.1.1",
23 23
     "vue-router": "^3.0.7",
24
+    "vue-trix": "^1.0.0",
24 25
     "vuetify": "^1.5.5",
25 26
     "vuex": "^3.1.1"
26 27
   },

+ 8
- 3
src/components/property/propertyPage.vue 파일 보기

@@ -18,7 +18,12 @@
18 18
     <section class="property-single nav-arrow-b">
19 19
       <div class="container">
20 20
         <div class="row">
21
-          <lightBox :thumbnails="propertyImages" :largeImages="propertyImages" class="lightBox" />
21
+          <lightBox
22
+            :thumbnails="propertyImages"
23
+            :largeImages="propertyImages"
24
+            :caption="false"
25
+            class="lightBox"
26
+          />
22 27
         </div>
23 28
         <div class="row">
24 29
           <div class="col-sm-12">
@@ -27,7 +32,7 @@
27 32
                 <div class="row">
28 33
                   <div class="col-sm-12">
29 34
                     <div class="title-box-d">
30
-                      <h3 class="title-d">property Description</h3>
35
+                      <h3 class="title-d">Property Description</h3>
31 36
                     </div>
32 37
                   </div>
33 38
                 </div>
@@ -72,7 +77,7 @@
72 77
                   <div class="summary-list">
73 78
                     <ul class="list">
74 79
                       <li class="d-flex justify-content-between">
75
-                        <strong>property ID:</strong>
80
+                        <strong>Property ID:</strong>
76 81
                         <span>{{ property.id }}</span>
77 82
                       </li>
78 83
                       <li class="d-flex justify-content-between">

+ 42
- 0
src/components/property/propertySearchFields.vue 파일 보기

@@ -13,6 +13,36 @@
13 13
           <option value="Rent">Rent</option>
14 14
         </select>
15 15
       </div>
16
+      <div class="form-group" v-if="propertyType === 'Residential'">
17
+        <label for="city">Property Type</label>
18
+        <select
19
+          class="form-control form-control-lg form-control-a"
20
+          id="forSelector"
21
+          v-model="selectedPropertyTypeRes"
22
+          @change="PropertyTypeSelected"
23
+        >
24
+          <option>All</option>
25
+          <option
26
+            v-for="(propertyType, i) in propertyTypesRes"
27
+            :key="i"
28
+          >{{ propertyType.description }}</option>
29
+        </select>
30
+      </div>
31
+      <div v-else class="form-group">
32
+        <label for="city">Property Type</label>
33
+        <select
34
+          class="form-control form-control-lg form-control-a"
35
+          id="forSelector"
36
+          v-model="selectedPropertyTypeCom"
37
+          @change="PropertyTypeSelected"
38
+        >
39
+          <option>All</option>
40
+          <option
41
+            v-for="(propertyType, i) in propertyTypesCom"
42
+            :key="i"
43
+          >{{ propertyType.description }}</option>
44
+        </select>
45
+      </div>
16 46
       <div class="form-group">
17 47
         <label for="city">Provice</label>
18 48
         <select
@@ -61,26 +91,38 @@
61 91
 import { mapState, mapActions } from 'vuex';
62 92
 
63 93
 export default {
94
+  props: {
95
+    propertyType: String,
96
+  },
64 97
   data() {
65 98
     return {
66 99
       selectedType: 'Sale',
67 100
       selectedProvince: 'All',
68 101
       selectedCity: 'All',
69 102
       selectedSuburb: 'All',
103
+      selectedPropertyTypeRes: 'All',
104
+      selectedPropertyTypeCom: 'All',
70 105
     };
71 106
   },
72 107
   mounted() {
73 108
     this.getProvince();
74 109
     this.$emit('TypeSelectedUpdated', this.selectedType);
110
+    this.getPropertyTypesRes();
111
+    this.getPropertyTypesCom();
75 112
   },
76 113
   computed: {
77 114
     ...mapState('searchTab', ['provinces', 'cities', 'suburbs']),
115
+    ...mapState('property', ['propertyTypesRes', 'propertyTypesCom']),
78 116
   },
79 117
   methods: {
80 118
     ...mapActions('searchTab', ['getProvince', 'getCities', 'getSuburbs']),
119
+    ...mapActions('property', ['getPropertyTypesRes', 'getPropertyTypesCom']),
81 120
     TypeSelected(item) {
82 121
       this.$emit('TypeSelectedUpdated', item.target.value);
83 122
     },
123
+    PropertyTypeSelected(item) {
124
+      this.$emit('PropertyTypeSelectedUpdated', item.target.value);
125
+    },
84 126
     ProvinceSelected(item) {
85 127
       if (item.target.value !== 'All') {
86 128
         this.getCities(Object.assign({}, { province: this.selectedProvince }));

+ 38
- 11
src/components/property/propertySearchPage.vue 파일 보기

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

+ 3
- 8
src/components/property/propertyeditPage.vue 파일 보기

@@ -180,13 +180,7 @@
180 180
             <div class="form-group row">
181 181
               <div class="col-md-12">
182 182
                 <label for="Property Description"></label>
183
-                <textarea
184
-                  class="form-control editor"
185
-                  placeholder="Property Description"
186
-                  name="description"
187
-                  v-model="property.description"
188
-                  id="description"
189
-                ></textarea>
183
+                <TextEditor name="description" v-model="property.description" id="description" />
190 184
                 <br />
191 185
                 <p>* A listing fee of R380 including VAT is payable to list your Property on the Uni-Vate website</p>
192 186
               </div>
@@ -237,15 +231,16 @@
237 231
 
238 232
 <script>
239 233
 import { mapState, mapActions } from 'vuex';
234
+import TextEditor from 'vue-trix';
240 235
 import UserField from './propertyUserField.vue';
241 236
 import ImageLoad from './propertyImage.vue';
242 237
 
243
-// https://vuejsexamples.com/a-vue-wrapper-around-the-trix-rich-text-editor/
244 238
 export default {
245 239
   name: 'PropertyEdit',
246 240
   components: {
247 241
     UserField,
248 242
     ImageLoad,
243
+    TextEditor,
249 244
   },
250 245
   data() {
251 246
     return {

+ 11
- 11
src/components/shared/lightBoxGallery.vue 파일 보기

@@ -1,5 +1,5 @@
1 1
 <template>
2
-  <div>
2
+  <div class="scrolling-wrapper">
3 3
     <img
4 4
       @click="lightboxEffect(index)"
5 5
       v-for="(thumbnail, index) in thumbnails"
@@ -45,31 +45,31 @@ export default {
45 45
     return {
46 46
       bg: false,
47 47
       currentImage: 0,
48
-      count: true,
49
-      caption: true,
48
+      count: true
50 49
     };
51 50
   },
52 51
   props: {
53 52
     thumbnails: {
54 53
       type: Array,
55
-      required: true,
54
+      required: true
56 55
     },
57 56
     largeImages: {
58 57
       type: Array,
59
-      required: true,
58
+      required: true
60 59
     },
61 60
     captions: {
62 61
       type: Array,
63
-      required: true,
62
+      required: true
64 63
     },
65 64
     thumbnailsPath: {
66 65
       type: String,
67
-      required: true,
66
+      required: true
68 67
     },
69 68
     largePath: {
70 69
       type: String,
71
-      required: true,
70
+      required: true
72 71
     },
72
+    caption: true
73 73
   },
74 74
   methods: {
75 75
     lightboxEffect(curr) {
@@ -91,8 +91,8 @@ export default {
91 91
       } else {
92 92
         this.currentImage = this.largeImages.length - 1;
93 93
       }
94
-    },
95
-  },
94
+    }
95
+  }
96 96
 };
97 97
 </script>
98 98
 
@@ -135,7 +135,7 @@ export default {
135 135
     display: flex;
136 136
     justify-content: center;
137 137
     align-items: center;
138
-    max-width: 900px;
138
+    max-width: 700px;
139 139
     left: 50%;
140 140
     top: 50%;
141 141
     transform: translate(-50%, -50%);

+ 38
- 28
src/components/shared/searchTab.vue 파일 보기

@@ -15,19 +15,20 @@
15 15
                 type="text"
16 16
                 class="form-control form-control-lg form-control-a"
17 17
                 placeholder="Keyword"
18
+                v-model="keyword"
18 19
               />
19 20
             </div>
20 21
           </div>
21
-          <div class="col-md-12 mb-2">
22
+          <div class="col-md-12">
22 23
             <ul class="nav nav-pills-a nav-pills mb-3 section-t3" id="pills-tab" role="tablist">
23 24
               <li class="nav-item">
24 25
                 <a
25 26
                   class="nav-link active"
26
-                  id="pills-TimeShare-tab"
27
+                  id="pills-video-tab"
27 28
                   data-toggle="pill"
28
-                  href="#pills-TimeShare"
29
+                  href="#pills-video"
29 30
                   role="tab"
30
-                  aria-controls="pills-TimeShare"
31
+                  aria-controls="pills-video"
31 32
                   aria-selected="true"
32 33
                   v-on:click="updateType('Timeshare')"
33 34
                 >Timeshare</a>
@@ -35,23 +36,23 @@
35 36
               <li class="nav-item">
36 37
                 <a
37 38
                   class="nav-link"
38
-                  id="pills-Residential-tab"
39
+                  id="pills-plans-tab"
39 40
                   data-toggle="pill"
40
-                  href="#pills-Residential"
41
+                  href="#pills-plans"
41 42
                   role="tab"
42
-                  aria-controls="pills-Residential"
43
+                  aria-controls="pills-plans"
43 44
                   aria-selected="false"
44 45
                   v-on:click="updateType('Residential')"
45 46
                 >Residential</a>
46 47
               </li>
47 48
               <li class="nav-item">
48 49
                 <a
49
-                  class="nav-link active"
50
-                  id="pills-Commercial-tab"
50
+                  class="nav-link"
51
+                  id="pills-map-tab"
51 52
                   data-toggle="pill"
52
-                  href="#pills-Commercial"
53
+                  href="#pills-map"
53 54
                   role="tab"
54
-                  aria-controls="pills-Commercial"
55
+                  aria-controls="pills-map"
55 56
                   aria-selected="false"
56 57
                   v-on:click="updateType('Commercial')"
57 58
                 >Commercial</a>
@@ -60,38 +61,44 @@
60 61
             <div class="tab-content" id="pills-tabContent">
61 62
               <div
62 63
                 class="tab-pane fade show active"
63
-                id="pills-TimeShare"
64
+                id="pills-video"
64 65
                 role="tabpanel"
65
-                aria-labelledby="pills-TimeShare-tab"
66
-              >
67
-                <i>TimeShare search</i>
68
-              </div>
66
+                aria-labelledby="pills-video-tab"
67
+              >timeshare search</div>
69 68
               <div
70
-                class="tab-Residential fade"
71
-                id="pills-Residential"
69
+                class="tab-pane fade"
70
+                id="pills-plans"
72 71
                 role="tabpanel"
73
-                aria-labelledby="pills-Residential-tab"
72
+                aria-labelledby="pills-plans-tab"
74 73
               >
75 74
                 <propertySearch
75
+                  propertyType="Residential"
76 76
                   @TypeSelectedUpdated="TypeSelectedUpdated"
77 77
                   @ProvinceSelectedUpdated="ProvinceSelectedUpdated"
78 78
                   @CitySelectedUpdated="CitySelectedUpdated"
79 79
                   @SuburbSelectedUpdated="SuburbSelectedUpdated"
80
+                  @PropertyTypeSelectedUpdated="PropertyTypeSelectedUpdated"
80 81
                 />
81 82
               </div>
82 83
               <div
83 84
                 class="tab-pane fade"
84
-                id="pills-Commercial"
85
+                id="pills-map"
85 86
                 role="tabpanel"
86
-                aria-labelledby="pills-Commercial-tab"
87
+                aria-labelledby="pills-map-tab"
87 88
               >
88
-                <propertySearch />
89
+                <propertySearch
90
+                  propertyType="Commercial"
91
+                  @TypeSelectedUpdated="TypeSelectedUpdated"
92
+                  @ProvinceSelectedUpdated="ProvinceSelectedUpdated"
93
+                  @CitySelectedUpdated="CitySelectedUpdated"
94
+                  @SuburbSelectedUpdated="SuburbSelectedUpdated"
95
+                  @PropertyTypeSelectedUpdated="PropertyTypeSelectedUpdated"
96
+                />
89 97
               </div>
90 98
             </div>
91 99
           </div>
92 100
           <div class="col-md-12">
93 101
             <button type="submit" class="btn btn-b" @click="Search">Search</button>
94
-            <!-- <router-link to="/property/search" class="btn btn-b" tag="button">Search</router-link> -->
95 102
           </div>
96 103
         </div>
97 104
       </form>
@@ -113,6 +120,8 @@ export default {
113 120
       selectedProvince: '',
114 121
       selectedCity: '',
115 122
       selectedSuburb: '',
123
+      selectedPropType: '',
124
+      keyword: '',
116 125
     };
117 126
   },
118 127
   methods: {
@@ -122,6 +131,9 @@ export default {
122 131
     TypeSelectedUpdated(item) {
123 132
       this.selectedType = item;
124 133
     },
134
+    PropertyTypeSelectedUpdated(item) {
135
+      this.selectedPropType = item;
136
+    },
125 137
     ProvinceSelectedUpdated(item) {
126 138
       this.selectedProvince = item;
127 139
     },
@@ -132,10 +144,7 @@ export default {
132 144
       this.selectedSuburb = item;
133 145
     },
134 146
     Search() {
135
-      // if (
136
-      //   this.selectedPropertyType === 'residential'
137
-      //   || this.selectedPropertyType === 'commerial'
138
-      // ) {
147
+      // need to see how to differenciate between properties and timeshare.
139 148
       this.$router.push({
140 149
         path: '/property/search',
141 150
         query: {
@@ -144,9 +153,10 @@ export default {
144 153
           province: this.selectedProvince,
145 154
           city: this.selectedCity,
146 155
           suburb: this.selectedSuburb,
156
+          propType: this.propertyType,
157
+          keyword: this.keyword,
147 158
         },
148 159
       });
149
-      // }
150 160
     },
151 161
   },
152 162
 };

+ 38
- 0
src/store/modules/property/property.js 파일 보기

@@ -6,8 +6,11 @@ export default {
6 6
     property: null,
7 7
     propertyImages: [],
8 8
     propertyTypes: [],
9
+    propertyTypesRes: [],
10
+    propertyTypesCom: [],
9 11
     propertyOverviewFields: [],
10 12
     propertyFields: [],
13
+    properties: [],
11 14
   },
12 15
   mutations: {
13 16
     setProperty(state, property) {
@@ -19,6 +22,12 @@ export default {
19 22
     setPropertyTypes(state, types) {
20 23
       state.propertyTypes = types;
21 24
     },
25
+    setPropertyTypesRes(state, types) {
26
+      state.propertyTypesRes = types;
27
+    },
28
+    setPropertyTypesCom(state, types) {
29
+      state.propertyTypesCom = types;
30
+    },
22 31
     setPropertyOverviewFields(state, fields) {
23 32
       state.propertyOverviewFields = fields;
24 33
     },
@@ -28,6 +37,9 @@ export default {
28 37
     updateCurrentProperty(state, property) {
29 38
       state.property = property;
30 39
     },
40
+    updateSearch(state, propertySearch) {
41
+      state.properties = propertySearch;
42
+    },
31 43
   },
32 44
   getters: {},
33 45
   actions: {
@@ -49,6 +61,18 @@ export default {
49 61
         .then(result => commit('setPropertyTypes', result.data))
50 62
         .catch(console.error);
51 63
     },
64
+    getPropertyTypesRes({ commit }) {
65
+      axios
66
+        .get('http://localhost:57260/Property/PropertyType/type/Residential')
67
+        .then(result => commit('setPropertyTypesRes', result.data))
68
+        .catch(console.error);
69
+    },
70
+    getPropertyTypesCom({ commit }) {
71
+      axios
72
+        .get('http://localhost:57260/Property/PropertyType/type/Commercial')
73
+        .then(result => commit('setPropertyTypesCom', result.data))
74
+        .catch(console.error);
75
+    },
52 76
     getPropertyOverviewFields({ commit }) {
53 77
       axios
54 78
         .get('http://localhost:57260/Property/PropertyFields/Property Overview')
@@ -65,5 +89,19 @@ export default {
65 89
         .then(result => commit('updateCurrentProperty', result.data))
66 90
         .catch(console.error);
67 91
     },
92
+    searchPropertiesParams({ commit }, item) {
93
+      axios
94
+        .get(
95
+          `http://localhost:57260/Property/Property/Search/${item.type}/${item.propertyType}/${item.province}/${item.city}/${item.suburb}/${item.propType}`,
96
+        )
97
+        .then(response => commit('updateSearch', response.data))
98
+        .catch(console.error);
99
+    },
100
+    searchPropertiesKeyword({ commit }, item) {
101
+      axios
102
+        .get(`http://localhost:57260/Property/Property/Search/Keyword/${item.keyword}`)
103
+        .then(response => commit('updateSearch', response.data))
104
+        .catch(console.error);
105
+    },
68 106
   },
69 107
 };

Loading…
취소
저장