Feltöltés vizsgaremek könyvkölcsönző
This commit is contained in:
commit
8739b17dc0
BIN
Frontend copy.zip
Normal file
BIN
Frontend copy.zip
Normal file
Binary file not shown.
20
Frontend copy/Frontend copy/.eslintrc.cjs
Normal file
20
Frontend copy/Frontend copy/.eslintrc.cjs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: { browser: true, es2020: true },
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'plugin:react/jsx-runtime',
|
||||||
|
'plugin:react-hooks/recommended',
|
||||||
|
],
|
||||||
|
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||||
|
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
||||||
|
settings: { react: { version: '18.2' } },
|
||||||
|
plugins: ['react-refresh'],
|
||||||
|
rules: {
|
||||||
|
'react-refresh/only-export-components': [
|
||||||
|
'warn',
|
||||||
|
{ allowConstantExport: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
24
Frontend copy/Frontend copy/.gitignore
vendored
Normal file
24
Frontend copy/Frontend copy/.gitignore
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
9
Frontend copy/Frontend copy/Cats.code-workspace
Normal file
9
Frontend copy/Frontend copy/Cats.code-workspace
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"name": "Cats",
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {}
|
||||||
|
}
|
8
Frontend copy/Frontend copy/README.md
Normal file
8
Frontend copy/Frontend copy/README.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# React + Vite
|
||||||
|
|
||||||
|
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||||
|
|
||||||
|
Currently, two official plugins are available:
|
||||||
|
|
||||||
|
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
||||||
|
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
5
Frontend copy/Frontend copy/config.js
Normal file
5
Frontend copy/Frontend copy/config.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
const config = {
|
||||||
|
backendUrl: 'http://localhost:3001/'
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
9
Frontend copy/Frontend copy/cypress.config.js
Normal file
9
Frontend copy/Frontend copy/cypress.config.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { defineConfig } from "cypress";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
e2e: {
|
||||||
|
setupNodeEvents(on, config) {
|
||||||
|
// implement node event listeners here
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
20
Frontend copy/Frontend copy/cypress/e2e/belepes.cy.js
Normal file
20
Frontend copy/Frontend copy/cypress/e2e/belepes.cy.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
describe('Felhasználó login teszt', () => {
|
||||||
|
beforeEach('',()=>{
|
||||||
|
cy.visit('http://localhost:5173')
|
||||||
|
cy.wait(3000)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Felhasználó belépésének tesztje',()=>{
|
||||||
|
cy.get('#root > div > div.flex.p-2.justify-between.items-center.border-b.border-gray-300.flex-wrap > div.flex.items-center.gap-6 > a:nth-child(2)').should('have.text','Belépés').click()
|
||||||
|
cy.wait(3000)
|
||||||
|
cy.get('#email').type('vassgeza@gmail.com')
|
||||||
|
cy.get('#password').type('VAssgeza')
|
||||||
|
cy.get('#root > div > div:nth-child(2) > div > div > div:nth-child(5) > button').should('have.text','Bejelentkezés').click()
|
||||||
|
cy.wait(3000)
|
||||||
|
cy.get('#root > div > div.p-40.flex.justify-center > div > a:nth-child(1) > button').should('contains.text','Könyvek adminisztrálás').click()
|
||||||
|
cy.wait(3000)
|
||||||
|
cy.get('#root > div > div.flex.p-2.justify-between.items-center.border-b.border-gray-300.flex-wrap > div.flex.items-center.gap-6 > a:nth-child(4)').should('contains.text','Kilépés').click()
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
14
Frontend copy/Frontend copy/cypress/e2e/fooldal.cy.js
Normal file
14
Frontend copy/Frontend copy/cypress/e2e/fooldal.cy.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
describe('template spec', () => {
|
||||||
|
beforeEach('',()=>{cy.visit('http://localhost:5173')})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
it('Belépés lehetőség megtalálható a menüben', () => {
|
||||||
|
cy.get('#root > div > div.flex.p-2.justify-between.items-center.border-b.border-gray-300.flex-wrap > div.flex.items-center.gap-6 > a:nth-child(2)').should('have.text','Belépés')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Bal oldali könyvkategóriában megjelenik az "Életrajzok, visszaemlékezések" kategória', () => {
|
||||||
|
cy.get('#root > div > div:nth-child(2) > div.flex > div.w-1\\/4.bg-gray-200.h-screen.bg-transparent > div > div.sm\\:first\\:col-span-2.py-14.px-11.rounded-lg.max-w-lg > ul > li:nth-child(3)').should('have.text','Életrajzok, visszaemlékezések')
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "Using fixtures to represent data",
|
||||||
|
"email": "hello@cypress.io",
|
||||||
|
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||||
|
}
|
25
Frontend copy/Frontend copy/cypress/support/commands.js
Normal file
25
Frontend copy/Frontend copy/cypress/support/commands.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// ***********************************************
|
||||||
|
// This example commands.js shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
20
Frontend copy/Frontend copy/cypress/support/e2e.js
Normal file
20
Frontend copy/Frontend copy/cypress/support/e2e.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// ***********************************************************
|
||||||
|
// This example support/e2e.js is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import './commands'
|
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
13
Frontend copy/Frontend copy/index.html
Normal file
13
Frontend copy/Frontend copy/index.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + React</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
6988
Frontend copy/Frontend copy/package-lock.json
generated
Normal file
6988
Frontend copy/Frontend copy/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
37
Frontend copy/Frontend copy/package.json
Normal file
37
Frontend copy/Frontend copy/package.json
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"name": "vite-react-app",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^6.5.2",
|
||||||
|
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||||
|
"daisyui": "^3.9.3",
|
||||||
|
"emailjs-com": "^3.2.0",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-router-dom": "^6.22.3",
|
||||||
|
"react-toastify": "^10.0.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "^18.2.15",
|
||||||
|
"@types/react-dom": "^18.2.7",
|
||||||
|
"@vitejs/plugin-react": "^4.0.3",
|
||||||
|
"autoprefixer": "^10.4.16",
|
||||||
|
"cypress": "^13.8.1",
|
||||||
|
"eslint": "^8.45.0",
|
||||||
|
"eslint-plugin-react": "^7.32.2",
|
||||||
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.3",
|
||||||
|
"postcss": "^8.4.31",
|
||||||
|
"tailwindcss": "^3.3.3",
|
||||||
|
"vite": "^4.4.5"
|
||||||
|
}
|
||||||
|
}
|
6
Frontend copy/Frontend copy/postcss.config.js
Normal file
6
Frontend copy/Frontend copy/postcss.config.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export default {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
1
Frontend copy/Frontend copy/public/vite.svg
Normal file
1
Frontend copy/Frontend copy/public/vite.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
38
Frontend copy/Frontend copy/src/App.css
Normal file
38
Frontend copy/Frontend copy/src/App.css
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
.message-box {
|
||||||
|
width:300px;
|
||||||
|
height:300px;
|
||||||
|
background-color:rgba(255,255,255,0.8);
|
||||||
|
border:1px solid #dddddd;
|
||||||
|
position:fixed;
|
||||||
|
left:0;
|
||||||
|
right:0;
|
||||||
|
top:0;
|
||||||
|
bottom:0;
|
||||||
|
box-shadow: 0px 0px 4px #343434;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-box-header {
|
||||||
|
background-color:#495f76;
|
||||||
|
height:30px;
|
||||||
|
cursor:pointer;
|
||||||
|
text-align: right;
|
||||||
|
color:white;
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-box-body {
|
||||||
|
height:200px;
|
||||||
|
display:grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
padding:10px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-box-buttons {
|
||||||
|
display:flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
77
Frontend copy/Frontend copy/src/App.jsx
Normal file
77
Frontend copy/Frontend copy/src/App.jsx
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
import { BrowserRouter, Routes, Route, Navigate, useParams } from "react-router-dom"
|
||||||
|
import { useState } from 'react'
|
||||||
|
import MainLayout from "./components/MainLayout"
|
||||||
|
import Navbar from "./components/Navbar"
|
||||||
|
import { ToastContainer, toast } from 'react-toastify';
|
||||||
|
import { library } from '@fortawesome/fontawesome-svg-core';
|
||||||
|
import { faBan, faCircleCheck, faCircleXmark, faPaperPlane, faPlus, faRightToBracket, faSquareCheck,
|
||||||
|
faTrash, faUpRightFromSquare, faUserPlus }
|
||||||
|
from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
|
import Main from "./components/Main"
|
||||||
|
import Login from "./components/Login"
|
||||||
|
import Registration from "./components/Registration"
|
||||||
|
import LeftSideBar from "./components/LeftSideBar"
|
||||||
|
import BookMain from "./components/BookMain"
|
||||||
|
import DetailedBook from "./components/DetailedBook"
|
||||||
|
import SupervisorAdmin from "./components/SupervisorAdmin"
|
||||||
|
import UserList from "./components/UserList"
|
||||||
|
import BookList from "./components/BookList"
|
||||||
|
import BookFormModify from "./components/BookFormModify"
|
||||||
|
import Cart from "./components/Cart"
|
||||||
|
import Checkout from "./components/Checkout"
|
||||||
|
import ForgottenPassword from "./components/ForgottenPassword"
|
||||||
|
import PasswordModify from "./components/PasswordModify"
|
||||||
|
import AccountUser from "./components/AccountUser"
|
||||||
|
import BorrowList from "./components/BorrowList"
|
||||||
|
library.add(
|
||||||
|
faRightToBracket, faUserPlus,
|
||||||
|
faTrash, faUpRightFromSquare,
|
||||||
|
faPlus, faSquareCheck,
|
||||||
|
faCircleXmark, faPaperPlane,
|
||||||
|
faCircleCheck,
|
||||||
|
faBan
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<BrowserRouter>
|
||||||
|
<Navbar />
|
||||||
|
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<Main />} />
|
||||||
|
<Route path="/belepes" element={<Login />} />
|
||||||
|
<Route path="/checkout" element={<Checkout />} />
|
||||||
|
<Route path="/newbook" element={<BookFormModify />} />
|
||||||
|
<Route path="/editbook/:BookID" element={<BookFormModify />} />
|
||||||
|
<Route path="/regisztracio" element={<Registration />} />
|
||||||
|
<Route path="/:BookID" element={<DetailedBook />} />
|
||||||
|
<Route path="/supervisor-admin" element={<SupervisorAdmin />} />
|
||||||
|
<Route path="/supervisor-admin/konyv-admin" element={<BookList />} />
|
||||||
|
<Route path="/supervisor-admin/felhasznalo-admin" element={<UserList />} />
|
||||||
|
<Route path="/cart" element={<Cart />} />
|
||||||
|
<Route path="/kategoria/:categoryID" element={<Main />} />
|
||||||
|
<Route path="/felhasznalofiok" element={<Main />} />
|
||||||
|
<Route path="/adataim/:UserID" element={<AccountUser/>} />
|
||||||
|
<Route path="/elfelejtettjelszo" element={<ForgottenPassword />} />
|
||||||
|
<Route path="/rendelesek-kezelese" element={<BorrowList />} />
|
||||||
|
<Route path="/jelszomodositas" element={<PasswordModify />} />
|
||||||
|
<Route path="*" element={<Navigate to={"/"} />} />
|
||||||
|
|
||||||
|
</Routes>
|
||||||
|
|
||||||
|
</BrowserRouter>
|
||||||
|
<ToastContainer />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App
|
1
Frontend copy/Frontend copy/src/assets/react.svg
Normal file
1
Frontend copy/Frontend copy/src/assets/react.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
After Width: | Height: | Size: 4.0 KiB |
40
Frontend copy/Frontend copy/src/components/AccountUser.jsx
Normal file
40
Frontend copy/Frontend copy/src/components/AccountUser.jsx
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { useParams } from 'react-router-dom'
|
||||||
|
import User from './User';
|
||||||
|
|
||||||
|
function AccountUser() {
|
||||||
|
const [user,setUser] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch('http://localhost:3001/user',{credentials: 'include'})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => setUser(data))
|
||||||
|
.catch(err => {
|
||||||
|
console.error("Hiba történt a felhasználó lekérésekor:", err); // Hiba kezelése
|
||||||
|
});
|
||||||
|
}, []); // Függőségek, hogy az useEffect csak a UserID változásakor fusson le újra
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex justify-center p-12'>
|
||||||
|
<div
|
||||||
|
class="p-4 group hover:saturate-100 saturate-0 transition-[filter] relative w-[248px] h-[318px] bg-[#FAEDE4] font-['Robot_Flex'] border-b-2 border-b-[#F04E29]">
|
||||||
|
|
||||||
|
<img
|
||||||
|
class="group-hover:rounded-br-[100px] rounded-br-[0px] transition-[border-radius] "
|
||||||
|
src="https://data.artofproblemsolving.com/images/people/rlemon309x309.png" />
|
||||||
|
<p class="m-[5px] text-[#262626] text-base">{user.Name}</p>
|
||||||
|
<p class="m-[5px] text-[#777674] text-xs">{user.Email}</p>
|
||||||
|
<p class="m-[5px] text-[#777674] text-xs">{user.ZIP} {user.City} {user.Address}</p>
|
||||||
|
|
||||||
|
{/*<!-- SVG of Arrow -->*/}
|
||||||
|
<svg
|
||||||
|
class="group-hover:opacity-100 opacity-0 transition-opacity absolute right-[10px] bottom-[10px]"
|
||||||
|
xmlns="http://www.w3.org/2000/svg" width="45" height="64" viewBox="0 0 45 64" fill="none">
|
||||||
|
<path d="M5.67927 0.685928C5.66838 0.658706 5.65749 0.636925 5.65749 0.636925L3.81168 1.12696C5.55403 11.7281 0.588324 15.4905 0.375974 15.6484L1.49217 17.2056C1.69363 17.0641 5.49414 14.2654 6.03318 7.14353C9.0333 14.2545 13.0244 20.1731 17.1298 24.774C17.059 24.8774 16.9882 24.9754 16.9229 25.0789C14.3311 29.0645 14.0861 34.651 16.1933 41.6912C18.6271 49.8203 24.5239 57.748 32.3754 63.4434L33.5025 61.8916C25.9886 56.4358 20.3477 48.8729 18.0336 41.1358C16.1388 34.8089 16.2913 29.6526 18.4692 26.2114C21.7035 29.5927 24.9432 32.1518 27.7636 33.8288C33.8945 37.4659 38.2232 36.377 40.2541 35.4078C42.4919 34.3406 44.1254 32.375 44.414 30.4094C44.4575 30.1099 44.4793 29.805 44.4793 29.5001C44.4793 27.5509 43.5864 25.5853 41.9039 23.8756C38.4628 20.3691 32.713 18.7465 26.5276 19.5306C23.1518 19.9607 20.3695 21.2457 18.3603 23.2821C14.4455 18.8554 10.645 13.1655 7.77554 6.34314C9.95348 8.22706 13.2476 10.2199 18.1425 11.5266L18.638 9.67539C9.24565 7.16531 6.28364 1.94369 5.75005 0.838382C5.73371 0.783935 5.71193 0.729488 5.6956 0.669594L5.67382 0.669594L5.67927 0.685928ZM26.7672 21.4308C33.3555 20.5923 38.2014 22.8411 40.5372 25.215C42.0509 26.7559 42.7533 28.5037 42.5192 30.1317C42.3558 31.2425 41.3431 32.767 39.4319 33.6763C37.744 34.4822 34.1069 35.3642 28.7437 32.179C25.9886 30.5455 22.8197 28.03 19.6617 24.6923C21.7797 22.5035 24.6056 21.6976 26.7726 21.4254L26.7672 21.4308Z" fill="#F04E29"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AccountUser
|
33
Frontend copy/Frontend copy/src/components/Book.jsx
Normal file
33
Frontend copy/Frontend copy/src/components/Book.jsx
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
function Book({ book }) {
|
||||||
|
// Biztonságosan destrukturáljuk a szükséges könyv tulajdonságokat
|
||||||
|
const { BookID, book_url, title, author, price } = book;
|
||||||
|
{/*console.log(`BookID innen book: ${BookID}`);*/}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-32 max-w-[450px] dark:bg-gray-900 dark:text-gray-100 border dark:border-0 mx-auto relative rounded-md hover:shadow-xl cursor-pointer duration-200">
|
||||||
|
<div className="overflow-hidden p-2 rounded-md">
|
||||||
|
{/* Dinamikus alt szöveg a jobb akadálymentesség érdekében */}
|
||||||
|
<img alt={`A(z) '${title}' című könyv borítója`} loading="lazy" className="book-image" src={book_url} />
|
||||||
|
</div>
|
||||||
|
<div className="justify-center px-10 py-4">
|
||||||
|
<h3 className="text-lg font-bold text-center">{title}</h3>
|
||||||
|
<div className="border-b-2 my-1"></div>
|
||||||
|
<h1 className="text-base text-center">Szerző: {author}</h1>
|
||||||
|
<p className="text-center text-xs flex justify-center gap-2 my-2">
|
||||||
|
<h3 className="text-lg text-center">{price} Ft</h3>
|
||||||
|
{/*<span>{book.discounted_price}</span>*/}
|
||||||
|
</p>
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<Link to={`/${BookID}`} className="flex justify-center w-full bg-teal-600 dark:bg-gray-600 text-white py-2 px-20 rounded-full font-bold hover:bg-gray-800 dark:hover:bg-gray-700">
|
||||||
|
Megnézem
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Book;
|
72
Frontend copy/Frontend copy/src/components/BookAdmin.jsx
Normal file
72
Frontend copy/Frontend copy/src/components/BookAdmin.jsx
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
|
|
||||||
|
function BookAdmin(props) {
|
||||||
|
|
||||||
|
const torles = (BookID) => {
|
||||||
|
fetch(`http://localhost:3001/books/${BookID}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: { "Content-type": "application/json" },
|
||||||
|
credentials: 'include',
|
||||||
|
})
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(res => {
|
||||||
|
toast.success(res); // Sikeres törlés üzenet
|
||||||
|
props.onDelete();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
toast.error("Hiba történt a törlés során."); // Hiba üzenet
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div className="flex-shrink-0 h-10 w-10">
|
||||||
|
<img className="h-15 w-15" src={props.book.book_url} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="ml-4">
|
||||||
|
<div className="text-sm font-medium text-gray-900">
|
||||||
|
{props.book.title}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-500">
|
||||||
|
{props.book.number_of_pages} oldal
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="text-sm text-gray-900">{props.book.author}</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||||
|
<Link to={`/editbook/${props.book.BookID}`} className="text-indigo-600 hover:text-indigo-900">Szerkeszt</Link>
|
||||||
|
<a onClick={() => document.getElementById(`torol${props.book.BookID}`).showModal()} className="ml-2 text-red-600 hover:text-red-900">Töröl</a>
|
||||||
|
</td>
|
||||||
|
<dialog id={`torol${props.book.BookID}`} className="modal">
|
||||||
|
<div className="modal-box">
|
||||||
|
<h3 className="font-bold text-lg">Törlés</h3>
|
||||||
|
<p className="py-4">
|
||||||
|
Biztosan törli {props.book.title} című könyv adatait?
|
||||||
|
</p>
|
||||||
|
<div className="modal-action">
|
||||||
|
<form method="dialog">
|
||||||
|
<button onClick={() => torles(props.book.BookID)} className="btn">Ok</button>
|
||||||
|
<button className="btn">Mégsem</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BookAdmin
|
264
Frontend copy/Frontend copy/src/components/BookFormModify.jsx
Normal file
264
Frontend copy/Frontend copy/src/components/BookFormModify.jsx
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { useParams, useNavigate, useLocation } from 'react-router-dom';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
|
|
||||||
|
function BookFormModify() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { BookID } = useParams();
|
||||||
|
|
||||||
|
|
||||||
|
let formObj = {
|
||||||
|
title: "",
|
||||||
|
author: "",
|
||||||
|
publisher: "",
|
||||||
|
categoryID: "",
|
||||||
|
the_year_of_publishing: "",
|
||||||
|
description: "",
|
||||||
|
language: "",
|
||||||
|
number_of_pages: "",
|
||||||
|
cover: "",
|
||||||
|
weight: "",
|
||||||
|
ISBN: "",
|
||||||
|
itemcode: "",
|
||||||
|
price: "",
|
||||||
|
discounted_price: "",
|
||||||
|
book_url: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
const [formData, setFormData] = useState(formObj);
|
||||||
|
|
||||||
|
const categories = [
|
||||||
|
{ "categoryID": 1, "category": "Család és szülők" },
|
||||||
|
{ "categoryID": 2, "category": "Életmód, egészség" },
|
||||||
|
{ "categoryID": 3, "category": "Életrajzok, visszaemlékezések" },
|
||||||
|
{ "categoryID": 4, "category": "Ezotéria" },
|
||||||
|
{ "categoryID": 5, "category": "Gasztronómia" },
|
||||||
|
{ "categoryID": 6, "category": "Gyermek és ifjúsági" },
|
||||||
|
{ "categoryID": 7, "category": "Hangoskönyv" },
|
||||||
|
{ "categoryID": 8, "category": "Hobbi, szabadidő" },
|
||||||
|
{ "categoryID": 9, "category": "Irodalom" },
|
||||||
|
{ "categoryID": 10, "category": "Képregény" },
|
||||||
|
{ "categoryID": 11, "category": "Kert, ház, otthon" },
|
||||||
|
{ "categoryID": 12, "category": "Lexikon, enciklopédia" },
|
||||||
|
{ "categoryID": 13, "category": "Művészet, építészet" },
|
||||||
|
{ "categoryID": 14, "category": "Napjaink, bulvár, politika" },
|
||||||
|
{ "categoryID": 15, "category": "Nyelvkönyv, szótár" },
|
||||||
|
{ "categoryID": 16, "category": "Pénz, gazdaság, üzleti élet" },
|
||||||
|
{ "categoryID": 17, "category": "Sport, természetjárás" },
|
||||||
|
{ "categoryID": 18, "category": "Számítástechnika, internet" },
|
||||||
|
{ "categoryID": 19, "category": "Tankönyvek, segédkönyvek" },
|
||||||
|
{ "categoryID": 20, "category": "Társadalomtudományok" }
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (BookID) {
|
||||||
|
fetch(`http://localhost:3001/books/${BookID}`, {
|
||||||
|
credentials: 'include'
|
||||||
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
setFormData(data);
|
||||||
|
})
|
||||||
|
.catch(err => console.error("Error loading the book data:", err));
|
||||||
|
}
|
||||||
|
}, [BookID]);
|
||||||
|
|
||||||
|
const handleInputChange = (event) => {
|
||||||
|
const { id, value } = event.target;
|
||||||
|
setFormData(prevState => ({
|
||||||
|
...prevState,
|
||||||
|
[id]: value
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const writeData = (event) => {
|
||||||
|
const { id, value } = event.target;
|
||||||
|
setFormData(prevState => ({
|
||||||
|
...prevState,
|
||||||
|
[id]: value
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleCategoryChange = (event) => {
|
||||||
|
const categoryID = event.target.value;
|
||||||
|
setFormData(prevState => ({
|
||||||
|
...prevState,
|
||||||
|
categoryID
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = async (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
console.log(BookID);
|
||||||
|
console.log(formData);
|
||||||
|
const method = BookID ? 'PUT' : 'POST';
|
||||||
|
try {
|
||||||
|
const response = await fetch(`http://localhost:3001/books/${BookID ? BookID : ''}`, {
|
||||||
|
method: method,
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(formData),
|
||||||
|
credentials: 'include'
|
||||||
|
});
|
||||||
|
const json = await response.json();
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
toast.success("Sikeres módosítás!"); // Sikeres művelet üzenet
|
||||||
|
navigate("/supervisor-admin/konyv-admin");
|
||||||
|
} else {
|
||||||
|
throw new Error(json.error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Hibás beküldés:', error);
|
||||||
|
toast.error(error.message); // Hiba üzenet
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center p-12">
|
||||||
|
<div className="mx-auto w-full max-w-4xl bg-white p-8">
|
||||||
|
<h2 className="text-2xl font-bold text-center mb-10">{BookID ? "Könyv módosítása" : "Új könyv felvitele"}</h2>
|
||||||
|
<form onSubmit={onSubmit} className="grid grid-cols-2 gap-6">
|
||||||
|
<div className="mb-2 col-span-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">A könyv címe</label>
|
||||||
|
<input type="text" id="title" placeholder="Könyv címe"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.title}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Szerző</label>
|
||||||
|
<input type="text" id="author" placeholder="Szerző neve"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.author}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Kiadó neve</label>
|
||||||
|
<input type="text" id="publisher" placeholder="Kiadó neve"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.publisher}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="col-span-2 mb-4">
|
||||||
|
<label className="block text-sm font-medium text-gray-700">Kategória</label>
|
||||||
|
<select id="categoryID" value={formData.categoryID} onChange={handleCategoryChange} className="block w-full px-3 py-2 mt-1 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
||||||
|
<option value="">Válassz egy kategóriát</option>
|
||||||
|
{categories.map((category) => (
|
||||||
|
<option key={category.categoryID} value={category.categoryID}>{category.category}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Kiadás éve</label>
|
||||||
|
<input type="text" id="the_year_of_publishing" placeholder="Kiadás éve"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.the_year_of_publishing}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Nyelv</label>
|
||||||
|
<input type="text" id="language" placeholder="Nyelv"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.language}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2 col-span-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Részletes leírás</label>
|
||||||
|
<textarea
|
||||||
|
id="description"
|
||||||
|
placeholder="Részletes leírás"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.description}
|
||||||
|
className="w-full h-40 rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md resize-none overflow-auto"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Lapok száma</label>
|
||||||
|
<input type="text" id="number_of_pages" placeholder="Lapok száma"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.number_of_pages}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Borító</label>
|
||||||
|
<input type="text" id="cover" placeholder="Borító"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.cover}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Súly</label>
|
||||||
|
<input type="text" id="weight" placeholder="A könyv súlya grammban"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.weight}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">ISBN</label>
|
||||||
|
<input type="text" id="ISBN" placeholder="ISBN szám"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.ISBN}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Kölcsönzési díja</label>
|
||||||
|
<input type="text" id="price" placeholder="Kölcsönzés díja forintban"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.price}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Kölcsönzés kedvezményes díja</label>
|
||||||
|
<input type="text" id="discounted_price" placeholder="Kölcsönzés díja forintban, nem kötelező"
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.discounted_price}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Könyv borítója</label>
|
||||||
|
<input type="text" id="book_url" placeholder="Könyv képének linkje"
|
||||||
|
required
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.book_url}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label className="block mb-2 text-base font-semibold text-[#07074D]">Itemcode</label>
|
||||||
|
<input type="text" id="itemcode" placeholder="Könyv egyedi azonosítója"
|
||||||
|
onChange={writeData}
|
||||||
|
value={formData.itemcode}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2 col-span-2">
|
||||||
|
<button type="submit"
|
||||||
|
className="w-full rounded-md bg-teal-500 py-3 px-8 text-center text-base font-semibold text-white outline-none hover:shadow-form">
|
||||||
|
{BookID ? "Könyv módosítása" : "Új könyv mentése"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BookFormModify
|
115
Frontend copy/Frontend copy/src/components/BookList.jsx
Normal file
115
Frontend copy/Frontend copy/src/components/BookList.jsx
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import BookAdmin from './BookAdmin';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
function BookList() {
|
||||||
|
const [books, setBooks] = useState([]); // Hozzáadva a books állapot és a setBooks állapot-beállító függvény
|
||||||
|
const [letter, setLetter] = useState("");
|
||||||
|
|
||||||
|
|
||||||
|
const inputLetterChange = (e) => {
|
||||||
|
const input = e.target.value;
|
||||||
|
setLetter(input.slice(0, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
fetch(`http://localhost:3001/books/search/${letter}`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => setBooks(data))
|
||||||
|
.catch(err => console.log(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch("http://localhost:3001/books/")
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
setBooks(data); // Feltehetőleg itt a 'books' az adatok tömbje
|
||||||
|
})
|
||||||
|
.catch(err => console.log(err));
|
||||||
|
}, [letter]);
|
||||||
|
|
||||||
|
const handlecClick2 = () => {
|
||||||
|
setLetter("");
|
||||||
|
}
|
||||||
|
|
||||||
|
const refreshBooks = () => {
|
||||||
|
fetch("http://localhost:3001/books/")
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
setBooks(data); // Feltehetőleg itt a 'books' az adatok tömbje
|
||||||
|
})
|
||||||
|
.catch(err => console.log(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
refreshBooks();
|
||||||
|
},[])
|
||||||
|
|
||||||
|
|
||||||
|
console.log(books)
|
||||||
|
console.log(letter)
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2 className='text-3xl flex justify-center p-12'>Kölcsönözhető könyvek listája</h2>
|
||||||
|
|
||||||
|
<div class="relative w-full max-w-xl mx-auto bg-white rounded-full">
|
||||||
|
<input placeholder="könyv címe, vagy szerző alapján,majd kitaláljuk" class="rounded-full w-full h-16 bg-transparent py-2 pl-8 pr-32 outline-none border-2 border-gray-100 shadow-md hover:outline-none focus:ring-teal-200 focus:border-teal-200" type="text" name="query" id="query" value={letter} onChange={inputLetterChange} />
|
||||||
|
<button type="submit" onClick={handleClick} class="absolute inline-flex items-center h-10 px-4 py-2 text-sm text-white transition duration-150 ease-in-out rounded-full outline-none right-3 top-3 bg-teal-600 sm:px-6 sm:text-base sm:font-medium hover:bg-teal-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-500">
|
||||||
|
<svg class="-ml-0.5 sm:-ml-1 mr-2 w-4 h-4 sm:h-5 sm:w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
||||||
|
</svg>
|
||||||
|
Keresés
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col sm:flex-row items-center justify-center p-4 space-x-4"'>
|
||||||
|
<div className="flex flex-col w-full sm:w-auto sm:flex-row p-4">
|
||||||
|
<Link to={"/newbook"}>
|
||||||
|
<button className="flex flex-row items-center justify-center w-full px-4 py-4 mb-4 text-sm font-bold bg-teal-500 leading-6 capitalize duration-100 transform rounded-sm shadow cursor-pointer focus:ring-4 focus:ring-green-500 focus:ring-opacity-50 focus:outline-none sm:mb-0 sm:w-auto sm:mr-4 md:pl-8 md:pr-6 xl:pl-12 xl:pr-10 hover:shadow-lg hover:-translate-y-1">
|
||||||
|
Új könyv felvitele
|
||||||
|
<span className="ml-4">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 24 24" className="w-5 h-5 fill-current"><path fill="currentColor" d="M17.92,11.62a1,1,0,0,0-.21-.33l-5-5a1,1,0,0,0-1.42,1.42L14.59,11H7a1,1,0,0,0,0,2h7.59l-3.3,3.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l5-5a1,1,0,0,0,.21-.33A1,1,0,0,0,17.92,11.62Z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<div className="flex flex-col w-full sm:w-auto sm:flex-row p-4">
|
||||||
|
<button onClick={handlecClick2} className="flex flex-row items-center justify-center w-full px-4 py-1 mb-4 text-sm font-bold bg-red-300 leading-6 capitalize duration-100 transform rounded-sm shadow cursor-pointer hover:shadow-lg hover:-translate-y-1">
|
||||||
|
Keresés törlése
|
||||||
|
<span className="ml-4">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 24 24" className="w-5 h-5 fill-current"><path fill="currentColor" d="M17.92,11.62a1,1,0,0,0-.21-.33l-5-5a1,1,0,0,0-1.42,1.42L14.59,11H7a1,1,0,0,0,0,2h7.59l-3.3,3.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l5-5a1,1,0,0,0,.21-.33A1,1,0,0,0,17.92,11.62Z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<table className="min-w-full divide-y divide-gray-200 overflow-x-auto">
|
||||||
|
<thead className="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Könyv címe
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Szerző
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Művelet
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="bg-white divide-y divide-gray-200">
|
||||||
|
{books.map((book) => (
|
||||||
|
<BookAdmin key={book.id} book={book} onDelete={refreshBooks} /> // 'book' objektum átadása helyesen
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BookList;
|
33
Frontend copy/Frontend copy/src/components/BookMain.jsx
Normal file
33
Frontend copy/Frontend copy/src/components/BookMain.jsx
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Book from "./Book";
|
||||||
|
import { useParams, useNavigate } from "react-router-dom";
|
||||||
|
import '../../style.css';
|
||||||
|
|
||||||
|
function BookMain() {
|
||||||
|
const [books, setBooks] = useState([]);
|
||||||
|
const { categoryID } = useParams();
|
||||||
|
{/*console.log(`BookMain category = ${categoryID}`);*/}
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Dinamikus URL kialakítása a categoryID alapján
|
||||||
|
const url = categoryID ? `http://localhost:3001/books/category/${categoryID}` : "http://localhost:3001/books";//
|
||||||
|
//const url= "http://localhost:3001/books";
|
||||||
|
fetch(url)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
setBooks(data);
|
||||||
|
})
|
||||||
|
.catch(err => console.log(err));
|
||||||
|
}, [categoryID]); // A useEffect most már a categoryID változásaira reagál
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5 mt-1 custom-padding">
|
||||||
|
{books.map((book, i) => (
|
||||||
|
<Book key={i} book={book} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BookMain;
|
132
Frontend copy/Frontend copy/src/components/Borrow.jsx
Normal file
132
Frontend copy/Frontend copy/src/components/Borrow.jsx
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
|
|
||||||
|
function Borrow(props) {
|
||||||
|
|
||||||
|
let formObj = {
|
||||||
|
bringedBack: "1"}
|
||||||
|
|
||||||
|
const [formData, setFormData] = useState(formObj);
|
||||||
|
|
||||||
|
const torles = (cartID) => {
|
||||||
|
fetch(`http://localhost:3001/admin/borrows/cart/${cartID}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: { "Content-type": "application/json" },
|
||||||
|
credentials: 'include',
|
||||||
|
})
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(res => {
|
||||||
|
toast.success(res); // Sikeres törlés üzenet
|
||||||
|
props.update();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
toast.error("Hiba történt a törlés során."); // Hiba üzenet
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const lezaras = (cartID) => {
|
||||||
|
setFormData(formObj);
|
||||||
|
fetch(`http://localhost:3001/admin/borrows/cart/${cartID}`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-type": "application/json" },
|
||||||
|
body: JSON.stringify(formData),
|
||||||
|
credentials: 'include',
|
||||||
|
})
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(res => {
|
||||||
|
toast.success(res); // Sikeres lezárás üzenet
|
||||||
|
props.update();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
toast.error("Hiba történt a lezárás során."); // Hiba üzenet
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div className="ml-4">
|
||||||
|
<div className="text-sm font-medium text-gray-900">
|
||||||
|
{props.borrow.cartID}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-500">
|
||||||
|
{props.borrow.start_of_borrowment}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="text-sm text-gray-900"> {props.borrow.Name}</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="text-sm text-gray-900"> {props.borrow.title}</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="text-sm text-gray-900"> {props.borrow.end_of_borrowment} </div>
|
||||||
|
</td>
|
||||||
|
{props.borrow.bringedBack === 0 && (
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="text-sm text-gray-900">Kölcsönözve</div>
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
{props.borrow.bringedBack === 1 && (
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="text-sm text-gray-900">Visszahozva, lezárt</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
)}
|
||||||
|
{props.borrow.bringedBack === 0 &&
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<button onClick={() => document.getElementById(`vissza${props.borrow.cartID}`).showModal()} className='bg-teal-300 p-4'> Lezárás </button>
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
{props.borrow.bringedBack === 1 &&
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||||
|
<a onClick={() => document.getElementById(`torol${props.borrow.cartID}`).showModal()} className="ml-2 text-red-600 hover:text-red-900">Töröl</a>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<dialog id={`torol${props.borrow.cartID}`} className="modal">
|
||||||
|
<div className="modal-box">
|
||||||
|
<h3 className="font-bold text-lg">Törlés</h3>
|
||||||
|
<p className="py-4">
|
||||||
|
Biztosan törli {props.borrow.cartID} azonosítójú kölcsönzést?
|
||||||
|
</p>
|
||||||
|
<div className="modal-action">
|
||||||
|
<form method="dialog">
|
||||||
|
<button onClick={() => torles(props.borrow.cartID)} className="btn">Ok</button>
|
||||||
|
<button className="btn">Mégsem</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
<dialog id={`vissza${props.borrow.cartID}`} className="modal">
|
||||||
|
<div className="modal-box">
|
||||||
|
<h3 className="font-bold text-lg">Törlés</h3>
|
||||||
|
<p className="py-4">
|
||||||
|
Biztosan lezárod {props.borrow.cartID} azonosítójú kölcsönzést?
|
||||||
|
</p>
|
||||||
|
<div className="modal-action">
|
||||||
|
<form method="dialog">
|
||||||
|
<button onClick={() => lezaras(props.borrow.cartID)} className="btn">Ok</button>
|
||||||
|
<button className="btn">Mégsem</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Borrow
|
129
Frontend copy/Frontend copy/src/components/BorrowList.jsx
Normal file
129
Frontend copy/Frontend copy/src/components/BorrowList.jsx
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import Borrow from './Borrow';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
function BorrowList() {
|
||||||
|
const [borrows, setBorrows] = useState([]);
|
||||||
|
const [letter, setLetter] = useState("");
|
||||||
|
const [lastCartID, setLastCartID] = useState(null);
|
||||||
|
const [search, setSearch] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadBorrows();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const loadBorrows = () => {
|
||||||
|
fetch("http://localhost:3001/admin/borrowedbooks")
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
setBorrows(data);
|
||||||
|
} else {
|
||||||
|
console.error('Received non-array data:', data);
|
||||||
|
setBorrows([]); // Beállít egy üres tömböt, ha a válasz nem tömb
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
setBorrows([]); // Hiba esetén is üres tömböt állít be
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateBorrows = () => {
|
||||||
|
loadBorrows(); // Frissíti a kölcsönzéseket
|
||||||
|
};
|
||||||
|
|
||||||
|
const inputLetterChange = (e) => {
|
||||||
|
const input = e.target.value;
|
||||||
|
setLetter(input.slice(0, 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
setSearch(true);
|
||||||
|
fetch(`http://localhost:3001/admin/borrows/cart/${letter}`, {
|
||||||
|
credentials: 'include'
|
||||||
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
setBorrows(data);
|
||||||
|
} else {
|
||||||
|
console.error('Received non-array data:', data);
|
||||||
|
setBorrows([]); // Beállít egy üres tömböt, ha a válasz nem tömb
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
setBorrows([]); // Hiba esetén is üres tömböt állít be
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlecClick2 = () => {
|
||||||
|
setLetter("");
|
||||||
|
setLastCartID(null);
|
||||||
|
setSearch(false);
|
||||||
|
updateBorrows();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2 className='text-3xl flex justify-center p-12'>Kölcsönözések listája</h2>
|
||||||
|
<div className="relative w-full max-w-xl mx-auto bg-white rounded-full">
|
||||||
|
<input
|
||||||
|
placeholder="Keresés rendelés azonosítója alapján"
|
||||||
|
className="rounded-full w-full h-16 bg-transparent py-2 pl-8 pr-32 outline-none border-2 border-gray-100 shadow-md hover:outline-none focus:ring-teal-200 focus:border-teal-200"
|
||||||
|
type="text"
|
||||||
|
name="query"
|
||||||
|
id="query"
|
||||||
|
value={letter}
|
||||||
|
onChange={inputLetterChange}
|
||||||
|
/>
|
||||||
|
{ !search &&
|
||||||
|
<button onClick={handleClick} className="absolute inline-flex items-center h-10 px-4 py-2 text-sm text-white transition duration-150 ease-in-out rounded-full outline-none right-3 top-3 bg-teal-600 sm:px-6 sm:text-base sm:font-medium hover:bg-teal-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-500">
|
||||||
|
Keresés
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
{ search &&
|
||||||
|
<button onClick={handlecClick2} className="absolute inline-flex items-center h-10 px-4 py-2 text-sm text-white transition duration-150 ease-in-out rounded-full outline-none right-3 top-3 bg-teal-600 sm:px-6 sm:text-base sm:font-medium hover:bg-teal-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-500">
|
||||||
|
Keresés törlése
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table className="min-w-full divide-y divide-gray-200 overflow-x-auto">
|
||||||
|
<thead className="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Kölcsönzés azonosítója és dátuma
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Kölcsönző neve
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Kölcsönzött könyv címe
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Kölcsönzés lejárati ideje
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Kölcsönzés státusza
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Lezárás
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Kölcsönzés törlése
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="bg-white divide-y divide-gray-200">
|
||||||
|
{Array.isArray(borrows) && borrows.map((borrow) => (
|
||||||
|
<Borrow key={borrow.CartID} borrow={borrow} update={updateBorrows} />
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BorrowList;
|
50
Frontend copy/Frontend copy/src/components/Caroussel.jsx
Normal file
50
Frontend copy/Frontend copy/src/components/Caroussel.jsx
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
function Caroussel() {
|
||||||
|
return (
|
||||||
|
<div className="w-full">
|
||||||
|
<section className="w-full">
|
||||||
|
<div className="py-2 px-0 mx-auto max-w-none">
|
||||||
|
<div className="grid p-8 grid-cols-1 sm:grid-cols-2 md:grid-cols-5 gap-4 h-full">
|
||||||
|
<div className="col-span-2 sm:col-span-1 md:col-span-2 bg-gray-50 h-auto md:h-full flex flex-col">
|
||||||
|
<Link to={'/kategoria/6'} href="" className="group relative flex flex-col overflow-hidden rounded-lg px-4 pb-4 pt-40 flex-grow w-full">
|
||||||
|
<img src="https://arthobby.hu/shop_ordered/27703/pic/ifj1.png" className="absolute inset-0 h-full w-full object-cover group-hover:scale-105 transition-transform duration-500 ease-in-out"/>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-b from-gray-900/25 to-gray-900/5"></div>
|
||||||
|
<h3 className="z-10 text-2xl font-medium text-white absolute top-0 left-0 p-4 xs:text-xl md:text-3xl">Ifjúsági regények</h3>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-2 sm:col-span-1 md:col-span-2 bg-stone-50 w-full">
|
||||||
|
<Link to={'/kategoria/16'} href="#" className="group relative flex flex-col overflow-hidden rounded-lg px-4 pb-4 pt-40 mb-4 w-full">
|
||||||
|
<img src="https://arthobby.hu/shop_ordered/27703/pic/buffet.png" alt="" className="absolute inset-0 h-full w-full object-cover group-hover:scale-105 transition-transform duration-500 ease-in-out"/>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-b from-gray-900/25 to-gray-900/5"></div>
|
||||||
|
<h3 className="z-10 text-2xl font-medium text-white absolute top-0 left-0 p-4 xs:text-xl md:text-3xl">Üzlet, politika</h3>
|
||||||
|
</Link>
|
||||||
|
<div className="grid gap-4 grid-cols-2 sm:grid-cols-2 lg:grid-cols-2">
|
||||||
|
<Link to={'/kategoria/13'} href="#" className="group relative flex flex-col overflow-hidden rounded-lg px-4 pb-4 pt-40 w-full">
|
||||||
|
<img src="https://arthobby.hu/shop_ordered/27703/pic/vangogh.png" alt="" className="absolute inset-0 h-full w-full object-cover group-hover:scale-105 transition-transform duration-500 ease-in-out"/>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-b from-gray-900/25 to-gray-900/5"></div>
|
||||||
|
<h3 className="z-10 text-2xl font-medium text-white absolute top-20 left-0 p-4 xs:text-xl md:text-3xl">Művészet</h3>
|
||||||
|
</Link>
|
||||||
|
<Link to={'/kategoria/11'} href="#" className="group relative flex flex-col overflow-hidden rounded-lg px-4 pb-4 pt-40 w-full">
|
||||||
|
<img src="https://arthobby.hu/shop_ordered/27703/pic/kert.png" alt="" className="absolute inset-0 h-full w-full object-cover group-hover:scale-105 transition-transform duration-500 ease-in-out"/>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-b from-gray-900/25 to-gray-900/5"></div>
|
||||||
|
<h3 className="z-10 text-2xl font-medium text-white absolute top-20 left-0 p-2 xs:text-xl md:text-3xl">Kert, szabadidő</h3>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-2 sm:col-span-1 md:col-span-1 bg-sky-50 h-auto md:h-full flex flex-col w-full">
|
||||||
|
<Link to={'/kategoria/5'} href="#" className="group relative flex flex-col overflow-hidden rounded-lg px-4 pb-4 pt-40 flex-grow w-full">
|
||||||
|
<img src="https://arthobby.hu/shop_ordered/27703/pic/gasztro.png " alt="" className="absolute inset-0 h-full w-full object-cover group-hover:scale-105 transition-transform duration-500 ease-in-out"/>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-b from-gray-900/25 to-gray-900/5"></div>
|
||||||
|
<h3 className="z-10 text-2xl font-medium text-white absolute top-0 left-0 p-4 xs:text-xl md:text-3xl">Gasztronómia </h3>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Caroussel;
|
196
Frontend copy/Frontend copy/src/components/Cart.jsx
Normal file
196
Frontend copy/Frontend copy/src/components/Cart.jsx
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
function Cart() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [total, setTotal] = useState(0);
|
||||||
|
const [totalBooks, setTotalBooks] = useState(0); // Hozzáadott állapot a könyvek összes darabszámának
|
||||||
|
const [totalBooksPrice, setTotalBooksPrice] = useState(0); // Hozzáadott állapot a könyvek összes árának
|
||||||
|
const [carts, setCarts] = useState(JSON.parse(localStorage.getItem('cart')) || []);
|
||||||
|
const [email, setEmail] = useState('');
|
||||||
|
const [UserID, setUserID] = useState('');
|
||||||
|
|
||||||
|
{/*localStorage.setItem('cart', JSON.stringify([]));*/ } //ezzel űrítem a kosarat amíg nincs user-hez kötve;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const total = carts.reduce((acc, item) => {
|
||||||
|
return acc + (item.price * item.quantity);
|
||||||
|
}, 0);
|
||||||
|
setTotal(total);
|
||||||
|
setUserID(localStorage.getItem('UserID') || '');
|
||||||
|
|
||||||
|
}, [carts]); //A kosárban lévő összes könyv árának beállítása
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const totalBooksCount = carts.reduce((acc, item) => {
|
||||||
|
return acc + item.quantity;
|
||||||
|
}, 0);
|
||||||
|
setTotalBooks(totalBooksCount); // A kosárban lévő összes könyv darabszámának beállítása
|
||||||
|
|
||||||
|
}, [carts]);
|
||||||
|
|
||||||
|
/*const handleInc = (BookID) => {
|
||||||
|
const updatedCart = carts.map(item => {
|
||||||
|
if(item.BookID === BookID) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
quantity: item.quantity + 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
setCarts(updatedCart);
|
||||||
|
};*/
|
||||||
|
|
||||||
|
/*const handleDec = (BookID) => {
|
||||||
|
const updatedCart = carts.map(item => {
|
||||||
|
if(item.BookID === BookID) {
|
||||||
|
const newQuantity = Math.max(1, item.quantity - 1);
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
quantity: newQuantity
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
setCarts(updatedCart);
|
||||||
|
};*/
|
||||||
|
|
||||||
|
const removeProduct = (BookID) => {
|
||||||
|
const updatedCart = carts.filter(item => item.BookID !== BookID);
|
||||||
|
setCarts(updatedCart);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleCheckout = () => {
|
||||||
|
const cart = JSON.parse(localStorage.getItem('cart')) || [];
|
||||||
|
const dateKezdo = new Date();
|
||||||
|
const dateVege = new Date(dateKezdo); // Létrehoz egy új Date objektumot a kezdő dátum alapján
|
||||||
|
dateVege.setDate(dateKezdo.getDate() + 30); // Hozzáad 30 napot a kezdő dátumhoz
|
||||||
|
const dateKezdoString = dateKezdo.toISOString().slice(0, 10);//levágom a Date-ből 0tól 10ig marad
|
||||||
|
const dateVegeString = dateVege.toISOString().slice(0, 10);//levágom a Date-ből 0tól 10ig marad
|
||||||
|
|
||||||
|
const cartID = Math.floor(100000 + Math.random() * 900000); // CartID létrehozása
|
||||||
|
const borowsbooks = carts.map(item => ({
|
||||||
|
UserID: UserID,
|
||||||
|
BookID: item.BookID,
|
||||||
|
cartID: cartID,
|
||||||
|
title: item.title,
|
||||||
|
quantity: item.quantity,
|
||||||
|
price: item.price,
|
||||||
|
/* total_price: (item.price * item.quantity).toFixed(2) csak akkor, ha kimomentelt rész vissazkerülne*/
|
||||||
|
start_of_borrowment: dateKezdoString,
|
||||||
|
end_of_borrowment: dateVegeString
|
||||||
|
})); // Könyvek tömb létrehozása és feltöltése
|
||||||
|
|
||||||
|
|
||||||
|
const formObj = {
|
||||||
|
borrowbooks: borowsbooks /* itt az összes könyv ami a kosárba van bekerül a formObj-be */
|
||||||
|
};
|
||||||
|
localStorage.setItem('checkoutData', JSON.stringify(formObj));
|
||||||
|
localStorage.setItem('dateKezdoString', dateKezdoString);
|
||||||
|
localStorage.setItem('dateVegeString', dateVegeString);
|
||||||
|
console.log(formObj)
|
||||||
|
navigate('/checkout');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClearCart = () => {
|
||||||
|
localStorage.removeItem('cart');
|
||||||
|
setCarts([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (carts.length === 0) {
|
||||||
|
return (
|
||||||
|
<div className="container mx-auto mt-10">
|
||||||
|
<h1 className=' h-[55vh] flex justify-center items-center text-4xl'>A kosár üres</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container mx-auto mt-10">
|
||||||
|
<div className="w-3/4 shadow-md my-10 flex-wrap">
|
||||||
|
<div className=" bg-white px-10 py-1">
|
||||||
|
<div className="flex justify-between border-b pb-8">
|
||||||
|
<h1 className="font-semibold text-2xl">Kosár</h1>
|
||||||
|
<button onClick={handleClearCart} className="bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded">Kosár ürítése</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-wrap mt-10 mb-5">
|
||||||
|
<h3 className="font-semibold text-gray-600 text-xs uppercase w-2/5">Product Details</h3>
|
||||||
|
<h3 className="font-semibold text-center text-gray-600 text-xs uppercase w-1/5">Quantity</h3>
|
||||||
|
<h3 className="font-semibold text-center text-gray-600 text-xs uppercase w-1/5">Price</h3>
|
||||||
|
<h3 className="font-semibold text-center text-gray-600 text-xs uppercase w-1/5">Total</h3>
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
carts.map(cart => (
|
||||||
|
<div className="flex items-center hover:bg-gray-100 -mx-8 px-6 py-5" key={cart.BookID}>
|
||||||
|
<div className="flex w-2/5">
|
||||||
|
<div className="w-20">
|
||||||
|
<img className="h-24" src={cart.book_url} alt={cart.title} />
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col justify-between ml-4 flex-grow">
|
||||||
|
<span className="font-bold text-sm">{cart.title}</span>
|
||||||
|
<span className="text-red-500 text-xs capitalize">{cart.author}</span>
|
||||||
|
<div className="font-semibold hover:text-red-500 text-gray-500 text-xs cursor-pointer" onClick={() => removeProduct(cart.BookID)}>Eltávolít</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/*itt lehetne növelni illetve csökkenteni a kosár értékét a ki kommentelt function-okkal*/}
|
||||||
|
{/*<div className="flex justify-center w-1/5">
|
||||||
|
<svg className="fill-current text-gray-600 w-3 cursor-pointer" viewBox="0 0 448 512" onClick={() => handleDec(cart.BookID)}>
|
||||||
|
<path d="M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z" />
|
||||||
|
</svg>
|
||||||
|
<input className="mx-2 border text-center w-8" type="text" value={cart.quantity} readOnly />
|
||||||
|
<svg className="fill-current text-gray-600 w-3 cursor-pointer" onClick={() => handleInc(cart.BookID)} viewBox="0 0 448 512">
|
||||||
|
<path d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z" />
|
||||||
|
</svg>
|
||||||
|
</div>*/}
|
||||||
|
<span className="text-center w-1/5 font-semibold text-sm">1 darab</span>
|
||||||
|
|
||||||
|
<span className="text-center w-1/5 font-semibold text-sm">${cart.price}</span>
|
||||||
|
<span className="text-center w-1/5 font-semibold text-sm">${(cart.price * cart.quantity).toFixed(2)}</span>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
<Link to={'/'} className="flex font-semibold text-gray-900 text-sm mt-10">
|
||||||
|
|
||||||
|
<svg className="fill-current mr-2 text-gray-900 w-4" viewBox="0 0 448 512"><path d="M134.059 296H436c6.627 0 12-5.373 12-12v-56c0-6.627-5.373-12-12-12H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.569 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296z" /></svg>
|
||||||
|
<h2> Vásárlás folytatása</h2>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="summary" className="w-2/4 px-8 py-10 container">
|
||||||
|
<h1 className="font-semibold text-2xl border-b pb-8">Összesítő</h1>
|
||||||
|
<div className="flex flex-wrap justify-between mt-10">
|
||||||
|
<span className="font-semibold text-sm">Összesen {totalBooks} darab könyv</span>
|
||||||
|
<span className="font-semibold text-sm">{total.toFixed(2)} Ft</span>
|
||||||
|
</div>
|
||||||
|
<div className="border-t mt-8">
|
||||||
|
<div className="flex font-semibold justify-between py-6 text-sm">
|
||||||
|
<span>Összesen fizetendő</span>
|
||||||
|
<span>{total.toFixed(2)} Ft</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{ UserID &&
|
||||||
|
<Link
|
||||||
|
to={"/checkout"}
|
||||||
|
onClick={handleCheckout}
|
||||||
|
className="bg-indigo-500 font-semibold hover:bg-indigo-600 py-3 p-2 text-sm text-white uppercase w-full"
|
||||||
|
>
|
||||||
|
tovább a kölcsönzés befejezéséhez
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
|
||||||
|
{ !UserID &&
|
||||||
|
<Link to={"/belepes"}><h6 className='text-pink-600'>Rendelés leadásához kérem jelentkezzen be! </h6></Link>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Cart;
|
112
Frontend copy/Frontend copy/src/components/Checkout.jsx
Normal file
112
Frontend copy/Frontend copy/src/components/Checkout.jsx
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import emailjs from 'emailjs-com';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
function Checkout() {
|
||||||
|
const [formObj, setFormObj] = useState({});
|
||||||
|
const [userEmail, setUserEmail] = useState("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const formObjFromLocalStorage = JSON.parse(localStorage.getItem('checkoutData'));
|
||||||
|
setFormObj(formObjFromLocalStorage);
|
||||||
|
setUserEmail(localStorage.getItem('email'));
|
||||||
|
}, []);
|
||||||
|
console.log(formObj);
|
||||||
|
console.log(userEmail);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleSendEmail = () => {
|
||||||
|
const bookRows = formObj.borrowbooks.map(book => `Kölcsönzött könyv címe: ${book.title}: Mennyisége: ${book.quantity} darab `).join('\n'); // Könyv sorok előkészítése
|
||||||
|
const bookRows1 = formObj.borrowbooks.map(book => `A rendelés azonosítója: ${book.cartID}`).join('\n'); // rendelés azonosító
|
||||||
|
|
||||||
|
const templateParams = {
|
||||||
|
to_email: userEmail, // Címzett email címe
|
||||||
|
from_email: 'infokonykolcsonzo@gmail.com', // Feladó email címe
|
||||||
|
subject: 'Kölcsönzési értesítő', // Az email tárgya
|
||||||
|
cartID: formObj.cartID, // Kosár azonosító
|
||||||
|
bookRows1: bookRows1, // rendelés azonosító
|
||||||
|
bookRows: bookRows, // Könyv sorok
|
||||||
|
DateVege: localStorage.getItem('dateVegeString'),
|
||||||
|
DateKezdo: localStorage.getItem('dateKezdoString'),
|
||||||
|
date: formObj.timestamp // Dátum
|
||||||
|
};
|
||||||
|
emailjs.send('service_mipbx9a', 'template_kdud6eo', templateParams, 't2P0egLC6EXkHDhyE')
|
||||||
|
.then((response) => {
|
||||||
|
console.log('Email sent successfully:', response);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Email sending failed:', error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const emptyLocalStorage = ()=>{
|
||||||
|
localStorage.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendOrderDetails = () => {
|
||||||
|
const orderDetails = {
|
||||||
|
borrowbooks: formObj.borrowbooks.map(book => ({
|
||||||
|
BookID: book.BookID,
|
||||||
|
cartID: book.cartID,
|
||||||
|
end_of_borrowment: book.end_of_borrowment,
|
||||||
|
quantity: book.quantity,
|
||||||
|
start_of_borrowment: book.start_of_borrowment,
|
||||||
|
UserID: book.UserID
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
console.log('Orderdetails ami JSON-be megy:', orderDetails);
|
||||||
|
fetch('http://localhost:3001/borrows', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(orderDetails),
|
||||||
|
credentials: 'include'
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => console.log('Success:', data))
|
||||||
|
.catch(error => console.error('Error:', error));
|
||||||
|
};
|
||||||
|
|
||||||
|
const end_of_order = ()=>{
|
||||||
|
sendOrderDetails();
|
||||||
|
handleSendEmail();
|
||||||
|
emptyLocalStorage();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="flex h-screen items-center justify-center bg-gray-900 p-5">
|
||||||
|
<div class="grid md:grid-cols-2 grid-cols-1 items-center gap-10 md:px-10">
|
||||||
|
<div>
|
||||||
|
<h1 class="mb-2 text-3xl font-bold text-white"><span class="text-green-500">Helló!</span> Köszönjük megrendelésed!</h1>
|
||||||
|
<p class="mb-6 text-white">Köszönjük könyv kölcsönzésedet. Ne felejtsd el, hogy a kölcsönzött könyveket a megadott határidőre hozd vissza. A rendelésed részleteiről email küldtünk regisztrált emailcímedre a kölcsönzésed megerősítése után.</p>
|
||||||
|
<div class="flex justify-center space-x-5">
|
||||||
|
<Link to={"/"} ><button onClick={end_of_order} class="flex w-full items-center justify-center gap-1 rounded-2xl bg-rose-500 p-5 py-3 font-semibold text-white hover:bg-rose-700">
|
||||||
|
Kölcsönzés véglegesítése
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="h-6 w-6">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z" />
|
||||||
|
</svg>
|
||||||
|
</button></Link>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src="https://images.pexels.com/photos/415829/pexels-photo-415829.jpeg?auto=compress&cs=tinysrgb&w=600" alt="" class="md:size-96 size-72 rounded-full " />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Itt jöhetnek a checkout részletei
|
||||||
|
<button onClick={handleSendEmail}>Kölcsönzési értesítő küldése</button>*/}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Checkout;
|
133
Frontend copy/Frontend copy/src/components/DetailedBook.jsx
Normal file
133
Frontend copy/Frontend copy/src/components/DetailedBook.jsx
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { useParams, Link } from 'react-router-dom';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
|
|
||||||
|
function DetailedBook() {
|
||||||
|
const { BookID } = useParams(); // Kinyeri a `bookID` paramétert az URL-ből
|
||||||
|
const [selectedBook, setSelectedBook] = useState({}); // Állapot kezdeti értéke null
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(`http://localhost:3001/books/${BookID}`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => setSelectedBook(data))
|
||||||
|
.catch(err => {
|
||||||
|
console.error("Hiba történt a könyvek lekérésekor:", err); // Hiba kezelése
|
||||||
|
});
|
||||||
|
}, [BookID]); // Függőségek, hogy az useEffect csak a bookID változásakor fusson le újra
|
||||||
|
|
||||||
|
const handleCart = (selectedBook) => {
|
||||||
|
const cart = JSON.parse(localStorage.getItem('cart')) || [];
|
||||||
|
const isProductExist = cart.find(item => item.BookID === selectedBook.BookID);
|
||||||
|
if (!isProductExist) {
|
||||||
|
localStorage.setItem('cart', JSON.stringify([...cart, { ...selectedBook, quantity: 1 }]));
|
||||||
|
toast.success(`${selectedBook.title} című könyv kosárba került `);
|
||||||
|
} else {
|
||||||
|
const isCartEmpty = cart.length === 0;
|
||||||
|
if (isCartEmpty) {
|
||||||
|
localStorage.removeItem('cart'); // Ha a kosár üres, töröljük a localStorage-ból
|
||||||
|
setCarts([]); // És frissítjük az állapotot is
|
||||||
|
}
|
||||||
|
toast.error(`${selectedBook.title} című könyv már szerepel a kosárban`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-transparent dark:bg-gray-800 py-8">
|
||||||
|
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
<div className="flex flex-col md:flex-row -mx-4">
|
||||||
|
<div className="md:flex-1 px-4">
|
||||||
|
{selectedBook ? (
|
||||||
|
<div>
|
||||||
|
<div className="bg-transparent dark:bg-gray-800 py-8">
|
||||||
|
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
<div className="flex flex-col md:flex-row -mx-4">
|
||||||
|
<div className="md:flex-1 px-4">
|
||||||
|
<div className="rounded-lg bg-gray-300 dark:bg-gray-700 mb-4">
|
||||||
|
<img className="w-full" src={selectedBook.book_url} alt="Product Image" />
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<span className="text-2xl font-bold text-gray-700 dark:text-gray-300 py-4">Kölcsönzési díj:</span>
|
||||||
|
<span className="text-2xl text-gray-600 dark:text-gray-300 py-4 px-2">{selectedBook.price} Ft</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<div>
|
||||||
|
<Link to={"/cart"}>
|
||||||
|
<button className="w-full bg-gray-900 dark:bg-gray-600 text-white py-2 px-4 rounded-full font-bold hover:bg-gray-800 dark:hover:bg-gray-700" onClick={() => handleCart(selectedBook)}>Kosárba</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="md:flex-1 px-4">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-800 dark:text-white mb-2">{selectedBook.title}</h2>
|
||||||
|
<h2 className="underline text-2xl font text-gray-800 dark:text-white mb-2">Szerző: {selectedBook.author}</h2>
|
||||||
|
<p className="underline text-gray-600 dark:text-gray-300 text-sm mb-4">
|
||||||
|
{selectedBook.publisher} | {selectedBook.the_year_of_publishing} | {selectedBook.language} nyelvű | {selectedBook.cover} kötésű | {selectedBook.number_of_pages} oldal
|
||||||
|
</p>
|
||||||
|
<div className="flex mb-4">
|
||||||
|
<div className="mr-4">
|
||||||
|
<span className="font-bold text-gray-700 dark:text-gray-300">Kölcsönzési díj:</span>
|
||||||
|
<span className="text-gray-600 dark:text-gray-300">{selectedBook.price} Ft</span>
|
||||||
|
</div>
|
||||||
|
<div className="mr-4">
|
||||||
|
<span className="font-bold text-gray-700 dark:text-gray-300">Státusz:</span>
|
||||||
|
<span className="text-green-600 dark:text-gray-300"> Kölcsönözhető</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-1xl text-justify font-bold text-gray-800 dark:text-white mb-2">
|
||||||
|
{selectedBook.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table className="min-w-full divide-y divide-gray-200">
|
||||||
|
<tbody className="bg-white divide-y divide-gray-200">
|
||||||
|
<tr>
|
||||||
|
<td className="px-2 py-4 whitespace-nowrap">Kiadó</td>
|
||||||
|
<td className="px-20 py-4 whitespace-nowrap">{selectedBook.publisher}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="px-2 py-4 whitespace-nowrap">Kiadás éve:</td>
|
||||||
|
<td className="px-20 py-4 whitespace-nowrap">{selectedBook.the_year_of_publishing}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="px-2 py-4 whitespace-nowrap">Nyelv</td>
|
||||||
|
<td className="px-20 py-4 whitespace-nowrap">{selectedBook.language}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="px-2 py-4 whitespace-nowrap">Borító</td>
|
||||||
|
<td className="px-20 py-4 whitespace-nowrap">{selectedBook.cover}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="px-2 py-4 whitespace-nowrap">Lapok száma</td>
|
||||||
|
<td className="px-20 py-4 whitespace-nowrap">{selectedBook.number_of_pages} oldal</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="px-2 py-4 whitespace-nowrap">ISBN</td>
|
||||||
|
<td className="px-20 py-4 whitespace-nowrap">{selectedBook.ISBN}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="px-2 py-4 whitespace-nowrap">Árukód</td>
|
||||||
|
<td className="px-20 py-4 whitespace-nowrap">{selectedBook.itemcode}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<p>Könyv adatainak betöltése...</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DetailedBook;
|
|
@ -0,0 +1,62 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import emailjs from 'emailjs-com';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
|
|
||||||
|
function ForgottenPassword() {
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
// Email küldési logika, ami megkapja a verificationCode-ot paraméterként
|
||||||
|
const handleSendEmail = (verificationCode) => {
|
||||||
|
const templateParams = {
|
||||||
|
to_email: email,
|
||||||
|
from_email: 'infokonykolcsonzo@gmail.com',
|
||||||
|
subject: 'Ellenőrző kód küldése',
|
||||||
|
ellenorzokod: verificationCode,
|
||||||
|
};
|
||||||
|
|
||||||
|
emailjs.send('service_mipbx9a', 'template_z4cxcwt', templateParams, 't2P0egLC6EXkHDhyE')
|
||||||
|
.then((response) => {
|
||||||
|
console.log('Email sent successfully:', response);
|
||||||
|
toast.success('Sikeres email küldés!')
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Hiba az email küldés során:', error);
|
||||||
|
toast.error(error.message)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const verificationCode = Math.floor(100000 + Math.random() * 900000); // Ellenőrző kód generálása
|
||||||
|
localStorage.setItem("verificationCode", verificationCode);
|
||||||
|
localStorage.setItem("email", email);
|
||||||
|
console.log(`verificationCode: ${verificationCode} email: ${email}`);
|
||||||
|
handleSendEmail(verificationCode); // Az ellenőrző kód átadása a handleSendEmail függvénynek
|
||||||
|
navigate("/jelszomodositas");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="min-h-screen bg-gray-100 flex items-center justify-center">
|
||||||
|
<div class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4 max-w-md w-full">
|
||||||
|
<h1 class="text-center text-2xl font-bold mb-6">Elfelejtett jelszó visszaállítása</h1>
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-gray-700 font-bold mb-2" for="email">
|
||||||
|
Email cím
|
||||||
|
</label>
|
||||||
|
<input class="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="email" type="email" placeholder="regisztrációnál használt email" value={email} required onChange={(e) => setEmail(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full" type="submit">
|
||||||
|
Hitelesítő kód küldése
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ForgottenPassword;
|
11
Frontend copy/Frontend copy/src/components/GetUrlParams.jsx
Normal file
11
Frontend copy/Frontend copy/src/components/GetUrlParams.jsx
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import {useLocation} from "react-router-dom";
|
||||||
|
|
||||||
|
function GetUrlParams(key, defaultVal = null) {
|
||||||
|
const location = useLocation();
|
||||||
|
const params = new URLSearchParams(location.search);
|
||||||
|
const value = params.get(key);
|
||||||
|
|
||||||
|
return value !== null ? value : defaultVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GetUrlParams;
|
53
Frontend copy/Frontend copy/src/components/LeftSideBar.jsx
Normal file
53
Frontend copy/Frontend copy/src/components/LeftSideBar.jsx
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import BookMain from './BookMain'; // Győződj meg róla, hogy a fájlnév és a komponens neve egyezik
|
||||||
|
|
||||||
|
function LeftSideBar() {
|
||||||
|
const [categories, setCategories] = useState([]);
|
||||||
|
const [selectCategory, setSelectCategory] = useState(null);
|
||||||
|
|
||||||
|
const handleCategoryClick = async (categoryID) => {
|
||||||
|
setSelectCategory(categoryID);
|
||||||
|
console.log(`categoryID innen LeftSIdeBar: ${categoryID}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchCategories = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("http://localhost:3001/categories");
|
||||||
|
const data = await response.json();
|
||||||
|
setCategories(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Hiba a kategóriák lekérésekor:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchCategories();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="bg-teal-300 sm:first:col-span-2 py-14 px-11 rounded-lg max-w-lg" style={{marginLeft: '35px' }}>
|
||||||
|
<h3 className="mb-4 text-black text-[14px] sm:text-[22px] font-extrabold leading-none">
|
||||||
|
Könyv kategóriák
|
||||||
|
</h3>
|
||||||
|
<ul className="mt-6 sm:mt-10">
|
||||||
|
{categories.map((category, index) => (
|
||||||
|
<li key={index} className="pt-2 pb-4 mb-2 last:mb-0 border-b border-black border-solid">
|
||||||
|
<Link to={`/kategoria/${category.categoryID}`} className="flex items-center justify-between text-black hover:text-white text-lg sm:text-xl font-medium" onClick={() => handleCategoryClick(category.categoryID)}>
|
||||||
|
<span>{category.category}</span>
|
||||||
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LeftSideBar;
|
129
Frontend copy/Frontend copy/src/components/Login.jsx
Normal file
129
Frontend copy/Frontend copy/src/components/Login.jsx
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import GetUrlParams from './GetUrlParams.jsx';
|
||||||
|
import {Link, useNavigate} from "react-router-dom";
|
||||||
|
import MessageBox from './MessageBox.jsx';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function Login() {
|
||||||
|
|
||||||
|
const regEmail = GetUrlParams("email");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [pass, setPass] = useState("");
|
||||||
|
const [errMessages, setErrMessages] = useState([]);
|
||||||
|
const [displayMb, setDisplayMb] = useState(false);
|
||||||
|
const buttonsMb = [{
|
||||||
|
text:"OK",
|
||||||
|
icon:"fa-solid fa-square-check",
|
||||||
|
cb:()=>setDisplayMb(false)
|
||||||
|
}];
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const signIn = async ()=> {
|
||||||
|
try {
|
||||||
|
const response = await fetch("http://localhost:3001/belepes", {
|
||||||
|
method:"POST",
|
||||||
|
body:JSON.stringify({
|
||||||
|
email:email,
|
||||||
|
pass:pass
|
||||||
|
}),
|
||||||
|
headers:{"Content-type":"application/json"},
|
||||||
|
credentials:"include"
|
||||||
|
});
|
||||||
|
|
||||||
|
const json = await response.json();
|
||||||
|
|
||||||
|
console.log("Válasz a szervertől:", json); // Logold a választ
|
||||||
|
|
||||||
|
if(response.ok) {
|
||||||
|
const isAdmin = json.isAdmin;
|
||||||
|
const email = json.email;
|
||||||
|
const UserID = json.userID;
|
||||||
|
const url = isAdmin ? "/supervisor-admin" : "/"; //Ha nem kell lehet törölni csak gondoltam ha belépett az illető, akkor navigáljuk annak megfelelően admin vagy más felületre
|
||||||
|
localStorage.setItem("isAdmin",isAdmin.toString());
|
||||||
|
localStorage.setItem("email",email);
|
||||||
|
localStorage.setItem("UserID",UserID);
|
||||||
|
navigate(url);
|
||||||
|
if (isAdmin){
|
||||||
|
toast.success('Sikeres belépés Adminisztrátorként')}
|
||||||
|
else
|
||||||
|
toast.success('Sikeres belépés!')
|
||||||
|
console.log("Email: ", localStorage.getItem("email"));
|
||||||
|
console.log("UserID: ", localStorage.getItem("UserID"));
|
||||||
|
console.log("Admin státusz: ", isAdmin); // Boolean logolása
|
||||||
|
} else {
|
||||||
|
console.log(json);
|
||||||
|
setErrMessages(json);
|
||||||
|
setDisplayMb(true);
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
setErrMessages([err]);
|
||||||
|
setDisplayMb(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center justify-center p-12" >
|
||||||
|
|
||||||
|
<div className="mx-auto w-full max-w-[550px] bg-white">
|
||||||
|
<div>
|
||||||
|
<MessageBox
|
||||||
|
messages={errMessages}
|
||||||
|
display={displayMb}
|
||||||
|
setDisplay={setDisplayMb}
|
||||||
|
buttons={buttonsMb}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className="mb-5">
|
||||||
|
{
|
||||||
|
regEmail && <div className="mb-3 block text-base font-medium text-[#07074D]">
|
||||||
|
{`Sikeresen regisztráltál a következő email címmel: ${regEmail}! Kérlek lépj be a felültre!`}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<label htmlFor="email" className="mb-3 block text-base font-medium text-[#07074D]">
|
||||||
|
Email cím
|
||||||
|
</label>
|
||||||
|
<input type="email" name="email" id="email" placeholder="email cím" onChange={e=>setEmail(e.target.value)} value={email}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-5">
|
||||||
|
<label htmlFor="email" className="mb-3 block text-base font-medium text-[#07074D]">
|
||||||
|
Jelszó
|
||||||
|
</label>
|
||||||
|
<input type="password" id="password" placeholder="jelszó" onChange={e=>setPass(e.target.value)} value={pass}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-5">
|
||||||
|
<Link to={"/elfelejtettjelszo"}> <p className='text-blue-900'>Elfelejettem a jelszavam</p></Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button onClick={signIn}
|
||||||
|
className="hover:shadow-form w-full rounded-md bg-[#6A64F1] py-3 px-8 text-center text-base font-semibold text-white outline-none">
|
||||||
|
Bejelentkezés
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Login;
|
||||||
|
|
18
Frontend copy/Frontend copy/src/components/Main.jsx
Normal file
18
Frontend copy/Frontend copy/src/components/Main.jsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import MainLayout from "./MainLayout";
|
||||||
|
import Caroussel from "./Caroussel";
|
||||||
|
import React from 'react';
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
|
function Main() {
|
||||||
|
const {categoryID} = useParams();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Caroussel/>
|
||||||
|
|
||||||
|
<MainLayout/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Main
|
19
Frontend copy/Frontend copy/src/components/MainLayout.jsx
Normal file
19
Frontend copy/Frontend copy/src/components/MainLayout.jsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
import LeftSideBar from './LeftSideBar';
|
||||||
|
import Caroussel from './Caroussel';
|
||||||
|
import BookMain from './BookMain';
|
||||||
|
function MainLayout() {
|
||||||
|
return (
|
||||||
|
<div className="flex">
|
||||||
|
<div className="w-1/4 bg-gray-200 h-screen bg-transparent">
|
||||||
|
<LeftSideBar/>
|
||||||
|
</div>
|
||||||
|
<div className="w-3/4 bg-white h-screen">
|
||||||
|
<BookMain />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MainLayout;
|
81
Frontend copy/Frontend copy/src/components/MessageBox.jsx
Normal file
81
Frontend copy/Frontend copy/src/components/MessageBox.jsx
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import "../App.css";
|
||||||
|
|
||||||
|
|
||||||
|
function MessageBox({messages, display, setDisplay, buttons}) {
|
||||||
|
const [position, setPosition] = useState({
|
||||||
|
x:window.innerWidth/2,
|
||||||
|
y:window.innerHeight/2
|
||||||
|
});
|
||||||
|
const [grabbed, setGrabbed] = useState(false);
|
||||||
|
|
||||||
|
const move = (e)=> {
|
||||||
|
if(e.nativeEvent.offsetX <= 0
|
||||||
|
|| e.nativeEvent.offsetX >= 300
|
||||||
|
|| e.nativeEvent.offsetY <= 0
|
||||||
|
|| e.nativeEvent.offsetY >= 28) {
|
||||||
|
setGrabbed(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!grabbed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setPosition(p=>(
|
||||||
|
{
|
||||||
|
...p,
|
||||||
|
x:p.x + e.nativeEvent.movementX,
|
||||||
|
y:p.y + e.nativeEvent.movementY
|
||||||
|
}
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onresize = ()=> {
|
||||||
|
setPosition({
|
||||||
|
x:window.innerWidth/2,
|
||||||
|
y:window.innerHeight/2
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="message-box"
|
||||||
|
style={
|
||||||
|
{
|
||||||
|
display:display ? "block" : "none",
|
||||||
|
left:position.x - 150,
|
||||||
|
top:position.y - 150
|
||||||
|
}
|
||||||
|
}>
|
||||||
|
<div className="message-box-header"
|
||||||
|
onMouseDown={()=>setGrabbed(true)}
|
||||||
|
onMouseUp={()=>setGrabbed(false)}
|
||||||
|
onMouseMove={move}>
|
||||||
|
<FontAwesomeIcon onClick={()=>setDisplay(false)}
|
||||||
|
icon="fa-solid fa-circle-xmark"/>
|
||||||
|
</div>
|
||||||
|
<div className="message-box-body">
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
messages.map((m, i)=>
|
||||||
|
<h5 key={i}>{m}</h5>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="message-box-buttons">
|
||||||
|
{
|
||||||
|
buttons.map((b, i)=>
|
||||||
|
<button className="input-md btn-primary" onClick={b.cb} key={i}>
|
||||||
|
{b.text}
|
||||||
|
<FontAwesomeIcon
|
||||||
|
className="ml-5"
|
||||||
|
icon={b.icon}/>
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MessageBox;
|
106
Frontend copy/Frontend copy/src/components/Navbar.jsx
Normal file
106
Frontend copy/Frontend copy/src/components/Navbar.jsx
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||||
|
import User from './User';
|
||||||
|
|
||||||
|
|
||||||
|
function Navbar() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [email, setEmail] = useState('');
|
||||||
|
const [isAdmin, setIsAdmin] = useState(false);
|
||||||
|
const location = useLocation();
|
||||||
|
const [UserID, setUserID] = useState(null); // UserID állapot hozzáadás
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const adminValue = localStorage.getItem("isAdmin");
|
||||||
|
setIsAdmin(adminValue);
|
||||||
|
setEmail(localStorage.getItem("email"))
|
||||||
|
setUserID(localStorage.getItem("UserID"))
|
||||||
|
}, [location])
|
||||||
|
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
localStorage.removeItem("email");
|
||||||
|
localStorage.removeItem("UserID");
|
||||||
|
localStorage.removeItem("isAdmin");
|
||||||
|
navigate("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex p-2 justify-between items-center border-b border-gray-300 flex-wrap">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<img src="https://arthobby.hu/shop_ordered/27703/pic/book-rrental.jpg" className="w-20 h-20" alt="Logo" />
|
||||||
|
<Link to={"/"} ><h2 className="font-bold text-2xl text-teal-500">Könyvkölcsönző</h2></Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-6">
|
||||||
|
|
||||||
|
<Link to="/"
|
||||||
|
className="duration-100 transform hover:scale-125 transition ease-linear px-2 py-2 m-4 inline">Főoldal
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{
|
||||||
|
(isAdmin==="1") &&
|
||||||
|
<Link to="/supervisor-admin"
|
||||||
|
className="duration-100 transform hover:scale-125 transition ease-linear px-2 py-2 m-4 inline">Rendszer Admin
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
|
||||||
|
{ (isAdmin!==1) && (localStorage.getItem('UserID')) &&
|
||||||
|
<Link to="/cart"
|
||||||
|
className="duration-100 transform hover:scale-125 transition ease-linear px-2 py-2 m-4 inline">Kosár
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
|
||||||
|
{(localStorage.getItem('UserID')) &&
|
||||||
|
<Link to="/" onClick={handleLogout}
|
||||||
|
className="duration-100 transform hover:scale-125 transition ease-linear px-2 py-2 m-4 inline">Kilépés
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
(isAdmin==="0" ) && localStorage.getItem('UserID') &&
|
||||||
|
<div>
|
||||||
|
<div class="relative inline-block text-left">
|
||||||
|
<div class="group">
|
||||||
|
<button type="button"
|
||||||
|
class="inline-flex justify-center items-center w-full px-4 py-2 text-sm font-medium text-white bg-teal-500 hover:bg-gray-700 focus:outline-none focus:bg-gray-700">
|
||||||
|
Felhasználoó fiók
|
||||||
|
{/*<!-- Dropdown arrow -->*/}
|
||||||
|
<svg class="w-4 h-4 ml-2 -mr-1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M10 12l-5-5h10l-5 5z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/*<!-- Dropdown menu -->*/}
|
||||||
|
<div
|
||||||
|
class="absolute left-0 w-40 mt-1 origin-top-left bg-white divide-y divide-gray-100 rounded-md shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition duration-300">
|
||||||
|
<div class="py-1">
|
||||||
|
<Link to={`/adataim/${UserID}`} class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Adataim</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{!(localStorage.getItem('UserID')) &&
|
||||||
|
<Link to="/belepes"
|
||||||
|
className="duration-100 transform hover:scale-125 transition ease-linear px-2 py-2 m-4 inline">Belépés
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
{!(localStorage.getItem('UserID')) &&
|
||||||
|
<Link to="/regisztracio"
|
||||||
|
className="duration-100 transform hover:scale-125 transition ease-linear px-2 py-2 m-4 inline">Regisztráció
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Navbar;
|
145
Frontend copy/Frontend copy/src/components/PasswordModify.jsx
Normal file
145
Frontend copy/Frontend copy/src/components/PasswordModify.jsx
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { useNavigate, Link } from 'react-router-dom';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
|
function PasswordModify() {
|
||||||
|
const email = localStorage.getItem("email");
|
||||||
|
const ellenorzokod = localStorage.getItem("verificationCode");
|
||||||
|
const [inputCode, setInputCode] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
const [passwordAgain, setPasswordAgain] = useState("");
|
||||||
|
const [codeVerified, setCodeVerified] = useState(false);
|
||||||
|
const [modified, setModified] = useState(false);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// További logika itt, ha szükséges
|
||||||
|
}, [codeVerified]);
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (ellenorzokod === inputCode) {
|
||||||
|
setCodeVerified(true);
|
||||||
|
toast.success("A kód helyes, kérem adja meg az új jelszavát."); // Sikeres kódüzenet
|
||||||
|
} else {
|
||||||
|
setCodeVerified(false);
|
||||||
|
toast.error("Hibás kód."); // Hibás kódüzenet
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let formObj = {
|
||||||
|
"email": email,
|
||||||
|
"pass": password
|
||||||
|
};
|
||||||
|
|
||||||
|
const [formData, setFormData] = useState(formObj);
|
||||||
|
|
||||||
|
const writeFormData = (e) => {
|
||||||
|
const key = e.target.id === "password" ? "pass" : e.target.id;
|
||||||
|
setFormData((prev) => ({ ...prev, [key]: e.target.value }));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const kuldes = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("http://localhost:3001/resetpass", {
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
credentials: 'include',
|
||||||
|
body: JSON.stringify(formData)
|
||||||
|
});
|
||||||
|
const valasz = await response.json();
|
||||||
|
console.log("Válasz a szervertől:", valasz);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
setModified(true);
|
||||||
|
setCodeVerified(false);
|
||||||
|
toast.success("Módosítás sikeres volt!"); // Sikeres módosítás üzenet
|
||||||
|
} else {
|
||||||
|
// Ezt az ágat használjuk, ha a válasz 200-as státuszkódot nem tartalmaz
|
||||||
|
toast.error(`Hiba történt: ${valasz.message}`); // Hibás módosítás üzenet, szerver válasza alapján
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Beküldési hiba:', error);
|
||||||
|
toast.error(`Hiba történt a módosítás során: ${error.message}`); // Az error.message tartalmazza a hibát, ha a válasz nem JSON formátumú
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handlePasswordSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log(formData.pass, passwordAgain);
|
||||||
|
if (formData.pass.length < 6) {
|
||||||
|
alert("A jelszónak minimum 6 karakter hosszúnak kell lennie");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (formData.pass !== passwordAgain) {
|
||||||
|
alert("A két jelszó nem egyezik meg!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
kuldes();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="min-h-screen bg-gray-100 flex items-center justify-center">
|
||||||
|
<div className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4 max-w-md w-full">
|
||||||
|
{(!codeVerified) && (!modified) &&
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block text-gray-700 text-sm font-bold mb-2">
|
||||||
|
Megadott email címedre ({email}) küldünk egy hitelesítő kódot, amelyet kérlek az alábbi mezőbe írj be.
|
||||||
|
</label>
|
||||||
|
<input className="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="ellenorzokod" type="text" placeholder="ellenőrző kód" value={inputCode} onChange={(e) => setInputCode(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full" type="submit">
|
||||||
|
Kód ellenőrzése
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
{(codeVerified) && (!modified) &&
|
||||||
|
<section>
|
||||||
|
<form onSubmit={handlePasswordSubmit}>
|
||||||
|
<div className="mb-4">
|
||||||
|
<h1 className='text-xl text-center'>A kód helyes, kérem adja meg az új jelszavát</h1>
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block text-gray-700 text-sm font-bold mb-2">
|
||||||
|
Jelszó
|
||||||
|
</label>
|
||||||
|
<input className="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="password" type="password" placeholder="Jelszó" required value={formData.pass} onChange={writeFormData} />
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block text-gray-700 text-sm font-bold mb-2">
|
||||||
|
Jelszó ismét
|
||||||
|
</label>
|
||||||
|
<input className="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="passwordAgain" type="password" placeholder="Jelszó" required value={passwordAgain} onChange={(e) => setPasswordAgain(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full" type="submit">
|
||||||
|
Jelszó módosítása
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
{ modified &&
|
||||||
|
<section>
|
||||||
|
<div className="mb-4">
|
||||||
|
<h1 className='text-3xl text-center'>Módosítás sikeres volt!</h1>
|
||||||
|
</div>
|
||||||
|
<Link to={"/"}>
|
||||||
|
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full" type="button">
|
||||||
|
Ok
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PasswordModify;
|
195
Frontend copy/Frontend copy/src/components/Registration.jsx
Normal file
195
Frontend copy/Frontend copy/src/components/Registration.jsx
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
|
import MessageBox from './MessageBox.jsx';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
|
|
||||||
|
function Registration() {
|
||||||
|
const registrationStyle = {
|
||||||
|
marginTop: '20vh', // 20%-kal lejjebb helyezzük el az elemet
|
||||||
|
};
|
||||||
|
|
||||||
|
const [fullName, setFullName] = useState("");
|
||||||
|
const [phone, setPhone] = useState(0);
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [pass, setPass] = useState("");
|
||||||
|
const [passAgain, setPassAgain] = useState("");
|
||||||
|
const [zip, setZip] = useState("");
|
||||||
|
const [city, setCity] = useState("");
|
||||||
|
const [address, setAddress] = useState("");
|
||||||
|
const [errMessages, setErrMessages] = useState([]);
|
||||||
|
const [displayMb, setDisplayMb] = useState(false);
|
||||||
|
const buttonsMb = [{
|
||||||
|
text:"OK",
|
||||||
|
icon:"fa-solid fa-square-check",
|
||||||
|
cb:()=>setDisplayMb(false)
|
||||||
|
}];
|
||||||
|
|
||||||
|
const navigate = useNavigate(); //ha kell!!!!!!
|
||||||
|
|
||||||
|
|
||||||
|
// const phoneRegex= /^\+36\d{9}$/;
|
||||||
|
|
||||||
|
// const handleSubmit = (e) => {
|
||||||
|
// e.preventDefault();
|
||||||
|
|
||||||
|
// if (password !== passwordAgain) {
|
||||||
|
// alert('A két jelszó nem egyezik meg!');
|
||||||
|
// } else if (!phoneRegex.test(phone)) {
|
||||||
|
// alert('A telefonszám formátuma érvénytelen. Kérjük, a +36-os országkóddal kezdődő 9 számjegyet adjon meg.')
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// // Itt a regisztrációs folyamat folytatódna, ha a jelszavak egyenlőek lennének
|
||||||
|
// console.log('A regisztráció folytatódik...');
|
||||||
|
// }
|
||||||
|
|
||||||
|
const register = async () => {
|
||||||
|
const regObj = {
|
||||||
|
fullName: fullName,
|
||||||
|
phone: phone,
|
||||||
|
email: email,
|
||||||
|
pass: pass,
|
||||||
|
passAgain: passAgain,
|
||||||
|
zip: zip,
|
||||||
|
city: city,
|
||||||
|
address: address
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch("http://localhost:3001/regisztracio", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(regObj),
|
||||||
|
headers: { "Content-type": "application/json" }
|
||||||
|
});
|
||||||
|
|
||||||
|
const json = await response.json();
|
||||||
|
console.log(json);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
toast.success("Sikeres regisztráció");
|
||||||
|
navigate(`/belepes`);
|
||||||
|
} else {
|
||||||
|
json.forEach((msg) => toast.error(msg)); // Hibás regisztrációs üzenetek megjelenítése
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
toast.error("Hiba történt a regisztráció során.");
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
|
||||||
|
<div className="flex items-center justify-center p-12" style={registrationStyle}>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<MessageBox
|
||||||
|
messages={errMessages}
|
||||||
|
display={displayMb}
|
||||||
|
setDisplay={setDisplayMb}
|
||||||
|
buttons={buttonsMb}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mx-auto w-full max-w-[550px] bg-white">
|
||||||
|
<h2 className='text-2xl truncate text-center mb-10'>Van már fiókód?
|
||||||
|
<Link to={"/belepes"} className='font-bold text-blue-800 m-12'>Kérlek jelentkezz be!
|
||||||
|
</Link>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<div className="mb-5">
|
||||||
|
<label className="mb-5 block text-base font-semibold text-[#07074D] sm:text-xl">
|
||||||
|
Teljes név
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="fullname"
|
||||||
|
placeholder="Teljes név"
|
||||||
|
onChange={e=>setFullName(e.target.value)}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-5">
|
||||||
|
<label className="mb-5 block text-base font-semibold text-[#07074D] sm:text-xl">
|
||||||
|
Telefonszám
|
||||||
|
</label>
|
||||||
|
<input type="text" id="phone" placeholder="telefonszám" onChange={e=>setPhone(e.target.value)}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-5">
|
||||||
|
<label className="mb-5 block text-base font-semibold text-[#07074D] sm:text-xl">
|
||||||
|
Email cím
|
||||||
|
</label>
|
||||||
|
<input type="email" id="email" placeholder="email" onChange={e=>setEmail(e.target.value)}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-5">
|
||||||
|
<label className="mb-5 block text-base font-semibold text-[#07074D] sm:text-xl">
|
||||||
|
Jelszó
|
||||||
|
</label>
|
||||||
|
<input type="password"
|
||||||
|
id="password"
|
||||||
|
placeholder="írd be a jelszavad"
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md"
|
||||||
|
value={pass}
|
||||||
|
onChange={(e)=>setPass(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-5">
|
||||||
|
<label className="mb-5 block text-base font-semibold text-[#07074D] sm:text-xl">
|
||||||
|
Jelszó újra
|
||||||
|
</label>
|
||||||
|
<input type="password"
|
||||||
|
id="passwordAgain"
|
||||||
|
placeholder="írd be a jelszavad ismét"
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md"
|
||||||
|
value={passAgain}
|
||||||
|
onChange={(e)=>setPassAgain(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-5 pt-3">
|
||||||
|
<label className="mb-5 block text-base font-semibold text-[#07074D] sm:text-xl">
|
||||||
|
Számlázási és lakcím
|
||||||
|
</label>
|
||||||
|
<div className="-mx-3 flex flex-wrap">
|
||||||
|
<div className="w-full px-3 sm:w-1/2">
|
||||||
|
<div className="mb-5">
|
||||||
|
<input type="text" id="ZIP" placeholder="irányítószám" onChange={e=>setZip(e.target.value)}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full px-3 sm:w-1/2">
|
||||||
|
<div className="mb-5">
|
||||||
|
<input type="text" id="city" placeholder="város" onChange={e=>setCity(e.target.value)}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full px-3">
|
||||||
|
<div className="mb-5">
|
||||||
|
<input type="text" id="address" placeholder="utca, házszám" onChange={e=>setAddress(e.target.value)}
|
||||||
|
className="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* A többi input mező */}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button onClick={register}
|
||||||
|
className="hover:shadow-form w-full rounded-md bg-[#6A64F1] py-3 px-8 text-center text-base font-semibold text-white outline-none"
|
||||||
|
>
|
||||||
|
Regisztráció
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Registration;
|
|
@ -0,0 +1,40 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
|
function SupervisorAdmin() {
|
||||||
|
return (
|
||||||
|
<div className='p-40 flex justify-center '>
|
||||||
|
<div class="flex justify-items-start flex-col max-w-sm gap-8">
|
||||||
|
<Link to={"/supervisor-admin/konyv-admin"}>
|
||||||
|
<button type="button" className="py-2 px-4 flex justify-center items-center bg-blue-600 hover:bg-blue-700 focus:ring-blue-500 focus:ring-offset-blue-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg">
|
||||||
|
<svg width="40" height="40" fill="none" className="stroke-current text-white-400 h-12 w-12 mr-4" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25" />
|
||||||
|
</svg>
|
||||||
|
Könyvek adminisztrálás
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Link to={"/supervisor-admin/felhasznalo-admin"}>
|
||||||
|
<button type="button" className="py-2 px-4 flex justify-center items-center bg-red-600 hover:bg-red-700 focus:ring-red-500 focus:ring-offset-red-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg">
|
||||||
|
<svg width="40" height="40" fill="currentColor" className="mr-2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
|
||||||
|
</svg>
|
||||||
|
Felhasználó adminisztrálás
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<Link to={"/rendelesek-kezelese"}>
|
||||||
|
<button type="button" class="py-2 px-4 flex justify-center items-center bg-gray-600 hover:bg-gray-700 focus:ring-gray-500 focus:ring-offset-gray-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg ">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="mr-2" viewBox="0 0 1792 1792">
|
||||||
|
<path d="M896 128q209 0 385.5 103t279.5 279.5 103 385.5q0 251-146.5 451.5t-378.5 277.5q-27 5-40-7t-13-30q0-3 .5-76.5t.5-134.5q0-97-52-142 57-6 102.5-18t94-39 81-66.5 53-105 20.5-150.5q0-119-79-206 37-91-8-204-28-9-81 11t-92 44l-38 24q-93-26-192-26t-192 26q-16-11-42.5-27t-83.5-38.5-85-13.5q-45 113-8 204-79 87-79 206 0 85 20.5 150t52.5 105 80.5 67 94 39 102.5 18q-39 36-49 103-21 10-45 15t-57 5-65.5-21.5-55.5-62.5q-19-32-48.5-52t-49.5-24l-20-3q-21 0-29 4.5t-5 11.5 9 14 13 12l7 5q22 10 43.5 38t31.5 51l10 23q13 38 44 61.5t67 30 69.5 7 55.5-3.5l23-4q0 38 .5 88.5t.5 54.5q0 18-13 30t-40 7q-232-77-378.5-277.5t-146.5-451.5q0-209 103-385.5t279.5-279.5 385.5-103zm-477 1103q3-7-7-12-10-3-13 2-3 7 7 12 9 6 13-2zm31 34q7-5-2-16-10-9-16-3-7 5 2 16 10 10 16 3zm30 45q9-7 0-19-8-13-17-6-9 5 0 18t17 7zm42 42q8-8-4-19-12-12-20-3-9 8 4 19 12 12 20 3zm57 25q3-11-13-16-15-4-19 7t13 15q15 6 19-6zm63 5q0-13-17-11-16 0-16 11 0 13 17 11 16 0 16-11zm58-10q-2-11-18-9-16 3-14 15t18 8 14-14z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
Kölcsönzések kezelése
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SupervisorAdmin
|
80
Frontend copy/Frontend copy/src/components/User.jsx
Normal file
80
Frontend copy/Frontend copy/src/components/User.jsx
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
|
function User(props) {
|
||||||
|
|
||||||
|
const torles = (UserID) => {
|
||||||
|
fetch(`http://localhost:3001/admin/users/${UserID}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: { "Content-type": "application/json" },
|
||||||
|
credentials: 'include',
|
||||||
|
})
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(res => {
|
||||||
|
toast.success(res); // Sikeres törlés üzenet
|
||||||
|
props.onDelete();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
toast.error("Hiba történt a törlés során."); // Hiba üzenet
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div className="flex-shrink-0 h-10 w-10">
|
||||||
|
<img className="h-10 w-10 rounded-full" src="https://i.pravatar.cc/150?img=1" alt=""/>
|
||||||
|
</div>
|
||||||
|
<div className="ml-4">
|
||||||
|
<div className="text-sm font-medium text-gray-900">
|
||||||
|
{props.user.UserID}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div className="text-sm text-gray-500">
|
||||||
|
{props.user.Name}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
|
||||||
|
{props.user.Email}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||||
|
<div className="text-sm text-gray-900">{props.Zip} {props.City}</div>
|
||||||
|
<div className="text-sm text-gray-500">{props.user.ZIP} {props.user.City } {props.user.Address}</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
|
||||||
|
{props.user.IsAdmin ? "Adminisztrátor" : "Vásárló"}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||||
|
<a onClick={() => document.getElementById(`torol${props.user.UserID}`).showModal()} className="ml-2 text-red-600 hover:text-red-900">Töröl</a>
|
||||||
|
</td>
|
||||||
|
<dialog id={`torol${props.user.UserID}`} className="modal">
|
||||||
|
<div className="modal-box">
|
||||||
|
<h3 className="font-bold text-lg">Törlés</h3>
|
||||||
|
<p className="py-4">
|
||||||
|
Biztosan törli {props.user.Name} nevű felhasználó adatait?
|
||||||
|
</p>
|
||||||
|
<div className="modal-action">
|
||||||
|
<form method="dialog">
|
||||||
|
<button onClick={() => torles(props.user.UserID)} className="btn">Ok</button>
|
||||||
|
<button className="btn">Mégsem</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default User;
|
119
Frontend copy/Frontend copy/src/components/UserList.jsx
Normal file
119
Frontend copy/Frontend copy/src/components/UserList.jsx
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
import React from 'react';
|
||||||
|
import User from './User';
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
function UserList() {
|
||||||
|
const [users, setUsers] = useState([]);
|
||||||
|
const [letter, setLetter] = useState("");
|
||||||
|
const [inputLetter, setInputLetter] = useState("");
|
||||||
|
const [searchPerformed, setSearchPerformed] = useState(false); // Új állapot, ami jelzi, hogy történt-e már keresés
|
||||||
|
|
||||||
|
const inputLetterChange = (e) => {
|
||||||
|
const input = e.target.value;
|
||||||
|
setInputLetter(input.slice(0, 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
setLetter(inputLetter);
|
||||||
|
setSearchPerformed(true); // Keresés történt
|
||||||
|
fetch(`http://localhost:3001/admin/users/search/${inputLetter}`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
setUsers(data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
setUsers([]); // Hiba esetén vagy ha nincsenek eredmények, üres listát állítunk be
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlecClick2 = () => {
|
||||||
|
setLetter("");
|
||||||
|
setInputLetter("");
|
||||||
|
setSearchPerformed(false); // Keresési állapot törlése
|
||||||
|
refreshUsers();
|
||||||
|
};
|
||||||
|
|
||||||
|
const refreshUsers = () => {
|
||||||
|
fetch("http://localhost:3001/admin/users")
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
console.log("Users refreshed", data);
|
||||||
|
setUsers(data);
|
||||||
|
})
|
||||||
|
.catch(err => console.log(err));
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
refreshUsers();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2 className='text-3xl flex justify-center p-12'>Regisztrált felhasználók listája</h2>
|
||||||
|
|
||||||
|
<div className="relative w-full max-w-xl mx-auto bg-white rounded-full">
|
||||||
|
<input
|
||||||
|
placeholder="Felhasználó kezdőbetűje alapján"
|
||||||
|
className="rounded-full w-full h-16 bg-transparent py-2 pl-8 pr-32 outline-none border-2 border-gray-100 shadow-md hover:outline-none focus:ring-teal-200 focus:border-teal-200"
|
||||||
|
type="text"
|
||||||
|
value={inputLetter}
|
||||||
|
onChange={inputLetterChange}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
onClick={handleClick}
|
||||||
|
className="absolute inline-flex items-center h-10 px-4 py-2 text-sm text-white transition duration-150 ease-in-out rounded-full outline-none right-3 top-3 bg-teal-600 sm:px-6 sm:text-base sm:font-medium hover:bg-teal-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-500"
|
||||||
|
>
|
||||||
|
Keresés
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{searchPerformed && (
|
||||||
|
<button
|
||||||
|
onClick={handlecClick2}
|
||||||
|
className="mt-4 bg-red-500 text-white px-4 py-2 rounded shadow"
|
||||||
|
>
|
||||||
|
Keresés törlése
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{users.length > 0 ? (
|
||||||
|
<table className="min-w-full divide-y divide-gray-200 overflow-x-auto">
|
||||||
|
<thead className="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Azonosító
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Név
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Emailcím
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Lakcím
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Vásárló / Adminisztátor
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Műveletek
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="bg-white divide-y divide-gray-200">
|
||||||
|
{users.map((user) => (
|
||||||
|
<User key={user.UserID} user={user} onDelete={refreshUsers} />
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
) : (
|
||||||
|
<h1 className="text-center my-10 text-xl">Nincs ilyen kezdőbetűvel felhasználó.</h1>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UserList;
|
3
Frontend copy/Frontend copy/src/index.css
Normal file
3
Frontend copy/Frontend copy/src/index.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
3
Frontend copy/Frontend copy/src/input.css
Normal file
3
Frontend copy/Frontend copy/src/input.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
10
Frontend copy/Frontend copy/src/main.jsx
Normal file
10
Frontend copy/Frontend copy/src/main.jsx
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import React from 'react'
|
||||||
|
import ReactDOM from 'react-dom/client'
|
||||||
|
import App from './App.jsx'
|
||||||
|
import './index.css'
|
||||||
|
|
||||||
|
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
)
|
14
Frontend copy/Frontend copy/style.css
Normal file
14
Frontend copy/Frontend copy/style.css
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
.custom-padding {
|
||||||
|
padding-left: 30px;
|
||||||
|
padding-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.book-image {
|
||||||
|
width: 100%; /* 100%-os szélesség */
|
||||||
|
height: 500px; /* Fix magasság például 200px */
|
||||||
|
object-fit: cover; /* A kép méretarányának megőrzése és kitöltése */
|
||||||
|
}
|
12
Frontend copy/Frontend copy/tailwind.config.js
Normal file
12
Frontend copy/Frontend copy/tailwind.config.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
export default {
|
||||||
|
content: [
|
||||||
|
"./index.html",
|
||||||
|
"./src/**/*.{js,ts,jsx,tsx}",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [require("daisyui")],
|
||||||
|
}
|
||||||
|
|
7
Frontend copy/Frontend copy/vite.config.js
Normal file
7
Frontend copy/Frontend copy/vite.config.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import react from '@vitejs/plugin-react'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react()],
|
||||||
|
})
|
BIN
Könyvkölcsönző webapplikáció vizsgaremek.docx
Normal file
BIN
Könyvkölcsönző webapplikáció vizsgaremek.docx
Normal file
Binary file not shown.
BIN
Könyvkölcsönző webapplikáció vizsgaremek.pdf
Normal file
BIN
Könyvkölcsönző webapplikáció vizsgaremek.pdf
Normal file
Binary file not shown.
371
backend_konyvkolcsonzo_v5/app/Books.js
Normal file
371
backend_konyvkolcsonzo_v5/app/Books.js
Normal file
|
@ -0,0 +1,371 @@
|
||||||
|
import CheckPermission from "./CheckPermission.js";
|
||||||
|
import conn from "./Conn.js";
|
||||||
|
|
||||||
|
class Books {
|
||||||
|
|
||||||
|
checkErrors(book) {
|
||||||
|
const errors = [];
|
||||||
|
|
||||||
|
if(book.author.length === 0
|
||||||
|
|| book.author === undefined
|
||||||
|
|| book.author === null){
|
||||||
|
console.log(typeof(book));
|
||||||
|
errors.push("A szerzőt kötelező beállítani!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(book.title.length === 0
|
||||||
|
|| book.title === undefined
|
||||||
|
|| book.title === null)
|
||||||
|
errors.push("A könyv címét kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.publisher.length === 0
|
||||||
|
|| book.publisher === undefined
|
||||||
|
|| book.title === null)
|
||||||
|
errors.push("A könyv kiadóját kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.the_year_of_publishing === 0
|
||||||
|
|| book.the_year_of_publishing === undefined
|
||||||
|
|| book.the_year_of_publishing === null)
|
||||||
|
errors.push("A könyv kiadásának évét kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.description.length === 0
|
||||||
|
|| book.description === undefined
|
||||||
|
|| book.description === null)
|
||||||
|
errors.push("A könyv leírását kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.language.length === 0
|
||||||
|
|| book.language === undefined
|
||||||
|
|| book.language === null)
|
||||||
|
errors.push("A könyv nyelvét kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.number_of_pages === 0
|
||||||
|
|| book.number_of_pages === undefined
|
||||||
|
|| book.number_of_pages === null)
|
||||||
|
errors.push("A könyv terjedelmét kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.cover.length === 0
|
||||||
|
|| book.cover === undefined
|
||||||
|
|| book.cover === null)
|
||||||
|
errors.push("A könyv borítójának típusát kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.cover.length === 0
|
||||||
|
|| book.cover === undefined
|
||||||
|
|| book.cover === null)
|
||||||
|
errors.push("A könyv súlyát kötelező megadni!");
|
||||||
|
|
||||||
|
if((!book.ISBN || book.ISBN.length === 0)
|
||||||
|
|| book.ISBN === undefined
|
||||||
|
|| book.ISBN === null)
|
||||||
|
errors.push("A könyv ISBN számát kötelező megadni!");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(book.itemcode.length === 0
|
||||||
|
|| book.itemcode === undefined
|
||||||
|
|| book.itemcode === null)
|
||||||
|
errors.push("A könyv termékkódját kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.price === 0
|
||||||
|
|| book.price === undefined
|
||||||
|
|| book.price === null)
|
||||||
|
errors.push("A könyv árát kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.discounted_price === 0
|
||||||
|
|| book.discounted_price === undefined
|
||||||
|
|| book.discounted_price === null)
|
||||||
|
errors.push("A könyv kedvezményes árát kötelező megadni!");
|
||||||
|
|
||||||
|
if(book.categoryID === 0
|
||||||
|
|| book.categoryID === undefined
|
||||||
|
|| book.categoryID === null)
|
||||||
|
errors.push("A könyv kategóriáját kötelező megadni!");
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
async serchBooks(char) {
|
||||||
|
const sql = `SELECT * FROM books WHERE title LIKE ?`;
|
||||||
|
const startingP = `${char}%`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await conn.promise().query(sql, [startingP]);
|
||||||
|
|
||||||
|
if(data[0].length !== 0) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages: data[0]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status: 404,
|
||||||
|
messages:["A keresett erőforrás nem található!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages: ["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getBooksCatID(id) {
|
||||||
|
const sql = `SELECT * FROM books WHERE categoryID = ?`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await conn.promise().query(sql, [id]);
|
||||||
|
|
||||||
|
if(data[0].length !== 0) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages: data[0]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:["A keresett erőforrás nem található!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages: ["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async getBook(id) {
|
||||||
|
const sql = `SELECT * FROM books WHERE BookID = ?`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await conn.promise().query(sql, [id]);
|
||||||
|
|
||||||
|
if(data[0].length !== 0) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages: data[0][0]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:["A keresett erőforrás nem található!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getBooks() {
|
||||||
|
const sql = "SELECT * FROM books";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:response[0]
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteBook(id, userID, isAdmin) {
|
||||||
|
const sql = `DELETE FROM books WHERE BookID = ?`;
|
||||||
|
|
||||||
|
if(!CheckPermission(userID, isAdmin, true)) {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:["Nincs jogosultságod törölni a bejegyzést!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [id]);
|
||||||
|
|
||||||
|
if(response[0].affectedRows === 1) {
|
||||||
|
return {
|
||||||
|
status:200, //ha a status code 204 (No Content) nem tudok hozzá üzenetet beállítani, emiatt állítottam be a 200-at!
|
||||||
|
messages:"Sikeres törlés!"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:"Az erőforrás nem található!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async addBook(book, userID, isAdmin) {
|
||||||
|
const sql = `INSERT INTO books (author, title, publisher, the_year_of_publishing,
|
||||||
|
description, language, number_of_pages, cover, weight, ISBN, itemcode, price, discounted_price, book_url, categoryID)
|
||||||
|
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`;
|
||||||
|
|
||||||
|
const errors = this.checkErrors(book);
|
||||||
|
|
||||||
|
if(!CheckPermission(userID, isAdmin, true)) {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:["Nincs jogosultságod létrehozni a bejegyzést!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errors.length > 0) {
|
||||||
|
console.log(errors);
|
||||||
|
return {
|
||||||
|
status:400,
|
||||||
|
messages:errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql,
|
||||||
|
[
|
||||||
|
|
||||||
|
book.author,
|
||||||
|
book.title,
|
||||||
|
book.publisher,
|
||||||
|
book.the_year_of_publishing,
|
||||||
|
book.description,
|
||||||
|
book.language,
|
||||||
|
book.number_of_pages,
|
||||||
|
book.cover,
|
||||||
|
book.weight,
|
||||||
|
book.ISBN,
|
||||||
|
book.itemcode,
|
||||||
|
book.price,
|
||||||
|
book.discounted_price,
|
||||||
|
book.book_url,
|
||||||
|
book.categoryID
|
||||||
|
|
||||||
|
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:["Sikeres felvitel!"]
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateBook(book, userID, isAdmin) {
|
||||||
|
const sql = `UPDATE books
|
||||||
|
SET author = ?, title = ?,
|
||||||
|
publisher = ?, the_year_of_publishing = ?,
|
||||||
|
description = ?, language = ?, number_of_pages = ?,
|
||||||
|
cover = ?, weight = ?, ISBN = ?, itemcode = ?, price = ?,
|
||||||
|
discounted_price = ?, book_url = ?, categoryID = ? WHERE BookID = ?`;
|
||||||
|
|
||||||
|
const errors = this.checkErrors(book);
|
||||||
|
|
||||||
|
if(!CheckPermission(userID, isAdmin, true)) {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:["Nincs jogosultságod felülírni a bejegyzést!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errors.length > 0) {
|
||||||
|
return {
|
||||||
|
status:400,
|
||||||
|
messages:errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql,
|
||||||
|
[
|
||||||
|
book.author,
|
||||||
|
book.title,
|
||||||
|
book.publisher,
|
||||||
|
book.the_year_of_publishing,
|
||||||
|
book.description,
|
||||||
|
book.language,
|
||||||
|
book.number_of_pages,
|
||||||
|
book.cover,
|
||||||
|
book.weight,
|
||||||
|
book.ISBN,
|
||||||
|
book.itemcode,
|
||||||
|
book.price,
|
||||||
|
book.discounted_price,
|
||||||
|
book.book_url,
|
||||||
|
book.categoryID,
|
||||||
|
book.bookID
|
||||||
|
|
||||||
|
]);
|
||||||
|
|
||||||
|
if(response[0].affectedRows === 1) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:["Sikeres felülírás"]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:["A keresett könyv nem található!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Books;
|
356
backend_konyvkolcsonzo_v5/app/BorrowedBooks.js
Normal file
356
backend_konyvkolcsonzo_v5/app/BorrowedBooks.js
Normal file
|
@ -0,0 +1,356 @@
|
||||||
|
import CheckPermission from "./CheckPermission.js";
|
||||||
|
import conn from "./Conn.js";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BorrowedBooks {
|
||||||
|
|
||||||
|
async getBorBooks() {
|
||||||
|
const sql = `SELECT borrowedbooks.BookID, borrowedbooks.cartID,
|
||||||
|
DATE_FORMAT(borrowedbooks.end_of_borrowment, '%Y-%m-%d') as end_of_borrowment,
|
||||||
|
borrowedbooks.quantity,
|
||||||
|
DATE_FORMAT(borrowedbooks.start_of_borrowment, '%Y-%m-%d') as start_of_borrowment,
|
||||||
|
borrowedbooks.UserID, borrowedbooks.bringedBack
|
||||||
|
,books.title, users.Name FROM borrowedbooks
|
||||||
|
INNER JOIN books
|
||||||
|
ON books.BookID = borrowedbooks.BookID
|
||||||
|
INNER JOIN users
|
||||||
|
ON users.UserID = borrowedbooks.UserID`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:response[0]
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getBorrowsByUser(userID) {
|
||||||
|
const sql = `SELECT borrowedbooks.BookID, borrowedbooks.cartID,
|
||||||
|
DATE_FORMAT(borrowedbooks.end_of_borrowment, '%Y-%m-%d') as end_of_borrowment,
|
||||||
|
borrowedbooks.quantity,
|
||||||
|
DATE_FORMAT(borrowedbooks.start_of_borrowment, '%Y-%m-%d') as start_of_borrowment,
|
||||||
|
borrowedbooks.UserID, borrowedbooks.bringedBack, books.title
|
||||||
|
FROM borrowedbooks
|
||||||
|
INNER JOIN books
|
||||||
|
ON books.BookID = borrowedbooks.BookID
|
||||||
|
WHERE UserID = ?`;
|
||||||
|
|
||||||
|
if(userID === null || userID === undefined) {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:["Nincs jogosultságod megtekinteni az adatokat!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [userID]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:response[0]
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getBorrowsByCartID(CartID, userID, isAdmin) {
|
||||||
|
const sql = `SELECT borrowedbooks.BookID, borrowedbooks.cartID,
|
||||||
|
DATE_FORMAT(borrowedbooks.end_of_borrowment, '%Y-%m-%d') as end_of_borrowment,
|
||||||
|
borrowedbooks.quantity,
|
||||||
|
DATE_FORMAT(borrowedbooks.start_of_borrowment, '%Y-%m-%d') as start_of_borrowment,
|
||||||
|
borrowedbooks.UserID, borrowedbooks.bringedBack,
|
||||||
|
books.title, users.Name FROM borrowedbooks
|
||||||
|
INNER JOIN books
|
||||||
|
ON books.BookID = borrowedbooks.BookID
|
||||||
|
INNER JOIN users
|
||||||
|
ON users.UserID = borrowedbooks.UserID WHERE cartID = ?`;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(!CheckPermission(userID, isAdmin, true)) {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:["Nincs jogosultságod megtekinteni az adatokat!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [CartID]);
|
||||||
|
if(response[0].length !==0)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:response[0][0]
|
||||||
|
};
|
||||||
|
}else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:["A keresett erőforrás nem található!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getBorrowsByUserID(userID, isAdmin) {
|
||||||
|
const sql = `SELECT borrowedbooks.BookID, borrowedbooks.cartID,
|
||||||
|
DATE_FORMAT(borrowedbooks.end_of_borrowment, '%Y-%m-%d') as end_of_borrowment,
|
||||||
|
borrowedbooks.quantity,
|
||||||
|
DATE_FORMAT(borrowedbooks.start_of_borrowment, '%Y-%m-%d') as start_of_borrowment,
|
||||||
|
borrowedbooks.UserID, borrowedbooks.bringedBack,
|
||||||
|
books.title, users.Name FROM borrowedbooks
|
||||||
|
INNER JOIN books
|
||||||
|
ON books.BookID = borrowedbooks.BookID
|
||||||
|
INNER JOIN users
|
||||||
|
ON users.UserID = borrowedbooks.UserID WHERE borrowedbooks.UserID = ?`;
|
||||||
|
|
||||||
|
if(isAdmin === null || isAdmin === undefined || isAdmin === "0") {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:["Nincs jogosultságod megtekinteni az adatokat!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [userID]);
|
||||||
|
if(response[0].length !==0)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:response[0]
|
||||||
|
};
|
||||||
|
}else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:["A keresett erőforrás nem található!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkBorrows(bookID, userID) {
|
||||||
|
const sql = `SELECT COUNT(*) as BookNumber
|
||||||
|
FROM borrowedbooks WHERE BookID = ?
|
||||||
|
AND bringedBack = ? AND UserID = ?`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [bookID, 0, userID]);
|
||||||
|
return parseInt(response[0][0].BookNumber);
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkCartID(cartID) {
|
||||||
|
const sql = `SELECT COUNT(*) as CartIDNumber
|
||||||
|
FROM borrowedbooks WHERE cartID = ?`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [cartID]);
|
||||||
|
return parseInt(response[0][0].CartIDNumber);
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async addBorrow(borrowDatas) {
|
||||||
|
|
||||||
|
|
||||||
|
const errors = [];
|
||||||
|
const successes = [];
|
||||||
|
if(borrowDatas.userID === null || borrowDatas.userID === undefined || borrowDatas.userID === "")
|
||||||
|
errors.push("Nincs jogosultságod a művelet elvégzéséhez. Kérlek jelentkezz be!")
|
||||||
|
if(await this.checkBorrows(borrowDatas.bookID, borrowDatas.userID) > 0)
|
||||||
|
errors.push("Már kivettél egy ilyen könyvet, és még nem hoztad vissza!");
|
||||||
|
|
||||||
|
if(errors.length > 0) {
|
||||||
|
return {
|
||||||
|
status:400,
|
||||||
|
messages:errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let borrowData of borrowDatas) {
|
||||||
|
|
||||||
|
const sql = `INSERT INTO borrowedbooks
|
||||||
|
(BookID, cartID, end_of_borrowment, quantity, start_of_borrowment, UserID)
|
||||||
|
VALUES(?,?,?,?,?,?)`;
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const response = await conn.promise().query(sql, [
|
||||||
|
borrowData.BookID,
|
||||||
|
borrowData.cartID,
|
||||||
|
borrowData.end_of_borrowment,
|
||||||
|
borrowData.quantity,
|
||||||
|
borrowData.start_of_borrowment,
|
||||||
|
borrowData.UserID
|
||||||
|
]);
|
||||||
|
const successMessage = "[Sikeres kölcsönzés!]";
|
||||||
|
if(!successes.includes(successMessage))
|
||||||
|
{
|
||||||
|
successes.push(successMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(successes.length > 0) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:successes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateOrder(borrowData, isAdmin) {
|
||||||
|
const sql = `UPDATE borrowedbooks SET bringedBack = ?
|
||||||
|
WHERE cartID = ?`;
|
||||||
|
|
||||||
|
if(isAdmin === null || isAdmin === undefined || isAdmin === "0") {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:"Nincs jogosultságod felülírni a megrendelést!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql,
|
||||||
|
[
|
||||||
|
borrowData.bringedBack,
|
||||||
|
borrowData.cartID,
|
||||||
|
|
||||||
|
]);
|
||||||
|
|
||||||
|
if(response[0].affectedRows > 0) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:"Sikeres felülírás!"
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:"A megadott azonosító alapján nem található megrendelés! "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteOrder(cartID, userID, isAdmin) {
|
||||||
|
const sql = `DELETE FROM borrowedbooks WHERE cartID = ?`;
|
||||||
|
|
||||||
|
if(!CheckPermission(userID, isAdmin, true)) {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:"Nincs jogosultságod törölni a bejegyzést!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [cartID]);
|
||||||
|
|
||||||
|
if(response[0].affectedRows > 0) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:"Sikeres törlés!"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:"A megrendelés nem található a megadott azonosító alapján!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage)
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:"A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default BorrowedBooks;
|
57
backend_konyvkolcsonzo_v5/app/Categories.js
Normal file
57
backend_konyvkolcsonzo_v5/app/Categories.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import conn from "./Conn.js";
|
||||||
|
|
||||||
|
class Categories {
|
||||||
|
async getCategory(id) {
|
||||||
|
const sql = `SELECT * FROM categories
|
||||||
|
WHERE categoryID = ?`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await conn.promise().query(sql, [id]);
|
||||||
|
|
||||||
|
if(data[0].length !==0) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:data[0][0]
|
||||||
|
};
|
||||||
|
}else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:["A keresett erőforrás nem található!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(errr);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCategories() {
|
||||||
|
const sql = "SELECT * FROM categories";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:response[0]
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Categories;
|
13
backend_konyvkolcsonzo_v5/app/CheckPermission.js
Normal file
13
backend_konyvkolcsonzo_v5/app/CheckPermission.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
function CheckPermission(userID, isAdmin, admin = false) {
|
||||||
|
console.log(userID, isAdmin, admin);
|
||||||
|
|
||||||
|
if(userID === undefined || userID === null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(admin && (isAdmin === undefined || isAdmin === null || isAdmin == 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CheckPermission;
|
10
backend_konyvkolcsonzo_v5/app/Conn.js
Normal file
10
backend_konyvkolcsonzo_v5/app/Conn.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import mysql from "mysql2";
|
||||||
|
|
||||||
|
const conn = mysql.createConnection({
|
||||||
|
host:"127.0.0.1",
|
||||||
|
user:"root",
|
||||||
|
password:"",
|
||||||
|
database:"konyvkolcsonzo"
|
||||||
|
});
|
||||||
|
|
||||||
|
export default conn;
|
3
backend_konyvkolcsonzo_v5/app/EmailCheck.js
Normal file
3
backend_konyvkolcsonzo_v5/app/EmailCheck.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const emailRegex = /^[\w\.\-\_öüóőúéáűíÖÜÓŐÚÉÁŰÍ]{1,255}\@[\w\.\-\_]{1,255}\.[\w]{2,8}$/;
|
||||||
|
|
||||||
|
export {emailRegex};
|
3
backend_konyvkolcsonzo_v5/app/PhoneNumberCheck.js
Normal file
3
backend_konyvkolcsonzo_v5/app/PhoneNumberCheck.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const phoneRegex = /^\+36\d{9}$/;
|
||||||
|
|
||||||
|
export {phoneRegex};
|
297
backend_konyvkolcsonzo_v5/app/User.js
Normal file
297
backend_konyvkolcsonzo_v5/app/User.js
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
import conn from "./Conn.js";
|
||||||
|
import hash from "./hash.js";
|
||||||
|
import { emailRegex } from "./EmailCheck.js";
|
||||||
|
import { phoneRegex } from "./PhoneNumberCheck.js";
|
||||||
|
import crypto from "crypto";
|
||||||
|
import CheckPermission from "./CheckPermission.js";
|
||||||
|
|
||||||
|
class User {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async register(user) { //CONCAT +
|
||||||
|
const sql = `INSERT INTO users
|
||||||
|
(IsAdmin, Name, Phone, Email, Pass, ZIP, City, Address)
|
||||||
|
VALUES(?,?,?,?,?,?,?,?)`;
|
||||||
|
|
||||||
|
let errors = [];
|
||||||
|
|
||||||
|
if(!emailRegex.test(user.email)) {
|
||||||
|
errors.push("A megadott email cím formátuma nem megfelelő!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(user.pass.length < 8) {
|
||||||
|
errors.push("A jelszónak legalább 8 karakteresnek kell lennie!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(user.pass !== user.passAgain) {
|
||||||
|
errors.push("A két jelszó nem egyezik meg!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!phoneRegex.test(user.phone)) {
|
||||||
|
errors.push("A telefonszám formátuma érvénytelen. Kérjük, a +36-os országkóddal kezdődő 9 számjegyet adjon meg!")
|
||||||
|
}
|
||||||
|
if(await this.checkEmail(user.email) !== 0)
|
||||||
|
errors.push("A megadott email címmel már regisztráltak a felületen!")
|
||||||
|
|
||||||
|
if(errors.length > 0) {
|
||||||
|
return {
|
||||||
|
status:400,
|
||||||
|
messages:errors
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
await conn.promise().query(sql,
|
||||||
|
[
|
||||||
|
false,
|
||||||
|
user.fullName,
|
||||||
|
user.phone,
|
||||||
|
user.email,
|
||||||
|
hash(user.pass),
|
||||||
|
user.zip,
|
||||||
|
user.city,
|
||||||
|
user.address
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:["Sikeres regisztráció!"]
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async login(user, res) {
|
||||||
|
const sql = `SELECT UserID, IsAdmin, Email FROM users WHERE Email = ? AND PAss = ?`;
|
||||||
|
const token = crypto.randomBytes(64).toString('hex'); //??????????? Nem használunk tokent
|
||||||
|
try {
|
||||||
|
const userData = await conn.promise().query(sql, [user.email, hash(user.pass)]);
|
||||||
|
|
||||||
|
if(userData[0].length === 1) {
|
||||||
|
const userID = parseInt(userData[0][0].UserID);
|
||||||
|
const isAdmin = parseInt(userData[0][0].IsAdmin);
|
||||||
|
const email = userData[0][0].Email;
|
||||||
|
|
||||||
|
const expires = new Date(Date.now() + 7 * 24 * 60 * 60 *1000);
|
||||||
|
res.cookie("userID", userID, {expires:expires, httpOnly:true});
|
||||||
|
res.cookie("isAdmin", isAdmin, {expires:expires, httpOnly:true});
|
||||||
|
res.cookie("email", email, {expires: expires, httpOnly:true});
|
||||||
|
|
||||||
|
return {
|
||||||
|
messages:{isAdmin:isAdmin, email: email, userID:userID, token:token, uzenet:["Sikeres belépés"]},
|
||||||
|
status:200
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
messages:["Nem megfelelő felhasználónév/jelszó páros!"],
|
||||||
|
status:403
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages: ["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getUsers(isAdmin) {
|
||||||
|
const sql = "SELECT * FROM users";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:response[0]
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteUser(userID, c_userID, isAdmin) {
|
||||||
|
const sql = `DELETE FROM users WHERE UserID = ?`;
|
||||||
|
|
||||||
|
if(!CheckPermission(c_userID, isAdmin, true)) {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:["Nincs jogosultságod törölni a bejegyzést!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [userID]);
|
||||||
|
|
||||||
|
if(response[0].affectedRows === 1) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:"Sikeres törlés!"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:"A felhasználó nem található a megadott ID alapján!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage)
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkEmail(email) {
|
||||||
|
const sql = `SELECT COUNT(*) as EmailExist
|
||||||
|
FROM users WHERE Email = ?`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [email]);
|
||||||
|
return parseInt(response[0][0].EmailExist);
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async resetPass(user) {
|
||||||
|
const sql = `UPDATE users SET Pass = ?
|
||||||
|
WHERE Email = ?`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(await this.checkEmail(user.email) !== 0){
|
||||||
|
const response = await conn.promise().query(sql,
|
||||||
|
[
|
||||||
|
hash(user.pass),
|
||||||
|
user.email,
|
||||||
|
|
||||||
|
]);
|
||||||
|
if(response[0].affectedRows === 1) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:["Sikeres felülírás!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:["A megadott email cím nem szerepel az adatbázisban! "]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async searchUsers(char) {
|
||||||
|
const sql = `SELECT * FROM users WHERE name LIKE ?`;
|
||||||
|
const startingP = `${char}%`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await conn.promise().query(sql, [startingP]);
|
||||||
|
|
||||||
|
if(data[0].length !== 0) {
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages: data[0]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status: 404,
|
||||||
|
messages:["A keresett erőforrás nem található!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages: ["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getProfile(userID) {
|
||||||
|
const sql = `SELECT * FROM users
|
||||||
|
WHERE UserID = ?`;
|
||||||
|
|
||||||
|
if(userID === null || userID === undefined || userID === "") {
|
||||||
|
return {
|
||||||
|
status:403,
|
||||||
|
messages:["Nem vagy belépve! Kérlek, lépj be előbb a felületre!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await conn.promise().query(sql, [userID]);
|
||||||
|
if(response[0].length == 1)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
status:200,
|
||||||
|
messages:response[0][0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return {
|
||||||
|
status:404,
|
||||||
|
messages:["Nem találtam a profilodhoz adatot!"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
console.log(err.errno);
|
||||||
|
console.log(err.sqlMessage);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status:503,
|
||||||
|
messages:["A szolgáltatás jelenleg nem elérhető! Próbálja meg később!"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default User;
|
5
backend_konyvkolcsonzo_v5/app/hash.js
Normal file
5
backend_konyvkolcsonzo_v5/app/hash.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import crypto from "crypto";
|
||||||
|
|
||||||
|
const hash = (str)=>crypto.createHash("sha512").update(str).digest("hex");
|
||||||
|
|
||||||
|
export default hash;
|
317
backend_konyvkolcsonzo_v5/index.js
Normal file
317
backend_konyvkolcsonzo_v5/index.js
Normal file
|
@ -0,0 +1,317 @@
|
||||||
|
import express from "express";
|
||||||
|
import cors from "cors";
|
||||||
|
import cookieParser from "cookie-parser";
|
||||||
|
import Categories from "./app/Categories.js";
|
||||||
|
import Books from "./app/Books.js";
|
||||||
|
import conn from "./app/Conn.js";
|
||||||
|
import User from "./app/User.js";
|
||||||
|
|
||||||
|
import crypto from 'crypto';
|
||||||
|
import BorrowedBooks from "./app/BorrowedBooks.js";
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
app.use(cors({
|
||||||
|
origin:"http://localhost:5173",
|
||||||
|
credentials:true,
|
||||||
|
methods: "GET,HEAD,PUT,PATCH,POST,DELETE"
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(cookieParser());
|
||||||
|
|
||||||
|
const c = new Categories();
|
||||||
|
const b = new Books();
|
||||||
|
const u = new User();
|
||||||
|
const bo = new BorrowedBooks();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Kategória lekérése ID alapján
|
||||||
|
//pl. http://localhost:3001/categories/15
|
||||||
|
|
||||||
|
app.get("/categories/:id" , async (req, res)=> {
|
||||||
|
const response = await c.getCategory(req.params.id);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Összes kategória lekérése
|
||||||
|
//pl. http://localhost:3001/categories
|
||||||
|
|
||||||
|
app.get("/categories", async (req, res)=> {
|
||||||
|
const response = await c.getCategories();
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Könyvek lekérése categoryID alapján
|
||||||
|
//pl. http://localhost:3001/books/category/3
|
||||||
|
|
||||||
|
app.get("/books/category/:id", async (req, res)=> {
|
||||||
|
const response = await b.getBooksCatID(req.params.id);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Könyv lekérése ID alapján
|
||||||
|
//pl. http://localhost:3001/books/18
|
||||||
|
|
||||||
|
app.get("/books/:id", async (req, res)=> {
|
||||||
|
const response = await b.getBook(req.params.id);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Összes könyv lekérése
|
||||||
|
//pl. http://localhost:3001/books
|
||||||
|
|
||||||
|
app.get("/books", async (req, res)=> {
|
||||||
|
const response = await b.getBooks();
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Könyv törlése ID alapján
|
||||||
|
//pl. DELETE http://localhost:3001/books/60 TESZTELVE POSTMAN-NEL
|
||||||
|
|
||||||
|
app.delete("/books/:id", async (req, res)=> {
|
||||||
|
const response = await b.deleteBook(req.params.id, req.cookies.userID, req.cookies.isAdmin);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Könyv hozzáadása
|
||||||
|
//pl. POST http://localhost:3001/books TESZTELVE POSTMAN-NEL CATEGORYID-T FRONTENDTŐL KAPJUK
|
||||||
|
/*
|
||||||
|
body-ba:
|
||||||
|
{
|
||||||
|
|
||||||
|
"author":"Jóósasdka",
|
||||||
|
"title":"Egy asascím",
|
||||||
|
"publisher":"Mitsaastomén",
|
||||||
|
"the_year_of_publishing":1111,
|
||||||
|
"description":"Blablablallvbllaslasla",
|
||||||
|
"language":"magyar",
|
||||||
|
"number_of_pages":666,
|
||||||
|
"cover":"puha",
|
||||||
|
"weight":280,
|
||||||
|
"ISBN":1234567891234,
|
||||||
|
"itemcode":780,
|
||||||
|
"price":3334533,
|
||||||
|
"discounted_price":22232,
|
||||||
|
"book_url ":"",
|
||||||
|
"categoryID":"3"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
app.post("/books", async (req, res)=> {
|
||||||
|
const response = await b.addBook(req.body, req.cookies.userID, req.cookies.isAdmin);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Könyv módosítása
|
||||||
|
//pl. PUT http://localhost:3001/books/81 TESZTELVE POSTMAN-NEL
|
||||||
|
/*
|
||||||
|
body-ba:
|
||||||
|
{
|
||||||
|
"author":"MÓDOSÍTOTT",
|
||||||
|
"title":"MÓDOSÍTOTT",
|
||||||
|
"publisher":"MÓDOSÍTOTT",
|
||||||
|
"the_year_of_publishing":1111,
|
||||||
|
"description":"MÓDOSÍTOTTBlablablallvbllaslasla",
|
||||||
|
"language":"magyar",
|
||||||
|
"number_of_pages":666,
|
||||||
|
"cover":"puha",
|
||||||
|
"weight":280,
|
||||||
|
"ISBN":1234567891234,
|
||||||
|
"itemcode":780,
|
||||||
|
"price":3334533,
|
||||||
|
"discounted_price":22232,
|
||||||
|
"book_url ":""
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.put("/books/:id", async (req, res)=> {
|
||||||
|
const books = req.body;
|
||||||
|
books.bookID = req.params.id;
|
||||||
|
|
||||||
|
const response = await b.updateBook(books, req.cookies.userID, req.cookies.isAdmin);
|
||||||
|
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Könyv keresés név kezdőbetű alapján
|
||||||
|
//pl. http://localhost:3001/books/search/p TESZTELVE POSTMAN-NEL
|
||||||
|
|
||||||
|
app.get("/books/search/:char", async (req, res)=> {
|
||||||
|
const response = await b.serchBooks(req.params.char);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/regisztracio", async(req, res)=> { //TESZTELVE
|
||||||
|
try {
|
||||||
|
const response = await u.register(req.body);
|
||||||
|
|
||||||
|
res.status(response.status).json(response.messages);
|
||||||
|
} catch(err) {
|
||||||
|
res.status(err.status).json(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/belepes", async (req, res)=> { //TESZTELVE
|
||||||
|
try {
|
||||||
|
const response = await u.login(req.body, res);
|
||||||
|
res.status(response.status).json(response.messages);
|
||||||
|
} catch(err) {
|
||||||
|
res.status(err.status).json(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Jelszó módosítása ha létezik a user táblában az emailcím
|
||||||
|
//pl. PUT http://localhost:3001/resetpass
|
||||||
|
|
||||||
|
/*body-ba:
|
||||||
|
{
|
||||||
|
"email":"fek94688@ilebi.com",
|
||||||
|
"pass":"alma"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.put("/resetpass", async (req, res)=> { //POSTMAN-NEL TESZTELVE
|
||||||
|
const response = await u.resetPass(req.body);
|
||||||
|
res.status(response.status).json(response.messages);
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
//Összes kölcsönzött könyv lekérése + INNER JOINNAL szerepel benne a könyv címe és a user neve is
|
||||||
|
//pl. http://localhost:3001/admin/borrowedbooks //POSTMAN-NEL TESZTELVE
|
||||||
|
|
||||||
|
app.get("/admin/borrowedbooks", async (req, res)=> {
|
||||||
|
const response = await bo.getBorBooks();
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//userID alapján a kikölcsönzött könyvek megjelenításe - userID-hoz általában az admin fér hozzá, ezért úgy állítottam be hogy az isAdmin értéke 1 legyen
|
||||||
|
//+ INNER JOINNAL szerepel benne a könyv címe és a user neve is
|
||||||
|
|
||||||
|
//pl. http://localhost:3001/admin/borrows/user/1 //POSTMAN-NEL TESZTELVE
|
||||||
|
|
||||||
|
app.get("/admin/borrows/user/:id", async (req, res)=> {
|
||||||
|
const response = await bo.getBorrowsByUserID(req.params.id, req.cookies.isAdmin);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//cartID alapján a kikölcsönzött könyvek megjelenításe - cartID-hoz általában az admin fér hozzá, ezért úgy állítottam be hogy az isAdmin értéke 1 legyen
|
||||||
|
//+ INNER JOINNAL szerepel benne a könyv címe és a user neve is
|
||||||
|
|
||||||
|
//pl. http://localhost:3001/admin/borrows/cart/17 //POSTMAN-NEL TESZTELVE
|
||||||
|
|
||||||
|
app.get("/admin/borrows/cart/:id", async (req, res)=> {
|
||||||
|
const response = await bo.getBorrowsByCartID(req.params.id, req.cookies.userID, req.cookies.isAdmin);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//UserID alapján, csak a USER saját megrendeléseit látja!!!!(!!!!!!a UserID a cookies - ból jön így a belépett felhasználó csak a saját rendeléseit listáztathatja ki) a kikölcsönzött könyvek megjelenítése + INNER JOINNAL szerepel benne a könyv neve is nem csak a BookID; UserID a cookieból jön!!!
|
||||||
|
//pl. http://localhost:3001/user/borrows //POSTMAN-NEL TESZTELVE
|
||||||
|
|
||||||
|
app.get("/user/borrows", async (req, res)=> {
|
||||||
|
const response = await bo.getBorrowsByUser(req.cookies.userID);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Könykölcsönzés felvitele
|
||||||
|
//pl.POST http://localhost:3001/borrows //POSTMAN-NEL TESZTELVE - KEZELI AZT IS HA KÉTSZER AKARJA KIVENNI A KÖNYVET ÉS MÉG NEM VITTE VISSZA
|
||||||
|
|
||||||
|
/*
|
||||||
|
body-ba:
|
||||||
|
{
|
||||||
|
"bookID":"3",
|
||||||
|
"cartID":"17", //frontend oldaról jön ezért nem autoincrement
|
||||||
|
"end_of_borrowment":"2024-12-21",
|
||||||
|
"quantity":"1",
|
||||||
|
"start_of_borrowment":"2024-12-18"
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
app.post("/borrows", async (req, res)=> { //userID a cookies-ból jön!!!!!! a belépett felhasználó tud csak kölcsönözni, cartID a megbeszéltek szerint a frontendről jön és nem autoincrement
|
||||||
|
const borrowData = req.body.borrowbooks;
|
||||||
|
console.log(borrowData[0]);
|
||||||
|
borrowData.userID = req.cookies.userID;
|
||||||
|
console.log(borrowData.userID);
|
||||||
|
console.log(typeof(borrowData.userID));
|
||||||
|
const response = await bo.addBorrow(borrowData);
|
||||||
|
res.clearCookie("userID");
|
||||||
|
res.clearCookie("isAdmin");
|
||||||
|
res.clearCookie("email");
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Kölcsönzések módosítása (a megbeszéltek alapján a bringedBAck értékét 1-re módosítani) cartID alapján
|
||||||
|
//pl. PUT http://localhost:3001/admin/borrows/cart/19 //POSTMAN-NEL TESZTELVE - Ha nem talál rendelésazonosító alapján hibát jelez
|
||||||
|
|
||||||
|
/*
|
||||||
|
body-ba:
|
||||||
|
{
|
||||||
|
"bringedBack":"1" "
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.put("/admin/borrows/cart/:id", async (req, res)=> {
|
||||||
|
const order = req.body;
|
||||||
|
order.cartID = req.params.id;
|
||||||
|
const response = await bo.updateOrder(order,req.cookies.isAdmin);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Kölcsönzés törlése cartID alapján
|
||||||
|
//pl. DELETE http://localhost:3001/admin/borrows/cart/19 //POSTMAN-NEL TESZTELVE - Ha nem talál rendelésazonosító alapján hibát jelez
|
||||||
|
|
||||||
|
app.delete("/admin/borrows/cart/:id", async (req, res)=> {
|
||||||
|
const response = await bo.deleteOrder(
|
||||||
|
req.params.id,
|
||||||
|
req.cookies.userID,
|
||||||
|
req.cookies.isAdmin
|
||||||
|
);
|
||||||
|
|
||||||
|
res.status(response.status).send(response.messages)
|
||||||
|
});
|
||||||
|
|
||||||
|
//USER törlése a user táblából
|
||||||
|
//pl. DELETE http://localhost:3001/admin/users/23 //POSTMAN-NEL TESZTELVE - Ha nem talál USERID alapján hibát jelez
|
||||||
|
|
||||||
|
app.delete("/admin/users/:id", async (req, res)=> {
|
||||||
|
const response = await u.deleteUser(
|
||||||
|
req.params.id,
|
||||||
|
req.cookies.userID,
|
||||||
|
req.cookies.isAdmin
|
||||||
|
);
|
||||||
|
res.status(response.status).send(response.messages)
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//Összes user lekérése adminként
|
||||||
|
//pl. GET http://localhost:3001/admin/users //POSTMAN-NEL TESZTELVE - Jogosultságot ellenőriz!
|
||||||
|
|
||||||
|
app.get("/admin/users", async (req, res)=> {
|
||||||
|
const response = await u.getUsers(req.cookies.isAdmin);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//User keresés név kezdőbetű alapján
|
||||||
|
//pl. http://localhost:3001/admin/users/search/p TESZTELVE POSTMAN-NEL
|
||||||
|
|
||||||
|
app.get("/admin/users/search/:char", async (req, res)=> {
|
||||||
|
const response = await u.searchUsers(req.params.char);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
//User adatainak kilistázása cookies-ból
|
||||||
|
//pl http://localhost:3001/user //FONTOS, HOGY BE LEGYEN JELENTKEZVE MERT SÜTIBŐL SZEDI A USERID-T - POSTMAN-NEL TESZTELVE
|
||||||
|
app.get("/user", async (req, res)=> {
|
||||||
|
const response = await u.getProfile(req.cookies.userID);
|
||||||
|
res.status(response.status).send(response.messages);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app.listen(3001, ()=>{console.log("Az alkalmazás a 3001-es porton fut! 😎")});
|
12
backend_konyvkolcsonzo_v5/node_modules/.bin/mime
generated
vendored
Normal file
12
backend_konyvkolcsonzo_v5/node_modules/.bin/mime
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../mime/cli.js" "$@"
|
||||||
|
fi
|
17
backend_konyvkolcsonzo_v5/node_modules/.bin/mime.cmd
generated
vendored
Normal file
17
backend_konyvkolcsonzo_v5/node_modules/.bin/mime.cmd
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
|
28
backend_konyvkolcsonzo_v5/node_modules/.bin/mime.ps1
generated
vendored
Normal file
28
backend_konyvkolcsonzo_v5/node_modules/.bin/mime.ps1
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
12
backend_konyvkolcsonzo_v5/node_modules/.bin/nodemon
generated
vendored
Normal file
12
backend_konyvkolcsonzo_v5/node_modules/.bin/nodemon
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../nodemon/bin/nodemon.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../nodemon/bin/nodemon.js" "$@"
|
||||||
|
fi
|
17
backend_konyvkolcsonzo_v5/node_modules/.bin/nodemon.cmd
generated
vendored
Normal file
17
backend_konyvkolcsonzo_v5/node_modules/.bin/nodemon.cmd
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nodemon\bin\nodemon.js" %*
|
28
backend_konyvkolcsonzo_v5/node_modules/.bin/nodemon.ps1
generated
vendored
Normal file
28
backend_konyvkolcsonzo_v5/node_modules/.bin/nodemon.ps1
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
12
backend_konyvkolcsonzo_v5/node_modules/.bin/nodetouch
generated
vendored
Normal file
12
backend_konyvkolcsonzo_v5/node_modules/.bin/nodetouch
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../touch/bin/nodetouch.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../touch/bin/nodetouch.js" "$@"
|
||||||
|
fi
|
17
backend_konyvkolcsonzo_v5/node_modules/.bin/nodetouch.cmd
generated
vendored
Normal file
17
backend_konyvkolcsonzo_v5/node_modules/.bin/nodetouch.cmd
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\touch\bin\nodetouch.js" %*
|
28
backend_konyvkolcsonzo_v5/node_modules/.bin/nodetouch.ps1
generated
vendored
Normal file
28
backend_konyvkolcsonzo_v5/node_modules/.bin/nodetouch.ps1
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
12
backend_konyvkolcsonzo_v5/node_modules/.bin/nopt
generated
vendored
Normal file
12
backend_konyvkolcsonzo_v5/node_modules/.bin/nopt
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../nopt/bin/nopt.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../nopt/bin/nopt.js" "$@"
|
||||||
|
fi
|
17
backend_konyvkolcsonzo_v5/node_modules/.bin/nopt.cmd
generated
vendored
Normal file
17
backend_konyvkolcsonzo_v5/node_modules/.bin/nopt.cmd
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nopt\bin\nopt.js" %*
|
28
backend_konyvkolcsonzo_v5/node_modules/.bin/nopt.ps1
generated
vendored
Normal file
28
backend_konyvkolcsonzo_v5/node_modules/.bin/nopt.ps1
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
12
backend_konyvkolcsonzo_v5/node_modules/.bin/semver
generated
vendored
Normal file
12
backend_konyvkolcsonzo_v5/node_modules/.bin/semver
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../semver/bin/semver.js" "$@"
|
||||||
|
fi
|
17
backend_konyvkolcsonzo_v5/node_modules/.bin/semver.cmd
generated
vendored
Normal file
17
backend_konyvkolcsonzo_v5/node_modules/.bin/semver.cmd
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %*
|
28
backend_konyvkolcsonzo_v5/node_modules/.bin/semver.ps1
generated
vendored
Normal file
28
backend_konyvkolcsonzo_v5/node_modules/.bin/semver.ps1
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
1176
backend_konyvkolcsonzo_v5/node_modules/.package-lock.json
generated
vendored
Normal file
1176
backend_konyvkolcsonzo_v5/node_modules/.package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
46
backend_konyvkolcsonzo_v5/node_modules/abbrev/LICENSE
generated
vendored
Normal file
46
backend_konyvkolcsonzo_v5/node_modules/abbrev/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
This software is dual-licensed under the ISC and MIT licenses.
|
||||||
|
You may use this software under EITHER of the following licenses.
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
The ISC License
|
||||||
|
|
||||||
|
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||||
|
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
Copyright Isaac Z. Schlueter and Contributors
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
23
backend_konyvkolcsonzo_v5/node_modules/abbrev/README.md
generated
vendored
Normal file
23
backend_konyvkolcsonzo_v5/node_modules/abbrev/README.md
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# abbrev-js
|
||||||
|
|
||||||
|
Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
var abbrev = require("abbrev");
|
||||||
|
abbrev("foo", "fool", "folding", "flop");
|
||||||
|
|
||||||
|
// returns:
|
||||||
|
{ fl: 'flop'
|
||||||
|
, flo: 'flop'
|
||||||
|
, flop: 'flop'
|
||||||
|
, fol: 'folding'
|
||||||
|
, fold: 'folding'
|
||||||
|
, foldi: 'folding'
|
||||||
|
, foldin: 'folding'
|
||||||
|
, folding: 'folding'
|
||||||
|
, foo: 'foo'
|
||||||
|
, fool: 'fool'
|
||||||
|
}
|
||||||
|
|
||||||
|
This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
|
61
backend_konyvkolcsonzo_v5/node_modules/abbrev/abbrev.js
generated
vendored
Normal file
61
backend_konyvkolcsonzo_v5/node_modules/abbrev/abbrev.js
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
module.exports = exports = abbrev.abbrev = abbrev
|
||||||
|
|
||||||
|
abbrev.monkeyPatch = monkeyPatch
|
||||||
|
|
||||||
|
function monkeyPatch () {
|
||||||
|
Object.defineProperty(Array.prototype, 'abbrev', {
|
||||||
|
value: function () { return abbrev(this) },
|
||||||
|
enumerable: false, configurable: true, writable: true
|
||||||
|
})
|
||||||
|
|
||||||
|
Object.defineProperty(Object.prototype, 'abbrev', {
|
||||||
|
value: function () { return abbrev(Object.keys(this)) },
|
||||||
|
enumerable: false, configurable: true, writable: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function abbrev (list) {
|
||||||
|
if (arguments.length !== 1 || !Array.isArray(list)) {
|
||||||
|
list = Array.prototype.slice.call(arguments, 0)
|
||||||
|
}
|
||||||
|
for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
|
||||||
|
args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort them lexicographically, so that they're next to their nearest kin
|
||||||
|
args = args.sort(lexSort)
|
||||||
|
|
||||||
|
// walk through each, seeing how much it has in common with the next and previous
|
||||||
|
var abbrevs = {}
|
||||||
|
, prev = ""
|
||||||
|
for (var i = 0, l = args.length ; i < l ; i ++) {
|
||||||
|
var current = args[i]
|
||||||
|
, next = args[i + 1] || ""
|
||||||
|
, nextMatches = true
|
||||||
|
, prevMatches = true
|
||||||
|
if (current === next) continue
|
||||||
|
for (var j = 0, cl = current.length ; j < cl ; j ++) {
|
||||||
|
var curChar = current.charAt(j)
|
||||||
|
nextMatches = nextMatches && curChar === next.charAt(j)
|
||||||
|
prevMatches = prevMatches && curChar === prev.charAt(j)
|
||||||
|
if (!nextMatches && !prevMatches) {
|
||||||
|
j ++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev = current
|
||||||
|
if (j === cl) {
|
||||||
|
abbrevs[current] = current
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for (var a = current.substr(0, j) ; j <= cl ; j ++) {
|
||||||
|
abbrevs[a] = current
|
||||||
|
a += current.charAt(j)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return abbrevs
|
||||||
|
}
|
||||||
|
|
||||||
|
function lexSort (a, b) {
|
||||||
|
return a === b ? 0 : a > b ? 1 : -1
|
||||||
|
}
|
21
backend_konyvkolcsonzo_v5/node_modules/abbrev/package.json
generated
vendored
Normal file
21
backend_konyvkolcsonzo_v5/node_modules/abbrev/package.json
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "abbrev",
|
||||||
|
"version": "1.1.1",
|
||||||
|
"description": "Like ruby's abbrev module, but in js",
|
||||||
|
"author": "Isaac Z. Schlueter <i@izs.me>",
|
||||||
|
"main": "abbrev.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "tap test.js --100",
|
||||||
|
"preversion": "npm test",
|
||||||
|
"postversion": "npm publish",
|
||||||
|
"postpublish": "git push origin --all; git push origin --tags"
|
||||||
|
},
|
||||||
|
"repository": "http://github.com/isaacs/abbrev-js",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"tap": "^10.1"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"abbrev.js"
|
||||||
|
]
|
||||||
|
}
|
243
backend_konyvkolcsonzo_v5/node_modules/accepts/HISTORY.md
generated
vendored
Normal file
243
backend_konyvkolcsonzo_v5/node_modules/accepts/HISTORY.md
generated
vendored
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
1.3.8 / 2022-02-02
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.34
|
||||||
|
- deps: mime-db@~1.51.0
|
||||||
|
* deps: negotiator@0.6.3
|
||||||
|
|
||||||
|
1.3.7 / 2019-04-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.6.2
|
||||||
|
- Fix sorting charset, encoding, and language with extra parameters
|
||||||
|
|
||||||
|
1.3.6 / 2019-04-28
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.24
|
||||||
|
- deps: mime-db@~1.40.0
|
||||||
|
|
||||||
|
1.3.5 / 2018-02-28
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.18
|
||||||
|
- deps: mime-db@~1.33.0
|
||||||
|
|
||||||
|
1.3.4 / 2017-08-22
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.16
|
||||||
|
- deps: mime-db@~1.29.0
|
||||||
|
|
||||||
|
1.3.3 / 2016-05-02
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.11
|
||||||
|
- deps: mime-db@~1.23.0
|
||||||
|
* deps: negotiator@0.6.1
|
||||||
|
- perf: improve `Accept` parsing speed
|
||||||
|
- perf: improve `Accept-Charset` parsing speed
|
||||||
|
- perf: improve `Accept-Encoding` parsing speed
|
||||||
|
- perf: improve `Accept-Language` parsing speed
|
||||||
|
|
||||||
|
1.3.2 / 2016-03-08
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.10
|
||||||
|
- Fix extension of `application/dash+xml`
|
||||||
|
- Update primary extension for `audio/mp4`
|
||||||
|
- deps: mime-db@~1.22.0
|
||||||
|
|
||||||
|
1.3.1 / 2016-01-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.9
|
||||||
|
- deps: mime-db@~1.21.0
|
||||||
|
|
||||||
|
1.3.0 / 2015-09-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.7
|
||||||
|
- deps: mime-db@~1.19.0
|
||||||
|
* deps: negotiator@0.6.0
|
||||||
|
- Fix including type extensions in parameters in `Accept` parsing
|
||||||
|
- Fix parsing `Accept` parameters with quoted equals
|
||||||
|
- Fix parsing `Accept` parameters with quoted semicolons
|
||||||
|
- Lazy-load modules from main entry point
|
||||||
|
- perf: delay type concatenation until needed
|
||||||
|
- perf: enable strict mode
|
||||||
|
- perf: hoist regular expressions
|
||||||
|
- perf: remove closures getting spec properties
|
||||||
|
- perf: remove a closure from media type parsing
|
||||||
|
- perf: remove property delete from media type parsing
|
||||||
|
|
||||||
|
1.2.13 / 2015-09-06
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.6
|
||||||
|
- deps: mime-db@~1.18.0
|
||||||
|
|
||||||
|
1.2.12 / 2015-07-30
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.4
|
||||||
|
- deps: mime-db@~1.16.0
|
||||||
|
|
||||||
|
1.2.11 / 2015-07-16
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.3
|
||||||
|
- deps: mime-db@~1.15.0
|
||||||
|
|
||||||
|
1.2.10 / 2015-07-01
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.2
|
||||||
|
- deps: mime-db@~1.14.0
|
||||||
|
|
||||||
|
1.2.9 / 2015-06-08
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.1
|
||||||
|
- perf: fix deopt during mapping
|
||||||
|
|
||||||
|
1.2.8 / 2015-06-07
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.0
|
||||||
|
- deps: mime-db@~1.13.0
|
||||||
|
* perf: avoid argument reassignment & argument slice
|
||||||
|
* perf: avoid negotiator recursive construction
|
||||||
|
* perf: enable strict mode
|
||||||
|
* perf: remove unnecessary bitwise operator
|
||||||
|
|
||||||
|
1.2.7 / 2015-05-10
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.5.3
|
||||||
|
- Fix media type parameter matching to be case-insensitive
|
||||||
|
|
||||||
|
1.2.6 / 2015-05-07
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.11
|
||||||
|
- deps: mime-db@~1.9.1
|
||||||
|
* deps: negotiator@0.5.2
|
||||||
|
- Fix comparing media types with quoted values
|
||||||
|
- Fix splitting media types with quoted commas
|
||||||
|
|
||||||
|
1.2.5 / 2015-03-13
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.10
|
||||||
|
- deps: mime-db@~1.8.0
|
||||||
|
|
||||||
|
1.2.4 / 2015-02-14
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Support Node.js 0.6
|
||||||
|
* deps: mime-types@~2.0.9
|
||||||
|
- deps: mime-db@~1.7.0
|
||||||
|
* deps: negotiator@0.5.1
|
||||||
|
- Fix preference sorting to be stable for long acceptable lists
|
||||||
|
|
||||||
|
1.2.3 / 2015-01-31
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.8
|
||||||
|
- deps: mime-db@~1.6.0
|
||||||
|
|
||||||
|
1.2.2 / 2014-12-30
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.7
|
||||||
|
- deps: mime-db@~1.5.0
|
||||||
|
|
||||||
|
1.2.1 / 2014-12-30
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.5
|
||||||
|
- deps: mime-db@~1.3.1
|
||||||
|
|
||||||
|
1.2.0 / 2014-12-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.5.0
|
||||||
|
- Fix list return order when large accepted list
|
||||||
|
- Fix missing identity encoding when q=0 exists
|
||||||
|
- Remove dynamic building of Negotiator class
|
||||||
|
|
||||||
|
1.1.4 / 2014-12-10
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.4
|
||||||
|
- deps: mime-db@~1.3.0
|
||||||
|
|
||||||
|
1.1.3 / 2014-11-09
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.3
|
||||||
|
- deps: mime-db@~1.2.0
|
||||||
|
|
||||||
|
1.1.2 / 2014-10-14
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.4.9
|
||||||
|
- Fix error when media type has invalid parameter
|
||||||
|
|
||||||
|
1.1.1 / 2014-09-28
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.2
|
||||||
|
- deps: mime-db@~1.1.0
|
||||||
|
* deps: negotiator@0.4.8
|
||||||
|
- Fix all negotiations to be case-insensitive
|
||||||
|
- Stable sort preferences of same quality according to client order
|
||||||
|
|
||||||
|
1.1.0 / 2014-09-02
|
||||||
|
==================
|
||||||
|
|
||||||
|
* update `mime-types`
|
||||||
|
|
||||||
|
1.0.7 / 2014-07-04
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fix wrong type returned from `type` when match after unknown extension
|
||||||
|
|
||||||
|
1.0.6 / 2014-06-24
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.4.7
|
||||||
|
|
||||||
|
1.0.5 / 2014-06-20
|
||||||
|
==================
|
||||||
|
|
||||||
|
* fix crash when unknown extension given
|
||||||
|
|
||||||
|
1.0.4 / 2014-06-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* use `mime-types`
|
||||||
|
|
||||||
|
1.0.3 / 2014-06-11
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.4.6
|
||||||
|
- Order by specificity when quality is the same
|
||||||
|
|
||||||
|
1.0.2 / 2014-05-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fix interpretation when header not in request
|
||||||
|
* deps: pin negotiator@0.4.5
|
||||||
|
|
||||||
|
1.0.1 / 2014-01-18
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Identity encoding isn't always acceptable
|
||||||
|
* deps: negotiator@~0.4.0
|
||||||
|
|
||||||
|
1.0.0 / 2013-12-27
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Genesis
|
23
backend_konyvkolcsonzo_v5/node_modules/accepts/LICENSE
generated
vendored
Normal file
23
backend_konyvkolcsonzo_v5/node_modules/accepts/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
|
||||||
|
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
'Software'), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
140
backend_konyvkolcsonzo_v5/node_modules/accepts/README.md
generated
vendored
Normal file
140
backend_konyvkolcsonzo_v5/node_modules/accepts/README.md
generated
vendored
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
# accepts
|
||||||
|
|
||||||
|
[![NPM Version][npm-version-image]][npm-url]
|
||||||
|
[![NPM Downloads][npm-downloads-image]][npm-url]
|
||||||
|
[![Node.js Version][node-version-image]][node-version-url]
|
||||||
|
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
|
||||||
|
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||||
|
|
||||||
|
Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
|
||||||
|
Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
|
||||||
|
|
||||||
|
In addition to negotiator, it allows:
|
||||||
|
|
||||||
|
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
|
||||||
|
as well as `('text/html', 'application/json')`.
|
||||||
|
- Allows type shorthands such as `json`.
|
||||||
|
- Returns `false` when no types match
|
||||||
|
- Treats non-existent headers as `*`
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
This is a [Node.js](https://nodejs.org/en/) module available through the
|
||||||
|
[npm registry](https://www.npmjs.com/). Installation is done using the
|
||||||
|
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ npm install accepts
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
```js
|
||||||
|
var accepts = require('accepts')
|
||||||
|
```
|
||||||
|
|
||||||
|
### accepts(req)
|
||||||
|
|
||||||
|
Create a new `Accepts` object for the given `req`.
|
||||||
|
|
||||||
|
#### .charset(charsets)
|
||||||
|
|
||||||
|
Return the first accepted charset. If nothing in `charsets` is accepted,
|
||||||
|
then `false` is returned.
|
||||||
|
|
||||||
|
#### .charsets()
|
||||||
|
|
||||||
|
Return the charsets that the request accepts, in the order of the client's
|
||||||
|
preference (most preferred first).
|
||||||
|
|
||||||
|
#### .encoding(encodings)
|
||||||
|
|
||||||
|
Return the first accepted encoding. If nothing in `encodings` is accepted,
|
||||||
|
then `false` is returned.
|
||||||
|
|
||||||
|
#### .encodings()
|
||||||
|
|
||||||
|
Return the encodings that the request accepts, in the order of the client's
|
||||||
|
preference (most preferred first).
|
||||||
|
|
||||||
|
#### .language(languages)
|
||||||
|
|
||||||
|
Return the first accepted language. If nothing in `languages` is accepted,
|
||||||
|
then `false` is returned.
|
||||||
|
|
||||||
|
#### .languages()
|
||||||
|
|
||||||
|
Return the languages that the request accepts, in the order of the client's
|
||||||
|
preference (most preferred first).
|
||||||
|
|
||||||
|
#### .type(types)
|
||||||
|
|
||||||
|
Return the first accepted type (and it is returned as the same text as what
|
||||||
|
appears in the `types` array). If nothing in `types` is accepted, then `false`
|
||||||
|
is returned.
|
||||||
|
|
||||||
|
The `types` array can contain full MIME types or file extensions. Any value
|
||||||
|
that is not a full MIME types is passed to `require('mime-types').lookup`.
|
||||||
|
|
||||||
|
#### .types()
|
||||||
|
|
||||||
|
Return the types that the request accepts, in the order of the client's
|
||||||
|
preference (most preferred first).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Simple type negotiation
|
||||||
|
|
||||||
|
This simple example shows how to use `accepts` to return a different typed
|
||||||
|
respond body based on what the client wants to accept. The server lists it's
|
||||||
|
preferences in order and will get back the best match between the client and
|
||||||
|
server.
|
||||||
|
|
||||||
|
```js
|
||||||
|
var accepts = require('accepts')
|
||||||
|
var http = require('http')
|
||||||
|
|
||||||
|
function app (req, res) {
|
||||||
|
var accept = accepts(req)
|
||||||
|
|
||||||
|
// the order of this list is significant; should be server preferred order
|
||||||
|
switch (accept.type(['json', 'html'])) {
|
||||||
|
case 'json':
|
||||||
|
res.setHeader('Content-Type', 'application/json')
|
||||||
|
res.write('{"hello":"world!"}')
|
||||||
|
break
|
||||||
|
case 'html':
|
||||||
|
res.setHeader('Content-Type', 'text/html')
|
||||||
|
res.write('<b>hello, world!</b>')
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
// the fallback is text/plain, so no need to specify it above
|
||||||
|
res.setHeader('Content-Type', 'text/plain')
|
||||||
|
res.write('hello, world!')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
res.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
http.createServer(app).listen(3000)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can test this out with the cURL program:
|
||||||
|
```sh
|
||||||
|
curl -I -H'Accept: text/html' http://localhost:3000/
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](LICENSE)
|
||||||
|
|
||||||
|
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master
|
||||||
|
[coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master
|
||||||
|
[github-actions-ci-image]: https://badgen.net/github/checks/jshttp/accepts/master?label=ci
|
||||||
|
[github-actions-ci-url]: https://github.com/jshttp/accepts/actions/workflows/ci.yml
|
||||||
|
[node-version-image]: https://badgen.net/npm/node/accepts
|
||||||
|
[node-version-url]: https://nodejs.org/en/download
|
||||||
|
[npm-downloads-image]: https://badgen.net/npm/dm/accepts
|
||||||
|
[npm-url]: https://npmjs.org/package/accepts
|
||||||
|
[npm-version-image]: https://badgen.net/npm/v/accepts
|
238
backend_konyvkolcsonzo_v5/node_modules/accepts/index.js
generated
vendored
Normal file
238
backend_konyvkolcsonzo_v5/node_modules/accepts/index.js
generated
vendored
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
/*!
|
||||||
|
* accepts
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Negotiator = require('negotiator')
|
||||||
|
var mime = require('mime-types')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module exports.
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = Accepts
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Accepts object for the given req.
|
||||||
|
*
|
||||||
|
* @param {object} req
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Accepts (req) {
|
||||||
|
if (!(this instanceof Accepts)) {
|
||||||
|
return new Accepts(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.headers = req.headers
|
||||||
|
this.negotiator = new Negotiator(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given `type(s)` is acceptable, returning
|
||||||
|
* the best match when true, otherwise `undefined`, in which
|
||||||
|
* case you should respond with 406 "Not Acceptable".
|
||||||
|
*
|
||||||
|
* The `type` value may be a single mime type string
|
||||||
|
* such as "application/json", the extension name
|
||||||
|
* such as "json" or an array `["json", "html", "text/plain"]`. When a list
|
||||||
|
* or array is given the _best_ match, if any is returned.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* // Accept: text/html
|
||||||
|
* this.types('html');
|
||||||
|
* // => "html"
|
||||||
|
*
|
||||||
|
* // Accept: text/*, application/json
|
||||||
|
* this.types('html');
|
||||||
|
* // => "html"
|
||||||
|
* this.types('text/html');
|
||||||
|
* // => "text/html"
|
||||||
|
* this.types('json', 'text');
|
||||||
|
* // => "json"
|
||||||
|
* this.types('application/json');
|
||||||
|
* // => "application/json"
|
||||||
|
*
|
||||||
|
* // Accept: text/*, application/json
|
||||||
|
* this.types('image/png');
|
||||||
|
* this.types('png');
|
||||||
|
* // => undefined
|
||||||
|
*
|
||||||
|
* // Accept: text/*;q=.5, application/json
|
||||||
|
* this.types(['html', 'json']);
|
||||||
|
* this.types('html', 'json');
|
||||||
|
* // => "json"
|
||||||
|
*
|
||||||
|
* @param {String|Array} types...
|
||||||
|
* @return {String|Array|Boolean}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Accepts.prototype.type =
|
||||||
|
Accepts.prototype.types = function (types_) {
|
||||||
|
var types = types_
|
||||||
|
|
||||||
|
// support flattened arguments
|
||||||
|
if (types && !Array.isArray(types)) {
|
||||||
|
types = new Array(arguments.length)
|
||||||
|
for (var i = 0; i < types.length; i++) {
|
||||||
|
types[i] = arguments[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no types, return all requested types
|
||||||
|
if (!types || types.length === 0) {
|
||||||
|
return this.negotiator.mediaTypes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// no accept header, return first given type
|
||||||
|
if (!this.headers.accept) {
|
||||||
|
return types[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
var mimes = types.map(extToMime)
|
||||||
|
var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
|
||||||
|
var first = accepts[0]
|
||||||
|
|
||||||
|
return first
|
||||||
|
? types[mimes.indexOf(first)]
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return accepted encodings or best fit based on `encodings`.
|
||||||
|
*
|
||||||
|
* Given `Accept-Encoding: gzip, deflate`
|
||||||
|
* an array sorted by quality is returned:
|
||||||
|
*
|
||||||
|
* ['gzip', 'deflate']
|
||||||
|
*
|
||||||
|
* @param {String|Array} encodings...
|
||||||
|
* @return {String|Array}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Accepts.prototype.encoding =
|
||||||
|
Accepts.prototype.encodings = function (encodings_) {
|
||||||
|
var encodings = encodings_
|
||||||
|
|
||||||
|
// support flattened arguments
|
||||||
|
if (encodings && !Array.isArray(encodings)) {
|
||||||
|
encodings = new Array(arguments.length)
|
||||||
|
for (var i = 0; i < encodings.length; i++) {
|
||||||
|
encodings[i] = arguments[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no encodings, return all requested encodings
|
||||||
|
if (!encodings || encodings.length === 0) {
|
||||||
|
return this.negotiator.encodings()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.negotiator.encodings(encodings)[0] || false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return accepted charsets or best fit based on `charsets`.
|
||||||
|
*
|
||||||
|
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
|
||||||
|
* an array sorted by quality is returned:
|
||||||
|
*
|
||||||
|
* ['utf-8', 'utf-7', 'iso-8859-1']
|
||||||
|
*
|
||||||
|
* @param {String|Array} charsets...
|
||||||
|
* @return {String|Array}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Accepts.prototype.charset =
|
||||||
|
Accepts.prototype.charsets = function (charsets_) {
|
||||||
|
var charsets = charsets_
|
||||||
|
|
||||||
|
// support flattened arguments
|
||||||
|
if (charsets && !Array.isArray(charsets)) {
|
||||||
|
charsets = new Array(arguments.length)
|
||||||
|
for (var i = 0; i < charsets.length; i++) {
|
||||||
|
charsets[i] = arguments[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no charsets, return all requested charsets
|
||||||
|
if (!charsets || charsets.length === 0) {
|
||||||
|
return this.negotiator.charsets()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.negotiator.charsets(charsets)[0] || false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return accepted languages or best fit based on `langs`.
|
||||||
|
*
|
||||||
|
* Given `Accept-Language: en;q=0.8, es, pt`
|
||||||
|
* an array sorted by quality is returned:
|
||||||
|
*
|
||||||
|
* ['es', 'pt', 'en']
|
||||||
|
*
|
||||||
|
* @param {String|Array} langs...
|
||||||
|
* @return {Array|String}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Accepts.prototype.lang =
|
||||||
|
Accepts.prototype.langs =
|
||||||
|
Accepts.prototype.language =
|
||||||
|
Accepts.prototype.languages = function (languages_) {
|
||||||
|
var languages = languages_
|
||||||
|
|
||||||
|
// support flattened arguments
|
||||||
|
if (languages && !Array.isArray(languages)) {
|
||||||
|
languages = new Array(arguments.length)
|
||||||
|
for (var i = 0; i < languages.length; i++) {
|
||||||
|
languages[i] = arguments[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no languages, return all requested languages
|
||||||
|
if (!languages || languages.length === 0) {
|
||||||
|
return this.negotiator.languages()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.negotiator.languages(languages)[0] || false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert extnames to mime.
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @return {String}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function extToMime (type) {
|
||||||
|
return type.indexOf('/') === -1
|
||||||
|
? mime.lookup(type)
|
||||||
|
: type
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if mime is valid.
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @return {String}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function validMime (type) {
|
||||||
|
return typeof type === 'string'
|
||||||
|
}
|
47
backend_konyvkolcsonzo_v5/node_modules/accepts/package.json
generated
vendored
Normal file
47
backend_konyvkolcsonzo_v5/node_modules/accepts/package.json
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"name": "accepts",
|
||||||
|
"description": "Higher-level content negotiation",
|
||||||
|
"version": "1.3.8",
|
||||||
|
"contributors": [
|
||||||
|
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||||
|
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": "jshttp/accepts",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "~2.1.34",
|
||||||
|
"negotiator": "0.6.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"deep-equal": "1.0.1",
|
||||||
|
"eslint": "7.32.0",
|
||||||
|
"eslint-config-standard": "14.1.1",
|
||||||
|
"eslint-plugin-import": "2.25.4",
|
||||||
|
"eslint-plugin-markdown": "2.2.1",
|
||||||
|
"eslint-plugin-node": "11.1.0",
|
||||||
|
"eslint-plugin-promise": "4.3.1",
|
||||||
|
"eslint-plugin-standard": "4.1.0",
|
||||||
|
"mocha": "9.2.0",
|
||||||
|
"nyc": "15.1.0"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"LICENSE",
|
||||||
|
"HISTORY.md",
|
||||||
|
"index.js"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"lint": "eslint .",
|
||||||
|
"test": "mocha --reporter spec --check-leaks --bail test/",
|
||||||
|
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
||||||
|
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"content",
|
||||||
|
"negotiation",
|
||||||
|
"accept",
|
||||||
|
"accepts"
|
||||||
|
]
|
||||||
|
}
|
15
backend_konyvkolcsonzo_v5/node_modules/anymatch/LICENSE
generated
vendored
Normal file
15
backend_konyvkolcsonzo_v5/node_modules/anymatch/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
The ISC License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Elan Shanker, Paul Miller (https://paulmillr.com)
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||||
|
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
87
backend_konyvkolcsonzo_v5/node_modules/anymatch/README.md
generated
vendored
Normal file
87
backend_konyvkolcsonzo_v5/node_modules/anymatch/README.md
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
anymatch [![Build Status](https://travis-ci.org/micromatch/anymatch.svg?branch=master)](https://travis-ci.org/micromatch/anymatch) [![Coverage Status](https://img.shields.io/coveralls/micromatch/anymatch.svg?branch=master)](https://coveralls.io/r/micromatch/anymatch?branch=master)
|
||||||
|
======
|
||||||
|
Javascript module to match a string against a regular expression, glob, string,
|
||||||
|
or function that takes the string as an argument and returns a truthy or falsy
|
||||||
|
value. The matcher can also be an array of any or all of these. Useful for
|
||||||
|
allowing a very flexible user-defined config to define things like file paths.
|
||||||
|
|
||||||
|
__Note: This module has Bash-parity, please be aware that Windows-style backslashes are not supported as separators. See https://github.com/micromatch/micromatch#backslashes for more information.__
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
```sh
|
||||||
|
npm install anymatch
|
||||||
|
```
|
||||||
|
|
||||||
|
#### anymatch(matchers, testString, [returnIndex], [options])
|
||||||
|
* __matchers__: (_Array|String|RegExp|Function_)
|
||||||
|
String to be directly matched, string with glob patterns, regular expression
|
||||||
|
test, function that takes the testString as an argument and returns a truthy
|
||||||
|
value if it should be matched, or an array of any number and mix of these types.
|
||||||
|
* __testString__: (_String|Array_) The string to test against the matchers. If
|
||||||
|
passed as an array, the first element of the array will be used as the
|
||||||
|
`testString` for non-function matchers, while the entire array will be applied
|
||||||
|
as the arguments for function matchers.
|
||||||
|
* __options__: (_Object_ [optional]_) Any of the [picomatch](https://github.com/micromatch/picomatch#options) options.
|
||||||
|
* __returnIndex__: (_Boolean [optional]_) If true, return the array index of
|
||||||
|
the first matcher that that testString matched, or -1 if no match, instead of a
|
||||||
|
boolean result.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const anymatch = require('anymatch');
|
||||||
|
|
||||||
|
const matchers = [ 'path/to/file.js', 'path/anyjs/**/*.js', /foo.js$/, string => string.includes('bar') && string.length > 10 ] ;
|
||||||
|
|
||||||
|
anymatch(matchers, 'path/to/file.js'); // true
|
||||||
|
anymatch(matchers, 'path/anyjs/baz.js'); // true
|
||||||
|
anymatch(matchers, 'path/to/foo.js'); // true
|
||||||
|
anymatch(matchers, 'path/to/bar.js'); // true
|
||||||
|
anymatch(matchers, 'bar.js'); // false
|
||||||
|
|
||||||
|
// returnIndex = true
|
||||||
|
anymatch(matchers, 'foo.js', {returnIndex: true}); // 2
|
||||||
|
anymatch(matchers, 'path/anyjs/foo.js', {returnIndex: true}); // 1
|
||||||
|
|
||||||
|
// any picomatc
|
||||||
|
|
||||||
|
// using globs to match directories and their children
|
||||||
|
anymatch('node_modules', 'node_modules'); // true
|
||||||
|
anymatch('node_modules', 'node_modules/somelib/index.js'); // false
|
||||||
|
anymatch('node_modules/**', 'node_modules/somelib/index.js'); // true
|
||||||
|
anymatch('node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // false
|
||||||
|
anymatch('**/node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // true
|
||||||
|
|
||||||
|
const matcher = anymatch(matchers);
|
||||||
|
['foo.js', 'bar.js'].filter(matcher); // [ 'foo.js' ]
|
||||||
|
anymatch master* ❯
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### anymatch(matchers)
|
||||||
|
You can also pass in only your matcher(s) to get a curried function that has
|
||||||
|
already been bound to the provided matching criteria. This can be used as an
|
||||||
|
`Array#filter` callback.
|
||||||
|
|
||||||
|
```js
|
||||||
|
var matcher = anymatch(matchers);
|
||||||
|
|
||||||
|
matcher('path/to/file.js'); // true
|
||||||
|
matcher('path/anyjs/baz.js', true); // 1
|
||||||
|
|
||||||
|
['foo.js', 'bar.js'].filter(matcher); // ['foo.js']
|
||||||
|
```
|
||||||
|
|
||||||
|
Changelog
|
||||||
|
----------
|
||||||
|
[See release notes page on GitHub](https://github.com/micromatch/anymatch/releases)
|
||||||
|
|
||||||
|
- **v3.0:** Removed `startIndex` and `endIndex` arguments. Node 8.x-only.
|
||||||
|
- **v2.0:** [micromatch](https://github.com/jonschlinkert/micromatch) moves away from minimatch-parity and inline with Bash. This includes handling backslashes differently (see https://github.com/micromatch/micromatch#backslashes for more information).
|
||||||
|
- **v1.2:** anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch)
|
||||||
|
for glob pattern matching. Issues with glob pattern matching should be
|
||||||
|
reported directly to the [micromatch issue tracker](https://github.com/jonschlinkert/micromatch/issues).
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
[ISC](https://raw.github.com/micromatch/anymatch/master/LICENSE)
|
20
backend_konyvkolcsonzo_v5/node_modules/anymatch/index.d.ts
generated
vendored
Normal file
20
backend_konyvkolcsonzo_v5/node_modules/anymatch/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
type AnymatchFn = (testString: string) => boolean;
|
||||||
|
type AnymatchPattern = string|RegExp|AnymatchFn;
|
||||||
|
type AnymatchMatcher = AnymatchPattern|AnymatchPattern[]
|
||||||
|
type AnymatchTester = {
|
||||||
|
(testString: string|any[], returnIndex: true): number;
|
||||||
|
(testString: string|any[]): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
type PicomatchOptions = {dot: boolean};
|
||||||
|
|
||||||
|
declare const anymatch: {
|
||||||
|
(matchers: AnymatchMatcher): AnymatchTester;
|
||||||
|
(matchers: AnymatchMatcher, testString: null, returnIndex: true | PicomatchOptions): AnymatchTester;
|
||||||
|
(matchers: AnymatchMatcher, testString: string|any[], returnIndex: true | PicomatchOptions): number;
|
||||||
|
(matchers: AnymatchMatcher, testString: string|any[]): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {AnymatchMatcher as Matcher}
|
||||||
|
export {AnymatchTester as Tester}
|
||||||
|
export default anymatch
|
104
backend_konyvkolcsonzo_v5/node_modules/anymatch/index.js
generated
vendored
Normal file
104
backend_konyvkolcsonzo_v5/node_modules/anymatch/index.js
generated
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
|
||||||
|
const picomatch = require('picomatch');
|
||||||
|
const normalizePath = require('normalize-path');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {(testString: string) => boolean} AnymatchFn
|
||||||
|
* @typedef {string|RegExp|AnymatchFn} AnymatchPattern
|
||||||
|
* @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher
|
||||||
|
*/
|
||||||
|
const BANG = '!';
|
||||||
|
const DEFAULT_OPTIONS = {returnIndex: false};
|
||||||
|
const arrify = (item) => Array.isArray(item) ? item : [item];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {AnymatchPattern} matcher
|
||||||
|
* @param {object} options
|
||||||
|
* @returns {AnymatchFn}
|
||||||
|
*/
|
||||||
|
const createPattern = (matcher, options) => {
|
||||||
|
if (typeof matcher === 'function') {
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
if (typeof matcher === 'string') {
|
||||||
|
const glob = picomatch(matcher, options);
|
||||||
|
return (string) => matcher === string || glob(string);
|
||||||
|
}
|
||||||
|
if (matcher instanceof RegExp) {
|
||||||
|
return (string) => matcher.test(string);
|
||||||
|
}
|
||||||
|
return (string) => false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array<Function>} patterns
|
||||||
|
* @param {Array<Function>} negPatterns
|
||||||
|
* @param {String|Array} args
|
||||||
|
* @param {Boolean} returnIndex
|
||||||
|
* @returns {boolean|number}
|
||||||
|
*/
|
||||||
|
const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
|
||||||
|
const isList = Array.isArray(args);
|
||||||
|
const _path = isList ? args[0] : args;
|
||||||
|
if (!isList && typeof _path !== 'string') {
|
||||||
|
throw new TypeError('anymatch: second argument must be a string: got ' +
|
||||||
|
Object.prototype.toString.call(_path))
|
||||||
|
}
|
||||||
|
const path = normalizePath(_path, false);
|
||||||
|
|
||||||
|
for (let index = 0; index < negPatterns.length; index++) {
|
||||||
|
const nglob = negPatterns[index];
|
||||||
|
if (nglob(path)) {
|
||||||
|
return returnIndex ? -1 : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const applied = isList && [path].concat(args.slice(1));
|
||||||
|
for (let index = 0; index < patterns.length; index++) {
|
||||||
|
const pattern = patterns[index];
|
||||||
|
if (isList ? pattern(...applied) : pattern(path)) {
|
||||||
|
return returnIndex ? index : true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnIndex ? -1 : false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {AnymatchMatcher} matchers
|
||||||
|
* @param {Array|string} testString
|
||||||
|
* @param {object} options
|
||||||
|
* @returns {boolean|number|Function}
|
||||||
|
*/
|
||||||
|
const anymatch = (matchers, testString, options = DEFAULT_OPTIONS) => {
|
||||||
|
if (matchers == null) {
|
||||||
|
throw new TypeError('anymatch: specify first argument');
|
||||||
|
}
|
||||||
|
const opts = typeof options === 'boolean' ? {returnIndex: options} : options;
|
||||||
|
const returnIndex = opts.returnIndex || false;
|
||||||
|
|
||||||
|
// Early cache for matchers.
|
||||||
|
const mtchers = arrify(matchers);
|
||||||
|
const negatedGlobs = mtchers
|
||||||
|
.filter(item => typeof item === 'string' && item.charAt(0) === BANG)
|
||||||
|
.map(item => item.slice(1))
|
||||||
|
.map(item => picomatch(item, opts));
|
||||||
|
const patterns = mtchers
|
||||||
|
.filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG))
|
||||||
|
.map(matcher => createPattern(matcher, opts));
|
||||||
|
|
||||||
|
if (testString == null) {
|
||||||
|
return (testString, ri = false) => {
|
||||||
|
const returnIndex = typeof ri === 'boolean' ? ri : false;
|
||||||
|
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
anymatch.default = anymatch;
|
||||||
|
module.exports = anymatch;
|
48
backend_konyvkolcsonzo_v5/node_modules/anymatch/package.json
generated
vendored
Normal file
48
backend_konyvkolcsonzo_v5/node_modules/anymatch/package.json
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"name": "anymatch",
|
||||||
|
"version": "3.1.3",
|
||||||
|
"description": "Matches strings against configurable strings, globs, regular expressions, and/or functions",
|
||||||
|
"files": [
|
||||||
|
"index.js",
|
||||||
|
"index.d.ts"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"picomatch": "^2.0.4"
|
||||||
|
},
|
||||||
|
"author": {
|
||||||
|
"name": "Elan Shanker",
|
||||||
|
"url": "https://github.com/es128"
|
||||||
|
},
|
||||||
|
"license": "ISC",
|
||||||
|
"homepage": "https://github.com/micromatch/anymatch",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/micromatch/anymatch"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"match",
|
||||||
|
"any",
|
||||||
|
"string",
|
||||||
|
"file",
|
||||||
|
"fs",
|
||||||
|
"list",
|
||||||
|
"glob",
|
||||||
|
"regex",
|
||||||
|
"regexp",
|
||||||
|
"regular",
|
||||||
|
"expression",
|
||||||
|
"function"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"test": "nyc mocha",
|
||||||
|
"mocha": "mocha"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"mocha": "^6.1.3",
|
||||||
|
"nyc": "^14.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
}
|
21
backend_konyvkolcsonzo_v5/node_modules/array-flatten/LICENSE
generated
vendored
Normal file
21
backend_konyvkolcsonzo_v5/node_modules/array-flatten/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
43
backend_konyvkolcsonzo_v5/node_modules/array-flatten/README.md
generated
vendored
Normal file
43
backend_konyvkolcsonzo_v5/node_modules/array-flatten/README.md
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# Array Flatten
|
||||||
|
|
||||||
|
[![NPM version][npm-image]][npm-url]
|
||||||
|
[![NPM downloads][downloads-image]][downloads-url]
|
||||||
|
[![Build status][travis-image]][travis-url]
|
||||||
|
[![Test coverage][coveralls-image]][coveralls-url]
|
||||||
|
|
||||||
|
> Flatten an array of nested arrays into a single flat array. Accepts an optional depth.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install array-flatten --save
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var flatten = require('array-flatten')
|
||||||
|
|
||||||
|
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9])
|
||||||
|
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
|
||||||
|
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9], 2)
|
||||||
|
//=> [1, 2, 3, [4, [5], 6], 7, 8, 9]
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
flatten(arguments) //=> [1, 2, 3]
|
||||||
|
})(1, [2, 3])
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|
||||||
|
[npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat
|
||||||
|
[npm-url]: https://npmjs.org/package/array-flatten
|
||||||
|
[downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat
|
||||||
|
[downloads-url]: https://npmjs.org/package/array-flatten
|
||||||
|
[travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat
|
||||||
|
[travis-url]: https://travis-ci.org/blakeembrey/array-flatten
|
||||||
|
[coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat
|
||||||
|
[coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master
|
64
backend_konyvkolcsonzo_v5/node_modules/array-flatten/array-flatten.js
generated
vendored
Normal file
64
backend_konyvkolcsonzo_v5/node_modules/array-flatten/array-flatten.js
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `arrayFlatten`.
|
||||||
|
*/
|
||||||
|
module.exports = arrayFlatten
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive flatten function with depth.
|
||||||
|
*
|
||||||
|
* @param {Array} array
|
||||||
|
* @param {Array} result
|
||||||
|
* @param {Number} depth
|
||||||
|
* @return {Array}
|
||||||
|
*/
|
||||||
|
function flattenWithDepth (array, result, depth) {
|
||||||
|
for (var i = 0; i < array.length; i++) {
|
||||||
|
var value = array[i]
|
||||||
|
|
||||||
|
if (depth > 0 && Array.isArray(value)) {
|
||||||
|
flattenWithDepth(value, result, depth - 1)
|
||||||
|
} else {
|
||||||
|
result.push(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive flatten function. Omitting depth is slightly faster.
|
||||||
|
*
|
||||||
|
* @param {Array} array
|
||||||
|
* @param {Array} result
|
||||||
|
* @return {Array}
|
||||||
|
*/
|
||||||
|
function flattenForever (array, result) {
|
||||||
|
for (var i = 0; i < array.length; i++) {
|
||||||
|
var value = array[i]
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
flattenForever(value, result)
|
||||||
|
} else {
|
||||||
|
result.push(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten an array, with the ability to define a depth.
|
||||||
|
*
|
||||||
|
* @param {Array} array
|
||||||
|
* @param {Number} depth
|
||||||
|
* @return {Array}
|
||||||
|
*/
|
||||||
|
function arrayFlatten (array, depth) {
|
||||||
|
if (depth == null) {
|
||||||
|
return flattenForever(array, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
return flattenWithDepth(array, [], depth)
|
||||||
|
}
|
39
backend_konyvkolcsonzo_v5/node_modules/array-flatten/package.json
generated
vendored
Normal file
39
backend_konyvkolcsonzo_v5/node_modules/array-flatten/package.json
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"name": "array-flatten",
|
||||||
|
"version": "1.1.1",
|
||||||
|
"description": "Flatten an array of nested arrays into a single flat array",
|
||||||
|
"main": "array-flatten.js",
|
||||||
|
"files": [
|
||||||
|
"array-flatten.js",
|
||||||
|
"LICENSE"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"test": "istanbul cover _mocha -- -R spec"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/blakeembrey/array-flatten.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"array",
|
||||||
|
"flatten",
|
||||||
|
"arguments",
|
||||||
|
"depth"
|
||||||
|
],
|
||||||
|
"author": {
|
||||||
|
"name": "Blake Embrey",
|
||||||
|
"email": "hello@blakeembrey.com",
|
||||||
|
"url": "http://blakeembrey.me"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/blakeembrey/array-flatten/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/blakeembrey/array-flatten",
|
||||||
|
"devDependencies": {
|
||||||
|
"istanbul": "^0.3.13",
|
||||||
|
"mocha": "^2.2.4",
|
||||||
|
"pre-commit": "^1.0.7",
|
||||||
|
"standard": "^3.7.3"
|
||||||
|
}
|
||||||
|
}
|
2
backend_konyvkolcsonzo_v5/node_modules/balanced-match/.github/FUNDING.yml
generated
vendored
Normal file
2
backend_konyvkolcsonzo_v5/node_modules/balanced-match/.github/FUNDING.yml
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
tidelift: "npm/balanced-match"
|
||||||
|
patreon: juliangruber
|
21
backend_konyvkolcsonzo_v5/node_modules/balanced-match/LICENSE.md
generated
vendored
Normal file
21
backend_konyvkolcsonzo_v5/node_modules/balanced-match/LICENSE.md
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
(MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
97
backend_konyvkolcsonzo_v5/node_modules/balanced-match/README.md
generated
vendored
Normal file
97
backend_konyvkolcsonzo_v5/node_modules/balanced-match/README.md
generated
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
# balanced-match
|
||||||
|
|
||||||
|
Match balanced string pairs, like `{` and `}` or `<b>` and `</b>`. Supports regular expressions as well!
|
||||||
|
|
||||||
|
[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match)
|
||||||
|
[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match)
|
||||||
|
|
||||||
|
[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match)
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Get the first matching pair of braces:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var balanced = require('balanced-match');
|
||||||
|
|
||||||
|
console.log(balanced('{', '}', 'pre{in{nested}}post'));
|
||||||
|
console.log(balanced('{', '}', 'pre{first}between{second}post'));
|
||||||
|
console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post'));
|
||||||
|
```
|
||||||
|
|
||||||
|
The matches are:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ node example.js
|
||||||
|
{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' }
|
||||||
|
{ start: 3,
|
||||||
|
end: 9,
|
||||||
|
pre: 'pre',
|
||||||
|
body: 'first',
|
||||||
|
post: 'between{second}post' }
|
||||||
|
{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' }
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### var m = balanced(a, b, str)
|
||||||
|
|
||||||
|
For the first non-nested matching pair of `a` and `b` in `str`, return an
|
||||||
|
object with those keys:
|
||||||
|
|
||||||
|
* **start** the index of the first match of `a`
|
||||||
|
* **end** the index of the matching `b`
|
||||||
|
* **pre** the preamble, `a` and `b` not included
|
||||||
|
* **body** the match, `a` and `b` not included
|
||||||
|
* **post** the postscript, `a` and `b` not included
|
||||||
|
|
||||||
|
If there's no match, `undefined` will be returned.
|
||||||
|
|
||||||
|
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`.
|
||||||
|
|
||||||
|
### var r = balanced.range(a, b, str)
|
||||||
|
|
||||||
|
For the first non-nested matching pair of `a` and `b` in `str`, return an
|
||||||
|
array with indexes: `[ <a index>, <b index> ]`.
|
||||||
|
|
||||||
|
If there's no match, `undefined` will be returned.
|
||||||
|
|
||||||
|
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
With [npm](https://npmjs.org) do:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install balanced-match
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security contact information
|
||||||
|
|
||||||
|
To report a security vulnerability, please use the
|
||||||
|
[Tidelift security contact](https://tidelift.com/security).
|
||||||
|
Tidelift will coordinate the fix and disclosure.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
(MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user