<template> <el-row :gutter="20"> <el-col :span="3"><div class="grid-content ep-bg-purple" /></el-col> <el-col :span="12"> <el-card style="width: 100%"> <template #header> <div class="card-header"> <span>Your Offer Information</span> </div> </template> <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="180px" :label-position="'right'" class="demo-ruleForm" :size="formSize" status-icon > <el-form-item label="Located City" prop="spaceLocateCity"> <el-col :span="15"> <el-input v-model="ruleForm.spaceLocateCity" :readonly="buttonState === 'edit'"/> </el-col> </el-form-item> <el-form-item label="State" prop="state"> <el-col :span="8"> <el-select v-model="ruleForm.state" placeholder="Select state" :disabled="buttonState === 'edit'" > <el-option v-for="(state_item, index) in USA_STATE_INITAL_LIST" :label="state_item" :value="state_item" /> </el-select> </el-col> </el-form-item> <el-form-item label="Zip Code" prop="zipCode"> <el-col :span="7"> <el-input v-model="ruleForm.zipCode" placeholder="24061" :readonly="buttonState === 'edit'"/> </el-col> </el-form-item> <el-col :span="24"> <el-form-item label="Space Type" prop="spaceType"> <el-select v-model="ruleForm.spaceType" placeholder="Please select your Space Type" :disabled="buttonState === 'edit'" > <el-option label="Apartment (No Roommates)" value="apt-single" /> <el-option label="Apartment (Shared with Roommates)" value="apt-share" /> <el-option label="Townhouse (No Roommates)" value="th-single" /> <el-option label="Townhouse (Shared with Roommates)" value="th-share" /> <el-option label="Single Family House (No Roommates)" value="sfh-single" /> <el-option label="Single Family House (Shared with Roommates)" value="sfh-share" /> <el-option label="Other" value="other" /> </el-select> </el-form-item> </el-col> <el-form-item label="Other Type" v-if="ruleForm.spaceType === 'other'" :required="ruleForm.spaceType === 'other'" > <el-col :span="8"> <el-input v-model="ruleForm.otherSpaceType" :readonly="buttonState === 'edit'"/> </el-col> </el-form-item> <el-form-item label="Space Available for Offering?"> <el-col :span="2"> <el-form-item prop="offering"> <el-switch v-model="ruleForm.offering" :disabled="buttonState === 'edit'"/> </el-form-item> </el-col> </el-form-item> <el-form-item></el-form-item> <el-form-item label="Time Window" v-if="ruleForm.offering" :required="ruleForm.offering" > <el-col :span="7"> <el-form-item prop="availableTimeStart"> <el-date-picker v-model="ruleForm.availableTimeStart" type="date" label="Pick a date" placeholder="Pick a date" style="width: 100%" :readonly="buttonState === 'edit'" /> </el-form-item> </el-col> <el-col class="text-center" :span="2"> <span class="text-gray-500"> To </span> </el-col> <el-col :span="7"> <el-form-item prop="availableTimeEnd"> <el-date-picker v-model="ruleForm.availableTimeEnd" label="Pick a time" placeholder="Pick a time" style="width: 100%" :readonly="buttonState === 'edit'" /> </el-form-item> </el-col> </el-form-item> <el-form-item label="Max Number of People" :required="ruleForm.offering" v-if="ruleForm.offering" prop="maxNumberOfPeople" > <el-col :span="4"> <el-input v-model="ruleForm.maxNumberOfPeople" :readonly="buttonState === 'edit'"/> </el-col> </el-form-item> <el-form-item></el-form-item> <el-form-item label="Space Details:" prop="spaceDetails"> <el-col :span="16" ><el-input v-model="ruleForm.spaceDetails" type="textarea" :readonly="buttonState === 'edit'" /></el-col> </el-form-item> <el-form-item v-if="buttonState === 'create'"> <el-button type="primary" @click="submitForm(ruleFormRef)" >Create</el-button> <el-button @click="resetForm(ruleFormRef)">Reset</el-button> </el-form-item> <el-form-item v-if="buttonState === 'edit'"> <el-button type="primary" @click="editForm()" >Edit</el-button> </el-form-item> <el-form-item v-if="buttonState === 'update'"> <el-button type="success" @click="updateForm(ruleFormRef)" >Save</el-button> <el-button type="danger" @click="deleteForm(ruleFormRef)">Delete</el-button> </el-form-item> </el-form> </el-card> </el-col> <el-col :span="6"> <el-card style="width: 100%"> <template #header> <div class="card-header"> <span>Match Request</span> </div> </template> <!-- TODO --> <el-card v-for="(item, index) in matchRequestList.value" shadow="hover" :fill="true" @click="selectMatchRequestItem(index)" > <time > {{formatDate(item.startTime)}} - {{formatDate(item.endTime)}}</time> <div class="w-bottom"> <span class="w-owner"> Wishlist Owner Name: {{item.wishListOwnerName}}</span> <br> <span class="w-zipCode" v-if="!item.hasOffer"> No Available Offer </span> <span class="w-zipCode">Zip Code: {{item.zipCode}}</span> </div> </el-card> </el-card> </el-col> <el-col :span="2"></el-col> </el-row> </template> <script lang="ts" setup> import { reactive, ref, onMounted } from "vue"; import type { FormInstance, FormRules } from "element-plus"; import { OfferFormModel } from "@/models/OfferFormModel"; import * as OfferPageService from "@/services/OfferPageService"; import { USA_STATE_INITAL_LIST } from "@/services/Constans"; // Form verification relate field const formSize = ref("default"); const ruleFormRef = ref<FormInstance>(); const rules = reactive<FormRules>({ spaceLocateCity: [ { required: true, message: "Please give your space location", trigger: "blur", }, { min: 0, max: 20, message: "Length should be 0 to 20", trigger: "blur" }, ], state: [ { required: true, message: "Please give your space located state", trigger: "blur", }, { min: 0, max: 20, message: "Length should be 0 to 20", trigger: "blur" }, ], zipCode: [ { required: true, message: "Please give your zip code of your space", trigger: "blur", }, ], spaceType: [ { required: true, message: "Please select your space type", trigger: "blur", }, ], }); // TODO: uncomment it when API connection ready let ruleForm = ref(new OfferFormModel()); let buttonState = ref("create"); let matchRequestList = reactive({value:[]}); onMounted(() => { loadInitOfferInfoPage(); loadOfferPageMatchRequest(); }) const loadInitOfferInfoPage = async () =>{ await OfferPageService.getUserOfferInfoFromServer().then( (data) => { console.log("Receive user offer data: ", data); if(data["data"] === null){ // TODO: Handle fetch error }else{ ruleForm.value = data["data"]; if(ruleForm.value.spaceLocateCity == null || ruleForm.value.spaceLocateCity == ""){ buttonState.value = "create"; }else{ buttonState.value = "edit"; } } }); } const loadOfferPageMatchRequest = async() =>{ await OfferPageService.getWishlistMatchRequestInfoList().then( (data) =>{ console.log("Fetching Offer Page Match Request Info: ", data); matchRequestList.value = data["data"]; }) } const submitForm = async (formEl: FormInstance | undefined) => { if (!formEl) return; await formEl.validate((valid, fields) => { if (valid) { // TODO: Check the return result console.log("Form Data before save in DB: ", ruleForm.value); OfferPageService.createNewUserOffer(ruleForm.value).then((data) => { console.log("Save user offer data: ", data); ruleForm.value = data["data"]; buttonState.value = "edit"; }) console.log("submit!"); } else { console.log("error submit!", fields); } }); }; const editForm = () => { buttonState.value = "update"; } const updateForm = async (formEl: FormInstance | undefined) => { if (!formEl) return; await formEl.validate((valid, fields) => { if (valid) { // TODO: Check the return result OfferPageService.updateOffer(ruleForm.value).then((data) =>{ console.log("Update user offer data: ", data); ruleForm.value = data["data"]; buttonState.value = "edit"; }) } else { console.log("error submit!", fields); } }); }; const deleteForm = async(formEl: FormInstance | undefined) => { // TODO: Check the return result await OfferPageService.deleteOffer(ruleForm.value.userId).then((data) =>{ console.log("Deleting Offer Record"); console.log("Message: " + data["message"]); resetForm(); buttonState.value = "create"; }); }; const resetForm = () => { let userId = ruleForm.value.userId; ruleForm.value = new OfferFormModel(); ruleForm.value.userId = userId; }; const options = Array.from({ length: 10000 }).map((_, idx) => ({ value: `${idx + 1}`, label: `${idx + 1}`, })); const formatDate = (dateString) => { const date = new Date(dateString); return new Intl.DateTimeFormat('en-US').format(date); } </script> <style scoped> .time { font-size: 12px; } .w-zipCode { font-size: 12px; } .w-owner { font-size: 12px; } </style>