Sfoglia il codice sorgente

сделана регистрация и авторизация с сервером и xml файлом с проверкой и записбю пользователей, добавлена страничка личный кабинет

Дамир Газизов 4 mesi fa
parent
commit
316ea9d2db

+ 0 - 0
ПП_Любивая_Газизов/dump-HeadControl-202406141131.sql


+ 19 - 0
ПП_Любивая_Газизов/registrations.xml

@@ -0,0 +1,19 @@
+
+            <users> 
+                <user>
+                    <name>Газизов Дамир Рамилевич</name>
+                    <phone>+7 (909) 297-0715</phone>
+                    <email>damirka20051904@mail.ru</email>
+                    <code>213412</code>
+                    <password>damir2005</password>
+                </user>
+            
+                <user>
+                    <name>Газизов Дамир Рамилевич</name>
+                    <phone>+7 (909) 297-0715</phone>
+                    <email>damirka2005@gmail.com</email>
+                    <code>123456</code>
+                    <password>damir1904</password>
+                </user>
+            </users> 
+            

+ 31 - 19
ПП_Любивая_Газизов/server.py

@@ -1,20 +1,20 @@
 from http.server import BaseHTTPRequestHandler, HTTPServer
+from xml.etree import ElementTree as ET
 import json
 import random
 import smtplib
+import os
 from email.mime.text import MIMEText
 
 HOST_NAME = 'localhost'
 PORT_NUMBER = 8000
-
 # Глобальный объект сервера
 server = None
-
 class MyHandler(BaseHTTPRequestHandler):
     def do_POST(self):
-        if self.path == '/send_code':
+        if self.path == 'http://localhost:8000/send_code':
             self.handle_send_code()
-        elif self.path == '/register':
+        elif self.path == 'http://localhost:8000/register':
             self.handle_registration()
         else:
             self.send_error(404, 'Not Found')
@@ -65,27 +65,40 @@ class MyHandler(BaseHTTPRequestHandler):
             self.wfile.write(bytes(f'Ошибка отправки кода: {e}', 'utf-8'))
 
     def handle_registration(self):
+        # Получаем XML-данные из запроса
         content_length = int(self.headers['Content-Length'])
-        body = self.rfile.read(content_length).decode('utf-8')
-        data = json.loads(body)
-
-        name = data['name']
-        phone = data['phone']
-        email = data['email']
-        code = data['code']
-        password = data['password']
-
-        # Здесь должна быть логика для проверки кода,
-        # записи данных в базу данных и т.д.
-        # В этом примере просто отправляем сообщение об успешной регистрации
-
+        xml_data = self.rfile.read(content_length).decode('utf-8')
+
+        # Парсим XML-данные
+        root = ET.fromstring(xml_data)
+
+        # Извлекаем информацию из XML
+        name = root.find('name').text
+        phone = root.find('phone').text
+        email = root.find('email').text
+        code = root.find('code').text
+        password = root.find('password').text
+
+        # Сохраняем данные в файл users.xml
+        with open('registrations.xml', 'a', encoding='utf-8') as f:
+            f.write(f"""
+                <user>
+                    <name>{name}</name>
+                    <phone>{phone}</phone>
+                    <email>{email}</email>
+                    <code>{code}</code>
+                    <password>{password}</password>
+                </user>
+            """)
+
+        # Отправляем ответ на AJAX-запрос
         self.send_response(200)
         self.send_header('Content-type', 'text/plain')
         self.send_header('Access-Control-Allow-Origin', '*')
         self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
         self.send_header('Access-Control-Allow-Headers', 'Content-Type')
         self.end_headers()
-        self.wfile.write(bytes('Регистрация успешна', 'utf-8'))
+        self.wfile.write(bytes('Данные успешно записаны', 'utf-8'))
 
     def do_OPTIONS(self):
         self.send_response(200)
@@ -184,7 +197,6 @@ class MyHandler(BaseHTTPRequestHandler):
         except FileNotFoundError:
             self.send_error(404, 'File not found')
 
-
 if __name__ == '__main__':
     # Создание глобального объекта сервера
     server = HTTPServer((HOST_NAME, PORT_NUMBER), MyHandler)

