Bläddra i källkod

Landing Pages

master
George Williams 5 år sedan
förälder
incheckning
4239377658

Binär
Landing Pages.docx Visa fil


+ 5
- 0
package-lock.json Visa fil

12243
       "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
12243
       "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
12244
       "dev": true
12244
       "dev": true
12245
     },
12245
     },
12246
+    "vue-js-modal": {
12247
+      "version": "1.3.33",
12248
+      "resolved": "https://registry.npmjs.org/vue-js-modal/-/vue-js-modal-1.3.33.tgz",
12249
+      "integrity": "sha512-AeYn51cG/iSZbRAOnDrmzdv+Q8bBtElB3R0U37eM3NRKkcFsf6CLBw5lip1sSbichdn1ANfzjM+N1gki3GvMqw=="
12250
+    },
12246
     "vue-json-excel": {
12251
     "vue-json-excel": {
12247
       "version": "0.2.98",
12252
       "version": "0.2.98",
12248
       "resolved": "https://registry.npmjs.org/vue-json-excel/-/vue-json-excel-0.2.98.tgz",
12253
       "resolved": "https://registry.npmjs.org/vue-json-excel/-/vue-json-excel-0.2.98.tgz",

+ 1
- 0
package.json Visa fil

26
     "vue": "^2.6.11",
26
     "vue": "^2.6.11",
27
     "vue-carousel": "^0.18.0",
27
     "vue-carousel": "^0.18.0",
28
     "vue-eva-icons": "^1.1.1",
28
     "vue-eva-icons": "^1.1.1",
29
+    "vue-js-modal": "^1.3.33",
29
     "vue-json-excel": "^0.2.98",
30
     "vue-json-excel": "^0.2.98",
30
     "vue-router": "^3.1.5",
31
     "vue-router": "^3.1.5",
31
     "vue-trix": "^1.1.7",
32
     "vue-trix": "^1.1.7",

+ 21
- 13
src/App.vue Visa fil

1
 <template>
1
 <template>
2
   <div id="app">
2
   <div id="app">
3
-    <a href="#" class="back-to-top">
3
+    <a v-if="!isLandingPage" href="#" class="back-to-top">
4
       <i class="fa fa-chevron-up"></i>
4
       <i class="fa fa-chevron-up"></i>
5
     </a>
5
     </a>
6
-    <div class="click-closed"></div>
7
-    <SearchTab />
8
-    <NavBar @routerGoTo="routerGoTo" />
9
-    <div class="pushDown"></div>
10
-    <router-view />
11
-    <FooterSection class="margin-top" />
6
+    <div v-if="!isLandingPage" class="click-closed"></div>
7
+    <SearchTab v-if="!isLandingPage" />
8
+    <NavBar v-if="!isLandingPage" @routerGoTo="routerGoTo" />
9
+    <div v-if="!isLandingPage" class="pushDown"></div>
10
+    <router-view @setLandingPage="setLandingPage" />
11
+    <FooterSection v-if="!isLandingPage" class="margin-top" />
12
   </div>
12
   </div>
13
 </template>
13
 </template>
14
 
14
 
15
 <script>
15
 <script>
16
-import SearchTab from './components/shared/searchTab.vue';
17
-import NavBar from './components/shared/navBar.vue';
18
-import FooterSection from './components/shared/footerSection.vue';
16
+import SearchTab from "./components/shared/searchTab.vue";
17
+import NavBar from "./components/shared/navBar.vue";
18
+import FooterSection from "./components/shared/footerSection.vue";
19
 
19
 
20
 export default {
20
 export default {
21
-  name: 'app',
21
+  name: "app",
22
+  data() {
23
+    return {
24
+      isLandingPage: false
25
+    };
26
+  },
22
   components: {
27
   components: {
23
     SearchTab,
28
     SearchTab,
24
     NavBar,
29
     NavBar,
25
-    FooterSection,
30
+    FooterSection
26
   },
31
   },
27
   methods: {
32
   methods: {
28
     routerGoTo(goTo) {
33
     routerGoTo(goTo) {
29
       this.$router.push(goTo);
34
       this.$router.push(goTo);
30
     },
35
     },
31
-  },
36
+    setLandingPage(item) {
37
+      this.isLandingPage = item;
38
+    }
39
+  }
32
 };
40
 };
33
 </script>
41
 </script>
34
 
42
 

+ 33
- 0
src/components/marketing/clientView.vue Visa fil

1
+<template>
2
+  <div>
3
+    <div class="no-style" v-html="campaignHtml"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+import { mapState, mapActions } from "vuex";
9
+
10
+export default {
11
+  name: "clientView",
12
+  data() {
13
+    return {};
14
+  },
15
+  methods: {
16
+    ...mapActions("campaign", ["getCampaignHTML"]),
17
+    routerGoTo(goto) {
18
+      this.$router.push(goto);
19
+    }
20
+  },
21
+  mounted() {
22
+    this.getCampaignHTML(this.$route.params.id);
23
+    this.$emit("setLandingPage", true);
24
+    if (!this.campaign.isActive) {
25
+      console.log("reroute to exp");
26
+      this.$router.push("/CampaignExpired");
27
+    }
28
+  },
29
+  computed: {
30
+    ...mapState("campaign", ["campaignHtml"])
31
+  }
32
+};
33
+</script>

+ 472
- 0
src/components/marketing/landingPage.vue Visa fil

1
+<template>
2
+  <div>
3
+    <div class="container">
4
+      <div class="container">
5
+        <div class="row">
6
+          <div class="col-md-12 col-lg-8">
7
+            <div class="title-box-d">
8
+              <br />
9
+              <h1 class="title-d" style="text-align:left; font-size: 250%">Landing Page</h1>
10
+            </div>
11
+          </div>
12
+        </div>
13
+      </div>
14
+      <div class="container col-md-12" style="text-align:left">
15
+        <div class="form-goup row">
16
+          <div class="col-md-4">
17
+            <label>Campaign Name</label>
18
+            <input v-if="isNew" class="form-control" type="text" v-model="campaign.name" />
19
+            <FieldEditor v-else :type="'text'" v-model="campaign.name" :mayEdit="true" />
20
+          </div>
21
+          <div class="col-md-4">
22
+            <label>Start Date</label>
23
+            <input v-if="isNew" class="form-control" type="date" v-model="campaign.startDate" />
24
+            <FieldEditor v-else :type="'date'" v-model="campaign.startDate" :mayEdit="true" />
25
+          </div>
26
+          <div class="col-md-4">
27
+            <label>End Date</label>
28
+            <input v-if="isNew" class="form-control" type="date" v-model="campaign.endDate" />
29
+            <FieldEditor v-else :type="'date'" v-model="campaign.endDate" :mayEdit="true" />
30
+          </div>
31
+        </div>
32
+        <div class="form-goup row">
33
+          <div class="col-md-4">
34
+            <label>Subject</label>
35
+            <input v-if="isNew" class="form-control" type="text" v-model="campaign.subject" />
36
+            <FieldEditor v-else :type="'text'" v-model="campaign.subject" :mayEdit="true" />
37
+          </div>
38
+          <div class="col-md-4">
39
+            <label>Number of items per row</label>
40
+            <input v-if="isNew" class="form-control" type="number" v-model="campaign.itemsPerRow" />
41
+            <FieldEditor v-else :type="'number'" v-model="campaign.itemsPerRow" :mayEdit="true" />
42
+          </div>
43
+        </div>
44
+        <br />
45
+        <div class="col-md-12">
46
+          <label>Main Body</label>
47
+          <ul class="nav nav-tabs" id="myTab" role="tablist">
48
+            <li class="nav-item">
49
+              <a
50
+                class="nav-link active"
51
+                id="directions-tab"
52
+                data-toggle="tab"
53
+                href="#directions"
54
+                role="tab"
55
+                aria-controls="directions"
56
+                aria-selected="false"
57
+              >Html</a>
58
+            </li>
59
+            <li class="nav-item">
60
+              <a
61
+                class="nav-link"
62
+                id="resort-layout-tab"
63
+                data-toggle="tab"
64
+                href="#resort-layout"
65
+                role="tab"
66
+                aria-controls="resort-layout"
67
+                aria-selected="true"
68
+              >Preview</a>
69
+            </li>
70
+          </ul>
71
+          <div
72
+            class="tab-content"
73
+            id="myTabContent"
74
+            style="background-color:rgba(255,255,255,0.75);padding:10px;border:silver solid thin;border-radius:10px;"
75
+          >
76
+            <div
77
+              class="tab-pane fade show active"
78
+              style="background-color:rgba(255,255,255,0.75);padding:10px;"
79
+              id="directions"
80
+              role="tabpanel"
81
+              aria-labelledby="directions-tab"
82
+            >
83
+              <div class="text-left">
84
+                <div class="input-group mb-3">
85
+                  <label>
86
+                    <i>Place the tag [items] as a place holder for the week items.</i>
87
+                  </label>
88
+                </div>
89
+                <div class="input-group mb-3">
90
+                  <!-- <div class="input-group-prepend">
91
+                    <span class="input-group-text" style="color: #60CBEB">
92
+                      <b>B</b>
93
+                    </span>
94
+                  </div>-->
95
+                  <textarea
96
+                    class="form-control"
97
+                    type="text"
98
+                    rows="10"
99
+                    step="any"
100
+                    name="levy"
101
+                    v-model="campaign.body"
102
+                  />
103
+                </div>
104
+              </div>
105
+            </div>
106
+            <div
107
+              class="tab-pane fade"
108
+              id="resort-layout"
109
+              role="tabpanel"
110
+              aria-labelledby="resort-layout-tab"
111
+            >
112
+              <div class="no-style" v-html="campaign.body"></div>
113
+            </div>
114
+          </div>
115
+        </div>
116
+        <br />
117
+        <div class="col-md-12">
118
+          <label>Item Template</label>
119
+          <ul class="nav nav-tabs" id="myTab" role="tablist">
120
+            <li class="nav-item">
121
+              <a
122
+                class="nav-link active"
123
+                id="template-tab"
124
+                data-toggle="tab"
125
+                href="#template"
126
+                role="tab"
127
+                aria-controls="template"
128
+                aria-selected="false"
129
+              >Html</a>
130
+            </li>
131
+            <li class="nav-item">
132
+              <a
133
+                class="nav-link"
134
+                id="preview-tab"
135
+                data-toggle="tab"
136
+                href="#preview"
137
+                role="tab"
138
+                aria-controls="preview"
139
+                aria-selected="true"
140
+              >Preview</a>
141
+            </li>
142
+          </ul>
143
+          <div
144
+            class="tab-content"
145
+            id="myTabContent"
146
+            style="background-color:rgba(255,255,255,0.75);padding:10px;border:silver solid thin;border-radius:10px;"
147
+          >
148
+            <div
149
+              class="tab-pane fade show active"
150
+              style="background-color:rgba(255,255,255,0.75);padding:10px;"
151
+              id="template"
152
+              role="tabpanel"
153
+              aria-labelledby="template-tab"
154
+            >
155
+              <div class="text-left">
156
+                <div class="input-group mb-3">
157
+                  <label>
158
+                    <i>
159
+                      Place the tag [image] as a place holder for the week's image.
160
+                      <br />Place the tag [link] for a hypher link to the week's page
161
+                    </i>
162
+                  </label>
163
+                </div>
164
+                <div class="input-group mb-3">
165
+                  <!-- <div class="input-group-prepend">
166
+                    <span class="input-group-text" style="color: #60CBEB">
167
+                      <b>B</b>
168
+                    </span>
169
+                  </div>-->
170
+                  <textarea
171
+                    class="form-control"
172
+                    type="text"
173
+                    rows="10"
174
+                    step="any"
175
+                    name="levy"
176
+                    v-model="campaign.itemBody"
177
+                  />
178
+                </div>
179
+              </div>
180
+            </div>
181
+            <div class="tab-pane fade" id="preview" role="tabpanel" aria-labelledby="preview-tab">
182
+              <div class="no-style" v-html="campaign.itemBody"></div>
183
+            </div>
184
+          </div>
185
+        </div>
186
+        <div class="col-md-12"></div>
187
+        <br />
188
+        <div class="col-md-12">
189
+          <label>
190
+            <b>Place Holders</b>
191
+          </label>
192
+          <div class="d-flex">
193
+            <div class="p-2">
194
+              <div
195
+                class="btn btn-primary myBackground"
196
+                @click="addClose()"
197
+                v-if="CanEdit"
198
+              >{{btnCaption}}</div>
199
+            </div>
200
+          </div>
201
+        </div>
202
+        <div class="col-md-12" v-if="showNew">
203
+          <LandingPageItems
204
+            @onItemAdd="onItemAdd"
205
+            :selectedClass="defaultPlaceholderClass"
206
+            :canSelectClass="false"
207
+            :editItem="placeholderItem"
208
+          />
209
+        </div>
210
+        <div class="col-md-12">
211
+          <hr />
212
+        </div>
213
+        <div class="col-md-12">
214
+          <ListView
215
+            :items="PlaceHolders"
216
+            :hideSearch="true"
217
+            :showColumnChooser="false"
218
+            :showNew="false"
219
+            :allowMultipleSelect="true"
220
+            :canEdit="false"
221
+            :deleteable="CanEdit"
222
+            @onDelete="onItemDelete"
223
+            :displayColumns="placeHolderColumns"
224
+            :sortKey="'name'"
225
+          />
226
+          <!-- :displayColumns="placeHolderColumns" -->
227
+        </div>
228
+        <br />
229
+        <div class="col-md-12">
230
+          <label>
231
+            <b>Weeks</b>
232
+          </label>
233
+          <div class="d-flex">
234
+            <div class="p-2">
235
+              <div
236
+                class="btn btn-primary myBackground"
237
+                @click="addWeekClose()"
238
+                v-if="CanEditWeeks"
239
+              >{{btnCaptionWeek}}</div>
240
+            </div>
241
+          </div>
242
+        </div>
243
+        <div class="col-md-12" v-if="showNewWeek">
244
+          <WeekAdd @onWeekItemAdd="AddNewWeek" />
245
+        </div>
246
+        <div class="col-md-12">
247
+          <hr />
248
+        </div>
249
+        <div class="col-md-12">
250
+          <ListView
251
+            :items="Weeks"
252
+            :hideSearch="true"
253
+            :showColumnChooser="false"
254
+            :showNew="false"
255
+            :canEdit="false"
256
+            :deleteable="CanEdit"
257
+            :allowMultipleSelect="false"
258
+            @onDelete="onItemDeleteWeek"
259
+            :sortKey="'weekUni'"
260
+            :displayColumns="weekColumns"
261
+            :displayFormats="weekFormats"
262
+          />
263
+          <!-- -->
264
+        </div>
265
+        <br />
266
+        <br />
267
+        <div class="form-group row">
268
+          <button
269
+            type="button"
270
+            @click="SaveData()"
271
+            class="btn btn-primary myBackground"
272
+            style="width: 85px; height:40px;"
273
+          >Save</button>
274
+          <button
275
+            type="button"
276
+            @click="Close()"
277
+            class="btn btn-primary myBackground"
278
+            style="width: 85px; height:40px;"
279
+          >Close</button>
280
+        </div>
281
+      </div>
282
+      <div v-if="wait" id="preloader"></div>
283
+    </div>
284
+  </div>
285
+</template>
286
+
287
+<script>
288
+import { VueEditor } from "vue2-editor";
289
+import { mapState, mapActions } from "vuex";
290
+import FieldEditor from "../../components/shared/fieldEditor";
291
+import ListView from "../shared/listView.vue";
292
+import Search from "../admin/misc/carouselSearch.vue";
293
+import LandingPageItems from "./landingPageItems.vue";
294
+import WeekAdd from "./landingPageWeek.vue";
295
+
296
+export default {
297
+  name: "LandingPage",
298
+  components: {
299
+    VueEditor,
300
+    FieldEditor,
301
+    Search,
302
+    LandingPageItems,
303
+    ListView,
304
+    WeekAdd
305
+  },
306
+  data() {
307
+    return {
308
+      wait: false,
309
+      isNew: true,
310
+      showNew: false,
311
+      showNewWeek: false,
312
+      weekColumns: ["image", "weekUni"],
313
+      weekFormats: ["image", ""],
314
+      placeHolderColumns: ["name", "boundTo", "format"],
315
+      defaultPlaceholderClass: {
316
+        fullName: "UnivateProperties_API.Model.Timeshare.TimeshareWeek",
317
+        name: "TimeshareWeek"
318
+      }
319
+    };
320
+  },
321
+  props: {
322
+    placeHolders: [],
323
+    weeks: [],
324
+    editable: {
325
+      default: false
326
+    }
327
+  },
328
+  methods: {
329
+    ...mapActions("campaign", [
330
+      "getCampaign",
331
+      "saveCampaign",
332
+      "updateCampaign",
333
+      "getCampaignItems",
334
+      "getCampaignPlaceHolders"
335
+    ]),
336
+    SaveData() {
337
+      this.wait = true;
338
+      if (this.isNew) {
339
+        for (let i = 0; i < this.campaign.items.length; i++) {
340
+          this.campaign.items[i].week = undefined;
341
+          if (
342
+            this.campaign.items[i].placeHolders &&
343
+            this.campaign.items[i].placeHolders.length > 0
344
+          ) {
345
+            this.campaign.items[
346
+              i
347
+            ].campaignItemPlaceHolder = this.campaign.items[i].placeHolders;
348
+          }
349
+        }
350
+
351
+        for (let i = 0; i < this.campaign.placeHolders.length; i++) {
352
+          this.campaign.placeHolders[i].format = this.campaign.placeHolders[
353
+            i
354
+          ].formatTemplate;
355
+        }
356
+        console.log(JSON.stringify(this.campaign));
357
+        // this.saveCampaign(this.campaign)
358
+        //   .then(fulfilled => {
359
+        //     this.$router.push("/landingPages");
360
+        //   })
361
+        //   .catch(error => {
362
+        //     console.log(error.message);
363
+        //   });
364
+      } else {
365
+        this.updateCampaign(this.campaign).then(() => {
366
+          this.$router.push("/landingPages");
367
+        });
368
+      }
369
+    },
370
+    Close() {
371
+      this.$router.push("/landingPages");
372
+    },
373
+    NewWeek() {
374
+      this.$router.push("/landingPage/week/0");
375
+    },
376
+    onItemAdd(item) {
377
+      const myList = this.campaign.placeHolders
378
+        ? this.campaign.placeHolders
379
+        : [];
380
+      myList.push({
381
+        name: item.name,
382
+        boundTo: item.property,
383
+        boundToClassDisplay: item.class.name,
384
+        boundToClass: item.class.fullName,
385
+        format: item.format,
386
+        formatTemplate: item.formatTemplate
387
+      });
388
+      this.PlaceHolders = myList;
389
+      this.campaign.placeHolders = this.PlaceHolders;
390
+      this.showNew = false;
391
+    },
392
+    addClose() {
393
+      if (this.showNew) {
394
+        this.showNew = false;
395
+      } else this.showNew = true;
396
+    },
397
+    addWeekClose() {
398
+      if (this.showNewWeek) {
399
+        this.showNewWeek = false;
400
+      } else {
401
+        this.showNewWeek = true;
402
+      }
403
+    },
404
+    onItemDelete(item) {
405
+      this.campaign.placeHolders = _.remove(
406
+        this.campaign.placeHolders,
407
+        x => x !== item
408
+      );
409
+      this.placeHolders = this.campaign.placeHolders;
410
+    },
411
+    // AddWeek(item) {
412
+    //   // const myList = this.campaign.items ? this.campaign.items : [];
413
+    //   // myList.push(item);
414
+    //   // this.campaign.items = myList;
415
+    //   //this.showNewWeek = false;
416
+    // },
417
+    AddNewWeek(week) {
418
+      var item = {
419
+        image: week.image,
420
+        weekUni: week.week.weekUni,
421
+        weekId: week.weekId,
422
+        placeHolders: week.placeHolders
423
+      };
424
+      this.campaign.items.push(item);
425
+      this.showNewWeek = false;
426
+    },
427
+    onItemDeleteWeek(item) {
428
+      this.campaign.items = _.remove(this.campaign.items, x => x !== item);
429
+      this.Weeks = this.campaign.items;
430
+    }
431
+  },
432
+  mounted() {
433
+    this.getCampaign(this.$route.params.id);
434
+
435
+    this.wait = false;
436
+    if (this.$route.params.id > 0) {
437
+      this.isNew = false;
438
+    }
439
+  },
440
+  computed: {
441
+    ...mapState("campaign", [
442
+      "campaign",
443
+      "campaignPlaceHolders",
444
+      "campaignItems"
445
+    ]),
446
+    PlaceHolders() {
447
+      if (this.campaign && this.campaign.placeHolders) {
448
+        return this.campaign.placeHolders;
449
+      }
450
+      return this.placeHolders;
451
+    },
452
+    Weeks() {
453
+      if (this.campaign && this.campaign.items) {
454
+        return this.campaign.items;
455
+      }
456
+      return this.weeks;
457
+    },
458
+    CanEdit() {
459
+      return this.editable || this.campaign.id === 0;
460
+    },
461
+    CanEditWeeks() {
462
+      return this.editable || this.campaign.id === 0;
463
+    },
464
+    btnCaption() {
465
+      return this.showNew ? "Close" : "New";
466
+    },
467
+    btnCaptionWeek() {
468
+      return this.showNewWeek ? "Close" : "New";
469
+    }
470
+  }
471
+};
472
+</script>

+ 6
- 0
src/components/marketing/landingPageExpired.vue Visa fil

1
+<template>
2
+  <div>
3
+    <br />
4
+    <H2>Sorry, this Marketing Campaign has expired</H2>
5
+  </div>
6
+</template>

+ 120
- 0
src/components/marketing/landingPageItems.vue Visa fil

1
+<template>
2
+  <div class="row">
3
+    <div class="col-md-12" v-if="message !== undefined">
4
+      <Alert :text="message" :type="'ERROR'" />
5
+    </div>
6
+    <div class="col-md-3">
7
+      <input
8
+        class="form-control"
9
+        type="text"
10
+        step="any"
11
+        name="levy"
12
+        placeholder="Name"
13
+        v-model="item.name"
14
+      />
15
+    </div>
16
+    <!-- <div class="col-md-3">
17
+      <select
18
+        v-if="canSelectClass"
19
+        class="form-control"
20
+        v-model="item.class"
21
+        @change="onClassChanged()"
22
+      >
23
+        <option v-for="(item, i) in classes" :key="i" :value="item">{{item.name}}</option>
24
+      </select>
25
+      <input v-else disabled class="form-control" v-model="selectedClass.name" />
26
+    </div>-->
27
+    <div class="col-md-3">
28
+      <select class="form-control" v-model="item.property">
29
+        <option v-for="(item, i) in properties" :key="i">{{item}}</option>
30
+      </select>
31
+    </div>
32
+    <div class="col-md-3">
33
+      <select class="form-control" v-model="item.format" @change="onFormatChanged">
34
+        <option v-for="(item, i) in formats" :key="i">{{item.displayName}}</option>
35
+      </select>
36
+    </div>
37
+    <div class="col-md-3">
38
+      <div class="btn btn-primary myBackground w-100" @click="onItemAdd()">Add</div>
39
+    </div>
40
+  </div>
41
+</template>
42
+<script>
43
+import { mapState, mapActions } from "vuex";
44
+import Alert from "../shared/alert.vue";
45
+
46
+export default {
47
+  components: {
48
+    Alert
49
+  },
50
+  mounted() {
51
+    this.init();
52
+    this.getFormats();
53
+    if (this.selectedClass !== undefined) {
54
+      this.item.class = this.selectedClass;
55
+      this.getProperties(this.item.class);
56
+    }
57
+  },
58
+  data() {
59
+    return {
60
+      message: undefined,
61
+      item: {
62
+        name: undefined,
63
+        class: undefined,
64
+        property: undefined,
65
+        format: "",
66
+        formatTemplate: ""
67
+      }
68
+    };
69
+  },
70
+  props: {
71
+    canSelectClass: {
72
+      default: true
73
+    },
74
+    selectedClass: {
75
+      default: Object
76
+    }
77
+  },
78
+  computed: {
79
+    ...mapState("info", ["classes", "properties"]),
80
+    ...mapState("placeHolderFormat", ["formats"]),
81
+    SelectedClass() {
82
+      this.item.class = selectedClass;
83
+    }
84
+  },
85
+  methods: {
86
+    ...mapActions("info", ["init", "getClasses", "getProperties"]),
87
+    ...mapActions("placeHolderFormat", ["getFormats"]),
88
+    onClassChanged() {
89
+      this.getProperties(this.item.class);
90
+    },
91
+    onFormatChanged(item) {
92
+      let val = this.formats.find(f => f.displayName == item.target.value);
93
+      this.item.formatTemplate = val.format;
94
+    },
95
+    onItemAdd() {
96
+      this.message = undefined;
97
+      let msg = "";
98
+
99
+      if (this.selectedClass !== undefined) {
100
+        this.item.class = this.selectedClass;
101
+      }
102
+
103
+      if (this.item.name === undefined) {
104
+        msg += "Please give a name...";
105
+      }
106
+      if (this.item.class === undefined) {
107
+        msg += "Please choose a class...";
108
+      }
109
+      if (this.item.property === undefined) {
110
+        msg += "Please choose a property...";
111
+      }
112
+      if (msg.length > 0) {
113
+        this.message = msg;
114
+      } else {
115
+        this.$emit("onItemAdd", this.item);
116
+      }
117
+    }
118
+  }
119
+};
120
+</script>

+ 262
- 0
src/components/marketing/landingPageWeek.vue Visa fil

1
+<template>
2
+  <div>
3
+    <div class="row">
4
+      <div class="col-md-12" v-if="message !== undefined">
5
+        <Alert :text="message" :type="'ERROR'" />
6
+      </div>
7
+    </div>
8
+    <div class="container col-md-12" style="text-align:left">
9
+      <div class="form-group row">
10
+        <div class="col-md-2">
11
+          <label>Find Week</label>
12
+          <button
13
+            type="button"
14
+            class="input-group-text fa fa-search"
15
+            style="color: #60CBEB"
16
+            data-toggle="modal"
17
+            data-target="#myModalWeeks"
18
+          ></button>
19
+          <!-- Modal content-->
20
+          <div id="myModalWeeks" class="modal fade" role="dialog">
21
+            <div class="modal-dialog modal-lg">
22
+              <div class="modal-content">
23
+                <div class="modal-header">
24
+                  <button type="button" class="close" data-dismiss="modal"></button>
25
+                </div>
26
+                <div padding-left="20px">
27
+                  <Search :name="'Timeshare'" @onSelected="onSelected" />
28
+                </div>
29
+                <div class="modal-footer">
30
+                  <button
31
+                    type="button"
32
+                    class="btn btn-b-n"
33
+                    style="width: 150px; height:40px;"
34
+                    data-dismiss="modal"
35
+                  >Close</button>
36
+                </div>
37
+              </div>
38
+            </div>
39
+          </div>
40
+          <!-- Modal content END-->
41
+        </div>
42
+        <div class="col-md-3">
43
+          <input class="form-control" type="label" disabled :value="weekUni" />
44
+        </div>
45
+        <div class="col-md-2">
46
+          <label>Upload Image?</label>
47
+          <div class="custom-control custom-switch">
48
+            <input
49
+              type="checkbox"
50
+              class="custom-control-input"
51
+              id="customSwitch1"
52
+              :checked="uploadImage"
53
+              @change="checkImage"
54
+            />
55
+            <label class="custom-control-label" for="customSwitch1">{{uploadImage ? 'Yes' : 'No'}}</label>
56
+          </div>
57
+        </div>
58
+        <div class="col-md-3">
59
+          <Images v-if="uploadImage" :allowMultiple="false" :loadedImages="LoadedImages" />
60
+          <input
61
+            v-else
62
+            class="form-control"
63
+            type="text"
64
+            placeholder="image url"
65
+            v-model="weekItem.imageUrl"
66
+          />
67
+        </div>
68
+        <div class="col-md-2">
69
+          <label>Custom Place holders</label>
70
+          <div class="custom-control custom-switch">
71
+            <input
72
+              type="checkbox"
73
+              class="custom-control-input"
74
+              id="customSwitch2"
75
+              :checked="showPlaceholder"
76
+              @change="ShowFields"
77
+            />
78
+            <label
79
+              class="custom-control-label"
80
+              for="customSwitch2"
81
+            >{{showPlaceholder ? 'Yes' : 'No'}}</label>
82
+          </div>
83
+        </div>
84
+      </div>
85
+      <hr v-if="showPlaceholder" />
86
+      <!-- <div class="form-group row">
87
+        <div class="col-md-5">
88
+          <button
89
+            type="button"
90
+            @click="ShowFields()"
91
+            class="btn btn-primary myBackground"
92
+          >Add Custom Place Holders</button>
93
+        </div>
94
+      </div>-->
95
+      <div class="form-group row">
96
+        <div class="col-md-12" v-if="messageCPH !== undefined">
97
+          <Alert :text="messageCPH" :type="'ERROR'" />
98
+        </div>
99
+      </div>
100
+      <div class="form-group row" v-if="showPlaceholder">
101
+        <div class="col-md-2">
102
+          <label>Place Holder</label>
103
+        </div>
104
+        <div class="col-md-3">
105
+          <input class="form-control" type="text" v-model="placeHolder" />
106
+        </div>
107
+        <div class="col-md-2">
108
+          <label>Value</label>
109
+        </div>
110
+        <div class="col-md-3">
111
+          <input class="form-control" type="text" v-model="value" />
112
+        </div>
113
+        <div class="col-md-2">
114
+          <button
115
+            type="button"
116
+            @click="AddCustomHolder()"
117
+            class="btn btn-primary myBackground"
118
+            style="width: 85px; height:40px;"
119
+          >Add</button>
120
+        </div>
121
+      </div>
122
+      <div class="form-group row" v-if="showPlaceholder">
123
+        <div class="col-md-12">
124
+          <ListView
125
+            :items="placeHolders"
126
+            :hideSearch="true"
127
+            :showColumnChooser="false"
128
+            :showNew="false"
129
+            :allowMultipleSelect="false"
130
+            :canEdit="false"
131
+            :deleteable="true"
132
+            @onDelete="onItemDelete"
133
+          />
134
+        </div>
135
+      </div>
136
+      <div class="form-group row">
137
+        <div class="col-md-1 offset-md-11">
138
+          <button
139
+            type="button"
140
+            @click="SaveData()"
141
+            class="btn btn-primary myBackground"
142
+            style="width: 85px; height:40px;"
143
+          >Add</button>
144
+        </div>
145
+      </div>
146
+    </div>
147
+  </div>
148
+</template>
149
+
150
+<script>
151
+import Search from "../admin/misc/carouselSearch.vue";
152
+import Images from "../property/propertyImage.vue";
153
+import { mapState, mapActions } from "vuex";
154
+import Alert from "../shared/alert.vue";
155
+import ListView from "../shared/listView.vue";
156
+
157
+export default {
158
+  name: "LandingPageWeek",
159
+  components: {
160
+    Search,
161
+    Images,
162
+    Alert,
163
+    ListView
164
+  },
165
+  data() {
166
+    return {
167
+      uploadImage: false,
168
+      message: undefined,
169
+      messageCPH: undefined,
170
+      weekUni: "",
171
+      weekItem: {
172
+        selectedWeek: undefined,
173
+        image: undefined,
174
+        imageUrl: undefined
175
+      },
176
+      placeHolders: [],
177
+      showPlaceholder: false,
178
+      placeHolder: undefined,
179
+      value: undefined
180
+    };
181
+  },
182
+  methods: {
183
+    ...mapActions("campaignItem", ["getCampaignItem"]),
184
+    onSelected(item) {
185
+      this.weekItem.selectedWeek = item[0];
186
+      this.weekUni = item[0].weekUni;
187
+    },
188
+    checkImage(item) {
189
+      this.uploadImage = !this.uploadImage;
190
+    },
191
+    ShowFields() {
192
+      this.showPlaceholder = !this.showPlaceholder;
193
+    },
194
+    SaveData() {
195
+      this.message = undefined;
196
+      let msg = "";
197
+      if (this.weekItem.selectedWeek === undefined) {
198
+        msg += "Please select a week. ";
199
+      }
200
+      if (
201
+        this.weekItem.image === undefined &&
202
+        this.weekItem.imageUrl === undefined
203
+      ) {
204
+        msg += "Please select an image for this week. ";
205
+      }
206
+      if (msg.length > 0) {
207
+        this.message = msg;
208
+      } else {
209
+        if (this.uploadImage) {
210
+          this.campaignItem.image = this.weekItem.image[0];
211
+        } else {
212
+          this.campaignItem.image = this.weekItem.imageUrl;
213
+        }
214
+        this.campaignItem.week = this.weekItem.selectedWeek;
215
+        this.campaignItem.weekId = this.weekItem.selectedWeek.id;
216
+
217
+        if (this.placeHolders.length > 0) {
218
+          this.campaignItem.placeHolders = this.placeHolders;
219
+          this.placeHolders = [];
220
+        }
221
+        this.$emit("onWeekItemAdd", this.campaignItem);
222
+        this.campaignItem.placeHolders = [];
223
+      }
224
+    },
225
+    LoadedImages(values) {
226
+      this.weekItem.image = values;
227
+    },
228
+    AddCustomHolder() {
229
+      this.messageCPH = undefined;
230
+      let msg = "";
231
+
232
+      if (this.placeHolder === undefined) {
233
+        msg += "Please enter a Place Holder name. ";
234
+      }
235
+      if (this.value === undefined) {
236
+        msg += "Please enter a Value. ";
237
+      }
238
+
239
+      if (msg.length > 0) {
240
+        this.messageCPH = msg;
241
+      } else {
242
+        this.placeHolders.push({
243
+          placeHolder: this.placeHolder,
244
+          value: this.value
245
+        });
246
+        this.placeHolder = undefined;
247
+        this.value = undefined;
248
+      }
249
+    },
250
+    onItemDelete(item) {
251
+      this.placeHolders = _.remove(this.placeHolders, x => x !== item);
252
+    }
253
+  },
254
+  mounted() {
255
+    this.getCampaignItem(this.$route.params.id);
256
+  },
257
+  computed: {
258
+    ...mapState("campaignItem", ["campaignItem"])
259
+  }
260
+};
261
+</script>
262
+

+ 87
- 0
src/components/marketing/landingPages.vue Visa fil

1
+<template>
2
+  <!-- eslint-disable max-len -->
3
+  <div>
4
+    <div class="container">
5
+      <div class="container">
6
+        <br />
7
+        <br />
8
+        <div class="row">
9
+          <div class="col-md-12 col-lg-8">
10
+            <div class="title-box-d">
11
+              <h1 class="title-d" style="text-align:left; font-size: 250%">Landing Pages</h1>
12
+            </div>
13
+          </div>
14
+        </div>
15
+      </div>
16
+    </div>
17
+    <div class="container">
18
+      <listView
19
+        @onNew="New"
20
+        @onEdit="Edit"
21
+        :items="campaigns"
22
+        :editable="true"
23
+        :deleteable="true"
24
+        :displayColumns="columns"
25
+        :displayFormats="formats"
26
+        :showCustomAction="true"
27
+        :CustomActionHeading="'Client View'"
28
+        :sortKey="'startDate'"
29
+        @onCustomClick="ClientVue"
30
+        @onDelete="Delete"
31
+      />
32
+    </div>
33
+    <br />
34
+  </div>
35
+</template>
36
+
37
+<script>
38
+import { mapState, mapActions } from "vuex";
39
+import listView from "../shared/listView.vue";
40
+
41
+export default {
42
+  name: "LandingPages",
43
+  components: {
44
+    listView
45
+  },
46
+  data() {
47
+    return {
48
+      columns: ["name", "startDate", "endDate", "subject"],
49
+      formats: ["text", "date", "date", "text"]
50
+    };
51
+  },
52
+  methods: {
53
+    ...mapActions("campaign", ["getCampaigns", "deleteCampaign"]),
54
+    Edit(item) {
55
+      this.$router.push(`/landingPage/${item.id}`);
56
+    },
57
+    Delete(item) {
58
+      this.deleteCampaign(item.id);
59
+    },
60
+    // Publish(item) {
61
+    //   this.publishProperty(item);
62
+    // }
63
+    New() {
64
+      this.$router.push("/landingPage/0");
65
+    },
66
+    ClientVue(item) {
67
+      this.$router.push(`/MarketingCampaign/${item.id}`);
68
+    }
69
+  },
70
+  mounted() {
71
+    this.getCampaigns();
72
+    this.$emit("setLandingPage", false);
73
+  },
74
+  computed: {
75
+    ...mapState("campaign", ["campaigns"])
76
+    // UserChanged() {
77
+    //   this.getProperties(Object.assign(this.user.id));
78
+    //   return this.user;
79
+    // }
80
+  },
81
+  watch: {
82
+    // UserChanged() {
83
+    //   console.log(this.user);
84
+    // }
85
+  }
86
+};
87
+</script>

+ 21
- 20
src/components/property/propertyPage.vue Visa fil

102
                         <strong>Property ID:</strong>
102
                         <strong>Property ID:</strong>
103
                         <span>{{ property.id }}</span>
103
                         <span>{{ property.id }}</span>
104
                       </li>
104
                       </li>
105
-                      <li class="d-flex justify-content-between">
105
+                      <!-- Should not be visible? -->
106
+                      <!-- <li class="d-flex justify-content-between">
106
                         <strong>Status:</strong>
107
                         <strong>Status:</strong>
107
                         <span
108
                         <span
108
                           v-if="property.status"
109
                           v-if="property.status"
109
                         >{{ property.status.code }} - {{ property.status.description }}</span>
110
                         >{{ property.status.code }} - {{ property.status.description }}</span>
110
-                      </li>
111
+                      </li>-->
111
                       <li class="d-flex justify-content-between">
112
                       <li class="d-flex justify-content-between">
112
                         <strong>Address:</strong>
113
                         <strong>Address:</strong>
113
                         <span
114
                         <span
283
 </template>
284
 </template>
284
 
285
 
285
 <script>
286
 <script>
286
-import { mapState, mapActions } from 'vuex';
287
-import makeOffer from '../processFlow/makeOffer.vue';
288
-import gallery from '../shared/gallerySlideShow.vue';
287
+import { mapState, mapActions } from "vuex";
288
+import makeOffer from "../processFlow/makeOffer.vue";
289
+import gallery from "../shared/gallerySlideShow.vue";
289
 
290
 
290
 export default {
291
 export default {
291
-  name: 'property',
292
+  name: "property",
292
   components: {
293
   components: {
293
     makeOffer,
294
     makeOffer,
294
-    gallery,
295
+    gallery
295
   },
296
   },
296
   data() {
297
   data() {
297
     return {
298
     return {
298
       index: null,
299
       index: null,
299
-      date: new Date(),
300
+      date: new Date()
300
     };
301
     };
301
   },
302
   },
302
   mounted() {
303
   mounted() {
305
     this.mayEditProperty(this.$route.params.id);
306
     this.mayEditProperty(this.$route.params.id);
306
   },
307
   },
307
   computed: {
308
   computed: {
308
-    ...mapState('property', ['property', 'propertyImages']),
309
-    ...mapState('propertyEdit', ['mayEdit']),
309
+    ...mapState("property", ["property", "propertyImages"]),
310
+    ...mapState("propertyEdit", ["mayEdit"])
310
   },
311
   },
311
   methods: {
312
   methods: {
312
-    ...mapActions('property', [
313
-      'getProperty',
314
-      'getPropertyImages',
315
-      'clearPropertyImages',
313
+    ...mapActions("property", [
314
+      "getProperty",
315
+      "getPropertyImages",
316
+      "clearPropertyImages"
316
     ]),
317
     ]),
317
-    ...mapActions('propertyEdit', ['mayEditProperty']),
318
+    ...mapActions("propertyEdit", ["mayEditProperty"]),
318
     formatPrice(value) {
319
     formatPrice(value) {
319
       const val = (value / 1).toFixed(2);
320
       const val = (value / 1).toFixed(2);
320
-      return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
321
+      return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
321
     },
322
     },
322
     formatAddress(value) {
323
     formatAddress(value) {
323
-      if (value !== '') {
324
+      if (value !== "") {
324
         return `${value}<br/>`;
325
         return `${value}<br/>`;
325
       }
326
       }
326
-      return '';
327
-    },
327
+      return "";
328
+    }
328
   },
329
   },
329
   beforeDestroy() {
330
   beforeDestroy() {
330
     this.clearPropertyImages();
331
     this.clearPropertyImages();
331
-  },
332
+  }
332
 };
333
 };
333
 </script>
334
 </script>
334
 
335
 

+ 92
- 90
src/components/shared/listView.vue Visa fil

16
               class="btn btn-primary myBackground btn-width cursor-pointer"
16
               class="btn btn-primary myBackground btn-width cursor-pointer"
17
               data-toggle="modal"
17
               data-toggle="modal"
18
               data-target="#myModal"
18
               data-target="#myModal"
19
-            >
20
-              Column Chooser
21
-            </div>
19
+            >Column Chooser</div>
22
             <div class="col-md-12">
20
             <div class="col-md-12">
23
               <div id="myModal" class="modal fade" role="dialog">
21
               <div id="myModal" class="modal fade" role="dialog">
24
                 <div class="modal-dialog modal-lg">
22
                 <div class="modal-dialog modal-lg">
40
             <div
38
             <div
41
               class="btn btn-primary myBackground btn-width cursor-pointer"
39
               class="btn btn-primary myBackground btn-width cursor-pointer"
42
               @click="onClearSelected()"
40
               @click="onClearSelected()"
43
-            >
44
-              Clear Selected
45
-            </div>
41
+            >Clear Selected</div>
46
           </div>
42
           </div>
47
           <div class="p2" v-if="showNew">
43
           <div class="p2" v-if="showNew">
48
-            <div class="btn btn-primary myBackground btn-width cursor-pointer" @click="onNew()">
49
-              New
50
-            </div>
44
+            <div class="btn btn-primary myBackground btn-width cursor-pointer" @click="onNew()">New</div>
51
           </div>
45
           </div>
52
         </div>
46
         </div>
53
       </div>
47
       </div>
68
                 :class="{ active: hover === c }"
62
                 :class="{ active: hover === c }"
69
               >
63
               >
70
                 <div class="d-flex bd-highlight">
64
                 <div class="d-flex bd-highlight">
71
-                  <div v-if="displayHeaders.length === 0" class="p-2 w-100 bd-highlight">
72
-                    {{ column | toProper }}
73
-                  </div>
74
-                  <div v-else class="p-2 w-100 bd-highlight">
75
-                    {{ displayHeaders[c] !== "" ? displayHeaders[c] : column | toProper }}
76
-                  </div>
65
+                  <div
66
+                    v-if="displayHeaders.length === 0"
67
+                    class="p-2 w-100 bd-highlight"
68
+                  >{{ column | toProper }}</div>
69
+                  <div
70
+                    v-else
71
+                    class="p-2 w-100 bd-highlight"
72
+                  >{{ displayHeaders[c] !== "" ? displayHeaders[c] : column | toProper }}</div>
77
                   <div class="p-2 flex-shrink-1 bd-highlight">
73
                   <div class="p-2 flex-shrink-1 bd-highlight">
78
                     <img
74
                     <img
79
                       src="../../../public/img/sort-up.png"
75
                       src="../../../public/img/sort-up.png"
102
             :class="{ selected: isSelected(i), 'cursor-pointer': allowSelect }"
98
             :class="{ selected: isSelected(i), 'cursor-pointer': allowSelect }"
103
           >
99
           >
104
             <td v-for="(column, c) in Columns" :key="c">
100
             <td v-for="(column, c) in Columns" :key="c">
105
-              <div v-if="displayFormats.length === 0">
106
-                {{ isObject(item[column]) ? item[column].display : item[column] }}
107
-              </div>
101
+              <div
102
+                v-if="displayFormats.length === 0"
103
+              >{{ isObject(item[column]) ? item[column].display : item[column] }}</div>
108
               <div v-else-if="displayFormats.length > 0 && displayFormats[c] === 'date'">
104
               <div v-else-if="displayFormats.length > 0 && displayFormats[c] === 'date'">
109
-                <div v-if="item[column] !== '0001-01-01T00:00:00'">
110
-                  {{ isObject(item[column]) ? item[column].display : item[column] | toDate }}
111
-                </div>
112
-              </div>
113
-              <div v-else-if="displayFormats.length > 0 && displayFormats[c] === 'money'">
114
-                {{ isObject(item[column]) ? item[column].display : item[column] | toCurrency }}
105
+                <div
106
+                  v-if="item[column] !== '0001-01-01T00:00:00'"
107
+                >{{ isObject(item[column]) ? item[column].display : item[column] | toDate }}</div>
115
               </div>
108
               </div>
109
+              <div
110
+                v-else-if="displayFormats.length > 0 && displayFormats[c] === 'money'"
111
+              >{{ isObject(item[column]) ? item[column].display : item[column] | toCurrency }}</div>
116
               <div v-else-if="displayFormats.length > 0 && displayFormats[c] === 'image'">
112
               <div v-else-if="displayFormats.length > 0 && displayFormats[c] === 'image'">
117
                 <img :src="item[column]" style="height:100px; width:100px; object-fit: cover;" />
113
                 <img :src="item[column]" style="height:100px; width:100px; object-fit: cover;" />
118
               </div>
114
               </div>
119
-              <div v-else>
120
-                {{ isObject(item[column]) ? item[column].display : item[column] }}
121
-              </div>
115
+              <div v-else>{{ isObject(item[column]) ? item[column].display : item[column] }}</div>
122
             </td>
116
             </td>
123
             <td v-if="showCustomAction" class="my-width">
117
             <td v-if="showCustomAction" class="my-width">
124
-              <button type="button" class="btn my-btn" @click="onCustomClick(item)">
125
-                {{ CustomActionHeading }}
126
-              </button>
118
+              <button
119
+                type="button"
120
+                class="btn my-btn"
121
+                @click="onCustomClick(item)"
122
+              >{{ CustomActionHeading }}</button>
127
             </td>
123
             </td>
128
             <td v-if="editable" class="my-width">
124
             <td v-if="editable" class="my-width">
129
               <button type="button" class="btn my-btn" @click="onEdit(item)">Edit</button>
125
               <button type="button" class="btn my-btn" @click="onEdit(item)">Edit</button>
137
       <div class="d-flex justify-content-between" v-if="showPager">
133
       <div class="d-flex justify-content-between" v-if="showPager">
138
         <div class="p-1">
134
         <div class="p-1">
139
           {{
135
           {{
140
-            currentPage +
141
-              " / " +
142
-              PageCount +
143
-              (!hideItemCount ? " - (" + items.length + " items)" : "")
136
+          currentPage +
137
+          " / " +
138
+          PageCount +
139
+          (!hideItemCount ? " - (" + FilteredItems.length + " items)" : "")
144
           }}
140
           }}
145
         </div>
141
         </div>
146
         <div class="p-1">
142
         <div class="p-1">
174
 </template>
170
 </template>
175
 
171
 
176
 <script>
172
 <script>
177
-import _ from 'lodash';
178
-import ItemsPerPageList from '../../assets/staticData/itemsPerPage';
179
-import BasePagination from './basePagination.vue';
180
-import Alert from './alert.vue';
181
-import ListViewControl from './listViewControl.vue';
173
+import _ from "lodash";
174
+import ItemsPerPageList from "../../assets/staticData/itemsPerPage";
175
+import BasePagination from "./basePagination.vue";
176
+import Alert from "./alert.vue";
177
+import ListViewControl from "./listViewControl.vue";
182
 
178
 
183
 export default {
179
 export default {
184
   components: {
180
   components: {
185
     BasePagination,
181
     BasePagination,
186
     Alert,
182
     Alert,
187
-    ListViewControl,
183
+    ListViewControl
188
   },
184
   },
189
   mounted() {
185
   mounted() {
190
     try {
186
     try {
200
   },
196
   },
201
   props: {
197
   props: {
202
     compact: {
198
     compact: {
203
-      default: true,
199
+      default: true
204
     },
200
     },
205
     allowSelect: {
201
     allowSelect: {
206
-      default: true,
202
+      default: true
207
     },
203
     },
208
     allowMultipleSelect: {
204
     allowMultipleSelect: {
209
-      default: false,
205
+      default: false
210
     },
206
     },
211
     hideSearch: {
207
     hideSearch: {
212
-      default: false,
208
+      default: false
213
     },
209
     },
214
     showNew: {
210
     showNew: {
215
-      default: true,
211
+      default: true
216
     },
212
     },
217
     items: undefined,
213
     items: undefined,
218
     editable: {
214
     editable: {
219
-      default: false,
215
+      default: false
220
     },
216
     },
221
     deleteable: {
217
     deleteable: {
222
-      default: false,
218
+      default: false
223
     },
219
     },
224
     columnCount: {
220
     columnCount: {
225
-      default: 6,
221
+      default: 6
226
     },
222
     },
227
     showPager: {
223
     showPager: {
228
-      default: true,
224
+      default: true
229
     },
225
     },
230
     title: {
226
     title: {
231
-      default: undefined,
227
+      default: undefined
232
     },
228
     },
233
     sortKey: {
229
     sortKey: {
234
-      default: 'id',
230
+      default: "id"
235
     },
231
     },
236
     hideItemCount: {
232
     hideItemCount: {
237
-      default: false,
233
+      default: false
238
     },
234
     },
239
     currentPage: {
235
     currentPage: {
240
-      default: 1,
236
+      default: 1
241
     },
237
     },
242
     bordered: {
238
     bordered: {
243
-      default: true,
239
+      default: true
244
     },
240
     },
245
     striped: {
241
     striped: {
246
-      default: true,
242
+      default: true
247
     },
243
     },
248
     showColumnChooser: {
244
     showColumnChooser: {
249
-      default: true,
245
+      default: true
250
     },
246
     },
251
     displayColumns: {
247
     displayColumns: {
252
-      default: [],
248
+      default: []
253
     },
249
     },
254
     displayFormats: {
250
     displayFormats: {
255
-      default: [],
251
+      default: []
256
     },
252
     },
257
     displayHeaders: {
253
     displayHeaders: {
258
-      default: [],
254
+      default: []
259
     },
255
     },
260
     showCustomAction: {
256
     showCustomAction: {
261
-      default: false,
257
+      default: false
262
     },
258
     },
263
     CustomActionHeading: {
259
     CustomActionHeading: {
264
-      default: '',
260
+      default: ""
265
     },
261
     },
266
     CustomActionCondition: {
262
     CustomActionCondition: {
267
-      default: '',
268
-    },
263
+      default: ""
264
+    }
269
   },
265
   },
270
   data() {
266
   data() {
271
     return {
267
     return {
272
       hover: -1,
268
       hover: -1,
273
       selectedItems: [],
269
       selectedItems: [],
274
       showControl: false,
270
       showControl: false,
275
-      sortKey: '',
271
+      sortKey: "",
276
       reverse: false,
272
       reverse: false,
277
-      searchItem: '',
273
+      searchItem: "",
278
       visibleItemsPerPageCount: 20,
274
       visibleItemsPerPageCount: 20,
279
       itemsPerPageList: ItemsPerPageList,
275
       itemsPerPageList: ItemsPerPageList,
280
       visibleColumn: [],
276
       visibleColumn: [],
281
-      allColumn: [],
277
+      allColumn: []
282
     };
278
     };
283
   },
279
   },
284
   methods: {
280
   methods: {
300
         for (const i in Object.keys(this.items)) {
296
         for (const i in Object.keys(this.items)) {
301
           const item = this.items[i];
297
           const item = this.items[i];
302
           for (const o in Object.keys(item)) {
298
           for (const o in Object.keys(item)) {
303
-            if (!listAll.includes(Object.keys(item)[o]) && !Array.isArray(Object.values(item)[o])) {
299
+            if (
300
+              !listAll.includes(Object.keys(item)[o]) &&
301
+              !Array.isArray(Object.values(item)[o])
302
+            ) {
304
               const columnName = Object.keys(item)[o];
303
               const columnName = Object.keys(item)[o];
305
               if (!listAll.some(x => x.column === columnName)) {
304
               if (!listAll.some(x => x.column === columnName)) {
306
                 listAll.push({
305
                 listAll.push({
307
                   column: columnName,
306
                   column: columnName,
308
-                  show: _.filter(listAll, x => x.show).length < this.columnCount,
307
+                  show: _.filter(listAll, x => x.show).length < this.columnCount
309
                 });
308
                 });
310
               }
309
               }
311
             }
310
             }
316
     },
315
     },
317
     onClearSelected() {
316
     onClearSelected() {
318
       this.selectedItems = [];
317
       this.selectedItems = [];
319
-      this.$emit('onClearSelected');
318
+      this.$emit("onClearSelected");
320
     },
319
     },
321
     isSelected(i) {
320
     isSelected(i) {
322
       const ind = this.getActualIndex(i);
321
       const ind = this.getActualIndex(i);
323
       return _.some(this.selectedItems, x => x === ind);
322
       return _.some(this.selectedItems, x => x === ind);
324
     },
323
     },
325
     onNew() {
324
     onNew() {
326
-      this.$emit('onNew');
325
+      this.$emit("onNew");
327
     },
326
     },
328
     isObject(item) {
327
     isObject(item) {
329
       return !!item && item.constructor === Object;
328
       return !!item && item.constructor === Object;
332
       return !!item && item.constructor === Date;
331
       return !!item && item.constructor === Date;
333
     },
332
     },
334
     isDecimal(item) {
333
     isDecimal(item) {
335
-      if (!!item && item.constructor === Number && item.indexOf('.') > 0) {
334
+      if (!!item && item.constructor === Number && item.indexOf(".") > 0) {
336
         return true;
335
         return true;
337
       }
336
       }
338
       return false;
337
       return false;
342
         !!item &&
341
         !!item &&
343
         item.constructor === String &&
342
         item.constructor === String &&
344
         item.length > 9 &&
343
         item.length > 9 &&
345
-        item.substring(0, 9) === 'data:image'
344
+        item.substring(0, 9) === "data:image"
346
       );
345
       );
347
     },
346
     },
348
     onEdit(item) {
347
     onEdit(item) {
349
-      this.$emit('onEdit', item);
348
+      this.$emit("onEdit", item);
350
     },
349
     },
351
     onDelete(item) {
350
     onDelete(item) {
352
-      this.$emit('onDelete', item);
351
+      this.$emit("onDelete", item);
353
     },
352
     },
354
     onCustomClick(item) {
353
     onCustomClick(item) {
355
-      this.$emit('onCustomClick', item);
354
+      this.$emit("onCustomClick", item);
356
     },
355
     },
357
     onRowClick(item, i) {
356
     onRowClick(item, i) {
358
       const ind = this.getActualIndex(i);
357
       const ind = this.getActualIndex(i);
362
         if (!this.allowMultipleSelect) {
361
         if (!this.allowMultipleSelect) {
363
           this.selectedItems = [];
362
           this.selectedItems = [];
364
         }
363
         }
365
-        this.selectedItems.push(ind);
364
+        this.selectedItems.push(item);
366
       }
365
       }
367
-      this.$emit('onRowClick', this.selectedItems);
366
+      this.$emit("onRowClick", this.selectedItems);
368
     },
367
     },
369
     getActualIndex(index) {
368
     getActualIndex(index) {
370
       return (this.currentPage - 1) * this.visibleItemsPerPageCount + index;
369
       return (this.currentPage - 1) * this.visibleItemsPerPageCount + index;
389
     async pageChangeHandle(value) {
388
     async pageChangeHandle(value) {
390
       console.log(value);
389
       console.log(value);
391
       switch (value) {
390
       switch (value) {
392
-        case 'next':
391
+        case "next":
393
           this.currentPage += 1;
392
           this.currentPage += 1;
394
           break;
393
           break;
395
-        case 'previous':
394
+        case "previous":
396
           this.currentPage -= 1;
395
           this.currentPage -= 1;
397
           break;
396
           break;
398
         default:
397
         default:
410
         if (array[i] === value) return true;
409
         if (array[i] === value) return true;
411
       }
410
       }
412
       return false;
411
       return false;
413
-    },
412
+    }
414
   },
413
   },
415
   computed: {
414
   computed: {
416
     ListWidth() {
415
     ListWidth() {
417
       if (this.showControl) {
416
       if (this.showControl) {
418
-        return 'col-md-9';
417
+        return "col-md-9";
419
       }
418
       }
420
-      return 'col-md-12';
419
+      return "col-md-12";
421
     },
420
     },
422
     SortDirection() {
421
     SortDirection() {
423
-      return this.reverse ? 'desc' : 'asc';
422
+      return this.reverse ? "desc" : "asc";
424
     },
423
     },
425
     PageCount() {
424
     PageCount() {
426
       return this.visibleItemsPerPageCount !== 0
425
       return this.visibleItemsPerPageCount !== 0
454
       return list;
453
       return list;
455
     },
454
     },
456
     FilteredItems() {
455
     FilteredItems() {
457
-      const list = _.filter(this.items, item => Object.values(item).some(
458
-        i => JSON.stringify(i)
459
-          .toLowerCase()
460
-          .indexOf(this.searchItem.toLowerCase()) > -1,
461
-      ));
456
+      const list = _.filter(this.items, item =>
457
+        Object.values(item).some(
458
+          i =>
459
+            JSON.stringify(i)
460
+              .toLowerCase()
461
+              .indexOf(this.searchItem.toLowerCase()) > -1
462
+        )
463
+      );
462
       return _.orderBy(list, this.sortKey, this.SortDirection);
464
       return _.orderBy(list, this.sortKey, this.SortDirection);
463
     },
465
     },
464
     DisplayItems() {
466
     DisplayItems() {
470
       }
472
       }
471
       return list.slice(startSlice, endSlice);
473
       return list.slice(startSlice, endSlice);
472
     },
474
     },
473
-    GetAllColumn() {},
474
-  },
475
+    GetAllColumn() {}
476
+  }
475
 };
477
 };
476
 </script>
478
 </script>
477
 <style scoped>
479
 <style scoped>

+ 17
- 13
src/components/shared/navBar.vue Visa fil

177
                   @click="routerGoTo('/user/updateProfileInfo')"
177
                   @click="routerGoTo('/user/updateProfileInfo')"
178
                 >Update Info</a>
178
                 >Update Info</a>
179
                 <a class="dropdown-item cursor-pointer" @click="routerGoTo('/payments')">Payments</a>
179
                 <a class="dropdown-item cursor-pointer" @click="routerGoTo('/payments')">Payments</a>
180
+                <a
181
+                  class="dropdown-item cursor-pointer"
182
+                  @click="routerGoTo('/landingPages')"
183
+                >Landing Pages / Campaignes</a>
180
               </div>
184
               </div>
181
             </li>
185
             </li>
182
             <li class="nav-item dropdown" v-if="!isLoggedIn">
186
             <li class="nav-item dropdown" v-if="!isLoggedIn">
214
 </template>
218
 </template>
215
 
219
 
216
 <script>
220
 <script>
217
-import { mapState, mapActions } from 'vuex';
218
-import Log from '../../assets/Log';
221
+import { mapState, mapActions } from "vuex";
222
+import Log from "../../assets/Log";
219
 
223
 
220
 export default {
224
 export default {
221
   computed: {
225
   computed: {
222
-    ...mapState('authentication', [
223
-      'user',
224
-      'flag',
225
-      'status',
226
-      'person',
227
-      'token',
226
+    ...mapState("authentication", [
227
+      "user",
228
+      "flag",
229
+      "status",
230
+      "person",
231
+      "token"
228
     ]),
232
     ]),
229
     isLoggedIn() {
233
     isLoggedIn() {
230
       console.log(Log.isLoggedIn());
234
       console.log(Log.isLoggedIn());
236
     // eslint-disable-next-line vue/return-in-computed-property
240
     // eslint-disable-next-line vue/return-in-computed-property
237
     Logout() {
241
     Logout() {
238
       return this.logout();
242
       return this.logout();
239
-    },
243
+    }
240
   },
244
   },
241
   methods: {
245
   methods: {
242
-    ...mapActions('authentication', ['logout']),
246
+    ...mapActions("authentication", ["logout"]),
243
 
247
 
244
     routerGoTo(goTo) {
248
     routerGoTo(goTo) {
245
-      this.$emit('routerGoTo', goTo);
246
-    },
247
-  },
249
+      this.$emit("routerGoTo", goTo);
250
+    }
251
+  }
248
 };
252
 };
249
 </script>
253
 </script>
250
 <style scoped>
254
 <style scoped>

+ 30
- 0
src/router/index.js Visa fil

53
 import AlertPage from '../components/shared/alertPage.vue';
53
 import AlertPage from '../components/shared/alertPage.vue';
54
 import PropertySearchResults from '../components/property/propertySearchResults.vue';
54
 import PropertySearchResults from '../components/property/propertySearchResults.vue';
55
 import Payments from '../components/financial/payments.vue';
55
 import Payments from '../components/financial/payments.vue';
56
+import LandingPages from "../components/marketing/landingPages.vue";
57
+import LandingPage from "../components/marketing/landingPage.vue";
58
+import LandingPageWeek from "../components/marketing/landingPageWeek.vue";
59
+import MarketingPage from "../components/marketing/clientView.vue";
60
+import MarketingPageExp from "../components/marketing/landingPageExpired.vue";
56
 
61
 
57
 Vue.use(Router);
62
 Vue.use(Router);
58
 
63
 
298
       name: 'Payments',
303
       name: 'Payments',
299
       component: Payments,
304
       component: Payments,
300
     },
305
     },
306
+    {
307
+      path: "/landingPages",
308
+      name: "LandingPages",
309
+      component: LandingPages
310
+    },
311
+    {
312
+      path: "/landingPage/:id",
313
+      name: "LandingPage",
314
+      component: LandingPage
315
+    },
316
+    {
317
+      path: "/landingPage/week/:id",
318
+      name: "LandingPageWeek",
319
+      component: LandingPageWeek
320
+    },
321
+    {
322
+      path: "/MarketingCampaign/:id",
323
+      name: "MarketingPage",
324
+      component: MarketingPage
325
+    },
326
+    {
327
+      path: "/CampaignExpired",
328
+      name: "CampaignExpired",
329
+      component: MarketingPageExp
330
+    }
301
   ],
331
   ],
