facebook-tool/gui/tabs/account_tab.py

174 lines
6.1 KiB
Python

from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QTableWidget, QTableWidgetItem,
QPushButton, QHBoxLayout, QDialog, QLabel, QLineEdit, QComboBox, QMessageBox,
QMenu, QAction, QSizePolicy
)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QHeaderView
from database.models import Account
PAGE_SIZE = 10
class AccountForm(QDialog):
def __init__(self, parent=None, account=None):
super().__init__(parent)
self.setWindowTitle("Account Form")
self.account = account
self.setMinimumSize(400, 200) # Form to hơn
layout = QVBoxLayout()
layout.addWidget(QLabel("Email"))
self.email_input = QLineEdit()
self.email_input.setMinimumWidth(250)
layout.addWidget(self.email_input)
layout.addWidget(QLabel("Password"))
self.password_input = QLineEdit()
layout.addWidget(self.password_input)
layout.addWidget(QLabel("Status"))
self.active_input = QComboBox()
self.active_input.addItems(["Inactive", "Active"])
layout.addWidget(self.active_input)
btn_layout = QHBoxLayout()
self.save_btn = QPushButton("Save")
self.save_btn.setMinimumWidth(80)
self.save_btn.clicked.connect(self.save)
btn_layout.addWidget(self.save_btn)
self.cancel_btn = QPushButton("Cancel")
self.cancel_btn.setMinimumWidth(80)
self.cancel_btn.clicked.connect(self.close)
btn_layout.addWidget(self.cancel_btn)
layout.addLayout(btn_layout)
self.setLayout(layout)
# nếu edit account
if account:
self.email_input.setText(account.get("email", ""))
self.password_input.setText(account.get("password", ""))
self.active_input.setCurrentText("Active" if account.get("is_active", 1) == 1 else "Inactive")
def save(self):
email = self.email_input.text()
password = self.password_input.text()
is_active = 1 if self.active_input.currentText() == "Active" else 0
try:
if self.account and "id" in self.account:
Account.update(self.account["id"], email, password, is_active)
else:
Account.create(email, password, is_active)
self.accept()
except Exception as e:
QMessageBox.warning(self, "Error", str(e))
class AccountTab(QWidget):
def __init__(self):
super().__init__()
self.current_page = 0
layout = QVBoxLayout()
# Add button
self.add_btn = QPushButton("Add Account")
self.add_btn.setMinimumWidth(120)
self.add_btn.clicked.connect(self.add_account)
layout.addWidget(self.add_btn)
# Table
self.table = QTableWidget()
self.table.verticalHeader().setDefaultSectionSize(28) # row gọn
self.table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
layout.addWidget(self.table)
# Pagination
pag_layout = QHBoxLayout()
self.prev_btn = QPushButton("Previous")
self.prev_btn.setMinimumWidth(100)
self.prev_btn.clicked.connect(self.prev_page)
pag_layout.addWidget(self.prev_btn)
self.next_btn = QPushButton("Next")
self.next_btn.setMinimumWidth(100)
self.next_btn.clicked.connect(self.next_page)
pag_layout.addWidget(self.next_btn)
layout.addLayout(pag_layout)
self.setLayout(layout)
self.load_data()
def load_data(self):
accounts = Account.all()
start = self.current_page * PAGE_SIZE
end = start + PAGE_SIZE
page_items = accounts[start:end]
self.table.setRowCount(len(page_items))
self.table.setColumnCount(4)
self.table.setHorizontalHeaderLabels(["ID", "Email", "Status", "Actions"])
for i, acc in enumerate(page_items):
# convert sqlite3.Row -> dict
acc_dict = {k: acc[k] for k in acc.keys()}
self.table.setItem(i, 0, QTableWidgetItem(str(acc_dict["id"])))
self.table.setItem(i, 1, QTableWidgetItem(acc_dict["email"]))
self.table.setItem(i, 2, QTableWidgetItem("Active" if acc_dict["is_active"] == 1 else "Inactive"))
# nút menu Actions
btn_menu = QPushButton("Actions")
menu = QMenu()
action_edit = QAction("Edit", btn_menu)
action_edit.triggered.connect(lambda _, a=acc_dict: self.edit_account(a))
menu.addAction(action_edit)
action_delete = QAction("Delete", btn_menu)
action_delete.triggered.connect(lambda _, a=acc_dict: self.delete_account(a))
menu.addAction(action_delete)
btn_menu.setMenu(menu)
self.table.setCellWidget(i, 3, btn_menu)
# Phân bổ column width hợp lý
header = self.table.horizontalHeader()
header.setSectionResizeMode(0, QHeaderView.ResizeToContents) # ID
header.setSectionResizeMode(1, QHeaderView.Stretch) # Email stretch
header.setSectionResizeMode(2, QHeaderView.ResizeToContents) # Status
header.setSectionResizeMode(3, QHeaderView.Fixed) # Actions fixed width
self.table.setColumnWidth(3, 100) # 100px cho Actions
# Enable/disable pagination buttons
self.prev_btn.setEnabled(self.current_page > 0)
self.next_btn.setEnabled(end < len(accounts))
def add_account(self):
form = AccountForm(self)
if form.exec_():
self.current_page = 0
self.load_data()
def edit_account(self, account):
form = AccountForm(self, account)
if form.exec_():
self.load_data()
def delete_account(self, account):
confirm = QMessageBox.question(
self, "Confirm", f"Delete account {account['email']}?",
QMessageBox.Yes | QMessageBox.No
)
if confirm == QMessageBox.Yes:
Account.delete(account["id"])
self.load_data()
def next_page(self):
self.current_page += 1
self.load_data()
def prev_page(self):
self.current_page -= 1
self.load_data()