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 14KB

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