+ 157 - 0
ПП_Любивая_Газизов/server_registr.py

@@ -0,0 +1,157 @@
+from http.server import BaseHTTPRequestHandler, HTTPServer
+import xml.etree.ElementTree as ET
+import os
+import json
+
+HOST_NAME = 'localhost'
+PORT_NUMBER = 8000
+
+class MyHandler(BaseHTTPRequestHandler):
+    def do_POST(self):
+        if self.path == '/save_user':
+            self.handle_registration()
+        elif self.path == '/login':
+            self.handle_login()
+        elif self.path == '/get_user':
+            self.handle_get_user()
+        else:
+            self.send_error(404, 'Not Found')
+
+    def handle_registration(self):
+        # Получаем XML-данные из запроса
+        content_length = int(self.headers['Content-Length'])
+        xml_data = self.rfile.read(content_length).decode('utf-8')
+
+        # Парсим XML-данные
+        root = ET.fromstring(xml_data)
+
+        # Извлекаем информацию из XML
+        name = root.find('name').text
+        phone = root.find('phone').text
+        email = root.find('email').text
+        code = root.find('code').text
+        password = root.find('password').text
+
+        # Сохраняем данные в файл registrations.xml
+        with open('registrations.xml', 'a', encoding='utf-8') as f:
+            f.write(f"""
+                <user>
+                    <name>{name}</name>
+                    <phone>{phone}</phone>
+                    <email>{email}</email>
+                    <code>{code}</code>
+                    <password>{password}</password>
+                </user>
+            """)
+
+        # Отправляем ответ на AJAX-запрос
+        self.send_response(200)
+        self.send_header('Content-type', 'text/plain')
+        self.send_header('Access-Control-Allow-Origin', '*')
+        self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
+        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
+        self.end_headers()
+        self.wfile.write(bytes('Данные успешно записаны', 'utf-8'))
+
+    def do_OPTIONS(self):
+        self.send_response(200)
+        self.send_header('Access-Control-Allow-Origin', '*')
+        self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
+        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
+        self.end_headers()
+
+    def handle_login(self):
+        content_length = int(self.headers['Content-Length'])
+        body = self.rfile.read(content_length).decode('utf-8')
+        data = json.loads(body)
+        email = data['email']
+        password = data['password']
+
+        # Чтение XML-файла
+        tree = ET.parse('registrations.xml')
+        root = tree.getroot()
+
+        # Поиск пользователя по email
+        user_found = False
+        for user in root.findall('user'):
+            if user.find('email').text == email:
+                if user.find('password').text == password:
+                    user_found = True
+                    self.send_response(200)
+                    self.send_header('Content-type', 'text/plain')
+                    self.send_header('Access-Control-Allow-Origin', '*')
+                    self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
+                    self.send_header('Access-Control-Allow-Headers', 'Content-Type')
+                    self.end_headers()
+                    self.wfile.write(bytes('Вы успешно авторизованы!', 'utf-8'))
+                    break
+                else:
+                    self.send_response(401)
+                    self.send_header('Content-type', 'text/plain')
+                    self.send_header('Access-Control-Allow-Origin', '*')
+                    self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
+                    self.send_header('Access-Control-Allow-Headers', 'Content-Type')
+                    self.end_headers()
+                    self.wfile.write(bytes('Неверный пароль', 'utf-8'))
+                    break
+
+        if not user_found:
+            self.send_response(404)
+            self.send_header('Content-type', 'text/plain')
+            self.send_header('Access-Control-Allow-Origin', '*')
+            self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
+            self.send_header('Access-Control-Allow-Headers', 'Content-Type')
+            self.end_headers()
+            self.wfile.write(bytes('Пользователь не существует', 'utf-8'))
+
+    def do_OPTIONS(self):
+        self.send_response(200)
+        self.send_header('Access-Control-Allow-Origin', '*')
+        self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
+        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
+        self.end_headers()
+
+    def handle_get_user(self):
+        content_length = int(self.headers['Content-Length'])
+        body = self.rfile.read(content_length).decode('utf-8')
+        data = json.loads(body)
+        email = data['email']
+
+        tree = ET.parse('registrations.xml')
+        root = tree.getroot()
+        user_found = False
+        for user in root.findall('user'):
+            if user.find('email').text == email:
+                user_found = True
+                user_data = {
+                    'name': user.find('name').text,
+                    'phone': user.find('phone').text,
+                    'email': user.find('email').text,
+                    'code': user.find('code').text,
+                    'password': user.find('password').text
+                }
+                self.send_response(200)
+                self.send_header('Content-type', 'application/json')
+                self.send_header('Access-Control-Allow-Origin', '*')
+                self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
+                self.send_header('Access-Control-Allow-Headers', 'Content-Type')
+                self.end_headers()
+                self.wfile.write(bytes(json.dumps(user_data), 'utf-8'))
+                break
+        if not user_found:
+            self.send_response(401)
+            self.send_header('Content-type', 'text/plain')
+            self.send_header('Access-Control-Allow-Origin', '*')
+            self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
+            self.send_header('Access-Control-Allow-Headers', 'Content-Type')
+            self.end_headers()
+            self.wfile.write(bytes('Пользователь не найден', 'utf-8'))
+
+if __name__ == '__main__':
+    server = HTTPServer((HOST_NAME, PORT_NUMBER), MyHandler)
+    print(f'Сервер запущен на http://{HOST_NAME}:{PORT_NUMBER}')
+    try:
+        server.serve_forever()
+    except KeyboardInterrupt:
+        server.server_close()
+        print('Сервер остановлен')

