feat: add fetching
This commit is contained in:
parent
fc88db10e0
commit
6e9947640b
@ -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
|
||||||
|
|||||||
@ -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": {
|
||||||
|
|||||||
59
src/App.vue
59
src/App.vue
@ -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>
|
||||||
|
|||||||
@ -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"
|
||||||
/>
|
/>
|
||||||
|
|||||||
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
|
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
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user