File size: 3,796 Bytes
02ee0b7
a67abac
02ee0b7
a67abac
02ee0b7
 
a67abac
 
 
 
 
 
 
 
 
ea1d31a
aba0609
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02ee0b7
 
 
 
aba0609
02ee0b7
 
175d049
 
02ee0b7
 
 
 
 
 
fea7e85
ea1d31a
02ee0b7
 
 
 
 
 
 
 
 
 
 
175d049
 
02ee0b7
 
 
 
 
 
 
 
 
 
 
 
 
da94ae5
 
02ee0b7
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import os
import base64
import urllib.parse
from pathlib import Path
import gradio as gr

def _logo_data_uri() -> str:
    """logo.png を Base64 エンコードして data URI を返す。ファイルがなければ空文字。"""
    logo_path = Path(__file__).parent / "logo.png"
    if logo_path.exists():
        data = base64.b64encode(logo_path.read_bytes()).decode()
        return f"data:image/png;base64,{data}"
    return ""

LOGO_SRC = _logo_data_uri()

# --- チャット(コメントアウト) ---
# # Level Bridge Chat の Space URL(環境変数で上書き可能)
# CHAT_SPACE_URL = os.environ.get(
#     "LEVEL_BRIDGE_CHAT_URL",
#     "https://dlpo-level-bridge-chat.hf.space",
# )
# # チャットiframeに転送するパラメータ名一覧
# FORWARD_PARAMS = ["url", "industry", "campaign_name", "cvr", "ctr", "cpa"]
#
#
# def build_chat_html(params: dict) -> str:
#     """URLパラメータをチャットiframe srcに付与してHTML生成"""
#     chat_params = {k: v for k, v in params.items() if k in FORWARD_PARAMS and v}
#     if chat_params:
#         src = CHAT_SPACE_URL + "?" + urllib.parse.urlencode(chat_params)
#     else:
#         src = CHAT_SPACE_URL
#     return f"""
# <div style="
#     border: 1px solid #e0e0e0;
#     border-radius: 12px;
#     overflow: hidden;
#     height: 1000px;
#     background: #fafafa;
# ">
#   <iframe
#     src="{src}"
#     style="width:100%; height:100%; border:none;"
#     allow="clipboard-write"
#   ></iframe>
# </div>
# <p style="font-size:11px; color:#999; margin-top:4px; text-align:right;">
#   Powered by Level Bridge Chat
# </p>
# """


def create_login_ui(handle_login_fn):
    """
    Create Gradio login UI (チャットはコメントアウト済み).

    Args:
        handle_login_fn: Function to handle login (request, email, password) -> (form_update, status_update, token)
                         First argument must be gr.Request for source detection.

    Returns:
        Gradio Blocks UI for login
    """
    with gr.Blocks(title="Login") as ui:

        # --- 上段: ロゴ ---
        gr.HTML(f'<img src="{LOGO_SRC}" alt="dlpo" style="height:48px;display:block;margin:16px 0 8px 0;">')

        with gr.Column(visible=True) as login_form:
            email_input = gr.Textbox(label="Email")
            pass_input = gr.Textbox(label="Password", type="password")
            login_btn = gr.Button("Login", variant="primary")

        status_msg = gr.Markdown("")

        # Hidden textbox to store token and trigger cookie setting via JS
        token_storage = gr.Textbox(visible=False, elem_id="token_storage")

        # External login handler (from app.py) is bound here.
        # gr.Request は Gradio が第1引数に自動注入するため inputs に含めない。
        login_btn.click(
            handle_login_fn,
            inputs=[email_input, pass_input],
            outputs=[login_form, status_msg, token_storage],
        )

        # When token is set, use JavaScript to save cookie and redirect
        token_storage.change(
            None,
            inputs=[token_storage],
            js="""(token) => {
                if (!token || token === "") return;

                // Set cookie: max-age=3600 は Supabase JWT の標準有効期限に合わせた値。
                // セッション延長には Supabase refresh_token による更新が必要(中長期対応候補)。
                document.cookie = `sb_access_token=${token}; path=/; max-age=3600; SameSite=None; Secure;`;

                console.log("Cookie set, redirecting...");

                // Wait briefly then redirect
                setTimeout(() => {
                    window.location.href = '/app/';
                }, 200);
            }""",
        )

    return ui