feat: Integrate global CyberMood theme into core modules
Migrated three core modules to use the global secubox-theme package:
Modules Updated:
- luci-app-secubox (dashboard, modules views)
- luci-app-network-modes (overview view)
- luci-app-system-hub (overview, services views)
Changes Per Module:
- Replaced module-specific theme imports with 'require secubox-theme/theme as Theme'
- Updated CSS imports to use global secubox-theme.css bundle
- Initialized global theme with Theme.init({ theme: 'dark', language: 'en' })
- Removed redundant theme.getTheme() calls from load() functions
- Added global theme CSS link tags to view renders
Benefits:
- Unified CyberMood design system across all modules
- Access to 100+ CSS variables (colors, spacing, effects)
- Theme switching support (dark, light, cyberpunk)
- Multi-language support (en, fr, de, es) via Theme.t()
- Reduced CSS duplication
- Consistent UI components (cards, buttons, badges)
Deployment:
- Created deploy-modules-with-theme.sh for batch deployment
- All modules successfully deployed to router 192.168.8.191
- Verified HTTP access to updated JavaScript files
Testing:
- ✅ SecuBox dashboard loads with global theme
- ✅ Network-modes overview uses theme CSS
- ✅ System-hub views integrate theme properly
- ✅ All 27 view files deployed successfully
Next Steps:
- Modules can now use Theme.createCard(), createButton(), createBadge()
- Translation keys available for internationalization
- Theme variants switchable via Theme.apply('dark'|'light'|'cyberpunk')
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a0c8d65472
commit
b884b12970
109
deploy-modules-with-theme.sh
Executable file
109
deploy-modules-with-theme.sh
Executable file
@ -0,0 +1,109 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy luci-app-secubox, network-modes, and system-hub with global theme support
|
||||
# Usage: ./deploy-modules-with-theme.sh [router_host]
|
||||
|
||||
set -e
|
||||
|
||||
ROUTER_HOST="${1:-root@192.168.8.191}"
|
||||
MODULES="luci-app-secubox luci-app-network-modes luci-app-system-hub"
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Deploying SecuBox modules with global theme to $ROUTER_HOST"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Modules: secubox, network-modes, system-hub"
|
||||
echo "Theme: Global CyberMood (secubox-theme)"
|
||||
echo ""
|
||||
|
||||
for MODULE in $MODULES; do
|
||||
MODULE_NAME=$(basename "$MODULE" | sed 's/luci-app-//')
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📦 Deploying $MODULE_NAME"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# Create backup on router
|
||||
echo "📦 Creating backup..."
|
||||
ssh "$ROUTER_HOST" "if [ -d '/www/luci-static/resources/$MODULE_NAME' ]; then \
|
||||
cp -r '/www/luci-static/resources/$MODULE_NAME' '/www/luci-static/resources/$MODULE_NAME.bak.$(date +%Y%m%d_%H%M%S)'; \
|
||||
echo '✓ Backup created'; \
|
||||
else \
|
||||
echo '✓ No existing module to backup'; \
|
||||
fi"
|
||||
|
||||
# Create tarball
|
||||
echo "📦 Creating tarball..."
|
||||
TARBALL="/tmp/${MODULE_NAME}-$(date +%Y%m%d_%H%M%S).tar.gz"
|
||||
(cd "$MODULE/htdocs/luci-static/resources" && tar czf "$TARBALL" "$MODULE_NAME" "view/$MODULE_NAME")
|
||||
|
||||
# Upload
|
||||
echo "🚀 Uploading to router..."
|
||||
scp "$TARBALL" "$ROUTER_HOST:/tmp/${MODULE_NAME}.tar.gz"
|
||||
|
||||
# Extract
|
||||
echo "📂 Extracting..."
|
||||
ssh "$ROUTER_HOST" "cd /www/luci-static/resources && tar xzf /tmp/${MODULE_NAME}.tar.gz && rm /tmp/${MODULE_NAME}.tar.gz"
|
||||
|
||||
# Set permissions
|
||||
echo "🔐 Setting permissions..."
|
||||
ssh "$ROUTER_HOST" "find /www/luci-static/resources/$MODULE_NAME -type f -name '*.css' -exec chmod 644 {} \; && \
|
||||
find /www/luci-static/resources/$MODULE_NAME -type f -name '*.js' -exec chmod 644 {} \; && \
|
||||
find /www/luci-static/resources/$MODULE_NAME -type d -exec chmod 755 {} \; && \
|
||||
find /www/luci-static/resources/view/$MODULE_NAME -type f -name '*.js' -exec chmod 644 {} \; && \
|
||||
find /www/luci-static/resources/view/$MODULE_NAME -type d -exec chmod 755 {} \;"
|
||||
|
||||
# Cleanup
|
||||
rm -f "$TARBALL"
|
||||
|
||||
echo "✅ $MODULE_NAME deployed"
|
||||
echo ""
|
||||
done
|
||||
|
||||
# Clear LuCI cache
|
||||
echo "🧹 Clearing LuCI cache..."
|
||||
ssh "$ROUTER_HOST" "rm -rf /tmp/luci-*"
|
||||
|
||||
# Restart services
|
||||
echo "🔄 Restarting services..."
|
||||
ssh "$ROUTER_HOST" "/etc/init.d/uhttpd restart"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ Verification"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
for MODULE in $MODULES; do
|
||||
MODULE_NAME=$(basename "$MODULE" | sed 's/luci-app-//')
|
||||
echo "📦 $MODULE_NAME:"
|
||||
ssh "$ROUTER_HOST" "if [ -d '/www/luci-static/resources/$MODULE_NAME' ]; then \
|
||||
echo ' ✅ Module files: OK'; \
|
||||
echo ' ✅ Views: \$(find /www/luci-static/resources/view/$MODULE_NAME -name \"*.js\" | wc -l) files'; \
|
||||
else \
|
||||
echo ' ❌ Module deployment failed'; \
|
||||
fi"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Theme status:"
|
||||
ssh "$ROUTER_HOST" "if [ -f '/www/luci-static/resources/secubox-theme/theme.js' ]; then \
|
||||
echo ' ✅ Global theme: Available'; \
|
||||
else \
|
||||
echo ' ⚠️ Global theme: Not found (run ./deploy-theme.sh first)'; \
|
||||
fi"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ Deployment complete!"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "📋 Updated modules now use:"
|
||||
echo " - 'require secubox-theme/theme as Theme'"
|
||||
echo " - Global CyberMood CSS variables"
|
||||
echo " - Dark/Light/Cyberpunk theme variants"
|
||||
echo " - Multi-language support (en, fr, de, es)"
|
||||
echo ""
|
||||
echo "🌐 Access modules:"
|
||||
echo " - SecuBox: http://$ROUTER_HOST/cgi-bin/luci/admin/secubox"
|
||||
echo " - Network Modes: http://$ROUTER_HOST/cgi-bin/luci/admin/secubox/network-modes"
|
||||
echo " - System Hub: http://$ROUTER_HOST/cgi-bin/luci/admin/secubox/system-hub"
|
||||
echo ""
|
||||
93
deploy-theme.sh
Executable file
93
deploy-theme.sh
Executable file
@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy luci-theme-secubox to OpenWrt router
|
||||
# Usage: ./deploy-theme.sh [router_host]
|
||||
|
||||
set -e
|
||||
|
||||
ROUTER_HOST="${1:-root@192.168.8.191}"
|
||||
THEME_DIR="luci-theme-secubox"
|
||||
TARGET_BASE="/www/luci-static/resources"
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Deploying luci-theme-secubox to $ROUTER_HOST"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# Check if theme directory exists
|
||||
if [ ! -d "$THEME_DIR" ]; then
|
||||
echo "❌ Error: $THEME_DIR directory not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create backup on router
|
||||
echo "📦 Creating backup..."
|
||||
ssh "$ROUTER_HOST" "if [ -d '$TARGET_BASE/secubox-theme' ]; then \
|
||||
cp -r '$TARGET_BASE/secubox-theme' '$TARGET_BASE/secubox-theme.bak.$(date +%Y%m%d_%H%M%S)'; \
|
||||
echo '✓ Backup created'; \
|
||||
else \
|
||||
echo '✓ No existing theme to backup'; \
|
||||
fi"
|
||||
|
||||
# Create target directory
|
||||
echo "📁 Creating target directory..."
|
||||
ssh "$ROUTER_HOST" "mkdir -p '$TARGET_BASE'"
|
||||
|
||||
# Create tarball of theme files
|
||||
echo "📦 Creating theme tarball..."
|
||||
TARBALL="/tmp/secubox-theme-$(date +%Y%m%d_%H%M%S).tar.gz"
|
||||
(cd "$THEME_DIR/htdocs/luci-static/resources" && tar czf "$TARBALL" secubox-theme/)
|
||||
|
||||
# Copy to router
|
||||
echo "🚀 Uploading theme to router..."
|
||||
scp "$TARBALL" "$ROUTER_HOST:/tmp/secubox-theme.tar.gz"
|
||||
|
||||
# Extract on router
|
||||
echo "📂 Extracting theme..."
|
||||
ssh "$ROUTER_HOST" "cd '$TARGET_BASE' && tar xzf /tmp/secubox-theme.tar.gz && rm /tmp/secubox-theme.tar.gz"
|
||||
|
||||
# Set correct permissions
|
||||
echo "🔐 Setting permissions..."
|
||||
ssh "$ROUTER_HOST" "find '$TARGET_BASE/secubox-theme' -type f -name '*.css' -exec chmod 644 {} \; && \
|
||||
find '$TARGET_BASE/secubox-theme' -type f -name '*.js' -exec chmod 644 {} \; && \
|
||||
find '$TARGET_BASE/secubox-theme' -type f -name '*.json' -exec chmod 644 {} \; && \
|
||||
find '$TARGET_BASE/secubox-theme' -type d -exec chmod 755 {} \;"
|
||||
|
||||
# Clear LuCI cache
|
||||
echo "🧹 Clearing LuCI cache..."
|
||||
ssh "$ROUTER_HOST" "rm -rf /tmp/luci-*"
|
||||
|
||||
# Restart services
|
||||
echo "🔄 Restarting services..."
|
||||
ssh "$ROUTER_HOST" "/etc/init.d/uhttpd restart"
|
||||
|
||||
# Cleanup local tarball
|
||||
rm -f "$TARBALL"
|
||||
|
||||
# Verify installation
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ Verification"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
ssh "$ROUTER_HOST" "if [ -f '$TARGET_BASE/secubox-theme/theme.js' ]; then \
|
||||
echo '✅ Theme controller: OK'; \
|
||||
echo '✅ CSS files: \$(find $TARGET_BASE/secubox-theme -name \"*.css\" | wc -l)'; \
|
||||
echo '✅ JS files: \$(find $TARGET_BASE/secubox-theme -name \"*.js\" | wc -l)'; \
|
||||
echo '✅ Translation files: \$(find $TARGET_BASE/secubox-theme/i18n -name \"*.json\" | wc -l)'; \
|
||||
else \
|
||||
echo '❌ Theme installation failed'; \
|
||||
exit 1; \
|
||||
fi"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ Theme deployed successfully!"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "📋 Usage in modules:"
|
||||
echo " 'require secubox-theme/theme as Theme';"
|
||||
echo ""
|
||||
echo "📚 Documentation:"
|
||||
echo " - README: luci-theme-secubox/README.md"
|
||||
echo " - API Reference: luci-theme-secubox/USAGE.md"
|
||||
echo ""
|
||||
@ -4,6 +4,10 @@
|
||||
'require ui';
|
||||
'require network-modes.api as api';
|
||||
'require secubox/help as Help';
|
||||
'require secubox-theme/theme as Theme';
|
||||
|
||||
// Initialize global theme
|
||||
Theme.init({ theme: 'dark', language: 'en' });
|
||||
|
||||
return view.extend({
|
||||
title: _('Network Modes'),
|
||||
@ -64,8 +68,10 @@ return view.extend({
|
||||
var currentModeInfo = modeInfos[currentMode];
|
||||
|
||||
var view = E('div', { 'class': 'network-modes-dashboard' }, [
|
||||
// Load help CSS
|
||||
// Load global theme CSS
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox/help.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('network-modes/dashboard.css') }),
|
||||
|
||||
// Header
|
||||
E('div', { 'class': 'nm-header' }, [
|
||||
|
||||
@ -2,24 +2,19 @@
|
||||
'require view';
|
||||
'require ui';
|
||||
'require secubox/api as API';
|
||||
'require secubox/theme as Theme';
|
||||
'require secubox-theme/theme as Theme';
|
||||
'require dom';
|
||||
'require poll';
|
||||
|
||||
// Load CSS (base theme variables first)
|
||||
// Load global theme CSS
|
||||
document.head.appendChild(E('link', {
|
||||
'rel': 'stylesheet',
|
||||
'type': 'text/css',
|
||||
'href': L.resource('secubox/secubox.css')
|
||||
}));
|
||||
document.head.appendChild(E('link', {
|
||||
'rel': 'stylesheet',
|
||||
'type': 'text/css',
|
||||
'href': L.resource('secubox/dashboard.css')
|
||||
'href': L.resource('secubox-theme/secubox-theme.css')
|
||||
}));
|
||||
|
||||
// Initialize theme
|
||||
Theme.init();
|
||||
// Initialize global theme
|
||||
Theme.init({ theme: 'dark', language: 'en' });
|
||||
|
||||
return view.extend({
|
||||
dashboardData: null,
|
||||
|
||||
@ -3,14 +3,14 @@
|
||||
'require ui';
|
||||
'require dom';
|
||||
'require secubox/api as API';
|
||||
'require secubox/theme as Theme';
|
||||
'require secubox-theme/theme as Theme';
|
||||
'require poll';
|
||||
|
||||
// Load CSS
|
||||
// Load global theme CSS
|
||||
document.head.appendChild(E('link', {
|
||||
'rel': 'stylesheet',
|
||||
'type': 'text/css',
|
||||
'href': L.resource('secubox/secubox.css')
|
||||
'href': L.resource('secubox-theme/secubox-theme.css')
|
||||
}));
|
||||
document.head.appendChild(E('link', {
|
||||
'rel': 'stylesheet',
|
||||
@ -18,8 +18,8 @@ document.head.appendChild(E('link', {
|
||||
'href': L.resource('secubox/modules.css')
|
||||
}));
|
||||
|
||||
// Initialize theme
|
||||
Theme.init();
|
||||
// Initialize global theme
|
||||
Theme.init({ theme: 'dark', language: 'en' });
|
||||
|
||||
return view.extend({
|
||||
modulesData: [],
|
||||
|
||||
@ -4,7 +4,10 @@
|
||||
'require dom';
|
||||
'require poll';
|
||||
'require system-hub/api as API';
|
||||
'require system-hub/theme as Theme';
|
||||
'require secubox-theme/theme as Theme';
|
||||
|
||||
// Initialize global theme
|
||||
Theme.init({ theme: 'dark', language: 'en' });
|
||||
|
||||
return view.extend({
|
||||
healthData: null,
|
||||
@ -13,8 +16,7 @@ return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
API.getSystemInfo(),
|
||||
API.getHealth(),
|
||||
Theme.getTheme()
|
||||
API.getHealth()
|
||||
]);
|
||||
},
|
||||
|
||||
@ -22,9 +24,9 @@ return view.extend({
|
||||
var self = this;
|
||||
this.sysInfo = data[0] || {};
|
||||
this.healthData = data[1] || {};
|
||||
var theme = data[2];
|
||||
|
||||
var container = E('div', { 'class': 'system-hub-dashboard' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('system-hub/common.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('system-hub/dashboard.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('system-hub/overview.css') }),
|
||||
|
||||
@ -3,7 +3,10 @@
|
||||
'require ui';
|
||||
'require dom';
|
||||
'require system-hub/api as API';
|
||||
'require system-hub/theme as Theme';
|
||||
'require secubox-theme/theme as Theme';
|
||||
|
||||
// Initialize global theme
|
||||
Theme.init({ theme: 'dark', language: 'en' });
|
||||
|
||||
return view.extend({
|
||||
services: [],
|
||||
@ -11,17 +14,14 @@ return view.extend({
|
||||
searchQuery: '',
|
||||
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
API.listServices(),
|
||||
Theme.getTheme()
|
||||
]);
|
||||
return API.listServices();
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
this.services = data[0] || [];
|
||||
var theme = data[1];
|
||||
this.services = data || [];
|
||||
|
||||
var container = E('div', { 'class': 'system-hub-services' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('system-hub/common.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('system-hub/dashboard.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('system-hub/services.css') }),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user