Files
CC-Switch/src/components/AppSwitcher.tsx
T
YoVinchen 17cf701bad style(ui): modernize component layouts and visual design
Update UI components with improved layouts, visual hierarchy, and
modern design patterns for better user experience.

Navigation & Brand Components:
- AppSwitcher
  * Enhanced visual design with better spacing
  * Improved active state indicators
  * Smoother transitions and hover effects
  * Better mobile responsiveness
- BrandIcons
  * Optimized icon rendering performance
  * Added support for more provider icons
  * Improved SVG handling and fallbacks
  * Better scaling across different screen sizes

Editor Components:
- JsonEditor
  * Enhanced syntax highlighting
  * Better error visualization
  * Improved code formatting options
  * Added line numbers and code folding support
- UsageScriptModal
  * Complete layout overhaul (1239 lines refactored)
  * Better script editor integration
  * Improved template selection UI
  * Enhanced preview and testing panels
  * Better error feedback and validation

Provider Components:
- ProviderCard
  * Redesigned card layout with modern aesthetics
  * Better information density and readability
  * Improved action buttons placement
  * Enhanced status indicators (active/inactive)
- ProviderList
  * Better grid/list view layouts
  * Improved drag-and-drop visual feedback
  * Enhanced sorting indicators
- ProviderActions
  * Streamlined action menu
  * Better icon consistency
  * Improved tooltips and accessibility

Usage & Footer:
- UsageFooter
  * Redesigned footer layout
  * Better quota visualization
  * Improved refresh controls
  * Enhanced error states

Design System Updates:
- dialog.tsx (shadcn/ui component)
  * Updated to latest design tokens
  * Better overlay animations
  * Improved focus management
- index.css
  * Added 65 lines of global utility classes
  * New animation keyframes
  * Enhanced color variables for dark mode
  * Improved typography scale
- tailwind.config.js
  * Extended theme with new design tokens
  * Added custom animations and transitions
  * New spacing and sizing utilities
  * Enhanced color palette

Visual Improvements:
- Consistent border radius across components
- Unified shadow system for depth perception
- Better color contrast for accessibility (WCAG AA)
- Smoother animations and transitions
- Improved dark mode support

These changes create a more polished, modern interface while
maintaining consistency with the application's design language.
2025-11-21 09:31:36 +08:00

97 lines
3.9 KiB
TypeScript

import type { AppId } from "@/lib/api";
import { ClaudeIcon, CodexIcon, GeminiIcon } from "./BrandIcons";
interface AppSwitcherProps {
activeApp: AppId;
onSwitch: (app: AppId) => void;
}
export function AppSwitcher({ activeApp, onSwitch }: AppSwitcherProps) {
const handleSwitch = (app: AppId) => {
if (app === activeApp) return;
onSwitch(app);
};
return (
<div className="glass p-1.5 rounded-full flex items-center gap-1.5">
<button
type="button"
onClick={() => handleSwitch("claude")}
className={`group relative flex items-center gap-2 px-4 py-2.5 rounded-full text-sm font-semibold overflow-hidden transition-all duration-300 ease-out ${
activeApp === "claude"
? "text-white scale-[1.02] shadow-[0_12px_35px_-15px_rgba(249,115,22,0.8)] ring-1 ring-white/10"
: "text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5"
}`}
>
{activeApp === "claude" && (
<div className="absolute inset-0 bg-gradient-to-r from-orange-500 via-amber-500 to-red-600 rounded-full opacity-90 blur-[1px] transition-all duration-500 -z-10 scale-100" />
)}
{activeApp !== "claude" && (
<div className="absolute inset-0 rounded-full bg-white/0 transition-all duration-300 -z-10" />
)}
<ClaudeIcon
size={16}
className={
activeApp === "claude"
? "text-white"
: "text-muted-foreground group-hover:text-orange-500 transition-colors"
}
/>
<span>Claude</span>
</button>
<button
type="button"
onClick={() => handleSwitch("codex")}
className={`group relative flex items-center gap-2 px-4 py-2.5 rounded-full text-sm font-semibold overflow-hidden transition-all duration-300 ease-out ${
activeApp === "codex"
? "text-white scale-[1.02] shadow-[0_12px_35px_-15px_rgba(59,130,246,0.8)] ring-1 ring-white/10"
: "text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5"
}`}
>
{activeApp === "codex" && (
<div className="absolute inset-0 bg-gradient-to-r from-blue-500 via-sky-500 to-cyan-500 rounded-full opacity-90 blur-[1px] transition-all duration-500 -z-10 scale-100" />
)}
{activeApp !== "codex" && (
<div className="absolute inset-0 rounded-full bg-white/0 transition-all duration-300 -z-10" />
)}
<CodexIcon
size={16}
className={
activeApp === "codex"
? "text-white"
: "text-muted-foreground group-hover:text-blue-500 transition-colors"
}
/>
<span>Codex</span>
</button>
<button
type="button"
onClick={() => handleSwitch("gemini")}
className={`group relative flex items-center gap-2 px-4 py-2.5 rounded-full text-sm font-semibold overflow-hidden transition-all duration-300 ease-out ${
activeApp === "gemini"
? "text-white scale-[1.02] shadow-[0_12px_35px_-15px_rgba(99,102,241,0.8)] ring-1 ring-white/10"
: "text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5"
}`}
>
{activeApp === "gemini" && (
<div className="absolute inset-0 bg-gradient-to-r from-indigo-500 via-violet-500 to-purple-600 rounded-full opacity-90 blur-[1px] transition-all duration-500 -z-10 scale-100" />
)}
{activeApp !== "gemini" && (
<div className="absolute inset-0 rounded-full bg-white/0 transition-all duration-300 -z-10" />
)}
<GeminiIcon
size={16}
className={
activeApp === "gemini"
? "text-white"
: "text-muted-foreground group-hover:text-indigo-500 transition-colors"
}
/>
<span>Gemini</span>
</button>
</div>
);
}