labwork04

This commit is contained in:
IlyasValiulov
2025-04-20 11:39:57 +04:00
parent e300caab10
commit 958a0a9fbb
11 changed files with 900 additions and 9 deletions

19
db.json Normal file
View File

@@ -0,0 +1,19 @@
{
"movies": [
{
"id": "ebed",
"title": "ФФФФФФФФФфф",
"imageUrl": "https://avatars.mds.yandex.net/i?id=8e077526d7dfae9d31827e81fea4e74c_l-5233298-images-thumbs&n=13"
},
{
"id": "8fd8",
"title": "ittifaq",
"imageUrl": "https://avatars.mds.yandex.net/i?id=17b83f995e81ac7426335d0659a050263d567f34-13135934-images-thumbs&n=13"
},
{
"id": "5267",
"title": "priora",
"imageUrl": "https://ir-3.ozone.ru/s3/multimedia-8/w1200/6738078680.jpg"
}
]
}

47
film_database.json Normal file
View File

@@ -0,0 +1,47 @@
{
"Movies": [
{
"id": "ebed",
"title_id": "ebed",
"image_id": "ebed"
},
{
"id": "8fd8",
"title_id": "8fd8",
"image_id": "8fd8"
},
{
"id": "63cb",
"title_id": "63cb",
"image_id": "63cb"
}
],
"Title": [
{
"id": "ebed",
"title": "ФФФФФФФФФфф"
},
{
"id": "8fd8",
"title": "ittifaq"
},
{
"id": "63cb",
"title": "priora"
}
],
"Image": [
{
"id": "ebed",
"imageUrl": "https://avatars.mds.yandex.net/i?id=8e077526d7dfae9d31827e81fea4e74c_l-5233298-images-thumbs&n=13"
},
{
"id": "8fd8",
"imageUrl": "https://avatars.mds.yandex.net/i?id=17b83f995e81ac7426335d0659a050263d567f34-13135934-images-thumbs&n=13"
},
{
"id": "63cb",
"imageUrl": "https://ir-3.ozone.ru/s3/multimedia-8/w1200/6738078680.jpg"
}
]
}

548
package-lock.json generated
View File

