From 350b3f649cfd6e97cd121b81522dcb087dea6910 Mon Sep 17 00:00:00 2001
From: muoimeo <bvnminh6a01@gmail.com>
Date: Mon, 14 Apr 2025 00:21:21 +0700
Subject: [PATCH] =?UTF-8?q?th=E1=BA=BF=20gi=E1=BB=9Bi=20vcl?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                    |   5 +-
 app/forms/auth.py                             |  19 +
 app/forms/auth_forms.py                       |  81 +--
 app/models/__init__.py                        |   4 +-
 app/models/activity_log.py                    |  20 +
 app/models/dietitian.py                       |  15 +-
 app/models/patient.py                         |   2 +-
 app/models/referral.py                        |  15 +-
 app/models/user.py                            |  71 +--
 app/routes/auth.py                            | 189 +++----
 app/routes/dietitians.py                      | 284 ++++------
 app/templates/auth_base.html                  |   5 +-
 app/templates/base.html                       | 135 ++++-
 app/templates/dietitians/edit.html            | 104 ----
 app/templates/dietitians/index.html           |  67 +--
 app/templates/dietitians/link_profile.html    | 121 ----
 app/templates/dietitians/show.html            |  51 +-
 app/templates/edit_profile.html               | 333 ++++++-----
 app/templates/login.html                      | 107 ++--
 app/templates/profile.html                    | 156 ++----
 app/templates/register.html                   | 181 ------
 app/utils/decorators.py                       |  16 +
 fix_template_urls.py                          |  46 --
 generate_patients.py                          | 129 +++++
 migrations/README                             |   1 +
 migrations/alembic.ini                        |  50 ++
 migrations/env.py                             | 113 ++++
 migrations/script.py.mako                     |  24 +
 ..._update_database_schema_to_match_models.py |  60 ++
 requirements.txt                              |   3 +-
 run.py                                        | 517 ++++++++----------
 run_ccu.bat                                   |  43 +-
 32 files changed, 1426 insertions(+), 1541 deletions(-)
 create mode 100644 app/forms/auth.py
 create mode 100644 app/models/activity_log.py
 delete mode 100644 app/templates/dietitians/edit.html
 delete mode 100644 app/templates/dietitians/link_profile.html
 delete mode 100644 app/templates/register.html
 create mode 100644 app/utils/decorators.py
 delete mode 100644 fix_template_urls.py
 create mode 100644 generate_patients.py
 create mode 100644 migrations/README
 create mode 100644 migrations/alembic.ini
 create mode 100644 migrations/env.py
 create mode 100644 migrations/script.py.mako
 create mode 100644 migrations/versions/cbc9db9dd958_update_database_schema_to_match_models.py

diff --git a/.gitignore b/.gitignore
index 0fb850d..b1766a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -146,4 +146,7 @@ logs/
 
 # Thư mục và tệp khác
 .DS_Store
-Thumbs.db 
\ No newline at end of file
+Thumbs.db 
+
+#json file
+*.json 
\ No newline at end of file
diff --git a/app/forms/auth.py b/app/forms/auth.py
new file mode 100644
index 0000000..49e3501
--- /dev/null
+++ b/app/forms/auth.py
@@ -0,0 +1,19 @@
+from flask_wtf import FlaskForm
+from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField
+from wtforms.validators import DataRequired, Email, EqualTo, Length, Optional, ValidationError
+
+class EditProfileForm(FlaskForm):
+    """Form chỉnh sửa hồ sơ người dùng"""
+    firstName = StringField('Tên', validators=[DataRequired(message="Tên không được để trống")])
+    lastName = StringField('Họ', validators=[DataRequired(message="Họ không được để trống")])
+    email = StringField('Email', validators=[DataRequired(message="Email không được để trống"), Email(message="Email không hợp lệ")])
+    phone = StringField('Số điện thoại', validators=[Optional()])
+    
+    # Các trường cho dietitian
+    specialization = StringField('Chuyên môn', validators=[Optional()])
+    notes = TextAreaField('Ghi chú', validators=[Optional(), Length(max=500, message="Ghi chú không được vượt quá 500 ký tự")])
+    
+    password = PasswordField('Mật khẩu mới', validators=[Optional(), Length(min=6, message="Mật khẩu phải có ít nhất 6 ký tự")])
+    confirm_password = PasswordField('Xác nhận mật khẩu', validators=[Optional(), EqualTo('password', message="Xác nhận mật khẩu không khớp")])
+    
+    submit = SubmitField('Cập nhật') 
\ No newline at end of file
diff --git a/app/forms/auth_forms.py b/app/forms/auth_forms.py
index 9a01367..b28b2cc 100644
--- a/app/forms/auth_forms.py
+++ b/app/forms/auth_forms.py
@@ -1,6 +1,6 @@
 from flask_wtf import FlaskForm
-from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField
-from wtforms.validators import DataRequired, Email, Length, EqualTo, ValidationError
+from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField, SelectField
+from wtforms.validators import DataRequired, Email, Length, EqualTo, ValidationError, Optional
 from app.models.user import User
 
 class LoginForm(FlaskForm):
@@ -9,80 +9,33 @@ class LoginForm(FlaskForm):
         DataRequired(message="Email không được để trống"),
         Email(message="Vui lòng nhập địa chỉ email hợp lệ")
     ])
+    dietitianID = StringField('Dietitian ID', validators=[Optional()])
     password = PasswordField('Mật khẩu', validators=[
         DataRequired(message="Mật khẩu không được để trống")
     ])
     remember = BooleanField('Ghi nhớ đăng nhập')
     submit = SubmitField('Đăng nhập')
 
-class RegisterForm(FlaskForm):
-    """Form đăng ký người dùng mới"""
-    firstName = StringField('Họ', validators=[
-        DataRequired(message="Họ không được để trống"),
-        Length(min=1, max=50, message="Họ phải có từ 1 đến 50 ký tự")
-    ])
-    lastName = StringField('Tên', validators=[
-        DataRequired(message="Tên không được để trống"),
-        Length(min=1, max=50, message="Tên phải có từ 1 đến 50 ký tự")
-    ])
-    username = StringField('Tên người dùng', validators=[
-        DataRequired(message="Tên người dùng không được để trống"),
-        Length(min=3, max=25, message="Tên người dùng phải có từ 3 đến 25 ký tự")
-    ])
-    email = StringField('Email', validators=[
-        DataRequired(message="Email không được để trống"),
-        Email(message="Vui lòng nhập địa chỉ email hợp lệ")
-    ])
-    password = PasswordField('Mật khẩu', validators=[
-        DataRequired(message="Mật khẩu không được để trống"),
-        Length(min=6, message="Mật khẩu phải có ít nhất 6 ký tự")
-    ])
-    confirm_password = PasswordField('Xác nhận mật khẩu', validators=[
-        DataRequired(message="Vui lòng xác nhận mật khẩu"),
-        EqualTo('password', message="Mật khẩu không khớp")
-    ])
-    submit = SubmitField('Đăng ký')
-
-    def validate_username(self, username):
-        """Kiểm tra xem tên người dùng đã tồn tại chưa"""
-        user = User.query.filter_by(username=username.data).first()
-        if user:
-            raise ValidationError('Tên người dùng này đã được sử dụng. Vui lòng chọn tên khác.')
-
-    def validate_email(self, email):
-        """Kiểm tra xem email đã tồn tại chưa"""
-        user = User.query.filter_by(email=email.data).first()
-        if user:
-            raise ValidationError('Email này đã được sử dụng. Vui lòng sử dụng email khác.')
-
 class EditProfileForm(FlaskForm):
-    """Form chỉnh sửa thông tin hồ sơ người dùng"""
-    username = StringField('Tên người dùng', validators=[
-        DataRequired(message="Tên người dùng không được để trống"),
-        Length(min=3, max=25, message="Tên người dùng phải có từ 3 đến 25 ký tự")
-    ])
-    email = StringField('Email', validators=[
-        DataRequired(message="Email không được để trống"),
-        Email(message="Vui lòng nhập địa chỉ email hợp lệ")
-    ])
-    bio = TextAreaField('Giới thiệu', validators=[
-        Length(max=200, message="Giới thiệu không được quá 200 ký tự")
-    ])
-    submit = SubmitField('Cập nhật thông tin')
+    """Form for users to edit their profile"""
+    firstName = StringField('First Name', validators=[DataRequired(), Length(min=2, max=50)])
+    lastName = StringField('Last Name', validators=[DataRequired(), Length(min=2, max=50)])
+    email = StringField('Email', validators=[DataRequired(), Email(), Length(max=100)])
+    phone = StringField('Số điện thoại', validators=[Optional()])
+    
+    # Các trường cho dietitian
+    specialization = StringField('Chuyên môn', validators=[Optional()])
+    notes = TextAreaField('Ghi chú', validators=[Optional(), Length(max=500, message="Ghi chú không được vượt quá 500 ký tự")])
+    
+    password = PasswordField('Mật khẩu mới', validators=[Optional(), Length(min=6, message="Mật khẩu phải có ít nhất 6 ký tự")])
+    confirm_password = PasswordField('Xác nhận mật khẩu', validators=[Optional(), EqualTo('password', message="Xác nhận mật khẩu không khớp")])
+    
+    submit = SubmitField('Cập nhật')
 
     def __init__(self, *args, **kwargs):
         super(EditProfileForm, self).__init__(*args, **kwargs)
-        self.original_username = kwargs.get('obj', None)
         self.original_email = kwargs.get('obj', None)
 
-    def validate_username(self, username):
-        """Kiểm tra xem tên người dùng đã tồn tại chưa"""
-        if self.original_username and self.original_username.username == username.data:
-            return
-        user = User.query.filter_by(username=username.data).first()
-        if user:
-            raise ValidationError('Tên người dùng này đã được sử dụng. Vui lòng chọn tên khác.')
-
     def validate_email(self, email):
         """Kiểm tra xem email đã tồn tại chưa"""
         if self.original_email and self.original_email.email == email.data:
diff --git a/app/models/__init__.py b/app/models/__init__.py
index 47a04f8..48524af 100644
--- a/app/models/__init__.py
+++ b/app/models/__init__.py
@@ -7,6 +7,7 @@ from .procedure import Procedure
 from .report import Report
 from .uploaded_file import UploadedFile
 from .dietitian import Dietitian, DietitianStatus
+from .activity_log import ActivityLog
 
 # Import bất kỳ model bổ sung nào ở đây 
 
@@ -20,5 +21,6 @@ __all__ = [
     'Report', 
     'UploadedFile',
     'Dietitian',
-    'DietitianStatus'
+    'DietitianStatus',
+    'ActivityLog'
 ] 
\ No newline at end of file
diff --git a/app/models/activity_log.py b/app/models/activity_log.py
new file mode 100644
index 0000000..d9a36bc
--- /dev/null
+++ b/app/models/activity_log.py
@@ -0,0 +1,20 @@
+from datetime import datetime
+from .. import db
+from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey
+from sqlalchemy.orm import relationship
+
+class ActivityLog(db.Model):
+    """Model để lưu trữ lịch sử hoạt động của người dùng."""
+    __tablename__ = 'activity_logs'
+
+    id = Column(Integer, primary_key=True)
+    user_id = Column(Integer, ForeignKey('users.userID'), nullable=False)
+    action = Column(String(255), nullable=False)  # Mô tả hành động (e.g., 'Logged In', 'Created Patient')
+    details = Column(Text)  # Chi tiết thêm về hành động (e.g., 'Patient ID: P-00001')
+    timestamp = Column(DateTime, default=datetime.utcnow)
+
+    # Relationship back to User
+    user = relationship("User", back_populates="activities")
+
+    def __repr__(self):
+        return f'<ActivityLog {self.id} by User {self.user_id} at {self.timestamp}>' 
\ No newline at end of file
diff --git a/app/models/dietitian.py b/app/models/dietitian.py
index 767cbd5..88c2555 100644
--- a/app/models/dietitian.py
+++ b/app/models/dietitian.py
@@ -26,7 +26,7 @@ class Dietitian(db.Model):
     created_at = Column(DateTime, default=datetime.utcnow)
     updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
     
-    user = relationship("User", back_populates="dietitian_profile")
+    user = relationship("User", back_populates="dietitian")
 
     @property
     def fullName(self):
@@ -38,5 +38,18 @@ class Dietitian(db.Model):
         """Return the dietitian ID in the format 'DT-XXXXX'."""
         return f"DT-{self.dietitianID:05d}"
     
+    @property
+    def patient_count(self):
+        """Trả về số lượng bệnh nhân mà dietitian đang chăm sóc."""
+        from app.models.patient import Patient
+        return Patient.query.filter_by(dietitian_id=self.dietitianID).count()
+    
+    def update_status_based_on_patient_count(self):
+        """Cập nhật trạng thái dựa trên số lượng bệnh nhân."""
+        if self.patient_count >= 6:
+            self.status = DietitianStatus.UNAVAILABLE
+        else:
+            self.status = DietitianStatus.AVAILABLE
+            
     def __repr__(self):
         return f"<Dietitian {self.fullName}>"
\ No newline at end of file
diff --git a/app/models/patient.py b/app/models/patient.py
index 706a1af..d47231f 100644
--- a/app/models/patient.py
+++ b/app/models/patient.py
@@ -24,7 +24,7 @@ class Patient(db.Model):
     status = Column(String(20), default='active', nullable=True)
     height = Column(Float, nullable=True)  # Height in cm
     weight = Column(Float, nullable=True)  # Weight in kg
-    blood_type = Column(String(5), nullable=True)
+    blood_type = Column(String(10), nullable=True)
     admission_date = Column(DateTime, nullable=True)
     
     # Timestamps
diff --git a/app/models/referral.py b/app/models/referral.py
index f576e91..d828018 100644
--- a/app/models/referral.py
+++ b/app/models/referral.py
@@ -49,4 +49,17 @@ class Referral(db.Model):
             else:
                 delta = datetime.utcnow() - self.referralRequestedDateTime
             return delta.days
-        return None 
\ No newline at end of file
+        return None 
+
+    # Add a property to generate a descriptive name
+    @property
+    def referral_name(self):
+        """Generates a descriptive name for the referral."""
+        if self.patient: # Check if patient relationship is loaded
+            patient_name = self.patient.full_name
+        else:
+            # Fallback if patient object not loaded, using patient_id which is always available
+            patient_name = f"Patient ID {self.patient_id}"
+
+        date_str = self.referralRequestedDateTime.strftime('%Y-%m-%d') if self.referralRequestedDateTime else "Unknown Date"
+        return f"Referral for {patient_name} ({date_str})" 
\ No newline at end of file
diff --git a/app/models/user.py b/app/models/user.py
index 3a00cd2..5d52a70 100644
--- a/app/models/user.py
+++ b/app/models/user.py
@@ -3,36 +3,45 @@ from flask_login import UserMixin
 from .. import db, login_manager
 from sqlalchemy.sql import func
 from flask_bcrypt import Bcrypt
-from sqlalchemy import Column, Integer, String, Boolean, DateTime, Enum
+from sqlalchemy import Column, Integer, String, Boolean, DateTime, Enum, ForeignKey
 from sqlalchemy.orm import relationship
 
 bcrypt = Bcrypt()
 
-class User(db.Model, UserMixin):
-    """User model for dietitians and administrators"""
+class User(UserMixin, db.Model):
+    """User model"""
     __tablename__ = 'users'
-    
+    __table_args__ = {'extend_existing': True}
+
     userID = Column('userID', Integer, primary_key=True)
-    username = Column(String(50), unique=True, nullable=False)
     email = Column(String(100), unique=True, nullable=False)
-    password_hash = Column(String(255), nullable=False)
-    role = Column(Enum('Admin', 'Dietitian'), default='Dietitian')
-    
-    # Relationship với Dietitian model
-    dietitian_profile = relationship("Dietitian", back_populates="user", uselist=False, cascade="all, delete-orphan")
+    password_hash = Column(String(128))
+    firstName = Column(String(50), nullable=False)
+    lastName = Column(String(50), nullable=False)
+    role = Column(Enum('Admin', 'Dietitian', name='user_roles_new'), default='Dietitian', nullable=False)
+    is_active = Column(Boolean, default=True)
+    created_at = Column(DateTime(timezone=True), server_default=func.now())
+    last_login = Column(DateTime(timezone=True))
     
+    # Relationships
+    dietitian = relationship("Dietitian", back_populates="user", uselist=False, cascade="all, delete-orphan")
+    activities = relationship("ActivityLog", back_populates="user", lazy='dynamic')
+
+    def set_password(self, password):
+        self.password_hash = bcrypt.generate_password_hash(password).decode('utf-8')
+
+    def check_password(self, password):
+        return bcrypt.check_password_hash(self.password_hash, password)
+
     @property
-    def id(self):
-        """Trả về userID để đảm bảo tương thích khi code truy cập user.id"""
-        return self.userID
-    
+    def full_name(self):
+        """Return the user's full name."""
+        return f"{self.firstName} {self.lastName}"
+
     @property
     def is_admin(self):
         return self.role == 'Admin'
-        
-    def get_id(self):
-        return str(self.userID)
-    
+
     @property
     def is_active(self):
         return True
@@ -45,25 +54,19 @@ class User(db.Model, UserMixin):
     def is_anonymous(self):
         return False
         
+    def get_id(self):
+        """Return the primary key of the user for Flask-Login."""
+        return str(self.userID)
+        
     def __repr__(self):
-        return f"User('{self.username}', '{self.email}')"
-    
-    @property
-    def full_name(self):
-        if self.dietitian_profile:
-            return f"{self.dietitian_profile.firstName} {self.dietitian_profile.lastName}"
-        return self.username
+        return f"User('{self.email}')"
 
     @property
-    def password(self):
-        raise AttributeError('password is not a readable attribute')
-
-    @password.setter
-    def password(self, password):
-        self.password_hash = bcrypt.generate_password_hash(password).decode('utf-8')
-
-    def verify_password(self, password):
-        return bcrypt.check_password_hash(self.password_hash, password)
+    def formattedID(self):
+        """Return the user ID in the format 'U-XXXXX' or 'AD-XXXXX'."""
+        if self.role == 'Admin':
+            return f"AD-{self.userID:05d}"
+        return f"U-{self.userID:05d}"
 
 @login_manager.user_loader
 def load_user(user_id):
diff --git a/app/routes/auth.py b/app/routes/auth.py
index 799062c..6a1311c 100644
--- a/app/routes/auth.py
+++ b/app/routes/auth.py
@@ -4,9 +4,11 @@ from werkzeug.security import generate_password_hash, check_password_hash
 from datetime import datetime
 from app import db, bcrypt
 from app.models.user import User
-from app.forms.auth_forms import LoginForm, RegisterForm, EditProfileForm, ChangePasswordForm, NotificationSettingsForm
+from app.models.dietitian import Dietitian, DietitianStatus
+from app.forms.auth_forms import LoginForm, EditProfileForm, ChangePasswordForm, NotificationSettingsForm
 from ..utils.validators import is_safe_url, validate_password, validate_email, sanitize_input
 from sqlalchemy.sql import text
+from app.utils.decorators import admin_required
 
 auth_bp = Blueprint('auth', __name__, url_prefix='/auth')
 
@@ -21,24 +23,43 @@ def login():
     if form.validate_on_submit():
         user = User.query.filter_by(email=form.email.data).first()
         
-        # Sử dụng phương thức verify_password của model User thay vì truy cập trực tiếp
-        if user and user.verify_password(form.password.data):
-            # Đăng nhập người dùng
-            login_user(user, remember=form.remember.data)
-            next_page = request.args.get('next')
-            
-            flash('Đăng nhập thành công!', 'success')
+        if not user or not user.check_password(form.password.data):
+            flash('Email hoặc mật khẩu không chính xác.', 'error')
+            return render_template('login.html', form=form, title='Đăng nhập')
+
+        # Kiểm tra role và dietitianID nếu là Dietitian
+        if user.role == 'Dietitian':
+            # Lấy Dietitian ID từ form và chuẩn hóa (viết hoa)
+            form_dietitian_id_raw = form.dietitianID.data
+            if not form_dietitian_id_raw:
+                flash('Vui lòng nhập Dietitian ID.', 'error')
+                return render_template('login.html', form=form, title='Đăng nhập')
             
