refactor: Extract UI into dedicated control panel module
- Create InsertrControlPanel class for unified UI management - Separate business logic from presentation layer - Remove DOM manipulation from auth.js and editor.js - Add comprehensive CSS for status indicators and editing effects - Implement consistent kebab-case file naming - Add event-driven communication between core and UI layers UI Architecture: - Unified control panel with status indicator and action buttons - Color-coded status dots (gray/blue/green for visitor/auth/editing) - Professional editing hover effects with tooltips - Responsive design for mobile devices - Proper z-index and accessibility management Business Logic: - Pure auth.js focused on authentication state and OAuth flows - Pure editor.js focused on content editing workflow - Event emitters for state changes between modules - Clean separation of concerns and testable architecture
This commit is contained in:
@@ -85,22 +85,85 @@
|
||||
}
|
||||
|
||||
/* =================================================================
|
||||
AUTHENTICATION CONTROLS
|
||||
UNIFIED CONTROL PANEL
|
||||
================================================================= */
|
||||
|
||||
.insertr-auth-controls {
|
||||
.insertr-control-panel {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
z-index: var(--insertr-z-overlay);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
gap: var(--insertr-spacing-sm);
|
||||
font-family: var(--insertr-font-family);
|
||||
font-size: var(--insertr-font-size-base);
|
||||
max-width: 280px;
|
||||
}
|
||||
|
||||
.insertr-auth-btn {
|
||||
/* Status Section */
|
||||
.insertr-status-section {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: var(--insertr-spacing-xs);
|
||||
}
|
||||
|
||||
.insertr-status-indicator {
|
||||
background: var(--insertr-bg-primary);
|
||||
color: var(--insertr-text-primary);
|
||||
border: 1px solid var(--insertr-border-color);
|
||||
border-radius: var(--insertr-border-radius);
|
||||
padding: var(--insertr-spacing-xs) var(--insertr-spacing-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--insertr-spacing-xs);
|
||||
font-size: var(--insertr-font-size-sm);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
transition: var(--insertr-transition);
|
||||
}
|
||||
|
||||
.insertr-status-text {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: 500;
|
||||
color: inherit;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.insertr-status-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
transition: var(--insertr-transition);
|
||||
}
|
||||
|
||||
.insertr-status-visitor {
|
||||
background: var(--insertr-text-muted);
|
||||
}
|
||||
|
||||
.insertr-status-authenticated {
|
||||
background: var(--insertr-primary);
|
||||
}
|
||||
|
||||
.insertr-status-editing {
|
||||
background: var(--insertr-success);
|
||||
animation: insertr-pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes insertr-pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.6; }
|
||||
}
|
||||
|
||||
/* Action Buttons Section */
|
||||
.insertr-action-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--insertr-spacing-xs);
|
||||
}
|
||||
|
||||
.insertr-action-btn {
|
||||
background: var(--insertr-primary);
|
||||
color: var(--insertr-text-inverse);
|
||||
border: none;
|
||||
@@ -117,21 +180,112 @@
|
||||
cursor: pointer;
|
||||
transition: var(--insertr-transition);
|
||||
line-height: var(--insertr-line-height);
|
||||
min-width: 80px;
|
||||
min-width: 120px;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.insertr-auth-btn:hover {
|
||||
.insertr-action-btn:hover {
|
||||
background: var(--insertr-primary-hover);
|
||||
color: var(--insertr-text-inverse);
|
||||
text-decoration: none;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.insertr-auth-btn:focus {
|
||||
.insertr-action-btn:focus {
|
||||
outline: 2px solid var(--insertr-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.insertr-action-btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.insertr-action-btn:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* Button Type Variants */
|
||||
.insertr-enhance-btn {
|
||||
background: var(--insertr-info);
|
||||
}
|
||||
|
||||
.insertr-enhance-btn:hover {
|
||||
background: #138496;
|
||||
}
|
||||
|
||||
.insertr-edit-btn.insertr-edit-active {
|
||||
background: var(--insertr-success);
|
||||
}
|
||||
|
||||
.insertr-edit-btn.insertr-edit-active:hover {
|
||||
background: #1e7e34;
|
||||
}
|
||||
|
||||
.insertr-auth-btn.insertr-authenticated {
|
||||
background: var(--insertr-text-secondary);
|
||||
}
|
||||
|
||||
.insertr-auth-btn.insertr-authenticated:hover {
|
||||
background: var(--insertr-text-primary);
|
||||
}
|
||||
|
||||
/* =================================================================
|
||||
EDITING INDICATORS
|
||||
Visual feedback for editable content
|
||||
================================================================= */
|
||||
|
||||
.insertr-editing-hover {
|
||||
outline: 2px dashed var(--insertr-primary);
|
||||
outline-offset: 2px;
|
||||
background: rgba(0, 123, 255, 0.05);
|
||||
position: relative;
|
||||
transition: var(--insertr-transition);
|
||||
}
|
||||
|
||||
.insertr-editing-hover::after {
|
||||
content: '✏️ Click to edit';
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: var(--insertr-text-primary);
|
||||
color: var(--insertr-text-inverse);
|
||||
padding: var(--insertr-spacing-xs) var(--insertr-spacing-sm);
|
||||
border-radius: var(--insertr-border-radius);
|
||||
font-size: var(--insertr-font-size-sm);
|
||||
font-family: var(--insertr-font-family);
|
||||
white-space: nowrap;
|
||||
z-index: var(--insertr-z-tooltip);
|
||||
opacity: 0;
|
||||
animation: insertr-tooltip-show 0.2s ease-in-out forwards;
|
||||
}
|
||||
|
||||
@keyframes insertr-tooltip-show {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-50%) translateY(-5px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide editing indicators when not in edit mode */
|
||||
body:not(.insertr-edit-mode) .insertr-editing-hover {
|
||||
outline: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
body:not(.insertr-edit-mode) .insertr-editing-hover::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* =================================================================
|
||||
MODAL OVERLAY & CONTAINER
|
||||
================================================================= */
|
||||
@@ -517,9 +671,27 @@
|
||||
padding: var(--insertr-spacing-sm);
|
||||
}
|
||||
|
||||
.insertr-auth-controls {
|
||||
.insertr-control-panel {
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
max-width: 240px;
|
||||
}
|
||||
|
||||
.insertr-action-btn {
|
||||
min-width: 100px;
|
||||
font-size: var(--insertr-font-size-sm);
|
||||
padding: var(--insertr-spacing-xs) var(--insertr-spacing-sm);
|
||||
}
|
||||
|
||||
.insertr-status-indicator {
|
||||
font-size: 11px;
|
||||
padding: 3px var(--insertr-spacing-xs);
|
||||
}
|
||||
|
||||
.insertr-editing-hover::after {
|
||||
font-size: 11px;
|
||||
padding: 2px var(--insertr-spacing-xs);
|
||||
top: -25px;
|
||||
}
|
||||
|
||||
.insertr-form-actions {
|
||||
|
||||
Reference in New Issue
Block a user