Add foundational components and logic for migration, UI design, and input handling
- Introduced foundational UI components (`Badge`, `LockCard`, `SectionHeader`, `AvatarIcon`, etc.) for flexible layouts and consistent design. - Added migration support with the `MigrationModal` component and backend integration for exporting/importing data between Electron and Tauri. - Extended form components with `TextAreaInput`, `OrderInput`, `ToggleField`, and `ToolbarSelect` for improved input handling. - Updated `ScribeShell` with migration popup logic to prompt users for data migration. - Integrated `AlertStack` for better alert handling and notification management. - Enhanced Rust/Tauri services with migration command implementations. - Added translations and styles for new components.
This commit is contained in:
98
components/ui/QSTextGeneratedPreview.tsx
Normal file
98
components/ui/QSTextGeneratedPreview.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import {RefreshCw, Send, Square} from 'lucide-react';
|
||||
import {useTranslations} from '@/lib/i18n';
|
||||
import IconButton from '@/components/ui/IconButton';
|
||||
import Button from '@/components/ui/Button';
|
||||
import Modal from '@/components/ui/Modal';
|
||||
|
||||
interface QSTextGeneratedPreviewProps {
|
||||
onClose: () => void;
|
||||
onRefresh: () => void;
|
||||
value: string;
|
||||
onInsert: () => void;
|
||||
isGenerating?: boolean;
|
||||
onStop?: () => void;
|
||||
}
|
||||
|
||||
export default function QSTextGeneratedPreview(
|
||||
{
|
||||
onClose,
|
||||
onRefresh,
|
||||
value,
|
||||
onInsert,
|
||||
isGenerating = false,
|
||||
onStop,
|
||||
}: QSTextGeneratedPreviewProps) {
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
const filteredValue: string = value.replace(/^starting\.{0,3}\s*/i, '').trim();
|
||||
const hasRealContent: boolean = filteredValue.length > 0;
|
||||
|
||||
const headerActions: React.ReactNode = isGenerating && onStop ? (
|
||||
<IconButton icon={Square} variant="danger" onClick={onStop}/>
|
||||
) : (
|
||||
<IconButton icon={RefreshCw} variant="ghost" onClick={onRefresh}/>
|
||||
);
|
||||
|
||||
const footerContent: React.ReactNode = (
|
||||
<Button variant="primary" onClick={onInsert} icon={Send}>
|
||||
{t("qsTextPreview.insert")}
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t("qsTextPreview.title")}
|
||||
onClose={onClose}
|
||||
size="md"
|
||||
actions={headerActions}
|
||||
footer={footerContent}
|
||||
enableOverflow={true}
|
||||
>
|
||||
<div className="font-['Lora']">
|
||||
{isGenerating && !hasRealContent ? (
|
||||
<div className="space-y-3 animate-pulse">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<span className="h-5 bg-primary/20 rounded px-4"></span>
|
||||
<span className="h-5 bg-primary/15 rounded px-6"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-3"></span>
|
||||
<span className="h-5 bg-primary/10 rounded px-8"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-5"></span>
|
||||
<span className="h-5 bg-primary/15 rounded px-4"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-7"></span>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<span className="h-5 bg-primary/15 rounded px-5"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-3"></span>
|
||||
<span className="h-5 bg-primary/10 rounded px-6"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-4"></span>
|
||||
<span className="h-5 bg-primary/15 rounded px-8"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-3"></span>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<span className="h-5 bg-primary/20 rounded px-6"></span>
|
||||
<span className="h-5 bg-primary/10 rounded px-4"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-5"></span>
|
||||
<span className="h-5 bg-primary/15 rounded px-7"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-3"></span>
|
||||
<span className="h-5 bg-primary/10 rounded px-5"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-4"></span>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<span className="h-5 bg-primary/15 rounded px-4"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-6"></span>
|
||||
<span className="h-5 bg-primary/10 rounded px-3"></span>
|
||||
<span className="h-5 bg-primary/20 rounded px-5"></span>
|
||||
<span className="h-5 bg-primary/15 rounded px-7"></span>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-text-primary text-justify leading-relaxed whitespace-pre-wrap fade-in-text">
|
||||
{filteredValue}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user