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.

residentialCreateNew.vue 18KB

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