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:
loveuer
2026-04-04 07:14:00 -07:00
parent 5a83e86bc9
commit 9874561410
83 changed files with 0 additions and 46 deletions

View 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);
}
}

View 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;