feat(customer-vue): Just pickup 매장 검색 페이지 구현
- 매장 검색 페이지 더보기 버튼 로직 구현 - 페이지 로딩 시 로딩 바 추가
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.26.0",
|
||||
"core-js": "^3.8.3",
|
||||
"vue": "^2.6.14",
|
||||
"vue-router": "^3.5.3",
|
||||
|
||||
15
customer-vue/src/api/store.js
Normal file
15
customer-vue/src/api/store.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
requestSearchStore(latitude, longitude, storeName, page) {
|
||||
const options = {
|
||||
params: {
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
storeName: storeName,
|
||||
page: page
|
||||
}
|
||||
}
|
||||
return axios.get("http://localhost:8000/store-service/searchStore", options);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,11 @@ const routes = [
|
||||
path: "/home",
|
||||
name: 'home',
|
||||
component: () => import('../views/HomeView')
|
||||
},
|
||||
{
|
||||
path: "/search",
|
||||
name: 'search-store',
|
||||
component: () => import('../views/SearchStore')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<app-navigation></app-navigation>
|
||||
<v-main style="background-color: #f2f2f2!important;">
|
||||
<v-container class="px-8 py-8" style="background-color: white; height: 100%">
|
||||
<v-main>
|
||||
<v-container class="px-8 py-8">
|
||||
<router-view></router-view>
|
||||
</v-container>
|
||||
</v-main>
|
||||
@@ -25,6 +25,11 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
max-width: 960px;
|
||||
max-width: 768px;
|
||||
background-color: white;
|
||||
height: 100%;
|
||||
}
|
||||
main {
|
||||
background-color: #f2f2f2!important;
|
||||
}
|
||||
</style>
|
||||
147
customer-vue/src/views/SearchStore.vue
Normal file
147
customer-vue/src/views/SearchStore.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-row>
|
||||
<v-text-field
|
||||
v-model="storeName"
|
||||
@keyup.enter="search"
|
||||
@click:append="search"
|
||||
append-icon="mdi-magnify"
|
||||
label="지역, 가게명으로 찾아보세요"
|
||||
filled
|
||||
>
|
||||
</v-text-field>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-alert
|
||||
border="left"
|
||||
colored-border
|
||||
color="deep-purple accent-4"
|
||||
elevation="2"
|
||||
dense
|
||||
>
|
||||
거리 순으로 가까운 매장을 찾아왔어요 😁
|
||||
</v-alert>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col v-for="card in cards" v-bind:key="card.storeId" sm="6">
|
||||
<v-card v-bind:data-id="card.storeId">
|
||||
<v-img
|
||||
height="180"
|
||||
src="https://cdn.vuetifyjs.com/images/cards/cooking.png"
|
||||
></v-img>
|
||||
<v-card-title>{{ card.name }}</v-card-title>
|
||||
<v-card-text>
|
||||
거리 : {{ card.distance }}
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
|
||||
</v-row>
|
||||
|
||||
<br><br>
|
||||
<v-row justify="center" v-if="hasNext">
|
||||
<v-btn @click="more"
|
||||
elevation="2"
|
||||
color="blue-grey"
|
||||
class="ma-2 white--text"
|
||||
>
|
||||
<b>더보기</b>
|
||||
<v-icon>mdi-chevron-down</v-icon>
|
||||
</v-btn>
|
||||
</v-row>
|
||||
|
||||
<v-overlay :value="isLoading">
|
||||
<v-progress-circular
|
||||
indeterminate
|
||||
size="64"
|
||||
></v-progress-circular>
|
||||
</v-overlay>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storeApi from "../api/store.js";
|
||||
|
||||
export default {
|
||||
name: "SearchStore",
|
||||
async mounted() {
|
||||
const location = await this.getLocation();
|
||||
|
||||
this.latitude = location.latitude;
|
||||
this.longitude = location.longitude;
|
||||
|
||||
await this.search();
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
isLoading: true,
|
||||
latitude: null,
|
||||
longitude: null,
|
||||
storeName: "",
|
||||
page: 0,
|
||||
cards: [],
|
||||
hasNext: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getLocation: async function() {
|
||||
console.log("initGeoLocation");
|
||||
return new Promise(function (resolve, reject) {
|
||||
if ('geolocation' in navigator) {
|
||||
navigator.geolocation.getCurrentPosition((position) => {
|
||||
const coords = position.coords;
|
||||
|
||||
resolve({
|
||||
latitude: coords.latitude,
|
||||
longitude: coords.longitude
|
||||
})
|
||||
})
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
},
|
||||
search: async function() {
|
||||
this.isLoading = true;
|
||||
try {
|
||||
this.page = 0;
|
||||
const response = await storeApi.requestSearchStore(this.latitude, this.longitude, this.storeName, this.page);
|
||||
this.cards = [];
|
||||
this.renderCard(response.data);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
this.isLoading = false;
|
||||
},
|
||||
more: async function() {
|
||||
this.isLoading = true;
|
||||
try {
|
||||
this.page += 1;
|
||||
const response = await storeApi.requestSearchStore(this.latitude, this.longitude, this.storeName, this.page);
|
||||
this.renderCard(response.data);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
this.isLoading = false;
|
||||
},
|
||||
renderCard: function(json) {
|
||||
this.hasNext = json.data.hasNext;
|
||||
const stores = json.data.stores;
|
||||
|
||||
stores.forEach( (store) => {
|
||||
this.cards.push({
|
||||
storeId: store.storeId,
|
||||
name: store.name,
|
||||
distance: store.distance
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user