feat: Rebuild admin-ui with Preact + Signals
Some checks failed
DSS Project Analysis / dss-context-update (push) Has been cancelled

Complete rebuild of the admin-ui using Preact + Signals for a lightweight,
reactive framework. Features include:

- Team-centric workdesks (UI, UX, QA, Admin)
- Comprehensive API client with 150+ DSS backend endpoints
- Dark mode with system preference detection
- Keyboard shortcuts and command palette
- AI chat sidebar with Claude integration
- Toast notifications system
- Export/import functionality for project backup
- TypeScript throughout with full type coverage

Bundle size: ~66KB main (21KB gzipped), ~5KB framework overhead

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-10 20:29:21 -03:00
parent 8713e2b1c9
commit 71c6dc805a
51 changed files with 9043 additions and 25 deletions

View File

@@ -0,0 +1,81 @@
import { signal, computed } from '@preact/signals';
// Types
export interface UserPreferences {
theme: 'light' | 'dark' | 'auto';
sidebarCollapsed: boolean;
panelHeight: number;
defaultTeam: string;
keyboardShortcutsEnabled: boolean;
notificationsEnabled: boolean;
}
export interface User {
id: string;
name: string;
email: string;
avatar?: string;
role: 'admin' | 'developer' | 'viewer';
}
// Default preferences
const DEFAULT_PREFERENCES: UserPreferences = {
theme: 'auto',
sidebarCollapsed: false,
panelHeight: 280,
defaultTeam: 'ui',
keyboardShortcutsEnabled: true,
notificationsEnabled: true
};
// User State Signals
export const user = signal<User | null>(null);
export const preferences = signal<UserPreferences>(DEFAULT_PREFERENCES);
// Computed Values
export const isAuthenticated = computed(() => user.value !== null);
export const isAdmin = computed(() => user.value?.role === 'admin');
export const userName = computed(() => user.value?.name ?? 'Guest');
export const userInitials = computed(() => {
const name = user.value?.name ?? 'Guest';
return name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
});
// Actions
export function loadUserPreferences(): void {
if (typeof window === 'undefined') return;
const saved = localStorage.getItem('dss-preferences');
if (saved) {
try {
const parsed = JSON.parse(saved);
preferences.value = { ...DEFAULT_PREFERENCES, ...parsed };
} catch {
preferences.value = DEFAULT_PREFERENCES;
}
}
}
export function saveUserPreferences(): void {
if (typeof window === 'undefined') return;
localStorage.setItem('dss-preferences', JSON.stringify(preferences.value));
}
export function updatePreferences(updates: Partial<UserPreferences>): void {
preferences.value = { ...preferences.value, ...updates };
saveUserPreferences();
}
export function setUser(userData: User | null): void {
user.value = userData;
}
export function logout(): void {
user.value = null;
localStorage.removeItem('dss-token');
}
// Keyboard shortcuts state
export const keyboardShortcutsEnabled = computed(() =>
preferences.value.keyboardShortcutsEnabled
);