refactor: Flatten directory structure
Move project files from uzdb/ subdirectory to root directory for cleaner project structure.
Changes:
- Move frontend/ to root
- Move internal/ to root
- Move build/ to root
- Move all config files (go.mod, wails.json, etc.) to root
- Remove redundant uzdb/ subdirectory nesting
Project structure is now:
├── frontend/ # React application
├── internal/ # Go backend
├── build/ # Wails build assets
├── doc/ # Design documentation
├── main.go # Entry point
└── ...
🤖 Generated with Qoder
This commit is contained in:
73
frontend/src/components/common/StatusIndicator.css
Normal file
73
frontend/src/components/common/StatusIndicator.css
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* StatusIndicator Component Styles
|
||||
*/
|
||||
|
||||
.status-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: var(--space-2);
|
||||
transition: all var(--transition-normal) var(--ease-in-out);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Connected state - Green with glow */
|
||||
.status-indicator.status-connected {
|
||||
background-color: var(--success);
|
||||
box-shadow: 0 0 4px var(--success);
|
||||
}
|
||||
|
||||
/* Active state - Blue with pulse animation */
|
||||
.status-indicator.status-active {
|
||||
background-color: var(--primary);
|
||||
box-shadow: 0 0 8px var(--primary);
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
/* Disconnected state - Gray with border */
|
||||
.status-indicator.status-disconnected {
|
||||
background-color: var(--text-muted);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* Connecting state - Orange spinning animation */
|
||||
.status-indicator.status-connecting {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border: 2px solid var(--warning);
|
||||
border-top-color: transparent;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
/* Error state - Red with help cursor */
|
||||
.status-indicator.status-error {
|
||||
background-color: var(--error);
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
/* Hover effect for clickable indicators */
|
||||
.status-indicator[tabindex]:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.status-indicator[tabindex]:focus-visible {
|
||||
outline: 2px solid var(--primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
93
frontend/src/components/common/StatusIndicator.tsx
Normal file
93
frontend/src/components/common/StatusIndicator.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* StatusIndicator Component
|
||||
*
|
||||
* Displays connection status with appropriate color and animation.
|
||||
* Based on layout-design.md section "连接状态指示器"
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import './StatusIndicator.css';
|
||||
|
||||
/**
|
||||
* Connection status types
|
||||
*/
|
||||
export type StatusType =
|
||||
| 'connected' // Green - Connection successful and available
|
||||
| 'active' // Blue - Currently in use with pulse effect
|
||||
| 'disconnected' // Gray - Saved but not connected
|
||||
| 'connecting' // Orange - Establishing connection (spinning)
|
||||
| 'error'; // Red - Connection failed
|
||||
|
||||
export interface StatusIndicatorProps {
|
||||
/** Current connection status */
|
||||
status: StatusType;
|
||||
/** Optional tooltip text shown on hover */
|
||||
tooltip?: string;
|
||||
/** Additional CSS class name */
|
||||
className?: string;
|
||||
/** Click handler */
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* StatusIndicator component renders a colored dot indicating connection state
|
||||
*/
|
||||
export const StatusIndicator: React.FC<StatusIndicatorProps> = ({
|
||||
status,
|
||||
tooltip,
|
||||
className = '',
|
||||
onClick,
|
||||
}) => {
|
||||
// Map status to CSS class
|
||||
const getStatusClass = (): string => {
|
||||
switch (status) {
|
||||
case 'connected':
|
||||
return 'status-connected';
|
||||
case 'active':
|
||||
return 'status-active';
|
||||
case 'disconnected':
|
||||
return 'status-disconnected';
|
||||
case 'connecting':
|
||||
return 'status-connecting';
|
||||
case 'error':
|
||||
return 'status-error';
|
||||
default:
|
||||
return 'status-disconnected';
|
||||
}
|
||||
};
|
||||
|
||||
// Get aria label for accessibility
|
||||
const getAriaLabel = (): string => {
|
||||
switch (status) {
|
||||
case 'connected':
|
||||
return 'Connected';
|
||||
case 'active':
|
||||
return 'Active connection';
|
||||
case 'disconnected':
|
||||
return 'Disconnected';
|
||||
case 'connecting':
|
||||
return 'Connecting...';
|
||||
case 'error':
|
||||
return 'Connection error';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<span
|
||||
className={`status-indicator ${getStatusClass()} ${className}`}
|
||||
role="status"
|
||||
aria-label={getAriaLabel()}
|
||||
title={tooltip}
|
||||
onClick={onClick}
|
||||
tabIndex={onClick ? 0 : undefined}
|
||||
onKeyDown={(e) => {
|
||||
if (onClick && (e.key === 'Enter' || e.key === ' ')) {
|
||||
e.preventDefault();
|
||||
onClick();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default StatusIndicator;
|
||||
Reference in New Issue
Block a user