mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-09 18:32:52 +00:00
dda1671e5a
* chore: remove CLAUDE.md and MANUAL_STEPS.md from git tracking These files contain internal project instructions that should not be public. Both are now in .gitignore to prevent re-tracking. * chore: remove build output and generated files from git tracking Remove backend/public/ (frontend build artifacts) and backend/cookies.txt from tracking. Add demo-video/ and website/ to .gitignore. * docs: align mintlify theme with website and app branding Update colors to brand cyan, add Geist font, dark mode default, gradient background, navbar with GitHub link and CTA, and footer matching the website structure. * chore: add shadcn MCP server configuration * feat: add stack context menu, tier icons, centered logo, and support section - Add right-click context menu on sidebar stacks with full actions (alerts, check updates, deploy, stop, restart, update, delete) - Mirror same actions in the three-dot dropdown menu - Create TierBadge component with Globe/Crown/Users icons for Community/Pro/Team tiers, replacing ProBadge across the app - Center logo and app name in sidebar header - Add tiered Support section in Settings with docs, GitHub issues, and tier-appropriate email support channels - Remove duplicate links from About section * docs: update changelog and stack management docs for context menu
149 lines
6.8 KiB
TypeScript
149 lines
6.8 KiB
TypeScript
import { Settings, LogOut, ExternalLink, Monitor, Sun, Moon, User } from 'lucide-react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
|
import { Separator } from '@/components/ui/separator';
|
|
import { useAuth } from '@/context/AuthContext';
|
|
import { useLicense } from '@/context/LicenseContext';
|
|
import { TierBadge } from './TierBadge';
|
|
|
|
type Theme = 'light' | 'dark' | 'auto';
|
|
|
|
interface UserProfileDropdownProps {
|
|
theme: Theme;
|
|
setTheme: (theme: Theme) => void;
|
|
onOpenSettings: () => void;
|
|
}
|
|
|
|
export function UserProfileDropdown({ theme, setTheme, onOpenSettings }: UserProfileDropdownProps) {
|
|
const { logout, user, isAdmin } = useAuth();
|
|
const { license } = useLicense();
|
|
|
|
return (
|
|
<Popover>
|
|
<PopoverTrigger asChild>
|
|
<Button variant="outline" size="icon" className="rounded-full w-9 h-9" title="Profile">
|
|
<User className="w-4 h-4" />
|
|
</Button>
|
|
</PopoverTrigger>
|
|
<PopoverContent className="w-64 p-0 rounded-xl" align="end" sideOffset={8}>
|
|
{/* User Info */}
|
|
<div className="px-4 py-3">
|
|
<div className="flex items-center gap-2">
|
|
<div className="w-8 h-8 rounded-full bg-muted flex items-center justify-center">
|
|
<User className="w-4 h-4 text-muted-foreground" />
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<p className="text-sm font-medium truncate">{user?.username ?? 'admin'}</p>
|
|
<div className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
|
<span className={`px-1.5 py-0.5 rounded text-[10px] font-medium uppercase ${isAdmin ? 'bg-primary/10 text-primary' : 'bg-muted text-muted-foreground'}`}>
|
|
{user?.role ?? 'admin'}
|
|
</span>
|
|
<span className="text-muted-foreground/40">·</span>
|
|
<TierBadge />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Separator />
|
|
|
|
{/* Navigation Links */}
|
|
<div className="p-1">
|
|
<button
|
|
onClick={onOpenSettings}
|
|
className="flex items-center gap-2 w-full px-3 py-2 text-sm rounded-lg hover:bg-muted transition-colors text-left"
|
|
>
|
|
<Settings className="w-4 h-4 text-muted-foreground" />
|
|
Settings
|
|
</button>
|
|
{license?.status === 'active' && (
|
|
<a
|
|
href="https://sencho.io/billing"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="flex items-center gap-2 w-full px-3 py-2 text-sm rounded-lg hover:bg-muted transition-colors"
|
|
>
|
|
<ExternalLink className="w-4 h-4 text-muted-foreground" />
|
|
Billing
|
|
</a>
|
|
)}
|
|
</div>
|
|
|
|
<Separator />
|
|
|
|
{/* Theme Toggle */}
|
|
<div className="p-3">
|
|
<p className="text-xs text-muted-foreground mb-2">Theme</p>
|
|
<div className="flex gap-1 bg-muted/50 rounded-lg p-1">
|
|
<button
|
|
onClick={() => setTheme('auto')}
|
|
className={`flex-1 flex items-center justify-center gap-1.5 px-2 py-1.5 rounded-md text-xs transition-colors ${
|
|
theme === 'auto' ? 'bg-background shadow-sm font-medium' : 'text-muted-foreground hover:text-foreground'
|
|
}`}
|
|
>
|
|
<Monitor className="w-3.5 h-3.5" />
|
|
System
|
|
</button>
|
|
<button
|
|
onClick={() => setTheme('light')}
|
|
className={`flex-1 flex items-center justify-center gap-1.5 px-2 py-1.5 rounded-md text-xs transition-colors ${
|
|
theme === 'light' ? 'bg-background shadow-sm font-medium' : 'text-muted-foreground hover:text-foreground'
|
|
}`}
|
|
>
|
|
<Sun className="w-3.5 h-3.5" />
|
|
Light
|
|
</button>
|
|
<button
|
|
onClick={() => setTheme('dark')}
|
|
className={`flex-1 flex items-center justify-center gap-1.5 px-2 py-1.5 rounded-md text-xs transition-colors ${
|
|
theme === 'dark' ? 'bg-background shadow-sm font-medium' : 'text-muted-foreground hover:text-foreground'
|
|
}`}
|
|
>
|
|
<Moon className="w-3.5 h-3.5" />
|
|
Dark
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<Separator />
|
|
|
|
{/* Documentation Links */}
|
|
<div className="p-1">
|
|
<a
|
|
href="https://docs.sencho.io"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="flex items-center gap-2 w-full px-3 py-2 text-sm rounded-lg hover:bg-muted transition-colors"
|
|
>
|
|
<ExternalLink className="w-4 h-4 text-muted-foreground" />
|
|
Documentation
|
|
</a>
|
|
<a
|
|
href="https://github.com/AnsoCode/Sencho/issues"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="flex items-center gap-2 w-full px-3 py-2 text-sm rounded-lg hover:bg-muted transition-colors"
|
|
>
|
|
<ExternalLink className="w-4 h-4 text-muted-foreground" />
|
|
Feedback
|
|
</a>
|
|
</div>
|
|
|
|
<Separator />
|
|
|
|
{/* Logout */}
|
|
<div className="p-2">
|
|
<Button
|
|
variant="outline"
|
|
className="w-full justify-center"
|
|
onClick={logout}
|
|
>
|
|
<LogOut className="w-4 h-4 mr-2" />
|
|
Log Out
|
|
</Button>
|
|
</div>
|
|
</PopoverContent>
|
|
</Popover>
|
|
);
|
|
}
|