@@ -18,6 +18,7 @@
"eslint-config-prettier": "^10.1.1",
"eslint-plugin-prettier": "^5.2.3",
"globals": "^16.0.0",
"json-server": "^1.0.0-beta.3",
"prettier": "^3.5.3",
"sass": "^1.85.1",
"vite": "^6.2.1"
@@ -988,6 +989,13 @@
"url": "https://opencollective.com/unts"
}
},
"node_modules/@polka/url": {
"version": "1.0.0-next.28",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
"integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
"dev": true,
"license": "MIT"
},
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
@@ -1264,6 +1272,263 @@
"win32"
]
},
"node_modules/@tinyhttp/accepts": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@tinyhttp/accepts/-/accepts-2.2.3.tgz",
"integrity": "sha512-9pQN6pJAJOU3McmdJWTcyq7LLFW8Lj5q+DadyKcvp+sxMkEpktKX5sbfJgJuOvjk6+1xWl7pe0YL1US1vaO/1w==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime": "4.0.4",
"negotiator": "^0.6.3"
},
"engines": {
"node": ">=12.20.0"
},
"funding": {
"type": "individual",
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1"
}
},
"node_modules/@tinyhttp/app": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@tinyhttp/app/-/app-2.5.2.tgz",
"integrity": "sha512-DcB3Y8GQppLQlO2VxRYF7LzTEAoZb+VRQXuIsErcu2fNaM1xdx6NQZDso5rlZUiaeg6KYYRfU34N4XkZbv6jSA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@tinyhttp/cookie": "2.1.1",
"@tinyhttp/proxy-addr": "2.2.1",
"@tinyhttp/req": "2.2.5",
"@tinyhttp/res": "2.2.5",
"@tinyhttp/router": "2.2.3",
"header-range-parser": "1.1.3",
"regexparam": "^2.0.2"
},
"engines": {
"node": ">=14.21.3"
},
"funding": {
"type": "individual",
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1"
}
},
"node_modules/@tinyhttp/content-disposition": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@tinyhttp/content-disposition/-/content-disposition-2.2.2.tgz",
"integrity": "sha512-crXw1txzrS36huQOyQGYFvhTeLeG0Si1xu+/l6kXUVYpE0TjFjEZRqTbuadQLfKGZ0jaI+jJoRyqaWwxOSHW2g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20.0"
},
"funding": {
"type": "individual",
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1"
}
},
"node_modules/@tinyhttp/content-type": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@tinyhttp/content-type/-/content-type-0.1.4.tgz",
"integrity": "sha512-dl6f3SHIJPYbhsW1oXdrqOmLSQF/Ctlv3JnNfXAE22kIP7FosqJHxkz/qj2gv465prG8ODKH5KEyhBkvwrueKQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.4"
}
},
"node_modules/@tinyhttp/cookie": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/cookie/-/cookie-2.1.1.tgz",
"integrity": "sha512-h/kL9jY0e0Dvad+/QU3efKZww0aTvZJslaHj3JTPmIPC9Oan9+kYqmh3M6L5JUQRuTJYFK2nzgL2iJtH2S+6dA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20.0"
},
"funding": {
"type": "individual",
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1"
}
},
"node_modules/@tinyhttp/cookie-signature": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/cookie-signature/-/cookie-signature-2.1.1.tgz",
"integrity": "sha512-VDsSMY5OJfQJIAtUgeQYhqMPSZptehFSfvEEtxr+4nldPA8IImlp3QVcOVuK985g4AFR4Hl1sCbWCXoqBnVWnw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/cors": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/cors/-/cors-2.0.1.tgz",
"integrity": "sha512-qrmo6WJuaiCzKWagv2yA/kw6hIISfF/hOqPWwmI6w0o8apeTMmRN3DoCFvQ/wNVuWVdU5J4KU7OX8aaSOEq51A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@tinyhttp/vary": "^0.1.3"
},
"engines": {
"node": ">=12.20 || 14.x || >=16"
}
},
"node_modules/@tinyhttp/encode-url": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/encode-url/-/encode-url-2.1.1.tgz",
"integrity": "sha512-AhY+JqdZ56qV77tzrBm0qThXORbsVjs/IOPgGCS7x/wWnsa/Bx30zDUU/jPAUcSzNOzt860x9fhdGpzdqbUeUw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/etag": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@tinyhttp/etag/-/etag-2.1.2.tgz",
"integrity": "sha512-j80fPKimGqdmMh6962y+BtQsnYPVCzZfJw0HXjyH70VaJBHLKGF+iYhcKqzI3yef6QBNa8DKIPsbEYpuwApXTw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/forwarded": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@tinyhttp/forwarded/-/forwarded-2.1.2.tgz",
"integrity": "sha512-9H/eulJ68ElY/+zYpTpNhZ7vxGV+cnwaR6+oQSm7bVgZMyuQfgROW/qvZuhmgDTIxnGMXst+Ba4ij6w6Krcs3w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/logger": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tinyhttp/logger/-/logger-2.1.0.tgz",
"integrity": "sha512-Ma1fJ9CwUbn9r61/4HW6+nflsVoslpOnCrfQ6UeZq7GGIgwLzofms3HoSVG7M+AyRMJpxlfcDdbH5oFVroDMKA==",
"dev": true,
"license": "MIT",
"dependencies": {
"colorette": "^2.0.20",
"dayjs": "^1.11.13",
"http-status-emojis": "^2.2.0"
},
"engines": {
"node": ">=14.18 || >=16.20"
}
},
"node_modules/@tinyhttp/proxy-addr": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/proxy-addr/-/proxy-addr-2.2.1.tgz",
"integrity": "sha512-BicqMqVI91hHq2BQmnqJUh0FQUnx7DncwSGgu2ghlh+JZG2rHK2ZN/rXkfhrx1rrUw6hnd0L36O8GPMh01+dDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@tinyhttp/forwarded": "2.1.2",
"ipaddr.js": "^2.2.0"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/req": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@tinyhttp/req/-/req-2.2.5.tgz",
"integrity": "sha512-trfsXwtmsNjMcGKcLJ+45h912kLRqBQCQD06ams3Tq0kf4gHLxjHjoYOC1Z9yGjOn81XllRx8wqvnvr+Kbe3gw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@tinyhttp/accepts": "2.2.3",
"@tinyhttp/type-is": "2.2.4",
"@tinyhttp/url": "2.1.1",
"header-range-parser": "^1.1.3"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/res": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@tinyhttp/res/-/res-2.2.5.tgz",
"integrity": "sha512-yBsqjWygpuKAVz4moWlP4hqzwiDDqfrn2mA0wviJAcgvGiyOErtlQwXY7aj3aPiCpURvxvEFO//Gdy6yV+xEpA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@tinyhttp/content-disposition": "2.2.2",
"@tinyhttp/cookie": "2.1.1",
"@tinyhttp/cookie-signature": "2.1.1",
"@tinyhttp/encode-url": "2.1.1",
"@tinyhttp/req": "2.2.5",
"@tinyhttp/send": "2.2.3",
"@tinyhttp/vary": "^0.1.3",
"es-escape-html": "^0.1.1",
"mime": "4.0.4"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/router": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@tinyhttp/router/-/router-2.2.3.tgz",
"integrity": "sha512-O0MQqWV3Vpg/uXsMYg19XsIgOhwjyhTYWh51Qng7bxqXixxx2PEvZWnFjP7c84K7kU/nUX41KpkEBTLnznk9/Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/send": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@tinyhttp/send/-/send-2.2.3.tgz",
"integrity": "sha512-o4cVHHGQ8WjVBS8UT0EE/2WnjoybrfXikHwsRoNlG1pfrC/Sd01u1N4Te8cOd/9aNGLr4mGxWb5qTm2RRtEi7g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@tinyhttp/content-type": "^0.1.4",
"@tinyhttp/etag": "2.1.2",
"mime": "4.0.4"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/type-is": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@tinyhttp/type-is/-/type-is-2.2.4.tgz",
"integrity": "sha512-7F328NheridwjIfefBB2j1PEcKKABpADgv7aCJaE8x8EON77ZFrAkI3Rir7pGjopV7V9MBmW88xUQigBEX2rmQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@tinyhttp/content-type": "^0.1.4",
"mime": "4.0.4"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/url": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/url/-/url-2.1.1.tgz",
"integrity": "sha512-POJeq2GQ5jI7Zrdmj22JqOijB5/GeX+LEX7DUdml1hUnGbJOTWDx7zf2b5cCERj7RoXL67zTgyzVblBJC+NJWg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/vary": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@tinyhttp/vary/-/vary-0.1.3.tgz",
"integrity": "sha512-SoL83sQXAGiHN1jm2VwLUWQSQeDAAl1ywOm6T0b0Cg1CZhVsjoiZadmjhxF6FHCCY7OHHVaLnTgSMxTPIDLxMg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20"
}
},
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
@@ -1455,6 +1720,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/colorette": {
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
"dev": true,
"license": "MIT"
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -1477,6 +1749,13 @@
"node": ">= 8"
}
},
"node_modules/dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
"dev": true,
"license": "MIT"
},
"node_modules/debug": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
@@ -1516,6 +1795,32 @@
"node": ">=0.10"
}
},
"node_modules/dot-prop": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz",
"integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"type-fest": "^4.18.2"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/es-escape-html": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/es-escape-html/-/es-escape-html-0.1.1.tgz",
"integrity": "sha512-yUx1o+8RsG7UlszmYPtks+dm6Lho2m8lgHMOsLJQsFI0R8XwUJwiMhM1M4E/S8QLeGyf6MkDV/pWgjQ0tdTSyQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.x"
}
},
"node_modules/esbuild": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
@@ -1769,6 +2074,19 @@
"node": ">=0.10.0"
}
},
"node_modules/eta": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/eta/-/eta-3.5.0.tgz",
"integrity": "sha512-e3x3FBvGzeCIHhF+zhK8FZA2vC5uFn6b4HJjegUbIWrDb4mJ7JjTGMJY9VGIbRVpmSwHopNiaJibhjIr+HfLug==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
},
"funding": {
"url": "https://github.com/eta-dev/eta?sponsor=1"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -1913,6 +2231,23 @@
"node": ">=8"
}
},
"node_modules/header-range-parser": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/header-range-parser/-/header-range-parser-1.1.3.tgz",
"integrity": "sha512-B9zCFt3jH8g09LR1vHL4pcAn8yMEtlSlOUdQemzHMRKMImNIhhszdeosYFfNW0WXKQtXIlWB+O4owHJKvEJYaA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.22.0"
}
},
"node_modules/http-status-emojis": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/http-status-emojis/-/http-status-emojis-2.2.0.tgz",
"integrity": "sha512-ompKtgwpx8ff0hsbpIB7oE4ax1LXoHmftsHHStMELX56ivG3GhofTX8ZHWlUaFKfGjcGjw6G3rPk7dJRXMmbbg==",
"dev": true,
"license": "MIT"
},
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -1957,6 +2292,26 @@
"node": ">=0.8.19"
}
},
"node_modules/inflection": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-3.0.2.tgz",
"integrity": "sha512-+Bg3+kg+J6JUWn8J6bzFmOWkTQ6L/NHfDRSYU+EVvuKHDxUDHAXgqixHfVlzuBQaPOTac8hn43aPhMNk6rMe3g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/ipaddr.js": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
"integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 10"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -2025,6 +2380,47 @@
"dev": true,
"license": "MIT"
},
"node_modules/json-server": {
"version": "1.0.0-beta.3",
"resolved": "https://registry.npmjs.org/json-server/-/json-server-1.0.0-beta.3.tgz",
"integrity": "sha512-DwE69Ep5ccwIJZBUIWEENC30Yj8bwr4Ax9W9VoIWAYnB8Sj4ReptscO8/DRHv/nXwVlmb3Bk73Ls86+VZdYkkA==",
"dev": true,
"license": "SEE LICENSE IN ./LICENSE",
"dependencies": {
"@tinyhttp/app": "^2.4.0",
"@tinyhttp/cors": "^2.0.1",
"@tinyhttp/logger": "^2.0.0",
"chalk": "^5.3.0",
"chokidar": "^4.0.1",
"dot-prop": "^9.0.0",
"eta": "^3.5.0",
"inflection": "^3.0.0",
"json5": "^2.2.3",
"lowdb": "^7.0.1",
"milliparsec": "^4.0.0",
"sirv": "^2.0.4",
"sort-on": "^6.1.0"
},
"bin": {
"json-server": "lib/bin.js"
},
"engines": {
"node": ">=18.3"
}
},
"node_modules/json-server/node_modules/chalk": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
@@ -2032,6 +2428,19 @@
"dev": true,
"license": "MIT"
},
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -2079,6 +2488,22 @@
"dev": true,
"license": "MIT"
},
"node_modules/lowdb": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/lowdb/-/lowdb-7.0.1.tgz",
"integrity": "sha512-neJAj8GwF0e8EpycYIDFqEPcx9Qz4GUho20jWFR7YiFeXzF1YMLdxB36PypcTSPMA+4+LvgyMacYhlr18Zlymw==",
"dev": true,
"license": "MIT",
"dependencies": {
"steno": "^4.0.2"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/typicode"
}
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -2094,6 +2519,32 @@
"node": ">=8.6"
}
},
"node_modules/milliparsec": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/milliparsec/-/milliparsec-4.0.0.tgz",
"integrity": "sha512-/wk9d4Z6/9ZvoEH/6BI4TrTCgmkpZPuSRN/6fI9aUHOfXdNTuj/VhLS7d+NqG26bi6L9YmGXutVYvWC8zQ0qtA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
}
},
"node_modules/mime": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-4.0.4.tgz",
"integrity": "sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==",
"dev": true,
"funding": [
"https://github.com/sponsors/broofa"
],
"license": "MIT",
"bin": {
"mime": "bin/cli.js"
},
"engines": {
"node": ">=16"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -2107,6 +2558,16 @@
"node": "*"
}
},
"node_modules/mrmime": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
"integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -2140,6 +2601,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/negotiator": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
"integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
@@ -2344,6 +2815,16 @@
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/regexparam": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/regexparam/-/regexparam-2.0.2.tgz",
"integrity": "sha512-A1PeDEYMrkLrfyOwv2jwihXbo9qxdGD3atBYQA9JJgreAx8/7rC6IUkWOw2NQlOxLp2wL0ifQbh1HuidDfYA6w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -2437,6 +2918,37 @@
"node": ">=8"
}
},
"node_modules/sirv": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
"integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@polka/url": "^1.0.0-next.24",
"mrmime": "^2.0.0",
"totalist": "^3.0.0"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/sort-on": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/sort-on/-/sort-on-6.1.0.tgz",
"integrity": "sha512-WTECP0nYNWO1n2g5bpsV0yZN9cBmZsF8ThHFbOqVN0HBFRoaQZLLEMvMmJlKHNPYQeVngeI5+jJzIfFqOIo1OA==",
"dev": true,
"license": "MIT",
"dependencies": {
"dot-prop": "^9.0.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -2447,6 +2959,19 @@
"node": ">=0.10.0"
}
},
"node_modules/steno": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/steno/-/steno-4.0.2.tgz",
"integrity": "sha512-yhPIQXjrlt1xv7dyPQg2P17URmXbuM5pdGkpiMB3RenprfiBlvK415Lctfe0eshk90oA7/tNq7WEiMK8RSP39A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/typicode"
}
},
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -2504,6 +3029,16 @@
"node": ">=8.0"
}
},
"node_modules/totalist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -2524,6 +3059,19 @@
"node": ">= 0.8.0"
}
},
"node_modules/type-fest": {
"version": "4.39.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.39.1.tgz",
"integrity": "sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w==",
"dev": true,
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",

View File

@@ -9,8 +9,10 @@
"build": "vite build",
"lint": "eslint src --fix",
"format": "prettier --write src/**/*.{js,css,html}",
"preview": "vite preview"
"preview": "vite preview",
"backend": "json-server db.json -p 3000"
},
"author": "IlyasValiulov",
"license": "ISC",
"devDependencies": {
@@ -19,10 +21,12 @@
"eslint-config-prettier": "^10.1.1",
"eslint-plugin-prettier": "^5.2.3",
"globals": "^16.0.0",
"json-server": "^1.0.0-beta.3",
"prettier": "^3.5.3",
"sass": "^1.85.1",
"vite": "^6.2.1"
},
"dependencies": {
"@popperjs/core": "^2.11.8",
"bootstrap": "^5.3.3"

36
src/edit.html Normal file
View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Редактирование фильма</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
<h1 class="mb-4" id="formTitle">Добавить новый фильм</h1>
<form id="movieForm">
<div class="mb-3">
<label for="movieTitle" class="form-label">Название фильма</label>
<input type="text" class="form-control" id="movieTitle" required>
</div>
<div class="mb-3">
<label for="movieImage" class="form-label">Ссылка на изображение</label>
<input type="url" class="form-control" id="movieImage" placeholder="https://example.com/image.jpg">
</div>
<div class="d-flex justify-content-between">
<button type="submit" class="btn btn-primary">Сохранить</button>
<a href="help.html" class="btn btn-secondary">Отмена</a>
</div>
</form>
</div>
<!-- <script src="js/model.js"></script>
<script src="js/view.js"></script>
<script src="js/controller.js"></script> -->
<script type="module" src="js/main.js"></script>
</body>
</html>

View File

@@ -6,7 +6,7 @@
<title>Помощь</title>
<!-- <link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="npcss/help.css" /> -->
<script type="module" src="js/main.js"></script>
<!-- <script type="module" src="js/main.js"></script> -->
</head>
<body>
<header class="container mt-4 mb-4">
@@ -35,7 +35,7 @@
</div>
</header>
<div class="container">
<!-- <div class="container">
<h2>Добавить фильм</h2>
<p></p>
@@ -52,6 +52,16 @@
</form>
<div id="movieContainer" class="row mt-5"></div>
</div> -->
<div class="container mt-4">
<h1 class="mb-4">Мои фильмы</h1>
<div class="mb-4">
<a href="edit.html" class="btn btn-success">Добавить новый фильм</a>
</div>
<div id="movieContainer" class="row"></div>
</div>
<footer class="container mt-auto">
@@ -63,7 +73,12 @@
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
<!-- <script src="js/model.js"></script>
<script src="js/view.js"></script>
<script src="js/controller.js"></script> -->
<script type="module" src="js/main.js"></script>
<!-- <script>
document.getElementById('movieForm').addEventListener('submit', function (event) {
event.preventDefault();
@@ -88,6 +103,6 @@
document.getElementById('movieForm').reset();
});
</script>
</script> -->
</body>
</html>

81
src/js/controller.js Normal file
View File

@@ -0,0 +1,81 @@
export class MovieController {
constructor(model, view) {
this.model = model;
this.view = view;
this.currentMovieId = null;
this.init();
}
async init() {
const urlParams = new URLSearchParams(window.location.search);
this.currentMovieId = urlParams.get('id');
if (window.location.pathname.includes('edit.html')) {
await this.initEditPage();
} else {
await this.initListPage();
}
}
async initListPage() {
const movies = await this.model.fetchMovies();
this.view.renderMovies(movies);
this.view.movieContainer.addEventListener('click', async (e) => {
if (e.target.classList.contains('delete-btn')) {
const id = e.target.getAttribute('data-id');
const confirmed = confirm('Вы уверены, что хотите удалить этот фильм?');
if (confirmed) {
const success = await this.model.deleteMovie(id);
if (success) {
const movies = await this.model.fetchMovies();
this.view.renderMovies(movies);
} else {
this.view.showError('Не удалось удалить фильм');
}
}
}
});
}
async initEditPage() {
if (this.currentMovieId) {
const movie = await this.model.getMovieById(this.currentMovieId);
if (movie) {
this.view.fillFormWithMovieData(movie);
}
}
this.view.movieForm.addEventListener('submit', async (e) => {
e.preventDefault();
await this.handleFormSubmit();
});
}
async handleFormSubmit() {
const movieData = this.view.getFormData();
try {
if (this.currentMovieId) {
const updatedMovie = await this.model.updateMovie(this.currentMovieId, movieData);
if (updatedMovie) {
this.view.redirectToList();
} else {
this.view.showError('Не удалось обновить фильм');
}
} else {
const newMovie = await this.model.createMovie(movieData);
if (newMovie) {
this.view.redirectToList();
} else {
this.view.showError('Не удалось создать фильм');
}
}
} catch (error) {
console.error('Error:', error);
this.view.showError('Произошла ошибка при сохранении фильма');
}
}
}

View File

@@ -1 +1,11 @@
import '../scss/styles.scss'
import '../scss/styles.scss';
import { MovieModel } from './model.js';
import { MovieView } from './view.js';
import { MovieController } from './controller.js';
document.addEventListener('DOMContentLoaded', () => {
const model = new MovieModel();
const view = new MovieView();
const controller = new MovieController(model, view);
});

70
src/js/model.js Normal file
View File

@@ -0,0 +1,70 @@
export class MovieModel {
constructor() {
this.apiUrl = 'http://localhost:3000/movies';
}
async getMovieById(id) {
try {
const response = await fetch(`${this.apiUrl}/${id}`);
return await response.json();
} catch (error) {
console.error('Error fetching movie:', error);
return null;
}
}
async fetchMovies() {
try {
const response = await fetch(this.apiUrl);
return await response.json();
} catch (error) {
console.error('Error fetching movies:', error);
return [];
}
}
async createMovie(movieData) {
try {
const response = await fetch(this.apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(movieData),
});
return await response.json();
} catch (error) {
console.error('Error creating movie:', error);
return null;
}
}
async updateMovie(id, movieData) {
try {
const response = await fetch(`${this.apiUrl}/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(movieData),
});
return await response.json();
} catch (error) {
console.error('Error updating movie:', error);
return null;
}
}
async deleteMovie(id) {
try {
const response = await fetch(`${this.apiUrl}/${id}`, {
method: 'DELETE',
});
return response.ok;
} catch (error) {
console.error('Error deleting movie:', error);
return false;
}
}
}

52
src/js/view.js Normal file
View File

@@ -0,0 +1,52 @@
export class MovieView {
constructor() {
this.movieContainer = document.getElementById('movieContainer');
this.movieForm = document.getElementById('movieForm');
}
renderMovies(movies) {
this.movieContainer.innerHTML = '';
movies.forEach(movie => {
const card = document.createElement('div');
card.className = 'col-md-4 mb-4';
const cardInner = `
<div class="card">
<img src="${movie.imageUrl || 'https://via.placeholder.com/300x450'}" class="card-img-top" alt="${movie.title}">
<div class="card-body">
<h5 class="card-title">${movie.title}</h5>
<div class="d-flex justify-content-between">
<a href="edit.html?id=${movie.id}" class="btn btn-warning">Редактировать</a>
<button class="btn btn-danger delete-btn" data-id="${movie.id}">Удалить</button>
</div>
</div>
</div>
`;
card.innerHTML = cardInner;
this.movieContainer.appendChild(card);
});
}
fillFormWithMovieData(movie) {
document.getElementById('movieTitle').value = movie.title;
document.getElementById('movieImage').value = movie.imageUrl || '';
}
getFormData() {
return {
title: document.getElementById('movieTitle').value,
imageUrl: document.getElementById('movieImage').value
};
}
showError(message) {
alert(message);
}
redirectToList() {
window.location.href = 'help.html';
}
}

View File

@@ -9,8 +9,17 @@ export default defineConfig({
}
}
},
// server: {
// port: 3000,
// hot: true,
// },
server: {
port: 3000,
hot: true,
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
},
}
});