Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

propertyeditPage.vue 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  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">Edit Property: {{ property.shortDescription }}</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. <input
  46. class="form-control"
  47. type="text"
  48. name="unit"
  49. id="unit"
  50. v-model="property.propertyUsageType"
  51. disabled
  52. />
  53. </div>
  54. </div>
  55. </div>
  56. <div class="form-group row">
  57. <div class="col-md-4">
  58. <label>Sale Type</label>
  59. <propField
  60. :display="property.isSale ? 'Sale' : 'Rental'"
  61. :editType="'selector'"
  62. :arrayObject="salesTypeArr"
  63. :propertyName="'isSale'"
  64. :mayEdit="mayEdit"
  65. @UpdateValue="UpdateValue"
  66. />
  67. </div>
  68. </div>
  69. <div class="form-group row">
  70. <div class="col-md-4">
  71. <label>Property Type</label>
  72. <propField
  73. :display="property.propertyType ? property.propertyType.description : ''"
  74. :editType="'selector'"
  75. :arrayObject="propertyTypes"
  76. :propertyName="'propertyType'"
  77. :mayEdit="mayEdit"
  78. @UpdateValue="UpdateValue"
  79. />
  80. </div>
  81. <div v-if="propertyType === 'Commercial'" class="col-md-4">
  82. <label>Property Name</label>
  83. <propField
  84. :display="property.propertyName"
  85. :editType="'text'"
  86. :propertyName="'propertyName'"
  87. :mayEdit="mayEdit"
  88. @UpdateValue="UpdateValue"
  89. />
  90. </div>
  91. <div v-if="propertyType === 'Commercial'" class="col-md-4">
  92. <label>Unit</label>
  93. <propField
  94. :label="'Property Type'"
  95. :display="property.unit"
  96. :editType="'text'"
  97. :propertyName="'unit'"
  98. :mayEdit="mayEdit"
  99. @UpdateValue="UpdateValue"
  100. />
  101. </div>
  102. </div>
  103. <div class="form-group row">
  104. <div class="col-md-6" style="margin-bottom: 1em">
  105. <label>Street Number</label>
  106. <propField
  107. :display="property.addressLine1"
  108. :editType="'text'"
  109. :propertyName="'addressLine1'"
  110. :mayEdit="mayEdit"
  111. @UpdateValue="UpdateValue"
  112. />
  113. </div>
  114. <div class="col-md-6" style="margin-bottom: 1em">
  115. <label>Street Name</label>
  116. <propField
  117. :display="property.addressLine2"
  118. :editType="'text'"
  119. :propertyName="'addressLine2'"
  120. :mayEdit="mayEdit"
  121. @UpdateValue="UpdateValue"
  122. />
  123. </div>
  124. <div class="col-md-6" style="margin-bottom: 1em">
  125. <label>Province</label>
  126. <propField
  127. :display="property.province ? property.province.description : ''"
  128. :editType="'selector'"
  129. :arrayObject="provinces"
  130. :propertyName="'province'"
  131. :mayEdit="mayEdit"
  132. @UpdateValue="UpdateValue"
  133. />
  134. </div>
  135. <div class="col-md-6" style="margin-bottom: 1em">
  136. <label>City</label>
  137. <propField
  138. :display="property.city ? property.city.description : ''"
  139. :editType="'selector'"
  140. :arrayObject="cities"
  141. :propertyName="'city'"
  142. :mayEdit="mayEdit"
  143. @UpdateValue="UpdateValue"
  144. />
  145. </div>
  146. <div class="col-md-6" style="margin-bottom: 1em">
  147. <label>Suburb</label>
  148. <propField
  149. :display="property.suburb ? property.suburb.description : ''"
  150. :editType="'selector'"
  151. :arrayObject="suburbs"
  152. :propertyName="'suburb'"
  153. :mayEdit="mayEdit"
  154. @UpdateValue="UpdateValue"
  155. />
  156. </div>
  157. <div class="col-md-6" style="margin-bottom: 1em">
  158. <label>Postal Code</label>
  159. <propField
  160. :display="property.addressLine3"
  161. :editType="'text'"
  162. :propertyName="'addressLine3'"
  163. :mayEdit="mayEdit"
  164. @UpdateValue="UpdateValue"
  165. />
  166. </div>
  167. </div>
  168. <div class="form-group row">
  169. <div class="col-md-6">
  170. <label v-if="salesType === 'Rental'">Rental Price</label>
  171. <label v-if="salesType !== 'Rental'">Sales Price</label>
  172. <propField
  173. :display="String(property.price)"
  174. :editType="'number'"
  175. :propertyName="'price'"
  176. :mayEdit="mayEdit"
  177. @UpdateValue="UpdateValue"
  178. />
  179. </div>
  180. <div class="col-md-6" v-if="salesType === 'Rental'">
  181. <label>Per</label>
  182. <propField
  183. :display="property.pricePer"
  184. :editType="'selector'"
  185. :propertyName="'pricePer'"
  186. :arrayObject="pricePerArr"
  187. :mayEdit="mayEdit"
  188. @UpdateValue="UpdateValue"
  189. />
  190. </div>
  191. </div>
  192. <div class="form-group row">
  193. <div class="col-md-12">
  194. <label for="Property Description">Description</label>
  195. <vue-editor v-model="property.description" :editor-toolbar="customToolbar" />
  196. <br />
  197. <p>* A listing fee of R380 including VAT is payable to list your Property on the Uni-Vate website</p>
  198. </div>
  199. </div>
  200. <div class="form-group row" />
  201. <div
  202. class="col-md-6"
  203. v-if="propertyType === 'Residential' & propertyOverviewFields.length > 0"
  204. >
  205. <div v-for="(item, i) in propertyOverviewFields[0].fields" :key="item.id">
  206. <label>{{ item.name }}</label>
  207. <propField
  208. :display="item.value"
  209. :editType="item.type"
  210. :propertyId="item.itemID"
  211. :userDefinedId="item.id"
  212. :isUDF="Boolean('true')"
  213. :isPropOverview="Boolean('true')"
  214. :mayEdit="mayEdit"
  215. :arrayIndex="i"
  216. @UpdateValue="UpdateValue"
  217. />
  218. </div>
  219. </div>
  220. <div class="form-group row" />
  221. <div v-for="(group, i) in propertyFields" :key="group.id">
  222. <div class="row">
  223. <div class="col-sm-12">
  224. <div class="title-box-d">
  225. <h5 class="title-d">{{ group.name }}</h5>
  226. </div>
  227. </div>
  228. </div>
  229. <div v-for="(field, ii) in group.fields" :key="field.id">
  230. <label>{{ field.name }}</label>
  231. <propField
  232. :display="field.value"
  233. :editType="field.type"
  234. :propertyId="field.itemID"
  235. :userDefinedId="field.id"
  236. :isUDF="Boolean('true')"
  237. :arrayIndex="i"
  238. :arrayItemIndex="ii"
  239. :mayEdit="mayEdit"
  240. @UpdateValue="UpdateValue"
  241. />
  242. </div>
  243. </div>
  244. <div class="form-group row" />
  245. <div class="row">
  246. <div class="col-sm-12">
  247. <div class="title-box-d">
  248. <h5 class="title-d">Media</h5>
  249. </div>
  250. </div>
  251. </div>
  252. <div class="form-group row">
  253. <div class="col-md-12">
  254. <label>Virtual Tour (URL)</label>
  255. <propField
  256. :display="property.virtualTour"
  257. :editType="'text'"
  258. :propertyName="'virtualTour'"
  259. :mayEdit="mayEdit"
  260. @UpdateValue="UpdateValue"
  261. />
  262. </div>
  263. </div>
  264. <div class="form-group row">
  265. <div class="col-md-12">
  266. <label>Video (URL)</label>
  267. <propField
  268. :display="property.video"
  269. :editType="'text'"
  270. :propertyName="'video'"
  271. :mayEdit="mayEdit"
  272. @UpdateValue="UpdateValue"
  273. />
  274. </div>
  275. </div>
  276. <div class="form-group row">
  277. <div class="col-md-6">
  278. <label>Images</label>
  279. <div class="input-group-prepend"></div>
  280. </div>
  281. </div>
  282. <div class="form-group row">
  283. <div class="col-md-2" v-for="(img, i) in propertyImages" :key="i">
  284. <input
  285. v-if="mayEdit"
  286. type="checkbox"
  287. id="checkbox"
  288. v-model="img.isDefault"
  289. :disabled="img.isDeleted"
  290. />
  291. <label v-if="mayEdit" for="checkbox" style="margin: 10px;">Main Image</label>
  292. <br />
  293. <img
  294. :src="img.image"
  295. style="height:200px; width:150px; object-fit: cover;"
  296. :class="[img.isDeleted ? 'opacity' : '']"
  297. />
  298. <span
  299. v-if="!img.isDeleted && mayEdit"
  300. class="input-group-text"
  301. align="center"
  302. @click="DeleteImage(img)"
  303. >
  304. <eva-icon name="trash-2-outline" fill="#60CBEB"></eva-icon>Delete
  305. </span>
  306. </div>
  307. </div>
  308. <ImageLoad
  309. :loadedImages="loadedImages"
  310. @DefaultImage="UpdateDefaultImage"
  311. :mayEdit="mayEdit"
  312. />
  313. <button
  314. v-if="!wait"
  315. type="button"
  316. @click="SubmitData()"
  317. class="btn btn-b-n"
  318. style="width: 85px; height:40px;"
  319. :disabled="!mayEdit"
  320. >Save</button>
  321. <button
  322. type="button"
  323. @click="Close()"
  324. class="btn btn-b-n"
  325. style="width: 85px; height:40px;"
  326. >Close</button>
  327. <div v-if="wait" id="preloader"></div>
  328. </form>
  329. </div>
  330. </div>
  331. </div>
  332. </div>
  333. </template>
  334. <script>
  335. import { mapState, mapActions } from 'vuex';
  336. import { VueEditor } from 'vue2-editor';
  337. import { setTimeout } from 'timers';
  338. import ImageLoad from './propertyImage.vue';
  339. import propField from './propertyFieldEditor.vue';
  340. export default {
  341. name: 'PropertyEdit',
  342. components: {
  343. ImageLoad,
  344. VueEditor,
  345. propField,
  346. },
  347. data() {
  348. return {
  349. propertyType: 'Residential',
  350. salesType: 'Rental',
  351. images: [],
  352. propertyFieldValues: [],
  353. defaultImage: 0,
  354. wait: false,
  355. customToolbar: [
  356. [{ header: [false, 1, 2, 3, 4, 5, 6] }],
  357. ['bold', 'italic', 'underline', 'strike'],
  358. [
  359. { align: '' },
  360. { align: 'center' },
  361. { align: 'right' },
  362. { align: 'justify' },
  363. ],
  364. [{ list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],
  365. [{ script: 'sub' }, { script: 'super' }],
  366. [{ indent: '-1' }, { indent: '+1' }],
  367. ],
  368. salesTypeArr: [
  369. { id: 1, description: 'Sale' },
  370. { id: 2, description: 'Rental' },
  371. ],
  372. pricePerArr: [
  373. { id: 'Month', description: 'Month' },
  374. { id: 'Day', description: 'Day' },
  375. ],
  376. };
  377. },
  378. methods: {
  379. ...mapActions('searchTab', [
  380. 'getProvince',
  381. 'getCities',
  382. 'getSuburbs',
  383. 'getListsForPropertyEdit',
  384. ]),
  385. ...mapActions('property', ['getPropertyTypes']),
  386. ...mapActions('propertyEdit', [
  387. 'getSavedPropertyData',
  388. 'updateProperty',
  389. 'mayEditProperty',
  390. ]),
  391. UpdateValue(item) {
  392. if (item.isUDF) {
  393. if (item.isPropOverview) {
  394. this.propertyOverviewFields[0].fields[item.arrayIndex].value = item.value;
  395. } else if (item.isPropOverview === false) {
  396. this.propertyFields[item.arrayIndex].fields[
  397. item.arrayItemIndex
  398. ].value = item.value;
  399. }
  400. } else if (!item.isUDF) {
  401. if (item.fieldName) {
  402. if (item.fieldName === 'isSale') {
  403. let isSaleValue = false;
  404. if (item.value === 'Sale') {
  405. isSaleValue = true;
  406. } else isSaleValue = false;
  407. this.property.isSale = isSaleValue;
  408. }
  409. if (item.fieldName === 'propertyType') {
  410. this.property.propertyType = this.propertyTypes.find(
  411. pt => pt.description === item.value,
  412. );
  413. this.property.propertyTypeId = this.property.propertyType.id;
  414. }
  415. if (item.fieldName === 'propertyName') {
  416. this.property.propertyName = item.value;
  417. }
  418. if (item.fieldName === 'unit') {
  419. this.property.unit = item.value;
  420. }
  421. if (item.fieldName === 'addressLine1') {
  422. this.property.addressLine1 = item.value;
  423. }
  424. if (item.fieldName === 'addressLine2') {
  425. this.property.addressLine2 = item.value;
  426. }
  427. if (item.fieldName === 'addressLine3') {
  428. this.property.addressLine3 = item.value;
  429. }
  430. if (item.fieldName === 'province') {
  431. if (item.value !== '') {
  432. this.property.province = this.provinces.find(
  433. p => p.description === item.value,
  434. );
  435. this.property.provinceId = this.property.province.id;
  436. this.getCities(Object.assign({}, { province: item.value }));
  437. this.property.city = null;
  438. this.property.suburb = null;
  439. this.property.addressLine3 = '';
  440. } else {
  441. this.property.province = null;
  442. this.property.city = null;
  443. this.property.suburb = null;
  444. this.property.addressLine3 = '';
  445. this.cities = [];
  446. this.suburbs = [];
  447. }
  448. }
  449. if (item.fieldName === 'city') {
  450. if (item.value !== '') {
  451. const newCity = this.cities.find(
  452. p => p.description === item.value,
  453. );
  454. this.property.city = newCity;
  455. this.property.cityId = newCity.id;
  456. this.getSuburbs(
  457. Object.assign(
  458. {},
  459. {
  460. province: this.property.province.description,
  461. city: item.value,
  462. },
  463. ),
  464. );
  465. this.property.suburb = null;
  466. this.property.addressLine3 = '';
  467. } else {
  468. this.property.city = null;
  469. this.property.suburb = null;
  470. this.property.addressLine3 = '';
  471. this.suburbs = [];
  472. }
  473. }
  474. if (item.fieldName === 'suburb') {
  475. if (item.value !== '') {
  476. const newSuburb = this.suburbs.find(
  477. p => p.description === item.value,
  478. );
  479. this.property.suburb = newSuburb;
  480. this.property.suburbId = newSuburb.id;
  481. this.property.addressLine3 = this.property.suburb.postalCode;
  482. } else {
  483. this.property.suburb = null;
  484. this.property.addressLine3 = '';
  485. }
  486. }
  487. if (item.fieldName === 'price') {
  488. this.property.price = item.value;
  489. }
  490. if (item.fieldName === 'pricePer') {
  491. this.property.pricePer = item.value;
  492. }
  493. if (item.fieldName === 'virtualTour') {
  494. this.property.virtualTour = item.value;
  495. }
  496. if (item.fieldName === 'video') {
  497. this.property.video = item.value;
  498. }
  499. }
  500. }
  501. },
  502. TypeChanged() {
  503. this.propertyType = this.property.propertyUsageType;
  504. },
  505. SubmitData() {
  506. this.wait = true;
  507. this.newPropertyImages.propertyId = this.property.id;
  508. this.newPropertyImages.Images = [];
  509. // eslint-disable-next-line no-plusplus
  510. for (let i = 0; i < this.images.length; i++) {
  511. let setAsDefault = false;
  512. if (i === this.defaultImage) {
  513. setAsDefault = true;
  514. }
  515. this.newPropertyImages.images.push({
  516. image: this.images[i],
  517. isDefault: setAsDefault,
  518. });
  519. }
  520. this.property.propertyImages = this.propertyImages;
  521. // eslint-disable-next-line no-plusplus
  522. for (let i = 0; i < this.property.propertyImages.length; i++) {
  523. this.property.propertyImages[i].image = '';
  524. }
  525. this.property.propertyOverviewFields = this.propertyOverviewFields;
  526. this.property.propertyFields = this.propertyFields;
  527. this.updateProperty({
  528. property: this.property,
  529. images: this.newPropertyImages,
  530. });
  531. // console.log(JSON.stringify(this.newPropertyImages));
  532. // Need to change to promis.
  533. setTimeout(
  534. () => this.$router.push({
  535. path: '/property/admin/list/my',
  536. }),
  537. 5000,
  538. );
  539. },
  540. Close() {
  541. this.$router.push('/property/admin/list/my');
  542. },
  543. loadedImages(values) {
  544. this.images = values;
  545. },
  546. UpdateDefaultImage(item) {
  547. this.defaultImage = item;
  548. },
  549. DeleteImage(image) {
  550. this.propertyImages.find(item => item.id === image.id).isDeleted = true;
  551. },
  552. },
  553. mounted() {
  554. // Need to check this can remove unused code
  555. this.wait = false;
  556. this.images = [];
  557. this.defaultImage = 0;
  558. if (this.propertyOverviewFields.length > 0) {
  559. this.propertyOverviewFields = [];
  560. }
  561. if (this.propertyFields.length > 0) {
  562. this.propertyFields = [];
  563. }
  564. if (this.property.description !== '') {
  565. this.property.description = '';
  566. }
  567. if (this.$route.params.propertyUsageType) {
  568. this.propertyType = this.$route.params.propertyUsageType;
  569. }
  570. this.salesType = this.$route.params.saleType;
  571. this.getPropertyTypes(this.propertyType);
  572. this.getListsForPropertyEdit(this.$route.query.id);
  573. this.getSavedPropertyData(
  574. Object.assign({}, { id: this.$route.query.id, type: this.propertyType }),
  575. );
  576. this.mayEditProperty(this.$route.query.id);
  577. },
  578. computed: {
  579. ...mapState('searchTab', ['provinces', 'cities', 'suburbs']),
  580. ...mapState('property', ['propertyTypes']),
  581. ...mapState('propertyEdit', [
  582. 'propertyOverviewFields',
  583. 'propertyFields',
  584. 'property',
  585. 'propertyImages',
  586. 'mayEdit',
  587. 'newPropertyImages',
  588. ]),
  589. ...mapState('authentication', ['user']),
  590. SalesTypeChanged() {
  591. if (this.property && this.property.propertyUsageType) {
  592. // eslint-disable-next-line vue/no-side-effects-in-computed-properties
  593. this.propertyType = this.property.propertyUsageType;
  594. // eslint-disable-next-line vue/no-side-effects-in-computed-properties
  595. this.salesType = this.property.isSale ? 'Sale' : 'Rental';
  596. }
  597. this.getPropertyTypes(this.propertyType);
  598. return this.propertyType;
  599. },
  600. },
  601. watch: {
  602. SalesTypeChanged() {
  603. return null;
  604. },
  605. },
  606. };
  607. </script>
  608. <style>
  609. span {
  610. cursor: pointer;
  611. }
  612. .opacity {
  613. opacity: 0.5;
  614. filter: alpha(opacity=50);
  615. }
  616. </style>