-            # Chuyển hướng đến trang được yêu cầu hoặc trang chính
-            if next_page:
-                # Kiểm tra an toàn cho URL chuyển hướng (is_safe_url cần được định nghĩa hoặc import)
-                # if is_safe_url(next_page): 
-                #     return redirect(next_page)
-                # Tạm thời cho phép mọi next_page nếu không có is_safe_url
-                 return redirect(next_page)
-            return redirect(url_for('dashboard.index'))
-        else:
-            flash('Email hoặc mật khẩu không chính xác. Vui lòng thử lại.', 'error')
+            form_dietitian_id = form_dietitian_id_raw.strip().upper()
+
+            # Kiểm tra xem user có dietitian profile không
+            if not user.dietitian:
+                 flash('Tài khoản Dietitian này chưa có hồ sơ được liên kết.', 'error')
+                 return render_template('login.html', form=form, title='Đăng nhập')
+
+            # Kiểm tra khớp Dietitian ID (đã chuẩn hóa)
+            if user.dietitian.formattedID.upper() != form_dietitian_id:
+                flash('Dietitian ID không khớp với tài khoản này.', 'error')
+                return render_template('login.html', form=form, title='Đăng nhập')
+        
+        # Nếu là Admin hoặc Dietitian đã xác thực ID thành công
+        login_user(user, remember=form.remember.data)
+        next_page = request.args.get('next')
+        flash('Đăng nhập thành công!', 'success')
+        
+        # Chuyển hướng đến trang được yêu cầu hoặc trang chính
+        if next_page:
+            # Kiểm tra an toàn cho URL chuyển hướng (is_safe_url cần được định nghĩa hoặc import)
+            # if is_safe_url(next_page): 
+            #     return redirect(next_page)
+            # Tạm thời cho phép mọi next_page nếu không có is_safe_url
+             return redirect(next_page)
+        return redirect(url_for('dashboard.index'))
     
     return render_template('login.html', form=form, title='Đăng nhập')
 
@@ -50,46 +71,6 @@ def logout():
     flash('Bạn đã đăng xuất thành công.', 'info')
     return redirect(url_for('auth.login'))
 
-@auth_bp.route('/register', methods=['GET', 'POST'])
-def register():
-    """Xử lý đăng ký người dùng mới"""
-    if current_user.is_authenticated:
-        return redirect(url_for('dashboard.index'))
-    
-    form = RegisterForm()
-    if form.validate_on_submit():
-        # Kiểm tra xem email đã được sử dụng chưa
-        existing_user = User.query.filter_by(email=form.email.data).first()
-        if existing_user:
-            flash('Email này đã được sử dụng. Vui lòng chọn email khác.', 'error')
-            return render_template('register.html', form=form)
-            
-        # Kiểm tra xem tên người dùng đã được sử dụng chưa
-        existing_username = User.query.filter_by(username=form.username.data).first()
-        if existing_username:
-            flash('Tên người dùng này đã được sử dụng. Vui lòng chọn tên khác.', 'error')
-            return render_template('register.html', form=form)
-        
-        # Tạo người dùng mới
-        user = User(
-            username=form.username.data,
-            email=form.email.data,
-            password=form.password.data,  # Sử dụng setter của User model thay vì gán hash trực tiếp
-            role='Dietitian'  # Mặc định là người dùng thông thường
-        )
-        
-        # Lưu vào cơ sở dữ liệu
-        try:
-            db.session.add(user)
-            db.session.commit()
-            flash('Tài khoản của bạn đã được tạo! Bạn có thể đăng nhập ngay bây giờ.', 'success')
-            return redirect(url_for('auth.login'))
-        except Exception as e:
-            db.session.rollback()
-            flash(f'Đã xảy ra lỗi khi tạo tài khoản: {str(e)}', 'danger')
-    
-    return render_template('register.html', form=form, title='Đăng ký')
-
 @auth_bp.route('/profile')
 @login_required
 def profile():
@@ -97,7 +78,7 @@ def profile():
     # Đếm số lượng tải lên bằng SQL trực tiếp chỉ với các cột chính
     upload_count = db.session.execute(
         text("SELECT COUNT(*) FROM uploadedfiles WHERE userID = :user_id"), 
-        {"user_id": current_user.id}
+        {"user_id": current_user.userID}
     ).scalar()
     
     return render_template(
@@ -106,38 +87,49 @@ def profile():
         upload_count=upload_count
     )
 
-@auth_bp.route('/edit-profile', methods=['GET', 'POST'])
+@auth_bp.route('/profile/edit', methods=['GET', 'POST'])
 @login_required
 def edit_profile():
-    """Xử lý chỉnh sửa thông tin hồ sơ người dùng"""
+    """Xử lý chỉnh sửa hồ sơ người dùng"""
+    # Truyền current_user vào form để validate email gốc
     form = EditProfileForm(obj=current_user)
-    password_form = ChangePasswordForm()
-    notification_form = NotificationSettingsForm(obj=current_user)
     
-    if request.method == 'POST' and form.validate_on_submit():
-        # Kiểm tra xem email mới đã tồn tại chưa (nếu email thay đổi)
-        if form.email.data != current_user.email:
-            existing_user = User.query.filter_by(email=form.email.data).first()
-            if existing_user:
-                flash('Email này đã được sử dụng bởi tài khoản khác.', 'danger')
-                return redirect(url_for('auth.edit_profile'))
-        
-        # Cập nhật thông tin người dùng
-        current_user.username = form.username.data
+    if form.validate_on_submit():
+        # Kiểm tra email trùng lặp (trừ email của chính người dùng hiện tại)
+        existing_user = User.query.filter(User.email == form.email.data, User.userID != current_user.userID).first()
+        if existing_user:
+            flash('Email này đã được sử dụng bởi người dùng khác.', 'danger')
+            # Render lại template với lỗi thay vì redirect
+            return render_template('edit_profile.html', title='Chỉnh sửa Hồ sơ', form=form)
+
+        # Cập nhật thông tin User
+        current_user.firstName = form.firstName.data
+        current_user.lastName = form.lastName.data
         current_user.email = form.email.data
-        
-        db.session.commit()
-        
-        flash('Thông tin hồ sơ đã được cập nhật thành công.', 'success')
-        return redirect(url_for('auth.profile'))
-    
-    return render_template(
-        'edit_profile.html', 
-        title='Chỉnh sửa hồ sơ',
-        form=form,
-        password_form=password_form,
-        notification_form=notification_form
-    )
+        current_user.phone = form.phone.data # Cập nhật phone nếu có
+
+        # Nếu là Dietitian và có profile, cập nhật cả profile Dietitian
+        if current_user.role == 'Dietitian' and current_user.dietitian:
+            current_user.dietitian.firstName = form.firstName.data
+            current_user.dietitian.lastName = form.lastName.data
+            current_user.dietitian.email = form.email.data # Giữ email đồng bộ
+            current_user.dietitian.phone = form.phone.data
+            # Cập nhật các trường dietitian khác nếu có trong form
+            if hasattr(form, 'specialization'):
+                current_user.dietitian.specialization = form.specialization.data
+            if hasattr(form, 'notes'):
+                current_user.dietitian.notes = form.notes.data
+
+        try:
+            db.session.commit()
+            flash('Hồ sơ của bạn đã được cập nhật thành công!', 'success')
+            return redirect(url_for('auth.profile')) # Redirect về trang profile sau khi thành công
+        except Exception as e:
+            db.session.rollback()
+            flash(f'Lỗi khi cập nhật hồ sơ: {str(e)}', 'danger')
+
+    # Nếu là GET request hoặc form validation thất bại, render template
+    return render_template('edit_profile.html', title='Chỉnh sửa Hồ sơ', form=form)
 
 @auth_bp.route('/change-password', methods=['POST'])
 @login_required
@@ -150,16 +142,16 @@ def change_password():
     # notification_form = NotificationSettingsForm(obj=current_user)
     
     if password_form.validate_on_submit():
-        # Sử dụng phương thức verify_password của model User
-        if not current_user.verify_password(password_form.current_password.data):
+        # Sử dụng phương thức check_password của model User
+        if not current_user.check_password(password_form.current_password.data):
             flash('Mật khẩu hiện tại không đúng.', 'danger')
             # Chuyển hướng về trang edit profile, có thể cần trả về cả các form khác
             # return redirect(url_for('auth.edit_profile', _anchor='password'))
             # Tạm thời redirect về profile:
             return redirect(url_for('auth.profile'))
         
-        # Sử dụng setter của model User để cập nhật và hash mật khẩu mới
-        current_user.password = password_form.new_password.data
+        # Sử dụng phương thức set_password để cập nhật mật khẩu mới
+        current_user.set_password(password_form.new_password.data)
         
         try:
             db.session.commit()
@@ -267,16 +259,17 @@ def admin_edit_user(user_id):
             existing_user = User.query.filter_by(email=form.email.data).first()
             if existing_user:
                 flash('Email này đã được sử dụng bởi tài khoản khác.', 'danger')
-                return redirect(url_for('auth.admin_edit_user', user_id=user.id))
+                return redirect(url_for('auth.admin_edit_user', user_id=user.userID))
         
         # Cập nhật thông tin người dùng
-        user.username = form.username.data
+        user.firstName = form.firstName.data
+        user.lastName = form.lastName.data
         user.email = form.email.data
         if hasattr(form, 'bio'):
             user.bio = form.bio.data
         
         db.session.commit()
