File size: 5,045 Bytes
4253e50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# auth/login.py
from dash import html, dcc, Input, Output, State, callback, no_update
import dash_bootstrap_components as dbc # Import dbc
from database import engine, users
from sqlalchemy import select
from werkzeug.security import check_password_hash # PENTING: Import untuk verifikasi hash

login_layout = dbc.Container(
    fluid=True,
    className="d-flex flex-column justify-content-center align-items-center min-vh-100 p-0 m-0",
    style={'background': 'linear-gradient(135deg, #1e2a47, #2c3e50)'},
    children=[
        dcc.Location(id='login-url-redirect', refresh=True),
        dbc.Row(
            dbc.Col(
                dbc.Card(
                    dbc.CardBody([
                        html.H2("Disease Dashboard Login", className="text-center mb-4", style={'color': '#2c3e50'}),
                        html.Div(id='login-message', className="mb-3 text-center"),
                        dbc.Form([
                            dbc.Row([
                                dbc.Label("Username", width=4, className="text-md-end"),
                                dbc.Col(
                                    dbc.Input(id='login-username', type='text', placeholder="Masukkan username Anda"),
                                    width=8
                                )
                            ], className="mb-3 align-items-center"),

                            dbc.Row([
                                dbc.Label("Password", width=4, className="text-md-end"),
                                dbc.Col(
                                    dbc.Input(id='login-password', type='password', placeholder="Masukkan password Anda"),
                                    width=8
                                )
                            ], className="mb-3 align-items-center"),
                            dbc.Button("Login", id='login-button', color="primary", className="w-100 mt-4", n_clicks=0, size="lg"),
                        ]),
                        html.Div(
                            dcc.Link("Belum punya akun? Daftar di sini", href="/signup", className="d-block mt-3 text-center"),
                        )
                    ]),
                    className="shadow-lg",
                    style={'padding': '2rem'}
                ),
                width=12, sm=10, md=8, lg=5, xl=4 # Sesuaikan lebar card login
            ),
            justify="center",
            className="w-100"
        )
    ]
)


layout = login_layout
# Callback untuk handle login
@callback(
    Output('login-status', 'data', allow_duplicate=True), # Targetkan store global di app.py
    Output('login-url-redirect', 'pathname', allow_duplicate=True),
    Output('login-message', 'children', allow_duplicate=True),
    Input('login-button', 'n_clicks'),
    State('login-username', 'value'),
    State('login-password', 'value'),
    prevent_initial_call=True
)
def handle_login(n_clicks_login, username, password_input):
    if not username or not password_input:
        return no_update, no_update, dbc.Alert("Username dan password harus diisi.", color="warning", dismissable=True, duration=4000)

    username = username.strip()

    with engine.connect() as conn:
        # Ambil id_user, username, password (hash), dan nama_lengkap
        stmt = select(
            users.c.id_user,       # Pastikan ini adalah nama PK di tabel users
            users.c.username,
            users.c.password,
            users.c.nama_lengkap
        ).where(users.c.username == username)
        user_record = conn.execute(stmt).fetchone()

        print(f"--- LOGIN DEBUG: Mencoba login untuk user: {username} ---")
        if user_record:
            hashed_password_from_db = user_record.password
            # print(f"--- LOGIN DEBUG: Hashed Password dari DB: {str(hashed_password_from_db)[:20]}... ---")
            # print(f"--- LOGIN DEBUG: Password Input: '{password_input}' ---")
            
            if check_password_hash(str(hashed_password_from_db), str(password_input).strip()):
                session_data = {
                    'logged_in': True,
                    'username': user_record.username,
                    'nama_lengkap': user_record.nama_lengkap,
                    'id_user': user_record.id_user  # <--- TAMBAHKAN BARIS INI
                }
                print(f"--- LOGIN DEBUG: Login BERHASIL. Session data: {session_data} ---")
                return session_data, '/beranda', dbc.Alert(f"Login berhasil, selamat datang {user_record.nama_lengkap}!", color="success", duration=4000)
            else:
                print(f"--- LOGIN DEBUG: Password SALAH untuk user: {username} ---")
                return no_update, no_update, dbc.Alert("Username atau password salah.", color="danger", dismissable=True, duration=4000)
        else:
            print(f"--- LOGIN DEBUG: Username '{username}' TIDAK DITEMUKAN ---")
            return no_update, no_update, dbc.Alert("Username atau password salah.", color="danger", dismissable=True, duration=4000)
# Layout export
layout = login_layout