From 6836f07af5b4a272da451f5093148e06c8f16077 Mon Sep 17 00:00:00 2001
From: Frank Zhang <fz2907@vt.edu>
Date: Thu, 24 Nov 2022 11:02:48 -0500
Subject: [PATCH] Start AgreedMatchPage to show the ongoing matches and history
 matches for user give rating and comments

---
 .../controllers/AgreedRecordController.java   |  56 ++++++++
 .../SwitchRoom/models/AgreedRecordModel.java  |  27 +++-
 .../MatchedWishlistRecordService.java         |  29 ++--
 .../src/components/AgreedMatchPage.vue        | 135 ++++++++++++++++++
 .../src/models/AgreedRecordModel.ts           |  47 ++++++
 .../switch-room/src/router/index.ts           |  10 ++
 .../src/services/AgreedMatchService.ts        |  12 ++
 .../switch-room/src/views/AgreedMatchView.vue |   7 +
 8 files changed, 311 insertions(+), 12 deletions(-)
 create mode 100644 BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/controllers/AgreedRecordController.java
 create mode 100644 FrontendFolder/switch-room/src/components/AgreedMatchPage.vue
 create mode 100644 FrontendFolder/switch-room/src/models/AgreedRecordModel.ts
 create mode 100644 FrontendFolder/switch-room/src/services/AgreedMatchService.ts
 create mode 100644 FrontendFolder/switch-room/src/views/AgreedMatchView.vue

