Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

commercialCreateNew.vue 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  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-5" 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. <div class="row">
  149. <div class="col-sm-12">
  150. <div class="section-header">
  151. <h2>Media</h2>
  152. </div>
  153. </div>
  154. </div>
  155. <div class="form-group row">
  156. <div class="col-md-12">
  157. <label class="uniSelectLabel">Virtual Tour (URL)</label>
  158. <div class="input-group-prepend">
  159. <input
  160. class="form-control uniInput"
  161. type="link"
  162. name="vtlink"
  163. id="vtlink"
  164. v-model="property.virtualTour"
  165. />
  166. </div>
  167. </div>
  168. </div>
  169. <div class="row">
  170. <div class="col-md-12">
  171. <label class="uniSelectLabel">Video (URL)</label>
  172. <div class="input-group-prepend">
  173. <input
  174. class="form-control uniInput"
  175. type="link"
  176. name="vlink"
  177. id="vlink"
  178. v-model="property.video"
  179. />
  180. </div>
  181. </div>
  182. </div>
  183. <div class="row mt-3">
  184. <div class="col-md-6">
  185. <div class="content-header">
  186. <h2>Images</h2>
  187. </div>
  188. <div class="input-group-prepend"></div>
  189. </div>
  190. </div>
  191. <ImageLoad
  192. :loadedImages="loadedImages"
  193. :savedImages="propertyImages"
  194. @DefaultImage="UpdateDefaultImage"
  195. />
  196. <button v-if="!wait" type="button" @click="SubmitData()" class="btn-solid-blue">
  197. Save
  198. </button>
  199. <div v-if="showPropertyTypeError">
  200. <p class="alert myError">
  201. Missing fields. Please fill in all required fields. Marked with *
  202. </p>
  203. </div>
  204. <div v-if="wait" id="preloader"></div>
  205. </div>
  206. </main>
  207. </div>
  208. </template>
  209. <script>
  210. /* eslint-disable */
  211. import { mapState, mapActions } from "vuex";
  212. import { VueEditor } from "vue2-editor";
  213. import UserField from "../../propertyUserField.vue";
  214. import ImageLoad from "../../propertyImage.vue";
  215. import Log from "../../../../assets/Log";
  216. import carouselSection from "./carouselSection";
  217. import mapSection from "../../mapSection";
  218. export default {
  219. name: "PropertyCreate",
  220. components: {
  221. UserField,
  222. ImageLoad,
  223. VueEditor,
  224. carouselSection,
  225. mapSection
  226. },
  227. data() {
  228. return {
  229. propertyType: "Commercial",
  230. salesType: "Rental",
  231. images: [],
  232. propertyFieldValues: [],
  233. defaultImage: 0,
  234. wait: false,
  235. customToolbar: [
  236. [{ header: [false, 1, 2, 3, 4, 5, 6] }],
  237. ["bold", "italic", "underline", "strike"],
  238. [{ align: "" }, { align: "center" }, { align: "right" }, { align: "justify" }],
  239. [{ list: "ordered" }, { list: "bullet" }, { list: "check" }],
  240. [{ script: "sub" }, { script: "super" }],
  241. [{ indent: "-1" }, { indent: "+1" }]
  242. ],
  243. error: "",
  244. addressSet: false,
  245. showPropertyTypeError: false,
  246. showDateError: false,
  247. user: Log.getUser(),
  248. mayEdit: Log.isLoggedIn()
  249. };
  250. },
  251. methods: {
  252. ...mapActions("property", [
  253. "getPropertyTypes",
  254. "getPropertyOverviewFields",
  255. "getPropertyFields",
  256. "saveProperty",
  257. "getProperty",
  258. "getPropertyImages",
  259. "clearPropertyImages",
  260. "getPropertyEditDisplay",
  261. "getPropertySavedOverviewFields",
  262. "getPropertySavedFields",
  263. "getSavedPropertyData"
  264. ]),
  265. updateLocation(place) {
  266. this.addressSet = true;
  267. this.property.streetNumber = place.streetNumber;
  268. this.property.streetName = place.streetName;
  269. this.property.suburb = place.suburb;
  270. this.property.city = place.city;
  271. this.property.province = place.province;
  272. this.property.country = place.country;
  273. this.property.postalCode = place.postalCode;
  274. this.property.addressUrl = place.url;
  275. this.property.propertCoords = place.coords;
  276. },
  277. TypeChanged() {
  278. this.property.propertyUsageType = this.propertyType;
  279. },
  280. SubmitData() {
  281. if (this.property.propertyTypeId === 0) {
  282. this.showPropertyTypeError = true;
  283. }
  284. if (this.salesType === "Rental" && this.property.dateAvailable === "undef") {
  285. this.showDateError = true;
  286. }
  287. if (this.showPropertyTypeError || this.showDateError) {
  288. return;
  289. }
  290. this.wait = true;
  291. if (this.salesType === "Sale") {
  292. this.property.isSale = true;
  293. this.property.dateAvailable = new Date();
  294. }
  295. if (this.images.length > 0) {
  296. this.property.propertyImages = [];
  297. }
  298. // eslint-disable-next-line no-plusplus
  299. for (let i = 0; i < this.images.length; i++) {
  300. let setAsDefault = false;
  301. if (i === this.defaultImage) {
  302. setAsDefault = true;
  303. }
  304. this.property.propertyImages.push({
  305. image: this.images[i],
  306. isDefault: setAsDefault
  307. });
  308. }
  309. this.property.propertyUserFields = this.propertyFieldValues;
  310. if (this.user) {
  311. this.property.userId = this.user.id;
  312. }
  313. this.saveProperty(this.property)
  314. .then(fulfilled => {
  315. this.$router.push(`/property/residential/property/${fulfilled.data.id}`);
  316. })
  317. .catch(error => {
  318. console.log(error.message);
  319. });
  320. },
  321. Close() {
  322. this.$router.push("/property/admin/list/my");
  323. },
  324. Login() {
  325. this.$router.push("/user/login");
  326. },
  327. PropertyTypeSelected(item) {
  328. if (item.target.options.selectedIndex > 0) {
  329. this.showPropertyTypeError = false;
  330. } else {
  331. this.showPropertyTypeError = true;
  332. }
  333. },
  334. loadedImages(values) {
  335. this.images = values;
  336. },
  337. UpdateUserDefinedFields(item) {
  338. let update = false;
  339. this.propertyFieldValues.forEach(element => {
  340. if (element.userDefinedFieldId === item.userDefinedFieldId) {
  341. element.value = item.value;
  342. update = true;
  343. }
  344. });
  345. if (!update) {
  346. this.propertyFieldValues.push(item);
  347. }
  348. },
  349. UpdateDefaultImage(item) {
  350. this.defaultImage = item;
  351. }
  352. },
  353. mounted() {
  354. this.wait = false;
  355. this.getProperty(0);
  356. this.clearPropertyImages();
  357. this.images = [];
  358. this.defaultImage = 0;
  359. if (this.propertyOverviewFields.length > 0) {
  360. this.propertyOverviewFields = [];
  361. }
  362. if (this.propertyFields.length > 0) {
  363. this.propertyFields = [];
  364. }
  365. if (this.property.description !== "") {
  366. this.property.description = "";
  367. }
  368. if (this.$route.params.propertyUsageType) {
  369. this.propertyType = this.$route.params.propertyUsageType;
  370. }
  371. this.salesType = this.$route.params.saleType;
  372. this.getPropertyOverviewFields();
  373. this.getPropertyFields(this.propertyType);
  374. },
  375. computed: {
  376. ...mapState("property", [
  377. "propertyTypes",
  378. "propertyOverviewFields",
  379. "propertyFields",
  380. "property",
  381. "propertyImages"
  382. ]),
  383. ...mapState("authentication", ["user"]),
  384. SalesTypeChanged() {
  385. // eslint-disable-next-line vue/no-side-effects-in-computed-properties
  386. // this.propertyType = this.$route.params.propType;
  387. // eslint-disable-next-line vue/no-side-effects-in-computed-properties
  388. this.salesType = this.$route.params.saleType;
  389. if (this.property && this.property.propertyUsageType) {
  390. // eslint-disable-next-line vue/no-side-effects-in-computed-properties
  391. this.propertyType = this.property.propertyUsageType;
  392. }
  393. if (!this.$route.query.id) {
  394. this.getPropertyFields(this.propertyType);
  395. }
  396. this.getPropertyTypes(this.propertyType);
  397. return this.propertyType;
  398. }
  399. },
  400. watch: {
  401. SalesTypeChanged() {
  402. return null;
  403. }
  404. }
  405. };
  406. </script>
  407. <style lang="scss" scoped></style>