diff --git a/API/main.py b/API/main.py index 5ebb89c..38e4b6e 100644 --- a/API/main.py +++ b/API/main.py @@ -5,10 +5,13 @@ import jwt from data.connect import init_db, connect, User, Document, DocumentCategory, Comment from flask import Flask, Response, request, jsonify +from flask_cors import CORS app = Flask(__name__) app.config['SECRET_KEY'] = 'jyeraghueykgaeyugheaughkawefy' +CORS(app) + @app.route('/api/v1/SignIn', methods=['POST']) def login(): @@ -249,6 +252,46 @@ def protected(): return jsonify({'message': 'Invalid token!'}), 401 +@app.route('/employees') +def get_employee_list(): + resp = [] + + months = { + 1: 'января', + 2: 'февраля', + 3: 'марта', + 4: 'апреля', + 5: 'мая', + 6: 'июня', + 7: 'июля', + 8: 'августа', + 9: 'сентября', + 10: 'октября', + 11: 'ноября', + 12: 'декабря' + } + + with connect() as session: + employees = session.query(User).all() + + for employee in employees: + resp.append( + { + 'id': employee.id, + 'first_name': employee.first_name, + 'last_name': employee.last_name, + 'patronymic': employee.patronymic, + 'email': employee.email, + 'phone': employee.work_phone, + 'post': employee.post.title, + 'birthday': f'{str(employee.birthday.day)} {months[employee.birthday.month]}' + } + ) + + + return resp + + def main(): init_db() app.run() diff --git a/WEB/app/package-lock.json b/WEB/app/package-lock.json index 3116a56..e70ac5a 100644 --- a/WEB/app/package-lock.json +++ b/WEB/app/package-lock.json @@ -10,7 +10,8 @@ "dependencies": { "next": "15.1.5", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "react-qr-code": "^2.0.15" }, "devDependencies": { "postcss": "^8", @@ -1227,6 +1228,12 @@ "jiti": "bin/jiti.js" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -1247,6 +1254,18 @@ "dev": true, "license": "MIT" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -1430,7 +1449,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -1676,6 +1694,23 @@ "dev": true, "license": "MIT" }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/qr.js": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz", + "integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==", + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -1718,6 +1753,25 @@ "react": "^19.0.0" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-qr-code": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.15.tgz", + "integrity": "sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.8.1", + "qr.js": "0.0.0" + }, + "peerDependencies": { + "react": "*" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/WEB/app/package.json b/WEB/app/package.json index fe5feac..4d6a10a 100644 --- a/WEB/app/package.json +++ b/WEB/app/package.json @@ -9,9 +9,10 @@ "lint": "next lint" }, "dependencies": { + "next": "15.1.5", "react": "^19.0.0", "react-dom": "^19.0.0", - "next": "15.1.5" + "react-qr-code": "^2.0.15" }, "devDependencies": { "postcss": "^8", diff --git a/WEB/app/src/app/app.css b/WEB/app/src/app/app.css index 4bc2597..e3708d5 100644 --- a/WEB/app/src/app/app.css +++ b/WEB/app/src/app/app.css @@ -24,5 +24,47 @@ .user-list { margin: 2vw; - border: 1px solid black; +} + +.employee-card { + min-width: 250px; + height: 200px; + background-color: #2f9836; + + padding: 1vw; + display: flex; + flex-direction: column; + justify-content: space-around; + margin: 2px; +} + +.row { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + +.fio { + margin-right: 5px; + font-size: x-large; + font-weight: bold; + color: white; +} + +.employee-text { + font-size: large; + margin-top: 3px; + color: white; +} + +.user-row-list { + display: flex; + flex-direction: row; + overflow-x: scroll; +} + +.row-qr { + display: flex; + flex-direction: row; + justify-content: space-between; } \ No newline at end of file diff --git a/WEB/app/src/app/components/employee-card.js b/WEB/app/src/app/components/employee-card.js new file mode 100644 index 0000000..bfbd799 --- /dev/null +++ b/WEB/app/src/app/components/employee-card.js @@ -0,0 +1,74 @@ +'use client'; + +import { useState } from "react"; +import QRCode from "react-qr-code"; + + +const EmployeeCard = (employee) => { + const [showQR, setShowQR] = useState(false); + + const qrText = `BEGIN:VCARD +VERSION:3.0 +N:${employee.employee.first_name} +FN:${employee.employee.last_name} +ORG:Дороги России +TITLE:${employee.employee.post} +TEL;WORK;VOICE:${employee.employee.phone} +TEL;CELL:${employee.employee.phone} +EMAIL;WORK;INTERNET:${employee.employee.email} +END:VCARD +`; + if (showQR) { + return ( + <> +