- Restructured docker-compose for Nginx Proxy Manager (no custom nginx) - Added domain wordly.art configuration - Added Prometheus + Grafana monitoring stack with pre-configured dashboards - Added PostgreSQL backup script to NAS (daily/weekly/monthly rotation) - Added alert rules for backend, system, and Docker metrics - Updated deployment guide for NPM + IONOS DNS homelab setup - Added marketing plan document - PDF translator and watermark support - Enhanced middleware, routes, and translator modules Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
'use client';
|
|
|
|
import { Lock } from 'lucide-react';
|
|
import { cn } from '@/lib/utils';
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipProvider,
|
|
TooltipTrigger,
|
|
} from '@/components/ui/tooltip';
|
|
import type { TranslationMode } from './types';
|
|
|
|
interface TranslationModeToggleProps {
|
|
mode: TranslationMode;
|
|
onModeChange: (mode: TranslationMode) => void;
|
|
isPro: boolean;
|
|
}
|
|
|
|
export function TranslationModeToggle({
|
|
mode,
|
|
onModeChange,
|
|
isPro,
|
|
}: TranslationModeToggleProps) {
|
|
return (
|
|
<TooltipProvider>
|
|
<div className="flex flex-col gap-1.5">
|
|
<label className="text-xs font-medium text-muted-foreground">
|
|
Translation Mode
|
|
</label>
|
|
<div className="flex rounded-lg border border-border bg-muted p-1">
|
|
<button
|
|
type="button"
|
|
className={cn(
|
|
'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-all',
|
|
mode === 'classic'
|
|
? 'bg-card text-foreground shadow-sm'
|
|
: 'text-muted-foreground hover:text-foreground'
|
|
)}
|
|
onClick={() => onModeChange('classic')}
|
|
>
|
|
Classic
|
|
<span className="ms-1.5 text-xs text-muted-foreground">
|
|
Fast
|
|
</span>
|
|
</button>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<button
|
|
type="button"
|
|
className={cn(
|
|
'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-all relative',
|
|
mode === 'llm'
|
|
? 'bg-card text-foreground shadow-sm'
|
|
: 'text-muted-foreground hover:text-foreground',
|
|
!isPro && 'cursor-not-allowed opacity-60'
|
|
)}
|
|
onClick={() => isPro && onModeChange('llm')}
|
|
disabled={!isPro}
|
|
>
|
|
Pro LLM
|
|
<span className="ms-1.5 text-xs text-muted-foreground">
|
|
Context-Aware
|
|
</span>
|
|
{!isPro && (
|
|
<Lock className="absolute right-2 top-1/2 -translate-y-1/2 size-3 text-muted-foreground" />
|
|
)}
|
|
</button>
|
|
</TooltipTrigger>
|
|
{!isPro && (
|
|
<TooltipContent side="top">
|
|
<p>Upgrade to Pro for LLM translation</p>
|
|
</TooltipContent>
|
|
)}
|
|
</Tooltip>
|
|
</div>
|
|
{!isPro && (
|
|
<p className="text-xs text-muted-foreground">
|
|
<a href="/pricing" className="text-primary hover:underline">
|
|
Upgrade to Pro
|
|
</a>{' '}
|
|
for LLM-powered translations
|
|
</p>
|
|
)}
|
|
</div>
|
|
</TooltipProvider>
|
|
);
|
|
}
|