-        flash(f'Thông tin của người dùng {user.username} đã được cập nhật thành công.', 'success')
+        flash(f'Thông tin của người dùng {user.firstName} {user.lastName} đã được cập nhật thành công.', 'success')
         return redirect(url_for('auth.admin_users'))
     
     return render_template(
@@ -297,12 +290,12 @@ def admin_delete_user(user_id):
     user = User.query.get_or_404(user_id)
     
     # Ngăn chặn xóa chính mình
-    if user.id == current_user.id:
+    if user.userID == current_user.userID:
         flash('Bạn không thể xóa tài khoản của chính mình.', 'danger')
         return redirect(url_for('auth.admin_users'))
     
     # Lưu tên người dùng để hiển thị trong thông báo
-    username = user.username
+    username = f"{user.firstName} {user.lastName}"
     
     # Xóa người dùng
     db.session.delete(user)
@@ -322,17 +315,17 @@ def admin_toggle_role(user_id):
     user = User.query.get_or_404(user_id)
     
     # Ngăn chặn hạ cấp chính mình
-    if user.id == current_user.id:
+    if user.userID == current_user.userID:
         flash('Bạn không thể thay đổi vai trò của chính mình.', 'danger')
         return redirect(url_for('auth.admin_users'))
     
     # Chuyển đổi vai trò
     if user.role == 'Admin':
         user.role = 'Dietitian'
-        message = f'{user.username} đã được hạ cấp xuống Dietitian.'
+        message = f'{user.firstName} {user.lastName} đã được hạ cấp xuống Dietitian.'
     else:
         user.role = 'Admin'
-        message = f'{user.username} đã được nâng cấp lên Admin.'
+        message = f'{user.firstName} {user.lastName} đã được nâng cấp lên Admin.'
     
     db.session.commit()
     flash(message, 'success')
diff --git a/app/routes/dietitians.py b/app/routes/dietitians.py
index 000b373..53a1a34 100644
--- a/app/routes/dietitians.py
+++ b/app/routes/dietitians.py
@@ -5,79 +5,79 @@ from app.models.dietitian import Dietitian, DietitianStatus
 from app.models.patient import Patient, Encounter
 from sqlalchemy import desc, or_, func, text
 from datetime import datetime
+from app.models.user import User
 
 dietitians_bp = Blueprint('dietitians', __name__, url_prefix='/dietitians')
 
 @dietitians_bp.route('/')
 @login_required
 def index():
-    """Hiển thị danh sách chuyên gia dinh dưỡng, ưu tiên user hiện tại"""
-    
-    search_query = request.args.get('search', '')
-    status_filter = request.args.get('status', '')
+    """Danh sách chuyên gia dinh dưỡng"""
     page = request.args.get('page', 1, type=int)
-    per_page = 10
+    search = request.args.get('search', '')
+    status_filter = request.args.get('status', '')
+    sort_by = request.args.get('sort_by', 'dietitianID')
+    sort_dir = request.args.get('sort_dir', 'asc')
     
-    try:
-        # Lấy dietitian profile của user hiện tại (nếu có)
-        current_dietitian = None
-        if hasattr(current_user, 'dietitian_profile'):
-            current_dietitian = current_user.dietitian_profile
-            
-            # Nếu user có role là dietitian nhưng không có dietitian profile
-            if current_dietitian is None and current_user.role == 'Dietitian':
-                flash('Tài khoản của bạn có vai trò là chuyên gia dinh dưỡng nhưng chưa được liên kết với hồ sơ chuyên gia.', 'warning')
-
-        # Xây dựng truy vấn cơ bản
-        base_query = Dietitian.query
-
-        # Áp dụng bộ lọc tìm kiếm
-        if search_query:
-            search_term = f'%{search_query}%'
-            base_query = base_query.filter(
-                or_(
-                    Dietitian.firstName.like(search_term),
-                    Dietitian.lastName.like(search_term),
-                    Dietitian.email.like(search_term),
-                    # Cần chuyển đổi ID sang chuỗi để tìm kiếm LIKE
-                    func.cast(Dietitian.dietitianID, db.String).like(search_term) 
-                )
-            )
-
-        # Áp dụng bộ lọc trạng thái
-        if status_filter and status_filter != 'all':
+    query = Dietitian.query
+    
+    query = query.outerjoin(User, User.userID == Dietitian.user_id).filter(
+        or_(Dietitian.user_id == None, User.role != 'Admin')
+    )
+    
+    if search:
+        search_term = f'%{search}%'
+        search_filter = db.or_(
+            Dietitian.firstName.ilike(search_term),
+            Dietitian.lastName.ilike(search_term),
+            Dietitian.email.ilike(search_term),
+            Dietitian.specialization.ilike(search_term)
+        )
+        if search.upper().startswith('DT-') and search[3:].isdigit():
             try:
-                status_enum = DietitianStatus[status_filter.upper()]
-                base_query = base_query.filter(Dietitian.status == status_enum)
-            except KeyError:
-                flash(f'Trạng thái lọc không hợp lệ: {status_filter}', 'warning')
-
-        # Loại trừ dietitian hiện tại khỏi truy vấn chính (nếu có)
-        if current_dietitian:
-            query_others = base_query.filter(Dietitian.dietitianID != current_dietitian.dietitianID)
+                search_id = int(search[3:])
+                search_filter = db.or_(search_filter, Dietitian.dietitianID == search_id)
+            except ValueError:
+                pass
+        query = query.filter(search_filter)
+    
+    if status_filter and status_filter != 'all':
+        try:
+            status_enum = DietitianStatus[status_filter.upper()]
+            query = query.filter(Dietitian.status == status_enum)
+        except KeyError:
+            flash(f'Trạng thái lọc không hợp lệ: {status_filter}', 'warning')
+            pass
+    
+    if sort_dir == 'desc':
+        query = query.order_by(desc(getattr(Dietitian, sort_by)))
+    else:
+        query = query.order_by(getattr(Dietitian, sort_by))
+    
+    dietitians_pagination = query.paginate(page=page, per_page=10)
+    
+    if current_user.is_authenticated:
+        if hasattr(current_user, 'dietitian') and current_user.dietitian:
+            current_dietitian = current_user.dietitian
+            other_dietitians = [d for d in dietitians_pagination.items if d.dietitianID != current_dietitian.dietitianID]
         else:
-            query_others = base_query
-        
-        # Sắp xếp theo lastName, firstName
-        query_others = query_others.order_by(Dietitian.lastName, Dietitian.firstName)
-
-        # Thực hiện phân trang cho các dietitian khác
-        pagination = query_others.paginate(page=page, per_page=per_page, error_out=False)
-        other_dietitians = pagination.items
-
-    except Exception as e:
-        flash(f'Lỗi khi truy vấn dữ liệu chuyên gia dinh dưỡng: {str(e)}', 'error')
+            current_dietitian = None
+            other_dietitians = dietitians_pagination.items
+    else:
         current_dietitian = None
-        other_dietitians = []
-        pagination = None # Đảm bảo pagination có giá trị
-    
-    return render_template('dietitians/index.html', 
-                           current_dietitian=current_dietitian, 
-                           other_dietitians=other_dietitians,
-                           pagination=pagination, # Truyền đối tượng pagination
-                           search_query=search_query,
-                           status_filter=status_filter,
-                           status_options=DietitianStatus)
+        other_dietitians = dietitians_pagination.items
+
+    return render_template(
+        'dietitians/index.html',
+        dietitians=dietitians_pagination,
+        search_query=search,
+        status_filter=status_filter,
+        sort_by=sort_by,
+        sort_dir=sort_dir,
+        status_options=DietitianStatus,
+        current_dietitian=current_dietitian,
+        other_dietitians=other_dietitians
+    )
 
 @dietitians_bp.route('/<int:id>')
 @login_required
@@ -131,45 +131,62 @@ def new():
 @login_required
 def edit(id):
     """Chỉnh sửa chuyên gia dinh dưỡng"""
-    # Sử dụng .first_or_404() để xử lý trường hợp không tìm thấy dietitian
     dietitian = Dietitian.query.filter_by(dietitianID=id).first_or_404()
     
     # Kiểm tra quyền: chỉ admin hoặc chính dietitian đó mới được sửa
-    if not current_user.is_admin and (not dietitian.user or dietitian.user_id != current_user.id):
+    if not current_user.is_admin and (not dietitian.user or dietitian.user_id != current_user.userID):
         flash('Bạn không có quyền chỉnh sửa thông tin này.', 'danger')
         return redirect(url_for('dietitians.index'))
-
+    
+    # Nếu user đang sửa profile của chính mình, chuyển hướng đến edit_profile
+    if dietitian.user and dietitian.user_id == current_user.userID:
+        return redirect(url_for('auth.edit_profile'))
+    
+    # Nếu là admin đang sửa thông tin dietitian khác
     if request.method == 'POST':
-        # Cập nhật dữ liệu
-        dietitian.firstName = request.form.get('firstName', dietitian.firstName)
-        dietitian.lastName = request.form.get('lastName', dietitian.lastName)
-        dietitian.email = request.form.get('email', dietitian.email)
-        dietitian.phone = request.form.get('phone', dietitian.phone)
-        dietitian.specialization = request.form.get('specialization', dietitian.specialization)
-        dietitian.notes = request.form.get('notes', dietitian.notes)
-        status_str = request.form.get('status', dietitian.status.name) # Lấy name thay vì value
-
-        # Chuyển đổi status string thành enum
+        # Lấy dữ liệu form
+        firstName = request.form.get('firstName', '').strip()
+        lastName = request.form.get('lastName', '').strip()
+        email = request.form.get('email', '').strip()
+        phone = request.form.get('phone', '').strip()
+        specialization = request.form.get('specialization', '').strip()
+        notes = request.form.get('notes', '').strip()
+        
+        # Kiểm tra dữ liệu
+        if not firstName or not lastName or not email:
+            flash('Họ, tên và email là bắt buộc.', 'danger')
+            return render_template('dietitians/edit_admin.html', dietitian=dietitian, status_options=DietitianStatus)
+        
         try:
-            status_upper = status_str.upper()
-            if status_upper not in [item.name for item in DietitianStatus]:
-                raise ValueError(f"Giá trị enum không hợp lệ: {status_upper}")
-            status_enum = DietitianStatus[status_upper]
-            dietitian.status = status_enum
-        except (ValueError, KeyError) as e:
-            flash(f'Trạng thái không hợp lệ: {status_str} - Lỗi: {str(e)}', 'error')
-            # Không return ngay, để user có thể sửa lại form
-        else: # Chỉ commit nếu không có lỗi trạng thái
-            try:
-                db.session.commit()
-                flash('Cập nhật chuyên gia dinh dưỡng thành công!', 'success')
-                return redirect(url_for('dietitians.show', id=dietitian.dietitianID))
-            except Exception as e:
-                db.session.rollback()
-                flash(f'Lỗi khi cập nhật: {str(e)}', 'error')
-    
-    # Truyền cả dietitian và status_options vào template
-    return render_template('dietitians/edit.html', dietitian=dietitian, status_options=DietitianStatus)
+            # Cập nhật thông tin dietitian
+            dietitian.firstName = firstName
+            dietitian.lastName = lastName
+            dietitian.email = email
+            dietitian.phone = phone
+            dietitian.specialization = specialization
+            dietitian.notes = notes
+            # Trạng thái không cho sửa trực tiếp ở đây
+            
+            # Đồng bộ ngược lại User nếu có thay đổi email, phone (tùy chọn)
+            if dietitian.user:
+                dietitian.user.firstName = dietitian.firstName
+                dietitian.user.lastName = dietitian.lastName
+                dietitian.user.email = dietitian.email
+                dietitian.user.phone = dietitian.phone
+            
+            db.session.commit()
+            flash('Cập nhật thông tin thành công!', 'success')
+            return redirect(url_for('dietitians.show', id=dietitian.dietitianID))
+        except Exception as e:
+            db.session.rollback()
+            flash(f'Có lỗi xảy ra: {str(e)}', 'danger')
+            # Render lại form với dietitian object
+            return render_template('dietitians/edit_admin.html', dietitian=dietitian, status_options=DietitianStatus)
+
+    # GET request: hiển thị form chỉnh sửa (dùng template riêng cho admin sửa)
+    # Lưu ý: Cần tạo template edit_admin.html hoặc điều chỉnh edit.html cũ
+    # Sử dụng một template riêng như edit_admin.html sẽ rõ ràng hơn
+    return render_template('dietitians/edit_admin.html', dietitian=dietitian, status_options=DietitianStatus)
 
 @dietitians_bp.route('/<int:id>/delete', methods=['POST'])
 @login_required
@@ -254,81 +271,4 @@ def unassign_patient(id, patient_id):
     except Exception as e:
         db.session.rollback()
         flash(f'Đã xảy ra lỗi: {str(e)}', 'error')
-    return redirect(url_for('dietitians.show', id=id))
-
-@dietitians_bp.route('/link_profile', methods=['GET', 'POST'])
-@login_required
-def link_profile():
-    """Liên kết tài khoản người dùng với hồ sơ dietitian"""
-    # Chỉ cho phép user có vai trò dietitian sử dụng tính năng này
-    if current_user.role != 'Dietitian':
-        flash('Chỉ người dùng có vai trò chuyên gia dinh dưỡng mới có thể liên kết hồ sơ.', 'error')
-        return redirect(url_for('dietitians.index'))
-    
-    # Kiểm tra nếu user đã có dietitian_profile
-    if current_user.dietitian_profile:
-        flash('Tài khoản của bạn đã được liên kết với hồ sơ chuyên gia dinh dưỡng.', 'info')
-        return redirect(url_for('dietitians.show', id=current_user.dietitian_profile.dietitianID))
-    
-    if request.method == 'POST':
-        action = request.form.get('action')
-        
-        if action == 'create_new':
-            # Tạo mới hồ sơ dietitian
-            firstName = request.form.get('firstName')
-            lastName = request.form.get('lastName')
-            email = request.form.get('email', current_user.email)
-            phone = request.form.get('phone')
-            specialization = request.form.get('specialization')
-            
-            # Tạo đối tượng dietitian mới
-            dietitian = Dietitian(
-                firstName=firstName,
-                lastName=lastName,
-                email=email,
-                phone=phone,
-                specialization=specialization,
-                status=DietitianStatus.AVAILABLE,
-                user_id=current_user.userID  # Liên kết với user hiện tại
-            )
-            
-            try:
-                db.session.add(dietitian)
-                db.session.commit()
-                flash('Đã tạo và liên kết hồ sơ chuyên gia dinh dưỡng thành công!', 'success')
-                return redirect(url_for('dietitians.show', id=dietitian.dietitianID))
-            except Exception as e:
-                db.session.rollback()
-                flash(f'Lỗi khi tạo hồ sơ: {str(e)}', 'error')
-        
-        elif action == 'link_existing':
-            # Liên kết với hồ sơ hiện có
-            dietitian_id = request.form.get('dietitian_id')
-            if not dietitian_id:
-                flash('Vui lòng chọn một hồ sơ để liên kết.', 'error')
-                return redirect(url_for('dietitians.link_profile'))
-            
-            try:
-                dietitian = Dietitian.query.get(int(dietitian_id))
-                if not dietitian:
-                    flash('Không tìm thấy hồ sơ chuyên gia dinh dưỡng.', 'error')
-                    return redirect(url_for('dietitians.link_profile'))
-                
-                # Kiểm tra xem hồ sơ đã được liên kết với user khác chưa
-                if dietitian.user_id and dietitian.user_id != current_user.userID:
-                    flash('Hồ sơ này đã được liên kết với một tài khoản khác.', 'error')
-                    return redirect(url_for('dietitians.link_profile'))
-                
-                # Liên kết hồ sơ với user hiện tại
-                dietitian.user_id = current_user.userID
-                db.session.commit()
-                flash('Đã liên kết hồ sơ chuyên gia dinh dưỡng thành công!', 'success')
-                return redirect(url_for('dietitians.show', id=dietitian.dietitianID))
-            except Exception as e:
-                db.session.rollback()
-                flash(f'Lỗi khi liên kết hồ sơ: {str(e)}', 'error')
-    
-    # Lấy danh sách dietitian chưa được liên kết với user nào
-    unlinked_dietitians = Dietitian.query.filter(Dietitian.user_id.is_(None)).all()
-    
-    return render_template('dietitians/link_profile.html', unlinked_dietitians=unlinked_dietitians) 
\ No newline at end of file
+    return redirect(url_for('dietitians.show', id=id)) 
\ No newline at end of file
diff --git a/app/templates/auth_base.html b/app/templates/auth_base.html
index 8ee31fe..d61f312 100644
--- a/app/templates/auth_base.html
+++ b/app/templates/auth_base.html
@@ -33,10 +33,11 @@
         }
         
         .auth-container {
-            max-width: 600px;
+            max-width: 650px;
+            min-width: 550px;
             width: 100%;
             margin: 2rem auto;
-            padding: 2.5rem;
+            padding: 2.5rem 3.5rem;
             background-color: white;
             border-radius: 1rem;
             box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
diff --git a/app/templates/base.html b/app/templates/base.html
index a27125f..f27b1f0 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -117,9 +117,10 @@
         
         .sidebar-toggle {
             position: absolute;
-            bottom: 20px;
+            top: 20px;
             right: -15px;
-            background: white;
+            background: #2563eb;
+            color: white;
             width: 30px;
             height: 30px;
             border-radius: 50%;
@@ -197,19 +198,32 @@
             justify-content: center;
         }
         
+        /* Dropdown menus */
         .dropdown-menu {
             opacity: 0;
             visibility: hidden;
             transform: translateY(10px);
-            transition: all 0.3s ease;
+            /* Delay hiding visibility until opacity transition is done */
+            transition: opacity 0.3s ease, transform 0.3s ease, visibility 0s linear 0.3s;
+            pointer-events: none; /* Prevent interaction when hidden */
         }
         
-        .dropdown:hover .dropdown-menu {
+        /* Visible state for dropdown menus */
+        .dropdown-menu.visible {
             opacity: 1;
             visibility: visible;
             transform: translateY(0);
+            /* Show visibility immediately when becoming visible */
+            transition: opacity 0.3s ease, transform 0.3s ease, visibility 0s linear 0s;
+            pointer-events: auto; /* Allow interaction when visible */
         }
         
+        /* Remove hover effect for dropdowns */
+        /* .dropdown.profile-dropdown:hover .dropdown-menu { ... } */ 
+
+        /* Remove :not(.hidden) rule as we use .visible now */
+        /* .dropdown-menu:not(.hidden) { ... } */
+        
         /* Flash messages */
         .alert-message {
             transition: all 0.5s ease;
@@ -237,7 +251,7 @@
             <div class="flex items-center justify-between mb-10">
                 <h2 class="text-xl font-bold animate-pulse-slow">CCU HTM</h2>
                 <div class="sidebar-toggle" id="sidebarToggle">
-                    <i class="fas fa-chevron-left"></i>
+                    <i class="fas fa-chevron-left text-blue-600"></i>
                 </div>
             </div>
             
@@ -278,7 +292,6 @@
                 </ul>
             </nav>
         </div>
-        {% endif %}
 
         <!-- Content with Header -->
         <div id="content-wrapper" class="content-wrapper flex-1 overflow-auto {% if not current_user.is_authenticated %}w-full ml-0{% endif %}">
@@ -294,14 +307,15 @@
                         <div class="flex items-center space-x-4">
                             <!-- Notifications -->
                             <div class="relative dropdown">
-                                <button class="p-2 text-gray-600 hover:text-blue-600 focus:outline-none">
+                                <button id="notificationButton" class="p-2 text-gray-600 hover:text-blue-600 focus:outline-none">
                                     <i class="fas fa-bell text-lg"></i>
                                     <span class="notification-badge">3</span>
                                 </button>
                                 
-                                <div class="dropdown-menu absolute right-0 mt-2 w-72 bg-white rounded-lg shadow-lg z-50 py-2">
-                                    <div class="px-4 py-2 border-b border-gray-200">
-                                        <h3 class="font-bold text-gray-800">Notifications</h3>
+                                <div id="notificationMenu" class="dropdown-menu absolute right-0 mt-2 w-72 bg-white rounded-lg shadow-lg z-50 py-2">
+                                    <div class="flex items-center justify-between px-4 py-2 border-b border-gray-100">
+                                        <h5 class="font-semibold text-gray-700">Thông báo</h5>
+                                        <span class="px-2 py-1 bg-blue-100 text-blue-700 rounded-lg text-xs">3 mới</span>
                                     </div>
                                     
                                     <div class="max-h-64 overflow-y-auto">
@@ -311,7 +325,7 @@
                                                     <i class="fas fa-info-circle text-blue-600"></i>
                                                 </div>
                                                 <div class="ml-3">
-                                                    <p class="text-sm font-medium text-gray-900">Welcome {{ current_user.username }}</p>
+                                                    <p class="text-sm font-medium text-gray-900">Welcome {{ current_user.full_name }}</p>
                                                     <p class="text-xs text-gray-500">Just now</p>
                                                 </div>
                                             </div>
@@ -346,26 +360,30 @@
                                 </div>
                             </div>
                             
-                            <!-- User Profile -->
-                            <div class="relative dropdown">
-                                <button class="flex items-center text-gray-700 hover:text-blue-600 focus:outline-none">
-                                    <span class="mr-2 hidden md:block">{{ current_user.username }}</span>
-                                    <div class="h-8 w-8 rounded-full bg-blue-500 flex items-center justify-center text-white">
-                                        <i class="fas fa-user"></i>
+                            <!-- User profile dropdown -->
+                            <div class="relative inline-block text-left dropdown profile-dropdown">
+                                <button class="flex items-center justify-center text-sm font-medium text-gray-700 hover:text-gray-900" type="button" id="dropdownMenuButton">
+                                    <span class="mr-2">{{ current_user.firstName }} {{ current_user.lastName }}</span>
+                                    <div class="w-8 h-8 rounded-full overflow-hidden bg-blue-500 flex items-center justify-center">
+                                        {% if current_user.profile_image %}
+                                            <img src="{{ current_user.profile_image }}" alt="Avatar" class="w-full h-full object-cover">
+                                        {% else %}
+                                            <span class="text-white text-sm font-bold">{{ current_user.firstName[0] }}{{ current_user.lastName[0] }}</span>
+                                        {% endif %}
                                     </div>
                                 </button>
-                                
-                                <div class="dropdown-menu absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg z-50 py-2">
-                                    <a href="{{ url_for('auth.profile') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
-                                        <i class="fas fa-user-circle mr-2"></i> My Profile
-                                    </a>
-                                    <a href="{{ url_for('auth.edit_profile') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
-                                        <i class="fas fa-cog mr-2"></i> Settings
-                                    </a>
-                                    <div class="border-t border-gray-200 my-1"></div>
-                                    <a href="{{ url_for('auth.logout') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
-                                        <i class="fas fa-sign-out-alt mr-2"></i> Logout
-                                    </a>
+                                <div id="userDropdownMenu" class="dropdown-menu absolute right-0 mt-2 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 z-50">
+                                    <div class="py-1" role="menu" aria-orientation="vertical" aria-labelledby="dropdownMenuButton">
+                                        <a href="{{ url_for('auth.profile') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" role="menuitem">
+                                            <i class="fas fa-user mr-2"></i> Xem Hồ sơ
+                                        </a>
+                                        <a href="{{ url_for('auth.edit_profile') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" role="menuitem">
+                                            <i class="fas fa-user-edit mr-2"></i> Chỉnh sửa Hồ sơ
+                                        </a>
+                                        <a href="{{ url_for('auth.logout') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" role="menuitem">
+                                            <i class="fas fa-sign-out-alt mr-2"></i> Đăng xuất
+                                        </a>
+                                    </div>
                                 </div>
                             </div>
                         </div>
@@ -414,6 +432,7 @@
                 </div>
             </div>
         </div>
+        {% endif %}
     </div>
 
     <!-- Footer -->
@@ -462,6 +481,64 @@
                     }
                 });
             }
+            
+            // User dropdown menu functionality
+            const dropdownButton = document.getElementById('dropdownMenuButton');
+            const dropdownMenu = document.getElementById('userDropdownMenu'); // Use specific ID
+            
+            // Notification dropdown menu functionality
+            const notificationButton = document.getElementById('notificationButton');
+            const notificationMenu = document.getElementById('notificationMenu');
+            
+            // Function to close all dropdowns
+            function closeAllDropdowns() {
+                if (dropdownMenu) dropdownMenu.classList.remove('visible');
+                if (notificationMenu) notificationMenu.classList.remove('visible');
+            }
+            
+            // Toggle user dropdown
+            if (dropdownButton && dropdownMenu) {
+                dropdownButton.addEventListener('click', function(event) {
+                    event.stopPropagation();
+                    const isVisible = dropdownMenu.classList.contains('visible');
+                    closeAllDropdowns(); // Close others first
+                    if (!isVisible) {
+                        dropdownMenu.classList.add('visible');
+                    }
+                });
+            }
+            
+            // Toggle notification dropdown
+            if (notificationButton && notificationMenu) {
+                notificationButton.addEventListener('click', function(event) {
+                    event.stopPropagation();
+                    const isVisible = notificationMenu.classList.contains('visible');
+                    closeAllDropdowns(); // Close others first
+                    if (!isVisible) {
+                        notificationMenu.classList.add('visible');
+                    }
+                });
+            }
+            
+            // Close dropdowns when clicking outside
+            document.addEventListener('click', function(event) {
+                // Check if the click is outside both dropdowns and their buttons
+                const isOutsideUser = dropdownButton && !dropdownButton.contains(event.target) && dropdownMenu && !dropdownMenu.contains(event.target);
+                const isOutsideNotification = notificationButton && !notificationButton.contains(event.target) && notificationMenu && !notificationMenu.contains(event.target);
+                
+                // Only close if the click is outside the currently open dropdown
+                if ((dropdownMenu && dropdownMenu.classList.contains('visible') && isOutsideUser) ||
+                    (notificationMenu && notificationMenu.classList.contains('visible') && isOutsideNotification)) {
+                   // Check again to be sure, might not be needed but safer
+                   if (isOutsideUser && isOutsideNotification) {
+                     closeAllDropdowns();
+                   } else if (dropdownMenu.classList.contains('visible') && isOutsideUser) {
+                       closeAllDropdowns(); // Close all if clicking outside user dropdown
+                   } else if (notificationMenu.classList.contains('visible') && isOutsideNotification) {
+                        closeAllDropdowns(); // Close all if clicking outside notification dropdown
+                   }
+                } 
+            });
         });
     </script>
     
diff --git a/app/templates/dietitians/edit.html b/app/templates/dietitians/edit.html
deleted file mode 100644
index 3d248a1..0000000
--- a/app/templates/dietitians/edit.html
+++ /dev/null
@@ -1,104 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}Chỉnh sửa chuyên gia dinh dưỡng - CCU HTM{% endblock %}
-
-{% block header %}Chỉnh sửa thông tin chuyên gia dinh dưỡng{% endblock %}
-
-{% block content %}
-<div class="container mx-auto px-4 py-6">
-    <!-- Breadcrumb -->
-    <div class="mb-6">
-        <nav class="flex" aria-label="Breadcrumb">
-            <ol class="inline-flex items-center space-x-1 md:space-x-3">
-                <li class="inline-flex items-center">
-                    <a href="{{ url_for('handle_root') }}" class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-blue-600 transition duration-200">
-                        <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"></path></svg>
-                        Trang chủ
-                    </a>
-                </li>
-                <li>
-                    <div class="flex items-center">
-                        <svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
-                        <a href="{{ url_for('dietitians.index') }}" class="ml-1 text-sm font-medium text-gray-700 hover:text-blue-600 md:ml-2 transition duration-200">Chuyên gia dinh dưỡng</a>
-                    </div>
-                </li>
-                <li>
-                    <div class="flex items-center">
-                        <svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
-                        <a href="{{ url_for('dietitians.show', id=dietitian.dietitianID) }}" class="ml-1 text-sm font-medium text-gray-700 hover:text-blue-600 md:ml-2 transition duration-200">{{ dietitian.fullName }}</a>
-                    </div>
-                </li>
-                <li aria-current="page">
-                    <div class="flex items-center">
-                        <svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
-                        <span class="ml-1 text-sm font-medium text-gray-500 md:ml-2">Chỉnh sửa</span>
-                    </div>
-                </li>
-            </ol>
-        </nav>
-    </div>
-
-    <div class="max-w-4xl mx-auto">
-        <div class="bg-white shadow overflow-hidden sm:rounded-lg">
-            <div class="px-4 py-5 sm:px-6 border-b border-gray-200">
-                <h3 class="text-lg leading-6 font-medium text-gray-900">Chỉnh sửa thông tin chuyên gia dinh dưỡng</h3>
-                <p class="mt-1 max-w-2xl text-sm text-gray-500">Cập nhật thông tin chi tiết cho chuyên gia dinh dưỡng.</p>
-            </div>
-
-            <form method="POST" action="{{ url_for('dietitians.update', id=dietitian.dietitianID) }}" class="px-4 py-5 sm:p-6">
-                <div class="grid grid-cols-6 gap-6">
-                    <div class="col-span-6 sm:col-span-3">
-                        <label for="firstName" class="block text-sm font-medium text-gray-700">Tên</label>
-                        <input type="text" name="firstName" id="firstName" value="{{ dietitian.firstName }}" class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" required>
-                    </div>
-
-                    <div class="col-span-6 sm:col-span-3">
-                        <label for="lastName" class="block text-sm font-medium text-gray-700">Họ</label>
-                        <input type="text" name="lastName" id="lastName" value="{{ dietitian.lastName }}" class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" required>
-                    </div>
-
-                    <div class="col-span-6 sm:col-span-3">
-                        <label for="email" class="block text-sm font-medium text-gray-700">Email</label>
-                        <input type="email" name="email" id="email" value="{{ dietitian.email }}" class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" required>
-                    </div>
-
-                    <div class="col-span-6 sm:col-span-3">
-                        <label for="phone" class="block text-sm font-medium text-gray-700">Số điện thoại</label>
-                        <input type="text" name="phone" id="phone" value="{{ dietitian.phone }}" class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
-                    </div>
-
-                    <div class="col-span-6">
-                        <label for="specialization" class="block text-sm font-medium text-gray-700">Chuyên môn</label>
-                        <input type="text" name="specialization" id="specialization" value="{{ dietitian.specialization }}" class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
-                    </div>
-
-                    <div class="col-span-6">
-                        <label for="notes" class="block text-sm font-medium text-gray-700">Ghi chú</label>
-                        <textarea name="notes" id="notes" rows="3" class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">{{ dietitian.notes }}</textarea>
-                    </div>
-
-                    <div class="col-span-6">
-                        <label for="status" class="block text-sm font-medium text-gray-700">Trạng thái</label>
-                        <select id="status" name="status" class="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm">
-                            <option value="available" {% if dietitian.status.value == 'available' %}selected{% endif %}>Khả dụng</option>
-                            <option value="unavailable" {% if dietitian.status.value == 'unavailable' %}selected{% endif %}>Không khả dụng</option>
-                            <option value="on_leave" {% if dietitian.status.value == 'on_leave' %}selected{% endif %}>Nghỉ phép</option>
-                        </select>
-                    </div>
-                </div>
-
-                <div class="pt-5 mt-4 border-t border-gray-200">
-                    <div class="flex justify-end">
-                        <a href="{{ url_for('dietitians.show', id=dietitian.dietitianID) }}" class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition duration-200">
-                            Hủy
-                        </a>
-                        <button type="submit" class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition duration-200">
-                            Cập nhật
-                        </button>
-                    </div>
-                </div>
-            </form>
-        </div>
-    </div>
-</div>
-{% endblock %} 
\ No newline at end of file
diff --git a/app/templates/dietitians/index.html b/app/templates/dietitians/index.html
index 70b3b35..3857a07 100644
--- a/app/templates/dietitians/index.html
+++ b/app/templates/dietitians/index.html
@@ -55,7 +55,7 @@
                     </select>
                 </div>
                 <div class="flex space-x-2">
