From fafa98bc19ffc87cfb1dd68f60deea90f3c58d8e Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 6 Jan 2026 10:17:05 +0000 Subject: [PATCH] update --- .../eco-peripherals/eco-peripherals.demo.ts | 21 + .../eco-peripherals/eco-peripherals.ts | 840 ++++++++++++ .../eco-peripherals/index.ts | 1 + .../eco-settings/eco-settings.demo.ts | 18 + .../eco-settings/eco-settings.ts | 1178 +++++++++++++++++ .../00group-applauncher/eco-settings/index.ts | 1 + ts_web/elements/00group-applauncher/index.ts | 2 + 7 files changed, 2061 insertions(+) create mode 100644 ts_web/elements/00group-applauncher/eco-peripherals/eco-peripherals.demo.ts create mode 100644 ts_web/elements/00group-applauncher/eco-peripherals/eco-peripherals.ts create mode 100644 ts_web/elements/00group-applauncher/eco-peripherals/index.ts create mode 100644 ts_web/elements/00group-applauncher/eco-settings/eco-settings.demo.ts create mode 100644 ts_web/elements/00group-applauncher/eco-settings/eco-settings.ts create mode 100644 ts_web/elements/00group-applauncher/eco-settings/index.ts diff --git a/ts_web/elements/00group-applauncher/eco-peripherals/eco-peripherals.demo.ts b/ts_web/elements/00group-applauncher/eco-peripherals/eco-peripherals.demo.ts new file mode 100644 index 0000000..26ae86d --- /dev/null +++ b/ts_web/elements/00group-applauncher/eco-peripherals/eco-peripherals.demo.ts @@ -0,0 +1,21 @@ +import { html } from '@design.estate/dees-element'; + +export const demo = () => html` + +
+ console.log('Device selected:', e.detail)} + @scan-start=${() => console.log('Scanning started')} + @scan-complete=${() => console.log('Scanning complete')} + > +
+`; diff --git a/ts_web/elements/00group-applauncher/eco-peripherals/eco-peripherals.ts b/ts_web/elements/00group-applauncher/eco-peripherals/eco-peripherals.ts new file mode 100644 index 0000000..f70df0c --- /dev/null +++ b/ts_web/elements/00group-applauncher/eco-peripherals/eco-peripherals.ts @@ -0,0 +1,840 @@ +import { + customElement, + DeesElement, + type TemplateResult, + html, + property, + css, + cssManager, + state, +} from '@design.estate/dees-element'; +import { DeesAppuiSecondarymenu, DeesIcon } from '@design.estate/dees-catalog'; +import type { ISecondaryMenuGroup, ISecondaryMenuItem } from '../../interfaces/secondarymenu.js'; +import { demo } from './eco-peripherals.demo.js'; + +// Ensure components are registered +DeesAppuiSecondarymenu; +DeesIcon; + +declare global { + interface HTMLElementTagNameMap { + 'eco-peripherals': EcoPeripherals; + } +} + +export type TPeripheralCategory = + | 'all' + | 'printers' + | 'scanners' + | 'speakers' + | 'storage' + | 'power' + | 'cameras' + | 'streaming' + | 'usb'; + +export type TConnectionType = 'network' | 'usb' | 'bluetooth'; + +export interface IPeripheralDevice { + id: string; + name: string; + type: TPeripheralCategory; + connectionType: TConnectionType; + status: 'online' | 'offline' | 'busy' | 'error'; + ip?: string; + manufacturer?: string; + model?: string; + isDefault?: boolean; +} + +@customElement('eco-peripherals') +export class EcoPeripherals extends DeesElement { + public static demo = demo; + public static demoGroup = 'App Launcher'; + + public static styles = [ + cssManager.defaultStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + background: ${cssManager.bdTheme('#f5f5f7', 'hsl(240 6% 10%)')}; + color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 98%)')}; + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + } + + .peripherals-container { + display: flex; + height: 100%; + } + + dees-appui-secondarymenu { + flex-shrink: 0; + background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 8%)')}; + border-right: 1px solid ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(240 5% 15%)')}; + } + + .content { + flex: 1; + overflow-y: auto; + padding: 32px 48px; + } + + .panel-header { + margin-bottom: 24px; + display: flex; + align-items: center; + justify-content: space-between; + } + + .panel-header-left { + display: flex; + flex-direction: column; + gap: 4px; + } + + .panel-title { + font-size: 28px; + font-weight: 600; + color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 98%)')}; + } + + .panel-description { + font-size: 14px; + color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 60%)')}; + } + + .scan-button { + display: flex; + align-items: center; + gap: 8px; + padding: 10px 20px; + background: hsl(217 91% 60%); + color: white; + border: none; + border-radius: 8px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: background 0.15s ease; + } + + .scan-button:hover { + background: hsl(217 91% 55%); + } + + .scan-button.scanning { + background: ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(240 5% 25%)')}; + cursor: not-allowed; + } + + .scan-button.scanning dees-icon { + animation: spin 1s linear infinite; + } + + @keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + + .device-section { + background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 12%)')}; + border: 1px solid ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(240 5% 18%)')}; + border-radius: 12px; + margin-bottom: 24px; + overflow: hidden; + } + + .section-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 20px; + border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 94%)', 'hsl(240 5% 15%)')}; + } + + .section-title { + font-size: 13px; + font-weight: 600; + color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 50%)')}; + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .device-count { + font-size: 12px; + color: ${cssManager.bdTheme('hsl(0 0% 60%)', 'hsl(0 0% 50%)')}; + background: ${cssManager.bdTheme('hsl(0 0% 94%)', 'hsl(240 5% 20%)')}; + padding: 2px 8px; + border-radius: 10px; + } + + .device-list { + padding: 8px 0; + } + + .device-item { + display: flex; + align-items: center; + gap: 16px; + padding: 14px 20px; + cursor: pointer; + transition: background 0.15s ease; + } + + .device-item:hover { + background: ${cssManager.bdTheme('hsl(0 0% 97%)', 'hsl(240 5% 14%)')}; + } + + .device-icon-wrapper { + width: 48px; + height: 48px; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + background: ${cssManager.bdTheme('hsl(0 0% 94%)', 'hsl(240 5% 18%)')}; + color: ${cssManager.bdTheme('hsl(0 0% 40%)', 'hsl(0 0% 70%)')}; + } + + .device-icon-wrapper.online { + background: ${cssManager.bdTheme('hsl(142 71% 93%)', 'hsl(142 71% 45% / 0.15)')}; + color: hsl(142 71% 35%); + } + + .device-icon-wrapper.busy { + background: ${cssManager.bdTheme('hsl(47 100% 93%)', 'hsl(47 100% 50% / 0.15)')}; + color: hsl(47 100% 40%); + } + + .device-icon-wrapper.error { + background: ${cssManager.bdTheme('hsl(0 72% 93%)', 'hsl(0 72% 51% / 0.15)')}; + color: hsl(0 72% 45%); + } + + .device-info { + flex: 1; + min-width: 0; + } + + .device-name { + font-size: 15px; + font-weight: 500; + color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 98%)')}; + display: flex; + align-items: center; + gap: 8px; + } + + .default-badge { + font-size: 10px; + font-weight: 600; + color: hsl(217 91% 60%); + background: ${cssManager.bdTheme('hsl(217 91% 95%)', 'hsl(217 91% 60% / 0.15)')}; + padding: 2px 6px; + border-radius: 4px; + text-transform: uppercase; + } + + .device-details { + font-size: 13px; + color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 55%)')}; + margin-top: 2px; + display: flex; + align-items: center; + gap: 12px; + } + + .device-detail { + display: flex; + align-items: center; + gap: 4px; + } + + .status-indicator { + width: 8px; + height: 8px; + border-radius: 50%; + flex-shrink: 0; + } + + .status-indicator.online { + background: hsl(142 71% 45%); + } + + .status-indicator.offline { + background: ${cssManager.bdTheme('hsl(0 0% 70%)', 'hsl(0 0% 40%)')}; + } + + .status-indicator.busy { + background: hsl(47 100% 50%); + } + + .status-indicator.error { + background: hsl(0 72% 51%); + } + + .device-actions { + display: flex; + align-items: center; + gap: 8px; + } + + .action-button { + padding: 8px 12px; + border: 1px solid ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(240 5% 25%)')}; + border-radius: 6px; + background: transparent; + color: ${cssManager.bdTheme('hsl(0 0% 30%)', 'hsl(0 0% 80%)')}; + font-size: 13px; + cursor: pointer; + transition: all 0.15s ease; + } + + .action-button:hover { + background: ${cssManager.bdTheme('hsl(0 0% 96%)', 'hsl(240 5% 18%)')}; + border-color: ${cssManager.bdTheme('hsl(0 0% 75%)', 'hsl(240 5% 35%)')}; + } + + .action-button.primary { + background: hsl(217 91% 60%); + border-color: hsl(217 91% 60%); + color: white; + } + + .action-button.primary:hover { + background: hsl(217 91% 55%); + } + + .empty-state { + padding: 48px 20px; + text-align: center; + } + + .empty-icon { + color: ${cssManager.bdTheme('hsl(0 0% 75%)', 'hsl(0 0% 35%)')}; + margin-bottom: 16px; + } + + .empty-title { + font-size: 16px; + font-weight: 500; + color: ${cssManager.bdTheme('hsl(0 0% 30%)', 'hsl(0 0% 80%)')}; + margin-bottom: 8px; + } + + .empty-description { + font-size: 14px; + color: ${cssManager.bdTheme('hsl(0 0% 55%)', 'hsl(0 0% 50%)')}; + } + + .connection-type { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 11px; + padding: 2px 6px; + border-radius: 4px; + background: ${cssManager.bdTheme('hsl(0 0% 94%)', 'hsl(240 5% 20%)')}; + color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 60%)')}; + } + `, + ]; + + @property({ type: String }) + accessor activeCategory: TPeripheralCategory = 'all'; + + @state() + accessor isScanning = false; + + @state() + accessor devices: IPeripheralDevice[] = [ + // Mock printers + { + id: 'printer-1', + name: 'HP LaserJet Pro', + type: 'printers', + connectionType: 'network', + status: 'online', + ip: '192.168.1.50', + manufacturer: 'HP', + model: 'LaserJet Pro M404n', + isDefault: true, + }, + { + id: 'printer-2', + name: 'Brother MFC-L2750DW', + type: 'printers', + connectionType: 'network', + status: 'online', + ip: '192.168.1.51', + manufacturer: 'Brother', + model: 'MFC-L2750DW', + }, + { + id: 'printer-3', + name: 'Canon PIXMA', + type: 'printers', + connectionType: 'usb', + status: 'offline', + manufacturer: 'Canon', + model: 'PIXMA TR8620', + }, + // Mock scanners + { + id: 'scanner-1', + name: 'Epson Perfection V600', + type: 'scanners', + connectionType: 'usb', + status: 'online', + manufacturer: 'Epson', + model: 'Perfection V600', + }, + // Mock speakers + { + id: 'speaker-1', + name: 'Sonos One', + type: 'speakers', + connectionType: 'network', + status: 'online', + ip: '192.168.1.60', + manufacturer: 'Sonos', + model: 'One (Gen 2)', + }, + { + id: 'speaker-2', + name: 'HomePod mini', + type: 'speakers', + connectionType: 'network', + status: 'online', + ip: '192.168.1.61', + manufacturer: 'Apple', + model: 'HomePod mini', + }, + // Mock NAS + { + id: 'nas-1', + name: 'Synology DS920+', + type: 'storage', + connectionType: 'network', + status: 'online', + ip: '192.168.1.100', + manufacturer: 'Synology', + model: 'DS920+', + }, + // Mock UPS + { + id: 'ups-1', + name: 'APC Back-UPS Pro', + type: 'power', + connectionType: 'usb', + status: 'online', + manufacturer: 'APC', + model: 'Back-UPS Pro 1500', + }, + // Mock cameras + { + id: 'camera-1', + name: 'Logitech C920', + type: 'cameras', + connectionType: 'usb', + status: 'online', + manufacturer: 'Logitech', + model: 'C920 HD Pro', + isDefault: true, + }, + { + id: 'camera-2', + name: 'Ring Indoor Cam', + type: 'cameras', + connectionType: 'network', + status: 'online', + ip: '192.168.1.70', + manufacturer: 'Ring', + model: 'Indoor Cam', + }, + // Mock streaming devices + { + id: 'streaming-1', + name: 'Living Room Apple TV', + type: 'streaming', + connectionType: 'network', + status: 'online', + ip: '192.168.1.80', + manufacturer: 'Apple', + model: 'Apple TV 4K', + }, + { + id: 'streaming-2', + name: 'Bedroom Chromecast', + type: 'streaming', + connectionType: 'network', + status: 'online', + ip: '192.168.1.81', + manufacturer: 'Google', + model: 'Chromecast with Google TV', + }, + // Mock USB devices + { + id: 'usb-1', + name: 'SanDisk Ultra', + type: 'usb', + connectionType: 'usb', + status: 'online', + manufacturer: 'SanDisk', + model: 'Ultra USB 3.0 128GB', + }, + ]; + + private getMenuGroups(): ISecondaryMenuGroup[] { + const allCount = this.devices.length; + const getCount = (type: TPeripheralCategory) => + this.devices.filter(d => d.type === type).length; + + return [ + { + name: 'Devices', + iconName: 'lucide:monitor', + items: [ + { + key: 'all', + iconName: 'lucide:layoutGrid', + action: () => this.activeCategory = 'all', + badge: allCount, + }, + ], + }, + { + name: 'Output', + iconName: 'lucide:printer', + items: [ + { + key: 'printers', + iconName: 'lucide:printer', + action: () => this.activeCategory = 'printers', + badge: getCount('printers') || undefined, + }, + { + key: 'speakers', + iconName: 'lucide:speaker', + action: () => this.activeCategory = 'speakers', + badge: getCount('speakers') || undefined, + }, + ], + }, + { + name: 'Input', + iconName: 'lucide:scan', + items: [ + { + key: 'scanners', + iconName: 'lucide:scan', + action: () => this.activeCategory = 'scanners', + badge: getCount('scanners') || undefined, + }, + { + key: 'cameras', + iconName: 'lucide:camera', + action: () => this.activeCategory = 'cameras', + badge: getCount('cameras') || undefined, + }, + ], + }, + { + name: 'Network', + iconName: 'lucide:network', + items: [ + { + key: 'storage', + iconName: 'lucide:hardDrive', + action: () => this.activeCategory = 'storage', + badge: getCount('storage') || undefined, + }, + { + key: 'streaming', + iconName: 'lucide:cast', + action: () => this.activeCategory = 'streaming', + badge: getCount('streaming') || undefined, + }, + ], + }, + { + name: 'Other', + iconName: 'lucide:plug', + items: [ + { + key: 'power', + iconName: 'lucide:batteryCharging', + action: () => this.activeCategory = 'power', + badge: getCount('power') || undefined, + }, + { + key: 'usb', + iconName: 'lucide:usb', + action: () => this.activeCategory = 'usb', + badge: getCount('usb') || undefined, + }, + ], + }, + ]; + } + + private getSelectedItem(): ISecondaryMenuItem | null { + for (const group of this.getMenuGroups()) { + for (const item of group.items) { + if ('key' in item && item.key === this.activeCategory) { + return item; + } + } + } + return null; + } + + private getFilteredDevices(): IPeripheralDevice[] { + if (this.activeCategory === 'all') { + return this.devices; + } + return this.devices.filter(d => d.type === this.activeCategory); + } + + private getCategoryTitle(): string { + const titles: Record = { + all: 'All Devices', + printers: 'Printers', + scanners: 'Scanners', + speakers: 'Speakers', + storage: 'Network Storage', + power: 'Power Devices', + cameras: 'Cameras', + streaming: 'Streaming Devices', + usb: 'USB Devices', + }; + return titles[this.activeCategory]; + } + + private getCategoryDescription(): string { + const descriptions: Record = { + all: 'View and manage all connected peripherals', + printers: 'Manage printers and print queues', + scanners: 'Configure scanners and scanning options', + speakers: 'Network speakers and audio devices', + storage: 'NAS devices and network storage', + power: 'UPS and power management devices', + cameras: 'Webcams and security cameras', + streaming: 'Apple TV, Chromecast, and streaming devices', + usb: 'USB storage and connected devices', + }; + return descriptions[this.activeCategory]; + } + + private getDeviceIcon(device: IPeripheralDevice): string { + const icons: Record = { + all: 'lucide:monitor', + printers: 'lucide:printer', + scanners: 'lucide:scan', + speakers: 'lucide:speaker', + storage: 'lucide:hardDrive', + power: 'lucide:batteryCharging', + cameras: 'lucide:camera', + streaming: 'lucide:cast', + usb: 'lucide:usb', + }; + return icons[device.type]; + } + + private getConnectionIcon(type: TConnectionType): string { + const icons: Record = { + network: 'lucide:wifi', + usb: 'lucide:usb', + bluetooth: 'lucide:bluetooth', + }; + return icons[type]; + } + + private async handleScan(): Promise { + if (this.isScanning) return; + + this.isScanning = true; + this.dispatchEvent(new CustomEvent('scan-start', { + bubbles: true, + composed: true, + })); + + // Simulate scanning + await new Promise(resolve => setTimeout(resolve, 3000)); + + this.isScanning = false; + this.dispatchEvent(new CustomEvent('scan-complete', { + bubbles: true, + composed: true, + })); + } + + private handleDeviceClick(device: IPeripheralDevice): void { + this.dispatchEvent(new CustomEvent('device-select', { + detail: { device }, + bubbles: true, + composed: true, + })); + } + + private handleSetDefault(device: IPeripheralDevice, e: Event): void { + e.stopPropagation(); + this.devices = this.devices.map(d => ({ + ...d, + isDefault: d.type === device.type ? d.id === device.id : d.isDefault, + })); + this.dispatchEvent(new CustomEvent('device-set-default', { + detail: { device }, + bubbles: true, + composed: true, + })); + } + + public render(): TemplateResult { + return html` +
+ +
+ ${this.renderContent()} +
+
+ `; + } + + private renderContent(): TemplateResult { + const devices = this.getFilteredDevices(); + + return html` +
+
+
${this.getCategoryTitle()}
+
${this.getCategoryDescription()}
+
+ +
+ + ${this.activeCategory === 'all' + ? this.renderGroupedDevices(devices) + : this.renderDeviceList(devices) + } + `; + } + + private renderGroupedDevices(devices: IPeripheralDevice[]): TemplateResult { + const groups = new Map(); + + for (const device of devices) { + const existing = groups.get(device.type) || []; + existing.push(device); + groups.set(device.type, existing); + } + + const categoryLabels: Record = { + all: 'All', + printers: 'Printers', + scanners: 'Scanners', + speakers: 'Speakers', + storage: 'Network Storage', + power: 'Power Devices', + cameras: 'Cameras', + streaming: 'Streaming', + usb: 'USB Devices', + }; + + return html` + ${Array.from(groups.entries()).map(([category, categoryDevices]) => html` +
+
+ ${categoryLabels[category]} + ${categoryDevices.length} +
+
+ ${categoryDevices.map(device => this.renderDeviceItem(device))} +
+
+ `)} + `; + } + + private renderDeviceList(devices: IPeripheralDevice[]): TemplateResult { + if (devices.length === 0) { + return this.renderEmptyState(); + } + + return html` +
+
+ Discovered Devices + ${devices.length} +
+
+ ${devices.map(device => this.renderDeviceItem(device))} +
+
+ `; + } + + private renderDeviceItem(device: IPeripheralDevice): TemplateResult { + return html` +
this.handleDeviceClick(device)}> +
+ +
+
+
+ ${device.name} + ${device.isDefault ? html`Default` : ''} +
+
+
+ + ${device.status.charAt(0).toUpperCase() + device.status.slice(1)} +
+ ${device.ip ? html` +
${device.ip}
+ ` : ''} + + + ${device.connectionType.toUpperCase()} + +
+
+
+ ${!device.isDefault && (device.type === 'printers' || device.type === 'cameras') ? html` + + ` : ''} + +
+
+ `; + } + + private renderEmptyState(): TemplateResult { + return html` +
+
+ +
No devices found
+
+ Click "Scan for Devices" to discover ${this.getCategoryTitle().toLowerCase()} on your network or connected via USB. +
+
+
+ `; + } +} diff --git a/ts_web/elements/00group-applauncher/eco-peripherals/index.ts b/ts_web/elements/00group-applauncher/eco-peripherals/index.ts new file mode 100644 index 0000000..030b4cb --- /dev/null +++ b/ts_web/elements/00group-applauncher/eco-peripherals/index.ts @@ -0,0 +1 @@ +export * from './eco-peripherals.js'; diff --git a/ts_web/elements/00group-applauncher/eco-settings/eco-settings.demo.ts b/ts_web/elements/00group-applauncher/eco-settings/eco-settings.demo.ts new file mode 100644 index 0000000..5acdb55 --- /dev/null +++ b/ts_web/elements/00group-applauncher/eco-settings/eco-settings.demo.ts @@ -0,0 +1,18 @@ +import { html } from '@design.estate/dees-element'; + +export const demo = () => html` + +
+ +
+`; diff --git a/ts_web/elements/00group-applauncher/eco-settings/eco-settings.ts b/ts_web/elements/00group-applauncher/eco-settings/eco-settings.ts new file mode 100644 index 0000000..4cbf7ae --- /dev/null +++ b/ts_web/elements/00group-applauncher/eco-settings/eco-settings.ts @@ -0,0 +1,1178 @@ +import { + customElement, + DeesElement, + type TemplateResult, + html, + property, + css, + cssManager, + state, +} from '@design.estate/dees-element'; +import { DeesAppuiSecondarymenu, DeesIcon } from '@design.estate/dees-catalog'; +import type { ISecondaryMenuGroup, ISecondaryMenuItem } from '../../interfaces/secondarymenu.js'; +import { demo } from './eco-settings.demo.js'; + +// Ensure components are registered +DeesAppuiSecondarymenu; +DeesIcon; + +declare global { + interface HTMLElementTagNameMap { + 'eco-settings': EcoSettings; + } +} + +export type TSettingsPanel = + | 'general' + | 'network' + | 'bluetooth' + | 'display' + | 'sound' + | 'notifications' + | 'privacy' + | 'accounts' + | 'apps' + | 'updates' + | 'about'; + +@customElement('eco-settings') +export class EcoSettings extends DeesElement { + public static demo = demo; + public static demoGroup = 'App Launcher'; + + public static styles = [ + cssManager.defaultStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + background: ${cssManager.bdTheme('#f5f5f7', 'hsl(240 6% 10%)')}; + color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 98%)')}; + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + } + + .settings-container { + display: flex; + height: 100%; + } + + dees-appui-secondarymenu { + flex-shrink: 0; + background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 8%)')}; + border-right: 1px solid ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(240 5% 15%)')}; + } + + .content { + flex: 1; + overflow-y: auto; + padding: 32px 48px; + } + + .panel-header { + margin-bottom: 32px; + } + + .panel-title { + font-size: 28px; + font-weight: 600; + color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 98%)')}; + margin-bottom: 8px; + } + + .panel-description { + font-size: 14px; + color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 60%)')}; + } + + .settings-section { + background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 12%)')}; + border: 1px solid ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(240 5% 18%)')}; + border-radius: 12px; + margin-bottom: 24px; + overflow: hidden; + } + + .section-title { + padding: 16px 20px 12px; + font-size: 13px; + font-weight: 600; + color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 50%)')}; + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .settings-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 14px 20px; + border-top: 1px solid ${cssManager.bdTheme('hsl(0 0% 94%)', 'hsl(240 5% 15%)')}; + transition: background 0.15s ease; + } + + .settings-item:first-child { + border-top: none; + } + + .settings-item:hover { + background: ${cssManager.bdTheme('hsl(0 0% 97%)', 'hsl(240 5% 14%)')}; + } + + .settings-item.clickable { + cursor: pointer; + } + + .item-left { + display: flex; + align-items: center; + gap: 14px; + } + + .item-icon { + width: 32px; + height: 32px; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + color: white; + } + + .item-icon.blue { background: hsl(217 91% 60%); } + .item-icon.green { background: hsl(142 71% 45%); } + .item-icon.orange { background: hsl(25 95% 53%); } + .item-icon.purple { background: hsl(262 83% 58%); } + .item-icon.red { background: hsl(0 72% 51%); } + .item-icon.teal { background: hsl(175 84% 32%); } + .item-icon.gray { background: hsl(220 9% 46%); } + + .item-info { + display: flex; + flex-direction: column; + gap: 2px; + } + + .item-label { + font-size: 15px; + font-weight: 500; + color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 98%)')}; + } + + .item-sublabel { + font-size: 13px; + color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 55%)')}; + } + + .item-right { + display: flex; + align-items: center; + gap: 8px; + color: ${cssManager.bdTheme('hsl(0 0% 60%)', 'hsl(0 0% 50%)')}; + } + + .item-value { + font-size: 14px; + color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 55%)')}; + } + + .toggle-switch { + position: relative; + width: 44px; + height: 24px; + background: ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(240 5% 25%)')}; + border-radius: 12px; + cursor: pointer; + transition: background 0.2s ease; + } + + .toggle-switch.active { + background: hsl(217 91% 60%); + } + + .toggle-switch::after { + content: ''; + position: absolute; + top: 2px; + left: 2px; + width: 20px; + height: 20px; + background: white; + border-radius: 50%; + transition: transform 0.2s ease; + box-shadow: ${cssManager.bdTheme('0 1px 3px rgba(0,0,0,0.2)', 'none')}; + } + + .toggle-switch.active::after { + transform: translateX(20px); + } + + .slider-container { + display: flex; + align-items: center; + gap: 12px; + min-width: 200px; + } + + .slider { + flex: 1; + height: 4px; + background: ${cssManager.bdTheme('hsl(0 0% 88%)', 'hsl(240 5% 25%)')}; + border-radius: 2px; + position: relative; + cursor: pointer; + } + + .slider-fill { + height: 100%; + background: hsl(217 91% 60%); + border-radius: 2px; + } + + .slider-value { + min-width: 36px; + text-align: right; + font-size: 14px; + color: ${cssManager.bdTheme('hsl(0 0% 40%)', 'hsl(0 0% 70%)')}; + } + + select { + padding: 8px 32px 8px 12px; + font-size: 14px; + border: 1px solid ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(240 5% 25%)')}; + border-radius: 8px; + background: ${cssManager.bdTheme('#ffffff', 'hsl(240 6% 15%)')}; + color: ${cssManager.bdTheme('hsl(0 0% 10%)', 'hsl(0 0% 90%)')}; + cursor: pointer; + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 10px center; + } + + select:focus { + outline: none; + border-color: hsl(217 91% 60%); + } + `, + ]; + + @property({ type: String }) + accessor activePanel: TSettingsPanel = 'general'; + + @state() + accessor wifiEnabled = true; + + @state() + accessor bluetoothEnabled = true; + + @state() + accessor darkMode = true; + + @state() + accessor notificationsEnabled = true; + + @state() + accessor soundEnabled = true; + + @state() + accessor brightness = 80; + + @state() + accessor volume = 70; + + private getMenuGroups(): ISecondaryMenuGroup[] { + return [ + { + name: 'System', + iconName: 'lucide:settings', + items: [ + { + key: 'general', + iconName: 'lucide:settings', + action: () => this.activePanel = 'general', + }, + { + key: 'display', + iconName: 'lucide:monitor', + action: () => this.activePanel = 'display', + }, + { + key: 'sound', + iconName: 'lucide:volume2', + action: () => this.activePanel = 'sound', + }, + { + key: 'notifications', + iconName: 'lucide:bell', + action: () => this.activePanel = 'notifications', + }, + ], + }, + { + name: 'Network', + iconName: 'lucide:wifi', + items: [ + { + key: 'network', + iconName: 'lucide:wifi', + action: () => this.activePanel = 'network', + }, + { + key: 'bluetooth', + iconName: 'lucide:bluetooth', + action: () => this.activePanel = 'bluetooth', + }, + ], + }, + { + name: 'Personal', + iconName: 'lucide:user', + items: [ + { + key: 'accounts', + iconName: 'lucide:user', + action: () => this.activePanel = 'accounts', + }, + { + key: 'privacy', + iconName: 'lucide:shield', + action: () => this.activePanel = 'privacy', + }, + ], + }, + { + name: 'System Info', + iconName: 'lucide:info', + items: [ + { + key: 'apps', + iconName: 'lucide:layoutGrid', + action: () => this.activePanel = 'apps', + }, + { + key: 'updates', + iconName: 'lucide:download', + action: () => this.activePanel = 'updates', + }, + { + key: 'about', + iconName: 'lucide:info', + action: () => this.activePanel = 'about', + }, + ], + }, + ]; + } + + private getSelectedItem(): ISecondaryMenuItem | null { + for (const group of this.getMenuGroups()) { + for (const item of group.items) { + if ('key' in item && item.key === this.activePanel) { + return item; + } + } + } + return null; + } + + public render(): TemplateResult { + return html` +
+ +
+ ${this.renderActivePanel()} +
+
+ `; + } + + private renderActivePanel(): TemplateResult { + switch (this.activePanel) { + case 'general': + return this.renderGeneralPanel(); + case 'network': + return this.renderNetworkPanel(); + case 'bluetooth': + return this.renderBluetoothPanel(); + case 'display': + return this.renderDisplayPanel(); + case 'sound': + return this.renderSoundPanel(); + case 'notifications': + return this.renderNotificationsPanel(); + case 'privacy': + return this.renderPrivacyPanel(); + case 'accounts': + return this.renderAccountsPanel(); + case 'apps': + return this.renderAppsPanel(); + case 'updates': + return this.renderUpdatesPanel(); + case 'about': + return this.renderAboutPanel(); + default: + return this.renderGeneralPanel(); + } + } + + private renderGeneralPanel(): TemplateResult { + return html` +
+
General
+
Configure general system settings
+
+ +
+
Appearance
+
+
+
+ +
+
+
Dark Mode
+
Use dark theme throughout the system
+
+
+
this.darkMode = !this.darkMode} + >
+
+
+
+
+ +
+
+
Text Size
+
+
+ +
+
+ +
+
Language & Region
+
+
+
+ +
+
+
Language
+
+
+
+ English (US) + +
+
+
+
+
+ +
+
+
Time Zone
+
+
+
+ UTC+01:00 + +
+
+
+ `; + } + + private renderNetworkPanel(): TemplateResult { + return html` +
+
Network
+
Manage Wi-Fi and network connections
+
+ +
+
Wi-Fi
+
+
+
+ +
+
+
Wi-Fi
+
${this.wifiEnabled ? 'Connected to HomeNetwork' : 'Off'}
+
+
+
this.wifiEnabled = !this.wifiEnabled} + >
+
+
+ + ${this.wifiEnabled ? html` +
+
Available Networks
+
+
+
+
HomeNetwork
+
Connected
+
+
+
+ + +
+
+
+
+
+
OfficeWiFi
+
+
+
+ + +
+
+
+
+
+
CoffeeShop_Guest
+
+
+
+ +
+
+
+ ` : ''} + `; + } + + private renderBluetoothPanel(): TemplateResult { + return html` +
+
Bluetooth
+
Manage Bluetooth devices and connections
+
+ +
+
Bluetooth
+
+
+
+ +
+
+
Bluetooth
+
${this.bluetoothEnabled ? 'On' : 'Off'}
+
+
+
this.bluetoothEnabled = !this.bluetoothEnabled} + >
+
+
+ + ${this.bluetoothEnabled ? html` +
+
Connected Devices
+
+
+
+ +
+
+
AirPods Pro
+
Connected
+
+
+ +
+
+ +
+
Available Devices
+
+
+
+
Magic Keyboard
+
+
+
+
+
+
+
JBL Speaker
+
+
+
+
+ ` : ''} + `; + } + + private renderDisplayPanel(): TemplateResult { + return html` +
+
Display
+
Adjust display and brightness settings
+
+ +
+
Brightness
+
+
+
+ +
+
+
Brightness
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+
Auto-Brightness
+
Automatically adjust based on ambient light
+
+
+
+
+
+ +
+
Night Shift
+
+
+
+ +
+
+
Night Shift
+
Reduce blue light in the evening
+
+
+
+
+
+ +
+
Resolution
+
+
+
+ +
+
+
Display Resolution
+
+
+ +
+
+ `; + } + + private renderSoundPanel(): TemplateResult { + return html` +
+
Sound
+
Configure audio settings and output devices
+
+ +
+
Volume
+
+
+
+ +
+
+
Output Volume
+
+
+
+ +
+
+
+ ${this.volume}% +
+
+
+
+
+ +
+
+
Mute
+
+
+
this.soundEnabled = !this.soundEnabled} + >
+
+
+ +
+
Output Device
+
+
+
+ +
+
+
Built-in Speakers
+
Selected
+
+
+ +
+
+
+
+ +
+
+
AirPods Pro
+
+
+
+
+ +
+
Sound Effects
+
+
+
+
Play sound effects
+
+
+
+
+
+
+
+
Play startup sound
+
+
+
+
+
+ `; + } + + private renderNotificationsPanel(): TemplateResult { + return html` +
+
Notifications
+
Control how apps notify you
+
+ +
+
Notifications
+
+
+
+ +
+
+
Allow Notifications
+
Show notifications from apps and services
+
+
+
this.notificationsEnabled = !this.notificationsEnabled} + >
+
+
+ + ${this.notificationsEnabled ? html` +
+
App Notifications
+
+
+
+ +
+
+
Mail
+
Banners, Sounds, Badges
+
+
+ +
+
+
+
+ +
+
+
Messages
+
Banners, Sounds, Badges
+
+
+ +
+
+
+
+ +
+
+
Calendar
+
Banners, Sounds
+
+
+ +
+
+ ` : ''} + `; + } + + private renderPrivacyPanel(): TemplateResult { + return html` +
+
Privacy & Security
+
Manage privacy settings and app permissions
+
+ +
+
Privacy
+
+
+
+ +
+
+
Location Services
+
On
+
+
+ +
+
+
+
+ +
+
+
Camera
+
3 apps have access
+
+
+ +
+
+
+
+ +
+
+
Microphone
+
2 apps have access
+
+
+ +
+
+ +
+
Security
+
+
+
+ +
+
+
Touch ID & Password
+
+
+ +
+
+ `; + } + + private renderAccountsPanel(): TemplateResult { + return html` +
+
Accounts
+
Manage your accounts and sign-in options
+
+ +
+
+
+
+ JD +
+
+
John Doe
+
john.doe@example.com
+
+
+ +
+
+ +
+
Connected Accounts
+
+
+
+ +
+
+
Google
+
john.doe@gmail.com
+
+
+ +
+
+
+
+ +
+
+
Microsoft
+
john.doe@outlook.com
+
+
+ +
+
+ `; + } + + private renderAppsPanel(): TemplateResult { + return html` +
+
Apps
+
Manage installed applications
+
+ +
+
Default Apps
+
+
+
+ +
+
+
Web Browser
+
+
+
+ Browser + +
+
+
+
+
+ +
+
+
Email Client
+
+
+
+ Mail + +
+
+
+ +
+
Installed Apps
+
+
+
+
Browser
+
Version 120.0.1
+
+
+ +
+
+
+
+
Mail
+
Version 16.0
+
+
+ +
+
+
+
+
Calendar
+
Version 14.0
+
+
+ +
+
+ `; + } + + private renderUpdatesPanel(): TemplateResult { + return html` +
+
Software Updates
+
Keep your system up to date
+
+ +
+
+
+
+ +
+
+
Your system is up to date
+
Last checked: Today at 9:00 AM
+
+
+
+
+ +
+
Update Settings
+
+
+
+
Automatic Updates
+
Download and install updates automatically
+
+
+
+
+
+
+
+
Beta Updates
+
Receive early access to new features
+
+
+
+
+
+ `; + } + + private renderAboutPanel(): TemplateResult { + return html` +
+
About
+
System information and details
+
+ +
+
+
+
+
Device Name
+
+
+ EcoBridge Desktop +
+
+
+
+
System Version
+
+
+ EcoOS 1.0.0 +
+
+
+
+
Processor
+
+
+ ARM64 +
+
+
+
+
Memory
+
+
+ 16 GB +
+
+
+
+
Storage
+
+
+ 512 GB (256 GB Available) +
+
+ +
+
Legal
+
+
+
+
Terms of Service
+
+
+ +
+
+
+
+
Privacy Policy
+
+
+ +
+
+
+
+
Open Source Licenses
+
+
+ +
+
+ `; + } +} diff --git a/ts_web/elements/00group-applauncher/eco-settings/index.ts b/ts_web/elements/00group-applauncher/eco-settings/index.ts new file mode 100644 index 0000000..1b6599f --- /dev/null +++ b/ts_web/elements/00group-applauncher/eco-settings/index.ts @@ -0,0 +1 @@ +export * from './eco-settings.js'; diff --git a/ts_web/elements/00group-applauncher/index.ts b/ts_web/elements/00group-applauncher/index.ts index 2973cf2..1ce25b4 100644 --- a/ts_web/elements/00group-applauncher/index.ts +++ b/ts_web/elements/00group-applauncher/index.ts @@ -4,3 +4,5 @@ export * from './eco-applauncher-wifimenu/index.js'; export * from './eco-applauncher-batterymenu/index.js'; export * from './eco-applauncher-soundmenu/index.js'; export * from './eco-applauncher-keyboard/index.js'; +export * from './eco-settings/index.js'; +export * from './eco-peripherals/index.js';