import React, { useState } from 'react'; import { Sparkles, Copy, Trash2, Wand2, Terminal, Palette, Zap, Check, FlaskConical, Skull, BrainCircuit, Loader2, AlertCircle, Key } from 'lucide-react'; // SỬA LỖI: Dùng CDN trực tiếp để chạy được ngay trên mọi môi trường import { HfInference } from "https://esm.sh/@huggingface/inference"; // --- CẤU HÌNH --- // ⚠️ QUAN TRỌNG: Để trống dòng này khi commit lên Hugging Face để tránh lỗi lộ secret const DEFAULT_HF_TOKEN = ""; const AI_MODEL = "HuggingFaceH4/zephyr-7b-beta"; const STYLES = [ { id: 'none', label: 'None', prompt: '' }, { id: 'anime', label: 'Anime/Manga', prompt: 'anime style, studio ghibli style, vibrant colors, makoto shinkai style, detailed background' }, { id: 'photo', label: 'Photorealistic', prompt: 'photorealistic, 8k, highly detailed, raw photo, dslr, soft lighting, f/1.8, fujifilm' }, { id: 'cyberpunk', label: 'Cyberpunk', prompt: 'cyberpunk, neon lights, futuristic, synthwave, high tech, night city, rain reflection' }, { id: 'fantasy', label: 'Dark Fantasy', prompt: 'dark fantasy, oil painting, intricate details, magical, mystical, greg rutkowski, dungeons and dragons' }, { id: '3d', label: '3D Render', prompt: '3d render, unreal engine 5, octane render, ray tracing, blender, cinema 4d, cgsociety' }, { id: 'ink', label: 'Ink Illustration', prompt: 'ink illustration, thick lines, hatching, cross-hatching, black and white, comic style' }, { id: 'nsfw_soft', label: 'Soft Artistic', prompt: 'soft lighting, artistic nude, elegant pose, classical art style, marble texture, dreamy atmosphere' }, ]; const QUALITY_TAGS = "masterpiece, best quality, ultra-detailed, 8k, hdr, high resolution, absurdres, sharp focus"; const NEGATIVE_PRESETS = { default: "blurry, low quality, text, watermark, bad anatomy, distorted, ugly, pixelated, grain, noise, lowres, error, unfinished, jpeg artifacts", realistic: "cartoon, drawing, anime, illustration, painting, sketch, fake, render, 3d, doll, plastic", anime: "photo, realistic, 3d, nose, lips, realism" }; const App = () => { const [basePrompt, setBasePrompt] = useState(""); const [selectedStyle, setSelectedStyle] = useState(STYLES[1]); const [addQuality, setAddQuality] = useState(true); const [customTags, setCustomTags] = useState(""); const [negativePrompt, setNegativePrompt] = useState(NEGATIVE_PRESETS.default); const [finalPrompt, setFinalPrompt] = useState(""); const [copied, setCopied] = useState(false); // State mới cho chế độ AI và Token const [useAI, setUseAI] = useState(false); const [userToken, setUserToken] = useState(DEFAULT_HF_TOKEN); const [isLoadingAI, setIsLoadingAI] = useState(false); const [aiError, setAiError] = useState(""); const generateManual = () => { let parts = []; if (basePrompt.trim()) parts.push(basePrompt.trim()); if (customTags.trim()) parts.push(customTags.trim()); if (selectedStyle.id !== 'none' && selectedStyle.prompt) { parts.push(selectedStyle.prompt); } if (addQuality) { parts.push(QUALITY_TAGS); } setFinalPrompt(parts.join(", ")); }; const generateWithAI = async () => { if (!basePrompt.trim()) return; // Kiểm tra Token nếu dùng AI Mode const tokenToUse = userToken.trim() || DEFAULT_HF_TOKEN; // Nếu không có token, vẫn thử gọi (có thể bị rate limit ở chế độ public) setIsLoadingAI(true); setAiError(""); setFinalPrompt(""); try { const hf = new HfInference(tokenToUse || undefined); const styleText = selectedStyle.id !== 'none' ? `Style: ${selectedStyle.label} (${selectedStyle.prompt}).` : ""; const qualityText = addQuality ? "Ensure high quality, detailed, 8k resolution." : ""; const customText = customTags ? `Include these elements: ${customTags}.` : ""; const systemPrompt = `You are an expert Stable Diffusion prompt engineer. Task: Rewrite the user's concept into a highly detailed, comma-separated prompt optimized for SDXL. Rules: 1. Use keywords and phrases, separated by commas. 2. Focus on visual description, lighting, composition, and texture. 3. ${styleText} 4. ${qualityText} 5. ${customText} 6. Output ONLY the prompt string. No explanations.`; const userMessage = `Concept: ${basePrompt}`; const output = await hf.textGeneration({ model: AI_MODEL, inputs: `<|system|>\n${systemPrompt}\n<|user|>\n${userMessage}\n<|assistant|>\n`, parameters: { max_new_tokens: 150, temperature: 0.7, top_p: 0.95, repetition_penalty: 1.2, } }); let result = output.generated_text; if (result.includes("<|assistant|>")) { result = result.split("<|assistant|>")[1]; } setFinalPrompt(result.trim()); } catch (err) { console.error(err); setAiError("Lỗi AI: " + (err.message || "Kết nối thất bại.")); generateManual(); // Fallback } finally { setIsLoadingAI(false); } }; const handleGenerate = () => { if (useAI) { generateWithAI(); } else { generateManual(); } }; const handleCopy = () => { navigator.clipboard.writeText(finalPrompt); setCopied(true); setTimeout(() => setCopied(false), 2000); }; const handleCopyAll = () => { const fullText = `Positive: ${finalPrompt}\nNegative: ${negativePrompt}`; navigator.clipboard.writeText(fullText); alert("Copied both Positive & Negative!"); }; const clearAll = () => { setBasePrompt(""); setCustomTags(""); setFinalPrompt(""); setAiError(""); }; return (
Uncensored Logic & AI Assistant