-                    <button type="submit" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition duration-200 w-full justify-center">
+                    <button type="submit" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition duration-200 w-full justify-center">
                         Lọc
                     </button>
                     <a href="{{ url_for('dietitians.index') }}" class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md shadow-sm text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition duration-200 w-full justify-center">
@@ -75,41 +75,39 @@
         <div class="border-t border-gray-200 px-4 py-5 sm:p-0">
             <div class="overflow-x-auto">
                 <table class="min-w-full divide-y divide-gray-200">
-                    <thead class="bg-gray-50">
+                    <thead class="bg-gray-100">
                         <tr>
-                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Chuyên gia</th>
-                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Liên hệ</th>
-                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Chuyên môn</th>
-                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Trạng thái</th>
-                            <th scope="col" class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Thao tác</th>
+                            <th scope="col" class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Chuyên gia</th>
+                            <th scope="col" class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Liên hệ</th>
+                            <th scope="col" class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Chuyên môn</th>
+                            <th scope="col" class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Trạng thái</th>
+                            <th scope="col" class="px-6 py-3 text-right text-xs font-semibold text-gray-600 uppercase tracking-wider">Thao tác</th>
                         </tr>
                     </thead>
                     <tbody class="bg-white divide-y divide-gray-200">
-                        <tr>
+                        <tr class="bg-blue-50 hover:bg-blue-100 transition duration-150">
                             <td class="px-6 py-4 whitespace-nowrap">
                                 <div class="flex items-center">
-                                    <!-- Avatar placeholder -->
                                     <div class="flex-shrink-0 h-10 w-10">
-                                        <span class="inline-flex items-center justify-center h-10 w-10 rounded-full bg-blue-100">
-                                            <span class="font-medium text-blue-700">{{ current_dietitian.firstName[0] }}{{ current_dietitian.lastName[0] }}</span>
+                                        <span class="inline-flex items-center justify-center h-10 w-10 rounded-full bg-blue-200 text-blue-800 font-bold">
+                                            {{ current_user.firstName[0] }}{{ current_user.lastName[0] }}
                                         </span>
                                     </div>
                                     <div class="ml-4">
-                                        <div class="text-sm font-medium text-gray-900">{{ current_dietitian.fullName }}</div>
-                                        <div class="text-sm text-gray-500">{{ current_dietitian.formattedID }}</div>
+                                        <div class="text-sm font-semibold text-gray-900">{{ current_user.firstName }} {{ current_user.lastName }}</div>
+                                        <div class="text-sm text-blue-700">{{ current_dietitian.formattedID }}</div>
                                     </div>
                                 </div>
                             </td>
                             <td class="px-6 py-4 whitespace-nowrap">
-                                <div class="text-sm text-gray-900">{{ current_dietitian.email or 'N/A' }}</div>
-                                <div class="text-sm text-gray-500">{{ current_dietitian.phone or 'N/A' }}</div>
+                                <div class="text-sm font-medium text-gray-800">{{ current_user.email or 'N/A' }}</div>
+                                <div class="text-sm text-gray-600">{{ current_user.phone or 'N/A' }}</div>
                             </td>
-                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ current_dietitian.specialization or 'N/A' }}</td>
+                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-700">{{ current_dietitian.specialization or 'N/A' }}</td>
                             <td class="px-6 py-4 whitespace-nowrap">{{ status_badge(current_dietitian.status.value) }}</td>
                             <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
-                                <a href="{{ url_for('dietitians.show', id=current_dietitian.dietitianID) }}" class="text-primary-600 hover:text-primary-900 mr-3 transition duration-200">Chi tiết</a>
-                                <a href="{{ url_for('dietitians.edit', id=current_dietitian.dietitianID) }}" class="text-indigo-600 hover:text-indigo-900 mr-3 transition duration-200">Sửa</a>
-                                <!-- Chỉ Admin mới thấy nút xóa -->
+                                <a href="{{ url_for('dietitians.show', id=current_dietitian.dietitianID) }}" class="text-blue-600 hover:text-blue-800 mr-3 transition duration-200">Chi tiết</a>
+                                <a href="{{ url_for('auth.edit_profile') }}" class="text-indigo-600 hover:text-indigo-900 mr-3 transition duration-200">Sửa</a>
                                 {% if current_user.is_admin %}
                                 <form action="{{ url_for('dietitians.delete', id=current_dietitian.dietitianID) }}" method="POST" class="inline-block" onsubmit="return confirm('Bạn có chắc chắn muốn xóa chuyên gia dinh dưỡng này?');">
                                     <button type="submit" class="text-red-600 hover:text-red-900 transition duration-200">Xóa</button>
@@ -122,31 +120,6 @@
             </div>
         </div>
     </div>
-    {% elif current_user.role == 'Dietitian' %}
-    <div class="mb-8 bg-gradient-to-r from-yellow-50 to-amber-50 shadow sm:rounded-lg border border-amber-200">
-        <div class="px-4 py-5 sm:px-6">
-            <h3 class="text-lg leading-6 font-medium text-gray-900">Chưa có hồ sơ chuyên gia dinh dưỡng</h3>
-        </div>
-        <div class="border-t border-gray-200 px-4 py-5">
-            <p class="text-gray-700 mb-4">Tài khoản của bạn có vai trò là chuyên gia dinh dưỡng nhưng chưa được liên kết với hồ sơ chuyên gia.</p>
-            <div class="flex space-x-4">
-                <a href="{{ url_for('dietitians.link_profile') }}" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition duration-200">
-                    <svg class="-ml-1 mr-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
-                        <path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd" />
-                    </svg>
-                    Tạo hoặc liên kết hồ sơ
-                </a>
-                {% if current_user.is_admin %}
-                <a href="{{ url_for('dietitians.new') }}" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-200">
-                    <svg class="-ml-1 mr-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
-                        <path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd" />
-                    </svg>
-                    Tạo hồ sơ mới (Admin)
-                </a>
-                {% endif %}
-            </div>
-        </div>
-    </div>
     {% endif %}
 
     <!-- Bảng Các Dietitian Khác -->
@@ -179,7 +152,7 @@
                                             </span>
                                         </div>
                                         <div class="ml-4">
-                                            <div class="text-sm font-medium text-gray-900">{{ dietitian.fullName }}</div>
+                                            <div class="text-sm font-medium text-gray-900">{{ dietitian.firstName }} {{ dietitian.lastName }}</div>
                                             <div class="text-sm text-gray-500">{{ dietitian.formattedID }}</div>
                                         </div>
                                     </div>
@@ -213,9 +186,9 @@
         </div>
         
         <!-- Phân trang -->
-        {% if pagination and pagination.pages > 1 %}
+        {% if dietitians and dietitians.pages > 1 %}
             <div class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6">
-                {{ render_pagination(pagination, 'dietitians.index', search=search_query, status=status_filter) }}
+                {{ render_pagination(dietitians, 'dietitians.index', search=search_query, status=status_filter) }}
             </div>
         {% endif %}
     </div>
diff --git a/app/templates/dietitians/link_profile.html b/app/templates/dietitians/link_profile.html
deleted file mode 100644
index 3edfae8..0000000
--- a/app/templates/dietitians/link_profile.html
+++ /dev/null
@@ -1,121 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}Liên kết hồ sơ Chuyên gia dinh dưỡng - CCU HTM{% endblock %}
-
-{% block header %}Liên kết hồ sơ Chuyên gia dinh dưỡng{% endblock %}
-
-{% block content %}
-<div class="container mx-auto px-4 py-6">
-    <!-- Breadcrumb -->
-    <nav class="mb-6" aria-label="Breadcrumb">
-        <ol class="inline-flex items-center space-x-1 md:space-x-3">
-            <li class="inline-flex items-center">
-                <a href="{{ url_for('handle_root') }}" class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-primary-600 transition duration-200">
-                    <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"></path></svg>
-                    Trang chủ
-                </a>
-            </li>
-            <li>
-                <div class="flex items-center">
-                    <svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
-                    <a href="{{ url_for('dietitians.index') }}" class="ml-1 text-sm font-medium text-gray-700 hover:text-primary-600 md:ml-2 transition duration-200">Chuyên gia dinh dưỡng</a>
-                </div>
-            </li>
-            <li aria-current="page">
-                <div class="flex items-center">
-                    <svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
-                    <span class="ml-1 text-sm font-medium text-gray-500 md:ml-2">Liên kết hồ sơ</span>
-                </div>
-            </li>
-        </ol>
-    </nav>
-
-    <div class="flex justify-between items-center mb-6">
-        <h1 class="text-2xl font-semibold text-gray-900">Liên kết hồ sơ Chuyên gia dinh dưỡng</h1>
-    </div>
-
-    <div class="bg-white shadow rounded-lg overflow-hidden mb-6">
-        <div class="px-6 py-5 border-b border-gray-200">
-            <h2 class="text-lg font-medium text-gray-900">Tạo hồ sơ mới</h2>
-            <p class="mt-1 text-sm text-gray-600">Tạo và liên kết hồ sơ chuyên gia dinh dưỡng mới với tài khoản của bạn.</p>
-        </div>
-        <div class="px-6 py-4">
-            <form method="POST" action="{{ url_for('dietitians.link_profile') }}">
-                <input type="hidden" name="action" value="create_new">
-                
-                <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-4">
-                    <div>
-                        <label for="firstName" class="block text-sm font-medium text-gray-700">Tên</label>
-                        <input type="text" name="firstName" id="firstName" required class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
-                    </div>
-                    <div>
-                        <label for="lastName" class="block text-sm font-medium text-gray-700">Họ</label>
-                        <input type="text" name="lastName" id="lastName" required class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
-                    </div>
-                </div>
-
-                <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-4">
-                    <div>
-                        <label for="email" class="block text-sm font-medium text-gray-700">Email</label>
-                        <input type="email" name="email" id="email" value="{{ current_user.email }}" class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
-                    </div>
-                    <div>
-                        <label for="phone" class="block text-sm font-medium text-gray-700">Số điện thoại</label>
-                        <input type="text" name="phone" id="phone" class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
-                    </div>
-                </div>
-
-                <div class="mb-4">
-                    <label for="specialization" class="block text-sm font-medium text-gray-700">Chuyên môn</label>
-                    <input type="text" name="specialization" id="specialization" class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
-                </div>
-
-                <div class="flex justify-end">
-                    <button type="submit" class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
-                        Tạo hồ sơ
-                    </button>
-                </div>
-            </form>
-        </div>
-    </div>
-
-    {% if unlinked_dietitians %}
-    <div class="bg-white shadow rounded-lg overflow-hidden">
-        <div class="px-6 py-5 border-b border-gray-200">
-            <h2 class="text-lg font-medium text-gray-900">Liên kết với hồ sơ có sẵn</h2>
-            <p class="mt-1 text-sm text-gray-600">Liên kết tài khoản của bạn với một hồ sơ chuyên gia dinh dưỡng đã có sẵn trong hệ thống.</p>
-        </div>
-        <div class="px-6 py-4">
-            <form method="POST" action="{{ url_for('dietitians.link_profile') }}">
-                <input type="hidden" name="action" value="link_existing">
-                
-                <div class="mb-4">
-                    <label for="dietitian_id" class="block text-sm font-medium text-gray-700">Chọn hồ sơ</label>
-                    <select name="dietitian_id" id="dietitian_id" required class="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm">
-                        <option value="">-- Chọn hồ sơ --</option>
-                        {% for d in unlinked_dietitians %}
-                            <option value="{{ d.dietitianID }}">{{ d.fullName }} ({{ d.formattedID }})</option>
-                        {% endfor %}
-                    </select>
-                </div>
-
-                <div class="flex justify-end">
-                    <button type="submit" class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
-                        Liên kết hồ sơ
-                    </button>
-                </div>
-            </form>
-        </div>
-    </div>
-    {% else %}
-    <div class="bg-white shadow rounded-lg overflow-hidden">
-        <div class="px-6 py-5 border-b border-gray-200">
-            <h2 class="text-lg font-medium text-gray-900">Liên kết với hồ sơ có sẵn</h2>
-        </div>
-        <div class="px-6 py-4">
-            <p class="text-gray-600">Hiện không có hồ sơ chuyên gia dinh dưỡng nào chưa được liên kết trong hệ thống.</p>
-        </div>
-    </div>
-    {% endif %}
-</div>
-{% endblock %} 
\ No newline at end of file
diff --git a/app/templates/dietitians/show.html b/app/templates/dietitians/show.html
index 2a6af58..24d80cd 100644
--- a/app/templates/dietitians/show.html
+++ b/app/templates/dietitians/show.html
@@ -1,6 +1,7 @@
 {% extends "base.html" %}
+{% from "_macros.html" import status_badge %}
 
-{% block title %}{{ dietitian.firstName }} {{ dietitian.lastName }} - CCU HTM{% endblock %}
+{% block title %}{{ dietitian.user.firstName if dietitian.user else dietitian.firstName }} {{ dietitian.user.lastName if dietitian.user else dietitian.lastName }} - CCU HTM{% endblock %}
 
 {% block header %}Thông tin chi tiết chuyên gia dinh dưỡng{% endblock %}
 
@@ -25,7 +26,7 @@
                 <li aria-current="page">
                     <div class="flex items-center">
                         <svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
-                        <span class="ml-1 text-sm font-medium text-gray-500 md:ml-2">{{ dietitian.firstName }} {{ dietitian.lastName }}</span>
+                        <span class="ml-1 text-sm font-medium text-gray-500 md:ml-2">{{ dietitian.user.firstName if dietitian.user else dietitian.firstName }} {{ dietitian.user.lastName if dietitian.user else dietitian.lastName }}</span>
                     </div>
                 </li>
             </ol>
@@ -40,55 +41,61 @@
                     <p class="mt-1 max-w-2xl text-sm text-gray-500">Chi tiết thông tin cá nhân và liên hệ.</p>
                 </div>
                 <div class="flex space-x-3">
+                    {% if current_user.is_admin or (dietitian.user and dietitian.user.userID == current_user.userID) %}
                     <a href="{{ url_for('dietitians.edit', id=dietitian.dietitianID) }}" class="inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition duration-200">
                         <svg class="mr-2 -ml-1 h-4 w-4" 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="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
                         </svg>
                         Chỉnh sửa
                     </a>
-                    <a href="{{ url_for('dietitians.delete', id=dietitian.dietitianID) }}" class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition duration-200" onclick="return confirm('Bạn có chắc chắn muốn xóa chuyên gia dinh dưỡng này?');">
-                        <svg class="mr-2 -ml-1 h-4 w-4" 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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
-                        </svg>
-                        Xóa
-                    </a>
+                    {% endif %}
+                    {% if current_user.is_admin %}
+                    <form action="{{ url_for('dietitians.delete', id=dietitian.dietitianID) }}" method="POST" onsubmit="return confirm('Bạn có chắc chắn muốn xóa chuyên gia dinh dưỡng này?');" class="inline-block">
+                        <button type="submit" class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition duration-200">
+                            <svg class="mr-2 -ml-1 h-4 w-4" 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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
+                            </svg>
+                            Xóa
+                        </button>
+                    </form>
+                    {% endif %}
                 </div>
             </div>
             <div class="border-t border-gray-200">
                 <dl>
                     <div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
                         <dt class="text-sm font-medium text-gray-500">Họ và tên</dt>
-                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.firstName }} {{ dietitian.lastName }}</dd>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.user.firstName if dietitian.user else dietitian.firstName }} {{ dietitian.user.lastName if dietitian.user else dietitian.lastName }}</dd>
                     </div>
                     <div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
                         <dt class="text-sm font-medium text-gray-500">Email</dt>
-                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.email }}</dd>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.user.email if dietitian.user else dietitian.email }}</dd>
                     </div>
                     <div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
                         <dt class="text-sm font-medium text-gray-500">Số điện thoại</dt>
-                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.phone }}</dd>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.user.phone if dietitian.user and dietitian.user.phone else dietitian.phone or 'None' }}</dd>
                     </div>
                     <div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
                         <dt class="text-sm font-medium text-gray-500">Chuyên môn</dt>
-                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.specialization }}</dd>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.specialization or 'None' }}</dd>
                     </div>
                     <div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
                         <dt class="text-sm font-medium text-gray-500">Trạng thái</dt>
                         <dd class="mt-1 text-sm sm:mt-0 sm:col-span-2">
-                            {% if dietitian.status == 'available' %}
-                                <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
-                                    Khả dụng
-                                </span>
-                            {% else %}
-                                <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">
-                                    Không khả dụng
-                                </span>
-                            {% endif %}
+                            {{ status_badge(dietitian.status.value) }}
                         </dd>
                     </div>
                     <div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
                         <dt class="text-sm font-medium text-gray-500">Ghi chú</dt>
-                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.notes }}</dd>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.notes or 'None' }}</dd>
+                    </div>
+                    <div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
+                        <dt class="text-sm font-medium text-gray-500">Dietitian ID</dt>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.formattedID }}</dd>
+                    </div>
+                    <div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
+                        <dt class="text-sm font-medium text-gray-500">User ID liên kết</dt>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ dietitian.user.formattedID if dietitian.user else 'Chưa liên kết' }}</dd>
                     </div>
                 </dl>
             </div>
diff --git a/app/templates/edit_profile.html b/app/templates/edit_profile.html
index d4f816d..c2ed581 100644
--- a/app/templates/edit_profile.html
+++ b/app/templates/edit_profile.html
@@ -1,171 +1,226 @@
 {% extends "base.html" %}
 
-{% block title %}Chỉnh sửa hồ sơ{% endblock %}
+{% block title %}Chỉnh sửa hồ sơ - CCU HTM{% endblock %}
+
+{% block header %}Chỉnh sửa thông tin cá nhân{% endblock %}
 
 {% block content %}