diff --git a/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/controllers/AgreedRecordController.java b/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/controllers/AgreedRecordController.java
new file mode 100644
index 00000000..b0677110
--- /dev/null
+++ b/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/controllers/AgreedRecordController.java
@@ -0,0 +1,56 @@
+package vt.CS5934.SwitchRoom.controllers;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import vt.CS5934.SwitchRoom.models.ResponseModel;
+import vt.CS5934.SwitchRoom.services.CommentRatingService;
+
+@CrossOrigin(
+        allowCredentials = "true",
+        origins = {"http://localhost:8080/"}
+)
+@RestController
+@RequestMapping("agreedRecord")
+public class AgreedRecordController {
+    private final Logger logger = LoggerFactory.getLogger(AgreedRecordController.class);
+
+    @Autowired
+    CommentRatingService commentRatingService;
+
+    @GetMapping("/offer")
+    public ResponseModel getAgreedOfferList(@CookieValue(value = "userId") Long userId){
+        ResponseModel responseModel = new ResponseModel();
+        try{
+            responseModel.setMessage("Success");
+            responseModel.setStatus(HttpStatus.OK);
+            responseModel.setData(commentRatingService.getRecordsByOfferId(userId));
+            return responseModel;
+        }catch (Exception e){
+            logger.error("Error in getWishlistList: "+e);
+            responseModel.setMessage("getAgreedOfferList Failed, Reason: " + e);
+            responseModel.setStatus(HttpStatus.NOT_FOUND);
+            responseModel.setData(null);
+            return responseModel;
+        }
+    }
+
+    @GetMapping("/wishlist")
+    public ResponseModel getAgreedWishlistList(@CookieValue(value = "userId") Long userId){
+        ResponseModel responseModel = new ResponseModel();
+        try{
+            responseModel.setMessage("Success");
+            responseModel.setStatus(HttpStatus.OK);
+            responseModel.setData(commentRatingService.getRecordsByWishlistUserId(userId));
+            return responseModel;
+        }catch (Exception e){
+            logger.error("Error in getWishlistList: "+e);
+            responseModel.setMessage("getAgreedOfferList Failed, Reason: " + e);
+            responseModel.setStatus(HttpStatus.NOT_FOUND);
+            responseModel.setData(null);
+            return responseModel;
+        }
+    }
+}
diff --git a/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/models/AgreedRecordModel.java b/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/models/AgreedRecordModel.java
index 294a9804..6c5fa435 100644
--- a/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/models/AgreedRecordModel.java
+++ b/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/models/AgreedRecordModel.java
@@ -14,23 +14,28 @@ public class AgreedRecordModel {
     @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;
     private Long stateCityCode;
+    private String state;
+    private String city;
     private Long wishlistId;
     private Long wishlistUserId;
     private Long offerId;
     private Date startTime;
     private Date endTime;
-    private Integer toOfferStar;
-    private Integer toVisitorStar;
+    private Integer toOfferStar = 5;
+    private Integer toVisitorStar = 5;
     @Column(length = 500)
     private String toOfferComment;
     @Column(length = 500)
     private String toVisitorComment;
     private boolean onGoing = true;
 
-    public AgreedRecordModel(Long stateCityCode, Long wishlistId, Long wishlistUserId, Long offerId, Date startTime,
+    public AgreedRecordModel(Long stateCityCode, String state, String city, Long wishlistId, Long wishlistUserId,
+                             Long offerId, Date startTime,
                              Date endTime, Integer toOfferStar, Integer toVisitorStar, String toOfferComment,
                              String toVisitorComment) {
         this.stateCityCode = stateCityCode;
+        this.state = state;
+        this.city = city;
         this.wishlistId = wishlistId;
         this.wishlistUserId = wishlistUserId;
         this.offerId = offerId;
@@ -137,4 +142,20 @@ public class AgreedRecordModel {
     public void setOnGoing(boolean onGoing) {
         this.onGoing = onGoing;
     }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
 }
diff --git a/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/services/MatchedWishlistRecordService.java b/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/services/MatchedWishlistRecordService.java
index 1932bd07..89d6a43e 100644
--- a/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/services/MatchedWishlistRecordService.java
+++ b/BackendFolder/SwitchRoom/src/main/java/vt/CS5934/SwitchRoom/services/MatchedWishlistRecordService.java
@@ -4,18 +4,13 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import vt.CS5934.SwitchRoom.models.AgreedRecordModel;
-import vt.CS5934.SwitchRoom.models.MatchedWishlistRecordModel;
-import vt.CS5934.SwitchRoom.models.UserOfferModel;
-import vt.CS5934.SwitchRoom.models.UserOfferWishlistLookUpModel;
-import vt.CS5934.SwitchRoom.repositories.AgreedRecordRepository;
-import vt.CS5934.SwitchRoom.repositories.MatchedWishlistRecordRepository;
-import vt.CS5934.SwitchRoom.repositories.UserOfferRepository;
-import vt.CS5934.SwitchRoom.repositories.UserOfferWishlistLookUpRepository;
+import vt.CS5934.SwitchRoom.models.*;
+import vt.CS5934.SwitchRoom.repositories.*;
 import vt.CS5934.SwitchRoom.utility.LookupTables;
 
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 @Service
 public class MatchedWishlistRecordService {
@@ -37,6 +32,10 @@ public class MatchedWishlistRecordService {
     UserOfferRepository userOfferRepository;
     @Autowired
     UserOfferWishlistLookUpRepository userOfferWishlistLookUpRepository;
+    @Autowired
+    WishlistWaitingMatchRepository wishlistWaitingMatchRepository;
+    @Autowired
+    WishlistItemRepository wishlistItemRepository;
 
     public List<MatchedWishlistRecordModel> getOfferListWithIDFromDB(long id){
         logger.info("Reached getOfferListIDFromDB()");
@@ -64,6 +63,8 @@ public class MatchedWishlistRecordService {
             record.setOfferResult(LookupTables.MATCHING_RECORD_USER_RESULT.Declined);
             if(record.getAgreedRecordId() != null){
                 agreedRecordRepository.deleteById(record.getAgreedRecordId());
+                wishlistItemRepository.save(wishlistItemRepository.findByWishlistItemId(wishlistId));
+                record.setAgreedRecordId(null);
             }
             matchedWishlistRecordRepository.save(record);
         }else{
@@ -79,6 +80,8 @@ public class MatchedWishlistRecordService {
             record.setWishlistResult(LookupTables.MATCHING_RECORD_USER_RESULT.Declined);
             if(record.getAgreedRecordId() != null){
                 agreedRecordRepository.deleteById(record.getAgreedRecordId());
+                wishlistItemRepository.save(wishlistItemRepository.findByWishlistItemId(wishlistId));
+                record.setAgreedRecordId(null);
             }
             matchedWishlistRecordRepository.save(record);
         }else{
@@ -96,12 +99,20 @@ public class MatchedWishlistRecordService {
             UserOfferWishlistLookUpModel offerWishLookup = userOfferWishlistLookUpRepository
                     .findByWishlistItemId(wishlistId);
             AgreedRecordModel agreedRecord = new AgreedRecordModel(
-                    offerModel.getStateCityCode(), wishlistId, offerWishLookup.getUserId(), offerId,
+                    offerModel.getStateCityCode(), offerModel.getState(), offerModel.getSpaceLocateCity(),
+                    wishlistId, offerWishLookup.getUserId(), offerId,
                     record.getStartTime(), record.getEndTime(), null, null,
                     null, null);
             agreedRecord = agreedRecordRepository.save(agreedRecord);
             record.setAgreedRecordId(agreedRecord.getId());
             matchedWishlistRecordRepository.save(record);
+            wishlistWaitingMatchRepository.deleteAllByWishlistItemId(wishlistId);
+            List<MatchedWishlistRecordModel> matchedWishlistRecords = matchedWishlistRecordRepository
+                    .findAllByWishlistItemId(wishlistId)
+                    .stream()
+                    .filter(item-> !Objects.equals(item.getOfferId(), offerId))
+                    .toList();
+            matchedWishlistRecordRepository.deleteAll(matchedWishlistRecords);
         }else{
             logger.error("Can not find the matched record with offerId: {}, and wishlistItemId:{}",
                     offerId, wishlistId);
diff --git a/FrontendFolder/switch-room/src/components/AgreedMatchPage.vue b/FrontendFolder/switch-room/src/components/AgreedMatchPage.vue
new file mode 100644
index 00000000..3656e71e
--- /dev/null
+++ b/FrontendFolder/switch-room/src/components/AgreedMatchPage.vue
@@ -0,0 +1,135 @@
+<template>
+  <div class="common-layout">
+    <el-container>
+      <el-header>
+        <el-tabs type="border-card" class="demo-tabs" @tab-change="handleTabClick">
+          <el-tab-pane label="Offer Agreements" @tab-click="clickOnOfferTab"></el-tab-pane>
+          <el-tab-pane label="Wishlist Agreements" @tab-click="clickOnWishlistTab"></el-tab-pane>
+        </el-tabs>
+      </el-header>
+      <el-container class="box-body">
+        <el-aside width="300px">
+          <el-space direction="vertical" width="100%">
+            <el-card
+                v-for="(item, index) in sideList.value"
+                shadow="hover"
+                style="width: 280px"
+                @click="selectItem(index)"
+            >
+              <span>{{ item.city }}, {{ item.state }}</span>
+              <div class="bottom">
+                <time class="time"
+                >"{{ formatDate(item.startTime) }} to {{ formatDate(item.endTime) }}"</time
+                >
+              </div>
+            </el-card>
+          </el-space>
+        </el-aside>
+        <el-main>Main</el-main>
+      </el-container>
+    </el-container>
+  </div>
+</template>
+
+
+<script setup lang="ts">
+import { Calendar } from '@element-plus/icons-vue'
+import { reactive, ref, onMounted } from "vue";
+import {AgreedRecordModel} from "@/models/AgreedRecordModel";
+import * as AgreedRecordService from "@/services/AgreedMatchService";
+
+let displayPage = null;
+const sideList = reactive({value:[]});
+const agreedRecord = ref(new AgreedRecordModel());
+
+const selectItem = (listIdx) => {
+  agreedRecord.value = sideList[listIdx];
+}
+
+const handleTabClick = (tabIdx) => {
+  if(tabIdx == 0){
+    clickOnOfferTab();
+  }else if(tabIdx == 1){
+    clickOnWishlistTab();
+  }
+}
+
+const clickOnOfferTab = async() =>{
+  // Load agreed offers from backend
+  displayPage = "offer";
+  await AgreedRecordService.getAgreedOfferRecord().then((response)=>{
+    console.log("Receiving offer records from backend: ", response);
+    if(response["data"]!== null){
+      sideList.value = response["data"];
+    }else{
+      // TODO: display empty page
+    }
+  })
+}
+
+const clickOnWishlistTab = async() =>{
+  // Load agreed Wishlist from backend
+  displayPage = "wishlist";
+  await AgreedRecordService.getAgreedWishlistRecord().then((response)=>{
+    console.log("Receiving wishlist records from backend: ", response);
+    // remove it when done
+    let testData = {
+      "message": "Success",
+      "status": "OK",
+      "data": [
+        {
+          "id": 1,
+          "stateCityCode": 1,
+          "state": "VA",
+          "city": "Chantilly",
+          "wishlistId": 1,
+          "wishlistUserId": 1,
+          "offerId": 2,
+          "startTime": "2022-11-07T04:56:25.000+00:00",
+          "endTime": "2022-11-11T04:55:50.000+00:00",
+          "toOfferStar": 5,
+          "toVisitorStar": 5,
+          "toOfferComment": null,
+          "toVisitorComment": null,
+          "onGoing": true
+        }
+      ]
+    }
+    if(response === undefined){
+      sideList.value = testData["data"]
+    }
+    // remove it when done
+    if(response["data"]!== null){
+      sideList.value = response["data"];
+    }else{
+      // TODO: display empty page
+    }
+  })
+}
+
+const formatDate = (dateString) => {
+  const date = new Date(dateString);
+  return new Intl.DateTimeFormat('en-US').format(date);
+}
+</script>
+
+<style>
+.demo-tabs > .el-tabs__content {
+}
+.el-tabs--border-card>.el-tabs__content{
+  padding: 0;
+}
+.demo-tabs .custom-tabs-label .el-icon {
+  vertical-align: middle;
+}
+.demo-tabs .custom-tabs-label span {
+  vertical-align: middle;
+  margin-left: 4px;
+}
+.box-body{
+  padding: 20px 0;
+}
+.el-header {
+  padding: 20px 0;
+}
+</style>
\ No newline at end of file
diff --git a/FrontendFolder/switch-room/src/models/AgreedRecordModel.ts b/FrontendFolder/switch-room/src/models/AgreedRecordModel.ts
new file mode 100644
index 00000000..e79d0ad0
--- /dev/null
+++ b/FrontendFolder/switch-room/src/models/AgreedRecordModel.ts
@@ -0,0 +1,47 @@
+export class AgreedRecordModel {
+    public readonly id: number;
+    public stateCityCode: number;
+    public state: string;
+    public city:string;
+    public wishlistId: number;
+    public wishlistUserId: number;
+    public offerId: number;
+    public startTime: Date|any;
+    public endTime: Date|any;
+    public toOfferStar: number;
+    public toVisitorStar: number;
+    public toOfferComment: string;
+    public toVisitorComment: string;
+    public onGoing: boolean|any;
+    constructor(
+        id = -1,
+        stateCityCode = -1,
+        state = "",
+        city = "",
+        wishlistId = -1,
+        wishlistUserId = -1,
+        offerId = -1,
+        startTime = null,
+        endTime = null,
+        toOfferStar = 5,
+        toVisitorStar = 5,
+        toOfferComment = "",
+        toVisitorComment = "",
+        onGoing = null,
+    ){
+        this.id = id;
+        this.stateCityCode = stateCityCode;
+        this.state = state;
+        this.city = city;
+        this.wishlistId = wishlistId;
+        this.wishlistUserId = wishlistUserId;
+        this.offerId = offerId;
+        this.startTime = startTime;
+        this.endTime = endTime;
+        this.toOfferStar = toOfferStar;
+        this.toVisitorStar = toVisitorStar;
+        this.toOfferComment = toOfferComment;
+        this.toVisitorComment = toVisitorComment;
+        this.onGoing = onGoing;
+    }
+}
\ No newline at end of file
diff --git a/FrontendFolder/switch-room/src/router/index.ts b/FrontendFolder/switch-room/src/router/index.ts
index 4ac42f62..b3640f58 100644
--- a/FrontendFolder/switch-room/src/router/index.ts
+++ b/FrontendFolder/switch-room/src/router/index.ts
@@ -51,6 +51,16 @@ const routes: Array<RouteRecordRaw> = [
     component: () =>
       import(/* webpackChunkName: "about" */ "../views/WishlistView.vue"),
   },
+  {
+    path: "/agreed-match-page",
+    name: "AgreedMatchPage",
+    meta: {
+      requiresAuth: true,
+      hideHeader: false,
+    },
+    component: () =>
+        import(/* webpackChunkName: "about" */ "../views/AgreedMatchView.vue"),
+  },
   {
     path: "/flight",
     name: "flight",
diff --git a/FrontendFolder/switch-room/src/services/AgreedMatchService.ts b/FrontendFolder/switch-room/src/services/AgreedMatchService.ts
new file mode 100644
index 00000000..4008e5e3
--- /dev/null
+++ b/FrontendFolder/switch-room/src/services/AgreedMatchService.ts
@@ -0,0 +1,12 @@
+import * as serverHttpService from "./ServerHttpService";
+
+const baseUrl = "agreedRecord";
+
+export function getAgreedOfferRecord() {
+    const urlPath = "/offer";
+    return serverHttpService.Get(baseUrl + urlPath);
+}
+export function getAgreedWishlistRecord() {
+    const urlPath = "/wishlist";
+    return serverHttpService.Get(baseUrl + urlPath);
+}
diff --git a/FrontendFolder/switch-room/src/views/AgreedMatchView.vue b/FrontendFolder/switch-room/src/views/AgreedMatchView.vue
new file mode 100644
index 00000000..0843c775
--- /dev/null
+++ b/FrontendFolder/switch-room/src/views/AgreedMatchView.vue
@@ -0,0 +1,7 @@
+<template>
+  <agreed-match-page></agreed-match-page>
+</template>
+
+<script setup lang="ts">
+import AgreedMatchPage from "@/components/AgreedMatchPage.vue";
+</script>
\ No newline at end of file
-- 
GitLab