diff --git a/CRM/Applications.py b/CRM/Applications.py
new file mode 100644
index 0000000..eead662
--- /dev/null
+++ b/CRM/Applications.py
@@ -0,0 +1,209 @@
+import sys
+import os
+import pandas as pd
+from PyQt6.QtWidgets import QApplication, QHeaderView, QTableWidgetItem
+from PyQt6.uic import loadUi
+from PyQt6.QtCore import Qt
+from main import BaseWindow
+
+# Klasör yolları
+BASE_DIR = os.path.dirname(__file__)
+UI_DIR = os.path.join(BASE_DIR, "UI_s")
+EXCEL_DIR = os.path.join(BASE_DIR, "Excels")
+
+
+class ApplicationsWindow(BaseWindow):
+ def __init__(self, role="admin"):
+ super().__init__()
+ self.role = role
+ loadUi(os.path.join(UI_DIR, "Applications.ui"), self)
+
+ # Excel başlıkları ve UI başlıkları artık aynı
+ self.table_columns = [
+ "DATE",
+ "FULL NAME",
+ "E-MAIL",
+ "PHONE NUMBER",
+ "POSTAL CODE",
+ "PROVINCE",
+ "CURRENT STATUS"
+ ]
+
+ self.setWindowTitle("Applications")
+ self.setFixedSize(1000, 600)
+ self.move_to_last_position()
+
+ header = self.tableWidget.horizontalHeader()
+ header.setSectionResizeMode(QHeaderView.ResizeMode.Fixed)
+ column_widths = [100, 200, 150, 120, 120, 200] # tablo sütun sayısına göre ayarla
+ for col, width in enumerate(column_widths):
+ self.tableWidget.setColumnWidth(col, width)
+
+ # Excel dosyalarını yükle
+ self.applications_file = os.path.join(EXCEL_DIR, "Basvurular.xlsx")
+ self.vit1_file = os.path.join(EXCEL_DIR, "VIT1.xlsx")
+ self.vit2_file = os.path.join(EXCEL_DIR, "VIT2.xlsx")
+
+ self.df = pd.read_excel(self.applications_file) if os.path.exists(self.applications_file) else pd.DataFrame()
+ self.vit1_df = pd.read_excel(self.vit1_file) if os.path.exists(self.vit1_file) else pd.DataFrame()
+ self.vit2_df = pd.read_excel(self.vit2_file) if os.path.exists(self.vit2_file) else pd.DataFrame()
+
+ # Butonlara fonksiyon bağla
+ self.pushButton_SEARCH.clicked.connect(self.search_applications)
+ self.lineEdit.textChanged.connect(self.search_applications) # CANLI ARAMA
+ self.pushButton_ALL_APPLICATIONS.clicked.connect(self.clear_search_input)
+ self.pushButton_ALL_APPLICATIONS.clicked.connect(self.load_all_applications)
+ self.pushButton_DEFINED_MENTOR_MEETING.clicked.connect(self.clear_search_input)
+ self.pushButton_DEFINED_MENTOR_MEETING.clicked.connect(self.show_defined_mentor)
+ self.pushButton_UNDEFINED_MENTOR_MEETING.clicked.connect(self.clear_search_input)
+ self.pushButton_UNDEFINED_MENTOR_MEETING.clicked.connect(self.show_undefined_mentor)
+ self.pushButton_DUPLICATE_REGISTRATION.clicked.connect(self.clear_search_input)
+ self.pushButton_DUPLICATE_REGISTRATION.clicked.connect(self.show_duplicates)
+ self.pushButton_PREVIOUS_VIT_CHECK.clicked.connect(self.clear_search_input)
+ self.pushButton_PREVIOUS_VIT_CHECK.clicked.connect(self.show_previous_vit)
+ self.pushButton_DIFFERENT_REGISTRATION.clicked.connect(self.clear_search_input)
+ self.pushButton_DIFFERENT_REGISTRATION.clicked.connect(self.show_different)
+ self.pushButton_APPLICATION_FILTERING.clicked.connect(self.clear_search_input)
+ self.pushButton_APPLICATION_FILTERING.clicked.connect(self.filter_applications)
+ self.pushButton_RETURN_REFERENCE_MENU.clicked.connect(self.return_to_menu)
+
+ # ---------------- Fonksiyonlar ---------------- #
+ def clear_search_input(self):
+ self.lineEdit.clear() #Herhangi bir butona basildiginda onceki yapilan arama silinsin
+
+ def display_data(self, df):
+ """DataFrame'i tabloya yazdır — artık UI başlıkları Excel başlıkları ile aynı."""
+ try:
+ self.tableWidget.clearContents()
+ self.tableWidget.setRowCount(0)
+
+ if df is None or df.empty:
+ print("Gösterilecek kayıt yok veya DataFrame boş.")
+ return
+
+ display_df = df.copy()
+ for col in self.table_columns:
+ if col not in display_df.columns:
+ display_df[col] = ""
+ display_df = display_df.reset_index(drop=True)
+
+ self.tableWidget.setRowCount(len(display_df))
+ self.tableWidget.setColumnCount(len(self.table_columns))
+ self.tableWidget.setHorizontalHeaderLabels(self.table_columns)
+
+ for row_idx, row in display_df.iterrows():
+ for col_idx, col_name in enumerate(self.table_columns):
+ value = row[col_name] if col_name in row else ""
+ item = QTableWidgetItem(str(value))
+ item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.tableWidget.setItem(row_idx, col_idx, item)
+
+ print(f"{len(display_df)} kayıt tabloya yüklendi.\n")
+
+ except Exception as e:
+ print(f"display_data() Hatası: {e}")
+
+ def search_applications(self):
+ """LineEdit içindeki metin ile FULL NAME araması."""
+ try:
+ search_text = self.lineEdit.text().strip().lower()
+ print("Arama metni:", search_text)
+
+ if 'FULL NAME' not in self.df.columns:
+ print("'FULL NAME' sütunu bulunamadı.")
+ return
+
+ if not search_text:
+ self.display_data(self.df)
+ return
+
+ df_clean = self.df.copy()
+ df_clean['FULL NAME'] = df_clean['FULL NAME'].astype(str).str.lower().str.strip()
+ mask = df_clean['FULL NAME'].apply(lambda x: search_text in x)
+ filtered_df = df_clean[mask].reset_index(drop=True)
+
+ print("Arama sonucu:", filtered_df[['FULL NAME']].to_string(index=False))
+ self.display_data(filtered_df)
+
+
+ except Exception as e:
+ print(f"Search Error: {e}")
+
+ def load_all_applications(self):
+ print(f"Toplam kayıt sayısı: {len(self.df)}")
+ self.display_data(self.df)
+ print("Tüm başvurular görüntülendi.\n")
+
+ def show_defined_mentor(self):
+ if 'MENTOR MEETING' in self.df.columns:
+ filtered_df = self.df[self.df['MENTOR MEETING'] == 'OK']
+ print(f"Mentoru atanmış adaylar filtrelendi: {len(filtered_df)} kayıt bulundu.")
+ self.display_data(filtered_df)
+
+ def show_undefined_mentor(self):
+ if 'MENTOR MEETING' in self.df.columns:
+ filtered_df = self.df[self.df['MENTOR MEETING'] == 'ATANMADI']
+ print(f"Mentoru atanmamış adaylar filtrelendi: {len(filtered_df)} kayıt bulundu.")
+ self.display_data(filtered_df)
+
+ def show_duplicates(self):
+ if all(col in self.df.columns for col in ['FULL NAME', 'E-MAIL']):
+ duplicates = self.df[self.df.duplicated(subset=['FULL NAME', 'E-MAIL'], keep=False)]
+ print(f"Mükerrer kayıtlar bulundu: {len(duplicates)}")
+ self.display_data(duplicates)
+
+ def filter_applications(self):
+ """Tekil kayıtları göster (FULL NAME + E-MAIL)."""
+ if all(col in self.df.columns for col in ['FULL NAME', 'E-MAIL']):
+ filtered = self.df.drop_duplicates(subset=['FULL NAME', 'E-MAIL'], keep='first')
+ self.display_data(filtered)
+ print("Tekil kayıtlar başarıyla listelendi.\n")
+
+ def show_previous_vit(self):
+ """VIT1 veya VIT2 ile ortak adayları göster."""
+ if self.vit1_df.empty and self.vit2_df.empty:
+ print("VIT1 ve VIT2 dosyaları bulunamadı.")
+ self.tableWidget.setRowCount(0)
+ return
+
+ vit_all = pd.concat([self.vit1_df, self.vit2_df], ignore_index=True)
+
+ # Sadece FULL NAME ve E-MAIL ile merge yap, orijinal df’den diğer sütunları al
+ common_keys = ['FULL NAME', 'E-MAIL']
+ merged = self.df.merge(vit_all[common_keys], how='inner', on=common_keys)
+ print(f"VIT1/VIT2 ile ortak kayıtlar bulundu: {len(merged)}")
+ self.display_data(merged)
+
+
+ def show_different(self):
+ """VIT1 ve VIT2’de olmayan adayları göster."""
+ if self.vit1_df.empty and self.vit2_df.empty:
+ print("VIT1 ve VIT2 dosyaları bulunamadı.")
+ self.tableWidget.setRowCount(0)
+ return
+
+ vit_all = pd.concat([self.vit1_df, self.vit2_df], ignore_index=True)
+ keys = ['FULL NAME', 'E-MAIL']
+ different_keys = self.df.merge(vit_all[keys], how='left', on=keys, indicator=True)
+ different = self.df[different_keys['_merge'] == 'left_only']
+ print(f"VIT1/VIT2’de olmayan adaylar: {len(different)}")
+ self.display_data(different)
+
+
+ def return_to_menu(self):
+ from main import PreferenceAdminMenu, PreferenceMenu
+ if self.role.lower() == "admin":
+ self.pref_menu = PreferenceAdminMenu(role=self.role)
+ else:
+ self.pref_menu = PreferenceMenu(role=self.role)
+ self.pref_menu.show()
+ self.close()
+
+
+# ----------------- Main ----------------- #
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ window = ApplicationsWindow(role="admin")
+ window.show()
+ sys.exit(app.exec())
+
diff --git a/CRM/Excels/Basvurular.xlsx b/CRM/Excels/Basvurular.xlsx
new file mode 100644
index 0000000..4c11b52
Binary files /dev/null and b/CRM/Excels/Basvurular.xlsx differ
diff --git a/CRM/Excels/Event.ods b/CRM/Excels/Event.ods
new file mode 100644
index 0000000..dbdb80b
Binary files /dev/null and b/CRM/Excels/Event.ods differ
diff --git a/CRM/Excels/Event.xlsx b/CRM/Excels/Event.xlsx
new file mode 100644
index 0000000..0d252ea
Binary files /dev/null and b/CRM/Excels/Event.xlsx differ
diff --git a/CRM/Excels/FullSheets.xlsx b/CRM/Excels/FullSheets.xlsx
new file mode 100644
index 0000000..c792df5
Binary files /dev/null and b/CRM/Excels/FullSheets.xlsx differ
diff --git a/CRM/Excels/Interviews.xlsx b/CRM/Excels/Interviews.xlsx
new file mode 100644
index 0000000..5494813
Binary files /dev/null and b/CRM/Excels/Interviews.xlsx differ
diff --git a/CRM/Excels/Mentor.xlsx b/CRM/Excels/Mentor.xlsx
new file mode 100644
index 0000000..021c357
Binary files /dev/null and b/CRM/Excels/Mentor.xlsx differ
diff --git a/CRM/Excels/Mulakatlar.xlsx b/CRM/Excels/Mulakatlar.xlsx
new file mode 100644
index 0000000..5494813
Binary files /dev/null and b/CRM/Excels/Mulakatlar.xlsx differ
diff --git a/CRM/Excels/VIT1.xlsx b/CRM/Excels/VIT1.xlsx
new file mode 100644
index 0000000..4211d0f
Binary files /dev/null and b/CRM/Excels/VIT1.xlsx differ
diff --git a/CRM/Excels/VIT2.xlsx b/CRM/Excels/VIT2.xlsx
new file mode 100644
index 0000000..c7077d9
Binary files /dev/null and b/CRM/Excels/VIT2.xlsx differ
diff --git a/CRM/Excels/users.xlsx b/CRM/Excels/users.xlsx
new file mode 100644
index 0000000..d25043f
Binary files /dev/null and b/CRM/Excels/users.xlsx differ
diff --git a/CRM/UI_s/Admin_Menu.ui b/CRM/UI_s/Admin_Menu.ui
new file mode 100644
index 0000000..88065ce
--- /dev/null
+++ b/CRM/UI_s/Admin_Menu.ui
@@ -0,0 +1,289 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 1000
+ 600
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ Nirmala UI
+
+
+
+ Admin Menu
+
+
+
+ :/logo/logo_icon.png:/logo/logo_icon.png
+
+
+ #Form{
+background-color: qconicalgradient(cx:0.114, cy:0.113318, angle:134.3, stop:0 rgba(214, 28, 30, 255), stop:1 rgba(255, 255, 255, 255));}
+
+
+
+
+ 10
+ 20
+ 981
+ 61
+
+
+
+
+ Nirmala UI
+ 30
+ 75
+ true
+
+
+
+ color: rgb(214, 30, 32);
+
+
+ ADMIN MENU
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ 710
+ 100
+ 201
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ SEND E-MAIL
+
+
+
+
+
+ 90
+ 100
+ 451
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ EVENT REGISTRATION
+
+
+
+
+
+ 90
+ 500
+ 461
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ RETURN TO ADMIN PREFERENCE MENU
+
+
+
+
+
+ 710
+ 500
+ 201
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ EXIT
+
+
+
+
+
+ 90
+ 190
+ 821
+ 291
+
+
+
+ background-color:rgb(255, 255, 255)
+
+
+ true
+
+
+ 194
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+ 28
+
+
+ true
+
+
+ 23
+
+
+ false
+
+
+ false
+
+
+
+ Event Name
+
+
+
+
+ Start Time
+
+
+
+
+ Participant Email
+
+
+
+
+ Organizer Email
+
+
+
+
+
+
+
+
+
diff --git a/CRM/UI_s/Applications.ui b/CRM/UI_s/Applications.ui
new file mode 100644
index 0000000..a0cdb3f
--- /dev/null
+++ b/CRM/UI_s/Applications.ui
@@ -0,0 +1,488 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 1000
+ 600
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ Nirmala UI
+
+
+
+ Applications
+
+
+
+ :/logo/logo_icon.png:/logo/logo_icon.png
+
+
+ #Form{
+background-color: qconicalgradient(cx:0.114, cy:0.113318, angle:134.3, stop:0 rgba(214, 28, 30, 255), stop:1 rgba(255, 255, 255, 255));}
+
+
+
+
+ 10
+ 20
+ 981
+ 61
+
+
+
+
+ Nirmala UI
+ 30
+ 75
+ true
+
+
+
+ color: rgb(214, 30, 32);
+
+
+ APPLICATIONS
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ 70
+ 120
+ 101
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ SEARCH
+
+
+
+
+
+ 660
+ 60
+ 271
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ RETURN PREFERENCE MENU
+
+
+
+
+
+ 70
+ 180
+ 301
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ DEFINED MENTOR MEETING
+
+
+
+
+
+ 390
+ 240
+ 251
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ ALL APPLICATIONS
+
+
+
+
+
+ 180
+ 120
+ 461
+ 51
+
+
+
+
+ 15
+ true
+
+
+
+ border-style:solid;
+border-width:3px;
+border-radius:20px;
+border-color: rgb(218, 30, 60);
+color: rgb(104, 104, 104);
+background-color: rgb(255, 255, 255);
+border-color: rgb(220, 63, 65);
+
+
+ Enter the text you want to search for here
+
+
+
+
+
+ 660
+ 180
+ 271
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ DIFFERENT REGISTRATION
+
+
+
+
+
+ 70
+ 240
+ 301
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ UNDEFINED MENTOR MEETING
+
+
+
+
+
+ 660
+ 240
+ 271
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ DUPLICATE REGISTRATION
+
+
+
+
+
+ 390
+ 180
+ 251
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ Qt::LeftToRight
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ PREVIOUS VIT CHECK
+
+
+
+
+
+ 660
+ 120
+ 271
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ APPLICATION FILTERING
+
+
+
+
+
+ 70
+ 310
+ 861
+ 261
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+ 136
+
+
+ true
+
+
+
+ DATE
+
+
+
+
+ FULL NAME
+
+
+
+
+ E-MAIL
+
+
+
+
+ PHONE NUMBER
+
+
+
+
+ POSTAL CODE
+
+
+
+
+ PROVINCE
+
+
+
+
+ CURRENT STATUS
+
+
+
+
+
+
+
+
+
diff --git a/CRM/UI_s/Interviews.ui b/CRM/UI_s/Interviews.ui
new file mode 100644
index 0000000..4af1679
--- /dev/null
+++ b/CRM/UI_s/Interviews.ui
@@ -0,0 +1,383 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 1000
+ 600
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ Nirmala UI
+
+
+
+ Interviews
+
+
+
+ :/logo/logo_icon.png:/logo/logo_icon.png
+
+
+ #Form{
+background-color: qconicalgradient(cx:0.114, cy:0.113318, angle:134.3, stop:0 rgba(214, 28, 30, 255), stop:1 rgba(255, 255, 255, 255));}
+
+
+
+
+ 10
+ 20
+ 981
+ 61
+
+
+
+
+ Nirmala UI
+ 30
+ 75
+ true
+
+
+
+ color: rgb(214, 30, 32);
+
+
+ INTERVIEWS
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ 70
+ 120
+ 101
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ SEARCH
+
+
+
+
+
+ 660
+ 120
+ 271
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ RETURN PREFERENCE MENU
+
+
+
+
+
+ 70
+ 190
+ 301
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ SUBMITTED PROJECTS
+
+
+
+
+
+ 180
+ 120
+ 461
+ 51
+
+
+
+
+ 15
+ true
+
+
+
+ Qt::ClickFocus
+
+
+ border-style:solid;
+border-width:3px;
+border-radius:20px;
+
+color: rgb(104, 104, 104);
+background-color: rgb(255, 255, 255);
+border-color: rgb(220, 63, 65);
+
+
+ Enter the text you want to search for here
+
+
+
+
+
+ 660
+ 190
+ 271
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ EXIT
+
+
+
+
+
+ 390
+ 190
+ 251
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ Qt::LeftToRight
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ RECEIVED PROJECTS
+
+
+
+
+
+ 70
+ 270
+ 861
+ 281
+
+
+
+ background-color:rgb(255, 255, 255)
+
+
+ 283
+
+
+ true
+
+
+
+ Full Name
+
+
+
+ Calibri
+ 9
+ 75
+ true
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ Submission Date
+
+
+
+ Calibri
+ 9
+ 75
+ true
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+ Delivery Date
+
+
+
+ Calibri
+ 9
+ 75
+ true
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CRM/UI_s/Login_Window.ui b/CRM/UI_s/Login_Window.ui
new file mode 100644
index 0000000..7e4cf60
--- /dev/null
+++ b/CRM/UI_s/Login_Window.ui
@@ -0,0 +1,272 @@
+
+
+ Form
+
+
+ true
+
+
+
+ 0
+ 0
+ 1000
+ 600
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ Modern
+ 15
+
+
+
+ Login Window
+
+
+
+ :/logo/logo_icon.png:/logo/logo_icon.png
+
+
+ false
+
+
+ #Form{
+background-color: qconicalgradient(cx:0.114, cy:0.113318, angle:134.3, stop:0 rgba(214, 28, 30, 255), stop:1 rgba(255, 255, 255, 255));}
+
+
+
+
+ 330
+ 250
+ 351
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ true
+
+
+
+ Qt::ClickFocus
+
+
+ Qt::LeftToRight
+
+
+ border-style:solid;
+border-width:3px;
+border-radius:20px;
+border-color: rgb(218, 30, 60);
+color: rgb(104, 104, 104);
+background-color: rgb(255, 255, 255);
+border-color: rgb(220, 63, 65);
+
+
+ Qt::ImhNone
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ false
+
+
+ Enter your username
+
+
+
+
+ true
+
+
+
+ 330
+ 320
+ 351
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ true
+
+
+
+ Qt::ClickFocus
+
+
+ border-style:solid;
+border-width:3px;
+border-radius:20px;
+border-color: rgb(218, 30, 60);
+color: rgb(104, 104, 104);
+background-color: rgb(255, 255, 255);
+border-color: rgb(220, 63, 65);
+
+
+ QLineEdit::Password
+
+
+ Qt::AlignCenter
+
+
+ Enter your password
+
+
+
+
+
+ 530
+ 420
+ 171
+ 71
+
+
+
+
+ Nirmala UI
+ 20
+ 75
+ true
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ EXIT
+
+
+
+
+ true
+
+
+
+ 310
+ 420
+ 171
+ 71
+
+
+
+
+ Nirmala UI
+ 20
+ 75
+ true
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ LOGIN
+
+
+ false
+
+
+
+
+
+ 10
+ 160
+ 981
+ 51
+
+
+
+
+ Nirmala UI
+ 32
+ 75
+ true
+ false
+
+
+
+ false
+
+
+ color: rgb(214, 30, 32);
+
+
+ CRM PROJECT
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ 280
+ 40
+ 431
+ 111
+
+
+
+ image: url(:/logo/logo_butun.png);
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CRM/UI_s/Mentor_Meeting_Page.ui b/CRM/UI_s/Mentor_Meeting_Page.ui
new file mode 100644
index 0000000..8aa5a32
--- /dev/null
+++ b/CRM/UI_s/Mentor_Meeting_Page.ui
@@ -0,0 +1,382 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 1000
+ 600
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ Nirmala UI
+
+
+
+ Mentor Meeting Page
+
+
+
+ :/logo/logo_icon.png:/logo/logo_icon.png
+
+
+ #Form{
+background-color: qconicalgradient(cx:0.114, cy:0.113318, angle:134.3, stop:0 rgba(214, 28, 30, 255), stop:1 rgba(255, 255, 255, 255));}
+
+
+
+
+ 10
+ 20
+ 981
+ 61
+
+
+
+
+ Nirmala UI
+ 30
+ 75
+ true
+
+
+
+ color: rgb(214, 30, 32);
+
+
+ MENTOR MEETING PAGE
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ 70
+ 120
+ 141
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ SEARCH
+
+
+
+
+
+ 670
+ 120
+ 271
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ RETURN PREFERENCE MENU
+
+
+
+
+
+ 70
+ 180
+ 141
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ ALL MEETINGS
+
+
+
+
+
+ 230
+ 120
+ 421
+ 51
+
+
+
+
+ 15
+ true
+
+
+
+ border-style:solid;
+border-width:3px;
+border-radius:20px;
+border-color: rgb(218, 30, 60);
+color: rgb(104, 104, 104);
+background-color: rgb(255, 255, 255);
+border-color: rgb(220, 63, 65);
+
+
+ Enter the text you want to search for here
+
+
+
+
+
+ 670
+ 180
+ 271
+ 51
+
+
+
+
+ Nirmala UI
+ 15
+ 50
+ false
+
+
+
+ Qt::LeftToRight
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ EXIT
+
+
+
+
+
+ 70
+ 250
+ 871
+ 321
+
+
+
+ background-color:rgb(255, 255, 255)
+
+
+ false
+
+
+ 144
+
+
+ 54
+
+
+ true
+
+
+
+ Meeting Date
+
+
+
+
+ Applicant Name
+
+
+
+
+ Mentor Name
+
+
+
+
+ IT Knowledge Level
+
+
+
+
+ Workload Level
+
+
+
+
+ Comments
+
+
+
+
+
+
+ 230
+ 180
+ 421
+ 51
+
+
+
+ QPushButton {
+ font-size: 16px;
+ font-weight: bold;
+ font-family: Arial;
+ color: black; /* Siyah yazı rengi */
+
+ background-color: rgb(255, 255, 255);
+ border-radius: 8px; /* Köşe yuvarlama */
+ padding: 8px; /* Küçük padding */
+ border: none;
+
+ /* Gölgelendirme eklemek için: */
+ box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); /* Gölgenin boyutu ve rengi */
+}
+
+QPushButton:hover {
+ background-color: #c0c0c0; /* Hover durumunda biraz daha koyu gri */
+ /* Hover durumunda gölgeyi değiştirmek için */
+ box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5); /* Hover sırasında daha belirgin gölge */
+}
+
+
+ -
+
+ VIT projesinin tamamına katılması uygun olur
+
+
+ -
+
+ VIT projesi ilk IT eğitimi alıp ITPH a yönlendirilmesi uygun olur
+
+
+ -
+
+ VIT projesi ingilizce eğitimi alıp ITPH a yönlendirilmesi uygun olur
+
+
+ -
+
+ VIT projesi kapsamında direkt ITPH a yönlendirilmesi uygun olur.
+
+
+ -
+
+ Direkt bireysel koçluk ile işe yönlendirilmesi uygun olur
+
+
+ -
+
+ Bir sonraki VIT projesine katilmasi daha uygun olur
+
+
+ -
+
+ Başka bir sektöre yönlendirilmeli
+
+
+ -
+
+ Diger
+
+
+
+
+
+
+
+
+
diff --git a/CRM/UI_s/Preference_Admin_Menu.ui b/CRM/UI_s/Preference_Admin_Menu.ui
new file mode 100644
index 0000000..fe52eff
--- /dev/null
+++ b/CRM/UI_s/Preference_Admin_Menu.ui
@@ -0,0 +1,297 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 1000
+ 600
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ Nirmala UI
+
+
+
+ Preference Admin Menu
+
+
+
+ :/logo/logo_icon.png:/logo/logo_icon.png
+
+
+ #Form{
+background-color: qconicalgradient(cx:0.114, cy:0.113318, angle:134.3, stop:0 rgba(214, 28, 30, 255), stop:1 rgba(255, 255, 255, 255));
+
+}
+
+
+
+
+ 10
+ 20
+ 981
+ 61
+
+
+
+
+ Nirmala UI
+ 30
+ 75
+ true
+
+
+
+ color: rgb(214, 30, 32);
+
+
+ PREFERENCE ADMIN MENU
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ 510
+ 160
+ 341
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ APPLICATIONS
+
+
+
+
+
+ 130
+ 250
+ 341
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ MENTOR MEETING
+
+
+
+
+
+ 130
+ 160
+ 341
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ INTERVIEWS
+
+
+
+
+
+ 130
+ 420
+ 341
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ RETURN MAIN MENU
+
+
+
+
+
+ 700
+ 420
+ 151
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ EXIT
+
+
+
+
+
+ 510
+ 250
+ 341
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ ADMIN MENU
+
+
+
+
+
+
+
+
diff --git a/CRM/UI_s/Preference_Menu.ui b/CRM/UI_s/Preference_Menu.ui
new file mode 100644
index 0000000..ea09aa0
--- /dev/null
+++ b/CRM/UI_s/Preference_Menu.ui
@@ -0,0 +1,259 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 1000
+ 600
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ Nirmala UI
+
+
+
+ Preference Menu
+
+
+
+ :/logo/logo_icon.png:/logo/logo_icon.png
+
+
+ #Form{
+background-color: qconicalgradient(cx:0.114, cy:0.113318, angle:134.3, stop:0 rgba(214, 28, 30, 255), stop:1 rgba(255, 255, 255, 255));}
+
+
+
+
+ 10
+ 20
+ 981
+ 61
+
+
+
+
+ Nirmala UI
+ 30
+ 75
+ true
+
+
+
+ color: rgb(214, 30, 32);
+
+
+ PREFERENCE MENU
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ 510
+ 160
+ 341
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ APPLICATIONS
+
+
+
+
+
+ 130
+ 250
+ 341
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ MENTOR MEETING
+
+
+
+
+
+ 130
+ 160
+ 341
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ INTERVIEWS
+
+
+
+
+
+ 130
+ 420
+ 341
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ RETURN MAIN MENU
+
+
+
+
+
+ 700
+ 420
+ 151
+ 71
+
+
+
+
+ Nirmala UI
+ 18
+ 50
+ false
+
+
+
+ QPushButton{
+ color: rgb(214, 30, 32);
+ background-color: rgb(253, 253, 253);
+}
+
+QPushButton::hover{
+ background-color: rgb(226, 92, 93);
+ color: rgb(255, 255, 255);
+}
+
+QPushButton::pressed{
+ background-color: rgb(216, 37, 39);
+}
+
+
+ EXIT
+
+
+
+
+
+
+
+
diff --git a/CRM/UI_s/Splash_Screen.ui b/CRM/UI_s/Splash_Screen.ui
new file mode 100644
index 0000000..7a98524
--- /dev/null
+++ b/CRM/UI_s/Splash_Screen.ui
@@ -0,0 +1,108 @@
+
+
+ Form
+
+
+ true
+
+
+
+ 0
+ 0
+ 1000
+ 600
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ 1000
+ 600
+
+
+
+
+ Modern
+ 15
+
+
+
+ Login Window
+
+
+
+ :/logo/logo_icon.png:/logo/logo_icon.png
+
+
+ false
+
+
+ #Form{
+background-color: qconicalgradient(cx:0.114, cy:0.113318, angle:134.3, stop:0 rgba(214, 28, 30, 255), stop:1 rgba(255, 255, 255, 255));}
+
+
+
+
+ 10
+ 130
+ 971
+ 250
+
+
+
+ image: url(:/logo/logo_butun.png);
+
+
+
+
+
+ true
+
+
+
+
+
+ 230
+ 460
+ 541
+ 23
+
+
+
+ QProgressBar {
+ background: rgba(255, 255, 255, 0.25); /* Yarı saydam beyaz */
+ border: 1px solid rgba(255, 255, 255, 0.4);
+ border-radius: 10px;
+ text-align: center;
+ color: rgba(255, 255, 255, 0.8);
+ font: bold 10pt "Segoe UI";
+}
+
+QProgressBar::chunk {
+ background-color: rgba(120, 120, 120, 0.85); /* Daha koyu gri dolum */
+ border-radius: 10px;
+ margin: 1px;
+}
+
+
+
+ 24
+
+
+
+
+
+
+
+
diff --git a/CRM/UI_s/ZZZZZZ.txt b/CRM/UI_s/ZZZZZZ.txt
new file mode 100644
index 0000000..6c518b9
--- /dev/null
+++ b/CRM/UI_s/ZZZZZZ.txt
@@ -0,0 +1,15 @@
+pyuic6 -x Splash_Screen.ui -o Splash_Screen.py
+
+pyuic6 -x Admin_Menu.ui -o Admin_Menu.py
+
+pyuic6 -x Applications.ui -o Applications.py
+
+pyuic6 -x Interviews.ui -o Interviews.py
+
+pyuic6 -x Login_Window.ui -o Login_Window.py
+
+pyuic6 -x Mentor_Meeting_Page.ui -o Mentor_Meeting_Page.py
+
+pyuic6 -x Preference_Admin_Menu.ui -o Preference_Admin_Menu.py
+
+pyuic6 -x Preference_Menu.ui -o Preference_Menu.py
diff --git a/CRM/UI_s/logo/logo.qrc b/CRM/UI_s/logo/logo.qrc
new file mode 100644
index 0000000..ac423f8
--- /dev/null
+++ b/CRM/UI_s/logo/logo.qrc
@@ -0,0 +1,6 @@
+
+
+ logo_butun.png
+ logo_icon.png
+
+
diff --git a/CRM/UI_s/logo/logo_butun.png b/CRM/UI_s/logo/logo_butun.png
new file mode 100644
index 0000000..af86ffd
Binary files /dev/null and b/CRM/UI_s/logo/logo_butun.png differ
diff --git a/CRM/UI_s/logo/logo_icon.png b/CRM/UI_s/logo/logo_icon.png
new file mode 100644
index 0000000..0829f07
Binary files /dev/null and b/CRM/UI_s/logo/logo_icon.png differ
diff --git a/CRM/__pycache__/Login_Window.cpython-313.pyc b/CRM/__pycache__/Login_Window.cpython-313.pyc
new file mode 100644
index 0000000..b8380cb
Binary files /dev/null and b/CRM/__pycache__/Login_Window.cpython-313.pyc differ
diff --git a/CRM/__pycache__/Splash_Screen.cpython-313.pyc b/CRM/__pycache__/Splash_Screen.cpython-313.pyc
new file mode 100644
index 0000000..08dcc36
Binary files /dev/null and b/CRM/__pycache__/Splash_Screen.cpython-313.pyc differ
diff --git a/CRM/__pycache__/logo_rc.cpython-313.pyc b/CRM/__pycache__/logo_rc.cpython-313.pyc
new file mode 100644
index 0000000..ea66a08
Binary files /dev/null and b/CRM/__pycache__/logo_rc.cpython-313.pyc differ
diff --git a/CRM/admin_menu_page.py b/CRM/admin_menu_page.py
new file mode 100644
index 0000000..a1c5514
--- /dev/null
+++ b/CRM/admin_menu_page.py
@@ -0,0 +1,211 @@
+
+import os
+import sys
+import smtplib
+from email.mime.text import MIMEText
+import pandas as pd
+
+from PyQt6.uic import loadUi
+from PyQt6.QtCore import Qt
+from PyQt6.QtWidgets import (
+ QApplication,
+ QMessageBox,
+ QTableWidgetItem
+)
+
+try:
+ from main import BaseWindow
+except Exception:
+ from PyQt6.QtWidgets import QWidget as BaseWindow
+
+
+BASE_DIR = os.path.dirname(__file__)
+UI_DIR = os.path.join(BASE_DIR, "UI_s")
+EXCEL_DIR = os.path.join(BASE_DIR, "Excels") # Event.xlsx burada olacak
+
+
+class AdminMenuWindow(BaseWindow):
+ def __init__(self, role="admin"):
+ super().__init__()
+
+ ui_path = os.path.join(UI_DIR, "Admin_Menu.ui")
+
+ try:
+ loadUi(ui_path, self)
+ except Exception as e:
+ QMessageBox.critical(
+ self, "UI Load Error",
+ f"Failed to load UI:\n{ui_path}\n\n{e}"
+ )
+ raise
+
+ self.role = role
+ self.setWindowTitle("Admin Menu")
+ self.setFixedSize(1000, 600)
+ self.setWindowFlag(Qt.WindowType.FramelessWindowHint)
+
+ if hasattr(self, "move_to_last_position"):
+ self.move_to_last_position()
+
+ # --- Button connections ---
+ self.pushButton_EVENT_REGISTRATION.clicked.connect(self.register_event)
+ self.pushButton_SEND_EMAIL.clicked.connect(self.send_email)
+ self.pushButton_Return_TO_ADMIN_PREFERENCE_menu.clicked.connect(self.return_to_admin_pref_menu)
+ self.pushButton_Exit.clicked.connect(self.close)
+
+ self.tableWidget.setColumnCount(4)
+
+
+
+ # 1) Excel (Event.xlsx) → Tabloya yükleme
+
+ def register_event(self):
+ excel_path = os.path.join(EXCEL_DIR, "Event.xlsx")
+
+ if not os.path.exists(excel_path):
+ QMessageBox.warning(self, "Missing File", f"Event.xlsx not found:\n{excel_path}")
+ return
+
+ try:
+ df = pd.read_excel(excel_path)
+
+ required_columns = [
+ "EVENT NAME",
+ "START TIME",
+ "PARTICIPANT E-MAIL",
+ "ORGANIZER E-MAIL"
+ ]
+
+ for col in required_columns:
+ if col not in df.columns:
+ QMessageBox.critical(
+ self,
+ "Column Error",
+ f"Missing column in Event.xlsx:\n'{col}'"
+ )
+ return
+
+ self.tableWidget.setRowCount(0)
+
+ for row_idx, row in df.iterrows():
+ self.tableWidget.insertRow(row_idx)
+ self.tableWidget.setItem(row_idx, 0, QTableWidgetItem(str(row["EVENT NAME"])))
+ self.tableWidget.setItem(row_idx, 1, QTableWidgetItem(str(row["START TIME"])))
+ self.tableWidget.setItem(row_idx, 2, QTableWidgetItem(str(row["PARTICIPANT E-MAIL"])))
+ self.tableWidget.setItem(row_idx, 3, QTableWidgetItem(str(row["ORGANIZER E-MAIL"])))
+
+ except Exception as e:
+ QMessageBox.critical(self, "Excel Error", f"Failed to read Event.xlsx:\n{e}")
+
+
+ # 2-Gerçek Mail Gönderme (Gmail App Password gerekli)
+
+ def send_email(self):
+ rows = self.tableWidget.rowCount()
+
+ if rows == 0:
+ QMessageBox.warning(self, "No Data", "No events loaded.")
+ return
+
+ SMTP_SERVER = "smtp.gmail.com"
+ SMTP_PORT = 587
+
+ # BURAYI KENDİ GMAIL HESABINLA DOLDURACAKSIN
+ SENDER_EMAIL = "your_email@gmail.com"
+ SENDER_PASSWORD = "your_app_password" # Gmail App Password
+
+ if "your_email" in SENDER_EMAIL:
+ QMessageBox.warning(
+ self,
+ "Setup Needed",
+ "Please set your Gmail address and App Password in the code."
+ )
+ return
+
+ try:
+ server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT, timeout=20)
+ server.starttls()
+ server.login(SENDER_EMAIL, SENDER_PASSWORD)
+
+ sent_count = 0
+
+ for r in range(rows):
+ event_name = self._safe(r, 0)
+ participant = self._safe(r, 2)
+ organizer = self._safe(r, 3)
+
+ emails = self._split_emails(participant) + self._split_emails(organizer)
+
+ if not emails:
+ continue
+
+ msg = MIMEText(
+ f"Hello,\n\nThis is a reminder for the event:\n\n"
+ f"{event_name}\n\nBest regards,\nCRM System"
+ )
+ msg["Subject"] = f"Event Reminder – {event_name}"
+ msg["From"] = SENDER_EMAIL
+
+ for email in emails:
+ msg["To"] = email
+ server.sendmail(SENDER_EMAIL, email, msg.as_string())
+ sent_count += 1
+
+ server.quit()
+
+ QMessageBox.information(self, "Success", f"Emails sent: {sent_count}")
+
+ except smtplib.SMTPAuthenticationError:
+ QMessageBox.critical(
+ self,
+ "Authentication Error",
+ "Gmail blocked the login.\n"
+ "You MUST use a Gmail App Password:\n"
+ "Google Account → Security → App Passwords."
+ )
+ except Exception as e:
+ QMessageBox.critical(self, "Email Error", str(e))
+
+
+ def _safe(self, r, c):
+ item = self.tableWidget.item(r, c)
+ return item.text().strip() if item else ""
+
+ def _split_emails(self, text):
+ if not text:
+ return []
+ parts = [p.strip() for p in text.replace(";", ",").split(",")]
+ return [p for p in parts if "@" in p]
+
+
+ # RETURN — Admin Preference Menu’ye geri dön
+ def return_to_admin_pref_menu(self):
+ # 1) Normal durumda: proje main.py'den çalışınca
+ try:
+ from main import PreferenceAdminMenu
+ except ImportError:
+ # 2) Python main.py'yi __main__ olarak çalıştırdıysa burası devreye girer
+ try:
+ from __main__ import PreferenceAdminMenu
+ except ImportError:
+ QMessageBox.warning(
+ self,
+ "Return Error",
+ "Cannot return to previous menu because main module was not found."
+ )
+ return
+ self.new_window = PreferenceAdminMenu(role=self.role) # REFERANS ÖNEMLİ
+ self.new_window.show()
+ self.close()
+
+
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ w = AdminMenuWindow()
+ w.show()
+ sys.exit(app.exec())
+
+
+
diff --git a/CRM/applications_page.py b/CRM/applications_page.py
new file mode 100644
index 0000000..e89c725
--- /dev/null
+++ b/CRM/applications_page.py
@@ -0,0 +1,36 @@
+import os
+from PyQt6.uic import loadUi
+from PyQt6.QtCore import Qt
+from main import BaseWindow
+
+BASE_DIR = os.path.dirname(__file__)
+UI_DIR = os.path.join(BASE_DIR, "UI_s")
+
+class ApplicationsWindow(BaseWindow):
+ def __init__(self, role="admin"):
+ super().__init__()
+ self.role = role
+ loadUi(os.path.join(UI_DIR, "Applications.ui"), self)
+ self.setWindowTitle("Applications")
+ self.setFixedSize(1000, 600)
+ self.move_to_last_position()
+
+ self.pushButton_RETURN_REFERENCE_MENU.clicked.connect(self.return_to_menu)
+ self.pushButton_SEARCH.clicked.connect(self.search_action)
+ self.pushButton_ALL_APPLICATIONS.clicked.connect(self.show_all_applications)
+
+ def return_to_menu(self):
+ from main import PreferenceAdminMenu, PreferenceMenu
+ if self.role.lower() == "admin":
+ self.pref_menu = PreferenceAdminMenu(role=self.role)
+ else:
+ self.pref_menu = PreferenceMenu(role=self.role)
+ self.pref_menu.show()
+ self.close()
+
+ def search_action(self):
+ text = self.lineEdit.text().strip()
+ print(f"Arama yapılıyor: {text}")
+
+ def show_all_applications(self):
+ print("Tüm başvurular listeleniyor...")
\ No newline at end of file
diff --git a/CRM/interviews_page.py b/CRM/interviews_page.py
new file mode 100644
index 0000000..b6f6b9d
--- /dev/null
+++ b/CRM/interviews_page.py
@@ -0,0 +1,190 @@
+# interview_page
+import os
+import pandas as pd
+from PyQt6.uic import loadUi
+from PyQt6.QtCore import Qt
+from PyQt6.QtWidgets import QMessageBox, QTableWidgetItem, QApplication
+from main import BaseWindow
+from PyQt6.QtWidgets import QHeaderView
+
+
+BASE_DIR = os.path.dirname(__file__)
+UI_DIR = os.path.join(BASE_DIR, "UI_s")
+EXCEL_PATH = os.path.join(BASE_DIR, "Excels", "Interviews.xlsx")
+
+
+class InterviewsWindow(BaseWindow):
+ def __init__(self, role="admin"):
+ super().__init__()
+ self.role = role
+ loadUi(os.path.join(UI_DIR, "Interviews.ui"), self)
+ self.setWindowTitle("Interviews")
+ self.setFixedSize(1000, 600)
+ self.setWindowFlag(Qt.WindowType.FramelessWindowHint)
+ self.move_to_last_position()
+ # Tablo başlıkları
+ self.tableWidget.setColumnCount(3)
+ self.tableWidget.setHorizontalHeaderLabels([
+ "Full Name", "Submitted Project", "Received Project"
+])
+ header = self.tableWidget.horizontalHeader()
+ header.setStretchLastSection(True)
+ header.setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
+ header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
+ header.setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
+
+
+ # Excel yükleme ve normalize edilmiş kolon isimleri
+ if os.path.exists(EXCEL_PATH):
+ try:
+ self.df = pd.read_excel(EXCEL_PATH)
+ except Exception as e:
+ QMessageBox.critical(self, "Dosya Hatası", f"Excel okunamadı:\n{e}")
+ self.df = pd.DataFrame()
+ else:
+ QMessageBox.critical(self, "Dosya Hatası", f"Excel dosyası bulunamadı:\n{EXCEL_PATH}")
+ self.df = pd.DataFrame()
+
+
+ self.col_map = {}
+ if not self.df.empty:
+ for c in self.df.columns:
+ self.col_map[c.strip().lower()] = c # map: lowercase -> gerçek sütun adı
+
+ # Olası sütun isimlerini tespit ediliyor (Türkçe ve İngilizce olasılıkları)
+ self.name_col = self._pick_column(["full name", "adınız soyadınız", "adınız soyadınız", "ad soyad", "adiniz soyadiniz"])
+ self.submitted_col = self._pick_column(["submitted project", "proje gonderilis tarihi", "proje gönderiliş tarihi", "project submitted", "submitted"])
+ self.received_col = self._pick_column(["received project", "projenin gelis tarihi", "proje gelis tarihi", "received"])
+
+ # Bağlantılar
+ self.pushButton_Return_REFERENCE_menu.clicked.connect(self.return_to_menu)
+ self.pushButton_EXIT.clicked.connect(self.close)
+ self.pushButton_SEARCH.clicked.connect(self.search_action)
+ self.pushButton_SUBMITTED_PROJECTS.clicked.connect(self.show_submitted_projects)
+ self.pushButton_RECEIVED_PROJECTS.clicked.connect(self.show_received_projects)
+
+
+
+ def _pick_column(self, candidates):
+ """Verilen anahtar listesine göre ilk eşleşen gerçek sütun adını döndürür."""
+ if self.df.empty:
+ return None
+ lower_cols = [c.lower().strip() for c in self.df.columns]
+ for cand in candidates:
+ cand_low = cand.lower().strip()
+ for i, lc in enumerate(lower_cols):
+ # Tam veya içinde eşleşme kabul edelim
+ if cand_low == lc or cand_low in lc or lc in cand_low:
+ return self.df.columns[i]
+ return None
+
+ def fill_table(self, data: pd.DataFrame):
+ # verilen DataFrame'i TableWidget'e yazmak
+ self.tableWidget.setRowCount(0)
+ for row_idx, row in data.reset_index(drop=True).iterrows():
+ self.tableWidget.insertRow(row_idx)
+ # Eğer sütun yoksa boş string koy
+ name_val = row.get(self.name_col, "") if self.name_col in row.index else row.get("Adınız Soyadınız", "")
+ sub_val = row.get(self.submitted_col, "") if self.submitted_col in row.index else row.get("Proje gonderilis tarihi", "")
+ rec_val = row.get(self.received_col, "") if self.received_col in row.index else row.get("Projenin gelis tarihi", "")
+
+ self.tableWidget.setItem(row_idx, 0, QTableWidgetItem("" if pd.isna(name_val) else str(name_val)))
+ self.tableWidget.setItem(row_idx, 1, QTableWidgetItem("" if pd.isna(sub_val) else str(sub_val)))
+ self.tableWidget.setItem(row_idx, 2, QTableWidgetItem("" if pd.isna(rec_val) else str(rec_val)))
+
+
+ def search_action(self):
+ """NAME sütununda BAŞLANGIÇ (startswith) araması yapar, case-insensitive."""
+ if self.name_col is None:
+ QMessageBox.critical(self, "Error", "Name column could not be found in the Excel file.")
+ return
+ text = self.lineEdit.text().strip()
+ if text == "":
+ QMessageBox.information(self, "INFO", "Please enter text to search.")
+ return
+
+ # Case-insensitive, baştan eşleşme. NaN güvenli.
+ series = self.df[self.name_col].astype(str).str.strip()
+ mask = series.str.lower().str.startswith(text.lower(), na=False)
+ filtered = self.df[mask]
+ if filtered.empty:
+ QMessageBox.information(self, "No Results ", f"No names starting with '{text}' were found.")
+
+ else:
+ self.fill_table(filtered)
+
+ def keyPressEvent(self, event):
+ if event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
+ self.search_action()
+
+
+
+
+ def show_submitted_projects(self):
+ # """Displays all candidates who have SUBMITTED a project."""
+ col = self.submitted_col
+ if col is None:
+ for c in self.df.columns:
+ low = c.strip().lower()
+ if "submitted" in low or ("send" in low) or ("gonder" in low):
+ col = c
+ break
+
+ if col is None:
+ QMessageBox.critical(self, "Error", "'Submitted Project' column not found in the Excel file.")
+ return
+
+ mask = self.df[col].notna() & (self.df[col].astype(str).str.strip() != "")
+ submitted = self.df[mask]
+
+ if submitted.empty:
+ QMessageBox.information(self, "Info", "No candidates with submitted projects found.")
+ else:
+ self.fill_table(submitted)
+
+
+
+ def show_received_projects(self):
+ # """Displays all candidates whose projects have been RECEIVED."""
+ col = self.received_col
+ if col is None:
+ for c in self.df.columns:
+ low = c.strip().lower()
+ if "received" in low or "gel" in low or "delivered" in low:
+ col = c
+ break
+
+ if col is None:
+ QMessageBox.critical(self, "Error", "'Received Project' column not found in the Excel file.")
+ return
+
+ mask = self.df[col].notna() & (self.df[col].astype(str).str.strip() != "")
+ received = self.df[mask]
+
+ if received.empty:
+ QMessageBox.information(self, "Info", "No candidates with received projects found.")
+ else:
+ self.fill_table(received)
+
+
+
+
+ def return_to_menu(self):
+ from main import PreferenceAdminMenu, PreferenceMenu
+ if self.role.lower() == "admin":
+ self.pref_menu = PreferenceAdminMenu(role=self.role)
+ else:
+ self.pref_menu = PreferenceMenu(role=self.role)
+ self.pref_menu.show()
+ self.close()
+
+
+# test
+if __name__ == "__main__":
+ import sys
+ app = QApplication(sys.argv)
+ w = InterviewsWindow(role="admin")
+ w.show()
+ sys.exit(app.exec())
+
+
diff --git a/CRM/main.py b/CRM/main.py
new file mode 100644
index 0000000..3563596
--- /dev/null
+++ b/CRM/main.py
@@ -0,0 +1,235 @@
+import sys
+import os
+import pandas as pd
+from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QLabel
+from PyQt6.QtCore import QTimer, Qt
+from PyQt6.QtGui import QPixmap, QIcon
+from PyQt6.uic import loadUi
+
+# Klasör yolları
+BASE_DIR = os.path.dirname(__file__)
+UI_DIR = os.path.join(BASE_DIR, "UI_s")
+IMG_DIR = os.path.join(UI_DIR, "logo")
+EXCEL_DIR = os.path.join(BASE_DIR, "Excels")
+
+# ==== GLOBAL DEĞİŞKEN ==== #
+last_window_pos = None # Son pencere pozisyonunu saklamak için
+
+# ==== BASE WINDOW ==== #
+class BaseWindow(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.oldPos = None
+
+ def mousePressEvent(self, event):
+ if event.button() == Qt.MouseButton.LeftButton:
+ self.oldPos = event.globalPosition().toPoint()
+
+ def mouseMoveEvent(self, event):
+ import main # global değişkeni güncel tutmak için if event.buttons() == Qt.MouseButton.LeftButton:
+ delta = event.globalPosition().toPoint() - self.oldPos
+ self.move(self.x() + delta.x(), self.y() + delta.y())
+ self.oldPos = event.globalPosition().toPoint()
+ main.last_window_pos = self.pos()
+
+ def move_to_last_position(self):
+ import main
+ if main.last_window_pos:
+ self.move(main.last_window_pos)
+ else:
+ # İlk sefer için, mevcut konumu kaydet
+ main.last_window_pos = self.pos()
+
+ self.setWindowIcon(QIcon("UI_s/logo/logo_icon.png"))
+
+
+class SplashScreen(BaseWindow):
+ def __init__(self):
+ super().__init__()
+ splash_ui_path = os.path.join(UI_DIR, "Splash_Screen.ui")
+ loadUi(splash_ui_path, self)
+ self.setWindowTitle("CRM Splash Screen")
+ self.setFixedSize(1000, 600)
+ self.move_to_last_position()
+
+ # Logo yükleme
+ logo_path = os.path.join(IMG_DIR, "logo_butun.png")
+ if os.path.exists(logo_path):
+ self.label_logo.setPixmap(QPixmap(logo_path))
+ self.label_logo.setScaledContents(True)
+
+
+
+ self.counter = 0
+ self.timer = QTimer()
+ self.timer.timeout.connect(self.update_progress)
+ self.timer.start(10)
+
+ def update_progress(self):
+ self.counter += 1
+ self.progressBar.setValue(self.counter)
+ if self.counter >= 100:
+ self.timer.stop()
+ self.show_login()
+
+ def show_login(self):
+ self.login_window = LoginWindow()
+ self.login_window.show()
+ self.close()
+
+
+class LoginWindow(BaseWindow):
+ def __init__(self):
+ super().__init__()
+ login_ui_path = os.path.join(UI_DIR, "Login_Window.ui")
+ loadUi(login_ui_path, self)
+ self.setWindowTitle("CRM Login")
+ self.setFixedSize(1000, 600)
+ self.move_to_last_position()
+
+ # Excel'den kullanıcıları oku
+ users_file = os.path.join(EXCEL_DIR, "users.xlsx")
+ if os.path.exists(users_file):
+ self.users_df = pd.read_excel(users_file)
+ else:
+ print("⚠️ Kullanıcı dosyası bulunamadı:", users_file)
+ self.users_df = pd.DataFrame(columns=["username", "password", "role"])
+
+ # Logo yükleme
+ logo_path = os.path.join(IMG_DIR, "logo_butun.png")
+ if os.path.exists(logo_path) and hasattr(self, "label"):
+ self.label.setPixmap(QPixmap(logo_path))
+ self.label.setScaledContents(True)
+
+ # Buton bağlantıları
+ self.pushButton_Exit.clicked.connect(self.close)
+ self.pushButton_Login.clicked.connect(self.login)
+
+ def login(self):
+ username = self.lineEdit_username.text()
+ password = self.lineEdit_password.text()
+
+ match = self.users_df[
+ (self.users_df['username'] == username) &
+ (self.users_df['password'] == password)
+ ]
+
+ if not match.empty:
+ role = match.iloc[0]['role'].lower()
+ print(f"Giriş başarılı! Rol: {role}")
+ if role == "admin":
+ self.dashboard = PreferenceAdminMenu(role=role)
+ else:
+ self.dashboard = PreferenceMenu(role=role)
+ self.dashboard.show()
+ self.close()
+ else:
+ print("Hatalı kullanıcı adı veya şifre.")
+
+ def keyPressEvent(self, event):
+ if event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
+ self.login()
+
+
+# ==== ADMIN REEFERENCE MENU ==== #
+class PreferenceAdminMenu(BaseWindow):
+ def __init__(self, role="admin"):
+ super().__init__()
+ self.role = role
+ loadUi(os.path.join(UI_DIR, "Preference_Admin_Menu.ui"), self)
+ self.setWindowTitle("Admin Menu")
+ self.setFixedSize(1000, 600)
+ self.move_to_last_position()
+
+ self.pushButton_INTERVIEWS.clicked.connect(self.open_interviews)
+ self.pushButton_APPLICATIONS.clicked.connect(self.open_applications)
+ self.pushButton_Mentor_Meeting.clicked.connect(self.open_mentor_meeting)
+ self.pushButton_ADMIN_MENU.clicked.connect(self.open_admin_settings)
+ self.pushButton_Return_Main_menu.clicked.connect(self.return_to_login)
+ self.pushButton_Exit.clicked.connect(self.close)
+
+ def open_interviews(self):
+ from interviews_page import InterviewsWindow
+ self.interviews_window = InterviewsWindow(role=self.role)
+ self.interviews_window.show()
+ self.close()
+
+ def open_applications(self):
+ from Applications import ApplicationsWindow #applications_page yerine Applications olarak düzelttim
+ self.app_window = ApplicationsWindow(role=self.role)
+ self.app_window.show()
+ self.close()
+
+ def open_mentor_meeting(self):
+ from mentor_meeting_page import MentorMeetingWindow
+ self.mentor_meeting_window = MentorMeetingWindow(role=self.role)
+ self.mentor_meeting_window.show()
+ self.close()
+
+ def open_admin_settings(self):
+ from admin_menu_page import AdminMenuWindow
+ self.admin_menu = AdminMenuWindow(role=self.role)
+ self.admin_menu.show()
+ self.close()
+
+ def return_to_login(self):
+ self.login = LoginWindow()
+ self.login.show()
+ self.close()
+
+
+# ==== USER REEFERENCE MENU ==== #
+class PreferenceMenu(BaseWindow):
+ def __init__(self, role="user"):
+ super().__init__()
+ self.role = role
+ loadUi(os.path.join(UI_DIR, "Preference_Menu.ui"), self)
+ self.setWindowTitle("User Menu")
+ self.setFixedSize(1000, 600)
+ self.move_to_last_position()
+
+ if hasattr(self, "pushButton_INTERVIEWS"):
+ self.pushButton_INTERVIEWS.clicked.connect(self.open_interviews)
+ if hasattr(self, "pushButton_APPLICATIONS"):
+ self.pushButton_APPLICATIONS.clicked.connect(self.open_applications)
+ if hasattr(self, "pushButton_Mentor_Meeting"):
+ self.pushButton_Mentor_Meeting.clicked.connect(self.open_mentor_meeting)
+ if hasattr(self, "pushButton_Return_Main_menu"):
+ self.pushButton_Return_Main_menu.clicked.connect(self.return_to_login)
+ if hasattr(self, "pushButton_Exit"):
+ self.pushButton_Exit.clicked.connect(self.close)
+
+ def open_interviews(self):
+ from interviews_page import InterviewsWindow
+ self.interviews_window = InterviewsWindow(role=self.role)
+ self.interviews_window.show()
+ self.close()
+
+ def open_applications(self):
+ from applications_page import ApplicationsWindow
+ self.app_window = ApplicationsWindow(role=self.role)
+ self.app_window.show()
+ self.close()
+
+ def open_mentor_meeting(self):
+ from mentor_meeting_page import MentorMeetingWindow
+ self.mentor_meeting_window = MentorMeetingWindow(role=self.role)
+ self.mentor_meeting_window.show()
+ self.close()
+
+ def return_to_login(self):
+ self.login = LoginWindow()
+ self.login.show()
+ self.close()
+
+
+# ==== MAIN ==== #
+def main():
+ app = QApplication(sys.argv)
+ splash = SplashScreen()
+ splash.show()
+ sys.exit(app.exec())
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/CRM/mentor_meeting_page.py b/CRM/mentor_meeting_page.py
new file mode 100644
index 0000000..2ac189e
--- /dev/null
+++ b/CRM/mentor_meeting_page.py
@@ -0,0 +1,159 @@
+import os
+import pandas as pd
+from PyQt6.uic import loadUi
+from PyQt6.QtCore import Qt
+from PyQt6.QtWidgets import QTableWidgetItem, QHeaderView
+from main import BaseWindow
+
+BASE_DIR = os.path.dirname(__file__)
+UI_DIR = os.path.join(BASE_DIR, "UI_s")
+EXCEL_DIR = os.path.join(BASE_DIR, "Excels")
+
+class MentorMeetingWindow(BaseWindow):
+ def __init__(self, role="admin"):
+ super().__init__()
+ self.role = role
+ loadUi(os.path.join(UI_DIR, "Mentor_Meeting_Page.ui"), self)
+ self.setWindowTitle("Mentor Meeting Page")
+ self.setFixedSize(1000, 600)
+ self.move_to_last_position()
+
+ header = self.tableWidget.horizontalHeader()
+ header.setSectionResizeMode(QHeaderView.ResizeMode.Fixed)
+ column_widths = [100, 200, 150, 120, 120, 200] # tablo sütun sayısına göre ayarla
+ for col, width in enumerate(column_widths):
+ self.tableWidget.setColumnWidth(col, width)
+
+ # Excel dosyasını yükle
+ self.excel_file = os.path.join(EXCEL_DIR, "Mentor.xlsx")
+ if os.path.exists(self.excel_file):
+ df_full = pd.read_excel(self.excel_file, header=None)
+
+ # İstenmeyen sütunları çıkar: 2., 6., 7.
+ # Pandas sütunları 0-index, yani 2. = 1, 6. = 5, 7. = 6
+ cols_to_use = [0, 2, 3, 4, 7, 5] # 0=Interview Date, 2=Applicant Name, 3=Mentor Name, 4=IT Knowledge Level, 7=Workload Level, 5=Comments
+ self.df = df_full.iloc[:, cols_to_use]
+ self.df.columns = ["Interview Date", "Applicant Name", "Mentor Name",
+ "IT Knowledge Level", "Workload Level", "Comments"]
+ else:
+ self.df = pd.DataFrame(columns=["Interview Date", "Applicant Name", "Mentor Name",
+ "IT Knowledge Level", "Workload Level", "Comments"])
+ print("Mentor Excel file not found!")
+
+ # Buton bağlantıları
+ self.pushButton_Return_REFERENCE_menu.clicked.connect(self.return_to_menu)
+ self.pushButton_EXIT.clicked.connect(self.close)
+ self.pushButton_SEARCH.clicked.connect(self.search_action)
+ self.lineEdit.textChanged.connect(self.search_action) # CANLI ARAMA
+ self.pushButton_ALL_MEETINGS.clicked.connect(self.show_all_records)
+ self.pushButton_ALL_MEETINGS.clicked.connect(self.clear_search_input)
+ self.comboBox.currentTextChanged.connect(self.filter_by_comment)
+ self.comboBox.currentTextChanged.connect(self.clear_search_input)
+
+ # Tablonun başlıklarını ayarla
+ self.tableWidget.setColumnCount(6)
+ self.tableWidget.setHorizontalHeaderLabels(self.df.columns)
+
+ # Tüm kayıtları göster başlangıçta
+ self.show_all_records()
+
+ def clear_search_input(self):
+ self.lineEdit.clear()
+
+ def return_to_menu(self):
+ from main import PreferenceAdminMenu, PreferenceMenu
+ if self.role.lower() == "admin":
+ self.pref_menu = PreferenceAdminMenu(role=self.role)
+ else:
+ self.pref_menu = PreferenceMenu(role=self.role)
+ self.pref_menu.show()
+ self.close()
+
+ def filter_by_comment(self, text):
+ """ComboBox seçimine göre Comments sütununu filtrele."""
+ try:
+ if 'Comments' not in self.df.columns:
+ print("'Comments' sütunu bulunamadı.")
+ return
+
+ if text == "" or text == "All":
+ # Seçim yoksa tüm veriyi göster
+ self.display_data(self.df)
+ return
+
+ filtered_df = self.df[self.df['Comments'] == text].reset_index(drop=True)
+ self.display_data(filtered_df)
+ print(f"ComboBox filtreleme: '{text}' seçildi, {len(filtered_df)} kayıt bulundu.")
+ except Exception as e:
+ print(f"filter_by_comment Hatası: {e}")
+
+ def show_all_records(self):
+ self.populate_table(self.df)
+
+ def display_data(self, df):
+ """DataFrame'i Mentor Meeting tablosuna yazdırır."""
+ try:
+ self.tableWidget.clearContents()
+ self.tableWidget.setRowCount(0)
+
+ if df is None or df.empty:
+ print("Gösterilecek kayıt yok veya DataFrame boş.")
+ return
+
+ # Tablonun sütun sayısını ayarla
+ self.tableWidget.setRowCount(len(df))
+ self.tableWidget.setColumnCount(len(df.columns))
+ self.tableWidget.setHorizontalHeaderLabels(df.columns.tolist())
+
+ for row_idx, row in df.iterrows():
+ for col_idx, value in enumerate(row):
+ item = QTableWidgetItem(str(value))
+ item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.tableWidget.setItem(row_idx, col_idx, item)
+
+ print(f"{len(df)} kayıt tabloya yüklendi.\n")
+
+ except Exception as e:
+ print(f"display_data() Hatası: {e}")
+
+
+ def search_action(self):
+ """Search by Applicant or Mentor Name, display all if empty"""
+ try:
+ search_text = self.lineEdit.text().strip().lower()
+ if not search_text:
+ self.show_all_records()
+ return
+
+ df_clean = self.df.copy()
+ df_clean['Applicant Name'] = df_clean['Applicant Name'].astype(str).str.lower().str.strip()
+ df_clean['Mentor Name'] = df_clean['Mentor Name'].astype(str).str.lower().str.strip()
+
+ mask = df_clean['Applicant Name'].apply(lambda x: search_text in x) | \
+ df_clean['Mentor Name'].apply(lambda x: search_text in x)
+
+ filtered_df = df_clean[mask].reset_index(drop=True)
+ self.populate_table(filtered_df)
+
+
+ except Exception as e:
+ print(f"Search Error: {e}")
+
+
+ def populate_table(self, df_to_show):
+ self.tableWidget.setRowCount(len(df_to_show))
+ for row_idx, row in df_to_show.iterrows():
+ for col_idx, value in enumerate(row):
+ item = QTableWidgetItem(str(value))
+ self.tableWidget.setItem(row_idx, col_idx, item)
+ self.tableWidget.resizeColumnsToContents()
+
+
+if __name__ == "__main__":
+ import sys
+ from PyQt6.QtWidgets import QApplication
+
+ app = QApplication(sys.argv)
+ window = MentorMeetingWindow(role="admin")
+ window.show()
+ sys.exit(app.exec())
diff --git a/interviews_page.py b/interviews_page.py
new file mode 100644
index 0000000..dace925
--- /dev/null
+++ b/interviews_page.py
@@ -0,0 +1,163 @@
+
+import os
+import pandas as pd
+from PyQt6.uic import loadUi
+from PyQt6.QtCore import Qt
+from PyQt6.QtWidgets import QMessageBox, QTableWidgetItem, QApplication
+from main import BaseWindow
+
+BASE_DIR = os.path.dirname(__file__)
+UI_DIR = os.path.join(BASE_DIR, "UI_s")
+EXCEL_PATH = os.path.join(BASE_DIR, "Excels", "Interviews.xlsx")
+
+
+class InterviewsWindow(BaseWindow):
+ def __init__(self, role="admin"):
+ super().__init__()
+ self.role = role
+ loadUi(os.path.join(UI_DIR, "Interviews.ui"), self)
+ self.setWindowTitle("Interviews")
+ self.setFixedSize(1000, 600)
+ self.setWindowFlag(Qt.WindowType.FramelessWindowHint)
+ self.move_to_last_position()
+
+ # Excel yükleme ve normalize edilmiş kolon isimleri
+ if os.path.exists(EXCEL_PATH):
+ try:
+ self.df = pd.read_excel(EXCEL_PATH)
+ except Exception as e:
+ QMessageBox.critical(self, "Dosya Hatası", f"Excel okunamadı:\n{e}")
+ self.df = pd.DataFrame()
+ else:
+ QMessageBox.critical(self, "Dosya Hatası", f"Excel dosyası bulunamadı:\n{EXCEL_PATH}")
+ self.df = pd.DataFrame()
+
+ # Normalize: ayrıca indekslenmiş küçük harfli isimlere erişim için bir yardımcı dict oluştur
+ # (orijinal sütun adlarını koruyoruz ancak lowercase anahtarlarla arama yapacağız)
+ self.col_map = {}
+ if not self.df.empty:
+ for c in self.df.columns:
+ self.col_map[c.strip().lower()] = c # map: lowercase -> gerçek sütun adı
+
+ # Olası sütun isimlerini tespit et (Türkçe ve İngilizce olasılıkları)
+ self.name_col = self._pick_column(["full name", "adınız soyadınız", "adınız soyadınız", "ad soyad", "adiniz soyadiniz"])
+ self.submitted_col = self._pick_column(["submitted project", "proje gonderilis tarihi", "proje gönderiliş tarihi", "project submitted", "submitted"])
+ self.received_col = self._pick_column(["received project", "projenin gelis tarihi", "proje gelis tarihi", "received"])
+
+ # Bağlantılar
+ self.pushButton_Return_REFERENCE_menu.clicked.connect(self.return_to_menu)
+ self.pushButton_EXIT.clicked.connect(self.close)
+ self.pushButton_SEARCH.clicked.connect(self.search_action)
+ self.pushButton_SUBMITTED_PROJECTS.clicked.connect(self.show_submitted_projects)
+ self.pushButton_RECEIVED_PROJECTS.clicked.connect(self.show_received_projects)
+
+ # Tablo başlıkları (UI'da Türkçe görünmesini istersen burayı bırak)
+ self.tableWidget.setColumnCount(3)
+ self.tableWidget.setHorizontalHeaderLabels([
+ "Adı Soyadı", "Proje Gönderiliş Tarihi", "Proje Geliş Tarihi"
+ ])
+
+
+ def _pick_column(self, candidates):
+ """Verilen anahtar listesine göre ilk eşleşen gerçek sütun adını döndürür."""
+ if self.df.empty:
+ return None
+ lower_cols = [c.lower().strip() for c in self.df.columns]
+ for cand in candidates:
+ cand_low = cand.lower().strip()
+ for i, lc in enumerate(lower_cols):
+ # Tam veya içinde eşleşme kabul edelim
+ if cand_low == lc or cand_low in lc or lc in cand_low:
+ return self.df.columns[i]
+ return None
+
+ def fill_table(self, data: pd.DataFrame):
+ """Tabloyu verilen DataFrame'e göre doldurur (görsel Türkçe başlıklar)."""
+ self.tableWidget.setRowCount(0)
+ for row_idx, row in data.reset_index(drop=True).iterrows():
+ self.tableWidget.insertRow(row_idx)
+ # Eğer sütun yoksa boş string koy
+ name_val = row.get(self.name_col, "") if self.name_col in row.index else row.get("Adınız Soyadınız", "")
+ sub_val = row.get(self.submitted_col, "") if self.submitted_col in row.index else row.get("Proje gonderilis tarihi", "")
+ rec_val = row.get(self.received_col, "") if self.received_col in row.index else row.get("Projenin gelis tarihi", "")
+
+ self.tableWidget.setItem(row_idx, 0, QTableWidgetItem("" if pd.isna(name_val) else str(name_val)))
+ self.tableWidget.setItem(row_idx, 1, QTableWidgetItem("" if pd.isna(sub_val) else str(sub_val)))
+ self.tableWidget.setItem(row_idx, 2, QTableWidgetItem("" if pd.isna(rec_val) else str(rec_val)))
+ self.tableWidget.resizeColumnsToContents()
+
+ def search_action(self):
+ """NAME sütununda BAŞLANGIÇ (startswith) araması yapar, case-insensitive."""
+ if self.name_col is None:
+ QMessageBox.critical(self, "Hata", "Ad/Soyad sütunu bulunamadı (Excel).")
+ return
+ text = self.lineEdit.text().strip()
+ if text == "":
+ QMessageBox.information(self, "Bilgi", "Lütfen arama kutusuna bir metin girin.")
+ return
+
+ # Case-insensitive, baştan eşleşme. NaN güvenli.
+ series = self.df[self.name_col].astype(str).str.strip()
+ mask = series.str.lower().str.startswith(text.lower(), na=False)
+ filtered = self.df[mask]
+ if filtered.empty:
+ QMessageBox.information(self, "Sonuç Yok", f"'{text}' ile başlayan isim bulunamadı.")
+ # istersen tümünü gösterme, şu an sadece uyarı
+ else:
+ self.fill_table(filtered)
+
+
+ def show_submitted_projects(self):
+ # """Projesini göndermiş adayları göster."""
+ # Sütun adlarını normalize et (boşlukları ve büyük harfleri temizle)
+ self.df.columns = [col.strip().upper() for col in self.df.columns]
+
+ if "SUBMITTED PROJECT" not in self.df.columns:
+ QMessageBox.critical(self, "Hata", "'SUBMITTED PROJECT' sütunu Excel dosyasında bulunamadı.")
+ return
+
+ # Boş olmayan satırları filtrele
+ submitted = self.df[self.df["SUBMITTED PROJECT"].notna() & (self.df["SUBMITTED PROJECT"].astype(str).str.strip() != "")]
+
+ if submitted.empty:
+ QMessageBox.information(self, "Bilgi", "Proje göndermiş aday bulunamadı.")
+ else:
+ self.fill_table(submitted)
+
+
+
+ def show_received_projects(self):
+ # """Projesi GELMİŞ adayları göster."""
+ if self.received_col is None:
+ QMessageBox.critical(self, "Hata", "Received (geliş) sütunu bulunamadı.")
+ return
+
+ r = self.df[self.received_col]
+ mask = r.notna() & (r.astype(str).str.strip() != "")
+ res = self.df[mask]
+ if res.empty:
+ QMessageBox.information(self, "Bilgi", "Projesi gelmiş aday bulunamadı.")
+ else:
+ self.fill_table(res)
+
+
+
+
+ def return_to_menu(self):
+ from main import PreferenceAdminMenu, PreferenceMenu
+ if self.role.lower() == "admin":
+ self.pref_menu = PreferenceAdminMenu(role=self.role)
+ else:
+ self.pref_menu = PreferenceMenu(role=self.role)
+ self.pref_menu.show()
+ self.close()
+
+
+# standalone test
+if __name__ == "__main__":
+ import sys
+ app = QApplication(sys.argv)
+ w = InterviewsWindow(role="admin")
+ w.show()
+ sys.exit(app.exec())
+