302
 });
332
 });

+ 6
- 0
src/store/index.js Visa fil

28
 import Alert from './modules/misc/alert';
28
 import Alert from './modules/misc/alert';
29
 import TenderWeek from './modules/timeshare/tenderWeeks';
29
 import TenderWeek from './modules/timeshare/tenderWeeks';
30
 import PaymentModule from './modules/financial/payment';
30
 import PaymentModule from './modules/financial/payment';
31
+import CampaignModule from "./modules/marketing/campaigns";
32
+import CampaignItemModule from "./modules/marketing/campaignItems";
33
+import PlaceHolderFormat from "./modules/misc/placeHolderFormat";
31
 
34
 
32
 Vue.use(Vuex);
35
 Vue.use(Vuex);
33
 /* eslint no-param-reassign: ["error", { "props": false }] */
36
 /* eslint no-param-reassign: ["error", { "props": false }] */
60
     alert: Alert,
63
     alert: Alert,
61
     tenderWeek: TenderWeek,
64
     tenderWeek: TenderWeek,
62
     payment: PaymentModule,
65
     payment: PaymentModule,
66
+    campaign: CampaignModule,
67
+    campaignItem: CampaignItemModule,
68
+    placeHolderFormat: PlaceHolderFormat
63
   },
69
   },
