You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

propertyCreate.vue 18KB

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