""" Moderner Account Generator Tab - Ohne Log-Widget, mit besserem Layout """ import logging from PyQt5.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QFormLayout, QGridLayout, QGroupBox, QLabel, QLineEdit, QSpinBox, QRadioButton, QCheckBox, QComboBox, QPushButton, QProgressBar, QMessageBox, QFrame, QScrollArea ) from PyQt5.QtCore import Qt, pyqtSignal, QPropertyAnimation, QEasingCurve from PyQt5.QtGui import QFont, QPalette logger = logging.getLogger("generator_tab") class ModernGeneratorTab(QWidget): """Modernes Widget für Account-Generierung ohne Log.""" # Signale start_requested = pyqtSignal(dict) stop_requested = pyqtSignal() account_created = pyqtSignal(str, dict) def __init__(self, platform_name, language_manager=None): super().__init__() self.platform_name = platform_name self.language_manager = language_manager self.init_ui() if self.language_manager: self.language_manager.language_changed.connect(self.update_texts) self.update_texts() def init_ui(self): """Initialisiert die moderne Benutzeroberfläche.""" # Haupt-Layout mit Scroll-Bereich main_layout = QVBoxLayout(self) main_layout.setContentsMargins(0, 0, 0, 0) # Scroll-Bereich für bessere Anpassung scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setFrameShape(QFrame.NoFrame) scroll_widget = QWidget() scroll_layout = QVBoxLayout(scroll_widget) scroll_layout.setContentsMargins(40, 30, 40, 30) scroll_layout.setSpacing(30) # Header mit Titel und Status header_widget = self.create_header() scroll_layout.addWidget(header_widget) # Haupt-Formular als Card form_card = self.create_form_card() scroll_layout.addWidget(form_card) # Erweiterte Optionen options_card = self.create_options_card() scroll_layout.addWidget(options_card) # Action-Bereich mit Buttons action_widget = self.create_action_area() scroll_layout.addWidget(action_widget) scroll_layout.addStretch() scroll.setWidget(scroll_widget) main_layout.addWidget(scroll) # Event-Verbindungen self.email_radio.toggled.connect(self.toggle_phone_input) self.phone_radio.toggled.connect(self.toggle_phone_input) # Initialer Status self.toggle_phone_input() def create_header(self): """Erstellt den Header-Bereich mit Titel und Status.""" header = QWidget() layout = QHBoxLayout(header) layout.setContentsMargins(0, 0, 0, 20) # Titel title = QLabel("Account erstellen") title_font = QFont() title_font.setPointSize(24) title_font.setWeight(QFont.Bold) title.setFont(title_font) layout.addWidget(title) layout.addStretch() # Status-Widget entfernt für cleanes Design return header def create_form_card(self): """Erstellt die Haupt-Formular-Card.""" card = QFrame() card.setObjectName("formCard") card.setStyleSheet(""" #formCard { background-color: white; border: 1px solid #e0e0e0; border-radius: 12px; padding: 30px; } """) layout = QVBoxLayout(card) # Section Title section_title = QLabel("Account-Informationen") section_font = QFont() section_font.setPointSize(16) section_font.setWeight(QFont.DemiBold) section_title.setFont(section_font) layout.addWidget(section_title) layout.addSpacing(20) # Grid-Layout für bessere Anordnung grid = QGridLayout() grid.setHorizontalSpacing(20) grid.setVerticalSpacing(20) # Erste Zeile: Vorname und Nachname self.first_name_label = self.create_label("Vorname") self.first_name_input = self.create_input("z.B. Max") grid.addWidget(self.first_name_label, 0, 0) grid.addWidget(self.first_name_input, 1, 0) self.last_name_label = self.create_label("Nachname") self.last_name_input = self.create_input("z.B. Mustermann") grid.addWidget(self.last_name_label, 0, 1) grid.addWidget(self.last_name_input, 1, 1) # Zweite Zeile: Alter self.age_label = self.create_label("Alter") self.age_input = self.create_input("z.B. 25") grid.addWidget(self.age_label, 2, 0) grid.addWidget(self.age_input, 3, 0) # Dritte Zeile: Registrierungsmethode self.reg_method_label = self.create_label("Registrierungsmethode") grid.addWidget(self.reg_method_label, 4, 0, 1, 2) # Radio Buttons in horizontaler Anordnung radio_widget = QWidget() radio_layout = QHBoxLayout(radio_widget) radio_layout.setContentsMargins(0, 0, 0, 0) self.email_radio = QRadioButton("E-Mail") self.phone_radio = QRadioButton("Telefon") self.email_radio.setChecked(True) # Styling für Radio Buttons radio_style = """ QRadioButton { font-size: 14px; spacing: 8px; } QRadioButton::indicator { width: 18px; height: 18px; } """ self.email_radio.setStyleSheet(radio_style) self.phone_radio.setStyleSheet(radio_style) radio_layout.addWidget(self.email_radio) radio_layout.addWidget(self.phone_radio) radio_layout.addStretch() grid.addWidget(radio_widget, 5, 0, 1, 2) # Vierte Zeile: Kontaktfeld (E-Mail Domain oder Telefon) self.email_domain_label = self.create_label("E-Mail Domain") self.email_domain_input = self.create_input("") self.email_domain_input.setText("z5m7q9dk3ah2v1plx6ju.com") grid.addWidget(self.email_domain_label, 6, 0) grid.addWidget(self.email_domain_input, 7, 0) self.phone_label = self.create_label("Telefonnummer") self.phone_input = self.create_input("z.B. +49123456789") self.phone_label.hide() self.phone_input.hide() grid.addWidget(self.phone_label, 6, 1) grid.addWidget(self.phone_input, 7, 1) layout.addLayout(grid) # Plattform-spezifische Felder self.add_platform_specific_fields(layout) return card def create_options_card(self): """Erstellt die Card für erweiterte Optionen.""" card = QFrame() card.setObjectName("optionsCard") card.setStyleSheet(""" #optionsCard { background-color: white; border: 1px solid #e0e0e0; border-radius: 12px; padding: 30px; } """) layout = QVBoxLayout(card) # Section Title section_title = QLabel("Erweiterte Optionen") section_font = QFont() section_font.setPointSize(16) section_font.setWeight(QFont.DemiBold) section_title.setFont(section_font) layout.addWidget(section_title) layout.addSpacing(15) # Optionen als moderne Checkboxen self.headless_check = self.create_checkbox("Browser im Hintergrund ausführen") self.headless_check.setToolTip("Der Browser wird nicht sichtbar sein") layout.addWidget(self.headless_check) return card def create_action_area(self): """Erstellt den Bereich mit Aktions-Buttons und Progress.""" widget = QWidget() layout = QVBoxLayout(widget) layout.setContentsMargins(0, 0, 0, 0) # Progress Bar (initial versteckt) self.progress_bar = QProgressBar() self.progress_bar.setMinimumHeight(6) self.progress_bar.setTextVisible(False) self.progress_bar.setStyleSheet(""" QProgressBar { background-color: #f0f0f0; border: none; border-radius: 3px; } QProgressBar::chunk { background-color: #2196F3; border-radius: 3px; } """) self.progress_bar.hide() layout.addWidget(self.progress_bar) layout.addSpacing(20) # Buttons button_layout = QHBoxLayout() button_layout.addStretch() self.stop_button = self.create_button("Abbrechen", primary=False) self.stop_button.clicked.connect(self.on_stop_clicked) self.stop_button.setEnabled(False) self.stop_button.hide() button_layout.addWidget(self.stop_button) self.start_button = self.create_button("Account erstellen", primary=True) self.start_button.clicked.connect(self.on_start_clicked) button_layout.addWidget(self.start_button) layout.addLayout(button_layout) return widget def create_label(self, text): """Erstellt ein modernes Label.""" label = QLabel(text) label.setStyleSheet(""" QLabel { color: #666; font-size: 13px; font-weight: 500; } """) return label def create_input(self, placeholder=""): """Erstellt ein modernes Input-Feld.""" input_field = QLineEdit() input_field.setPlaceholderText(placeholder) input_field.setMinimumHeight(42) input_field.setStyleSheet(""" QLineEdit { border: 2px solid #e0e0e0; border-radius: 8px; padding: 10px 15px; font-size: 14px; background-color: #fafafa; } QLineEdit:focus { border-color: #2196F3; background-color: white; } QLineEdit:hover { border-color: #bdbdbd; } """) return input_field def create_checkbox(self, text): """Erstellt eine moderne Checkbox.""" checkbox = QCheckBox(text) checkbox.setStyleSheet(""" QCheckBox { font-size: 14px; color: #333; spacing: 10px; } QCheckBox::indicator { width: 20px; height: 20px; border-radius: 4px; border: 2px solid #e0e0e0; background-color: white; } QCheckBox::indicator:checked { background-color: #2196F3; border-color: #2196F3; image: url(check_white.png); } QCheckBox::indicator:hover { border-color: #2196F3; } """) return checkbox def create_button(self, text, primary=False): """Erstellt einen modernen Button.""" button = QPushButton(text) button.setMinimumHeight(45) button.setCursor(Qt.PointingHandCursor) if primary: button.setStyleSheet(""" QPushButton { background-color: #2196F3; color: white; border: none; border-radius: 8px; padding: 12px 32px; font-size: 14px; font-weight: 600; } QPushButton:hover { background-color: #1976D2; } QPushButton:pressed { background-color: #0D47A1; } QPushButton:disabled { background-color: #BBBBBB; } """) else: button.setStyleSheet(""" QPushButton { background-color: white; color: #666; border: 2px solid #e0e0e0; border-radius: 8px; padding: 12px 32px; font-size: 14px; font-weight: 500; } QPushButton:hover { border-color: #bdbdbd; background-color: #f5f5f5; } QPushButton:pressed { background-color: #eeeeee; } QPushButton:disabled { color: #BBBBBB; border-color: #eeeeee; } """) return button def add_platform_specific_fields(self, parent_layout): """Fügt plattformspezifische Felder hinzu.""" platform = self.platform_name.lower() def toggle_phone_input(self): """Wechselt zwischen E-Mail und Telefon-Eingabe.""" if self.email_radio.isChecked(): self.email_domain_label.show() self.email_domain_input.show() self.phone_label.hide() self.phone_input.hide() else: self.email_domain_label.hide() self.email_domain_input.hide() self.phone_label.show() self.phone_input.show() def on_start_clicked(self): """Wird aufgerufen, wenn der Start-Button geklickt wird.""" params = self.get_params() valid, error_msg = self.validate_inputs(params) if not valid: self.show_error(error_msg) return # UI für laufenden Prozess anpassen self.set_running(True) self.progress_bar.show() self.progress_bar.setValue(0) # Signal auslösen self.start_requested.emit(params) def on_stop_clicked(self): """Wird aufgerufen, wenn der Stop-Button geklickt wird.""" self.stop_requested.emit() def get_params(self): """Sammelt alle Parameter für die Account-Erstellung.""" first_name = self.first_name_input.text().strip() last_name = self.last_name_input.text().strip() full_name = f"{first_name} {last_name}" params = { "first_name": first_name, "last_name": last_name, "full_name": full_name, "age_text": self.age_input.text().strip(), "registration_method": "email" if self.email_radio.isChecked() else "phone", "headless": self.headless_check.isChecked(), "debug": True, "email_domain": self.email_domain_input.text().strip(), "use_proxy": False } if self.phone_radio.isChecked(): params["phone_number"] = self.phone_input.text().strip() return params def validate_inputs(self, params): """Validiert die Eingaben.""" if not params.get("first_name"): return False, "Bitte geben Sie einen Vornamen ein." if not params.get("last_name"): return False, "Bitte geben Sie einen Nachnamen ein." age_text = params.get("age_text", "") if not age_text: return False, "Bitte geben Sie ein Alter ein." try: age = int(age_text) params["age"] = age except ValueError: return False, "Das Alter muss eine ganze Zahl sein." if age < 13 or age > 99: return False, "Das Alter muss zwischen 13 und 99 liegen." if params.get("registration_method") == "phone" and not params.get("phone_number"): return False, "Bitte geben Sie eine Telefonnummer ein." return True, "" def set_running(self, running: bool): """Setzt den Status auf 'Wird ausgeführt' oder 'Bereit'.""" if running: self.start_button.hide() self.stop_button.show() self.stop_button.setEnabled(True) # Status-Dot entfernt # Status-Text entfernt else: self.start_button.show() self.stop_button.hide() self.stop_button.setEnabled(False) self.progress_bar.hide() # Status-Dot entfernt # Status-Text entfernt def set_progress(self, value: int): """Setzt den Fortschritt.""" self.progress_bar.setValue(value) def set_status(self, message: str): """Setzt die Statusnachricht.""" # Status-Text entfernt logger.info(f"Status: {message}") def show_error(self, message: str): """Zeigt eine moderne Fehlermeldung an.""" from views.widgets.modern_message_box import show_error show_error(self, "Fehler", message) def update_texts(self): """Aktualisiert UI-Texte gemäß der aktuellen Sprache.""" # Hier würden die Übersetzungen implementiert pass