127 lines
5.1 KiB
Python
127 lines
5.1 KiB
Python
# modules/login_page.py
|
||
import flet as ft
|
||
import logging
|
||
import tkinter as tk
|
||
|
||
class LoginPage:
|
||
def __init__(self, page: ft.Page, logger: logging.Logger, settings_manager, db_manager, on_login_success, project_info):
|
||
self.page = page
|
||
self.logger = logger
|
||
self.settings_manager = settings_manager
|
||
self.db_manager = db_manager
|
||
self.on_login_success = on_login_success
|
||
self.project_info = project_info # {'name': ..., 'window_title': ..., 'version': ..., 'authors': ...}
|
||
self.logger.log("Initializing LoginPage...", level=logging.DEBUG)
|
||
self.build_page()
|
||
|
||
def build_page(self):
|
||
# 헤더: 프로그램 제목, 버전, 제작자 정보
|
||
self.header = ft.Container(
|
||
content=ft.Column(
|
||
[
|
||
ft.Text(self.project_info.get("window_title", "App"), style=ft.TextStyle(size=30, weight="bold"), color="black"),
|
||
ft.Text(f"Version {self.project_info.get('version', '0.0.0')}", style=ft.TextStyle(size=16), color="gray"),
|
||
ft.Text(f"제작자: {self.project_info.get('authors', '')}", style=ft.TextStyle(size=16), color="gray"),
|
||
],
|
||
horizontal_alignment="center",
|
||
spacing=5,
|
||
),
|
||
padding=10,
|
||
bgcolor="white",
|
||
alignment=ft.alignment.center,
|
||
border=ft.border.all(1, "lightgray"),
|
||
border_radius=ft.border_radius.all(5),
|
||
)
|
||
|
||
# 로그인 폼
|
||
self.username_field = ft.TextField(
|
||
label="사용자 이름", width=300, on_submit=lambda e: self.password_field.focus()
|
||
)
|
||
self.password_field = ft.TextField(
|
||
label="비밀번호", width=300, password=True, on_submit=lambda e: self.login(None)
|
||
)
|
||
self.remember_checkbox = ft.Checkbox(label="정보 저장")
|
||
self.login_button = ft.ElevatedButton(text="로그인", on_click=self.login)
|
||
self.message = ft.Text("", color="red")
|
||
|
||
# 로그인 폼 컨테이너
|
||
self.form_container = ft.Container(
|
||
content=ft.Column(
|
||
[
|
||
self.username_field,
|
||
self.password_field,
|
||
self.remember_checkbox,
|
||
self.login_button,
|
||
self.message,
|
||
],
|
||
alignment="center",
|
||
horizontal_alignment="center",
|
||
spacing=15,
|
||
),
|
||
padding=20,
|
||
bgcolor="white",
|
||
border=ft.border.all(1, "lightgray"),
|
||
border_radius=ft.border_radius.all(10),
|
||
shadow=ft.BoxShadow(blur_radius=10, spread_radius=1, offset=ft.Offset(2,2), color="gray"),
|
||
)
|
||
|
||
# 전체 로그인 페이지 컨텐츠 (중앙 정렬)
|
||
self.controls = [
|
||
ft.Container(
|
||
content=ft.Column(
|
||
[
|
||
self.header,
|
||
self.form_container,
|
||
],
|
||
spacing=20,
|
||
horizontal_alignment="center",
|
||
),
|
||
alignment=ft.alignment.center,
|
||
expand=True,
|
||
bgcolor="#f0f2f5",
|
||
)
|
||
]
|
||
|
||
def login(self, e):
|
||
self.logger.log("LoginPage.login() 호출됨", level=logging.DEBUG)
|
||
username = self.username_field.value.strip()
|
||
password = self.password_field.value.strip()
|
||
if not username or not password:
|
||
self.message.value = "사용자 이름과 비밀번호를 모두 입력하세요."
|
||
self.page.update()
|
||
return
|
||
|
||
result = self.db_manager.login(username, password)
|
||
if "error" not in result:
|
||
self.logger.log(f"로그인 성공: {result}", level=logging.DEBUG)
|
||
self.db_manager.update_last_login(result["id"])
|
||
if self.remember_checkbox.value:
|
||
user_info = {"username": username, "password": password, "id": result["id"]}
|
||
self.settings_manager.save_user_info(user_info)
|
||
self.message.value = "로그인 성공!"
|
||
self.page.update()
|
||
self.on_login_success()
|
||
else:
|
||
self.message.value = f"로그인 실패: {result['error']}"
|
||
self.logger.log(f"로그인 실패: {result['error']}", level=logging.WARNING)
|
||
self.page.update()
|
||
|
||
def show(self):
|
||
# 창 크기를 500×500로 설정하고 중앙 배치
|
||
self.page.window.width = 500
|
||
self.page.window.height = 500
|
||
# 중앙 배치를 위해 tkinter로 화면 해상도 계산
|
||
root = tk.Tk()
|
||
root.withdraw()
|
||
screen_width = root.winfo_screenwidth()
|
||
screen_height = root.winfo_screenheight()
|
||
root.destroy()
|
||
self.page.window.x = int((screen_width - 500) / 2)
|
||
self.page.window.y = int((screen_height - 500) / 2)
|
||
if hasattr(self.page.window, "center"):
|
||
self.page.window.center()
|
||
self.page.controls.clear()
|
||
for ctrl in self.controls:
|
||
self.page.add(ctrl)
|
||
self.page.update()
|