Add CmdForge welcome page to sidebar

- Create welcome_page.py with branded landing page
- Add quick action cards for common tasks (Create Tool, Registry, etc.)
- Add "CmdForge" entry at top of sidebar navigation
- Update page indices for navigation

Co-Authored-By: Claude Opus 4.5 <[email protected]>
This commit is contained in:
rob
2026-01-15 22:18:00 -04:00
co-authored by Claude Opus 4.5
parent 88c9a8a1e7
commit 4d9a0e5943
3 changed files with 193 additions and 6 deletions
+175
View File
@@ -0,0 +1,175 @@
"""Welcome page - CmdForge landing page."""
from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
QFrame, QGridLayout, QSizePolicy
)
from PySide6.QtCore import Qt
class WelcomePage(QWidget):
"""CmdForge welcome/landing page."""
def __init__(self, main_window):
super().__init__()
self.main_window = main_window
self._setup_ui()
def _setup_ui(self):
"""Set up the UI."""
layout = QVBoxLayout(self)
layout.setContentsMargins(48, 48, 48, 48)
layout.setSpacing(32)
# Top spacer
layout.addStretch(1)
# Logo/title
title = QLabel("CmdForge")
title.setStyleSheet("""
font-size: 48px;
font-weight: bold;
color: #667eea;
""")
title.setAlignment(Qt.AlignCenter)
layout.addWidget(title)
# Tagline
tagline = QLabel("Build AI-powered command-line tools")
tagline.setStyleSheet("""
font-size: 18px;
color: #718096;
""")
tagline.setAlignment(Qt.AlignCenter)
layout.addWidget(tagline)
layout.addSpacing(24)
# Quick actions
actions_container = QWidget()
actions_container.setMaximumWidth(600)
actions_layout = QGridLayout(actions_container)
actions_layout.setSpacing(16)
# Create tool card
create_card = self._create_action_card(
"Create Tool",
"Build a new AI-powered command-line tool with prompts, code, and data flow",
"New Tool",
self._on_create_tool
)
actions_layout.addWidget(create_card, 0, 0)
# Browse registry card
registry_card = self._create_action_card(
"Browse Registry",
"Discover and install tools shared by the community",
"Open Registry",
self._on_browse_registry
)
actions_layout.addWidget(registry_card, 0, 1)
# Manage tools card
tools_card = self._create_action_card(
"My Tools",
"View, edit, and run your existing tools",
"Open Tools",
self._on_open_tools
)
actions_layout.addWidget(tools_card, 1, 0)
# Providers card
providers_card = self._create_action_card(
"AI Providers",
"Configure AI backends like Claude, GPT, and custom providers",
"Configure",
self._on_open_providers
)
actions_layout.addWidget(providers_card, 1, 1)
# Center the actions container
actions_wrapper = QHBoxLayout()
actions_wrapper.addStretch()
actions_wrapper.addWidget(actions_container)
actions_wrapper.addStretch()
layout.addLayout(actions_wrapper)
# Bottom spacer
layout.addStretch(2)
# Footer
footer = QLabel("CmdForge - AI Tool Builder")
footer.setStyleSheet("color: #a0aec0; font-size: 12px;")
footer.setAlignment(Qt.AlignCenter)
layout.addWidget(footer)
def _create_action_card(self, title: str, description: str, button_text: str, callback) -> QFrame:
"""Create an action card widget."""
card = QFrame()
card.setStyleSheet("""
QFrame {
background-color: white;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 16px;
}
QFrame:hover {
border-color: #667eea;
}
""")
card.setMinimumSize(260, 140)
layout = QVBoxLayout(card)
layout.setContentsMargins(16, 16, 16, 16)
layout.setSpacing(8)
# Title
title_label = QLabel(title)
title_label.setStyleSheet("font-size: 16px; font-weight: 600; color: #2d3748; border: none;")
layout.addWidget(title_label)
# Description
desc_label = QLabel(description)
desc_label.setWordWrap(True)
desc_label.setStyleSheet("font-size: 13px; color: #718096; border: none;")
layout.addWidget(desc_label, 1)
# Button
btn = QPushButton(button_text)
btn.clicked.connect(callback)
btn.setStyleSheet("""
QPushButton {
background-color: #667eea;
color: white;
border: none;
border-radius: 4px;
padding: 8px 16px;
font-weight: 500;
}
QPushButton:hover {
background-color: #5a67d8;
}
""")
layout.addWidget(btn)
return card
def _on_create_tool(self):
"""Handle create tool action."""
self.main_window.open_tool_builder()
def _on_browse_registry(self):
"""Handle browse registry action."""
self.main_window.navigate_to("registry")
def _on_open_tools(self):
"""Handle open tools action."""
self.main_window.navigate_to("tools")
def _on_open_providers(self):
"""Handle open providers action."""
self.main_window.navigate_to("providers")
def refresh(self):
"""Refresh the page (nothing to refresh)."""
pass