feat: add fetching
This commit is contained in:
parent
fc88db10e0
commit
6e9947640b
@ -6,6 +6,8 @@ before_script:
|
||||
- yarn install
|
||||
|
||||
deploy-pages:
|
||||
variables:
|
||||
VITE_API_URL: https://94f4d2a6f1595ab1.mokky.dev
|
||||
script:
|
||||
- npm run build
|
||||
pages: true
|
||||
@ -13,3 +15,5 @@ deploy-pages:
|
||||
paths:
|
||||
- dist
|
||||
publish: dist
|
||||
after_script:
|
||||
- echo Vue Sneakers Page Deployed at $CI_PAGES_UR
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.9",
|
||||
"vue": "^3.5.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
59
src/App.vue
59
src/App.vue
@ -1,10 +1,46 @@
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref, watch } from 'vue'
|
||||
import Header from '@/components/Header.vue'
|
||||
import CardList from '@/components/CardList.vue'
|
||||
import Drawer from '@/components/Drawer.vue'
|
||||
import axios from 'axios'
|
||||
import Spinner from '@/components/Spinner.vue'
|
||||
|
||||
const showDrawer = ref(false);
|
||||
const items = ref([]);
|
||||
const isLoading = ref(false);
|
||||
const filters = reactive({
|
||||
searchQuery: '',
|
||||
sortBy: ''
|
||||
});
|
||||
|
||||
const fetchItems = async (filters = {}) => {
|
||||
const params = {};
|
||||
if (filters.searchQuery) {
|
||||
params.title = '*' + filters.searchQuery + '*'
|
||||
}
|
||||
if (filters.sortBy) {
|
||||
params.sortBy = filters.sortBy
|
||||
}
|
||||
|
||||
try {
|
||||
isLoading.value = true
|
||||
const { data } = await axios.get(`${import.meta.env.VITE_API_URL}/items`, { params });
|
||||
items.value = data
|
||||
} catch (e) {
|
||||
console.error('Some error', e)
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(fetchItems)
|
||||
watch(filters, fetchItems)
|
||||
</script>
|
||||
<template>
|
||||
<!-- <Drawer/>-->
|
||||
<Drawer v-if="showDrawer"/>
|
||||
|
||||
<div
|
||||
class="mt-14 w-4/5 mx-auto bg-white rounded-xl shadow-xl"
|
||||
>
|
||||
@ -15,20 +51,29 @@
|
||||
<h2 class="text-3xl font-bold">Все кроссовки</h2>
|
||||
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
<select class="py-2 px-3 border rounded-md outline-none">
|
||||
<option>По названию</option>
|
||||
<option>По цене (сначала дешевые)</option>
|
||||
<option>По цене (сначала дорогие)</option>
|
||||
<select class="py-2 px-3 border rounded-md outline-none" v-model="filters.sortBy">
|
||||
<option value="" disabled>Сортировка по:</option>
|
||||
<option value="title">По названию</option>
|
||||
<option value="price">По цене (сначала дешевые)</option>
|
||||
<option value="-price">По цене (сначала дорогие)</option>
|
||||
</select>
|
||||
|
||||
<div class="relative">
|
||||
<img class="absolute top-3 left-4" src="/search.svg" alt="Search">
|
||||
<input class="border rounded-md py-2 pl-11 pr-4 outline-none focus:border-gray-400" type="text" placeholder="Поиск">
|
||||
<input v-model="filters.searchQuery" class="border rounded-md py-2 pl-11 pr-4 outline-none focus:border-gray-400" type="text" placeholder="Поиск">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CardList/>
|
||||
|
||||
<div v-if="isLoading" class="flex justify-center align-center">
|
||||
<Spinner/>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<CardList v-if="items.length > 0" :items="items" />
|
||||
<h2 v-else>Пусто</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -8,14 +8,20 @@
|
||||
const onClickFavorite = () => {
|
||||
alert('Добавлено в Избранное')
|
||||
}
|
||||
|
||||
defineProps({
|
||||
items: Array
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid grid-cols-4 gap-5">
|
||||
<div class="grid md:grid-cols-2 xl:grid-cols-4 gap-5">
|
||||
<Card
|
||||
image-url="/sneakers/sneakers-1.jpg"
|
||||
title="Мужские кроссовки Nike Blazer Mid Suede"
|
||||
:price="12999"
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
:image-url="item.imageUrl"
|
||||
:title="item.title"
|
||||
:price="item.price"
|
||||
:on-click-add="onClickAdd"
|
||||
:on-click-favorite="onClickFavorite"
|
||||
/>
|
||||
|
||||
59
src/components/Spinner.vue
Normal file
59
src/components/Spinner.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<span class="loader"></span>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.loader {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
border: 3px solid;
|
||||
border-color: #FFF #FFF transparent transparent;
|
||||
box-sizing: border-box;
|
||||
animation: rotation 1s linear infinite;
|
||||
}
|
||||
.loader::after,
|
||||
.loader::before {
|
||||
content: '';
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
border: 3px solid;
|
||||
border-color: transparent transparent #95af4d #95af4d;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
animation: rotationBack 0.5s linear infinite;
|
||||
transform-origin: center center;
|
||||
}
|
||||
.loader::before {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-color: #FFF #FFF transparent transparent;
|
||||
animation: rotation 1.5s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotationBack {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
107
yarn.lock
107
yarn.lock
@ -1181,10 +1181,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"abbrev@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "abbrev@npm:2.0.0"
|
||||
checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372
|
||||
"abbrev@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "abbrev@npm:3.0.0"
|
||||
checksum: 10c0/049704186396f571650eb7b22ed3627b77a5aedf98bb83caf2eac81ca2a3e25e795394b0464cfb2d6076df3db6a5312139eac5b6a126ca296ac53c5008069c28
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -1280,6 +1280,7 @@ __metadata:
|
||||
"@vitejs/plugin-vue-jsx": "npm:^4.1.1"
|
||||
"@vue/eslint-config-prettier": "npm:^10.1.0"
|
||||
autoprefixer: "npm:^10.4.20"
|
||||
axios: "npm:^1.7.9"
|
||||
eslint: "npm:^9.14.0"
|
||||
eslint-plugin-vue: "npm:^9.30.0"
|
||||
npm-run-all2: "npm:^7.0.1"
|
||||
@ -1306,6 +1307,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"asynckit@npm:^0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "asynckit@npm:0.4.0"
|
||||
checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"autoprefixer@npm:^10.4.20":
|
||||
version: 10.4.20
|
||||
resolution: "autoprefixer@npm:10.4.20"
|
||||
@ -1324,6 +1332,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"axios@npm:^1.7.9":
|
||||
version: 1.7.9
|
||||
resolution: "axios@npm:1.7.9"
|
||||
dependencies:
|
||||
follow-redirects: "npm:^1.15.6"
|
||||
form-data: "npm:^4.0.0"
|
||||
proxy-from-env: "npm:^1.1.0"
|
||||
checksum: 10c0/b7a41e24b59fee5f0f26c1fc844b45b17442832eb3a0fb42dd4f1430eb4abc571fe168e67913e8a1d91c993232bd1d1ab03e20e4d1fee8c6147649b576fc1b0b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"balanced-match@npm:^1.0.0":
|
||||
version: 1.0.2
|
||||
resolution: "balanced-match@npm:1.0.2"
|
||||
@ -1496,6 +1515,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"combined-stream@npm:^1.0.8":
|
||||
version: 1.0.8
|
||||
resolution: "combined-stream@npm:1.0.8"
|
||||
dependencies:
|
||||
delayed-stream: "npm:~1.0.0"
|
||||
checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"commander@npm:^4.0.0":
|
||||
version: 4.1.1
|
||||
resolution: "commander@npm:4.1.1"
|
||||
@ -1596,6 +1624,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"delayed-stream@npm:~1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "delayed-stream@npm:1.0.0"
|
||||
checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"didyoumean@npm:^1.2.2":
|
||||
version: 1.2.2
|
||||
resolution: "didyoumean@npm:1.2.2"
|
||||
@ -1618,9 +1653,9 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"electron-to-chromium@npm:^1.5.73":
|
||||
version: 1.5.83
|
||||
resolution: "electron-to-chromium@npm:1.5.83"
|
||||
checksum: 10c0/12380962d057c4679add1047cdddb18b909904614272da0527e505a3859eaffde2022dd0688ce7f230582de96405c3d33b667680614475cdafd3f629caa2fee1
|
||||
version: 1.5.85
|
||||
resolution: "electron-to-chromium@npm:1.5.85"
|
||||
checksum: 10c0/1997a4531423f71d1cdc1e5b1b85353d661fc82bae0439d546dacf53923716914ae22e2d74bc6d65b478a4b7ff9b083206c29f7819bc6c7dfdea3ef7c3f1f81c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -2099,6 +2134,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"follow-redirects@npm:^1.15.6":
|
||||
version: 1.15.9
|
||||
resolution: "follow-redirects@npm:1.15.9"
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
checksum: 10c0/5829165bd112c3c0e82be6c15b1a58fa9dcfaede3b3c54697a82fe4a62dd5ae5e8222956b448d2f98e331525f05d00404aba7d696de9e761ef6e42fdc780244f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"foreground-child@npm:^3.1.0":
|
||||
version: 3.3.0
|
||||
resolution: "foreground-child@npm:3.3.0"
|
||||
@ -2109,6 +2154,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"form-data@npm:^4.0.0":
|
||||
version: 4.0.1
|
||||
resolution: "form-data@npm:4.0.1"
|
||||
dependencies:
|
||||
asynckit: "npm:^0.4.0"
|
||||
combined-stream: "npm:^1.0.8"
|
||||
mime-types: "npm:^2.1.12"
|
||||
checksum: 10c0/bb102d570be8592c23f4ea72d7df9daa50c7792eb0cf1c5d7e506c1706e7426a4e4ae48a35b109e91c85f1c0ec63774a21ae252b66f4eb981cb8efef7d0463c8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fraction.js@npm:^4.3.7":
|
||||
version: 4.3.7
|
||||
resolution: "fraction.js@npm:4.3.7"
|
||||
@ -2706,6 +2762,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mime-db@npm:1.52.0":
|
||||
version: 1.52.0
|
||||
resolution: "mime-db@npm:1.52.0"
|
||||
checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mime-types@npm:^2.1.12":
|
||||
version: 2.1.35
|
||||
resolution: "mime-types@npm:2.1.35"
|
||||
dependencies:
|
||||
mime-db: "npm:1.52.0"
|
||||
checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimatch@npm:^3.1.2":
|
||||
version: 3.1.2
|
||||
resolution: "minimatch@npm:3.1.2"
|
||||
@ -2902,13 +2974,13 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"nopt@npm:^8.0.0":
|
||||
version: 8.0.0
|
||||
resolution: "nopt@npm:8.0.0"
|
||||
version: 8.1.0
|
||||
resolution: "nopt@npm:8.1.0"
|
||||
dependencies:
|
||||
abbrev: "npm:^2.0.0"
|
||||
abbrev: "npm:^3.0.0"
|
||||
bin:
|
||||
nopt: bin/nopt.js
|
||||
checksum: 10c0/19cb986f79abaca2d0f0b560021da7b32ee6fcc3de48f3eaeb0c324d36755c17754f886a754c091f01f740c17caf7d6aea8237b7fbaf39f476ae5e30a249f18f
|
||||
checksum: 10c0/62e9ea70c7a3eb91d162d2c706b6606c041e4e7b547cbbb48f8b3695af457dd6479904d7ace600856bf923dd8d1ed0696f06195c8c20f02ac87c1da0e1d315ef
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -3289,6 +3361,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"proxy-from-env@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "proxy-from-env@npm:1.1.0"
|
||||
checksum: 10c0/fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"punycode@npm:^2.1.0":
|
||||
version: 2.3.1
|
||||
resolution: "punycode@npm:2.3.1"
|
||||
@ -3963,8 +4042,8 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"vite@npm:^6.0.5":
|
||||
version: 6.0.7
|
||||
resolution: "vite@npm:6.0.7"
|
||||
version: 6.0.11
|
||||
resolution: "vite@npm:6.0.11"
|
||||
dependencies:
|
||||
esbuild: "npm:^0.24.2"
|
||||
fsevents: "npm:~2.3.3"
|
||||
@ -4010,7 +4089,7 @@ __metadata:
|
||||
optional: true
|
||||
bin:
|
||||
vite: bin/vite.js
|
||||
checksum: 10c0/ae81047b4290a7206b9394a39a782d509e9610462e7946422ba22d5bc615b5a322c07e33d7bf9dd0b3312ec3f5c63353b725913d1519324bfdf539b4f1e03f52
|
||||
checksum: 10c0/a0537f9bf8d6ded740646a4aa44b8dbf442d3005e75f7b27e981ef6011f22d4759f5eb643a393c0ffb8d21e2f50fb5f774d3a53108fb96a10b0f83697e8efe84
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user