+ 1 - 0
ПП_Любивая_Газизов/авторизация.html

@@ -25,6 +25,7 @@
         <div id="successPopup" class="popup">
             <span class="close-button" onclick="closePopup()">×</span>
             <h3 style="color: rgb(255, 255, 255);">Вы успешно авторизованы!</h3>
+            <button type="button" onclick="redirectToCabinet()">Перейти в личный кабинет</button>
         </div>
         <div id="errorPopup" class="popup">
             <span class="close-button" onclick="closePopup()">×</span>

BIN
ПП_Любивая_Газизов/картинки/скроллинг.webp


BIN
ПП_Любивая_Газизов/картинки/сотрудник1.png


+ 59 - 0
ПП_Любивая_Газизов/личныйкабинет.html

@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Личный кабинет</title>
+    <link rel="stylesheet" type="text/css" href="стили/личныйкабинет.css"> 
+</head>
+<body>
+    <header>
+        <!-- Добавьте ваш логотип или заголовок -->
+    </header>
+
+    <div class="container">
+        <h2>Личный кабинет</h2>
+
+        <div class="profile-info">
+            <div class="profile-picture">
+                <div class="upload-wrapper">
+                    <img id="profileImage" src="картинки/сотрудник1.png"> 
+                    <input type="file" id="profileImageUpload" accept="image/*" style="display: none;">
+                </div>
+            </div>
+            <div class="profile-details">
+                <p><strong>Имя:</strong> <span id="profileName"></span></p>
+                <p><strong>Номер телефона:</strong> <span id="profilePhone"></span></p>
+                <p><strong>Почта:</strong> <span id="profileEmail"></span></p>
+                <p><strong>Пароль:</strong> <span id="profilePassword"></span></p>
+                <button id="editProfileButton">Редактировать профиль</button>
+            </div>
+        </div>
+
+        <div id="editProfileForm" class="popup" style="display: none;">
+            <span class="close-button" onclick="closePopup()">×</span>
+            <h3>Редактировать профиль</h3>
+            <form id="editForm">
+                <input type="text" id="editName" placeholder="Имя" required>
+                <input type="tel" id="editPhone" placeholder="Номер телефона" required>
+                <input type="email" id="editEmail" placeholder="Email" required>
+                <input type="password" id="editPassword" placeholder="Новый пароль" required>
+                <button type="submit">Сохранить изменения</button>
+            </form>
+        </div>
+
+        <div id="successPopup" class="popup">
+            <span class="close-button" onclick="closePopup()">×</span>
+            <h3>Изменения сохранены!</h3>
+        </div>
+        <div id="errorPopup" class="popup">
+            <span class="close-button" onclick="closePopup()">×</span>
+            <h3 id="errorMessage"></h3>
+        </div>
+    </div>
+
+    <a href="главная.html" class="footer-link">На главную</a>
+    <script src="скрипты_js/личныйкабинет.js"></script> 
+    <script src="https://kit.fontawesome.com/your-fontawesome-kit-id.js" crossorigin="anonymous"></script> 
+</body>
+</html>

