Changes:
- Add next-themes dependency for theme management
- Create ThemeProvider wrapper for app root layout
- Set dark mode as default theme
- Create ThemeToggle component with Sun/Moon icons
- Add theme toggle to home page navigation
- Add theme toggle to dashboard header
- App now starts in dark mode with ability to switch to light mode
Styling uses existing Tailwind dark mode variables configured in
tailwind.config.ts and globals.css. All existing components automatically
support dark theme.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
"""
|
||
Logging configuration for E-Voting Backend.
|
||
|
||
Provides structured logging with appropriate levels for different modules.
|
||
"""
|
||
|
||
import logging
|
||
import sys
|
||
from datetime import datetime
|
||
|
||
# Create custom formatter with emojis and colors
|
||
class ColoredFormatter(logging.Formatter):
|
||
"""Custom formatter with colors and emojis for better visibility"""
|
||
|
||
# ANSI color codes
|
||
COLORS = {
|
||
'DEBUG': '\033[36m', # Cyan
|
||
'INFO': '\033[32m', # Green
|
||
'WARNING': '\033[33m', # Yellow
|
||
'ERROR': '\033[31m', # Red
|
||
'CRITICAL': '\033[35m', # Magenta
|
||
}
|
||
RESET = '\033[0m'
|
||
|
||
# Emoji prefixes
|
||
EMOJIS = {
|
||
'DEBUG': '🔍',
|
||
'INFO': 'ℹ️ ',
|
||
'WARNING': '⚠️ ',
|
||
'ERROR': '❌',
|
||
'CRITICAL': '🔥',
|
||
}
|
||
|
||
def format(self, record):
|
||
# Add color and emoji
|
||
levelname = record.levelname
|
||
emoji = self.EMOJIS.get(levelname, '')
|
||
color = self.COLORS.get(levelname, '')
|
||
|
||
# Format message
|
||
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||
formatted = f"{color}{emoji} {timestamp} - {record.name} - {levelname} - {record.getMessage()}{self.RESET}"
|
||
|
||
# Add exception info if present
|
||
if record.exc_info:
|
||
formatted += f"\n{self.format_exception(record.exc_info)}"
|
||
|
||
return formatted
|
||
|
||
def format_exception(self, exc_info):
|
||
"""Format exception info"""
|
||
import traceback
|
||
return '\n'.join(traceback.format_exception(*exc_info))
|
||
|
||
|
||
def setup_logging(level=logging.INFO):
|
||
"""
|
||
Setup logging for the entire application.
|
||
|
||
Args:
|
||
level: Logging level (default: logging.INFO)
|
||
"""
|
||
# Remove existing handlers
|
||
root_logger = logging.getLogger()
|
||
for handler in root_logger.handlers[:]:
|
||
root_logger.removeHandler(handler)
|
||
|
||
# Create console handler with colored formatter
|
||
console_handler = logging.StreamHandler(sys.stdout)
|
||
console_handler.setLevel(level)
|
||
formatter = ColoredFormatter()
|
||
console_handler.setFormatter(formatter)
|
||
|
||
# Add handler to root logger
|
||
root_logger.addHandler(console_handler)
|
||
root_logger.setLevel(level)
|
||
|
||
# Set specific loggers
|
||
logging.getLogger('backend').setLevel(level)
|
||
logging.getLogger('backend.blockchain_elections').setLevel(logging.DEBUG)
|
||
logging.getLogger('backend.init_blockchain').setLevel(logging.INFO)
|
||
logging.getLogger('backend.services').setLevel(logging.INFO)
|
||
logging.getLogger('backend.main').setLevel(logging.INFO)
|
||
|
||
# Suppress verbose third-party logging
|
||
logging.getLogger('sqlalchemy.engine').setLevel(logging.ERROR)
|
||
logging.getLogger('sqlalchemy.pool').setLevel(logging.ERROR)
|
||
logging.getLogger('sqlalchemy.dialects').setLevel(logging.ERROR)
|
||
logging.getLogger('uvicorn').setLevel(logging.INFO)
|
||
logging.getLogger('uvicorn.access').setLevel(logging.WARNING)
|
||
|
||
|
||
# Setup logging on import
|
||
setup_logging()
|