Przeglądaj źródła

Landing Pages

master
George Williams 5 lat temu
rodzic
commit
4239377658

BIN
Landing Pages.docx Wyświetl plik


+ 5
- 0
package-lock.json Wyświetl plik

@@ -12243,6 +12243,11 @@
12243 12243
       "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
12244 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 12251
     "vue-json-excel": {
12247 12252
       "version": "0.2.98",
12248 12253
       "resolved": "https://registry.npmjs.org/vue-json-excel/-/vue-json-excel-0.2.98.tgz",

+ 1
- 0
package.json Wyświetl plik

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

+ 21
- 13
src/App.vue Wyświetl plik

@@ -1,34 +1,42 @@
1 1
 <template>
2 2
   <div id="app">
3
-    <a href="#" class="back-to-top">
3
+    <a v-if="!isLandingPage" href="#" class="back-to-top">
4 4
       <i class="fa fa-chevron-up"></i>
5 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 12
   </div>
13 13
 </template>
14 14
 
15 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 20
 export default {
21
-  name: 'app',
21
+  name: "app",
22
+  data() {
23
+    return {
24
+      isLandingPage: false
25
+    };
26
+  },
22 27
   components: {
23 28
     SearchTab,
24 29
     NavBar,
25
-    FooterSection,
30
+    FooterSection
26 31
   },
27 32
   methods: {
28 33
     routerGoTo(goTo) {
29 34
       this.$router.push(goTo);
30 35
     },
31
-  },
36
+    setLandingPage(item) {
37
+      this.isLandingPage = item;
38
+    }
39
+  }
32 40
 };
33 41
 </script>
34 42
 

+ 33
- 0
src/components/marketing/clientView.vue Wyświetl plik

@@ -0,0 +1,33 @@
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 Wyświetl plik

@@ -0,0 +1,472 @@
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 Wyświetl plik

@@ -0,0 +1,6 @@
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 Wyświetl plik

@@ -0,0 +1,120 @@
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 Wyświetl plik

@@ -0,0 +1,262 @@
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 Wyświetl plik

@@ -0,0 +1,87 @@
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 Wyświetl plik

@@ -102,12 +102,13 @@
102 102
                         <strong>Property ID:</strong>
103 103
                         <span>{{ property.id }}</span>
104 104
                       </li>
105
-                      <li class="d-flex justify-content-between">
105
+                      <!-- Should not be visible? -->
106
+                      <!-- <li class="d-flex justify-content-between">
106 107
                         <strong>Status:</strong>
107 108
                         <span
108 109
                           v-if="property.status"
109 110
                         >{{ property.status.code }} - {{ property.status.description }}</span>
110
-                      </li>
111
+                      </li>-->
111 112
                       <li class="d-flex justify-content-between">
112 113
                         <strong>Address:</strong>
113 114
                         <span
@@ -283,20 +284,20 @@
283 284
 </template>
284 285
 
285 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 291
 export default {
291
-  name: 'property',
292
+  name: "property",
292 293
   components: {
293 294
     makeOffer,
294
-    gallery,
295
+    gallery
295 296
   },
296 297
   data() {
297 298
     return {
298 299
       index: null,
299
-      date: new Date(),
300
+      date: new Date()
300 301
     };
301 302
   },
302 303
   mounted() {
@@ -305,30 +306,30 @@ export default {
305 306
     this.mayEditProperty(this.$route.params.id);
306 307
   },
307 308
   computed: {
308
-    ...mapState('property', ['property', 'propertyImages']),
309
-    ...mapState('propertyEdit', ['mayEdit']),
309
+    ...mapState("property", ["property", "propertyImages"]),
310
+    ...mapState("propertyEdit", ["mayEdit"])
310 311
   },
311 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 319
     formatPrice(value) {
319 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 323
     formatAddress(value) {
323
-      if (value !== '') {
324
+      if (value !== "") {
324 325
         return `${value}<br/>`;
325 326
       }
326
-      return '';
327
-    },
327
+      return "";
328
+    }
328 329
   },
329 330
   beforeDestroy() {
330 331
     this.clearPropertyImages();
331
-  },
332
+  }
332 333
 };
333 334
 </script>
334 335
 

+ 92
- 90
src/components/shared/listView.vue Wyświetl plik

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

+ 17
- 13
src/components/shared/navBar.vue Wyświetl plik

@@ -177,6 +177,10 @@
177 177
                   @click="routerGoTo('/user/updateProfileInfo')"
178 178
                 >Update Info</a>
179 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 184
               </div>
181 185
             </li>
182 186
             <li class="nav-item dropdown" v-if="!isLoggedIn">
@@ -214,17 +218,17 @@
214 218
 </template>
215 219
 
216 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 224
 export default {
221 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 233
     isLoggedIn() {
230 234
       console.log(Log.isLoggedIn());
@@ -236,15 +240,15 @@ export default {
236 240
     // eslint-disable-next-line vue/return-in-computed-property
237 241
     Logout() {
238 242
       return this.logout();
239
-    },
243
+    }
240 244
   },
241 245
   methods: {
242
-    ...mapActions('authentication', ['logout']),
246
+    ...mapActions("authentication", ["logout"]),
243 247
 
244 248
     routerGoTo(goTo) {
245
-      this.$emit('routerGoTo', goTo);
246
-    },
247
-  },
249
+      this.$emit("routerGoTo", goTo);
250
+    }
251
+  }
248 252
 };
249 253
 </script>
250 254
 <style scoped>

+ 30
- 0
src/router/index.js Wyświetl plik

@@ -53,6 +53,11 @@ import CarouselDetail from '../components/admin/misc/carousel.vue';
53 53
 import AlertPage from '../components/shared/alertPage.vue';
54 54
 import PropertySearchResults from '../components/property/propertySearchResults.vue';
55 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 62
 Vue.use(Router);
58 63
 
@@ -298,5 +303,30 @@ export default new Router({
298 303
       name: 'Payments',
299 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 Wyświetl plik

@@ -28,6 +28,9 @@ import Individual from './modules/user/individual';
28 28
 import Alert from './modules/misc/alert';
29 29
 import TenderWeek from './modules/timeshare/tenderWeeks';
30 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 35
 Vue.use(Vuex);
33 36
 /* eslint no-param-reassign: ["error", { "props": false }] */
@@ -60,5 +63,8 @@ export default new Vuex.Store({
60 63
     alert: Alert,
61 64
     tenderWeek: TenderWeek,
62 65
     payment: PaymentModule,
66
+    campaign: CampaignModule,
67
+    campaignItem: CampaignItemModule,
68
+    placeHolderFormat: PlaceHolderFormat
63 69
   },
64 70
 });

+ 36
- 0
src/store/modules/marketing/campaignItems.js Wyświetl plik

@@ -0,0 +1,36 @@
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 Wyświetl plik

@@ -0,0 +1,98 @@
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 Wyświetl plik

@@ -0,0 +1,22 @@
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
+};

Ładowanie…
Anuluj
Zapisz