Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

propertyCreate.vue 22KB

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