soulsync/ui/pages/dashboard.py
2025-07-09 12:07:41 -07:00

220 lines
No EOL
7.5 KiB
Python

from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QFrame, QGridLayout, QScrollArea, QSizePolicy)
from PyQt6.QtCore import Qt, QTimer
from PyQt6.QtGui import QFont, QPalette
class StatCard(QFrame):
def __init__(self, title: str, value: str, subtitle: str = "", parent=None):
super().__init__(parent)
self.setup_ui(title, value, subtitle)
def setup_ui(self, title: str, value: str, subtitle: str):
self.setFixedHeight(120)
self.setStyleSheet("""
StatCard {
background: #282828;
border-radius: 8px;
border: 1px solid #404040;
}
StatCard:hover {
background: #333333;
border: 1px solid #1db954;
}
""")
layout = QVBoxLayout(self)
layout.setContentsMargins(20, 15, 20, 15)
layout.setSpacing(5)
# Title
title_label = QLabel(title)
title_label.setFont(QFont("Arial", 10))
title_label.setStyleSheet("color: #b3b3b3;")
# Value
value_label = QLabel(value)
value_label.setFont(QFont("Arial", 24, QFont.Weight.Bold))
value_label.setStyleSheet("color: #ffffff;")
# Subtitle
if subtitle:
subtitle_label = QLabel(subtitle)
subtitle_label.setFont(QFont("Arial", 9))
subtitle_label.setStyleSheet("color: #b3b3b3;")
layout.addWidget(subtitle_label)
layout.addWidget(title_label)
layout.addWidget(value_label)
layout.addStretch()
class ActivityItem(QWidget):
def __init__(self, icon: str, title: str, subtitle: str, time: str, parent=None):
super().__init__(parent)
self.setup_ui(icon, title, subtitle, time)
def setup_ui(self, icon: str, title: str, subtitle: str, time: str):
self.setFixedHeight(60)
layout = QHBoxLayout(self)
layout.setContentsMargins(15, 10, 15, 10)
layout.setSpacing(15)
# Icon
icon_label = QLabel(icon)
icon_label.setFixedSize(32, 32)
icon_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
icon_label.setStyleSheet("""
QLabel {
color: #1db954;
font-size: 18px;
background: rgba(29, 185, 84, 0.1);
border-radius: 16px;
}
""")
# Text content
text_layout = QVBoxLayout()
text_layout.setSpacing(2)
title_label = QLabel(title)
title_label.setFont(QFont("Arial", 10, QFont.Weight.Medium))
title_label.setStyleSheet("color: #ffffff;")
subtitle_label = QLabel(subtitle)
subtitle_label.setFont(QFont("Arial", 9))
subtitle_label.setStyleSheet("color: #b3b3b3;")
text_layout.addWidget(title_label)
text_layout.addWidget(subtitle_label)
# Time
time_label = QLabel(time)
time_label.setFont(QFont("Arial", 9))
time_label.setStyleSheet("color: #b3b3b3;")
time_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop)
layout.addWidget(icon_label)
layout.addLayout(text_layout)
layout.addStretch()
layout.addWidget(time_label)
class DashboardPage(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
def setup_ui(self):
self.setStyleSheet("""
DashboardPage {
background: #191414;
}
""")
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(30, 30, 30, 30)
main_layout.setSpacing(30)
# Header
header = self.create_header()
main_layout.addWidget(header)
# Stats grid
stats_grid = self.create_stats_grid()
main_layout.addWidget(stats_grid)
# Recent activity
activity_section = self.create_activity_section()
main_layout.addWidget(activity_section)
main_layout.addStretch()
def create_header(self):
header = QWidget()
layout = QVBoxLayout(header)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(5)
# Welcome message
welcome_label = QLabel("Welcome back!")
welcome_label.setFont(QFont("Arial", 28, QFont.Weight.Bold))
welcome_label.setStyleSheet("color: #ffffff;")
# Subtitle
subtitle_label = QLabel("Here's what's happening with your music library")
subtitle_label.setFont(QFont("Arial", 14))
subtitle_label.setStyleSheet("color: #b3b3b3;")
layout.addWidget(welcome_label)
layout.addWidget(subtitle_label)
return header
def create_stats_grid(self):
stats_widget = QWidget()
grid = QGridLayout(stats_widget)
grid.setSpacing(20)
# Sample stats - these will be populated with real data later
stats = [
("Spotify Playlists", "12", "3 synced today"),
("Plex Tracks", "2,847", "156 added this week"),
("Missing Tracks", "23", "Ready to download"),
("Artists Scanned", "89", "Metadata updated"),
("Downloads", "5", "In progress"),
("Sync Status", "98%", "Up to date")
]
for i, (title, value, subtitle) in enumerate(stats):
card = StatCard(title, value, subtitle)
grid.addWidget(card, i // 3, i % 3)
return stats_widget
def create_activity_section(self):
activity_widget = QWidget()
layout = QVBoxLayout(activity_widget)
layout.setSpacing(15)
# Section header
header_label = QLabel("Recent Activity")
header_label.setFont(QFont("Arial", 16, QFont.Weight.Bold))
header_label.setStyleSheet("color: #ffffff;")
# Activity container
activity_container = QFrame()
activity_container.setStyleSheet("""
QFrame {
background: #282828;
border-radius: 8px;
border: 1px solid #404040;
}
""")
activity_layout = QVBoxLayout(activity_container)
activity_layout.setContentsMargins(0, 0, 0, 0)
activity_layout.setSpacing(1)
# Sample activity items
activities = [
("🔄", "Playlist Sync", "Synced 'Favorites' playlist to Plex", "2 min ago"),
("📥", "Download Complete", "Downloaded 'Song Title' by Artist", "5 min ago"),
("🎵", "Artist Updated", "Updated metadata for 'Artist Name'", "1 hour ago"),
("", "Sync Complete", "All playlists synchronized successfully", "3 hours ago"),
("📊", "Library Scan", "Scanned 156 new tracks in Plex", "1 day ago")
]
for icon, title, subtitle, time in activities:
item = ActivityItem(icon, title, subtitle, time)
activity_layout.addWidget(item)
# Add separator (except for last item)
if (icon, title, subtitle, time) != activities[-1]:
separator = QFrame()
separator.setFixedHeight(1)
separator.setStyleSheet("background: #404040;")
activity_layout.addWidget(separator)
layout.addWidget(header_label)
layout.addWidget(activity_container)
return activity_widget