-<div class="container mt-4">
-    <div class="row">
-        <div class="col-md-12 mb-4">
-            <h1 class="mb-3">Chỉnh sửa hồ sơ</h1>
-            <div class="card shadow">
-                <div class="card-body">
-                    <ul class="nav nav-tabs" id="profileTabs" role="tablist">
-                        <li class="nav-item" role="presentation">
-                            <a class="nav-link active" id="profile-tab" data-toggle="tab" href="#profile" role="tab">
-                                Thông tin cá nhân
-                            </a>
-                        </li>
-                        <li class="nav-item" role="presentation">
-                            <a class="nav-link" id="password-tab" data-toggle="tab" href="#password" role="tab">
-                                Thay đổi mật khẩu
-                            </a>
-                        </li>
-                        <li class="nav-item" role="presentation">
-                            <a class="nav-link" id="notifications-tab" data-toggle="tab" href="#notifications" role="tab">
-                                Cài đặt thông báo
-                            </a>
-                        </li>
-                    </ul>
-                    
-                    <div class="tab-content p-3" id="profileTabsContent">
-                        <!-- Tab thông tin cá nhân -->
-                        <div class="tab-pane fade show active" id="profile" role="tabpanel">
-                            <form method="POST" action="{{ url_for('auth.edit_profile') }}">
-                                {{ form.csrf_token }}
-                                
-                                <div class="form-group">
-                                    {{ form.username.label }}
-                                    {{ form.username(class="form-control") }}
-                                    {% if form.username.errors %}
-                                        <div class="invalid-feedback d-block">
-                                            {% for error in form.username.errors %}
-                                                {{ error }}
-                                            {% endfor %}
-                                        </div>
+<div class="container mx-auto px-4 py-6">
+    <!-- Breadcrumb -->
+    <div class="mb-6">
+        <nav class="flex" aria-label="Breadcrumb">
+            <ol class="inline-flex items-center space-x-1 md:space-x-3">
+                <li class="inline-flex items-center">
+                    <a href="{{ url_for('handle_root') }}" class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-blue-600 transition duration-200">
+                        <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"></path></svg>
+                        Trang chủ
+                    </a>
+                </li>
+                <li aria-current="page">
+                    <div class="flex items-center">
+                        <svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
+                        <span class="ml-1 text-sm font-medium text-gray-500 md:ml-2">Chỉnh sửa hồ sơ</span>
+                    </div>
+                </li>
+            </ol>
+        </nav>
+    </div>
+
+    <div class="max-w-4xl mx-auto">
+        <div class="bg-white shadow overflow-hidden sm:rounded-lg">
+            <div class="px-4 py-5 sm:px-6 border-b border-gray-200">
+                <h3 class="text-lg leading-6 font-medium text-gray-900">Chỉnh sửa thông tin cá nhân</h3>
+                <p class="mt-1 max-w-2xl text-sm text-gray-500">Cập nhật thông tin chi tiết của bạn.</p>
+            </div>
+
+            <div class="px-4 py-5 sm:p-6">
+                <!-- Tab navigation -->
+                <nav class="flex border-b border-gray-200">
+                    <button id="profile-tab" type="button" class="py-4 px-6 text-center border-b-2 border-primary-500 font-medium text-sm text-primary-600 bg-white" aria-current="page">
+                        Thông tin cá nhân
+                    </button>
+                    <button id="password-tab" type="button" class="py-4 px-6 text-center border-b-2 border-transparent font-medium text-sm text-gray-500 hover:text-gray-700 hover:border-gray-300 bg-white">
+                        Thay đổi mật khẩu
+                    </button>
+                </nav>
+
+                <!-- Profile content -->
+                <div id="profile-content" class="py-6">
+                    <form action="{{ url_for('auth.edit_profile') }}" method="POST" class="space-y-8 divide-y divide-gray-200">
+                        {{ form.csrf_token if form is defined }}
+                        <input type="hidden" name="form_type" value="profile">
+                        <div class="space-y-8 divide-y divide-gray-200">
+                            <div class="grid grid-cols-6 gap-6">
+                                <div class="col-span-6 sm:col-span-3">
+                                    <label for="firstName" class="block text-sm font-medium text-gray-700">Tên</label>
+                                    {{ form.firstName(id="firstName", class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border border-gray-300 rounded-md", required=True) }}
+                                    {% if form.firstName.errors %}
+                                        <p class="mt-2 text-sm text-red-600">{{ form.firstName.errors[0] }}</p>
                                     {% endif %}
                                 </div>
-                                
-                                <div class="form-group">
-                                    {{ form.email.label }}
-                                    {{ form.email(class="form-control") }}
-                                    {% if form.email.errors %}
-                                        <div class="invalid-feedback d-block">
-                                            {% for error in form.email.errors %}
-                                                {{ error }}
-                                            {% endfor %}
-                                        </div>
+
+                                <div class="col-span-6 sm:col-span-3">
+                                    <label for="lastName" class="block text-sm font-medium text-gray-700">Họ</label>
+                                    {{ form.lastName(id="lastName", class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border border-gray-300 rounded-md", required=True) }}
+                                    {% if form.lastName.errors %}
+                                        <p class="mt-2 text-sm text-red-600">{{ form.lastName.errors[0] }}</p>
                                     {% endif %}
                                 </div>
-                                
-                                {% if form.bio %}
-                                <div class="form-group">
-                                    {{ form.bio.label }}
-                                    {{ form.bio(class="form-control", rows=3) }}
-                                    {% if form.bio.errors %}
-                                        <div class="invalid-feedback d-block">
-                                            {% for error in form.bio.errors %}
-                                                {{ error }}
-                                            {% endfor %}
-                                        </div>
+
+                                <div class="col-span-6 sm:col-span-3">
+                                    <label for="email" class="block text-sm font-medium text-gray-700">Email</label>
+                                    {{ form.email(id="email", class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border border-gray-300 rounded-md", required=True) }}
+                                    {% if form.email.errors %}
+                                        <p class="mt-2 text-sm text-red-600">{{ form.email.errors[0] }}</p>
                                     {% endif %}
                                 </div>
-                                {% endif %}
-                                
-                                <div class="form-group">
-                                    <button type="submit" class="btn btn-primary">Cập nhật thông tin</button>
-                                    <a href="{{ url_for('auth.profile') }}" class="btn btn-secondary">Hủy</a>
-                                </div>
-                            </form>
-                        </div>
-                        
-                        <!-- Tab thay đổi mật khẩu -->
-                        <div class="tab-pane fade" id="password" role="tabpanel">
-                            <form method="POST" action="{{ url_for('auth.change_password') }}">
-                                {{ password_form.csrf_token }}
-                                
-                                <div class="form-group">
-                                    {{ password_form.current_password.label }}
-                                    {{ password_form.current_password(class="form-control") }}
-                                    {% if password_form.current_password.errors %}
-                                        <div class="invalid-feedback d-block">
-                                            {% for error in password_form.current_password.errors %}
-                                                {{ error }}
-                                            {% endfor %}
-                                        </div>
+
+                                <div class="col-span-6 sm:col-span-3">
+                                    <label for="phone" class="block text-sm font-medium text-gray-700">Số điện thoại</label>
+                                    {{ form.phone(id="phone", class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border border-gray-300 rounded-md") }}
+                                    {% if form.phone.errors %}
+                                        <p class="mt-2 text-sm text-red-600">{{ form.phone.errors[0] }}</p>
                                     {% endif %}
                                 </div>
-                                
-                                <div class="form-group">
-                                    {{ password_form.new_password.label }}
-                                    {{ password_form.new_password(class="form-control") }}
-                                    {% if password_form.new_password.errors %}
-                                        <div class="invalid-feedback d-block">
-                                            {% for error in password_form.new_password.errors %}
-                                                {{ error }}
-                                            {% endfor %}
-                                        </div>
+
+                                {% if current_user.role == 'Dietitian' or (form.specialization is defined) %}
+                                <div class="col-span-6">
+                                    <label for="specialization" class="block text-sm font-medium text-gray-700">Chuyên môn</label>
+                                    {{ form.specialization(id="specialization", class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border border-gray-300 rounded-md") }}
+                                    {% if form.specialization.errors %}
+                                        <p class="mt-2 text-sm text-red-600">{{ form.specialization.errors[0] }}</p>
                                     {% endif %}
                                 </div>
-                                
-                                <div class="form-group">
-                                    {{ password_form.confirm_password.label }}
-                                    {{ password_form.confirm_password(class="form-control") }}
-                                    {% if password_form.confirm_password.errors %}
-                                        <div class="invalid-feedback d-block">
-                                            {% for error in password_form.confirm_password.errors %}
-                                                {{ error }}
-                                            {% endfor %}
-                                        </div>
-                                    {% endif %}
+
+                                <div class="col-span-6">
+                                    <label for="status" class="block text-sm font-medium text-gray-700">Trạng thái</label>
+                                    <div class="mt-1 block w-full py-2 px-3 border border-gray-300 bg-gray-100 rounded-md shadow-sm text-sm text-gray-700">
+                                        {{ current_user.dietitian_profile.status.value if current_user.dietitian_profile else 'N/A' }}
+                                        <span class="text-xs text-gray-500 ml-2">(Tự động cập nhật)</span>
+                                    </div>
                                 </div>
-                                
-                                <div class="form-group">
-                                    <button type="submit" class="btn btn-primary">Cập nhật mật khẩu</button>
+
+                                <div class="col-span-6">
+                                    <label for="notes" class="block text-sm font-medium text-gray-700">Ghi chú</label>
+                                    {{ form.notes(id="notes", rows="3", class="mt-1 focus:ring-primary-500 focus:border-primary-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md") }}
+                                    {% if form.notes.errors %}
+                                        <p class="mt-2 text-sm text-red-600">{{ form.notes.errors[0] }}</p>
+                                    {% endif %}
                                 </div>
-                            </form>
+                                {% endif %}
+                            </div>
                         </div>
                         
-                        <!-- Tab cài đặt thông báo -->
-                        <div class="tab-pane fade" id="notifications" role="tabpanel">
-                            <form method="POST" action="{{ url_for('auth.update_notifications') }}">
-                                {{ notification_form.csrf_token }}
-                                
-                                <div class="form-group form-check">
-                                    {{ notification_form.email_notifications(class="form-check-input") }}
-                                    {{ notification_form.email_notifications.label(class="form-check-label") }}
-                                </div>
-                                
-                                <div class="form-group form-check">
-                                    {{ notification_form.system_notifications(class="form-check-input") }}
-                                    {{ notification_form.system_notifications.label(class="form-check-label") }}
+                        <div class="pt-5">
+                            <div class="flex justify-end">
+                                <button type="button" class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500" onclick="window.location.href='{{ url_for('auth.profile') }}'">
+                                    Hủy
+                                </button>
+                                <button type="submit" class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
+                                    Lưu thay đổi
+                                </button>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+
+                <!-- Password content (Initially hidden) -->
+                <div id="password-content" class="py-6 hidden">
+                    <form action="{{ url_for('auth.change_password') }}" method="POST" class="space-y-8 divide-y divide-gray-200">
+                        <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
+                        <div class="space-y-8 divide-y divide-gray-200">
+                            <div>
+                                <div>
+                                    <h3 class="text-lg leading-6 font-medium text-gray-900">Thay đổi mật khẩu</h3>
+                                    <p class="mt-1 text-sm text-gray-500">Cập nhật mật khẩu của bạn để bảo mật tài khoản.</p>
                                 </div>
-                                
-                                <div class="form-group">
-                                    <button type="submit" class="btn btn-primary">Cập nhật cài đặt thông báo</button>
+
+                                <div class="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6">
+                                    <div class="sm:col-span-4">
+                                        <label for="current_password" class="block text-sm font-medium text-gray-700">Mật khẩu hiện tại</label>
+                                        <div class="mt-1">
+                                            <input type="password" name="current_password" id="current_password" 
+                                                class="shadow-sm focus:ring-primary-500 focus:border-primary-500 block w-full sm:text-sm border border-gray-300 rounded-md" required>
+                                        </div>
+                                    </div>
+
+                                    <div class="sm:col-span-4">
+                                        <label for="new_password" class="block text-sm font-medium text-gray-700">Mật khẩu mới</label>
+                                        <div class="mt-1">
+                                            <input type="password" name="new_password" id="new_password" 
+                                                class="shadow-sm focus:ring-primary-500 focus:border-primary-500 block w-full sm:text-sm border border-gray-300 rounded-md" required>
+                                        </div>
+                                    </div>
+
+                                    <div class="sm:col-span-4">
+                                        <label for="confirm_password" class="block text-sm font-medium text-gray-700">Xác nhận mật khẩu mới</label>
+                                        <div class="mt-1">
+                                            <input type="password" name="confirm_password" id="confirm_password" 
+                                                class="shadow-sm focus:ring-primary-500 focus:border-primary-500 block w-full sm:text-sm border border-gray-300 rounded-md" required>
+                                        </div>
+                                    </div>
                                 </div>
-                            </form>
+                            </div>
                         </div>
-                    </div>
+                        
+                        <div class="pt-5">
+                            <div class="flex justify-end">
+                                <button type="button" class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500" onclick="window.location.href='{{ url_for('auth.profile') }}'">
+                                    Hủy
+                                </button>
+                                <button type="submit" class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
+                                    Lưu thay đổi
+                                </button>
+                            </div>
+                        </div>
+                    </form>
                 </div>
             </div>
         </div>
     </div>
 </div>
-{% endblock %}
 
-{% block extra_js %}
+<!-- JavaScript để xử lý tab -->
 <script>
-    $(document).ready(function() {
-        // Kích hoạt tab dựa trên hash URL
-        var hash = window.location.hash;
-        if (hash) {
-            $('#profileTabs a[href="' + hash + '"]').tab('show');
+    document.addEventListener('DOMContentLoaded', function() {
+        const profileTab = document.getElementById('profile-tab');
+        const passwordTab = document.getElementById('password-tab');
+        const profileContent = document.getElementById('profile-content');
+        const passwordContent = document.getElementById('password-content');
+
+        // Kiểm tra hash URL để hiển thị tab tương ứng
+        if (window.location.hash === '#change-password') {
+            showPasswordTab();
+        }
+
+        profileTab.addEventListener('click', showProfileTab);
+        passwordTab.addEventListener('click', showPasswordTab);
+
+        function showProfileTab() {
+            profileTab.classList.add('border-primary-500', 'text-primary-600');
+            profileTab.classList.remove('border-transparent', 'text-gray-500');
+            passwordTab.classList.add('border-transparent', 'text-gray-500');
+            passwordTab.classList.remove('border-primary-500', 'text-primary-600');
+            
+            profileContent.classList.remove('hidden');
+            passwordContent.classList.add('hidden');
+            
+            // Cập nhật URL hash
+            window.location.hash = '';
+        }
+
+        function showPasswordTab() {
+            passwordTab.classList.add('border-primary-500', 'text-primary-600');
+            passwordTab.classList.remove('border-transparent', 'text-gray-500');
+            profileTab.classList.add('border-transparent', 'text-gray-500');
+            profileTab.classList.remove('border-primary-500', 'text-primary-600');
+            
+            passwordContent.classList.remove('hidden');
+            profileContent.classList.add('hidden');
+            
+            // Cập nhật URL hash
+            window.location.hash = 'change-password';
         }
-        
-        // Cập nhật hash khi thay đổi tab
-        $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
-            window.location.hash = e.target.hash;
-        });
     });
 </script>
 {% endblock %} 
\ No newline at end of file
diff --git a/app/templates/login.html b/app/templates/login.html
index b8414b1..0d1aef1 100644
--- a/app/templates/login.html
+++ b/app/templates/login.html
@@ -7,11 +7,15 @@
     .login-form {
         animation: fadeIn 0.6s ease-in-out 0.3s forwards;
         opacity: 0;
+        width: 100%;
+        margin: 0 auto;
     }
     
     .form-input {
         font-size: 1.05rem;
-        padding: 0.75rem 1rem;
+        padding: 0.85rem 1.2rem;
+        width: 100%;
+        border-radius: 0.5rem;
     }
     
     .form-input:focus {
@@ -23,7 +27,8 @@
         transition: all 0.3s ease;
         background: linear-gradient(to right, #3b82f6, #2563eb);
         font-size: 1.1rem;
-        padding: 0.75rem 1.5rem;
+        padding: 0.85rem 1.5rem;
+        border-radius: 0.5rem;
     }
     
     .btn-login:hover {
@@ -33,42 +38,73 @@
     }
     
     .form-label {
-        font-size: 1rem;
+        font-size: 1.05rem;
         margin-bottom: 0.5rem;
+        font-weight: 500;
     }
     
     .alert-message {
+        margin-bottom: 1rem;
+    }
+    
+    .mb-5 {
         margin-bottom: 1.5rem;
     }
+    
+    .error-container {
+        margin-bottom: 1rem;
+    }
+    
+    .error-container.hidden {
+        display: none;
+        margin: 0;
+        padding: 0;
+        height: 0;
+    }
+    
+    @media (max-width: 500px) {
+        .flex.items-center.justify-between {
+            flex-direction: column;
+            align-items: flex-start;
+        }
+        
+        .flex.items-center.justify-between a {
+            margin-top: 0.5rem;
+            margin-left: 0;
+        }
+    }
 </style>
 {% endblock %}
 
 {% block content %}
 <div class="bg-white rounded-lg shadow-lg p-8 login-form">
-    <h2 class="text-3xl font-bold text-center text-gray-800 mb-8">Đăng nhập</h2>
+    <h2 class="text-3xl font-bold text-center text-gray-800 mb-6">Đăng nhập</h2>
     
-    {% with messages = get_flashed_messages(with_categories=true) %}
-        {% if messages %}
-            {% for category, message in messages %}
-                <div class="p-4 mb-4 rounded-md {% if category == 'error' %}bg-red-100 text-red-700{% else %}bg-green-100 text-green-700{% endif %} animate-fadeIn alert-message">
-                    <div class="flex">
-                        <div class="flex-shrink-0">
-                            {% if category == 'error' %}
-                                <i class="fas fa-exclamation-circle text-red-500"></i>
-                            {% else %}
-                                <i class="fas fa-check-circle text-green-500"></i>
-                            {% endif %}
-                        </div>
-                        <div class="ml-3">
-                            <p class="text-sm font-medium">{{ message }}</p>
+    <!-- Error message container - Only takes space when messages exist -->
+    <div class="error-container {% if not get_flashed_messages() %}hidden{% endif %}">
+        {% with messages = get_flashed_messages(with_categories=true) %}
+            {% if messages %}
+                {% for category, message in messages %}
+                    <div class="p-4 mb-4 rounded-md {% if category == 'error' %}bg-red-100 text-red-700{% else %}bg-green-100 text-green-700{% endif %} animate-fadeIn alert-message">
+                        <div class="flex">
+                            <div class="flex-shrink-0">
+                                {% if category == 'error' %}
+                                    <i class="fas fa-exclamation-circle text-red-500"></i>
+                                {% else %}
+                                    <i class="fas fa-check-circle text-green-500"></i>
+                                {% endif %}
+                            </div>
+                            <div class="ml-3">
+                                <p class="text-sm font-medium">{{ message }}</p>
+                            </div>
                         </div>
                     </div>
-                </div>
-            {% endfor %}
-        {% endif %}
-    {% endwith %}
+                {% endfor %}
+            {% endif %}
+        {% endwith %}
+    </div>
     
-    <form method="POST" action="{{ url_for('auth.login') }}">
+    <form method="POST" action="{{ url_for('auth.login') }}" class="mt-4 px-1">
         {{ form.hidden_tag() }}
         
         <div class="mb-5">
@@ -83,6 +119,18 @@
             {% endif %}
         </div>
         
+        <div class="mb-5">
+            <label for="dietitianID" class="block form-label font-medium text-gray-700">Dietitian ID (nếu có)</label>
+            {{ form.dietitianID(class="form-input w-full border border-gray-300 rounded-md focus:outline-none", placeholder="Ví dụ: DT-00001") }}
+            {% if form.dietitianID.errors %}
+                <div class="text-red-600 text-sm mt-1">
+                    {% for error in form.dietitianID.errors %}
+                        {{ error }}
+                    {% endfor %}
+                </div>
+            {% endif %}
+        </div>
+        
         <div class="mb-5">
             <label for="password" class="block form-label font-medium text-gray-700">Mật khẩu</label>
             {{ form.password(class="form-input w-full border border-gray-300 rounded-md focus:outline-none", placeholder="Nhập mật khẩu của bạn") }}
@@ -98,12 +146,12 @@
         <div class="flex items-center justify-between mb-8">
             <div class="flex items-center">
                 {{ form.remember(class="h-5 w-5 text-blue-600 focus:ring-blue-500 border-gray-300 rounded") }}
-                <label for="remember" class="ml-2 block text-base text-gray-700">
+                <label for="remember" class="ml-2 block text-sm md:text-base text-gray-700">
                     Ghi nhớ đăng nhập
                 </label>
             </div>
             
-            <a href="#" class="text-base text-blue-600 hover:text-blue-800 transition">
+            <a href="{{ url_for('auth.reset_password_request') }}" class="text-sm md:text-base text-blue-600 hover:text-blue-800 transition ml-4">
                 Quên mật khẩu?
             </a>
         </div>
@@ -112,15 +160,6 @@
             Đăng nhập
         </button>
     </form>
-    
-    <div class="mt-8 text-center">
-        <p class="text-base text-gray-600">
-            Chưa có tài khoản? 
-            <a href="{{ url_for('auth.register') }}" class="text-blue-600 hover:text-blue-800 font-medium transition">
-                Đăng ký ngay
-            </a>
-        </p>
-    </div>
 </div>
 {% endblock %}
 
diff --git a/app/templates/profile.html b/app/templates/profile.html
index faca06f..2a71f6e 100644
--- a/app/templates/profile.html
+++ b/app/templates/profile.html
@@ -1,133 +1,49 @@
 {% extends "base.html" %}
 
-{% block title %}Profile - CCU HTM{% endblock %}
+{% block title %}Hồ sơ người dùng{% endblock %}
 
 {% block content %}
-<div class="container mx-auto px-4 py-8">
-    <div class="max-w-4xl mx-auto">
-        <!-- Profile header -->
-        <div class="bg-white rounded-lg shadow-md overflow-hidden mb-6 transform hover:scale-[1.01] transition-all duration-300">
-            <div class="bg-primary-600 h-32 relative">
-                <div class="absolute bottom-0 left-0 transform translate-y-1/2 ml-8">
-                    <div class="rounded-full bg-white p-1 shadow-lg">
-                        <div class="bg-gray-200 rounded-full h-24 w-24 flex items-center justify-center text-3xl font-bold text-primary-600">
-                            {{ current_user.username[0].upper() }}
-                        </div>
-                    </div>
-                </div>
-                <div class="absolute top-4 right-4">
-                    <a href="{{ url_for('auth.edit_profile') }}" class="bg-white text-primary-600 px-4 py-2 rounded-md shadow hover:bg-gray-50 transition-colors flex items-center gap-2">
-                        <i class="fas fa-pencil-alt"></i> Edit Profile
-                    </a>
-                </div>
-            </div>
-            <div class="pt-16 pb-8 px-8">
-                <h1 class="text-2xl font-bold text-gray-800">{{ current_user.username }}</h1>
-                <p class="text-gray-600">{{ current_user.email }}</p>
-                <div class="mt-4 grid grid-cols-1 md:grid-cols-3 gap-4">
-                    <div class="bg-gray-50 p-4 rounded-lg">
-                        <div class="text-sm text-gray-500">Role</div>
-                        <div class="font-medium">{{ current_user.role or 'User' }}</div>
-                    </div>
-                    <div class="bg-gray-50 p-4 rounded-lg">
-                        <div class="text-sm text-gray-500">Member Since</div>
-                        <div class="font-medium">{{ current_user.created_at.strftime('%B %d, %Y') if current_user.created_at else 'N/A' }}</div>
-                    </div>
-                    <div class="bg-gray-50 p-4 rounded-lg">
-                        <div class="text-sm text-gray-500">Last Login</div>
-                        <div class="font-medium">{{ current_user.last_login.strftime('%B %d, %Y %H:%M') if current_user.last_login else 'N/A' }}</div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <!-- Activity section -->
-        <div class="bg-white rounded-lg shadow-md overflow-hidden mb-6 transform hover:scale-[1.01] transition-all duration-300">
-            <div class="px-8 py-6">
-                <h2 class="text-xl font-bold text-gray-800 mb-4">Recent Activity</h2>
-                
-                {% if activities %}
-                    <div class="space-y-4">
-                        {% for activity in activities %}
-                            <div class="flex items-start p-3 hover:bg-gray-50 rounded-lg transition-colors">
-                                <div class="flex-shrink-0 bg-primary-100 text-primary-600 p-2 rounded-full mr-4">
-                                    <i class="fas fa-{{ activity.icon if activity.icon else 'check' }}"></i>
-                                </div>
-                                <div>
-                                    <p class="font-medium text-gray-800">{{ activity.description }}</p>
-                                    <p class="text-sm text-gray-500">{{ activity.timestamp.strftime('%B %d, %Y %H:%M') }}</p>
-                                </div>
-                            </div>
-                        {% endfor %}
-                    </div>
-                {% else %}
-                    <div class="text-gray-500 text-center py-4">
-                        <p>No recent activity to display</p>
-                    </div>
-                {% endif %}
-            </div>
-        </div>
+<div class="container mx-auto mt-10 px-4">
+    <h1 class="text-3xl font-semibold text-gray-800 mb-6">Hồ sơ người dùng</h1>
 
-        <!-- Stats section -->
-        <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
-            <div class="bg-white rounded-lg shadow-md overflow-hidden transform hover:scale-[1.01] transition-all duration-300">
-                <div class="px-8 py-6">
-                    <h2 class="text-xl font-bold text-gray-800 mb-4">Uploads</h2>
-                    <div class="flex items-center justify-center h-32">
-                        <div class="text-center">
-                            <div class="text-4xl font-bold text-primary-600">{{ upload_count if upload_count is defined else 0 }}</div>
-                            <div class="text-gray-500">Files Uploaded</div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-            
-            <div class="bg-white rounded-lg shadow-md overflow-hidden transform hover:scale-[1.01] transition-all duration-300">
-                <div class="px-8 py-6">
-                    <h2 class="text-xl font-bold text-gray-800 mb-4">Patients</h2>
-                    <div class="flex items-center justify-center h-32">
-                        <div class="text-center">
-                            <div class="text-4xl font-bold text-primary-600">{{ patient_count if patient_count is defined else 0 }}</div>
-                            <div class="text-gray-500">Patients Added</div>
-                        </div>
-                    </div>
+    <div class="bg-white shadow-md rounded-lg overflow-hidden">
+        <div class="px-6 py-4">
+            <div class="flex items-center mb-4">
+                <!-- Placeholder for user avatar -->
+                <img class="h-16 w-16 rounded-full object-cover mr-4" src="https://via.placeholder.com/64" alt="User Avatar">
+                <div>
+                    <h2 class="text-xl font-semibold text-gray-900">{{ current_user.full_name }}</h2>
+                    <p class="text-gray-600">{{ current_user.role }}</p>
                 </div>
             </div>
-        </div>
 
-        <!-- Security section -->
-        <div class="bg-white rounded-lg shadow-md overflow-hidden mb-6 transform hover:scale-[1.01] transition-all duration-300">
-            <div class="px-8 py-6">
-                <h2 class="text-xl font-bold text-gray-800 mb-4">Security</h2>
-                <div class="space-y-4">
-                    <div class="flex items-center justify-between p-3 hover:bg-gray-50 rounded-lg transition-colors">
-                        <div class="flex items-center">
-                            <div class="bg-green-100 text-green-600 p-2 rounded-full mr-4">
-                                <i class="fas fa-lock"></i>
-                            </div>
-                            <div>
-                                <p class="font-medium text-gray-800">Password</p>
-                                <p class="text-sm text-gray-500">Last changed: {{ password_changed if password_changed is defined else 'N/A' }}</p>
-                            </div>
-                        </div>
-                        <a href="{{ url_for('auth.edit_profile') }}#password" class="text-primary-600 hover:text-primary-700">Change</a>
-                    </div>
-                    
-                    <div class="flex items-center justify-between p-3 hover:bg-gray-50 rounded-lg transition-colors">
-                        <div class="flex items-center">
-                            <div class="bg-blue-100 text-blue-600 p-2 rounded-full mr-4">
-                                <i class="fas fa-envelope"></i>
-                            </div>
-                            <div>
-                                <p class="font-medium text-gray-800">Email Address</p>
-                                <p class="text-sm text-gray-500">{{ current_user.email }}</p>
-                            </div>
-                        </div>
-                        <a href="{{ url_for('auth.edit_profile') }}#email" class="text-primary-600 hover:text-primary-700">Update</a>
-                    </div>
-                </div>
+            <div class="border-t border-gray-200 pt-4">
+                <dl>
+                    <div class="bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
+                        <dt class="text-sm font-medium text-gray-500">Họ và tên</dt>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ current_user.full_name }}</dd>
+                    </div>
+                    <div class="bg-white px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
+                        <dt class="text-sm font-medium text-gray-500">Email</dt>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ current_user.email }}</dd>
+                    </div>
+                    <div class="bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
+                        <dt class="text-sm font-medium text-gray-500">Vai trò</dt>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ current_user.role }}</dd>
+                    </div>
+                    <div class="bg-white px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
+                        <dt class="text-sm font-medium text-gray-500">Ngày tham gia</dt>
+                        <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{ current_user.created_at.strftime('%d/%m/%Y') if current_user.created_at else 'N/A' }}</dd>
+                    </div>
+                    <!-- Add more fields as needed -->
+                </dl>
             </div>
         </div>
+        <div class="px-6 py-3 bg-gray-50 text-right">
+            <a href="{{ url_for('auth.edit_profile') }}" class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
+                Chỉnh sửa hồ sơ
+            </a>
+        </div>
     </div>
 </div>
 {% endblock %} 
\ No newline at end of file
diff --git a/app/templates/register.html b/app/templates/register.html
deleted file mode 100644
index f756e75..0000000
--- a/app/templates/register.html
+++ /dev/null
@@ -1,181 +0,0 @@
-{% extends "auth_base.html" %}
-
-{% block title %}Đăng ký - CCU HTM{% endblock %}
-
-{% block extra_css %}
-<style>
-    .register-form {
-        animation: fadeIn 0.6s ease-in-out 0.3s forwards;
-        opacity: 0;
-    }
-    
-    .form-input {
-        font-size: 1.05rem;
-        padding: 0.75rem 1rem;
-    }
-    
-    .form-input:focus {
-        border-color: #3b82f6;
-        box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
-    }
-    
-    .btn-register {
-        transition: all 0.3s ease;
-        background: linear-gradient(to right, #3b82f6, #2563eb);
-        font-size: 1.1rem;
-        padding: 0.75rem 1.5rem;
-    }
-    
-    .btn-register:hover {
-        transform: translateY(-2px);
-        box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);
-        background: linear-gradient(to right, #2563eb, #1d4ed8);
-    }
-    
-    .form-label {
-        font-size: 1rem;
-        margin-bottom: 0.5rem;
-    }
-    
-    .alert-message {
-        margin-bottom: 1.5rem;
-    }
-    
-    .name-fields {
-        display: grid;
-        grid-template-columns: 1fr 1fr;
-        gap: 1rem;
-    }
-</style>
-{% endblock %}
-
-{% block content %}
-<div class="bg-white rounded-lg shadow-lg p-8 register-form">
-    <h2 class="text-3xl font-bold text-center text-gray-800 mb-8">Tạo tài khoản mới</h2>
-    
-    {% with messages = get_flashed_messages(with_categories=true) %}
-        {% if messages %}
-            {% for category, message in messages %}
-                <div class="p-4 mb-4 rounded-md {% if category == 'error' %}bg-red-100 text-red-700{% else %}bg-green-100 text-green-700{% endif %} animate-fadeIn alert-message">
-                    <div class="flex">
-                        <div class="flex-shrink-0">
-                            {% if category == 'error' %}
-                                <i class="fas fa-exclamation-circle text-red-500"></i>
-                            {% else %}
-                                <i class="fas fa-check-circle text-green-500"></i>
-                            {% endif %}
-                        </div>
-                        <div class="ml-3">
-                            <p class="text-sm font-medium">{{ message }}</p>
-                        </div>
-                    </div>
-                </div>
-            {% endfor %}
-        {% endif %}
-    {% endwith %}
-    
-    <form method="POST" action="{{ url_for('auth.register') }}">
-        {{ form.hidden_tag() }}
-        
-        <div class="name-fields mb-5">
-            <div>
-                <label for="firstName" class="block form-label font-medium text-gray-700">Họ</label>
-                {{ form.firstName(class="form-input w-full border border-gray-300 rounded-md focus:outline-none", placeholder="Nhập họ của bạn") }}
-                {% if form.firstName.errors %}
-                    <div class="text-red-600 text-sm mt-1">
-                        {% for error in form.firstName.errors %}
-                            {{ error }}
-                        {% endfor %}
-                    </div>
-                {% endif %}
-            </div>
-            
-            <div>
-                <label for="lastName" class="block form-label font-medium text-gray-700">Tên</label>
-                {{ form.lastName(class="form-input w-full border border-gray-300 rounded-md focus:outline-none", placeholder="Nhập tên của bạn") }}
-                {% if form.lastName.errors %}
-                    <div class="text-red-600 text-sm mt-1">
-                        {% for error in form.lastName.errors %}
-                            {{ error }}
-                        {% endfor %}
-                    </div>
-                {% endif %}
-            </div>
-        </div>
-        
-        <div class="mb-5">
-            <label for="username" class="block form-label font-medium text-gray-700">Tên người dùng</label>
-            {{ form.username(class="form-input w-full border border-gray-300 rounded-md focus:outline-none", placeholder="Nhập tên người dùng của bạn") }}
-            {% if form.username.errors %}
-                <div class="text-red-600 text-sm mt-1">
-                    {% for error in form.username.errors %}
-                        {{ error }}
-                    {% endfor %}
-                </div>
-            {% endif %}
-        </div>
-        
-        <div class="mb-5">
-            <label for="email" class="block form-label font-medium text-gray-700">Email</label>
-            {{ form.email(class="form-input w-full border border-gray-300 rounded-md focus:outline-none", placeholder="Nhập email của bạn") }}
-            {% if form.email.errors %}
-                <div class="text-red-600 text-sm mt-1">
-                    {% for error in form.email.errors %}
-                        {{ error }}
-                    {% endfor %}
-                </div>
-            {% endif %}
-        </div>
-        
-        <div class="mb-5">
-            <label for="password" class="block form-label font-medium text-gray-700">Mật khẩu</label>
-            {{ form.password(class="form-input w-full border border-gray-300 rounded-md focus:outline-none", placeholder="Nhập mật khẩu của bạn") }}
-            {% if form.password.errors %}
-                <div class="text-red-600 text-sm mt-1">
-                    {% for error in form.password.errors %}
-                        {{ error }}
-                    {% endfor %}
-                </div>
-            {% endif %}
-        </div>
-        
-        <div class="mb-6">
-            <label for="confirm_password" class="block form-label font-medium text-gray-700">Xác nhận mật khẩu</label>
-            {{ form.confirm_password(class="form-input w-full border border-gray-300 rounded-md focus:outline-none", placeholder="Nhập lại mật khẩu của bạn") }}
-            {% if form.confirm_password.errors %}
-                <div class="text-red-600 text-sm mt-1">
-                    {% for error in form.confirm_password.errors %}
-                        {{ error }}
-                    {% endfor %}
-                </div>
-            {% endif %}
-        </div>
-        
-        <div class="text-base text-gray-600 mb-8">
-            Bằng cách đăng ký, bạn đồng ý với các <a href="#" class="text-blue-600 hover:text-blue-800 transition">Điều khoản sử dụng</a> và <a href="#" class="text-blue-600 hover:text-blue-800 transition">Chính sách bảo mật</a> của chúng tôi.
-        </div>
-        
-        <button type="submit" class="btn-register w-full border border-transparent rounded-md shadow-sm font-medium text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
-            Đăng ký
-        </button>
-    </form>
-    
-    <div class="mt-8 text-center">
-        <p class="text-base text-gray-600">
-            Đã có tài khoản? 
-            <a href="{{ url_for('auth.login') }}" class="text-blue-600 hover:text-blue-800 font-medium transition">
-                Đăng nhập ngay
-            </a>
-        </p>
-    </div>
-</div>
-{% endblock %}
-
-{% block extra_js %}
-<script>
-    document.addEventListener('DOMContentLoaded', function() {
-        // Tập trung vào trường họ khi trang tải xong
-        document.getElementById('firstName').focus();
-    });
-</script>
-{% endblock %} 
\ No newline at end of file
diff --git a/app/utils/decorators.py b/app/utils/decorators.py
new file mode 100644
index 0000000..9c12896
--- /dev/null
+++ b/app/utils/decorators.py
@@ -0,0 +1,16 @@
+from functools import wraps
+from flask import flash, redirect, url_for, request
+from flask_login import current_user
+
+def admin_required(f):
+    """Decorator để giới hạn quyền truy cập chỉ cho Admin."""
+    @wraps(f)
+    def decorated_function(*args, **kwargs):
+        if not current_user.is_authenticated:
+            flash('Bạn cần đăng nhập để truy cập trang này.', 'warning')
+            return redirect(url_for('auth.login', next=request.url))
+        if not current_user.is_admin:
+            flash('Bạn không có quyền truy cập trang này.', 'danger')
+            return redirect(url_for('dashboard.index')) # Hoặc trang chính khác
+        return f(*args, **kwargs)
+    return decorated_function 
\ No newline at end of file
diff --git a/fix_template_urls.py b/fix_template_urls.py
deleted file mode 100644
index c37361f..0000000
--- a/fix_template_urls.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import re
-
-def fix_templates():
-    """Sửa tất cả template đang sử dụng url_for('index') thành url_for('handle_root')"""
-    templates_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'app', 'templates')
-    pattern = re.compile(r"url_for\('index'\)")
-    replacement = "url_for('handle_root')"
-    
-    # Đếm số file đã được sửa
-    fixed_count = 0
-    
-    # Đi qua tất cả các file trong thư mục templates và các thư mục con
-    for root, dirs, files in os.walk(templates_dir):
-        for file in files:
-            if file.endswith('.html'):
-                filepath = os.path.join(root, file)
-                
-                # Đọc nội dung file
-                with open(filepath, 'r', encoding='utf-8') as f:
-                    content = f.read()
-                
-                # Kiểm tra xem có cần sửa không
-                if pattern.search(content):
-                    # Sửa nội dung
-                    modified_content = pattern.sub(replacement, content)
-                    
-                    # Ghi lại vào file
-                    with open(filepath, 'w', encoding='utf-8') as f:
-                        f.write(modified_content)
-                    
-                    # Tăng số file đã sửa
-                    fixed_count += 1
-                    
-                    # In thông báo
-                    rel_path = os.path.relpath(filepath, os.path.dirname(os.path.abspath(__file__)))
-                    print(f"Đã sửa file: {rel_path}")
-    
-    print(f"\nHoàn tất! Đã sửa {fixed_count} file template.")
-
-if __name__ == "__main__":
-    print("Bắt đầu sửa các template...")
-    fix_templates() 
\ No newline at end of file
diff --git a/generate_patients.py b/generate_patients.py
new file mode 100644
index 0000000..93b30e2
--- /dev/null
+++ b/generate_patients.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import json
+import random
+# Bạn cần cài đặt thư viện Faker: pip install Faker
+from faker import Faker
+import os
+
+# Lấy đường dẫn thư mục của script hiện tại
+script_dir = os.path.dirname(os.path.abspath(__file__))
+output_file = os.path.join(script_dir, 'patients_data.json')
+
+fake = Faker('en_US') # Có thể dùng 'vi_VN' nếu muốn tên Việt
+
+def generate_measurement(age):
+    """Tạo dữ liệu đo lường ngẫu nhiên nhưng hợp lý theo độ tuổi"""
+    measurements = {}
+
+    # Nhiệt độ (Temperature): 36.0 - 37.5, có thể cao hơn nếu già/bệnh
+    base_temp = random.uniform(36.0, 37.2)
+    if age > 70 or random.random() < 0.1: # 10% chance of higher temp
+        base_temp += random.uniform(0.3, 1.0)
+    measurements['temperature'] = round(base_temp, 1)
+
+    # Nhịp tim (Heart Rate): Trẻ khỏe: 60-80, Già/Bệnh: 70-100+
+    base_hr = random.randint(65, 85)
+    if age < 30:
+        base_hr = random.randint(60, 80)
+    elif age > 60:
+        base_hr += random.randint(5, 20)
+    if random.random() < 0.15: # 15% chance of abnormal HR
+        base_hr += random.randint(15, 30) * random.choice([-1, 1])
+    measurements['heart_rate'] = max(40, min(140, base_hr)) # Giới hạn hợp lý
+
+    # Huyết áp (Blood Pressure): Trẻ khỏe: 110-120 / 70-80. Già/Bệnh: Cao hơn
+    systolic = random.randint(110, 125)
+    diastolic = random.randint(70, 85)
+    if age > 50:
+        systolic += random.randint(10, 25)
+        diastolic += random.randint(5, 15)
+    if random.random() < 0.2: # 20% chance of higher BP
+        systolic += random.randint(10, 20)
+        diastolic += random.randint(5, 10)
+    measurements['blood_pressure_systolic'] = max(90, min(180, systolic))
+    measurements['blood_pressure_diastolic'] = max(50, min(110, diastolic))
+
+    # SpO2: 95-100, có thể thấp hơn nếu bệnh
+    spo2 = random.uniform(96.0, 99.5)
+    if random.random() < 0.1: # 10% chance of lower SpO2
+        spo2 -= random.uniform(2.0, 5.0)
+    measurements['oxygen_saturation'] = round(max(88.0, min(100.0, spo2)), 1)
+
+    # Nhịp thở (Respiratory Rate): 12-20 (đổi tên biến thành resp_rate cho khớp model)
+    measurements['resp_rate'] = random.randint(12, 20)
+    if random.random() < 0.05: # Chance of slightly higher
+         measurements['resp_rate'] += random.randint(1,4)
+
+    # FiO2: Thường là 21% (không khí), có thể cao hơn nếu thở oxy
+    measurements['fio2'] = 21.0
+    if random.random() < 0.15: # 15% thở oxy
+        measurements['fio2'] = round(random.uniform(24.0, 60.0), 1)
+
+    # Tidal Volume: Khoảng 6-8 ml/kg trọng lượng cơ thể lý tưởng
+    # Tạm thời để giá trị ngẫu nhiên đơn giản (đổi tên biến)
+    measurements['tidal_vol'] = random.randint(350, 550)
+
+    # Các chỉ số khác (tùy chọn, để None hoặc giá trị ngẫu nhiên cơ bản)
+    measurements['end_tidal_co2'] = round(random.uniform(35, 45), 1) if random.random() < 0.5 else None
+    measurements['feed_vol'] = random.randint(100, 500) if random.random() < 0.3 else None
+    measurements['peep'] = random.randint(4, 8) if random.random() < 0.4 else None
+    measurements['pip'] = random.randint(25, 35) if random.random() < 0.4 else None
+
+    return measurements
+
+def generate_patients(num_patients=50):
+    patients = []
+    blood_types = ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-']
+    genders = ['male', 'female', 'other']
+
+    for i in range(num_patients):
+        patient_id_val = f"P-{i+1:05d}" # Sử dụng patient_id_val để tránh trùng tên biến
+        age = random.randint(18, 90)
+        gender = random.choices(genders, weights=[48, 48, 4], k=1)[0]
+
+        if gender == 'male':
+            firstName = fake.first_name_male()
+            lastName = fake.last_name()
+            height = round(random.uniform(160, 190), 1)
+            weight = round(random.gauss(mu=height * 0.45, sigma=10), 1)
+        elif gender == 'female':
+            firstName = fake.first_name_female()
+            lastName = fake.last_name()
+            height = round(random.uniform(150, 175), 1)
+            weight = round(random.gauss(mu=height * 0.4, sigma=8), 1)
+        else:
+            firstName = fake.first_name_nonbinary()
+            lastName = fake.last_name()
+            height = round(random.uniform(155, 180), 1)
+            weight = round(random.gauss(mu=height * 0.42, sigma=9), 1)
+
+        weight = max(40, min(150, weight))
+
+        patient = {
+            "patientID": patient_id_val, # Sử dụng patient_id_val
+            "firstName": firstName,
+            "lastName": lastName,
+            "age": age,
+            "gender": gender,
+            "height": height,
+            "weight": weight,
+            "blood_type": random.choice(blood_types),
+            "initial_measurement": generate_measurement(age)
+        }
+        patients.append(patient)
+
+    return patients
+
+if __name__ == "__main__":
+    num = 50
+    print(f"Generating {num} patient records...")
+    patient_data = generate_patients(num)
+
+    try:
+        with open(output_file, 'w', encoding='utf-8') as f:
+            json.dump(patient_data, f, indent=4, ensure_ascii=False)
+        print(f"Successfully generated {num} patient records to {output_file}")
+    except IOError as e:
+        print(f"Error writing to file {output_file}: {e}")
diff --git a/migrations/README b/migrations/README
new file mode 100644
index 0000000..0e04844
--- /dev/null
+++ b/migrations/README
@@ -0,0 +1 @@
+Single-database configuration for Flask.
diff --git a/migrations/alembic.ini b/migrations/alembic.ini
new file mode 100644
index 0000000..ec9d45c
--- /dev/null
+++ b/migrations/alembic.ini
@@ -0,0 +1,50 @@
+# A generic, single database configuration.
+
+[alembic]
+# template used to generate migration files
+# file_template = %%(rev)s_%%(slug)s
+
+# set to 'true' to run the environment during
+# the 'revision' command, regardless of autogenerate
+# revision_environment = false
+
+
+# Logging configuration
+[loggers]
+keys = root,sqlalchemy,alembic,flask_migrate
+
+[handlers]
+keys = console
+
+[formatters]
+keys = generic
+
+[logger_root]
+level = WARN
+handlers = console
+qualname =
+
+[logger_sqlalchemy]
+level = WARN
+handlers =
+qualname = sqlalchemy.engine
+
+[logger_alembic]
+level = INFO
+handlers =
+qualname = alembic
+
+[logger_flask_migrate]
+level = INFO
+handlers =
+qualname = flask_migrate
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[formatter_generic]
+format = %(levelname)-5.5s [%(name)s] %(message)s
+datefmt = %H:%M:%S
diff --git a/migrations/env.py b/migrations/env.py
new file mode 100644
index 0000000..4c97092
--- /dev/null
+++ b/migrations/env.py
@@ -0,0 +1,113 @@
+import logging
+from logging.config import fileConfig
+
+from flask import current_app
+
+from alembic import context
+
+# this is the Alembic Config object, which provides
+# access to the values within the .ini file in use.
+config = context.config
+
+# Interpret the config file for Python logging.
+# This line sets up loggers basically.
+fileConfig(config.config_file_name)
+logger = logging.getLogger('alembic.env')
+
+
+def get_engine():
+    try:
+        # this works with Flask-SQLAlchemy<3 and Alchemical
+        return current_app.extensions['migrate'].db.get_engine()
+    except (TypeError, AttributeError):
+        # this works with Flask-SQLAlchemy>=3
+        return current_app.extensions['migrate'].db.engine
+
+
+def get_engine_url():
+    try:
+        return get_engine().url.render_as_string(hide_password=False).replace(
+            '%', '%%')
+    except AttributeError:
+        return str(get_engine().url).replace('%', '%%')
+
+
+# add your model's MetaData object here
+# for 'autogenerate' support
+# from myapp import mymodel
+# target_metadata = mymodel.Base.metadata
+config.set_main_option('sqlalchemy.url', get_engine_url())
+target_db = current_app.extensions['migrate'].db
+
+# other values from the config, defined by the needs of env.py,
+# can be acquired:
+# my_important_option = config.get_main_option("my_important_option")
+# ... etc.
+
+
+def get_metadata():
+    if hasattr(target_db, 'metadatas'):
+        return target_db.metadatas[None]
+    return target_db.metadata
+
+
+def run_migrations_offline():
+    """Run migrations in 'offline' mode.
+
+    This configures the context with just a URL
+    and not an Engine, though an Engine is acceptable
+    here as well.  By skipping the Engine creation
+    we don't even need a DBAPI to be available.
+
+    Calls to context.execute() here emit the given string to the
+    script output.
+
+    """
+    url = config.get_main_option("sqlalchemy.url")
+    context.configure(
+        url=url, target_metadata=get_metadata(), literal_binds=True
+    )
+
+    with context.begin_transaction():
+        context.run_migrations()
+
+
+def run_migrations_online():
+    """Run migrations in 'online' mode.
+
+    In this scenario we need to create an Engine
+    and associate a connection with the context.
+
+    """
+
+    # this callback is used to prevent an auto-migration from being generated
+    # when there are no changes to the schema
+    # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
+    def process_revision_directives(context, revision, directives):
+        if getattr(config.cmd_opts, 'autogenerate', False):
+            script = directives[0]
+            if script.upgrade_ops.is_empty():
+                directives[:] = []
+                logger.info('No changes in schema detected.')
+
+    conf_args = current_app.extensions['migrate'].configure_args
+    if conf_args.get("process_revision_directives") is None:
+        conf_args["process_revision_directives"] = process_revision_directives
+
+    connectable = get_engine()
+
+    with connectable.connect() as connection:
+        context.configure(
+            connection=connection,
+            target_metadata=get_metadata(),
+            **conf_args
+        )
+
+        with context.begin_transaction():
+            context.run_migrations()
+
+
+if context.is_offline_mode():
+    run_migrations_offline()
+else:
+    run_migrations_online()
diff --git a/migrations/script.py.mako b/migrations/script.py.mako
new file mode 100644
index 0000000..2c01563
--- /dev/null
+++ b/migrations/script.py.mako
@@ -0,0 +1,24 @@
+"""${message}
+
+Revision ID: ${up_revision}
+Revises: ${down_revision | comma,n}
+Create Date: ${create_date}
+
+"""
+from alembic import op
+import sqlalchemy as sa
+${imports if imports else ""}
+
+# revision identifiers, used by Alembic.
+revision = ${repr(up_revision)}
+down_revision = ${repr(down_revision)}
+branch_labels = ${repr(branch_labels)}
+depends_on = ${repr(depends_on)}
+
+
+def upgrade():
+    ${upgrades if upgrades else "pass"}
+
+
+def downgrade():
+    ${downgrades if downgrades else "pass"}
diff --git a/migrations/versions/cbc9db9dd958_update_database_schema_to_match_models.py b/migrations/versions/cbc9db9dd958_update_database_schema_to_match_models.py
new file mode 100644
index 0000000..929010b
--- /dev/null
+++ b/migrations/versions/cbc9db9dd958_update_database_schema_to_match_models.py
@@ -0,0 +1,60 @@
+"""Update database schema to match models
+
+Revision ID: cbc9db9dd958
+Revises: 
+Create Date: 2025-04-13 19:06:46.600555
+
+"""
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.dialects import mysql
+
+# revision identifiers, used by Alembic.
+revision = 'cbc9db9dd958'
+down_revision = None
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.create_table('activity_logs',
+    sa.Column('id', sa.Integer(), nullable=False),
+    sa.Column('user_id', sa.Integer(), nullable=False),
+    sa.Column('action', sa.String(length=255), nullable=False),
+    sa.Column('details', sa.Text(), nullable=True),
+    sa.Column('timestamp', sa.DateTime(), nullable=True),
+    sa.ForeignKeyConstraint(['user_id'], ['users.userID'], ),
+    sa.PrimaryKeyConstraint('id')
+    )
+    with op.batch_alter_table('users', schema=None) as batch_op:
+        batch_op.add_column(sa.Column('firstName', sa.String(length=50), nullable=False))
+        batch_op.add_column(sa.Column('lastName', sa.String(length=50), nullable=False))
+        batch_op.add_column(sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True))
+        batch_op.add_column(sa.Column('last_login', sa.DateTime(timezone=True), nullable=True))
+        batch_op.alter_column('password_hash',
+               existing_type=mysql.VARCHAR(length=255),
+               type_=sa.String(length=128),
+               nullable=True)
+        batch_op.drop_index('username')
+        batch_op.drop_column('username')
+
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    with op.batch_alter_table('users', schema=None) as batch_op:
+        batch_op.add_column(sa.Column('username', mysql.VARCHAR(length=50), nullable=False))
+        batch_op.create_index('username', ['username'], unique=True)
+        batch_op.alter_column('password_hash',
+               existing_type=sa.String(length=128),
+               type_=mysql.VARCHAR(length=255),
+               nullable=False)
+        batch_op.drop_column('last_login')
+        batch_op.drop_column('created_at')
+        batch_op.drop_column('lastName')
+        batch_op.drop_column('firstName')
+
+    op.drop_table('activity_logs')
+    # ### end Alembic commands ###
diff --git a/requirements.txt b/requirements.txt
index da70a9d..7ae5fa4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -42,4 +42,5 @@ coverage==7.2.2
 black==23.1.0
 flake8==6.0.0
 isort==5.12.0
-mypy==0.991 
\ No newline at end of file
+mypy==0.991 
+Faker
\ No newline at end of file
diff --git a/run.py b/run.py
index 7a3d58d..b3246be 100644
--- a/run.py
+++ b/run.py
@@ -10,34 +10,13 @@ from flask_bcrypt import Bcrypt
 from flask import Flask
 from datetime import datetime
 from flask_migrate import Migrate, init, migrate, upgrade
+import json # Import json
 
-# Định nghĩa schema updates cho các bảng
-schema_updates = {
-    'dietitians': [
-        "ALTER TABLE dietitians ADD COLUMN user_id INT NULL UNIQUE",
-        "ALTER TABLE dietitians ADD CONSTRAINT fk_dietitian_user FOREIGN KEY (user_id) REFERENCES users(userID) ON DELETE SET NULL",
-        "ALTER TABLE dietitians ADD COLUMN status ENUM('available', 'unavailable', 'on_leave') DEFAULT 'available'",
-        "ALTER TABLE dietitians ADD COLUMN email VARCHAR(100) UNIQUE",
-        "ALTER TABLE dietitians ADD COLUMN phone VARCHAR(20)",
-        "ALTER TABLE dietitians ADD COLUMN specialization VARCHAR(100)",
-        "ALTER TABLE dietitians ADD COLUMN notes TEXT",
-        "ALTER TABLE dietitians ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP",
-        "ALTER TABLE dietitians ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
-    ],
-    'patients': [
-        "ALTER TABLE patients ADD COLUMN dietitianID INT NULL",
-        "ALTER TABLE patients ADD CONSTRAINT fk_patient_dietitian FOREIGN KEY (dietitianID) REFERENCES dietitians(dietitianID)"
-    ],
-    'encounters': [
-        "ALTER TABLE encounters ADD COLUMN dietitianID INT NULL",
-        "ALTER TABLE encounters ADD CONSTRAINT fk_encounter_dietitian FOREIGN KEY (dietitianID) REFERENCES dietitians(dietitianID)"
-    ],
-    'procedures': [
-        "ALTER TABLE procedures ADD COLUMN procedureName VARCHAR(100)",
-        "ALTER TABLE procedures ADD COLUMN procedureEndDateTime DATETIME",
-        "ALTER TABLE procedures ADD COLUMN procedureResults TEXT"
-    ]
-}
+# Import models and status needed for reset
+from app.models.user import User
+from app.models.dietitian import Dietitian, DietitianStatus
+from app.models.patient import Patient, Encounter # Import Encounter
+from app.models.measurement import PhysiologicalMeasurement # Import Measurement
 
 def clear_cache():
     print("\n[Cache] Cleaning __pycache__ and .pyc files...")
@@ -52,6 +31,7 @@ def clear_cache():
                     print(f"[Error] {e}")
 
 def create_mysql_database(app):
+    """Create MySQL database if it doesn't exist"""
     try:
         uri = app.config['SQLALCHEMY_DATABASE_URI']
         if not uri.startswith('mysql'):
@@ -64,9 +44,13 @@ def create_mysql_database(app):
 
         connection = mysql.connector.connect(host=host, user=user, password=pwd)
         cursor = connection.cursor()
+        
+        # Create database with UTF-8 support
         cursor.execute(f"CREATE DATABASE IF NOT EXISTS {db} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")
-        cursor.close(); connection.close()
-        print(f"[DB] Database '{db}' ready.")
+        cursor.close()
+        connection.close()
+        
+        print(f"[DB] Database '{db}' created/verified.")
         return True
     except Exception as e:
         print(f"[DB Error] {e}")
@@ -92,8 +76,8 @@ def init_tables_and_admin(app, db):
             if not User.query.filter_by(email='admin@ccuhtm.com').first():
                 admin = User(
                     username='admin',
-                    email='admin@ccuhtm.com',
-                    password=bcrypt.generate_password_hash('admin').decode('utf-8')
+                    email='admin@gmail.com',
+                    password=bcrypt.generate_password_hash('111111').decode('utf-8')
                 )
                 db.session.add(admin)
                 db.session.commit()
@@ -134,319 +118,256 @@ def run_migrations(app, db):
         print(f"Lỗi khi thực hiện migration: {str(e)}")
         return False
 
-def check_database_structure(app):
+def perform_database_reset(app, db, bcrypt):
     """
-    Kiểm tra cấu trúc cơ sở dữ liệu hiện tại
+    Reset the database by deleting all data and recreating default accounts.
+    This is a destructive operation.
     """
     try:
-        # Đọc thông tin kết nối từ cấu hình
-        db_uri = app.config['SQLALCHEMY_DATABASE_URI']
-        
-        if not db_uri.startswith('mysql'):
-            print("Không phải cấu hình MySQL, không thể kiểm tra cấu trúc.")
+        # First ensure database exists
+        if not create_mysql_database(app):
+            print("[Error] Failed to create/verify database.")
             return False
+
+        # Get database connection information
+        uri = app.config['SQLALCHEMY_DATABASE_URI']
+        if not uri.startswith('mysql'):
+            print("[Error] Only MySQL databases are supported for reset.")
+            return False
+            
+        # Parse connection string
+        creds, path = uri.replace('mysql://', '').split('@')
+        user_db, pwd = creds.split(':') # Renamed user to user_db to avoid conflict
+        host, database = path.split('/')
         
-        # Phân tích chuỗi kết nối
-        db_parts = db_uri.replace('mysql://', '').split('@')
-        auth_parts = db_parts[0].split(':')
-        host_parts = db_parts[1].split('/')
-        
-        username = auth_parts[0]
-        password = auth_parts[1] if len(auth_parts) > 1 else ''
-        host = host_parts[0]
-        database = host_parts[1]
-        
-        print(f"Đang kết nối đến MySQL với người dùng '{username}' trên máy chủ '{host}'")
-        
-        # Kết nối đến MySQL
+        # Connect directly to database
+        print(f"[DB] Connecting to MySQL database '{database}'...")
         connection = mysql.connector.connect(
             host=host,
-            user=username,
-            password=password,
+            user=user_db, # Use renamed variable
+            password=pwd,
             database=database
         )
-        
         cursor = connection.cursor()
         
-        # Lấy danh sách tất cả các bảng
-        cursor.execute("SHOW TABLES")
-        tables = cursor.fetchall()
-        
-        print("\n=== DANH SÁCH BẢNG TRONG CƠ SỞ DỮ LIỆU ===")
-        for (table_name,) in tables:
-            print(f"\n--- Bảng: {table_name} ---")
+        try:
+            # Disable foreign key checks
+            print("[DB] Disabling foreign key checks...")
+            cursor.execute("SET FOREIGN_KEY_CHECKS = 0")
             
-            # Lấy cấu trúc của bảng
-            cursor.execute(f"DESCRIBE {table_name}")
-            columns = cursor.fetchall()
+            # Get all tables
+            print("[DB] Getting list of all tables...")
+            cursor.execute("SHOW TABLES")
+            tables = cursor.fetchall()
             
-            # Hiển thị thông tin cột
-            print("Tên cột\t\tLoại dữ liệu\tCó thể NULL\tKhóa\tMặc định\tThông tin khác")
-            print("-" * 100)
-            for column in columns:
-                field = column[0]
-                type = column[1]
-                null = column[2]
-                key = column[3]
-                default = column[4]
-                extra = column[5]
-                print(f"{field: <16} {type: <16} {null: <16} {key: <8} {default if default else 'NULL': <16} {extra}")
-        
-        # Đóng kết nối
-        cursor.close()
-        connection.close()
-        
-        return True
-    
-    except Exception as e:
-        print(f"Lỗi khi kiểm tra cấu trúc cơ sở dữ liệu: {str(e)}")
-        return False
-
-def update_database_schema(app, db):
-    """
-    Cập nhật cấu trúc cơ sở dữ liệu trực tiếp từ models
-    Cách này nhanh hơn so với migration nhưng chỉ nên dùng trong môi trường phát triển
-    """
-    try:
-        # Định nghĩa schema updates cho các bảng
-        schema_updates = {
-            'dietitians': [
-                "ALTER TABLE dietitians ADD COLUMN user_id INT NULL UNIQUE",
-                "ALTER TABLE dietitians ADD CONSTRAINT fk_dietitian_user FOREIGN KEY (user_id) REFERENCES users(userID) ON DELETE SET NULL",
-                "ALTER TABLE dietitians ADD COLUMN status ENUM('available', 'unavailable', 'on_leave') DEFAULT 'available'",
-                "ALTER TABLE dietitians ADD COLUMN email VARCHAR(100) UNIQUE",
-                "ALTER TABLE dietitians ADD COLUMN phone VARCHAR(20)",
-                "ALTER TABLE dietitians ADD COLUMN specialization VARCHAR(100)",
-                "ALTER TABLE dietitians ADD COLUMN notes TEXT",
-                "ALTER TABLE dietitians ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP",
-                "ALTER TABLE dietitians ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
-            ],
-            'patients': [
-                "ALTER TABLE patients ADD COLUMN dietitianID INT NULL",
-                "ALTER TABLE patients ADD CONSTRAINT fk_patient_dietitian FOREIGN KEY (dietitianID) REFERENCES dietitians(dietitianID)"
-            ],
-            'encounters': [
-                "ALTER TABLE encounters ADD COLUMN dietitianID INT NULL",
-                "ALTER TABLE encounters ADD CONSTRAINT fk_encounter_dietitian FOREIGN KEY (dietitianID) REFERENCES dietitians(dietitianID)"
-            ],
-            'procedures': [
-                "ALTER TABLE procedures ADD COLUMN procedureName VARCHAR(100)",
-                "ALTER TABLE procedures ADD COLUMN procedureEndDateTime DATETIME",
-                "ALTER TABLE procedures ADD COLUMN procedureResults TEXT"
-            ]
-        }
-        
-        # Đọc thông tin kết nối từ cấu hình
-        db_uri = app.config['SQLALCHEMY_DATABASE_URI']
-        
-        if not db_uri.startswith('mysql'):
-            print("Không phải cấu hình MySQL, không thể cập nhật cấu trúc.")
+            # Drop all tables
+            print("[DB] Dropping all tables...")
+            for (table_name,) in tables:
+                print(f"  - Dropping table: {table_name}")
+                cursor.execute(f"DROP TABLE IF EXISTS `{table_name}`")
+                
+            # Re-enable foreign key checks
+            print("[DB] Re-enabling foreign key checks...")
+            cursor.execute("SET FOREIGN_KEY_CHECKS = 1")
+            
+            # Commit changes
+            connection.commit()
+            
+        except mysql.connector.Error as e:
+            print(f"[MySQL Error] {e}")
             return False
+        finally:
+            # Ensure connection is closed
+            if connection.is_connected():
+                cursor.close()
+                connection.close()
         
-        # Phân tích chuỗi kết nối
-        db_parts = db_uri.replace('mysql://', '').split('@')
-        auth_parts = db_parts[0].split(':')
-        host_parts = db_parts[1].split('/')
-        
-        username = auth_parts[0]
-        password = auth_parts[1] if len(auth_parts) > 1 else ''
-        host = host_parts[0]
-        database = host_parts[1]
-        
-        print(f"Đang kết nối đến MySQL với người dùng '{username}' trên máy chủ '{host}'")
-        
-        # Kết nối đến MySQL
-        connection = mysql.connector.connect(
-            host=host,
-            user=username,
-            password=password,
-            database=database
-        )
-        
-        cursor = connection.cursor()
-        
+        # Now use Flask-SQLAlchemy to create tables and users
         with app.app_context():
-            # Kiểm tra và xóa cột 'userID' không mong muốn khỏi bảng 'dietitians'
-            print("\nKiểm tra và xóa cột 'userID' không mong muốn khỏi bảng 'dietitians'...")
             try:
-                cursor.execute("SHOW COLUMNS FROM dietitians LIKE 'userID'")
-                if cursor.fetchone():
-                    print("  - Tìm thấy cột 'userID'. Đang xóa...")
-                    cursor.execute("ALTER TABLE dietitians DROP COLUMN userID")
-                    print("  - Đã xóa cột 'userID'.")
-                else:
-                    print("  - Cột 'userID' không tồn tại, không cần xóa.")
-            except mysql.connector.Error as err:
-                print(f"  - Lỗi khi kiểm tra/xóa cột 'userID': {err.msg}")
-
-            # Thực hiện các câu lệnh cập nhật
-            for table, statements in schema_updates.items():
-                print(f"\nĐang cập nhật bảng {table}...")
+                # Create all tables
+                print("[DB] Creating all tables from models...")
+                db.create_all()
+                db.session.commit()
                 
-                # Kiểm tra xem bảng có tồn tại không
-                cursor.execute(f"SHOW TABLES LIKE '{table}'")
-                table_exists = cursor.fetchone()
+                print("[DB] Creating default admin account...")
+                # Create default admin account
+                admin_user = User(
+                    firstName="Admin", 
+                    lastName="User",
+                    email="admin@ccuhtm.com",
+                    role="Admin"
+                )
+                admin_user.set_password("admin") # Use set_password method
+                db.session.add(admin_user)
                 
-                if not table_exists:
-                    print(f"  - Bảng {table} không tồn tại, bỏ qua")
-                    continue
+                print("[DB] Creating default dietitian accounts...")
+                default_password = "111111"
+                hashed_password = bcrypt.generate_password_hash(default_password).decode('utf-8')
+                created_dietitian_users = [] # List to store created users
+
+                for i in range(1, 6):
+                    # Create User with Dietitian role
+                    dietitian_user = User(
+                        firstName=f"Dietitian{i}",
+                        lastName="Test",
+                        email=f"dietitian{i}@gmail.com",
+                        password_hash=hashed_password,
+                        role="Dietitian"
+                    )
+                    db.session.add(dietitian_user)
+                    db.session.flush()  # Get the userID for the new user
+                    created_dietitian_users.append(dietitian_user) # Add user to list
+                    
+                    # Create Dietitian profile and link it to the user
+                    dietitian_profile = Dietitian(
+                        firstName=dietitian_user.firstName,
+                        lastName=dietitian_user.lastName,
+                        email=dietitian_user.email,
+                        status=DietitianStatus.AVAILABLE,
+                        user_id=dietitian_user.userID 
+                    )
+                    db.session.add(dietitian_profile)
                 
-                # Lấy danh sách các cột hiện tại của bảng
-                cursor.execute(f"SHOW COLUMNS FROM {table}")
-                existing_columns = [column[0] for column in cursor.fetchall()]
+                # Commit all changes
+                db.session.commit()
+                print("\n[DB] Database reset completed successfully.")
+                print("[Admin] Default admin account created:")
+                print(f"  - Email: {admin_user.email}")
+                print("  - Password: admin")
+                print("[Dietitians] 5 default dietitian accounts created:")
+                print(f"  - Password (for all): {default_password}")
                 
-                # Thực hiện các câu lệnh ALTER TABLE
-                for statement in statements:
+                # Truy vấn và in thông tin dietitian sau khi commit
+                print("  - Created Dietitian Details:")
+                final_dietitians = Dietitian.query.join(User).filter(User.email.in_([u.email for u in created_dietitian_users])).order_by(Dietitian.dietitianID).all()
+                for dt in final_dietitians:
+                    print(f"    - {dt.user.email} / {dt.formattedID}")
+
+                print("\nImportant: Please change passwords after logging in!")
+                
+                # --- Add Patients from JSON --- 
+                print("[DB] Adding patients from JSON file...")
+                json_file_path = os.path.join(os.path.dirname(__file__), 'patients_data.json')
+                if not os.path.exists(json_file_path):
+                    print(f"[Warning] patients_data.json not found at {json_file_path}. Skipping patient data loading.")
+                else:
                     try:
-                        column_name = None
-                        constraint_name = None
-                        is_add_column = "ADD COLUMN" in statement
-                        is_add_constraint = "ADD CONSTRAINT" in statement
+                        with open(json_file_path, 'r', encoding='utf-8') as f:
+                            patients_json_data = json.load(f)
+                        
+                        patients_added = 0
+                        measurements_added = 0
+                        for patient_data in patients_json_data:
+                            try:
+                                # Create Patient
+                                new_patient = Patient(
+                                    id=patient_data.get('patientID'), 
+                                    firstName=patient_data.get('firstName'),
+                                    lastName=patient_data.get('lastName'),
+                                    age=patient_data.get('age'),
+                                    gender=patient_data.get('gender'),
+                                    height=patient_data.get('height'),
+                                    weight=patient_data.get('weight'),
+                                    blood_type=patient_data.get('blood_type'),
+                                    admission_date=datetime.utcnow() 
+                                )
+                                new_patient.calculate_bmi() 
+                                db.session.add(new_patient)
+                                # Không cần flush vì khóa chính (id) đã có giá trị
 
-                        if is_add_column:
-                            # Phân tích cú pháp để lấy tên cột
-                            parts = statement.split("ADD COLUMN")[1].strip().split(" ")
-                            if len(parts) > 0:
-                                column_name = parts[0].strip('`') # Remove potential backticks
+                                # Create an initial Encounter for the patient
+                                initial_encounter = Encounter(
+                                    patientID=new_patient.id, # Link using patient's string ID
+                                    admissionDateTime=new_patient.admission_date # Use patient's admission time
+                                    # Các trường khác sẽ là NULL hoặc default
+                                )
+                                db.session.add(initial_encounter)
+                                db.session.flush() # Flush để lấy encounter.id (Integer)
 
-                            # Kiểm tra xem cột đã tồn tại chưa
-                            if column_name and column_name in existing_columns:
-                                print(f"  - Bỏ qua: Cột {column_name} đã tồn tại trong bảng {table}")
-                                continue
-                        elif is_add_constraint:
-                            # Phân tích cú pháp để lấy tên constraint
-                            parts = statement.split("ADD CONSTRAINT")[1].strip().split(" ")
-                            if len(parts) > 0:
-                                constraint_name = parts[0].strip('`')
+                                # Create Initial Measurement, linking to the new encounter
+                                initial_measurement_data = patient_data.get('initial_measurement', {})
+                                if initial_measurement_data:
+                                    new_measurement = PhysiologicalMeasurement(
+                                        patient_id=new_patient.id, 
+                                        encounter_id=initial_encounter.id, # Sử dụng ID của encounter vừa tạo
+                                        measurementDateTime=datetime.utcnow(),
+                                        temperature=initial_measurement_data.get('temperature'),
+                                        heart_rate=initial_measurement_data.get('heart_rate'),
+                                        blood_pressure_systolic=initial_measurement_data.get('blood_pressure_systolic'),
+                                        blood_pressure_diastolic=initial_measurement_data.get('blood_pressure_diastolic'),
+                                        oxygen_saturation=initial_measurement_data.get('oxygen_saturation'),
+                                        resp_rate=initial_measurement_data.get('resp_rate'),
+                                        fio2=initial_measurement_data.get('fio2'),
+                                        tidal_vol=initial_measurement_data.get('tidal_vol'),
+                                        end_tidal_co2=initial_measurement_data.get('end_tidal_co2'),
+                                        feed_vol=initial_measurement_data.get('feed_vol'),
+                                        peep=initial_measurement_data.get('peep'),
+                                        pip=initial_measurement_data.get('pip')
+                                    )
+                                    db.session.add(new_measurement)
+                                    measurements_added += 1
+                                
+                                patients_added += 1
+                            except Exception as patient_err:
+                                print(f"[Error] Could not add patient {patient_data.get('patientID')}: {patient_err}")
+                                db.session.rollback() 
+                        
+                        db.session.commit() 
+                        print(f"[DB] Successfully added {patients_added} patients and {measurements_added} initial measurements.")
 
-                            # Kiểm tra xem constraint đã tồn tại chưa
-                            if constraint_name:
-                                cursor.execute(f"SHOW CREATE TABLE {table}")
-                                create_table_sql = cursor.fetchone()[1]
-                                if constraint_name in create_table_sql:
-                                    print(f"  - Bỏ qua: Constraint {constraint_name} đã tồn tại trong bảng {table}")
-                                    continue
+                    except FileNotFoundError:
+                         print(f"[Error] patients_data.json not found at {json_file_path}.")
+                    except json.JSONDecodeError:
+                        print(f"[Error] Could not decode JSON from {json_file_path}.")
+                    except Exception as json_err:
+                        print(f"[Error] Failed loading patient data from JSON: {json_err}")
+                        db.session.rollback()
 
-                        # Thêm log đặc biệt cho việc thêm cột status vào dietitians
-                        if table == 'dietitians' and column_name == 'status':
-                            print(f"  -> Đang chuẩn bị thực thi: {statement}")
+                # Kết thúc phần thêm bệnh nhân
 
-                        cursor.execute(statement)
-                        print(f"  - Thành công: {statement}")
-                    except mysql.connector.Error as err:
-                        # Lỗi cụ thể từ MySQL Connector
-                        print(f"  - Lỗi MySQL khi thực thi: {statement}")
-                        print(f"    Error Code: {err.errno}")
-                        print(f"    SQLSTATE: {err.sqlstate}")
-                        print(f"    Message: {err.msg}")
-                    except Exception as e:
-                        # Lỗi chung khác
-                        print(f"  - Lỗi chung khi thực thi: {statement}")
-                        print(f"    {str(e)}")
-            
-            # Commit các thay đổi
-            print(f"Committing changes for database {database}...")
-            connection.commit()
-            
-        # Đóng kết nối
-        cursor.close()
-        connection.close()
-        
-        print("\nHoàn tất cập nhật cấu trúc cơ sở dữ liệu!")
-        return True
-    
-    except Exception as e:
-        print(f"Lỗi khi cập nhật cấu trúc cơ sở dữ liệu: {str(e)}")
-        return False
-
-def create_admin_user_direct():
-    """Tạo tài khoản admin trực tiếp"""
-    try:
-        from app import create_app, db
-        from app.models.user import User
-        from flask_bcrypt import Bcrypt
-
-        app = create_app()
-        bcrypt = Bcrypt(app)
-        
-        with app.app_context():
-            admin_email = 'admin@ccuhtm.com'
-            if not User.query.filter_by(email=admin_email).first():
-                admin = User(
-                    username='admin',
-                    email=admin_email,
-                    password=bcrypt.generate_password_hash('admin').decode('utf-8'),
-                    role='Admin'
-                )
-                db.session.add(admin)
-                db.session.commit()
-                print("[Admin] Created default admin user with username: admin, password: admin")
-            else:
-                print("[Admin] Admin user already exists")
-        
-        return True
+                return True
+            except Exception as e:
+                db.session.rollback()
+                print(f"[Error] Failed during table creation or data insertion: {e}")
+                return False
+                
     except Exception as e:
-        print(f"[Error] Failed to create admin user: {e}")
+        print(f"[Error] Failed to reset database: {e}")
         return False
 
 def main():
-    # Phân tích tham số dòng lệnh
+    # Parse command line arguments
     parser = argparse.ArgumentParser(description='CCU HTM Management System')
-    parser.add_argument('--init', action='store_true', help='Khởi tạo cơ sở dữ liệu')
-    parser.add_argument('--clean', action='store_true', help='Xóa cache trước khi chạy')
-    parser.add_argument('--admin', action='store_true', help='Tạo tài khoản admin')
-    parser.add_argument('--port', type=int, default=5000, help='Port để chạy ứng dụng')
-    parser.add_argument('--migrate', action='store_true', help='Thực hiện migration cơ sở dữ liệu')
-    parser.add_argument('--check-db', action='store_true', help='Kiểm tra cấu trúc cơ sở dữ liệu')
-    parser.add_argument('--update-db', action='store_true', help='Cập nhật cấu trúc cơ sở dữ liệu trực tiếp từ models')
+    parser.add_argument('--reset', action='store_true', help='Reset database (deletes all data and recreates admin account)')
+    parser.add_argument('--clean', action='store_true', help='Clean cache before running')
+    parser.add_argument('--port', type=int, default=5000, help='Port to run the application')
+    parser.add_argument('--migrate', action='store_true', help='Run database migrations')
     args = parser.parse_args()
 
-    # Import modules
     from app import create_app, db
+    bcrypt = Bcrypt(create_app())
 
-    # Tạo ứng dụng
     app = create_app()
     
-    # Xóa cache nếu yêu cầu
     if args.clean:
         clear_cache()
     
-    # Khởi tạo cơ sở dữ liệu nếu yêu cầu
-    if args.init:
-        print("Bắt đầu khởi tạo cơ sở dữ liệu...")
-        if create_mysql_database(app):
-            if init_tables_and_admin(app, db):
-                print("Khởi tạo cơ sở dữ liệu hoàn tất!")
-            else:
-                print("Lỗi khi khởi tạo bảng và tài khoản admin.")
+    if args.reset:
+        print("[DB] Starting database reset requested via --reset flag...")
+        if perform_database_reset(app, db, bcrypt): 
+            print("[DB] Database reset via --reset flag completed!")
         else:
-            print("Lỗi khi tạo cơ sở dữ liệu MySQL.")
+            print("[Error] Failed to reset database via --reset flag.")
+        return # Exit after reset attempt
     
-    # Thực hiện migration nếu yêu cầu
     if args.migrate:
-        print("Bắt đầu thực hiện migration...")
+        print("[DB] Starting database migration...")
         run_migrations(app, db)
+        return # Exit after migration attempt
     
-    # Kiểm tra cấu trúc cơ sở dữ liệu nếu yêu cầu
-    if args.check_db:
-        print("Đang kiểm tra cấu trúc cơ sở dữ liệu...")
-        check_database_structure(app)
-    
-    # Cập nhật cấu trúc cơ sở dữ liệu trực tiếp nếu yêu cầu
-    if args.update_db:
-        print("Bắt đầu cập nhật cấu trúc cơ sở dữ liệu...")
-        update_database_schema(app, db)
-    
-    # Tạo tài khoản admin nếu yêu cầu
-    if args.admin:
-        print("Bắt đầu tạo tài khoản admin...")
-        create_admin_user_direct()
-        
-    # Chạy ứng dụng nếu không có tham số nào khác hoặc chỉ có flag --clean
-    is_only_clean = args.clean and not any([args.init, args.admin, args.migrate, args.check_db, args.update_db])
-    if not any([args.init, args.admin, args.migrate, args.check_db, args.update_db]) or is_only_clean:
-        print(f"Khởi chạy CCU HTM trên port {args.port}...")
-        app.run(host='0.0.0.0', port=args.port, debug=True)
+    print(f"\n[App] Starting CCU HTM on port {args.port}...")
+    app.run(host='0.0.0.0', port=args.port, debug=True)
 
 if __name__ == '__main__':
     main()
diff --git a/run_ccu.bat b/run_ccu.bat
index af81c1a..ad98dfc 100644
--- a/run_ccu.bat
+++ b/run_ccu.bat
@@ -5,45 +5,40 @@ echo -------------------------
 :menu
 cls
 echo Select a function:
-echo 1. Initialize the database (includes migration)
-echo 2. Run the application
-echo 3. Create admin account
-echo 4. Update database schema
-echo 5. Exit
+echo 1. Run the application
+echo 2. Apply database migrations
+echo 3. Reset database (warning: this will delete all data)
+echo 4. Exit
 echo.
 
-set /p choice=Your choice (1-5): 
+set /p choice=Your choice (1-4): 
 
 if "%choice%"=="1" (
-    echo Initializing the database and performing migration...
-    python run.py --init --migrate
-    echo.
-    echo Press any key to return to the menu...
-    pause >nul
-    goto menu
-)
-if "%choice%"=="2" (
     echo Starting the application...
     python run.py --clean
     goto end
 )
-if "%choice%"=="3" (
-    echo Creating admin account...
-    python run.py --admin
+if "%choice%"=="2" (
+    echo Applying database migrations...
+    python run.py --migrate
     echo.
     echo Press any key to return to the menu...
     pause >nul
     goto menu
 )
-if "%choice%"=="4" (
-    echo Updating database schema...
-    python run.py --check-db --update-db
-    echo.
-    echo Press any key to return to the menu...
-    pause >nul
+if "%choice%"=="3" (
+    echo WARNING: This will delete all existing data in the database.
+    set /p confirm="Are you sure you want to proceed? (Y/N) "
+    if /i "%confirm%"=="y" (
+        echo Resetting database...
+        python run.py --reset
+        echo.
+        echo Press any key to return to the menu...
+        pause >nul
+    )
     goto menu
 )
-if "%choice%"=="5" (
+if "%choice%"=="4" (
     goto end
 ) else (
     echo Invalid choice!
-- 
GitLab