diff --git a/backend/__pycache__/admin_preference_menu.cpython-313.pyc b/backend/__pycache__/admin_preference_menu.cpython-313.pyc new file mode 100644 index 0000000..e3d55ae Binary files /dev/null and b/backend/__pycache__/admin_preference_menu.cpython-313.pyc differ diff --git a/backend/__pycache__/adminmenu.cpython-313.pyc b/backend/__pycache__/adminmenu.cpython-313.pyc new file mode 100644 index 0000000..9bcc7f8 Binary files /dev/null and b/backend/__pycache__/adminmenu.cpython-313.pyc differ diff --git a/backend/__pycache__/applications_menu.cpython-313.pyc b/backend/__pycache__/applications_menu.cpython-313.pyc new file mode 100644 index 0000000..103bdaa Binary files /dev/null and b/backend/__pycache__/applications_menu.cpython-313.pyc differ diff --git a/backend/__pycache__/interviews_menu.cpython-313.pyc b/backend/__pycache__/interviews_menu.cpython-313.pyc new file mode 100644 index 0000000..2f252de Binary files /dev/null and b/backend/__pycache__/interviews_menu.cpython-313.pyc differ diff --git a/backend/__pycache__/mentor_menu.cpython-313.pyc b/backend/__pycache__/mentor_menu.cpython-313.pyc new file mode 100644 index 0000000..ab22393 Binary files /dev/null and b/backend/__pycache__/mentor_menu.cpython-313.pyc differ diff --git a/backend/__pycache__/preference_menu.cpython-313.pyc b/backend/__pycache__/preference_menu.cpython-313.pyc new file mode 100644 index 0000000..03a0cb6 Binary files /dev/null and b/backend/__pycache__/preference_menu.cpython-313.pyc differ diff --git a/backend/__pycache__/utils.cpython-313.pyc b/backend/__pycache__/utils.cpython-313.pyc new file mode 100644 index 0000000..df64df9 Binary files /dev/null and b/backend/__pycache__/utils.cpython-313.pyc differ diff --git a/backend/admin_preference_menu.py b/backend/admin_preference_menu.py new file mode 100644 index 0000000..0ffeba4 --- /dev/null +++ b/backend/admin_preference_menu.py @@ -0,0 +1,45 @@ +from PyQt6 import QtWidgets, uic +from applications_menu import ApplicationsWindow +from interviews_menu import InterviewsMenuWindow +from mentor_menu import MentorMeetingWindow +from adminmenu import AdminMenuWindow + +class AdminPreferenceMenuWindow(QtWidgets.QMainWindow): + def __init__(self): + super().__init__() + uic.loadUi("ui/admin_preference_menu.ui", self) + self.pushButton_mentorinterview.clicked.connect(self.open_mentor_interviews_window) + self.pushButton_applications.clicked.connect(self.open_applications_window) + self.pushButton_interviews.clicked.connect(self.open_interviews_window) + self.pushButton_adminmenu.clicked.connect(self.open_admin_menu_window) + self.pushButton_exit.clicked.connect(self.close) + + def open_mentor_interviews_window(self): + self.interviews_window = MentorMeetingWindow(parent=self) + self.interviews_window.show() + self.hide() + + def open_applications_window(self): + self.applications_window = ApplicationsWindow(parent=self) + self.applications_window.show() + self.hide() + + def open_interviews_window(self): + self.interviews_window = InterviewsMenuWindow(parent=self) + self.interviews_window.show() + self.hide() + + def open_admin_menu_window(self): + self.admin_menu_window = AdminMenuWindow(parent=self) + self.admin_menu_window.show() + self.hide() + + + +# Test amaçlı çalıştırmak için: +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + window = AdminPreferenceMenuWindow() + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/backend/adminmenu.py b/backend/adminmenu.py new file mode 100644 index 0000000..95fa93e --- /dev/null +++ b/backend/adminmenu.py @@ -0,0 +1,126 @@ +from PyQt6 import QtWidgets, uic +from googleapiclient.discovery import build +from google.oauth2.credentials import Credentials +from google.auth.transport.requests import Request +from dotenv import load_dotenv # .env dosyasını okumak için +import os +import datetime +import smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart + +# .env dosyasını yükle +load_dotenv() + +SCOPES = [ + 'https://www.googleapis.com/auth/calendar.readonly', + 'https://www.googleapis.com/auth/drive.readonly' +] +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +CREDENTIALS_PATH = os.path.join(BASE_DIR, "../credentials.json") +TOKEN_PATH = os.path.join(BASE_DIR, "../token.json") + +class AdminMenuWindow(QtWidgets.QMainWindow): + def __init__(self, parent=None): + super().__init__() + self.parent_menu = parent + uic.loadUi("ui/admin_menu.ui", self) + self.pushButton_preference_admin_menu.clicked.connect(self.back_to_admin_preference_menu) + self.pushButton_activity_control.clicked.connect(self.load_activities_to_table) + self.pushButton_sendmail.clicked.connect(self.send_emails_to_participants) + self.pushButton_exit.clicked.connect(QtWidgets.QApplication.quit) + + def back_to_admin_preference_menu(self): + if self.parent_menu is not None: + self.parent_menu.show() + self.close() + + def get_calendar_service(self): + creds = None + if os.path.exists(TOKEN_PATH): + creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES) + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + from google_auth_oauthlib.flow import InstalledAppFlow + flow = InstalledAppFlow.from_client_secrets_file(CREDENTIALS_PATH, SCOPES) + creds = flow.run_local_server(port=0) + with open(TOKEN_PATH, "w") as token: + token.write(creds.to_json()) + return build('calendar', 'v3', credentials=creds) + + def load_activities_to_table(self): + service = self.get_calendar_service() + now = datetime.datetime.utcnow().isoformat() + 'Z' + events_result = service.events().list( + calendarId='primary', timeMin=now, + maxResults=20, singleEvents=True, + orderBy='startTime').execute() + events = events_result.get('items', []) + + table = self.tableWidget_admin_menu_dashboard + table.setRowCount(len(events)) + table.setColumnCount(4) + table.setHorizontalHeaderLabels(["Event Name", "Start Time", "Organizer Email", "Participants"]) + + for row, event in enumerate(events): + event_name = event.get('summary', 'No Title') + start_time = event['start'].get('dateTime', event['start'].get('date', '')) + organizer_email = event.get('organizer', {}).get('email', '') + participants = [att.get('email', '') for att in event.get('attendees', [])] if 'attendees' in event else [] + participants_str = ", ".join(participants) + + table.setItem(row, 0, QtWidgets.QTableWidgetItem(event_name)) + table.setItem(row, 1, QtWidgets.QTableWidgetItem(start_time)) + table.setItem(row, 2, QtWidgets.QTableWidgetItem(organizer_email)) + table.setItem(row, 3, QtWidgets.QTableWidgetItem(participants_str)) + + def send_emails_to_participants(self): + service = self.get_calendar_service() + now = datetime.datetime.utcnow().isoformat() + 'Z' + events_result = service.events().list( + calendarId='primary', timeMin=now, + maxResults=20, singleEvents=True, + orderBy='startTime').execute() + events = events_result.get('items', []) + + sender_email = "vit7team2crmproject@gmail.com" + # .env dosyasından şifreyi oku + sender_password = os.environ.get("CRM_GMAIL_APP_PASSWORD") + + if not sender_password: + QtWidgets.QMessageBox.critical(self, "Hata", "Mail gönderimi için uygulama şifresi bulunamadı!") + return + + for event in events: + event_name = event.get('summary', 'No Title') + start_time = event['start'].get('dateTime', event['start'].get('date', '')) + participants = [att.get('email', '') for att in event.get('attendees', [])] if 'attendees' in event else [] + + for recipient in participants: + msg = MIMEMultipart() + msg['From'] = sender_email + msg['To'] = recipient + msg['Subject'] = f"Etkinlik Daveti: {event_name}" + + body = f"Merhaba,\n\n{event_name} etkinliğine davetlisiniz.\nBaşlangıç Zamanı: {start_time}\n\nİyi günler!" + msg.attach(MIMEText(body, 'plain')) + + try: + with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server: + server.login(sender_email, sender_password) + server.sendmail(sender_email, recipient, msg.as_string()) + print(f"Mail gönderildi: {recipient}") + except Exception as e: + print(f"Mail gönderilemedi: {recipient}, Hata: {e}") + + QtWidgets.QMessageBox.information(self, "Bilgi", "Tüm katılımcılara mail gönderimi tamamlandı.") + +# Test amaçlı çalıştırmak için: +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + window = AdminMenuWindow() + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/backend/applications_menu.py b/backend/applications_menu.py new file mode 100644 index 0000000..c891a99 --- /dev/null +++ b/backend/applications_menu.py @@ -0,0 +1,111 @@ +from PyQt6 import QtWidgets, uic +import pandas as pd +from utils import get_engine + +class ApplicationsWindow(QtWidgets.QMainWindow): + def __init__(self, parent=None): + super().__init__(parent) + self.parent_menu = parent + uic.loadUi("ui/applications_menu.ui", self) + self.df = None + self.load_table_data() + self.lineEdit_search.textChanged.connect(self.filter_table) + self.pushButton_all_applications.clicked.connect(self.load_table_data) + self.pushButton_planned_mentor_meetings.clicked.connect(self.planned_mentor_meetings) + self.pushButton_unscheduled_mentor_meetings.clicked.connect(self.unscheduled_mentor_meetings) + self.pushButton_repeted_registeration.clicked.connect(self.repeated_registration) + self.pushButton_dif_registeration.clicked.connect(self.different_registration) + self.pushButton_filter_application.clicked.connect(self.filter_applications) + self.pushButton_BackMenu.clicked.connect(self.back_to_menu) + self.pushButton_exit.clicked.connect(self.close) + + def get_base_query(self): + return """ + SELECT + b."ZamanDamgasi" AS "Date", + k."AdSoyad" AS "Name Surname", + k."MailAdresi" AS "Mail", + k."TelefonNumarasi" AS "Telephone", + k."PostaKodu" AS "Post Code", + k."YasadiginizEyalet" AS "State", + b."EkonomikDurum" AS "Economical Situation" + FROM basvurular b + LEFT JOIN kursiyerler k + ON b."KursiyerID" = k."KursiyerID" + """ + + def load_table_data(self): + try: + engine = get_engine() + query = self.get_base_query() + self.df = pd.read_sql(query, engine) + self.show_table(self.df) + except Exception as e: + QtWidgets.QMessageBox.critical(self, "Hata", f"Veri yüklenemedi: {e}") + + def show_table(self, df): + self.tableWidget_application_dashboard.setRowCount(len(df)) + self.tableWidget_application_dashboard.setColumnCount(len(df.columns) - 2) # Son iki sütun filtre için + self.tableWidget_application_dashboard.setHorizontalHeaderLabels( + ["Date", "Name Surname", "Mail", "Telephone", "Post Code", "State", "Economical Situation"] + ) + for row in range(len(df)): + for col in range(7): # Sadece ilk 7 sütunu göster + value = str(df.iloc[row, col]) + self.tableWidget_application_dashboard.setItem(row, col, QtWidgets.QTableWidgetItem(value)) + + def filter_table(self): + if self.df is None: + return + search_text = self.lineEdit_search.text().lower() + if search_text == "": + filtered_df = self.df + else: + filtered_df = self.df[self.df['Name Surname'].str.lower().str.contains(search_text)] + self.show_table(filtered_df) + + def planned_mentor_meetings(self): + if self.df is None: + self.load_table_data() + filtered = self.df[self.df["MentorGorusmesi"] == "OK"] + self.show_table(filtered) + + def unscheduled_mentor_meetings(self): + if self.df is None: + self.load_table_data() + filtered = self.df[self.df["MentorGorusmesi"] != "OK"] + self.show_table(filtered) + + def repeated_registration(self): + if self.df is None: + self.load_table_data() + filtered = self.df[self.df.duplicated(subset=["Name Surname", "Mail"], keep=False)] + self.show_table(filtered) + + def different_registration(self): + if self.df is None: + self.load_table_data() + # Farklı kayıtlar: Aynı isim ve mail başka bir yerde yoksa + merged = self.df.groupby(["Name Surname", "Mail"]).size().reset_index(name='counts') + unique = merged[merged['counts'] == 1] + filtered = self.df.set_index(["Name Surname", "Mail"]).loc[unique.set_index(["Name Surname", "Mail"]).index].reset_index() + self.show_table(filtered) + + def filter_applications(self): + if self.df is None: + self.load_table_data() + filtered = self.df.drop_duplicates(subset=["Name Surname", "Mail"]) + self.show_table(filtered) + + def back_to_menu(self): + if self.parent_menu is not None: + self.parent_menu.show() + self.close() + +# Test amaçlı çalıştırmak için: +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + window = ApplicationsWindow() + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/backend/auth.py b/backend/auth.py new file mode 100644 index 0000000..a737cb3 --- /dev/null +++ b/backend/auth.py @@ -0,0 +1,63 @@ +import os.path + +from google.auth.transport.requests import Request +from google.oauth2.credentials import Credentials +from google_auth_oauthlib.flow import InstalledAppFlow +from googleapiclient.discovery import build +from googleapiclient.errors import HttpError + +# If modifying these scopes, delete the file token.json. +SCOPES = [ + 'https://www.googleapis.com/auth/calendar.readonly', + 'https://www.googleapis.com/auth/drive.readonly' +] +CREDENTIALS_PATH = "../credentials.json" +TOKEN_PATH = "../token.json" + +def main(): + """Shows basic usage of the Drive v3 API. + Prints the names and ids of the first 10 files the user has access to. + """ + creds = None + # The file token.json stores the user's access and refresh tokens, and is + # created automatically when the authorization flow completes for the first + # time. + if os.path.exists(TOKEN_PATH): + creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES) + # If there are no (valid) credentials available, let the user log in. + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + flow = InstalledAppFlow.from_client_secrets_file( + CREDENTIALS_PATH, SCOPES + ) + creds = flow.run_local_server(port=0) + # Save the credentials for the next run + with open(TOKEN_PATH, "w") as token: + token.write(creds.to_json()) + + try: + service = build("drive", "v3", credentials=creds) + + # Call the Drive v3 API + results = ( + service.files() + .list(pageSize=10, fields="nextPageToken, files(id, name)") + .execute() + ) + items = results.get("files", []) + + if not items: + print("No files found.") + return + print("Files:") + for item in items: + print(f"{item['name']} ({item['id']})") + except HttpError as error: + # TODO(developer) - Handle errors from drive API. + print(f"An error occurred: {error}") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/backend/interviews_menu.py b/backend/interviews_menu.py new file mode 100644 index 0000000..276ae6b --- /dev/null +++ b/backend/interviews_menu.py @@ -0,0 +1,80 @@ +from PyQt6 import QtWidgets, uic +import pandas as pd +from utils import get_engine + +class InterviewsMenuWindow(QtWidgets.QMainWindow): + def __init__(self, parent=None): + super().__init__(parent) + self.parent_menu = parent + uic.loadUi("ui/interviews_menu.ui", self) + self.df = None + self.load_table_data() + self.lineEdit_search.textChanged.connect(self.filter_table) + self.pushButton_all_submitted_projects.clicked.connect(self.show_submitted_projects) + self.pushButton_project_arrivals.clicked.connect(self.show_project_arrivals) + self.pushButton_BackMenu.clicked.connect(self.back_to_menu) + self.pushButton_exit.clicked.connect(self.close) + + def get_base_query(self): + return """ + SELECT + k."AdSoyad" AS "Name Surname", + p."ProjeGonderilisTarihi" AS "Project Sending Date", + p."ProjeninGelisTarihi" AS "Project Arrival Date" + FROM projetakip p + LEFT JOIN kursiyerler k + ON p."KursiyerID" = k."KursiyerID" + """ + + def load_table_data(self): + try: + engine = get_engine() + query = self.get_base_query() + self.df = pd.read_sql(query, engine) + self.show_table(self.df) + except Exception as e: + QtWidgets.QMessageBox.critical(self, "Hata", f"Veri yüklenemedi: {e}") + + def show_table(self, df): + self.tableWidget.setRowCount(len(df)) + self.tableWidget.setColumnCount(len(df.columns)) + self.tableWidget.setHorizontalHeaderLabels(df.columns) + for row in range(len(df)): + for col in range(len(df.columns)): + value = str(df.iloc[row, col]) + self.tableWidget.setItem(row, col, QtWidgets.QTableWidgetItem(value)) + + def filter_table(self): + if self.df is None: + return + search_text = self.lineEdit_search.text().lower() + if search_text == "": + filtered_df = self.df + else: + filtered_df = self.df[self.df['Name Surname'].str.lower().str.contains(search_text)] + self.show_table(filtered_df) + + def show_submitted_projects(self): + if self.df is None: + self.load_table_data() + filtered = self.df[self.df["Project Sending Date"].notnull()] + self.show_table(filtered) + + def show_project_arrivals(self): + if self.df is None: + self.load_table_data() + filtered = self.df[self.df["Project Arrival Date"].notnull()] + self.show_table(filtered) + + def back_to_menu(self): + if self.parent_menu is not None: + self.parent_menu.show() + self.close() + +# Test amaçlı çalıştırmak için: +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + window = InterviewsMenuWindow() + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/backend/login.py b/backend/login.py new file mode 100644 index 0000000..cfb354c --- /dev/null +++ b/backend/login.py @@ -0,0 +1,52 @@ +import sys +from PyQt6 import QtWidgets, uic +from preference_menu import PreferenceMenuWindow +from admin_preference_menu import AdminPreferenceMenuWindow +from utils import get_engine +import pandas as pd + +class LoginWindow(QtWidgets.QDialog): + def __init__(self): + super().__init__() + uic.loadUi("ui/login.ui", self) + self.pushButton_login.clicked.connect(self.handle_login) # Giriş butonu + self.pushButton_exit.clicked.connect(QtWidgets.QApplication.quit) # Exit butonu + self.label_status.setText("") # Uyarı etiketi + + def handle_login(self): + username = self.lineEdit_username.text().strip() + password = self.lineEdit_password.text().strip() + try: + engine = get_engine() + df = pd.read_sql("SELECT * FROM kullanicilar", engine) + df = df.apply(lambda col: col.map(lambda x: x.strip() if isinstance(x, str) else x)) + user = df[(df['KullaniciAdi'] == username) & (df['Parola'] == password)] + if not user.empty: + yetki = user.iloc[0]['Yetki'] + self.label_status.setText("Giriş başarılı!") + if yetki == "admin": + self.open_admin_menu() + elif yetki == "user": + self.open_user_menu() + else: + self.label_status.setText("Yetki tanımsız!") + else: + self.label_status.setText("Kullanıcı adı veya şifre yanlış!") + except Exception as e: + self.label_status.setText(f"Hata: {e}") + + def open_admin_menu(self): + self.admin_menu = AdminPreferenceMenuWindow() + self.admin_menu.show() + self.close() + + def open_user_menu(self): + self.user_menu = PreferenceMenuWindow() + self.user_menu.show() + self.close() + +if __name__ == "__main__": + app = QtWidgets.QApplication(sys.argv) + window = LoginWindow() + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/backend/mentor_menu.py b/backend/mentor_menu.py new file mode 100644 index 0000000..547e919 --- /dev/null +++ b/backend/mentor_menu.py @@ -0,0 +1,98 @@ +from PyQt6 import QtWidgets, uic +import pandas as pd +from utils import get_engine + +class MentorMeetingWindow(QtWidgets.QMainWindow): + def __init__(self, parent=None): + super().__init__(parent) + self.parent_menu = parent + uic.loadUi("ui/mentor_menu.ui", self) + self.df = None + self.load_table_data() + self.pushButton_AllApplication.clicked.connect(self.show_applications) + self.pushButton_search.clicked.connect(self.search_applications) + self.comboBox_secenekler.currentIndexChanged.connect(self.listComboBoxChanged) + self.pushButton_backmenu.clicked.connect(self.back_to_menu) + self.pushButton_exit.clicked.connect(self.close) + self.comboBox_secenekler.addItems([ + "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" + ]) + self.comboBox_secenekler.setCurrentIndex(0) + self.comboBox_secenekler.setEditable(True) + self.comboBox_secenekler.lineEdit().setPlaceholderText("Sonuç Seçiniz") + self.comboBox_secenekler.lineEdit().setReadOnly(False) + + def get_base_query(self): + return """ + SELECT + m."GorusmeTarihi" AS "Date", + b."BasvuruDonemi" AS "Group", + k."AdSoyad" AS "Full Name", + m."Mentoradsoyad" AS "Mentor", + m."VITProjesineKatilabilirMi" AS "Mentor Advice", + m."Dusunce" AS "Note" + FROM mentorgorusme m + LEFT JOIN kursiyerler k ON m."KursiyerID" = k."KursiyerID" + LEFT JOIN basvurular b ON m."KursiyerID" = b."KursiyerID" + """ + + def load_table_data(self): + try: + engine = get_engine() + query = self.get_base_query() + self.df = pd.read_sql(query, engine) + self.show_table(self.df) + except Exception as e: + QtWidgets.QMessageBox.critical(self, "Hata", f"Veri yüklenemedi: {e}") + + def show_table(self, df): + self.tableWidget_mentor_menu_dashboard.setRowCount(len(df)) + self.tableWidget_mentor_menu_dashboard.setColumnCount(len(df.columns)) + self.tableWidget_mentor_menu_dashboard.setHorizontalHeaderLabels(df.columns) + for row in range(len(df)): + for col in range(len(df.columns)): + value = str(df.iloc[row, col]) + self.tableWidget_mentor_menu_dashboard.setItem(row, col, QtWidgets.QTableWidgetItem(value)) + + def show_applications(self): + self.load_table_data() + + def search_applications(self): + search_text = self.lineEdit_search.text().lower() + if search_text == "": + QtWidgets.QMessageBox.warning(self, "Uyarı", "Lütfen arama metni girin.") + return + filtered_df = self.df[self.df["Full Name"].str.lower().str.contains(search_text)] + if filtered_df.empty: + QtWidgets.QMessageBox.information(self, "Sonuç", "Arama kriterlerine uygun başvuru bulunamadı.") + else: + self.show_table(filtered_df) + + def listComboBoxChanged(self): + selected_option = self.comboBox_secenekler.currentText() + filtered_df = self.df[self.df['Mentor Advice'] == selected_option] + if filtered_df.empty: + QtWidgets.QMessageBox.information(self, "Sonuç", "Seçilen kritere uygun başvuru bulunamadı.") + else: + self.show_table(filtered_df) + QtWidgets.QMessageBox.information(self, "Sonuç", f"{len(filtered_df)} başvuru bulundu.") + + def back_to_menu(self): + if self.parent_menu is not None: + self.parent_menu.show() + self.close() + +# Test amaçlı çalıştırmak için: +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + window = MentorMeetingWindow() + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/backend/preference_menu.py b/backend/preference_menu.py new file mode 100644 index 0000000..3fcedcf --- /dev/null +++ b/backend/preference_menu.py @@ -0,0 +1,39 @@ +from PyQt6 import QtWidgets, uic, QtGui +from applications_menu import ApplicationsWindow +from interviews_menu import InterviewsMenuWindow +from mentor_menu import MentorMeetingWindow + + +class PreferenceMenuWindow(QtWidgets.QMainWindow): + def __init__(self): + super().__init__() + uic.loadUi("ui/preference_menu.ui", self) + self.pushButton_application.clicked.connect(self.open_applications_window) # <-- EKLENDİ + self.pushButton_interviews.clicked.connect(self.open_interviews_window) # <-- EKLENDİ + self.pushButton_mentormeeting.clicked.connect(self.open_mentor_meeting_window) + self.pushButton_exit.clicked.connect(self.close) + + self.label_language.setFont(QtGui.QFont("Arial", 4)) + + def open_applications_window(self): + self.applications_window = ApplicationsWindow(parent=self) # parent=self ile pencereyi bağla + self.applications_window.show() + self.hide() + + def open_interviews_window(self): + self.interviews_window = InterviewsMenuWindow(parent=self) # parent=self ile pencereyi bağla + self.interviews_window.show() + self.hide() + + def open_mentor_meeting_window(self): + self.mentor_meeting_window = MentorMeetingWindow(parent=self) # parent=self ile pencereyi bağla + self.mentor_meeting_window.show() + self.hide() + +# Test amaçlı çalıştırmak için: +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + window = PreferenceMenuWindow() + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/backend/utils.py b/backend/utils.py new file mode 100644 index 0000000..5e55517 --- /dev/null +++ b/backend/utils.py @@ -0,0 +1,10 @@ +from sqlalchemy import create_engine + +def get_engine(): + """ + PostgreSQL veritabanı bağlantısı için SQLAlchemy engine döndürür. + """ + engine = create_engine( + 'postgresql+psycopg2://postgres:POSTGRES@localhost:5432/crm' + ) + return engine \ No newline at end of file diff --git a/excel_tablolarim/Basvurular.xlsx b/excel_tablolarim/Basvurular.xlsx new file mode 100644 index 0000000..f38c1d7 Binary files /dev/null and b/excel_tablolarim/Basvurular.xlsx differ diff --git a/excel_tablolarim/Kullanicilar.xlsx b/excel_tablolarim/Kullanicilar.xlsx new file mode 100644 index 0000000..186acfb Binary files /dev/null and b/excel_tablolarim/Kullanicilar.xlsx differ diff --git a/excel_tablolarim/Kursiyerler.xlsx b/excel_tablolarim/Kursiyerler.xlsx new file mode 100644 index 0000000..5e1ecf8 Binary files /dev/null and b/excel_tablolarim/Kursiyerler.xlsx differ diff --git a/excel_tablolarim/MentorGorusme.xlsx b/excel_tablolarim/MentorGorusme.xlsx new file mode 100644 index 0000000..acaee4d Binary files /dev/null and b/excel_tablolarim/MentorGorusme.xlsx differ diff --git a/excel_tablolarim/ProjeTakip.xlsx b/excel_tablolarim/ProjeTakip.xlsx new file mode 100644 index 0000000..f4d5e81 Binary files /dev/null and b/excel_tablolarim/ProjeTakip.xlsx differ diff --git a/images/back.png b/images/back.png new file mode 100644 index 0000000..621077a Binary files /dev/null and b/images/back.png differ diff --git a/images/blackhome.png b/images/blackhome.png new file mode 100644 index 0000000..c40c6b2 Binary files /dev/null and b/images/blackhome.png differ diff --git a/images/categories.png b/images/categories.png new file mode 100644 index 0000000..3fedb11 Binary files /dev/null and b/images/categories.png differ diff --git a/images/email.png b/images/email.png new file mode 100644 index 0000000..bcf580c Binary files /dev/null and b/images/email.png differ diff --git a/images/home.png b/images/home.png new file mode 100644 index 0000000..8f27cff Binary files /dev/null and b/images/home.png differ diff --git a/images/logo.jpg b/images/logo.jpg new file mode 100644 index 0000000..ecd7284 Binary files /dev/null and b/images/logo.jpg differ diff --git a/images/logout.png b/images/logout.png new file mode 100644 index 0000000..9cca4b8 Binary files /dev/null and b/images/logout.png differ diff --git a/images/search.png b/images/search.png new file mode 100644 index 0000000..1b45f58 Binary files /dev/null and b/images/search.png differ diff --git a/images/userresim.png b/images/userresim.png new file mode 100644 index 0000000..5e3b045 Binary files /dev/null and b/images/userresim.png differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4fb2a2b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,38 @@ +cachetools==5.5.2 +certifi==2025.6.15 +charset-normalizer==3.4.2 +et_xmlfile==2.0.0 +google-api-core==2.25.1 +google-api-python-client==2.174.0 +google-auth==2.40.3 +google-auth-httplib2==0.2.0 +google-auth-oauthlib==1.2.2 +googleapis-common-protos==1.70.0 +greenlet==3.2.3 +httplib2==0.22.0 +idna==3.10 +numpy==2.3.1 +oauthlib==3.3.1 +openpyxl==3.1.5 +pandas==2.3.0 +proto-plus==1.26.1 +protobuf==6.31.1 +psycopg2==2.9.10 +pyasn1==0.6.1 +pyasn1_modules==0.4.2 +pyparsing==3.2.3 +PyQt6==6.9.1 +PyQt6-Qt6==6.9.1 +PyQt6_sip==13.10.2 +python-dateutil==2.9.0.post0 +python-dotenv==1.1.1 +pytz==2025.2 +requests==2.32.4 +requests-oauthlib==2.0.0 +rsa==4.9.1 +six==1.17.0 +SQLAlchemy==2.0.41 +typing_extensions==4.14.0 +tzdata==2025.2 +uritemplate==4.2.0 +urllib3==2.5.0 diff --git a/task1.py b/task1.py new file mode 100644 index 0000000..af84d51 --- /dev/null +++ b/task1.py @@ -0,0 +1,161 @@ +import psycopg2 + +conn=psycopg2.connect( + host="localhost", + database="postgres", + user="postgres", + password="POSTGRES", + port="5432" +) + +cur=conn.cursor() + +# employees tablosunu oluştur +cur.execute(""" + CREATE TABLE IF NOT EXISTS employees ( + emp_id INTEGER PRIMARY KEY, + first_name VARCHAR(50) NOT NULL, + last_name VARCHAR(50) NOT NULL, + salary INTEGER NOT NULL, + job_title VARCHAR(100) NOT NULL, + gender VARCHAR(10) NOT NULL, + hire_date DATE NOT NULL + ); +""") + +# employees tablosuna kayıt ekle +cur.executemany(""" + INSERT INTO employees (emp_id, first_name, last_name, salary, job_title, gender, hire_date) + VALUES (%s, %s, %s, %s, %s, %s, %s) + ON CONFLICT (emp_id) DO NOTHING; +""", [ + (17679, 'Robert', 'Gilmore', 110000, 'Operations Director', 'Male', '2018-09-04'), + (26650, 'Elvis', 'Ritter', 86000, 'Sales Manager', 'Male', '2017-11-24'), + (30840, 'David', 'Barrow', 85000, 'Data Scientist', 'Male', '2019-12-02'), + (49714, 'Hugo', 'Forester', 55000, 'IT Support Specialist', 'Male', '2019-11-22'), + (51821, 'Linda', 'Foster', 95000, 'Data Scientist', 'Female', '2019-04-29'), + (67323, 'Lisa', 'Wiener', 75000, 'Business Analyst', 'Female', '2018-08-09'), + (70950, 'Rodney', 'Weaver', 87000, 'Project Manager', 'Male', '2018-12-20'), + (71329, 'Gayle', 'Meyer', 77000, 'HR Manager', 'Female', '2019-06-28'), + (76589, 'Jason', 'Christian', 99000, 'Project Manager', 'Male', '2019-01-21'), + (97927, 'Billie', 'Lanning', 67000, 'Web Developer', 'Female', '2018-06-25') +]) + +# departments tablosunu oluştur +cur.execute(""" + CREATE TABLE IF NOT EXISTS departments ( + emp_id INTEGER, + dept_name VARCHAR(50) NOT NULL, + dept_id INTEGER, + PRIMARY KEY (emp_id, dept_id) + ); +""") + +# departments tablosuna kayıt ekle +cur.executemany(""" + INSERT INTO departments (emp_id, dept_name, dept_id) + VALUES (%s, %s, %s) + ON CONFLICT DO NOTHING; +""", [ + (17679, 'Operations', 13), + (26650, 'Marketing', 14), + (30840, 'Operations', 13), + (49823, 'Technology', 12), + (51821, 'Operations', 13), + (67323, 'Marketing', 14), + (71119, 'Administrative', 11), + (76589, 'Operations', 13), + (97927, 'Technology', 12) +]) + + +# 1. Find the employees who get paid more than Rodney Weaver. +cur.execute(""" + SELECT first_name, last_name, salary + FROM employees + WHERE salary > (SELECT salary FROM employees WHERE first_name='Rodney' AND last_name='Weaver'); +""") +print("1. Employees paid more than Rodney Weaver:", cur.fetchall()) + +# 2. Find the average, min and max salaries +cur.execute(""" + SELECT AVG(salary), MIN(salary), MAX(salary) + FROM employees; +""") +print("2. Average, Min, Max salaries:", cur.fetchone()) + +# 3. Employees whose salary is more than 87000 (first name, last name, salary) +cur.execute(""" + SELECT first_name, last_name, salary + FROM employees + WHERE salary > 87000; +""") +print("3. Employees with salary > 87000:", cur.fetchall()) + +# 4. Employees who work under the Operations department +cur.execute(""" + SELECT e.first_name, e.last_name + FROM employees e + JOIN departments d ON e.emp_id = d.emp_id + WHERE d.dept_name = 'Operations'; +""") +print("4. Employees in Operations department:", cur.fetchall()) + +# 5. Employees who work under the Technology department +cur.execute(""" + SELECT e.first_name, e.last_name + FROM employees e + JOIN departments d ON e.emp_id = d.emp_id + WHERE d.dept_name = 'Technology'; +""") +print("5. Employees in Technology department:", cur.fetchall()) + +# 6. Average salary of female employees +cur.execute(""" + SELECT AVG(salary) + FROM employees + WHERE gender = 'Female'; +""") +print("6. Average salary of female employees:", cur.fetchone()[0]) + +# 7. Average salaries of each department +cur.execute(""" + SELECT d.dept_name, AVG(e.salary) + FROM employees e + JOIN departments d ON e.emp_id = d.emp_id + GROUP BY d.dept_name; +""") +print("7. Average salaries by department:", cur.fetchall()) + +# 8. Oldest and newest employees +cur.execute(""" + SELECT first_name, last_name, hire_date + FROM employees + WHERE hire_date = (SELECT MIN(hire_date) FROM employees) + OR hire_date = (SELECT MAX(hire_date) FROM employees); +""") +print("8. Oldest and newest employees:", cur.fetchall()) + +# 9. Hiring date and department of the highest paid employee +cur.execute(""" + SELECT e.hire_date, d.dept_name + FROM employees e + JOIN departments d ON e.emp_id = d.emp_id + WHERE e.salary = (SELECT MAX(salary) FROM employees); +""") +print("9. Hiring date and department of highest paid employee:", cur.fetchall()) + +# 10. Hiring date and department of the lowest paid employee +cur.execute(""" + SELECT e.hire_date, d.dept_name + FROM employees e + JOIN departments d ON e.emp_id = d.emp_id + WHERE e.salary = (SELECT MIN(salary) FROM employees); +""") +print("10. Hiring date and department of lowest paid employee:", cur.fetchall()) + + +conn.commit() +cur.close() +conn.close() + diff --git a/task2_excelden_db_ye_aktarim.py b/task2_excelden_db_ye_aktarim.py new file mode 100644 index 0000000..347a31d --- /dev/null +++ b/task2_excelden_db_ye_aktarim.py @@ -0,0 +1,34 @@ +import os +import pandas as pd +from sqlalchemy import create_engine + +# PostgreSQL bağlantı ayarları +db_user = 'postgres' +db_password = 'POSTGRES' +db_host = 'localhost' +db_port = '5432' +db_name = 'crm' + +# SQLAlchemy engine oluştur +engine = create_engine(f'postgresql+psycopg2://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}') + +# Excel dosyalarının bulunduğu klasör +excel_klasor = 'excel_tablolarim' + +# Aktarılacak dosya isimleri +dosyalar = [ + 'Basvurular.xlsx', + 'Kullanicilar.xlsx', + 'Kursiyerler.xlsx', + 'MentorGorusme.xlsx', + 'ProjeTakip.xlsx' +] + +for dosya in dosyalar: + dosya_yolu = os.path.join(excel_klasor, dosya) + tablo_adi = os.path.splitext(dosya)[0].lower() # Tablo adı: dosya adı küçük harfli ve uzantısız + df = pd.read_excel(dosya_yolu) + df.to_sql(tablo_adi, engine, if_exists='replace', index=False) + print(f"{dosya} dosyasındaki veriler '{tablo_adi}' tablosuna aktarıldı.") + +print("Tüm dosyalar başarıyla PostgreSQL'e aktarıldı.") \ No newline at end of file diff --git a/ui/admin_menu.ui b/ui/admin_menu.ui new file mode 100644 index 0000000..927422d --- /dev/null +++ b/ui/admin_menu.ui @@ -0,0 +1,615 @@ + + + MainWindow + + + + 0 + 0 + 1300 + 750 + + + + + 1300 + 750 + + + + + 1500 + 1200 + + + + MainWindow + + + Qt::RightToLeft + + + QMainWindow, QDialog { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + Qt::ToolButtonFollowStyle + + + + + 1200 + 0 + + + + QMainWindow, QWidget { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + + + + + 600 + 600 + + + + + 1500 + 2000 + + + + Qt::LeftToRight + + + QMainWindow { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + + + 10 + 90 + 333 + 587 + + + + Qt::TabFocus + + + Qt::RightToLeft + + + QFrame { + background-color: white; + border-radius: 20px; + padding: 20px; +} + + + + QFrame::WinPanel + + + QFrame::Raised + + + + + + + Palatino Linotype + 16 + 50 + false + + + + 3 + + + QLabel#welcomeLabel { + color: #ecf0f1; + font: italic 18pt "Georgia"; + padding: 10px; + letter-spacing: 1px; +} + + + + QFrame::NoFrame + + + Welcome Admin + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + + Activity Control + + + + + + + Qt::LeftToRight + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + Send Mail + + + + ../images/email.png../images/email.png + + + + 20 + 20 + + + + 300 + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + Preference Admin Menü + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + + + + ../images/logout.png../images/logout.png + + + + 18 + 18 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 370 + 130 + 800 + 500 + + + + + 15 + 15 + + + + + 500 + 500 + + + + + 1000 + 700 + + + + QHeaderView::section { + background-color: #2c5364; + color: white; + padding: 4px; + font-weight: bold; + border: 1px solid #203a43; +} + +QTableWidget { + gridline-color: white; + color: white; /* ← Bu satır metinleri beyaz yapar */ +} + + + 185 + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 10 + + + + + 11 + + + + + Event Name + + + + + Start Time + + + + + Organizer Email + + + + + Participants + + + + + + + 1060 + 650 + 60 + 30 + + + + + 60 + 16777215 + + + + QComboBox#comboBox_language { + background-color: #ffffff; + color: #2c5364; /* Tema ile uyumlu koyu mavi */ + border: 2px solid #2c5364; + border-radius: 5px; + padding: 4px; + min-width: 10px; + font-weight: bold; +} +QComboBox QAbstractItemView { + background-color: #ffffff; + color: #2c5364; + selection-background-color: #203a43; + selection-color: white; +} + + + + + + + + + + Türkçe + + + + + Englısh + + + + + Dutch + + + + + Français + + + + + Español + + + + + Deutsch + + + + + + + 1000 + 660 + 53 + 16 + + + + + 100 + 20 + + + + QLabel#label_language { + color: white; + font-weight: bold; + font-size: 6pt; +} + + + + Languages + + + + + + 60 + 10 + 231 + 71 + + + + + 250 + 80 + + + + Qt::LeftToRight + + + + + + ../images/logo.jpg + + + true + + + + + + 370 + 30 + 791 + 34 + + + + + -1 + 75 + true + + + + QLabel { + background-color: #7f7f7f; + color: white; + font-weight: bold; + font-size: 18px; + padding: 6px 12px; + border-radius: 8px; +} + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + Admin Panel + + + Qt::AutoText + + + false + + + Qt::AlignCenter + + + + + + + + + + 0 + 0 + 1300 + 26 + + + + + + + + diff --git a/ui/admin_preference_menu.ui b/ui/admin_preference_menu.ui new file mode 100644 index 0000000..5c79f1e --- /dev/null +++ b/ui/admin_preference_menu.ui @@ -0,0 +1,497 @@ + + + MainWindow + + + + 0 + 0 + 900 + 900 + + + + + 900 + 900 + + + + + 900 + 900 + + + + MainWindow + + + Qt::RightToLeft + + + QMainWindow, QWidget { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + Qt::ToolButtonFollowStyle + + + + QMainWindow, QDialog { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + + + 120 + 40 + 621 + 761 + + + + + 500 + 600 + + + + + 900 + 1000 + + + + QMainWindow, QDialog { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + + + 130 + 160 + 361 + 431 + + + + Qt::TabFocus + + + Qt::RightToLeft + + + QFrame { + background-color: white; + border-radius: 20px; + padding: 20px; +} + + + + QFrame::WinPanel + + + QFrame::Raised + + + + + + + -1 + 75 + true + + + + QLabel { + background-color: #7f7f7f; + color: white; + font-weight: bold; + font-size: 18px; + padding: 6px 12px; + border-radius: 8px; +} + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + CRM-Admin Preference Menu + + + Qt::AutoText + + + false + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + Mentor Interview + + + + + + + Qt::LeftToRight + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + Applications + + + + ../images/categories.png../images/categories.png + + + + 18 + 18 + + + + 300 + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + Interviews + + + + + + + Qt::LeftToRight + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + Admin Menu + + + + ../images/home.png../images/home.png + + + + 17 + 17 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + + + + ../images/logout.png../images/logout.png + + + + 18 + 18 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 510 + 720 + 60 + 20 + + + + + 60 + 16777215 + + + + QComboBox#comboBox_language { + background-color: #ffffff; + color: #2c5364; /* Tema ile uyumlu koyu mavi */ + border: 2px solid #2c5364; + border-radius: 5px; + padding: 4px; + min-width: 10px; + font-weight: bold; +} +QComboBox QAbstractItemView { + background-color: #ffffff; + color: #2c5364; + selection-background-color: #203a43; + selection-color: white; +} + + + + + + + + + + Türkçe + + + + + English + + + + + Dutch + + + + + Deutsch + + + + + Русский + + + + + Español + + + + + العربية + + + + + 简体中文 + + + + + 日本語 + + + + + + + 440 + 720 + 61 + 20 + + + + + 100 + 20 + + + + QLabel#label_language { + color: white; + font-weight: bold; + font-size: 6pt; +} + + + + Languages + + + + + + 100 + 10 + 441 + 81 + + + + + + + ../images/logo.jpg + + + true + + + + + + + + 0 + 0 + 900 + 26 + + + + + + + + diff --git a/ui/applications_menu.ui b/ui/applications_menu.ui new file mode 100644 index 0000000..270ca00 --- /dev/null +++ b/ui/applications_menu.ui @@ -0,0 +1,893 @@ + + + MainWindow + + + + 0 + 0 + 1500 + 900 + + + + + 1500 + 900 + + + + + 1500 + 900 + + + + MainWindow + + + QMainWindow, QWidget { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + + + 1500 + 1500 + + + + + + + + 65 + 16777215 + + + + Qt::RightToLeft + + + QLabel#label_language { + color: white; + font-weight: bold; + font-size: 6pt; +} + + + + Languages + + + + + + + + 65 + 16777215 + + + + Qt::LeftToRight + + + QComboBox#comboBox_language { + background-color: #ffffff; + color: #2c5364; /* Tema ile uyumlu koyu mavi */ + border: 2px solid #2c5364; + border-radius: 5px; + padding: 4px; + min-width: 8px; + font-weight: bold; +} +QComboBox QAbstractItemView { + background-color: #ffffff; + color: #2c5364; + selection-background-color: #203a43; + selection-color: white; +} + + + + + + + + + Türkçe + + + + + English + + + + + Dutch + + + + + Français + + + + + Русский + + + + + Deutsch + + + + + العربية + + + + + 简体中文 + + + + + Español + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 18 + + + 18 + + + 18 + + + 18 + + + 18 + + + + + true + + + + 200 + 30 + + + + font: 6pt "MS Shell Dlg 2"; + + + + + + ../images/logo.jpg + + + true + + + + + + + + 0 + 0 + + + + QLineEdit { + background-color: white; + color: #2c5364; /* Tema rengine zıt ve okunabilir */ + border: 2px solid #203a43; + border-radius: 5px; + padding: 5px; + font-size: 12pt; +} + + + + + + + + + 0 + 0 + + + + QPushButton { + background-color: #8f8f8f; + color: white; + border-radius: 8px; + padding: 6px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + Search + + + + ../images/search.png../images/search.png + + + + 17 + 17 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QFrame { + background-color: white; + border-radius: 20px; + padding: 5px; +} + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + + 75 + true + + + + 📂 Application Buttons + + + + + + + + 0 + 0 + + + + + 150 + 70 + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + All Applications + + + + + + + + 0 + 0 + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + Planned Mentor Meetings + + + + + + + + 0 + 0 + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + + Unscheduled M. Meetings + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QFrame { + background-color: white; + border-radius: 20px; + padding: 5px; +} + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + + 75 + true + + + + 📂 VIT Record Buttons + + + + + + + + 0 + 0 + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + Previous VIT Control + + + + + + + + 0 + 0 + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + Repeted Regitiration + + + + + + + + 0 + 0 + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + Diffrent Registiration + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + QFrame { + background-color: white; + border-radius: 20px; + padding: 5px; +} + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + + 75 + true + + + + ⚙️ Filter Options + + + + + + + + 0 + 0 + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + Filter Application + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + Qt::LeftToRight + + + QPushButton { + background-color: #8f8f8f; + color: white; + border-radius: 8px; + padding: 6px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + Back Menu + + + + ../images/back.png../images/back.png + + + + 17 + 17 + + + + + + + + + + + + 0 + 0 + + + + QPushButton { + background-color: #8f8f8f; + color: white; + border-radius: 8px; + padding: 6px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + + + + + ../images/logout.png../images/logout.png + + + + 18 + 18 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 15 + 15 + + + + + 100 + 100 + + + + + 1400 + 1000 + + + + QHeaderView::section { + background-color: #2c5364; + color: white; + padding: 4px; + font-weight: bold; + border: 1px solid #203a43; +} + +QTableWidget { + gridline-color: white; + color: white; /* ← Bu satır metinleri beyaz yapar */ +} + + + 155 + + + + Date + + + + + Name Surname + + + + + Mail + + + + + Telephone + + + + + Post Code + + + + + State + + + + + Economical Situation + + + + + + + + + Georgia + 18 + + + + QLabel { + font-family: "Georgia"; + font-size: 18pt; + color: white; +} + + + + Application Dashboard + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + 0 + 1500 + 26 + + + + + + + + diff --git a/ui/interviews_menu.ui b/ui/interviews_menu.ui new file mode 100644 index 0000000..979dd77 --- /dev/null +++ b/ui/interviews_menu.ui @@ -0,0 +1,488 @@ + + + MainWindow + + + + 0 + 0 + 1172 + 789 + + + + + 1172 + 789 + + + + + 1172 + 789 + + + + MainWindow + + + QMainWindow, QWidget { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 40 + + + + + + + + + + QLineEdit { + background-color: white; + color: #2c5364; /* Tema rengine zıt ve okunabilir */ + border: 2px solid #203a43; + border-radius: 5px; + padding: 5px; + font-size: 12pt; +} + + + + + + + QPushButton { + background-color: #8f8f8f; + color: white; + border-radius: 8px; + padding: 6px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + Search + + + + ../images/search.png../images/search.png + + + + 18 + 18 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + Submitted Projects + + + + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + Project Arrivals + + + + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + Back Menu + + + + ../images/back.png../images/back.png + + + + 18 + 18 + + + + + + + + QPushButton { + background-color: #a40000; + color: white; + border: none; + border-radius: 8px; + padding: 8px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + + + + ../images/logout.png../images/logout.png + + + + 18 + 18 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QHeaderView::section { + background-color: #2c5364; + color: white; + padding: 4px; + font-weight: bold; + border: 1px solid #203a43; +} + +QTableWidget { + gridline-color: white; + color: white; /* ← Bu satır metinleri beyaz yapar */ +} + + + 155 + + + + Name Surname + + + + 75 + true + + + + + + Project Sending Date + + + + 75 + true + + + + + + Project Arrival Date + + + + 75 + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QComboBox#comboBox_language { + background-color: #ffffff; + color: #2c5364; /* Tema ile uyumlu koyu mavi */ + border: 2px solid #2c5364; + border-radius: 5px; + padding: 4px; + min-width: 10px; + font-weight: bold; +} +QComboBox QAbstractItemView { + background-color: #ffffff; + color: #2c5364; + selection-background-color: #203a43; + selection-color: white; +} + + + + + + + + + Türkçe + + + + + English + + + + + Dutch + + + + + Français + + + + + Español + + + + + Deutsch + + + + + Русский + + + + + العربية + + + + + 简体中文 + + + + + + + + + 65 + 16777215 + + + + QLabel#label_language { + color: white; + font-weight: bold; + font-size: 6pt; +} + + + + Languages + + + + + + + + 150 + 30 + + + + + + + ../images/logo.jpg + + + true + + + + + + + + Georgia + 18 + + + + QLabel { + font-family: "Georgia"; + font-size: 18pt; + color: white; +} + + + + <html><head/><body><p align="center"><span style=" font-size:20pt; font-weight:600;">We R Here Interviews Menu</span></p></body></html> + + + + + + + + + 0 + 0 + 1172 + 26 + + + + + + + + diff --git a/ui/login.ui b/ui/login.ui new file mode 100644 index 0000000..7fea15b --- /dev/null +++ b/ui/login.ui @@ -0,0 +1,363 @@ + + + Dialog + + + + 0 + 0 + 900 + 900 + + + + + 900 + 900 + + + + + 900 + 900 + + + + + 200 + 300 + + + + Dialog + + + QDialog { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 150 + 20 + + + + Qt::RightToLeft + + + QComboBox#comboBox_language { + background-color: #ffffff; + color: #2c5364; /* Tema ile uyumlu koyu mavi */ + border: 2px solid #2c5364; + border-radius: 5px; + padding: 4px; + min-width: 10px; + font-weight: bold; +} +QComboBox QAbstractItemView { + background-color: #ffffff; + color: #2c5364; + selection-background-color: #203a43; + selection-color: white; +} + + + + + + + + + + + + + + + Türkçe + + + + + English + + + + + Dutch + + + + + Français + + + + + العربية + + + + + Español + + + + + Deutsch + + + + + Русский + + + + + 简体中文 + + + + + + + + QLineEdit { + padding: 8px; + border: 1px solid #ccc; + border-radius: 5px; +} + + + + Username + + + + + + + Qt::ClickFocus + + + QLineEdit { + padding: 8px; + border: 1px solid #ccc; + border-radius: 5px; +} + + + + QLineEdit::Password + + + Password + + + + + + + + 550 + 30 + + + + color: rgb(255, 0, 0); + + + <html><head/><body><p><br/></p></body></html> + + + + + + + color: red; +font-weight: bold; +text-decoration: underline; + + + <a href='#'>Forgot Password?</a> + + + Qt::RichText + + + true + + + + + + + QCheckBox { + color: white; /* Yazı rengini buradan ayarlarsın */ + font-weight: bold; +} + + + + Remember me + + + + + + + + 101 + 101 + + + + Qt::RightToLeft + + + + + + ../images/userresim.png + + + true + + + Qt::AlignJustify|Qt::AlignVCenter + + + + + + + + 295 + 71 + + + + + + + ../images/logo.jpg + + + true + + + + + + + QPushButton { + background-color: #8b0000; + color: white; + padding: 10px 20px; + border: 2px solid #b22222; + border-radius: 10px; + font-size: 14px; + font-weight: bold; +} + +QPushButton:hover { + background-color: #b22222; + border-color: #8b0000; +} + +QPushButton:pressed { + background-color: #4b0000; +} + + + + Login + + + + + + + + 100 + 16777215 + + + + QLabel#label_language { + color: white; + font-weight: bold; + font-size: 6pt; +} + + + + 🌐Languages + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QPushButton { + background-color: #8b0000; + color: white; + padding: 10px 20px; + border: 2px solid #b22222; + border-radius: 10px; + font-size: 14px; + font-weight: bold; +} + +QPushButton:hover { + background-color: #b22222; + border-color: #8b0000; +} + +QPushButton:pressed { + background-color: #4b0000; +} + + + + Exit + + + + + + + + diff --git a/ui/mentor_menu.ui b/ui/mentor_menu.ui new file mode 100644 index 0000000..063592a --- /dev/null +++ b/ui/mentor_menu.ui @@ -0,0 +1,620 @@ + + + MainWindow + + + + 0 + 0 + 1309 + 780 + + + + + 1309 + 780 + + + + + 1309 + 780 + + + + MainWindow + + + QMainWindow, QWidget { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + + + + + + 750 + 20 + + + + QComboBox { + /* ComboBox'ın kendi (kapalıykenki) arka planı */ + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); + /* ComboBox'ın içindeki yazının rengi (seçili öğe vs.) */ + color: white; + border: 1px solid #2c5364; /* Kenarlık rengi (gradient ile uyumlu) */ + border-radius: 5px; /* Köşe yuvarlama */ + padding: 5px; /* İç boşluk */ + min-height: 25px; /* Minimum yükseklik (görsel denge için) */ +} + +QComboBox QAbstractItemView { + /* Açılır liste açıldığında öğelerin arka planı */ + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); + /* Açılır listedeki öğelerin yazı rengi */ + color: white; + selection-background-color: #007bff; /* Seçili öğenin arka plan rengi (mavi gibi) */ + selection-color: white; /* Seçili öğenin yazı rengi */ + border: none; /* Kenarlık kaldırma */ +} + + + + 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 + + + + + + + + + 0 + 0 + + + + Qt::LeftToRight + + + QPushButton { + background-color: #8f8f8f; + color: white; + border-radius: 8px; + padding: 6px; + font-weight: bold; +} +QPushButton:hover { + background-color: #cc0000; +} + + + + + Search + + + + ../images/search.png../images/search.png + + + + 17 + 17 + + + + + + + + + 0 + 0 + + + + Qt::LeftToRight + + + QLineEdit { + font: 6pt "MS Shell Dlg 2"; + background-color: white; + color: #2c5364; /* Tema rengine zıt ve okunabilir */ + border: 2px solid #203a43; + border-radius: 5px; + padding: 5px; + font-size: 12pt; +} + + + + + + + + + + + + + + + 250 + 250 + + + + Qt::TabFocus + + + Qt::RightToLeft + + + QFrame { + background-color: white; + border-radius: 20px; + padding: 20px; +} + + + + QFrame::WinPanel + + + QFrame::Raised + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + + All Application + + + + + + + Qt::LeftToRight + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + Back Menu + + + + ../../../Downloads/back (2).png../../../Downloads/back (2).png + + + + 20 + 20 + + + + 300 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + + + + ../images/logout.png../images/logout.png + + + + 18 + 18 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + -1 + 75 + true + + + + QLabel { + background-color: #7f7f7f; + color: white; + font-weight: bold; + font-size: 18px; + padding: 6px 12px; + border-radius: 8px; +} + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + Mentor Menu + + + Qt::AutoText + + + false + + + Qt::AlignCenter + + + + + + + + 250 + 80 + + + + + + + ../images/logo.jpg + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 15 + 15 + + + + + 990 + 540 + + + + + 990 + 550 + + + + QHeaderView::section { + background-color: #2c5364; + color: white; + padding: 4px; + font-weight: bold; + border: 1px solid #203a43; +} + +QTableWidget { + gridline-color: white; + color: white; /* ← Bu satır metinleri beyaz yapar */ +} + + + 155 + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 10 + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 15 + + + + + 16 + + + + + 17 + + + + + 18 + + + + + 19 + + + + + Date + + + + + Group + + + + + Full Name + + + + + Mentor + + + + + Mentor Advice + + + + + Note + + + + + + + + + + 0 + 0 + 1309 + 26 + + + + + + + + diff --git a/ui/preference_menu.ui b/ui/preference_menu.ui new file mode 100644 index 0000000..3f8a95b --- /dev/null +++ b/ui/preference_menu.ui @@ -0,0 +1,483 @@ + + + MainWindow + + + + 0 + 0 + 900 + 900 + + + + + 900 + 900 + + + + + 900 + 900 + + + + MainWindow + + + Qt::RightToLeft + + + QMainWindow, QWidget { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + Qt::ToolButtonFollowStyle + + + + QMainWindow, QWidget { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364); +} + + + + + + 120 + 50 + 641 + 741 + + + + + 500 + 600 + + + + + 900 + 1000 + + + + QPushButton { + background-color: #f4f6f8; + color: white; + font-weight: bold; + border-radius: 10px; + padding: 6px; +} +QPushButton:hover { + background-color: #48a; +} + + + + + 130 + 180 + 361 + 431 + + + + Qt::TabFocus + + + Qt::RightToLeft + + + QFrame { + background-color: white; + border-radius: 20px; + padding: 20px; +} + + + + QFrame::WinPanel + + + QFrame::Raised + + + + + + + -1 + 75 + true + + + + QLabel { + background-color: #7f7f7f; + color: white; + font-weight: bold; + font-size: 18px; + padding: 6px 12px; + border-radius: 8px; +} + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + CRM-Preference Menu + + + Qt::AutoText + + + false + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::LeftToRight + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + Applications + + + + ../images/categories.png../images/categories.png + + + + 18 + 18 + + + + 300 + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + Interviews + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + + Mentor Meeting + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QPushButton { + background-color: #b30000; + color: white; + border-radius: 10px; + padding: 8px 20px; + font-weight: bold; + font-size: 14px; + border: 2px solid #8b0000; +} + +QPushButton:hover { + background-color: #e60000; + border: 2px solid #ff0000; +} + + + + + + + + + ../images/logout.png../images/logout.png + + + + 18 + 18 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 530 + 700 + 60 + 20 + + + + + 0 + 0 + + + + + 22 + 0 + + + + + 60 + 16777215 + + + + QComboBox#comboBox_language { + background-color: #ffffff; + color: #2c5364; /* Tema ile uyumlu koyu mavi */ + border: 2px solid #2c5364; + border-radius: 5px; + padding: 4px; + min-width: 10px; + font-weight: bold; +} +QComboBox QAbstractItemView { + background-color: #ffffff; + color: #2c5364; + selection-background-color: #203a43; + selection-color: white; +} + + + + + + + + + + Türkçe + + + + + Deutsch + + + + + Englısh + + + + + Dutch + + + + + Français + + + + + Español + + + + + Русский + + + + + العربية + + + + + 日本語 + + + + + 简体中文 + + + + + + + 470 + 700 + 61 + 20 + + + + + 100 + 20 + + + + QLabel#label_language { + color: white; + font-weight: bold; + font-size: 6pt; +} + + + + Languages + + + + + + 110 + 20 + 421 + 81 + + + + + + + ../images/logo.jpg + + + true + + + + + + + + 0 + 0 + 900 + 26 + + + + + + + +