update yaTuhan semoga aku cepat lulus

This commit is contained in:
Jesselyn Mu
2025-02-08 16:11:48 +07:00
parent b7aed60245
commit c2de18d78b
31 changed files with 1180 additions and 9851 deletions

119
App.py
View File

@ -2,21 +2,21 @@ import os
import sys import sys
import streamlit as st import streamlit as st
from pages.karyawan_form import show_karyawan_form
from pages.pimpinan_form import show_pimpinan_form
from pages.prediction import show_prediction
from pages.report import show_report
from pages.exploration import show_exploration
from pages.karyawan_komen import show_karyawan_komen
from pages.pimpinan_exploration import show_pimpinan_exploration
st.set_page_config(page_title="TALENTRA", layout="wide", initial_sidebar_state="collapsed") st.set_page_config(page_title="TALENTRA", layout="wide", initial_sidebar_state="collapsed")
from pages.Form_Kepuasan import show_karyawan_form
from pages.Form_Penilaian import show_pimpinan_form
from pages.Prediksi import show_prediction
from pages.Laporan import show_report
from pages.Dashboard import show_exploration
from pages.Form_Keluhan import show_karyawan_komen
from pages.Dashboard_Pimpinan import show_pimpinan_exploration
sys.path.append(os.path.dirname(os.path.abspath(__file__))) sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import pages as pg import pages as pg
from login import show_login from pages.login import show_login
parent_dir = os.path.dirname(os.path.abspath(__file__)) parent_dir = os.path.dirname(os.path.abspath(__file__))
logo_path = os.path.join(parent_dir, "asset/logo.png") logo_path = os.path.join(parent_dir, "asset/logo.png")
@ -126,67 +126,72 @@ def navbar_home():
if current_page == "Login": if current_page == "Login":
return return
st.markdown( st.markdown("""
f"""
<style> <style>
.navbar {{ .navbar-container {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
background-color: #D0EEFF;
border-radius: 15px;
padding: 10px 20px; padding: 10px 20px;
font-family: 'Poppins', sans-serif; width: 100%;
margin-top: 0px; /* Hilangkan jarak atas */ }
background-color: #D0EEFF; /* Background navbar */ .navbar-left {
border-radius: 15px; /* Membulatkan sudut navbar */
}}
.navbar .logo {{
display: flex; display: flex;
align-items: center; align-items: center;
}} gap: 10px;
.navbar .logo img {{ }
.navbar-left img {
height: 40px; height: 40px;
margin-right: 10px; }
}} .navbar-center {
.navbar .nav-links {{ flex: 1;
display: flex; text-align: center;
align-items: center; /* Pusatkan teks secara vertikal */ font-family: 'Inter', sans-serif;
gap: 60px;
}}
.navbar .nav-links .welcome-text {{
color: #1D567E; color: #1D567E;
font-size: 16px; font-size: 18px;
font-weight: bold; font-weight: bold !important;
margin: 0; /* Hilangkan margin default */ }
}} .navbar-right {
.navbar .login-button {{ margin-left: auto;
background-color: #264CBE; }
color: white; .stButton > button {
border: none; background-color: #264CBE !important;
padding: 8px 15px; color: white !important;
border-radius: 5px; border-radius: 10px !important;
font-size: 16px; font-size: 10px !important; /* Membesarkan ukuran teks */\
font-weight: bold; font-weight: bold !important; /* Mengatur ketebalan teks */
cursor: pointer; font-type: 'Inter', sans-serif !important; /* Mengatur jenis font */
text-decoration: none; padding: 10px 20px !important; /* Mengatur padding tombol */
}} margin-top: 6px !important; /* Mengatur jarak atas */
.navbar .login-button:hover {{ width: 100px !important; /* Opsional: Mengatur lebar tombol */
background-color: white; height: 50px !important; /* Opsional: Mengatur tinggi tombol */
color: #264CBE; }
}}
</style> </style>
<div class="navbar"> """, unsafe_allow_html=True)
<div class="logo">
col1, col2 = st.columns([11, 1])
with col1:
st.markdown(f"""
<div class="navbar-container">
<div class="navbar-left">
<img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo"> <img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo">
</div> </div>
<div class="nav-links"> <div class="navbar-center">
<!-- Ganti teks "Home" dengan teks statis --> Selamat Datang di TALENTRA
<span class="welcome-text">Selamat Datang di TALENTRA</span>
</div> </div>
<a class="login-button" href="?page=Login">Login</a> <div class="navbar-right">
</div> """, unsafe_allow_html=True)
""",
unsafe_allow_html=True, with col2:
) if st.button("Login", key="login_button"):
st.session_state["page"] = "Login"
st.rerun()
st.markdown("</div></div>", unsafe_allow_html=True) # Menutup div navbar
options = { options = {
"show_menu": False, "show_menu": False,

Binary file not shown.

34
feature_explanation.json Normal file
View File

@ -0,0 +1,34 @@
{
"domisili": "Domisili",
"jenis_kelamin": "Jenis Kelamin",
"marriage_stat": "Status Pernikahan",
"dependant": "Jumlah Tanggungan",
"education": "Pendidikan",
"absent_90D": "Jumlah Absen dalam 90 Hari",
"avg_time_work": "Rata-rata Waktu Bekerja",
"departemen": "Departemen",
"position": "Posisi",
"income": "Pendapatan",
"total_komp": "Total Komplain/Keluhan",
"job_satisfaction": "Kepuasan Kerja",
"performance_rating": "Performa Kerja",
"age_years": "Usia",
"active_work": "Lama Bekerja (Hari)",
"active_work_months": "Lama Bekerja (Bulan)",
"income_3_months": "Pendapatan dalam 3 Bulan",
"income_6_months": "Pendapatan dalam 6 Bulan",
"total_income_work": "Total Pendapatan dalam Masa Bekerja",
"absence_ratio": "Rasio ketidakhadiran terhadap durasi kerja",
"income_dependant_ratio": "Rasio pendapatan terhadap jumlah tanggungan",
"work_efficiency": "Efisiensi kerja berdasarkan jam kerja rata-rata per hari",
"active_work_category": "Kategori lama bekerja",
"work_stability_score": "Stabilitas kerja berdasarkan durasi dan ketidakhadiran",
"married_dependant_ratio": "Rasio tanggungan",
"position_score": "Skor posisi berdasarkan level jabatan",
"job_income_position_score": "Rasio pendapatan terhadap skor posisi",
"education_score": "Skor pendidikan berdasarkan level pendidikan",
"education_income_ratio": "Rasio pendapatan terhadap skor pendidikan",
"weighted_satisfaction_performance": "Gabungan kepuasan kerja dan performa",
"resign_risk_indicator": "Indikator risiko resign berdasarkan usia dan lama bekerja",
"adjusted_work_time": "Jam kerja yang disesuaikan dengan ketidakhadiran"
}

File diff suppressed because it is too large Load Diff

View File

@ -6,24 +6,16 @@ import plotly.express as px
import seaborn as sns import seaborn as sns
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
# st.set_page_config(page_title="TALENTRA", layout="wide", initial_sidebar_state="collapsed")
# Fungsi untuk mendapatkan gambar sebagai base64 # Fungsi untuk mendapatkan gambar sebagai base64
def get_image_as_base64(image_path): def get_image_as_base64(image_path):
import base64 import base64
with open(image_path, "rb") as img_file: with open(image_path, "rb") as img_file:
return base64.b64encode(img_file.read()).decode("utf-8") return base64.b64encode(img_file.read()).decode("utf-8")
# Fungsi untuk menampilkan navbar
def navbar(): def navbar():
current_page = "exploration" # Sesuaikan dengan halaman saat ini logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png") # Sesuaikan path logo
# Cek status login
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
login_button_link = "?page=Login&logout=true" # Tambahkan parameter logout
else:
login_button_text = "Logout"
login_button_link = "?page=Login"
st.markdown( st.markdown(
f""" f"""
@ -31,69 +23,144 @@ def navbar():
.navbar {{ .navbar {{
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: center;
padding: 10px 20px; padding: 10px 20px;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
margin-top: 20px; /* Hilangkan jarak atas */ margin-top: 20px;
background-color: #D0EEFF; /* Background navbar */ background-color: #D0EEFF; /* Background navbar */
border-radius: 15px; /* Membulatkan sudut navbar */ border-radius: 15px; /* Membulatkan sudut navbar */
}} }}
.navbar .logo {{ .navbar .logo {{
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px;
}} }}
.navbar .logo img {{ .navbar .logo img {{
height: 40px; height: 40px;
margin-right: 10px;
}} }}
.navbar .nav-links {{ .navbar .text {{
display: flex; font-size: 18px;
gap: 60px;
}}
.navbar .nav-links a {{
color: black;
text-decoration: none;
font-size: 16px;
font-weight: bold; font-weight: bold;
}}
.navbar .nav-links a:hover {{
color: royalblue;
}}
.navbar .nav-links a.active {{
color: #264CBE; /* Warna saat aktif */
text-decoration: underline; /* Garis bawah saat aktif */
}}
.navbar .login-button {{
background-color: #264CBE;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
text-decoration: none;
}}
.navbar .login-button:hover {{
background-color: white;
color: #264CBE; color: #264CBE;
}} }}
</style> </style>
<div class="navbar"> <div class="navbar">
<div class="logo"> <div class="logo">
<img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo"> <img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo">
<div class="text">Halaman Dashboard</div>
</div> </div>
<div class="nav-links">
<a href="?page=Prediksi" class="{ 'active' if st.session_state.page == 'Prediksi' else '' }">Prediksi</a>
<a href="?page=exploration" class="{ 'active' if st.session_state.page == 'exploration' else '' }">Dashboard</a>
<a href="?page=report" class="{ 'active' if st.session_state.page == 'report' else '' }">Laporan</a>
</div>
<a class="login-button" href="{login_button_link}">{login_button_text}</a>
</div> </div>
""", """,
unsafe_allow_html=True, unsafe_allow_html=True,
) )
def menu():
# **Pastikan Streamlit Session State Sudah Punya `page`**
if "page" not in st.session_state:
st.session_state["page"] = "Home"
current_page = st.session_state["page"]
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# **Login Check**
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
else:
login_button_text = "Login"
# **Gunakan Streamlit Columns agar Navbar Sejajar (4 Kolom)**
col2, col3, col4, col5 = st.columns([1.5, 1.5, 1.5, 1]) # 4 Kolom tanpa col1 (logo)
# **Custom CSS untuk Tombol Navbar yang Spesifik**
st.markdown(
"""
<style>
/* Tombol di col2 (Prediksi) */
div[data-testid="column"]:nth-child(1) button {
background-color: #FF5733 !important; /* Warna oranye */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(1) button:hover {
background-color: #E64A19 !important; /* Warna oranye lebih gelap saat hover */
}
/* Tombol di col3 (Dashboard) */
div[data-testid="column"]:nth-child(2) button {
background-color: #33FF57 !important; /* Warna hijau */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(2) button:hover {
background-color: #2ECC71 !important; /* Warna hijau lebih gelap saat hover */
}
/* Tombol di col4 (Laporan) */
div[data-testid="column"]:nth-child(3) button {
background-color: #3357FF !important; /* Warna biru */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(3) button:hover {
background-color: #2C3E50 !important; /* Warna biru lebih gelap saat hover */
}
.stButton > button {
background-color: #264CBE;
color: white;
font-family: 'Inter', sans-serif;
font-size: 16px;
font-weight: 600;
border: none;
border-radius: 5px;
padding: 10px;
cursor: pointer;
margin-top: 20px;
width: 100%;
}
.stButton > button:hover {
background-color: #ffffff;
color: #264CBE;
}
</style>
""",
unsafe_allow_html=True
)
# Tombol navigasi dengan warna berbeda di col2, col3, col4
with col2:
if st.button("Prediksi", key="nav_prediksi"):
st.switch_page("pages/Prediksi.py") # Pindah ke halaman yang sudah ada
with col3:
if st.button("Dashboard", key="nav_dashboard"):
st.switch_page("pages/Dashboard.py") # Pindah ke halaman yang sesuai
with col4:
if st.button("Laporan", key="nav_laporan"):
st.switch_page("pages/Laporan.py") # Pindah ke halaman laporan
with col5:
if st.button(login_button_text, key="login_button"):
if 'logged_in' in st.session_state and st.session_state['logged_in']:
st.session_state['logged_in'] = False # Logout user
else:
st.switch_page("pages/login.py") # Pindah ke halaman login
def connect_to_db(): def connect_to_db():
try: try:
conn = mysql.connector.connect( conn = mysql.connector.connect(
@ -113,7 +180,7 @@ def get_all_employee_data(filter_employee_id=None, filter_join_date=None):
if conn: if conn:
try: try:
query = """ query = """
SELECT employee_id AS ID_Karyawan, domisili as Domisili, jenis_kelamin as Jenis_Kelamin, SELECT employee_id AS ID_Karyawan, Nama, domisili as Domisili, jenis_kelamin as Jenis_Kelamin,
join_date as Tanggal_Masuk, resign_date as Tanggal_Keluar, marriage_stat as Status_Pernikahan, join_date as Tanggal_Masuk, resign_date as Tanggal_Keluar, marriage_stat as Status_Pernikahan,
dependant as Jumlah_Tanggungan, education as Pendidikan, absent_90D as Absen_90Hari, dependant as Jumlah_Tanggungan, education as Pendidikan, absent_90D as Absen_90Hari,
avg_time_work as Rata_Rata_Jam_Kerja, departemen as Departemen, position as Posisi, avg_time_work as Rata_Rata_Jam_Kerja, departemen as Departemen, position as Posisi,
@ -169,13 +236,14 @@ def get_joined_employee_data(filter_employee_id=None):
def show_exploration(): def show_exploration():
navbar() navbar()
menu()
st.markdown(""" st.markdown("""
<style> <style>
.stDownloadButton > button { .stDownloadButton > button {
background-color: #264CBE; background-color: #264CBE;
color: white; color: white;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
border: none; border: none;
@ -197,7 +265,7 @@ def show_exploration():
background-color: #D0EEFF; background-color: #D0EEFF;
padding: 20px !important; padding: 20px !important;
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
border-radius: 10px; border-radius: 10px;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -212,10 +280,10 @@ def show_exploration():
st.markdown( st.markdown(
""" """
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<h3 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h4 style="text-align: center; font-family: 'Inter', sans-serif;">
Halaman Dashboard Lihat dan Temukan Informasi yang Anda Inginkan
</h3> </h4>
""", unsafe_allow_html=True """, unsafe_allow_html=True
) )
@ -251,8 +319,8 @@ def show_exploration():
st.markdown( st.markdown(
""" """
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<h4 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h4 style="text-align: center; font-family: 'Inter', sans-serif;">
Analisis Visual Distribusi Karyawan Analisis Visual Distribusi Karyawan
</h4> </h4>
""", unsafe_allow_html=True """, unsafe_allow_html=True
@ -264,7 +332,7 @@ def show_exploration():
with col1: with col1:
st.markdown( st.markdown(
""" """
<h6 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h6 style="text-align: center; font-family: 'Inter', sans-serif;">
Distribusi Karyawan Berdasarkan Status Pernikahan Distribusi Karyawan Berdasarkan Status Pernikahan
</h6> </h6>
""", unsafe_allow_html=True """, unsafe_allow_html=True
@ -280,7 +348,7 @@ def show_exploration():
with col2: with col2:
st.markdown( st.markdown(
""" """
<h6 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h6 style="text-align: center; font-family: 'Inter', sans-serif;">
Distribusi Karyawan Berdasarkan Pendidikan Distribusi Karyawan Berdasarkan Pendidikan
</h6> </h6>
""", unsafe_allow_html=True """, unsafe_allow_html=True
@ -298,7 +366,7 @@ def show_exploration():
with col1: with col1:
st.markdown( st.markdown(
""" """
<h6 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h6 style="text-align: center; font-family: 'Inter', sans-serif;">
Distribusi Karyawan Berdasarkan Domisili Distribusi Karyawan Berdasarkan Domisili
</h6> </h6>
""", unsafe_allow_html=True """, unsafe_allow_html=True
@ -314,7 +382,7 @@ def show_exploration():
with col2: with col2:
st.markdown( st.markdown(
""" """
<h6 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h6 style="text-align: center; font-family: 'Inter', sans-serif;">
Distribusi Karyawan Berdasarkan Departemen Distribusi Karyawan Berdasarkan Departemen
</h6> </h6>
""", unsafe_allow_html=True """, unsafe_allow_html=True

View File

@ -9,87 +9,148 @@ def get_image_as_base64(image_path):
with open(image_path, "rb") as img_file: with open(image_path, "rb") as img_file:
return base64.b64encode(img_file.read()).decode("utf-8") return base64.b64encode(img_file.read()).decode("utf-8")
# Fungsi untuk menampilkan navbar
def navbar(): def navbar():
current_page = st.session_state.get("page", "Home")
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png") logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# Cek status login
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
login_button_link = "?page=Login&logout=true" # Tambahkan parameter logout
else:
login_button_text = "Logout"
login_button_link = "?page=Login"
st.markdown( st.markdown(
f""" f"""
<style> <style>
.navbar {{ .navbar {{
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: center;
padding: 10px 20px; padding: 10px 20px;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
margin-top: 20px; /* Hilangkan jarak atas */ margin-top: 20px;
background-color: #D0EEFF; /* Background navbar */ background-color: #D0EEFF; /* Background navbar */
border-radius: 15px; /* Membulatkan sudut navbar */ border-radius: 15px; /* Membulatkan sudut navbar */
}} }}
.navbar .logo {{ .navbar .logo {{
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px;
}} }}
.navbar .logo img {{ .navbar .logo img {{
height: 40px; height: 40px;
margin-right: 10px;
}} }}
.navbar .nav-links {{ .navbar .text {{
display: flex; font-size: 18px;
gap: 60px;
}}
.navbar .nav-links a {{
color: black;
text-decoration: none;
font-size: 16px;
font-weight: bold; font-weight: bold;
}}
.navbar .nav-links a:hover {{
color: royalblue;
}}
.navbar .nav-links a.active {{
color: #264CBE; /* Warna saat aktif */
text-decoration: underline; /* Garis bawah saat aktif */
}}
.navbar .login-button {{
background-color: #264CBE;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
text-decoration: none;
}}
.navbar .login-button:hover {{
background-color: white;
color: #264CBE; color: #264CBE;
}} }}
</style> </style>
<div class="navbar"> <div class="navbar">
<div class="logo"> <div class="logo">
<img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo"> <img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo">
<div class="text">Halaman Dashboard</div>
</div> </div>
<div class="nav-links">
<a href="?page=pimpinan_form" class="{ 'active' if st.session_state.page == 'pimpinan_form' else '' }">Form Penilaian</a>
<a href="?page=pimpinan_exploration" class="{ 'active' if st.session_state.page == 'pimpinan_exploration' else '' }">Dashboard</a>
</div>
<a class="login-button" href="{login_button_link}">{login_button_text}</a>
</div> </div>
""", """,
unsafe_allow_html=True, unsafe_allow_html=True,
) )
def menu():
# **Pastikan Streamlit Session State Sudah Punya `page`**
if "page" not in st.session_state:
st.session_state["page"] = "Home"
current_page = st.session_state["page"]
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# **Login Check**
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
else:
login_button_text = "Login"
# **Gunakan Streamlit Columns agar Navbar Sejajar (4 Kolom)**
col2, col3, col4 = st.columns([1.5, 1.5, 1]) # 4 Kolom tanpa col1 (logo)
# **Custom CSS untuk Tombol Navbar yang Spesifik**
st.markdown(
"""
<style>
/* Tombol di col2 (Prediksi) */
div[data-testid="column"]:nth-child(1) button {
background-color: #FF5733 !important; /* Warna oranye */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(1) button:hover {
background-color: #E64A19 !important; /* Warna oranye lebih gelap saat hover */
}
/* Tombol di col3 (Dashboard) */
div[data-testid="column"]:nth-child(2) button {
background-color: #33FF57 !important; /* Warna hijau */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(2) button:hover {
background-color: #2ECC71 !important; /* Warna hijau lebih gelap saat hover */
}
/* Tombol di col4 (Laporan) */
div[data-testid="column"]:nth-child(3) button {
background-color: #3357FF !important; /* Warna biru */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(3) button:hover {
background-color: #2C3E50 !important; /* Warna biru lebih gelap saat hover */
}
.stButton > button {
background-color: #264CBE;
color: white;
font-family: 'Inter', sans-serif;
font-size: 16px;
font-weight: 600;
border: none;
border-radius: 5px;
padding: 10px;
cursor: pointer;
margin-top: 20px;
width: 100%;
}
.stButton > button:hover {
background-color: #ffffff;
color: #264CBE;
}
</style>
""",
unsafe_allow_html=True
)
# Tombol navigasi dengan warna berbeda di col2, col3, col4
with col2:
if st.button("Form Penilaian", key="nav_prediksi"):
st.switch_page("pages/Form_Penilaian.py") # Pindah ke halaman yang sudah ada
with col3:
if st.button("Dashboard", key="nav_dashboard"):
st.switch_page("pages/Dashboard_Pimpinan.py") # Pindah ke halaman yang sesuai
with col4:
if st.button(login_button_text, key="login_button"):
if 'logged_in' in st.session_state and st.session_state['logged_in']:
st.session_state['logged_in'] = False # Logout user
else:
st.switch_page("pages/login.py") # Pindah ke halaman login
def connect_to_db(): def connect_to_db():
try: try:
conn = mysql.connector.connect( conn = mysql.connector.connect(
@ -147,13 +208,14 @@ def get_history_prediction():
def show_pimpinan_exploration(): def show_pimpinan_exploration():
navbar() navbar()
menu()
st.markdown(""" st.markdown("""
<style> <style>
.stDownloadButton > button { .stDownloadButton > button {
background-color: #264CBE; background-color: #264CBE;
color: white; color: white;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
border: none; border: none;
@ -175,7 +237,7 @@ def show_pimpinan_exploration():
background-color: #D0EEFF; background-color: #D0EEFF;
padding: 20px !important; padding: 20px !important;
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
border-radius: 10px; border-radius: 10px;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -190,10 +252,10 @@ def show_pimpinan_exploration():
st.markdown( st.markdown(
""" """
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<h3 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h4 style="text-align: center; font-family: 'Inter', sans-serif;">
Dashboard Silahkan Pilih Data Karyawan yang Ingin Dilihat
</h3> </h4>
""", unsafe_allow_html=True """, unsafe_allow_html=True
) )
@ -203,6 +265,8 @@ def show_pimpinan_exploration():
["Semua Data Karyawan", "Histori Prediksi"] ["Semua Data Karyawan", "Histori Prediksi"]
) )
if menu_option == "Semua Data Karyawan":
col1, col2 = st.columns(2) col1, col2 = st.columns(2)
with col1: with col1:
filter_employee_id = st.text_input("Filter berdasarkan Karyawan_ID", placeholder="Contoh: EM12345") filter_employee_id = st.text_input("Filter berdasarkan Karyawan_ID", placeholder="Contoh: EM12345")
@ -214,7 +278,6 @@ def show_pimpinan_exploration():
"Corporate Strategy & Communications"] "Corporate Strategy & Communications"]
) )
if menu_option == "Semua Data Karyawan":
df = get_all_data_with_comments() df = get_all_data_with_comments()
if not df.empty: if not df.empty:
@ -242,11 +305,20 @@ def show_pimpinan_exploration():
elif menu_option == "Histori Prediksi": elif menu_option == "Histori Prediksi":
df = get_history_prediction() df = get_history_prediction()
col1, col2 = st.columns(2)
with col1:
filter_employee_id = st.text_input("Filter berdasarkan Karyawan_ID", placeholder="Contoh: EM12345")
with col2:
filter_retensi = st.selectbox("Pilih Kategori Retensi/Tidak", ["Semua", "Retensi", "Tidak Retensi"])
if not df.empty: if not df.empty:
# Terapkan filter # Terapkan filter
if filter_employee_id: if filter_employee_id:
df = df[df['Karyawan_ID'].str.contains(filter_employee_id, na=False)] df = df[df['Karyawan_ID'].str.contains(filter_employee_id, na=False)]
if filter_retensi != "Semua":
df = df[df["Hasil_Prediksi_Retensi"] == filter_retensi]
# Tampilkan data # Tampilkan data
st.dataframe(df) st.dataframe(df)

View File

@ -68,97 +68,159 @@ def update_total_comments(employee_id):
finally: finally:
conn.close() conn.close()
# Fungsi untuk menampilkan navbar
def navbar(): def navbar():
current_page = st.session_state.get("page", "Home")
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png") logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# Cek status login
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
login_button_link = "?page=Login&logout=true" # Tambahkan parameter logout
else:
login_button_text = "Logout"
login_button_link = "?page=Login"
st.markdown( st.markdown(
f""" f"""
<style> <style>
.navbar {{ .navbar {{
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: center;
padding: 10px 20px; padding: 10px 20px;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
margin-top: 20px; /* Hilangkan jarak atas */ margin-top: 20px;
background-color: #D0EEFF; /* Background navbar */ background-color: #D0EEFF; /* Background navbar */
border-radius: 15px; /* Membulatkan sudut navbar */ border-radius: 15px; /* Membulatkan sudut navbar */
}} }}
.navbar .logo {{ .navbar .logo {{
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px;
}} }}
.navbar .logo img {{ .navbar .logo img {{
height: 40px; height: 40px;
margin-right: 10px;
}} }}
.navbar .nav-links {{ .navbar .text {{
display: flex; font-size: 18px;
gap: 60px;
}}
.navbar .nav-links a {{
color: black;
text-decoration: none;
font-size: 16px;
font-weight: bold; font-weight: bold;
}}
.navbar .nav-links a:hover {{
color: royalblue;
}}
.navbar .nav-links a.active {{
color: #264CBE; /* Warna saat aktif */
text-decoration: underline; /* Garis bawah saat aktif */
}}
.navbar .login-button {{
background-color: #264CBE;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
text-decoration: none;
}}
.navbar .login-button:hover {{
background-color: white;
color: #264CBE; color: #264CBE;
}} }}
</style> </style>
<div class="navbar"> <div class="navbar">
<div class="logo"> <div class="logo">
<img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo"> <img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo">
<div class="text">Form Komplain</div>
</div> </div>
<div class="nav-links">
<a href="?page=karyawan_form" class="{ 'active' if st.session_state.page == 'karyawan_form' else '' }">Form Kepuasan Kerja</a>
<a href="?page=karyawan_komen" class="{ 'active' if st.session_state.page == 'karyawan_komen' else '' }">Form Komplain</a>
</div>
<a class="login-button" href="{login_button_link}">{login_button_text}</a>
</div> </div>
""", """,
unsafe_allow_html=True, unsafe_allow_html=True,
) )
def menu():
# **Pastikan Streamlit Session State Sudah Punya `page`**
if "page" not in st.session_state:
st.session_state["page"] = "Home"
current_page = st.session_state["page"]
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# **Login Check**
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
else:
login_button_text = "Login"
# **Gunakan Streamlit Columns agar Navbar Sejajar (4 Kolom)**
col2, col3, col4 = st.columns([1.5, 1.5, 1]) # 4 Kolom tanpa col1 (logo)
# **Custom CSS untuk Tombol Navbar yang Spesifik**
st.markdown(
"""
<style>
/* Tombol di col2 (Prediksi) */
div[data-testid="column"]:nth-child(1) button {
background-color: #FF5733 !important; /* Warna oranye */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(1) button:hover {
background-color: #E64A19 !important; /* Warna oranye lebih gelap saat hover */
}
/* Tombol di col3 (Dashboard) */
div[data-testid="column"]:nth-child(2) button {
background-color: #33FF57 !important; /* Warna hijau */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(2) button:hover {
background-color: #2ECC71 !important; /* Warna hijau lebih gelap saat hover */
}
/* Tombol di col4 (Laporan) */
div[data-testid="column"]:nth-child(3) button {
background-color: #3357FF !important; /* Warna biru */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(3) button:hover {
background-color: #2C3E50 !important; /* Warna biru lebih gelap saat hover */
}
.stButton > button {
background-color: #264CBE;
color: white;
font-family: 'Inter', sans-serif;
font-size: 16px;
font-weight: 600;
border: none;
border-radius: 5px;
padding: 10px;
cursor: pointer;
margin-top: 20px;
width: 100%;
}
.stButton > button:hover {
background-color: #ffffff;
color: #264CBE;
}
</style>
""",
unsafe_allow_html=True
)
# Tombol navigasi dengan warna berbeda di col2, col3, col4
with col2:
if st.button("Form Kepuasan Kerja", key="nav_prediksi"):
st.switch_page("pages/Form_Kepuasan.py") # Pindah ke halaman yang sudah ada
with col3:
if st.button("Form Keluhan", key="nav_dashboard"):
st.switch_page("pages/Form_Keluhan.py") # Pindah ke halaman yang sesuai
with col4:
if st.button(login_button_text, key="login_button"):
if 'logged_in' in st.session_state and st.session_state['logged_in']:
st.session_state['logged_in'] = False # Logout user
else:
st.switch_page("pages/login.py") # Pindah ke halaman login
def show_karyawan_komen(): def show_karyawan_komen():
# Navbar # Navbar
navbar() navbar()
menu()
st.markdown(""" st.markdown("""
<style> <style>
.stButton > button { .stButton > button {
background-color: #264CBE; background-color: #264CBE;
color: white; color: white;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
border: none; border: none;
@ -180,7 +242,7 @@ def show_karyawan_komen():
background-color: #D0EEFF; background-color: #D0EEFF;
padding: 20px !important; padding: 20px !important;
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
border-radius: 10px; border-radius: 10px;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -195,9 +257,9 @@ def show_karyawan_komen():
st.markdown( st.markdown(
""" """
<h3 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h4 style="text-align: center; font-family: 'Inter', sans-serif;">
Form Komplain Silahkan Berikan Keluhan Anda
</h3> </h4>
""", unsafe_allow_html=True """, unsafe_allow_html=True
) )

View File

@ -9,87 +9,148 @@ def get_image_as_base64(image_path):
with open(image_path, "rb") as img_file: with open(image_path, "rb") as img_file:
return base64.b64encode(img_file.read()).decode("utf-8") return base64.b64encode(img_file.read()).decode("utf-8")
# Fungsi untuk menampilkan navbar
def navbar(): def navbar():
current_page = st.session_state.get("page", "Home")
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png") logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# Cek status login
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
login_button_link = "?page=Login&logout=true" # Tambahkan parameter logout
else:
login_button_text = "Logout"
login_button_link = "?page=Login"
st.markdown( st.markdown(
f""" f"""
<style> <style>
.navbar {{ .navbar {{
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: center;
padding: 10px 20px; padding: 10px 20px;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
margin-top: 20px; /* Hilangkan jarak atas */ margin-top: 20px;
background-color: #D0EEFF; /* Background navbar */ background-color: #D0EEFF; /* Background navbar */
border-radius: 15px; /* Membulatkan sudut navbar */ border-radius: 15px; /* Membulatkan sudut navbar */
}} }}
.navbar .logo {{ .navbar .logo {{
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px;
}} }}
.navbar .logo img {{ .navbar .logo img {{
height: 40px; height: 40px;
margin-right: 10px;
}} }}
.navbar .nav-links {{ .navbar .text {{
display: flex; font-size: 18px;
gap: 60px;
}}
.navbar .nav-links a {{
color: black;
text-decoration: none;
font-size: 16px;
font-weight: bold; font-weight: bold;
}}
.navbar .nav-links a:hover {{
color: royalblue;
}}
.navbar .nav-links a.active {{
color: #264CBE; /* Warna saat aktif */
text-decoration: underline; /* Garis bawah saat aktif */
}}
.navbar .login-button {{
background-color: #264CBE;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
text-decoration: none;
}}
.navbar .login-button:hover {{
background-color: white;
color: #264CBE; color: #264CBE;
}} }}
</style> </style>
<div class="navbar"> <div class="navbar">
<div class="logo"> <div class="logo">
<img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo"> <img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo">
<div class="text">Form Kepuasan Kerja</div>
</div> </div>
<div class="nav-links">
<a href="?page=karyawan_form" class="{ 'active' if st.session_state.page == 'karyawan_form' else '' }">Form Kepuasan Kerja</a>
<a href="?page=karyawan_komen" class="{ 'active' if st.session_state.page == 'karyawan_komen' else '' }">Form Komplain</a>
</div>
<a class="login-button" href="{login_button_link}">{login_button_text}</a>
</div> </div>
""", """,
unsafe_allow_html=True, unsafe_allow_html=True,
) )
def menu():
# **Pastikan Streamlit Session State Sudah Punya `page`**
if "page" not in st.session_state:
st.session_state["page"] = "Home"
current_page = st.session_state["page"]
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# **Login Check**
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
else:
login_button_text = "Login"
# **Gunakan Streamlit Columns agar Navbar Sejajar (4 Kolom)**
col2, col3, col4 = st.columns([1.5, 1.5, 1]) # 4 Kolom tanpa col1 (logo)
# **Custom CSS untuk Tombol Navbar yang Spesifik**
st.markdown(
"""
<style>
/* Tombol di col2 (Prediksi) */
div[data-testid="column"]:nth-child(1) button {
background-color: #FF5733 !important; /* Warna oranye */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(1) button:hover {
background-color: #E64A19 !important; /* Warna oranye lebih gelap saat hover */
}
/* Tombol di col3 (Dashboard) */
div[data-testid="column"]:nth-child(2) button {
background-color: #33FF57 !important; /* Warna hijau */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(2) button:hover {
background-color: #2ECC71 !important; /* Warna hijau lebih gelap saat hover */
}
/* Tombol di col4 (Laporan) */
div[data-testid="column"]:nth-child(3) button {
background-color: #3357FF !important; /* Warna biru */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(3) button:hover {
background-color: #2C3E50 !important; /* Warna biru lebih gelap saat hover */
}
.stButton > button {
background-color: #264CBE;
color: white;
font-family: 'Inter', sans-serif;
font-size: 16px;
font-weight: 600;
border: none;
border-radius: 5px;
padding: 10px;
cursor: pointer;
margin-top: 20px;
width: 100%;
}
.stButton > button:hover {
background-color: #ffffff;
color: #264CBE;
}
</style>
""",
unsafe_allow_html=True
)
# Tombol navigasi dengan warna berbeda di col2, col3, col4
with col2:
if st.button("Form Kepuasan Kerja", key="nav_prediksi"):
st.switch_page("pages/Form_Kepuasan.py") # Pindah ke halaman yang sudah ada
with col3:
if st.button("Form Keluhan", key="nav_dashboard"):
st.switch_page("pages/Form_Keluhan.py") # Pindah ke halaman yang sesuai
with col4:
if st.button(login_button_text, key="login_button"):
if 'logged_in' in st.session_state and st.session_state['logged_in']:
st.session_state['logged_in'] = False # Logout user
else:
st.switch_page("pages/login.py") # Pindah ke halaman login
def connect_to_db(): def connect_to_db():
try: try:
conn = mysql.connector.connect( conn = mysql.connector.connect(
@ -158,13 +219,14 @@ def save_job_satisfaction(employee_id, responses):
def show_karyawan_form(): def show_karyawan_form():
navbar() navbar()
menu()
st.markdown(""" st.markdown("""
<style> <style>
.stButton > button { .stButton > button {
background-color: #264CBE; background-color: #264CBE;
color: white; color: white;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
border: none; border: none;
@ -186,7 +248,7 @@ def show_karyawan_form():
background-color: #D0EEFF; background-color: #D0EEFF;
padding: 20px !important; padding: 20px !important;
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
border-radius: 10px; border-radius: 10px;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -201,9 +263,9 @@ def show_karyawan_form():
st.markdown( st.markdown(
""" """
<h3 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h4 style="text-align: center; font-family: 'Inter', sans-serif;">
Form Kepuasan Kerja Karyawan Silahkan Isi Form Kepuasan Kerja Anda
</h3> </h4>
""", unsafe_allow_html=True """, unsafe_allow_html=True
) )
@ -239,7 +301,7 @@ def show_karyawan_form():
st.markdown( st.markdown(
""" """
<h3 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h3 style="text-align: center; font-family: 'Inter', sans-serif;">
Isi Form Kepuasan Kerja Isi Form Kepuasan Kerja
</h3> </h3>
""", unsafe_allow_html=True """, unsafe_allow_html=True

View File

@ -3,93 +3,156 @@ import os
import mysql.connector import mysql.connector
import math import math
# st.set_page_config(page_title="TALENTRA", layout="wide", initial_sidebar_state="collapsed")
# Fungsi untuk mendapatkan gambar sebagai base64 # Fungsi untuk mendapatkan gambar sebagai base64
def get_image_as_base64(image_path): def get_image_as_base64(image_path):
import base64 import base64
with open(image_path, "rb") as img_file: with open(image_path, "rb") as img_file:
return base64.b64encode(img_file.read()).decode("utf-8") return base64.b64encode(img_file.read()).decode("utf-8")
# Fungsi untuk menampilkan navbar
def navbar(): def navbar():
current_page = st.session_state.get("page", "Home")
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png") logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# Cek status login
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
login_button_link = "?page=Login&logout=true" # Tambahkan parameter logout
else:
login_button_text = "Logout"
login_button_link = "?page=Login"
st.markdown( st.markdown(
f""" f"""
<style> <style>
.navbar {{ .navbar {{
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: center;
padding: 10px 20px; padding: 10px 20px;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
margin-top: 20px; /* Hilangkan jarak atas */ margin-top: 20px;
background-color: #D0EEFF; /* Background navbar */ background-color: #D0EEFF; /* Background navbar */
border-radius: 15px; /* Membulatkan sudut navbar */ border-radius: 15px; /* Membulatkan sudut navbar */
}} }}
.navbar .logo {{ .navbar .logo {{
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px;
}} }}
.navbar .logo img {{ .navbar .logo img {{
height: 40px; height: 40px;
margin-right: 10px;
}} }}
.navbar .nav-links {{ .navbar .text {{
display: flex; font-size: 18px;
gap: 60px;
}}
.navbar .nav-links a {{
color: black;
text-decoration: none;
font-size: 16px;
font-weight: bold; font-weight: bold;
}}
.navbar .nav-links a:hover {{
color: royalblue;
}}
.navbar .nav-links a.active {{
color: #264CBE; /* Warna saat aktif */
text-decoration: underline; /* Garis bawah saat aktif */
}}
.navbar .login-button {{
background-color: #264CBE;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
text-decoration: none;
}}
.navbar .login-button:hover {{
background-color: white;
color: #264CBE; color: #264CBE;
}} }}
</style> </style>
<div class="navbar"> <div class="navbar">
<div class="logo"> <div class="logo">
<img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo"> <img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo">
<div class="text">Form Penilaian Kinerja Karyawan</div>
</div> </div>
<div class="nav-links">
<a href="?page=pimpinan_form" class="{ 'active' if st.session_state.page == 'pimpinan_form' else '' }">Form Penilaian</a>
<a href="?page=pimpinan_exploration" class="{ 'active' if st.session_state.page == 'pimpinan_exploration' else '' }">Dashboard</a>
</div>
<a class="login-button" href="{login_button_link}">{login_button_text}</a>
</div> </div>
""", """,
unsafe_allow_html=True, unsafe_allow_html=True,
) )
def menu():
# **Pastikan Streamlit Session State Sudah Punya `page`**
if "page" not in st.session_state:
st.session_state["page"] = "Home"
current_page = st.session_state["page"]
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# **Login Check**
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
else:
login_button_text = "Login"
# **Gunakan Streamlit Columns agar Navbar Sejajar (4 Kolom)**
col2, col3, col4 = st.columns([1.5, 1.5, 1]) # 4 Kolom tanpa col1 (logo)
# **Custom CSS untuk Tombol Navbar yang Spesifik**
st.markdown(
"""
<style>
/* Tombol di col2 (Prediksi) */
div[data-testid="column"]:nth-child(1) button {
background-color: #FF5733 !important; /* Warna oranye */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(1) button:hover {
background-color: #E64A19 !important; /* Warna oranye lebih gelap saat hover */
}
/* Tombol di col3 (Dashboard) */
div[data-testid="column"]:nth-child(2) button {
background-color: #33FF57 !important; /* Warna hijau */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(2) button:hover {
background-color: #2ECC71 !important; /* Warna hijau lebih gelap saat hover */
}
/* Tombol di col4 (Laporan) */
div[data-testid="column"]:nth-child(3) button {
background-color: #3357FF !important; /* Warna biru */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(3) button:hover {
background-color: #2C3E50 !important; /* Warna biru lebih gelap saat hover */
}
.stButton > button {
background-color: #264CBE;
color: white;
font-family: 'Inter', sans-serif;
font-size: 16px;
font-weight: 600;
border: none;
border-radius: 5px;
padding: 10px;
cursor: pointer;
margin-top: 20px;
width: 100%;
}
.stButton > button:hover {
background-color: #ffffff;
color: #264CBE;
}
</style>
""",
unsafe_allow_html=True
)
# Tombol navigasi dengan warna berbeda di col2, col3, col4
with col2:
if st.button("Form Penilaian", key="nav_prediksi"):
st.switch_page("pages/Form_Penilaian.py") # Pindah ke halaman yang sudah ada
with col3:
if st.button("Dashboard", key="nav_dashboard"):
st.switch_page("pages/Dashboard_Pimpinan.py") # Pindah ke halaman yang sesuai
with col4:
if st.button(login_button_text, key="login_button"):
if 'logged_in' in st.session_state and st.session_state['logged_in']:
st.session_state['logged_in'] = False # Logout user
else:
st.switch_page("pages/login.py") # Pindah ke halaman login
# Fungsi untuk koneksi ke database # Fungsi untuk koneksi ke database
def connect_to_db(): def connect_to_db():
try: try:
@ -105,6 +168,22 @@ def connect_to_db():
st.error(f"Koneksi ke database gagal: {e}") st.error(f"Koneksi ke database gagal: {e}")
return None return None
def get_employee_id_by_name(employee_name):
conn = connect_to_db()
if conn:
try:
cursor = conn.cursor(dictionary=True)
query = "SELECT employee_id FROM data_employee_db WHERE Nama = %s LIMIT 1"
cursor.execute(query, (employee_name,))
result = cursor.fetchone()
conn.close()
return result["employee_id"] if result else None
except mysql.connector.Error as e:
st.error(f"Terjadi kesalahan saat mencari Employee ID: {e}")
conn.close()
return None
# Fungsi untuk mencocokkan employee_id di database # Fungsi untuk mencocokkan employee_id di database
def check_employee_in_db(employee_id): def check_employee_in_db(employee_id):
conn = connect_to_db() conn = connect_to_db()
@ -161,13 +240,14 @@ def save_employee_ratings(employee_id, responses):
# Fungsi utama untuk form kinerja rating karyawan # Fungsi utama untuk form kinerja rating karyawan
def show_pimpinan_form(): def show_pimpinan_form():
navbar() navbar()
menu()
st.markdown(""" st.markdown("""
<style> <style>
.stButton > button { .stButton > button {
background-color: #264CBE; background-color: #264CBE;
color: white; color: white;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
border: none; border: none;
@ -189,7 +269,7 @@ def show_pimpinan_form():
background-color: #D0EEFF; background-color: #D0EEFF;
padding: 20px !important; padding: 20px !important;
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
border-radius: 10px; border-radius: 10px;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -204,52 +284,44 @@ def show_pimpinan_form():
st.markdown( st.markdown(
""" """
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<h3 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h4 style="text-align: center; font-family: 'Inter', sans-serif;">
Form Penilaian Kinerja Rating Karyawan Silahkan Isi Form Penilaian Karyawan Anda
</h3> </h4>
""", unsafe_allow_html=True """, unsafe_allow_html=True
) )
# Inisialisasi session state # Inisialisasi session state
if "employee_id" not in st.session_state: if "employee_name" not in st.session_state:
st.session_state.employee_id = None # Awalnya kosong st.session_state.employee_name = None
if "submit_success" not in st.session_state: if "submit_success" not in st.session_state:
st.session_state.submit_success = False # Awalnya False st.session_state.submit_success = False
# Input Employee ID # Input Nama Karyawan
if not st.session_state.employee_id: # Jika belum ada ID yang tersimpan if not st.session_state.employee_name:
employee_id = st.text_input("Masukkan ID Karyawan yang ingin diisi", placeholder="Contoh: 12345") employee_name = st.text_input("Masukkan Nama Lengkap Karyawan yang ingin diberikan penilaian", placeholder="Contoh: Budi Santoso")
# Tombol untuk mencocokkan employee_id
if st.button("Isi Form"): if st.button("Isi Form"):
if not employee_name:
st.error("Harap masukkan Nama Lengkap Karyawan terlebih dahulu.")
return
# Cari ID berdasarkan nama
employee_id = get_employee_id_by_name(employee_name)
if not employee_id: if not employee_id:
st.error("Harap masukkan Employee ID terlebih dahulu.") st.error("Nama Karyawan tidak ditemukan di database.")
return return
# Cek apakah employee_id ada di database # Simpan Nama dan ID di session_state
employee_data = check_employee_in_db(employee_id) st.session_state.employee_name = employee_name
if not employee_data:
st.error("Employee ID tidak ditemukan di database.")
return
# Jika ditemukan, simpan Employee ID di session_state
st.session_state.employee_id = employee_id st.session_state.employee_id = employee_id
# Jika Employee ID sudah disimpan # Jika Nama sudah ditemukan
if st.session_state.employee_id: if st.session_state.employee_name:
st.success(f"Karyawan_ID ditemukan! Anda sedang mengisi untuk ID: {st.session_state.employee_id}") st.success(f"Karyawan ditemukan! Anda sedang mengisi untuk {st.session_state.employee_name} (ID: {st.session_state.employee_id})")
# Pertanyaan penilaian (2 kolom)
st.markdown(
"""
<h5 style="text-align: center; font-family: 'Poppins', sans-serif;">
Isi Form Kinerja Karyawan
</h5>
""", unsafe_allow_html=True
)
# Pertanyaan penilaian
questions = [ questions = [
"Bagaimana tingkat keandalan karyawan dalam menyelesaikan tugas tepat waktu?", "Bagaimana tingkat keandalan karyawan dalam menyelesaikan tugas tepat waktu?",
"Seberapa efektif karyawan ini dalam bekerja secara mandiri atau dalam tim?", "Seberapa efektif karyawan ini dalam bekerja secara mandiri atau dalam tim?",
@ -263,7 +335,7 @@ def show_pimpinan_form():
options = {"Sangat Buruk": 1, "Cukup Baik": 2, "Baik": 3, "Sangat Baik": 4} options = {"Sangat Buruk": 1, "Cukup Baik": 2, "Baik": 3, "Sangat Baik": 4}
# Buat dua kolom # Tampilkan pertanyaan dalam dua kolom
col1, col2 = st.columns(2) col1, col2 = st.columns(2)
responses = [] responses = []
@ -277,18 +349,17 @@ def show_pimpinan_form():
response = st.selectbox(question, list(options.keys()), key=f"q{idx}") response = st.selectbox(question, list(options.keys()), key=f"q{idx}")
responses.append(options[response]) responses.append(options[response])
# Tombol Submit # Tombol Submit
if st.button("Submit") and not st.session_state.submit_success: if st.button("Submit") and not st.session_state.submit_success:
final_score = save_employee_ratings(st.session_state.employee_id, responses) final_score = save_employee_ratings(st.session_state.employee_id, responses)
if final_score is not None: if final_score is not None:
st.session_state.submit_success = True # Tandai data berhasil disimpan st.session_state.submit_success = True
st.success(f"Data berhasil disimpan! Skor Akhir: {final_score} untuk Karyawan_ID: {st.session_state.employee_id}") st.success(f"Data berhasil disimpan! Skor Akhir: {final_score} untuk {st.session_state.employee_name}")
# Jika data berhasil disimpan, tampilkan tombol kembali # Jika data berhasil disimpan, tampilkan tombol kembali
if st.session_state.submit_success: if st.session_state.submit_success:
if st.button("Kembali ke Form Awal"): if st.button("Kembali ke Form Awal"):
# Reset Employee ID dan status submit st.session_state.employee_name = None
st.session_state.employee_id = None st.session_state.employee_id = None
st.session_state.submit_success = False st.session_state.submit_success = False
st.rerun() st.rerun()

View File

@ -4,6 +4,11 @@ import mysql.connector
import pandas as pd import pandas as pd
import json import json
with open("feature_explanation.json", "r") as f:
feature_dict = json.load(f)
# st.set_page_config(page_title="TALENTRA", layout="wide", initial_sidebar_state="collapsed")
# Fungsi untuk mendapatkan gambar sebagai base64 # Fungsi untuk mendapatkan gambar sebagai base64
def get_image_as_base64(image_path): def get_image_as_base64(image_path):
import base64 import base64
@ -86,98 +91,163 @@ def get_shap_top_features():
finally: finally:
conn.close() conn.close()
# Fungsi untuk menampilkan navbar
def navbar(): def navbar():
current_page = st.session_state.get("page", "Home")
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png") logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# Cek status login
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
login_button_link = "?page=Login&logout=true" # Tambahkan parameter logout
else:
login_button_text = "Logout"
login_button_link = "?page=Login"
st.markdown( st.markdown(
f""" f"""
<style> <style>
.navbar {{ .navbar {{
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: center;
padding: 10px 20px; padding: 10px 20px;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
margin-top: 20px; /* Hilangkan jarak atas */ margin-top: 20px;
background-color: #D0EEFF; /* Background navbar */ background-color: #D0EEFF; /* Background navbar */
border-radius: 15px; /* Membulatkan sudut navbar */ border-radius: 15px; /* Membulatkan sudut navbar */
}} }}
.navbar .logo {{ .navbar .logo {{
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px;
}} }}
.navbar .logo img {{ .navbar .logo img {{
height: 40px; height: 40px;
margin-right: 10px;
}} }}
.navbar .nav-links {{ .navbar .text {{
display: flex; font-size: 18px;
gap: 60px;
}}
.navbar .nav-links a {{
color: black;
text-decoration: none;
font-size: 16px;
font-weight: bold; font-weight: bold;
}}
.navbar .nav-links a:hover {{
color: royalblue;
}}
.navbar .nav-links a.active {{
color: #264CBE; /* Warna saat aktif */
text-decoration: underline; /* Garis bawah saat aktif */
}}
.navbar .login-button {{
background-color: #264CBE;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
text-decoration: none;
}}
.navbar .login-button:hover {{
background-color: white;
color: #264CBE; color: #264CBE;
}} }}
</style> </style>
<div class="navbar"> <div class="navbar">
<div class="logo"> <div class="logo">
<img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo"> <img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo">
<div class="text">Halaman Laporan</div>
</div> </div>
<div class="nav-links">
<a href="?page=Prediksi" class="{ 'active' if st.session_state.page == 'Prediksi' else '' }">Prediksi</a>
<a href="?page=exploration" class="{ 'active' if st.session_state.page == 'exploration' else '' }">Dashboard</a>
<a href="?page=report" class="{ 'active' if st.session_state.page == 'report' else '' }">Laporan</a>
</div>
<a class="login-button" href="{login_button_link}">{login_button_text}</a>
</div> </div>
""", """,
unsafe_allow_html=True, unsafe_allow_html=True,
) )
def menu():
# **Pastikan Streamlit Session State Sudah Punya `page`**
if "page" not in st.session_state:
st.session_state["page"] = "Home"
current_page = st.session_state["page"]
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# **Login Check**
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
else:
login_button_text = "Login"
# **Gunakan Streamlit Columns agar Navbar Sejajar (4 Kolom)**
col2, col3, col4, col5 = st.columns([1.5, 1.5, 1.5, 1]) # 4 Kolom tanpa col1 (logo)
# **Custom CSS untuk Tombol Navbar yang Spesifik**
st.markdown(
"""
<style>
/* Tombol di col2 (Prediksi) */
div[data-testid="column"]:nth-child(1) button {
background-color: #FF5733 !important; /* Warna oranye */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(1) button:hover {
background-color: #E64A19 !important; /* Warna oranye lebih gelap saat hover */
}
/* Tombol di col3 (Dashboard) */
div[data-testid="column"]:nth-child(2) button {
background-color: #33FF57 !important; /* Warna hijau */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(2) button:hover {
background-color: #2ECC71 !important; /* Warna hijau lebih gelap saat hover */
}
/* Tombol di col4 (Laporan) */
div[data-testid="column"]:nth-child(3) button {
background-color: #3357FF !important; /* Warna biru */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(3) button:hover {
background-color: #2C3E50 !important; /* Warna biru lebih gelap saat hover */
}
.stButton > button {
background-color: #264CBE;
color: white;
font-family: 'Inter', sans-serif;
font-size: 16px;
font-weight: 600;
border: none;
border-radius: 5px;
padding: 10px;
cursor: pointer;
margin-top: 20px;
width: 100%;
}
.stButton > button:hover {
background-color: #ffffff;
color: #264CBE;
}
</style>
""",
unsafe_allow_html=True
)
# Tombol navigasi dengan warna berbeda di col2, col3, col4
with col2:
if st.button("Prediksi", key="nav_prediksi"):
st.switch_page("pages/Prediksi.py") # Pindah ke halaman yang sudah ada
with col3:
if st.button("Dashboard", key="nav_dashboard"):
st.switch_page("pages/Dashboard.py") # Pindah ke halaman yang sesuai
with col4:
if st.button("Laporan", key="nav_laporan"):
st.switch_page("pages/Laporan.py") # Pindah ke halaman laporan
with col5:
if st.button(login_button_text, key="login_button"):
if 'logged_in' in st.session_state and st.session_state['logged_in']:
st.session_state['logged_in'] = False # Logout user
else:
st.switch_page("pages/login.py") # Pindah ke halaman login
def show_report(): def show_report():
# Tampilkan navbar # Tampilkan navbar
navbar() navbar()
menu()
st.markdown(""" st.markdown("""
<style> <style>
.stDownloadButton > button { .stDownloadButton > button {
background-color: #264CBE; background-color: #264CBE;
color: white; color: white;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
border: none; border: none;
@ -199,7 +269,7 @@ def show_report():
background-color: #D0EEFF; background-color: #D0EEFF;
padding: 20px !important; padding: 20px !important;
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
border-radius: 10px; border-radius: 10px;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -215,10 +285,10 @@ def show_report():
# Konten halaman Laporan # Konten halaman Laporan
st.markdown( st.markdown(
""" """
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<h3 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h4 style="text-align: center; font-family: 'Inter', sans-serif;">
Halaman Laporan Lihat Hasil Prediksi
</h3> </h4>
""", unsafe_allow_html=True """, unsafe_allow_html=True
) )
@ -229,26 +299,42 @@ def show_report():
) )
if menu_option == "History Prediksi": if menu_option == "History Prediksi":
st.markdown(
"""
<h5 style="text-align: center; font-family: 'Poppins', sans-serif;">
Tabel Histori Prediksi
</h5>
""", unsafe_allow_html=True
)
# Ambil data dari tabel history_prediction # Ambil data dari tabel history_prediction
df = get_all_predictions() df = get_all_predictions()
if not df.empty: if not df.empty:
# **Filter Tanggal Prediksi**
col1, col2, col3 = st.columns(3)
with col1:
# st.markdown("Pilih Tanggal Mulai Prediksi")
start_date = st.date_input("Dari Tanggal Prediksi", df["Waktu_Prediksi"].min().date() if not df.empty else None)
with col2:
# st.markdown("Pilih Tanggal Akhir Prediksi")
end_date = st.date_input("Sampai Tanggal Prediksi", df["Waktu_Prediksi"].max().date() if not df.empty else None)
with col3:
# **Filter Hasil Prediksi Retensi**
# st.markdown("Pilih Retensi/Tidak")
filter_retensi = st.selectbox("Pilih Kategori Retensi/Tidak", ["Semua", "Retensi", "Tidak Retensi"])
# **Filter Data Sesuai Input Pengguna**
if start_date and end_date:
df = df[(df["Waktu_Prediksi"] >= pd.Timestamp(start_date)) & (df["Waktu_Prediksi"] <= pd.Timestamp(end_date))]
if filter_retensi != "Semua":
df = df[df["Hasil_Prediksi_Retensi"] == filter_retensi]
# Tampilkan data dalam bentuk tabel # Tampilkan data dalam bentuk tabel
st.dataframe(df) st.dataframe(df)
# Tombol untuk mendownload CSV # Tombol untuk mendownload CSV
if not df.empty:
csv = df.to_csv(index=False) # Konversi DataFrame ke CSV tanpa indeks csv = df.to_csv(index=False) # Konversi DataFrame ke CSV tanpa indeks
st.download_button( st.download_button(
label="Download Tabel sebagai CSV", label="Download Tabel sebagai CSV",
data=csv, data=csv,
file_name="history_prediction.csv", file_name="history_prediction_filtered.csv",
mime="text/csv", mime="text/csv",
) )
else: else:
@ -257,20 +343,28 @@ def show_report():
elif menu_option == "History SHAP Values": elif menu_option == "History SHAP Values":
st.markdown( st.markdown(
""" """
<h5 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h5 style="text-align: center; font-family: 'Inter', sans-serif;">
Tabel Histori SHAP Values Tabel Histori SHAP Values
</h5> </h5>
""", unsafe_allow_html=True """, unsafe_allow_html=True
) )
# Ambil data dari tabel shap_pred_result # Ambil data dari tabel shap_pred_result
df = get_shap_top_features() df = get_shap_top_features()
if not df.empty: if not df.empty:
# Tambahkan kolom deskripsi fitur berdasarkan JSON
for i in range(1, 6): # Karena ada 5 fitur top SHAP
feature_col = f"Nama_Fitur_{i}"
desc_col = f"Deskripsi_Fitur_{i}"
if feature_col in df.columns:
df[desc_col] = df[feature_col].map(feature_dict).fillna("-") # Isi dengan "-" jika tidak ada di JSON
# Tampilkan data dalam bentuk tabel # Tampilkan data dalam bentuk tabel
st.dataframe(df) st.dataframe(df)
# Tombol untuk mendownload CSV # Konversi DataFrame ke CSV untuk di-download
csv = df.to_csv(index=False) # Konversi DataFrame ke CSV tanpa indeks csv = df.to_csv(index=False)
st.download_button( st.download_button(
label="Download Tabel sebagai CSV", label="Download Tabel sebagai CSV",
data=csv, data=csv,

View File

@ -9,11 +9,17 @@ import numpy as np
import mysql.connector import mysql.connector
import io import io
import json import json
import streamlit.components.v1 as components
import time
import json
reg_model = pickle.load(open('regression_model.sav', 'rb')) reg_model = pickle.load(open('regression_model.sav', 'rb'))
class_model = pickle.load(open('clasification_model.sav', 'rb')) class_model = pickle.load(open('clasification_model.sav', 'rb'))
train_file_path = 'X_train.csv' train_file_path = 'X_train.csv'
with open("feature_explanation.json", "r") as f:
feature_dict = json.load(f)
def connect_to_db(): def connect_to_db():
try: try:
conn = mysql.connector.connect( conn = mysql.connector.connect(
@ -141,88 +147,134 @@ def get_image_as_base64(image_path):
with open(image_path, "rb") as img_file: with open(image_path, "rb") as img_file:
return base64.b64encode(img_file.read()).decode("utf-8") return base64.b64encode(img_file.read()).decode("utf-8")
# Fungsi untuk menampilkan navbar
def navbar(): def navbar():
current_page = st.session_state.get("page", "Home")
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png") logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# Cek status login
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
login_button_link = "?page=Login&logout=true" # Tambahkan parameter logout
else:
login_button_text = "Logout"
login_button_link = "?page=Login"
st.markdown( st.markdown(
f""" f"""
<style> <style>
.navbar {{ .navbar {{
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: center;
padding: 10px 20px; padding: 10px 20px;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
margin-top: 20px; /* Hilangkan jarak atas */ margin-top: 20px;
background-color: #D0EEFF; /* Background navbar */ background-color: #D0EEFF; /* Background navbar */
border-radius: 15px; /* Membulatkan sudut navbar */ border-radius: 15px; /* Membulatkan sudut navbar */
}} }}
.navbar .logo {{ .navbar .logo {{
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px;
}} }}
.navbar .logo img {{ .navbar .logo img {{
height: 40px; height: 40px;
margin-right: 10px;
}} }}
.navbar .nav-links {{ .navbar .text {{
display: flex; font-size: 18px;
gap: 60px;
}}
.navbar .nav-links a {{
color: black;
text-decoration: none;
font-size: 16px;
font-weight: bold; font-weight: bold;
}}
.navbar .nav-links a:hover {{
color: royalblue;
}}
.navbar .nav-links a.active {{
color: #264CBE; /* Warna saat aktif */
text-decoration: underline; /* Garis bawah saat aktif */
}}
.navbar .login-button {{
background-color: #264CBE;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
text-decoration: none;
}}
.navbar .login-button:hover {{
background-color: white;
color: #264CBE; color: #264CBE;
}} }}
</style> </style>
<div class="navbar"> <div class="navbar">
<div class="logo"> <div class="logo">
<img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo"> <img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo">
<div class="text">Halaman Prediksi Karyawan</div>
</div> </div>
<div class="nav-links">
<a href="?page=Prediksi" class="{ 'active' if st.session_state.page == 'Prediksi' else '' }">Prediksi</a>
<a href="?page=exploration" class="{ 'active' if st.session_state.page == 'exploration' else '' }">Dashboard</a>
<a href="?page=report" class="{ 'active' if st.session_state.page == 'report' else '' }">Laporan</a>
</div>
<a class="login-button" href="{login_button_link}">{login_button_text}</a>
</div> </div>
""", """,
unsafe_allow_html=True, unsafe_allow_html=True,
) )
def menu():
# **Pastikan Streamlit Session State Sudah Punya `page`**
if "page" not in st.session_state:
st.session_state["page"] = "Home"
current_page = st.session_state["page"]
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
# **Login Check**
if 'logged_in' in st.session_state and st.session_state['logged_in']:
login_button_text = "Logout"
else:
login_button_text = "Login"
# **Gunakan Streamlit Columns agar Navbar Sejajar (4 Kolom)**
col2, col3, col4, col5 = st.columns([1.5, 1.5, 1.5, 1]) # 4 Kolom tanpa col1 (logo)
# **Custom CSS untuk Tombol Navbar yang Spesifik**
st.markdown(
"""
<style>
/* Tombol di col2 (Prediksi) */
div[data-testid="column"]:nth-child(1) button {
background-color: #FF5733 !important; /* Warna oranye */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(1) button:hover {
background-color: #E64A19 !important; /* Warna oranye lebih gelap saat hover */
}
/* Tombol di col3 (Dashboard) */
div[data-testid="column"]:nth-child(2) button {
background-color: #33FF57 !important; /* Warna hijau */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(2) button:hover {
background-color: #2ECC71 !important; /* Warna hijau lebih gelap saat hover */
}
/* Tombol di col4 (Laporan) */
div[data-testid="column"]:nth-child(3) button {
background-color: #3357FF !important; /* Warna biru */
color: white !important;
padding: 10px 20px !important;
margin: 5px 0 !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
}
div[data-testid="column"]:nth-child(3) button:hover {
background-color: #2C3E50 !important; /* Warna biru lebih gelap saat hover */
}
</style>
""",
unsafe_allow_html=True
)
# Tombol navigasi dengan warna berbeda di col2, col3, col4
with col2:
if st.button("Prediksi", key="nav_prediksi"):
st.switch_page("pages/Prediksi.py") # Pindah ke halaman yang sudah ada
with col3:
if st.button("Dashboard", key="nav_dashboard"):
st.switch_page("pages/Dashboard.py") # Pindah ke halaman yang sesuai
with col4:
if st.button("Laporan", key="nav_laporan"):
st.switch_page("pages/Laporan.py") # Pindah ke halaman laporan
with col5:
if st.button(login_button_text, key="login_button"):
if 'logged_in' in st.session_state and st.session_state['logged_in']:
st.session_state['logged_in'] = False # Logout user
else:
st.switch_page("pages/login.py") # Pindah ke halaman login
def save_prediction_to_db(employee_id, hasil_prediksi_klasifikasi, probabilitas_pred_klasifikasi, hasil_prediksi_regresi): def save_prediction_to_db(employee_id, hasil_prediksi_klasifikasi, probabilitas_pred_klasifikasi, hasil_prediksi_regresi):
conn = connect_to_db() conn = connect_to_db()
if conn: if conn:
@ -260,13 +312,14 @@ def save_shap_to_db_with_features(employee_id, shap_dict):
def show_prediction(): def show_prediction():
navbar() navbar()
menu()
st.markdown(""" st.markdown("""
<style> <style>
.stButton > button { .stButton > button {
background-color: #264CBE; background-color: #264CBE;
color: white; color: white;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
border: none; border: none;
@ -287,7 +340,7 @@ def show_prediction():
background-color: #D0EEFF; background-color: #D0EEFF;
padding: 20px !important; padding: 20px !important;
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
border-radius: 10px; border-radius: 10px;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -302,10 +355,10 @@ def show_prediction():
st.markdown( st.markdown(
""" """
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<h3 style="text-align: center; font-family: 'Poppins', sans-serif;"> <h4 style="text-align: center; font-family: 'Inter', sans-serif;">
Halaman Prediksi Masukkan ID Karyawan dan Lihat Hasilnya
</h3> </h4>
""", unsafe_allow_html=True """, unsafe_allow_html=True
) )
@ -335,11 +388,9 @@ def show_prediction():
cat_feature = ['departemen', 'position', 'domisili', 'marriage_stat', 'job_satisfaction', cat_feature = ['departemen', 'position', 'domisili', 'marriage_stat', 'job_satisfaction',
'performance_rating', 'education', 'active_work_category', 'resign_risk_indicator', 'jenis_kelamin'] 'performance_rating', 'education', 'active_work_category', 'resign_risk_indicator', 'jenis_kelamin']
# Pastikan data uji memiliki kolom yang sesuai dengan model
X_test_class = df[expected_columns_class] X_test_class = df[expected_columns_class]
X_test_reg = df[expected_columns_reg] X_test_reg = df[expected_columns_reg]
# Konversi fitur kategori menjadi string
for col in cat_feature: for col in cat_feature:
if col in X_test_class.columns: if col in X_test_class.columns:
X_test_class[col] = X_test_class[col].astype(str) X_test_class[col] = X_test_class[col].astype(str)
@ -366,13 +417,13 @@ def show_prediction():
st.markdown( st.markdown(
f""" f"""
<div style="border: 1px solid #ddd; border-radius: 10px; padding: 20px; margin-bottom: 20px; background-color: #FFFFFF;"> <div style="border: 1px solid #ddd; border-radius: 10px; padding: 20px; margin-bottom: 20px; background-color: #FFFFFF;">
<h4 style="color: {warna_retensi}; text-align: center; font-family: 'Poppins', sans-serif;"> <h4 style="color: {warna_retensi}; text-align: center; font-family: 'Inter', sans-serif;">
Prediksi Kemungkinan Retensi: {hasil_prediksi_retensi} Prediksi Kemungkinan Retensi: {hasil_prediksi_retensi}
</h4> </h4>
<p style="text-align: center; font-family: 'Poppins', sans-serif;"> <p style="text-align: center; font-family: 'Inter', sans-serif;">
<b>Probabilitas Kemungkinan Retensi:</b> {classification_prob[0][0]:.2f} <b>Probabilitas Kemungkinan Retensi:</b> {classification_prob[0][0]:.2f}
</p> </p>
<p style="text-align: center; font-family: 'Poppins', sans-serif;"> <p style="text-align: center; font-family: 'Inter', sans-serif;">
<b>Prediksi Durasi Kerja (bulan):</b> {hasil_prediksi_regresi} bulan <b>Prediksi Durasi Kerja (bulan):</b> {hasil_prediksi_regresi} bulan
</p> </p>
</div> </div>
@ -423,57 +474,40 @@ def show_prediction():
plot_placeholder = st.empty() plot_placeholder = st.empty()
# Modify the generate_shap_plot function
def generate_shap_plot(X_test_class, explainer_class, shap_dict, predicted_class): def generate_shap_plot(X_test_class, explainer_class, shap_dict, predicted_class):
plt.close('all') plt.close('all')
try: try:
# Generate new SHAP explanation
shap_explanation = explainer_class(X_test_class.iloc[0:1]) shap_explanation = explainer_class(X_test_class.iloc[0:1])
# Create figure
plt.figure(figsize=(4, 2), dpi=100) plt.figure(figsize=(4, 2), dpi=100)
# Handle different SHAP value structures
if isinstance(shap_explanation, list): if isinstance(shap_explanation, list):
# For multi-class output shap.plots.waterfall(shap_explanation[1][0] if predicted_class == 1 and len(shap_explanation) > 1 else shap_explanation[0][0])
if predicted_class == 1 and len(shap_explanation) > 1:
shap.plots.waterfall(shap_explanation[1][0])
else: else:
shap.plots.waterfall(shap_explanation[0][0])
else:
# For single-class output
shap.plots.waterfall(shap_explanation[0]) shap.plots.waterfall(shap_explanation[0])
# Save and display plot
buf = io.BytesIO() buf = io.BytesIO()
plt.savefig(buf, format='png', bbox_inches="tight", dpi=100) plt.savefig(buf, format='png', bbox_inches="tight", dpi=100)
buf.seek(0) buf.seek(0)
col1, col2 = st.columns([1.5, 2]) # **Kolom pertama untuk grafik, kolom kedua untuk penjelasan** col1, col2 = st.columns([1.5, 2])
with col1: with col1:
st.image(buf, caption="SHAP Waterfall Plot", use_container_width=True) st.image(buf, caption="SHAP Waterfall Plot", use_container_width=True)
with col2: with col2:
top_factors = sorted(shap_dict.items(), key=lambda x: abs(x[1]), reverse=True)[:5] top_factors = sorted(shap_dict.items(), key=lambda x: abs(x[1]), reverse=True)[:5]
summary_list = [
f"{feature_dict.get(factor, factor)}: {X_test_class.iloc[0][factor]}" if factor in X_test_class.columns else f"{feature_dict.get(factor, factor)}"
for factor, _ in top_factors
]
summary_text = "<br>".join(summary_list)
# Bangun kesimpulan dinamis
summary = " dan ".join(
[f"<b>{factor}</b> dengan kontribusi <b>{'+' if value > 0 else ''}{value:.2f}</b>" for factor, value in top_factors]
)
# Kesimpulan Dinamis
st.markdown( st.markdown(
f""" f"""
<div style="text-align: justify; font-family: 'Poppins', sans-serif;"> <div style="text-align: justify; font-family: 'Inter', sans-serif;">
<h4 style="color:#264CBE; font-size:18px; font-weight:600; font-family: 'Poppins', sans-serif;">Faktor Utama yang Mempengaruhi Prediksi:</h4> <h4 style="color:#264CBE; font-size:18px; font-weight:600;">Faktor Utama yang Mempengaruhi Prediksi:</h4>
<p> <p>{summary_text}</p>
Grafik ini menunjukkan bagaimana hasil prediksi dihitung berdasarkan beberapa faktor utama.
Faktor-faktor yang paling memengaruhi hasil prediksi adalah {summary}.
Faktor-faktor ini memberikan kontribusi signifikan terhadap hasil akhir prediksi,
baik dalam meningkatkan maupun menurunkan probabilitas retensi karyawan.
</p>
</div> </div>
""", """,
unsafe_allow_html=True unsafe_allow_html=True

View File

@ -4,6 +4,6 @@ print("Current directory:", os.getcwd())
print("Files in pages directory:", os.listdir(os.path.dirname(__file__))) print("Files in pages directory:", os.listdir(os.path.dirname(__file__)))
from .home import show_home from .home import show_home
from .karyawan_form import show_karyawan_form from .Form_Kepuasan import show_karyawan_form
from .pimpinan_form import show_pimpinan_form from .Form_Penilaian import show_pimpinan_form
from .prediction import show_prediction from .Prediksi import show_prediction

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -33,7 +33,7 @@ def show_home():
} }
.text-content { .text-content {
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 40px; font-size: 40px;
font-weight: bold; font-weight: bold;
color: #333333; color: #333333;
@ -63,7 +63,7 @@ def show_home():
border-radius: 15px; border-radius: 15px;
margin-top: 50px !important; margin-top: 50px !important;
margin-bottom: 50px !important; margin-bottom: 50px !important;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
text-align: center; text-align: center;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
} }
@ -105,7 +105,7 @@ def show_home():
.content-section .text-content { .content-section .text-content {
flex: 1; flex: 1;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px; font-size: 16px;
color: #555555; color: #555555;
line-height: 1.6; line-height: 1.6;
@ -121,7 +121,7 @@ def show_home():
.about-section h2, .about-section h2,
.content-section h2 { .content-section h2 {
font-family: 'Poppins', sans-serif; /* Gunakan font Poppins */ font-family: 'Inter', sans-serif; /* Gunakan font Inter */
font-size: 28px; font-size: 28px;
font-weight: bold; font-weight: bold;
color: #333333; color: #333333;
@ -129,7 +129,7 @@ def show_home():
} }
.about-section p, .about-section p,
.content-section .text-content p { .content-section .text-content p {
font-family: 'Poppins', sans-serif; /* Gunakan font Poppins */ font-family: 'Inter', sans-serif; /* Gunakan font Inter */
font-size: 16px; font-size: 16px;
color: #555555; color: #555555;
line-height: 1.6; line-height: 1.6;
@ -138,7 +138,7 @@ def show_home():
/* Judul Bagian Aplikasi */ /* Judul Bagian Aplikasi */
.section-title { .section-title {
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 28px; font-size: 28px;
font-weight: bold; font-weight: bold;
color: #333333; color: #333333;
@ -148,7 +148,7 @@ def show_home():
/* Berita dan Informasi */ /* Berita dan Informasi */
.news-section { .news-section {
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -180,7 +180,7 @@ def show_home():
background-color: #D0EEFF; background-color: #D0EEFF;
padding: 20px !important; padding: 20px !important;
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
border-radius: 10px; border-radius: 10px;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -245,9 +245,10 @@ def show_home():
dengan fitur-fitur yang terstruktur berdasarkan peran pengguna. dengan fitur-fitur yang terstruktur berdasarkan peran pengguna.
Dimulai dari Halaman Utama, pengguna diarahkan ke Halaman Login, Dimulai dari Halaman Utama, pengguna diarahkan ke Halaman Login,
yang kemudian membagi akses berdasarkan peran: Admin, Karyawan, dan Pimpinan. yang kemudian membagi akses berdasarkan peran: Admin, Karyawan, dan Pimpinan.
Admin memiliki akses ke Halaman Prediksi, Halaman Dashboard, dan Halaman Laporan untuk mengelola data dan analisis. Akses berdasarkan peran:
Karyawan dapat mengisi Form Kepuasan Kerja dan Form Komplain untuk memberikan feedback dan keluhan. Admin: Halaman Prediksi, Dashboard, dan Laporan.
Pimpinan memiliki akses ke Form Penilaian untuk evaluasi serta Halaman Dashboard untuk melihat data yang relevan. Karyawan: Form Kepuasan Kerja dan Form Komplain.
Pimpinan: Form Penilaian dan Halaman Dashboard.
Aplikasi ini dirancang untuk mempermudah pengelolaan dan pengambilan keputusan berbasis data. Aplikasi ini dirancang untuk mempermudah pengelolaan dan pengambilan keputusan berbasis data.
</p> </p>
</div> </div>

View File

@ -7,45 +7,112 @@ def get_image_as_base64(image_path):
with open(image_path, "rb") as img_file: with open(image_path, "rb") as img_file:
return base64.b64encode(img_file.read()).decode("utf-8") return base64.b64encode(img_file.read()).decode("utf-8")
def navbar(): st.markdown("""
logo_path = os.path.join(os.path.dirname(__file__), "./asset/logo.png")
st.markdown(
f"""
<style> <style>
.navbar {{ .stButton > button {
border-radius: 10px !important;
font-weight: bold !important;
font-family: 'Inter', sans-serif !important;
margin-top: 6px !important;
}
/* Tombol Home (Kecil dan Biru) */
.home-button button {
background-color: #264CBE !important; /* Biru */
color: white !important;
font-size: 12px !important;
width: 80px !important;
height: 35px !important;
}
/* Tombol Login (Lebih Panjang dan Warna Berbeda) */
.login-button button {
background-color: #FFA500 !important; /* Oranye */
color: white !important;
font-size: 16px !important;
width: 100% !important;
height: 50px !important;
}
.login-button button:hover {
background-color: white !important;
color: #FFA500 !important;
border: 2px solid #FFA500 !important;
}
</style>
""", unsafe_allow_html=True)
def navbar():
current_page = st.session_state["page"]
print("Navbar current page:", repr(current_page))
logo_path = os.path.join(os.path.dirname(__file__), "../asset/logo.png")
if current_page == "Home":
return # Tidak perlu menampilkan navbar di Home jika tidak diinginkan
st.markdown("""
<style>
.navbar-container {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: space-between;
background-color: #D0EEFF;
border-radius: 15px;
padding: 10px 20px; padding: 10px 20px;
font-family: 'Poppins', sans-serif; width: 100%;
margin-top: 20px; }
background-color: #D0EEFF; /* Background navbar */ .navbar-left {
border-radius: 15px; /* Membulatkan sudut navbar */
}}
.navbar .logo {{
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px; gap: 10px;
}} }
.navbar .logo img {{ .navbar-left img {
height: 40px; height: 40px;
}} }
.navbar .text {{ .navbar-center {
flex: 1;
text-align: center;
font-family: 'Inter', sans-serif;
color: #1D567E;
font-size: 18px; font-size: 18px;
font-weight: bold; font-weight: bold;
color: #264CBE; }
}} .navbar-right {
margin-left: auto;
}
.stButton > button {
background-color: #264CBE !important;
color: white !important;
border-radius: 10px !important;
font-size: 12px !important;
font-weight: bold !important;
font-family: 'Inter', sans-serif !important;
padding: 10px 20px !important;
margin-top: 6px !important;
width: 100px !important;
height: 50px !important;
}
</style> </style>
<div class="navbar"> """, unsafe_allow_html=True)
<div class="logo">
col1, col2 = st.columns([11, 1])
with col1:
st.markdown(f"""
<div class="navbar-container">
<div class="navbar-left">
<img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo"> <img src="data:image/png;base64,{get_image_as_base64(logo_path)}" alt="Logo">
<div class="text">Silahkan Login ke Akun Anda</div>
</div> </div>
<div class="navbar-center">
Selamat Datang di TALENTRA
</div> </div>
""", <div class="navbar-right">
unsafe_allow_html=True, """, unsafe_allow_html=True)
)
with col2:
if st.button("Kembali", key="home_button"):
st.session_state["page"] = "Home"
st.rerun() # Refresh halaman untuk memperbarui state
st.markdown("</div></div>", unsafe_allow_html=True)
# Fungsi untuk koneksi ke database # Fungsi untuk koneksi ke database
def connect_to_db(): def connect_to_db():
@ -79,7 +146,7 @@ def show_login():
navbar() navbar()
st.markdown(""" st.markdown("""
<style> <style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
/* Reset Layout */ /* Reset Layout */
html, body, [data-testid="stAppViewContainer"] { html, body, [data-testid="stAppViewContainer"] {
@ -87,7 +154,7 @@ def show_login():
padding: 0; padding: 0;
height: 100%; height: 100%;
width: 100%; width: 100%;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
} }
/* Fullscreen Center */ /* Fullscreen Center */
@ -116,7 +183,7 @@ def show_login():
color: #333; color: #333;
margin-bottom: 20px; margin-bottom: 20px;
font-weight: 500; font-weight: 500;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
} }
/* Input Fields */ /* Input Fields */
@ -125,7 +192,7 @@ def show_login():
border: 1px solid #e9ecef; border: 1px solid #e9ecef;
padding: 10px; padding: 10px;
border-radius: 5px; border-radius: 5px;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
width: 100%; width: 100%;
} }
@ -133,7 +200,7 @@ def show_login():
.stButton > button { .stButton > button {
background-color: #264CBE; background-color: #264CBE;
color: white; color: white;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: 2000; font-weight: 2000;
border: none; border: none;
@ -155,7 +222,7 @@ def show_login():
background-color: #D0EEFF; background-color: #D0EEFF;
padding: 20px !important; padding: 20px !important;
text-align: center; text-align: center;
font-family: 'Poppins', sans-serif; font-family: 'Inter', sans-serif;
border-radius: 10px; border-radius: 10px;
margin-top: 50px !important; margin-top: 50px !important;
} }
@ -203,11 +270,11 @@ def main():
if st.session_state['logged_in']: if st.session_state['logged_in']:
role = st.session_state['role'] role = st.session_state['role']
if role == 'admin': if role == 'admin':
st.switch_page("pages/prediction.py") st.switch_page("pages/Prediksi.py")
elif role == 'karyawan': elif role == 'karyawan':
st.switch_page("pages/karyawan_form.py") st.switch_page("pages/Form_Kepuasan.py")
elif role == 'pimpinan': elif role == 'pimpinan':
st.switch_page("pages/pimpinan_form.py") st.switch_page("pages/Form_Penilaian.py")
else: else:
show_login() show_login()