Resell1/modules/login.py

97 lines
3.9 KiB
Python

import flet as ft
from flet import (
AlertDialog, TextField, Checkbox, ElevatedButton, Text, Column, Row,
MainAxisAlignment
)
import asyncio
import logging
class LoginDialog:
"""
flet 기반 로그인 다이얼로그.
- 이메일, 비밀번호 입력란
- "정보 저장" 체크박스 (체크 시, SettingsManager를 통해 사용자 정보를 저장)
- "비밀번호 보기" 체크박스 (비밀번호 입력란 에코 모드 전환)
- 로그인 및 비밀번호 찾기 버튼
"""
def __init__(self, page: ft.Page, logger: logging.Logger, settings_manager, supabase_manager):
self.page = page
self.logger = logger
self.settings_manager = settings_manager
self.supabase_manager = supabase_manager
self.result = None # 로그인 성공 여부 (True/False)
self.create_dialog()
def create_dialog(self):
# 입력 필드 및 체크박스
self.email_field = TextField(label="이메일", width=300)
self.password_field = TextField(label="비밀번호", width=300, password=True)
self.remember_checkbox = Checkbox(label="정보 저장")
self.show_password_checkbox = Checkbox(label="비밀번호 보기")
self.error_text = Text("", color="red")
self.show_password_checkbox.on_change = self.toggle_password
# 버튼들
self.login_button = ElevatedButton("로그인", on_click=self.on_login)
self.reset_button = ElevatedButton("비밀번호 찾기", on_click=self.on_reset)
content = Column([
self.email_field,
self.password_field,
Row([self.remember_checkbox, self.show_password_checkbox]),
self.error_text,
Row([self.login_button, self.reset_button], alignment=MainAxisAlignment.CENTER)
])
self.dialog = AlertDialog(
title=Text("로그인"),
content=content,
actions_alignment=MainAxisAlignment.CENTER
)
self.page.dialog = self.dialog
self.dialog.open = True
self.page.update()
def toggle_password(self, e: ft.ControlEvent):
self.password_field.password = not self.show_password_checkbox.value
self.page.update()
def on_login(self, e: ft.ControlEvent):
email = self.email_field.value.strip()
password = self.password_field.value.strip()
if not email or not password:
self.error_text.value = "이메일과 비밀번호를 모두 입력하세요."
self.page.update()
return
# 실제 Supabase 로그인을 시도합니다.
result = self.supabase_manager.login(email, password)
if "error" not in result:
self.logger.log(f"로그인 성공: {result}", level=logging.DEBUG)
# 마지막 로그인 시간 업데이트
self.supabase_manager.update_last_login(result["id"])
if self.remember_checkbox.value:
user_info = {"email": email, "password": password, "id": result["id"]}
self.settings_manager.save_user_info(user_info)
self.result = True
self.dialog.open = False
self.page.update()
else:
self.error_text.value = f"로그인 실패: {result['error']}"
self.logger.log(f"로그인 실패: {result['error']}", level=logging.WARNING)
self.page.update()
def on_reset(self, e: ft.ControlEvent):
self.error_text.value = "비밀번호 찾기 기능은 구현되지 않았습니다."
self.page.update()
async def show(self) -> bool:
"""
로그인 다이얼로그를 보여주고, 로그인 성공 시 True를 반환합니다.
(비동기적으로 result가 채워질 때까지 기다립니다.)
"""
while self.result is None:
await asyncio.sleep(0.1)
return self.result