64
 });
70
 });

+ 36
- 0
src/store/modules/marketing/campaignItems.js Visa fil

1
+import axios from "axios";
2
+
3
+export default {
4
+    namespaced: true,
5
+    state: {
6
+        campaignItem: {}
7
+    },
8
+    mutations: {
9
+        setCampaignItem(state, campaignItem) {
10
+            state.campaignItem = campaignItem;
11
+        }
12
+    },
13
+    getters: {},
14
+    actions: {
15
+        getCampaignItem({ commit }, id) {
16
+            axios
17
+                .get(`/api/campaignItem/${id}`)
18
+                .then(result => commit("setCampaignItem", result.data))
19
+                .catch(console.error);
20
+            console.log(JSON.stringify(result.data))
21
+        },
22
+        saveCampaign({ commit }, item) {
23
+            axios
24
+                .post("/api/campaignItem", item)
25
+                .then(result => commit("setCampaignItem", result.data))
26
+                .catch(console.error);
27
+            console.log(JSON.stringify(item));
28
+        },
29
+        updateCampaign({ commit }, item) {
30
+            axios
31
+                .put("/api/campaignItem", item)
32
+                .then(result => commit("setCampaignItem", item))
33
+                .catch(console.error);
34
+        }
35
+    }
36
+};

+ 98
- 0
src/store/modules/marketing/campaigns.js Visa fil