+ 1 - 2
ПП_Любивая_Газизов/регистрация.html

@@ -43,7 +43,6 @@
         </div>
     </div>
     <a href="главная.html" class="footer-link">На главную</a>
-    <script src="джава/регистрация.js"></script>
-    <script src="джава/апи.js"></script>
+    <script src="скрипты_js/регистрация.js"></script>
 </body>
 </html>

+ 46 - 51
ПП_Любивая_Газизов/скрипты_js/авторизация.js

@@ -1,56 +1,51 @@
-document.getElementById('loginForm').addEventListener('submit', function(event) {
-    event.preventDefault();
-    const email = document.getElementById('email').value;
-    const password = document.getElementById('password').value;
-    
-    // Отправка данных на сервер
-    fetch('/login', {
-        method: 'POST',
-        headers: {
-            'Content-Type': 'application/json'
-        },
-        body: JSON.stringify({ email: email, password: password })
-    })
-    .then(response => {
-        if (response.ok) {
-            return response.json();
-        } else {
-            throw new Error('Ошибка авторизации!');
-        }
-    })
-    .then(data => {
-        if (data.status === 'success') {
-            // Авторизация успешна!
-            document.getElementById('successPopup').style.display = 'block';
-            
-            // Проверяем, является ли пользователь администратором
-            // (замените `isAdmin` на вашу проверку роли пользователя)
-            if (isAdmin(email)) { 
-                document.getElementById('register-link').style.display = 'block'; 
-            }
-        } else {
-            // Ошибка авторизации
-            document.getElementById('errorMessage').textContent = 'Неверный email или пароль';
-            document.getElementById('errorPopup').style.display = 'block';
-        }
-    })
-    .catch(error => {
-        // Ошибка связи с сервером
-        document.getElementById('errorMessage').textContent = 'Ошибка сервера!';
-        document.getElementById('errorPopup').style.display = 'block';
-    });
+const loginForm = document.getElementById('loginForm');
+const successPopup = document.getElementById('successPopup');
+const errorPopup = document.getElementById('errorPopup');
+const errorMessage = document.getElementById('errorMessage');
+
+loginForm.addEventListener('submit', (event) => {
+  event.preventDefault(); 
+
+  const email = document.getElementById('email').value;
+  const password = document.getElementById('password').value;
+
+  fetch('http://localhost:8000/login', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    body: JSON.stringify({ email: email, password: password })
+  })
+  .then(response => {
+    if (response.ok) {
+      return response.text();
+    } else if (response.status === 401) {
+      errorMessage.textContent = 'Неверный пароль';
+      errorPopup.style.display = 'block';
+    } else if (response.status === 404) {
+      errorMessage.textContent = 'Пользователь не существует';
+      errorPopup.style.display = 'block';
+    } else {
+      throw new Error('Ошибка на сервере.');
+    }
+  })
+  .then(data => {
+    console.log('Ответ от сервера:', data);
+    successPopup.style.display = 'block';
+    loginForm.reset();
+  })
+  .catch(error => {
+    console.error('Ошибка:', error);
+  });
 });
 
-// Функция для проверки, является ли пользователь администратором
-// (замените на вашу реализацию проверки роли пользователя)
-function isAdmin(email) {
-    // Логика для определения, является ли пользователь администратором
-    // (например, проверка по базе данных или другим критериям)
-    return email === 'admin@example.com'; // Пример, замените на свою логику
+function closePopup() {
+  successPopup.style.display = 'none';
+  errorPopup.style.display = 'none';
 }
 
-// Закрытие всплывающего окна
-function closePopup() {
-    document.getElementById('successPopup').style.display = 'none';
-    document.getElementById('errorPopup').style.display = 'none';
+
+function redirectToCabinet() {
+    window.location.href = "личныйкабинет.html"; // Замените "личный_кабинет.html" на реальный адрес страницы личного кабинета
 }
+

+ 38 - 0
ПП_Любивая_Газизов/скрипты_js/личныйкабинет.js

@@ -0,0 +1,38 @@
+const profileImage = document.getElementById('profileImage');
+const profileImageUpload = document.getElementById('profileImageUpload');
+
+profileImageUpload.addEventListener('change', function(event) {
+  const file = event.target.files[0];
+  const reader = new FileReader();
+
+  reader.onload = function(e) {
+    profileImage.src = e.target.result; 
+  };
+
+  reader.readAsDataURL(file);
+});
+
+
+function getUser(email) {
+  fetch('/get_user', {
+      method: 'POST',
+      headers: {
+          'Content-Type': 'application/json'
+      },
+      body: JSON.stringify({ email: email })
+  })
+  .then(response => {
+      if (response.ok) {
+          return response.json();
+      } else {
+          throw new Error('Ошибка при получении пользователя');
+      }
+  })
+  .then(userData => {
+      // Обработка данных пользователя (userData)
+  })
+  .catch(error => {
+      console.error('Ошибка:', error);
+  });
+}
+

+ 45 - 20
ПП_Любивая_Газизов/скрипты_js/регистрация.js

@@ -1,24 +1,49 @@
-document.getElementById('getCodeButton').addEventListener('click', function() {
-    const email = document.getElementById('email').value;
+const registrationForm = document.getElementById('registrationForm');
+    registrationForm.addEventListener('submit', (event) => {
+      event.preventDefault();
 
-    // Вызов функции из файла апи.js
-    sendVerificationCode(email);
-});
+      const name = document.getElementById('name').value;
+      const phone = document.getElementById('phone').value;
+      const email = document.getElementById('email').value;
+      const code = document.getElementById('code').value;
+      const password = document.getElementById('password').value;
 
-document.getElementById('registrationForm').addEventListener('submit', function(event) {
-    event.preventDefault();
-    const name = document.getElementById('name').value;
-    const phone = document.getElementById('phone').value;
-    const email = document.getElementById('email').value;
-    const code = document.getElementById('code').value;
-    const password = document.getElementById('password').value;
+      // Создаем объект XML для записи данных
+      const xml = `
+        <user>
+          <name>${name}</name>
+          <phone>${phone}</phone>
+          <email>${email}</email>
+          <code>${code}</code>
+          <password>${password}</password>
+        </user>
+      `;
 
-    // Вызов функции из файла апи.js для регистрации
-    registerUser(name, phone, email, code, password);
-});
+      // Отправляем XML-данные на сервер
+      fetch('http://localhost:8000/save_user', {
+        method: 'POST',
+        headers: {
+          'Content-Type': 'text/xml; charset=utf-8'
+        },
+        body: xml
+      })
+      .then(response => {
+        if (!response.ok) {
+          throw new Error('Ошибка при отправке данных на сервер');
+        }
+        return response.text(); 
+      })
+      .then(data => {
+        console.log('Ответ от сервера:', data);
+        document.getElementById('successPopup').style.display = 'block';
+        registrationForm.reset();
+      })
+      .catch(error => {
+        console.error('Ошибка:', error);
+      });
+    });
 
-// Закрытие всплывающего окна
-function closePopup() {
-    document.getElementById('successPopup').style.display = 'none';
-    document.getElementById('errorPopup').style.display = 'none';
-}
+    // Функция для закрытия всплывающего окна
+    function closePopup() {
+      document.getElementById('successPopup').style.display = 'none';
+    }

+ 411 - 0
ПП_Любивая_Газизов/стили/личныйкабинет.css

@@ -0,0 +1,411 @@
+
+body {
+    margin: 0;
+    font-family: sans-serif;
+    overflow-x: hidden;
+    background-image: url('../картинки/фон.jpg');
+    font-family: sans-serif;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    min-height: 100vh;
+    background-color: #f4f4f4; 
+    background-size: cover;
+    background-position: center;
+  }
+
+  .container {
+    position: relative;
+    width: 100%;
+    overflow: hidden; /* Скрываем переполнение для закругления */
+  }
+
+  .background-image {
+    width: 100%;
+    height: 400px; /* Высота фона */
+    background-size: cover;
+    background-position: center;
+    border-radius: 10px; /* Закругленные углы */
+    min-height: 100vh
+  }
+
+  .content {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    text-align: center;
+    color: #fff;
+    z-index: 1; /* Помещаем текст поверх изображения */
+  }
+
+  .content h2 {
+    font-size: 36px;
+    margin-bottom: 10px;
+    color: #fff;
+  }
+
+  h4 {
+    font-size: 28px;
+    margin-bottom: 10px;
+    color: #fff;
+  }
+
+  p {
+    font-size: 24px;
+    margin-bottom: 10px;
+    color: #fff;
+  }
+
+  header {
+    background-color: transparent;
+    padding: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    position: absolute; /* Помещаем меню поверх изображения */
+    top: 20px; /* Отступ сверху */
+    left: 20px; /* Отступ слева */
+    z-index: 2; /* Помещаем меню поверх текста */
+    justify-content: space-between;
+    width: 95%
+  }
+
+  .logo {
+    font-size: 24px;
+    font-weight: bold;
+    color: #0022ff; /* Синий цвет */
+    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); /* Тень */
+  }
+
+  nav {
+    display: flex;
+  }
+
+  nav a {
+    text-decoration: none;
+    color: #faf3f3;
+    padding: 10px 20px;
+    position: relative;
+    margin-left: 20px;
+  }
+
+  nav a::after {
+    content: "";
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    height: 3px;
+    background: linear-gradient(to right, #007bff, #663399, #ff0000); /* Градиент */
+    transform: scaleX(0);
+    transition: transform 0.3s ease-in-out;
+  }
+
+  nav a:hover::after {
+    transform: scaleX(1);
+  }
+
+  .dropdown {
+    position: relative;
+    margin-left: 20px;
+  }
+
+  .dropdown-content {
+    display: none;
+    position: absolute;
+    background-color: #f9f9f9;
+    min-width: 160px;
+    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
+    z-index: 1;
+  }
+
+  .dropdown-content a {
+    color: #333;
+    padding: 12px 16px;
+    text-decoration: none;
+    display: block;
+  }
+
+  .dropdown-content a:hover {
+    background-color: #f1f1f1;
+  }
+
+  .dropdown:hover .dropdown-content {
+    display: block;
+  }
+
+  .icon {
+    margin-left: 20px;
+    cursor: pointer;
+  }
+
+  .icon img {
+    width: 30px;
+    height: 30px;
+  }
+
+  /* Стили для фонов */
+  section {
+    padding: 50px;
+    text-align: center;
+    min-height: 100vh;
+  }
+
+
+  .background-image1 {
+    width: 100%;
+    height: 400px; /* Высота фона */
+    background-image: url('аудирс7.jpg'); /* Замените на путь к вашей картинке */
+    background-size: cover;
+    background-position: center;
+    border-radius: 10px; /* Закругленные углы */
+    min-height: 100vh
+  }
+
+  .background-image2 {
+    width: 100%;
+    height: 400px; /* Высота фона */
+    background-image: url('киак5.jpg'); /* Замените на путь к вашей картинке */
+    background-size: cover;
+    background-position: center;
+    border-radius: 10px; /* Закругленные углы */
+    min-height: 100vh
+  }
+
+  .data_foot {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 5px;
+}
+
+hr {
+    width: 100%;
+    border: 1px solid #D1D1D1;
+}
+
+.i:hover svg path {
+    fill: #D1D1D1;
+}
+
+  .scroll-to-top {
+    position: fixed;
+    bottom: 20px;
+    right: 20px;
+    display: none; 
+    z-index: 10;
+    cursor: pointer;
+  }
+
+  .scroll-to-top img {
+    width: 50px;
+  }
+
+.container {
+    background-color: #fff;
+    padding: 40px;
+    border-radius: 5px;
+    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+    width: 350px;
+    background-color: rgba(255, 255, 255, 0.8); 
+}
+
+h2 {
+    text-align: center;
+    margin-bottom: 20px;
+    color: #333;
+}
+
+p {
+    text-align: center;
+    margin-bottom: 20px;
+    color: #333;
+}
+input[type="email"],
+input[type="password"] {
+    width: 100%;
+    padding: 12px;
+    margin-bottom: 15px;
+    border: 1px solid #ccc;
+    border-radius: 4px;
+    box-sizing: border-box;
+}
+
+input[type="text"],
+input[type="email"],
+input[type="tel"],
+input[type="password"], 
+input[type="kod"] {
+    width: 100%;
+    padding: 12px;
+    margin-bottom: 15px;
+    border: 1px solid #ccc;
+    border-radius: 4px;
+    box-sizing: border-box;
+}
+
+button {
+    background-color: #444444;
+    color: #fff;
+    padding: 12px 20px;
+    border: none;
+    border-radius: 4px;
+    cursor: pointer;
+    width: 100%;
+}
+
+button:hover {
+    background-color: #6e6e6e;
+}
+
+.register-link {
+    text-align: center;
+    margin-top: 15px;
+    color: #333;
+}
+
+.register-link a {
+    color: #444444;
+    text-decoration: none;
+}
+
+nav a {
+    text-decoration: none;
+    color: #faf3f3;
+    padding: 10px 20px;
+    position: relative;
+    margin-left: 20px;
+}
+
+nav a::after {
+    content: "";
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    height: 3px;
+    background: linear-gradient(to right, #ffffff, #ffffff, #ffffff); /* Градиент */
+    transform: scaleX(0);
+    transition: transform 0.3s ease-in-out;
+}
+
+nav a:hover::after {
+    transform: scaleX(1);
+}
+
+
+.footer-link {
+  position: absolute;
+  bottom: 20px; 
+  left: 50%;
+  transform: translateX(-50%);
+  color: white;
+  text-decoration: none;
+  font-weight: bold;
+  background-color: #444444;
+  padding: 10px 20px;
+  border-radius: 5px;
+  z-index: 2;
+}
+
+.footer-link:hover {
+  background-color: #6e6e6e; 
+}
+
+  .popup {
+    display: none;
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    background-color: rgba(80, 80, 80, 0.7);
+    padding: 20px;
+    border-radius: 5px;
+    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
+    z-index: 1000;
+    text-align: center;
+}
+
+.close-button {
+    position: absolute;
+    top: 10px;
+    right: 10px;
+    cursor: pointer;
+}
+
+.register-link {
+  text-align: center;
+  margin-top: 15px;
+  color: #333;
+}
+
+.register-link a {
+  color: #007bff;
+  text-decoration: none;
+}
+
+nav a {
+  text-decoration: none;
+  color: #faf3f3;
+  padding: 10px 20px;
+  position: relative;
+  margin-left: 20px;
+}
+
+nav a::after {
+  content: "";
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  height: 3px;
+  background: linear-gradient(to right, #bebebe, #3a3a3a, #bebebe); 
+  transform: scaleX(0);
+  transition: transform 0.3s ease-in-out;
+}
+
+nav a:hover::after {
+  transform: scaleX(1);
+}
+
+
+.profile-picture .upload-wrapper {
+    position: relative;
+    width: 150px; 
+    height: 150px;
+    border-radius: 50%; 
+    overflow: hidden; /* Скрывает лишнюю часть изображения */
+    margin: 0 auto; /* Центрирование по горизонтали */
+}
+
+
+
+.profile-picture img {
+    width: 100%; 
+    height: 100%;
+    background-color: #444444;
+    object-fit: cover; 
+    border-radius: 50%; /* Делаем изображение круглым */
+}
+
+.profile-picture .upload-icon {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    background-color: rgba(0, 0, 0, 0.5); 
+    border-radius: 50%; 
+    width: 30px;
+    height: 30px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    cursor: pointer; 
+}
+
+.profile-picture .upload-icon i {
+    color: white; 
+    font-size: 1.5em; 
+}
+