import os import re from PyQt6.QtWidgets import ( QButtonGroup, QFrame, QLabel, QMessageBox, QPushButton, QTextEdit, ) from PyQt6.QtGui import QIcon, QPixmap from PyQt6.QtCore import Qt from PyQt6 import QtCore from core.services.payment_phase.do_we_have_billing_id import do_we_have_billing_id from gui.v2.ui.pages.Page import Page from gui.v2.ui.popups.message_box import style_message_box, mark_confirm_button HOW_MANY_PROFILES_DEFAULT = 6 class IdPage(Page): def __init__(self, page_stack, main_window=None, parent=None): super().__init__("Id", page_stack, main_window, parent) self.update_status = main_window self.btn_path = main_window.btn_path self.buttonGroup = QButtonGroup(self) self.display.setGeometry(QtCore.QRect(-10, 50, 550, 460)) self.create_interface_elements() self.connect_button = QPushButton(self) self.connect_button.setObjectName("connect_button") self.connect_button.setGeometry(625, 450, 90, 50) self.connect_button.setIconSize(self.connect_button.size()) tor_icon = QIcon(os.path.join(self.btn_path, "connect.png")) self.connect_button.setIcon(tor_icon) self.connect_button.clicked.connect(self.on_connect) self.connect_button.setDisabled(True) self.button_reverse.setVisible(True) def on_connect(self): text = self.text_edit.toPlainText() pattern = r'^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$' if re.match(pattern, text): self.update_status.update_status('Enabling profile in progress...') profile_data = { 'id': int(self.update_status.current_profile_id), 'billing_code': str(text) } menu_page = self.find_menu_page() if menu_page: menu_page.enabling_profile(profile_data) else: self.update_status.update_status( 'Incorrect format for the billing code') def find_menu_page(self): return self.custom_window.navigator.get_cached("menu") def create_interface_elements(self): self.object_selected = None self.display.setGeometry(QtCore.QRect(0, 0, 0, 0)) self.button_reverse.clicked.connect(self.reverse) self.button_go.clicked.connect(self.go_selected) column_title_style = "color: #00ffff; font-size: 18px; font-weight: bold;" column_button_style = """ QPushButton { background-color: #000000; color: #00ffff; border: 2px solid #00ffff; border-radius: 10px; font-size: 15px; font-weight: bold; padding: 10px; } QPushButton:hover { background-color: #003333; } """ column_desc_style = "color: #888888; font-size: 12px; font-style: italic;" self.single_title = QLabel("Single Profile", self) self.single_title.setGeometry(15, 50, 240, 40) self.single_title.setStyleSheet(column_title_style) self.single_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.single_button = QPushButton("One Profile Only", self) self.single_button.setGeometry(40, 220, 200, 100) self.single_button.setStyleSheet(column_button_style) self.single_button.clicked.connect(self.go_single_profile) self.single_desc = QLabel("Buy a single billing for one profile.", self) self.single_desc.setGeometry(15, 335, 240, 40) self.single_desc.setStyleSheet(column_desc_style) self.single_desc.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.single_desc.setWordWrap(True) self.multiple_title = QLabel("Multiple Profiles", self) self.multiple_title.setGeometry(285, 50, 240, 40) self.multiple_title.setStyleSheet(column_title_style) self.multiple_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.multiple_button = QPushButton("Multiple Profiles\nat Once", self) self.multiple_button.setGeometry(310, 220, 200, 100) self.multiple_button.setStyleSheet(column_button_style) self.multiple_button.clicked.connect(self.go_multiple_profiles) self.multiple_desc = QLabel( f"Buy a bundle of {HOW_MANY_PROFILES_DEFAULT} tickets at once, which are cryptographically seperated from each other.", self) self.multiple_desc.setGeometry(285, 335, 240, 80) self.multiple_desc.setStyleSheet(column_desc_style) self.multiple_desc.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.multiple_desc.setWordWrap(True) self.title = QLabel("Use Existing", self) self.title.setGeometry(QtCore.QRect(555, 50, 230, 40)) self.title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.title.setStyleSheet(column_title_style) self.note_label = QLabel( "Billing IDs are tied to a single location", self) self.note_label.setGeometry(555, 90, 230, 50) self.note_label.setStyleSheet(column_desc_style) self.note_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.note_label.setWordWrap(True) self.note_label.show() self.id_bg_label = QLabel(self) self.id_bg_label.setGeometry(550, 220, 250, 220) self.id_bg_label.setPixmap(QPixmap(os.path.join(self.btn_path, "button230x220.png")).scaled( self.id_bg_label.size(), Qt.AspectRatioMode.KeepAspectRatio)) self.text_edit = QTextEdit(self) self.text_edit.setGeometry(550, 230, 230, 190) self.text_edit.setPlaceholderText("Enter your existing billing Id here") self.text_edit.textChanged.connect(self.toggle_button_state) separator_style = "color: #00ffff; background-color: #00ffff;" self.separator_left = QFrame(self) self.separator_left.setFrameShape(QFrame.Shape.VLine) self.separator_left.setFrameShadow(QFrame.Shadow.Plain) self.separator_left.setGeometry(270, 60, 2, 420) self.separator_left.setStyleSheet(separator_style) self.separator_right = QFrame(self) self.separator_right.setFrameShape(QFrame.Shape.VLine) self.separator_right.setFrameShadow(QFrame.Shadow.Plain) self.separator_right.setGeometry(540, 60, 2, 420) self.separator_right.setStyleSheet(separator_style) def go_single_profile(self): self.text_edit.clear() self.custom_window.navigator.navigate("duration_selection") def go_multiple_profiles(self): billing_id = do_we_have_billing_id() if billing_id: self._prompt_existing_tickets(billing_id) else: self._continue_multiple_flow() def _continue_multiple_flow(self): self.custom_window.navigator.navigate("plan_picker") plan_page = self.custom_window.navigator.get_cached("plan_picker") if plan_page is not None: plan_page.start_sync() def _prompt_existing_tickets(self, billing_id): box = QMessageBox(self) box.setWindowTitle("Existing ticket purchase found") box.setText( "You already have a pending ticket purchase. Continue to check if it's paid, " "or wipe it and start over?") style_message_box(box) check_button = box.addButton( "Check payment", QMessageBox.ButtonRole.AcceptRole) mark_confirm_button(check_button) wipe_button = box.addButton( "Wipe and start over", QMessageBox.ButtonRole.DestructiveRole) box.exec() clicked = box.clickedButton() if clicked == check_button: self._resume_existing_ticket(billing_id) elif clicked == wipe_button: self._continue_multiple_flow() def _resume_existing_ticket(self, billing_id): self.update_status.update_status("Checking existing ticket payment...") self.custom_window.navigator.navigate("payment_details") payment_page = self.custom_window.navigator.get_cached("payment_details") if payment_page is not None: payment_page.resume_ticket_billing(billing_id) def toggle_button_state(self): text = self.text_edit.toPlainText() if text.strip(): self.connect_button.setEnabled(True) else: self.connect_button.setEnabled(False) def show_next(self): self.text_edit.clear() self.custom_window.navigator.navigate("duration_selection") def validate_password(self): self.button_go.setVisible(False) text = self.text_edit.toPlainText().strip().lower() if text == "zenaku": self.button_go.setVisible(True) def show_object_selected(self, function, page_class): function() self.object_selected = page_class def go_selected(self): if self.object_selected: self.custom_window.navigator.navigate(self.object_selected) self.display.clear() for boton in self.buttons: boton.setChecked(False) self.button_go.setVisible(False) def reverse(self): self.custom_window.navigator.navigate("menu")