1
+import axios from "axios";
2
+import { Object } from "core-js";
3
+
4
+export default {
5
+    namespaced: true,
6
+    state: {
7
+        campaign: Object,
8
+        campaigns: [],
9
+        campaignDTO: {},
10
+        campaignHtml: '',
11
+        campaignPlaceHolders: [],
12
+        campaignItems: []
13
+    },
14
+    mutations: {
15
+        setCampaign(state, campaign) {
16
+            state.campaign = campaign;
17
+        },
18
+        setCampaigns(state, campaign) {
19
+            state.campaigns = campaign;
20
+        },
21
+        setCampaignDTO(state, campaignDTO) {
22
+            state.campaignDTO = campaignDTO;
23
+        },
24
+        setCampaignItems(state, items) {
25
+            state.campaignItems = items;
26
+        },
27
+        setCampaignPlaceHolders(state, items) {
28
+            state.campaignPlaceHolders = items;
29
+        },
30
+        setCampaignsUpdate(state, item) {
31
+            state.campaigns.pop(state.campaigns.find(p => p.id === item.id));
32
+            state.campaigns.push(item);
33
+        },
34
+        removeCampaign(state, id) {
35
+            state.campaigns.pop(state.campaigns.find(p => p.id === id));
36
+        },
37
+        setCampaignHTML(state, campaign) {
38
+            state.campaignHtml = campaign;
39
+        }
40
+    },
41
+    getters: {},
42
+    actions: {
43
+        getCampaign({ commit }, id) {
44
+            axios
45
+                .get(`/api/campaign/${id}`)
46
+                .then(result => commit("setCampaign", result.data))
47
+                .catch(console.error);
48
+        },
49
+        getCampaignDTO({ commit }, id) {
50
+            axios
51
+                .get(`/api/campaign/GetDTO/${id}`)
52
+                .then(result => commit("setCampaignDTO", result.data))
53
+                .catch(console.error);
54
+        },
55
+        getCampaignHTML({ commit }, id) {
56
+            axios
57
+                .get(`/api/campaign/GetLandingPage/${id}`)
58
+                .then(result => commit("setCampaignHTML", result.data))
59
+                .catch(console.error);
60
+        },
61
+        getCampaignItems({ commit }, id) {
62
+            axios
63
+                .get(`/api/campaign/GetCampaignItems/${id}`)
64
+                .then(result => commit("setCampaignItems", result.data))
65
+                .catch(console.error);
66
+        },
67
+        getCampaignPlaceHolders({ commit }, id) {
68
+            axios
69
+                .get(`/api/campaign/GetCampaignPlaceHolders/${id}`)
70
+                .then(result => commit("setCampaignPlaceHolders", result.data))
71
+                .catch(console.error);
72
+        },
73
+        getCampaigns({ commit }) {
74
+            axios
75
+                .get("/api/campaign")
76
+                .then(result => commit("setCampaigns", result.data))
77
+                .catch(console.error);
78
+        },
79
+        saveCampaign({ commit }, item) {
80
+            axios
81
+                .post("/api/campaign", item)
82
+                .then(result => commit("setCampaignsUpdate", result.data))
83
+                .catch(console.error);
84
+        },
85
+        updateCampaign({ commit }, item) {
86
+            axios
87
+                .put("/api/campaign", item)
88
+                .then(result => commit("setCampaignsUpdate", item))
89
+                .catch(console.error);
90
+        },
91
+        deleteCampaign({ commit }, id) {
92
+            axios
93
+                .delete(`/api/campaign/${id}`)
94
+                .then(result => commit("removeCampaign", id))
95
+                .catch(console.error);
96
+        }
97
+    }
98
+};

+ 22
- 0
src/store/modules/misc/placeHolderFormat.js Visa fil

1
+import axios from 'axios';
2
+
3
+export default {
4
+    namespaced: true,
5
+    state: {
6
+        formats: [],
7
+    },
8
+    mutations: {
9
+        setFormats(state, item) {
10
+            state.formats = item;
11
+        },
12
+    },
13
+    getters: {},
14
+    actions: {
15
+        getFormats({ commit }) {
16
+            axios
17
+                .get('/api/PlaceHolderFormat')
18
+                .then(result => commit('setFormats', result.data))
19
+                .catch(console.error);
20
+        },
21
+    },
22
+};

Laddar…
Avbryt
Spara