._.
This commit is contained in:
parent
83b9e57ea6
commit
492807f8a2
43
API/main.py
43
API/main.py
@ -5,10 +5,13 @@ import jwt
|
|||||||
|
|
||||||
from data.connect import init_db, connect, User, Document, DocumentCategory, Comment
|
from data.connect import init_db, connect, User, Document, DocumentCategory, Comment
|
||||||
from flask import Flask, Response, request, jsonify
|
from flask import Flask, Response, request, jsonify
|
||||||
|
from flask_cors import CORS
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config['SECRET_KEY'] = 'jyeraghueykgaeyugheaughkawefy'
|
app.config['SECRET_KEY'] = 'jyeraghueykgaeyugheaughkawefy'
|
||||||
|
|
||||||
|
CORS(app)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/v1/SignIn', methods=['POST'])
|
@app.route('/api/v1/SignIn', methods=['POST'])
|
||||||
def login():
|
def login():
|
||||||
@ -249,6 +252,46 @@ def protected():
|
|||||||
return jsonify({'message': 'Invalid token!'}), 401
|
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():
|
def main():
|
||||||
init_db()
|
init_db()
|
||||||
app.run()
|
app.run()
|
||||||
|
|||||||
58
WEB/app/package-lock.json
generated
58
WEB/app/package-lock.json
generated
@ -10,7 +10,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"next": "15.1.5",
|
"next": "15.1.5",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0"
|
"react-dom": "^19.0.0",
|
||||||
|
"react-qr-code": "^2.0.15"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
@ -1227,6 +1228,12 @@
|
|||||||
"jiti": "bin/jiti.js"
|
"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": {
|
"node_modules/lilconfig": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
|
||||||
@ -1247,6 +1254,18 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"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": {
|
"node_modules/lru-cache": {
|
||||||
"version": "10.4.3",
|
"version": "10.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||||
@ -1430,7 +1449,6 @@
|
|||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
@ -1676,6 +1694,23 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"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": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
@ -1718,6 +1753,25 @@
|
|||||||
"react": "^19.0.0"
|
"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": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
|
|||||||
@ -9,9 +9,10 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"next": "15.1.5",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"next": "15.1.5"
|
"react-qr-code": "^2.0.15"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
|
|||||||
@ -24,5 +24,47 @@
|
|||||||
|
|
||||||
.user-list {
|
.user-list {
|
||||||
margin: 2vw;
|
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;
|
||||||
}
|
}
|
||||||
74
WEB/app/src/app/components/employee-card.js
Normal file
74
WEB/app/src/app/components/employee-card.js
Normal file
@ -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 (
|
||||||
|
<>
|
||||||
|
<div className="employee-card">
|
||||||
|
<QRCode
|
||||||
|
size={256}
|
||||||
|
style={{ height: "auto", maxWidth: "100%", width: "100%" }}
|
||||||
|
value={qrText}
|
||||||
|
viewBox={`0 0 256 256`}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setShowQR(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Закрыть
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="employee-card">
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<label className="fio">{employee.employee.last_name}</label>
|
||||||
|
<label className="fio">{employee.employee.first_name}</label>
|
||||||
|
<label className="fio">{employee.employee.patronymic}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label className="employee-text">{employee.employee.post}</label>
|
||||||
|
<a className="employee-text" href={`mailto:${employee.employee.email}`}>{employee.employee.email}</a>
|
||||||
|
<label className="employee-text">{employee.employee.phone}</label>
|
||||||
|
<label className="employee-text">{employee.employee.phone}</label>
|
||||||
|
|
||||||
|
<div className="row-qr">
|
||||||
|
<label className="employee-text">{employee.employee.birthday}</label>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setShowQR(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
QR-код
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EmployeeCard;
|
||||||
@ -1,7 +1,40 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import './app.css';
|
import './app.css';
|
||||||
import Header from './components/header.js';
|
import Header from './components/header.js';
|
||||||
|
import EmployeeCard from './components/employee-card.js';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
|
||||||
|
const [employees, setEmployees] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchEmployees();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchEmployees = async () => {
|
||||||
|
try {
|
||||||
|
const data = await fetch('http://localhost:5000/employees');
|
||||||
|
|
||||||
|
if (data.ok) {
|
||||||
|
const json_data = await data.json();
|
||||||
|
setEmployees(json_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const b = (digit) => {
|
||||||
|
}
|
||||||
|
|
||||||
|
const a = [1, 2, 3, 4];
|
||||||
|
a.map(
|
||||||
|
b
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
@ -14,6 +47,12 @@ export default function Home() {
|
|||||||
|
|
||||||
<div className='user-row-list'>
|
<div className='user-row-list'>
|
||||||
|
|
||||||
|
{employees.map(
|
||||||
|
(employee) => (
|
||||||
|
<EmployeeCard key={employee.id} employee={employee} />
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user