feat: add fetching

This commit is contained in:
Sergey Krylov 2025-01-23 06:53:52 +03:00
parent fc88db10e0
commit 6e9947640b
6 changed files with 219 additions and 25 deletions

View File

@ -6,6 +6,8 @@ before_script:
- yarn install - yarn install
deploy-pages: deploy-pages:
variables:
VITE_API_URL: https://94f4d2a6f1595ab1.mokky.dev
script: script:
- npm run build - npm run build
pages: true pages: true
@ -13,3 +15,5 @@ deploy-pages:
paths: paths:
- dist - dist
publish: dist publish: dist
after_script:
- echo Vue Sneakers Page Deployed at $CI_PAGES_UR

View File

@ -11,6 +11,7 @@
"format": "prettier --write src/" "format": "prettier --write src/"
}, },
"dependencies": { "dependencies": {
"axios": "^1.7.9",
"vue": "^3.5.13" "vue": "^3.5.13"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,10 +1,46 @@
<script setup> <script setup>
import { onMounted, reactive, ref, watch } from 'vue'
import Header from '@/components/Header.vue' import Header from '@/components/Header.vue'
import CardList from '@/components/CardList.vue' import CardList from '@/components/CardList.vue'
import Drawer from '@/components/Drawer.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> </script>
<template> <template>
<!-- <Drawer/>--> <Drawer v-if="showDrawer"/>
<div <div
class="mt-14 w-4/5 mx-auto bg-white rounded-xl shadow-xl" 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> <h2 class="text-3xl font-bold">Все кроссовки</h2>
<div class="flex gap-4 flex-wrap"> <div class="flex gap-4 flex-wrap">
<select class="py-2 px-3 border rounded-md outline-none"> <select class="py-2 px-3 border rounded-md outline-none" v-model="filters.sortBy">
<option>По названию</option> <option value="" disabled>Сортировка по:</option>
<option>По цене (сначала дешевые)</option> <option value="title">По названию</option>
<option>По цене (сначала дорогие)</option> <option value="price">По цене (сначала дешевые)</option>
<option value="-price">По цене (сначала дорогие)</option>
</select> </select>
<div class="relative"> <div class="relative">
<img class="absolute top-3 left-4" src="/search.svg" alt="Search"> <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> </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>
</div> </div>

View File

@ -8,14 +8,20 @@
const onClickFavorite = () => { const onClickFavorite = () => {
alert('Добавлено в Избранное') alert('Добавлено в Избранное')
} }
defineProps({
items: Array
})
</script> </script>
<template> <template>
<div class="grid grid-cols-4 gap-5"> <div class="grid md:grid-cols-2 xl:grid-cols-4 gap-5">
<Card <Card
image-url="/sneakers/sneakers-1.jpg" v-for="item in items"
title="Мужские кроссовки Nike Blazer Mid Suede" :key="item.id"
:price="12999" :image-url="item.imageUrl"
:title="item.title"
:price="item.price"
:on-click-add="onClickAdd" :on-click-add="onClickAdd"
:on-click-favorite="onClickFavorite" :on-click-favorite="onClickFavorite"
/> />

View 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
View File

@ -1181,10 +1181,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"abbrev@npm:^2.0.0": "abbrev@npm:^3.0.0":
version: 2.0.0 version: 3.0.0
resolution: "abbrev@npm:2.0.0" resolution: "abbrev@npm:3.0.0"
checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372 checksum: 10c0/049704186396f571650eb7b22ed3627b77a5aedf98bb83caf2eac81ca2a3e25e795394b0464cfb2d6076df3db6a5312139eac5b6a126ca296ac53c5008069c28
languageName: node languageName: node
linkType: hard linkType: hard
@ -1280,6 +1280,7 @@ __metadata:
"@vitejs/plugin-vue-jsx": "npm:^4.1.1" "@vitejs/plugin-vue-jsx": "npm:^4.1.1"
"@vue/eslint-config-prettier": "npm:^10.1.0" "@vue/eslint-config-prettier": "npm:^10.1.0"
autoprefixer: "npm:^10.4.20" autoprefixer: "npm:^10.4.20"
axios: "npm:^1.7.9"
eslint: "npm:^9.14.0" eslint: "npm:^9.14.0"
eslint-plugin-vue: "npm:^9.30.0" eslint-plugin-vue: "npm:^9.30.0"
npm-run-all2: "npm:^7.0.1" npm-run-all2: "npm:^7.0.1"
@ -1306,6 +1307,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "autoprefixer@npm:^10.4.20":
version: 10.4.20 version: 10.4.20
resolution: "autoprefixer@npm:10.4.20" resolution: "autoprefixer@npm:10.4.20"
@ -1324,6 +1332,17 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "balanced-match@npm:^1.0.0":
version: 1.0.2 version: 1.0.2
resolution: "balanced-match@npm:1.0.2" resolution: "balanced-match@npm:1.0.2"
@ -1496,6 +1515,15 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "commander@npm:^4.0.0":
version: 4.1.1 version: 4.1.1
resolution: "commander@npm:4.1.1" resolution: "commander@npm:4.1.1"
@ -1596,6 +1624,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "didyoumean@npm:^1.2.2":
version: 1.2.2 version: 1.2.2
resolution: "didyoumean@npm:1.2.2" resolution: "didyoumean@npm:1.2.2"
@ -1618,9 +1653,9 @@ __metadata:
linkType: hard linkType: hard
"electron-to-chromium@npm:^1.5.73": "electron-to-chromium@npm:^1.5.73":
version: 1.5.83 version: 1.5.85
resolution: "electron-to-chromium@npm:1.5.83" resolution: "electron-to-chromium@npm:1.5.85"
checksum: 10c0/12380962d057c4679add1047cdddb18b909904614272da0527e505a3859eaffde2022dd0688ce7f230582de96405c3d33b667680614475cdafd3f629caa2fee1 checksum: 10c0/1997a4531423f71d1cdc1e5b1b85353d661fc82bae0439d546dacf53923716914ae22e2d74bc6d65b478a4b7ff9b083206c29f7819bc6c7dfdea3ef7c3f1f81c
languageName: node languageName: node
linkType: hard linkType: hard
@ -2099,6 +2134,16 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "foreground-child@npm:^3.1.0":
version: 3.3.0 version: 3.3.0
resolution: "foreground-child@npm:3.3.0" resolution: "foreground-child@npm:3.3.0"
@ -2109,6 +2154,17 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "fraction.js@npm:^4.3.7":
version: 4.3.7 version: 4.3.7
resolution: "fraction.js@npm:4.3.7" resolution: "fraction.js@npm:4.3.7"
@ -2706,6 +2762,22 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "minimatch@npm:^3.1.2":
version: 3.1.2 version: 3.1.2
resolution: "minimatch@npm:3.1.2" resolution: "minimatch@npm:3.1.2"
@ -2902,13 +2974,13 @@ __metadata:
linkType: hard linkType: hard
"nopt@npm:^8.0.0": "nopt@npm:^8.0.0":
version: 8.0.0 version: 8.1.0
resolution: "nopt@npm:8.0.0" resolution: "nopt@npm:8.1.0"
dependencies: dependencies:
abbrev: "npm:^2.0.0" abbrev: "npm:^3.0.0"
bin: bin:
nopt: bin/nopt.js nopt: bin/nopt.js
checksum: 10c0/19cb986f79abaca2d0f0b560021da7b32ee6fcc3de48f3eaeb0c324d36755c17754f886a754c091f01f740c17caf7d6aea8237b7fbaf39f476ae5e30a249f18f checksum: 10c0/62e9ea70c7a3eb91d162d2c706b6606c041e4e7b547cbbb48f8b3695af457dd6479904d7ace600856bf923dd8d1ed0696f06195c8c20f02ac87c1da0e1d315ef
languageName: node languageName: node
linkType: hard linkType: hard
@ -3289,6 +3361,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "punycode@npm:^2.1.0":
version: 2.3.1 version: 2.3.1
resolution: "punycode@npm:2.3.1" resolution: "punycode@npm:2.3.1"
@ -3963,8 +4042,8 @@ __metadata:
linkType: hard linkType: hard
"vite@npm:^6.0.5": "vite@npm:^6.0.5":
version: 6.0.7 version: 6.0.11
resolution: "vite@npm:6.0.7" resolution: "vite@npm:6.0.11"
dependencies: dependencies:
esbuild: "npm:^0.24.2" esbuild: "npm:^0.24.2"
fsevents: "npm:~2.3.3" fsevents: "npm:~2.3.3"
@ -4010,7 +4089,7 @@ __metadata:
optional: true optional: true
bin: bin:
vite: bin/vite.js vite: bin/vite.js
checksum: 10c0/ae81047b4290a7206b9394a39a782d509e9610462e7946422ba22d5bc615b5a322c07e33d7bf9dd0b3312ec3f5c63353b725913d1519324bfdf539b4f1e03f52 checksum: 10c0/a0537f9bf8d6ded740646a4aa44b8dbf442d3005e75f7b27e981ef6011f22d4759f5eb643a393c0ffb8d21e2f50fb5f774d3a53108fb96a10b0f83697e8efe84
languageName: node languageName: node
linkType: hard linkType: hard