import React, { useState, useEffect, useRef, useCallback } from 'react'; // --- Komponen Ikon SVG --- const SparklesIcon = ({ className }) => (); const ClipboardIcon = ({ className }) => (); const CheckIcon = ({ className }) => (); const MessageCircleIcon = ({ className }) => (); const XIcon = ({ className, onClick }) => (); const LightbulbIcon = ({ className }) => (); const SaveIcon = ({ className }) => (); const RefreshCwIcon = ({ className }) => (); const Spinner = ({ className }) => (
); // --- Konfigurasi Platform --- const platformConfig = { 'Threads': { blocks: 5, chars: 500, type: 'text' }, 'Instagram': { blocks: 1, chars: 2200, type: 'text' }, 'Facebook': { blocks: 1, chars: 5000, type: 'text' }, 'LinkedIn': { blocks: 1, chars: 3000, type: 'text' }, 'TikTok': { type: 'script' }, // Tipe khusus 'Landing Page Lynk.id': { blocks: 1, chars: 10000, type: 'text' }, 'Email Newsletter': { blocks: 1, chars: 15000, type: 'text' }, 'Chanel WhatsApp': { blocks: 1, chars: 4096, type: 'text' }, 'Chanel Telegram': { blocks: 1, chars: 4096, type: 'text' }, }; const defaultLanguageStyles = ['Santai & Humoris','Inspiratif & Menyentuh','Tegas & Informatif','Provokatif & Mengajak Diskusi','Empati & Mendukung','Formal & Akademis','Gaul & Kekinian']; // --- Fungsi Helper untuk API Call & Format --- const callGeminiAPI = async (prompt, schema = null) => { const chatHistory = [{ role: "user", parts: [{ text: prompt }] }]; const payload = { contents: chatHistory }; if (schema) { payload.generationConfig = { responseMimeType: "application/json", responseSchema: schema, }; } const apiKey = ""; const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) { const errorBody = await response.text(); throw new Error(`Permintaan API gagal: ${response.status} ${errorBody}`); } const result = await response.json(); if (result.candidates && result.candidates[0].content && result.candidates[0].content.parts.length > 0) { const text = result.candidates[0].content.parts[0].text; return schema ? JSON.parse(text) : text; } else { throw new Error("Struktur respons dari AI tidak valid atau konten tidak ditemukan."); } }; const formatForReadability = (text) => { // Fungsi ini bisa dikembangkan untuk format yang lebih kompleks jika perlu return text; }; // --- Komponen Utama Aplikasi --- const App = () => { // State untuk input utama const [platform, setPlatform] = useState('Threads'); const [customPlatform, setCustomPlatform] = useState(''); const [niche, setNiche] = useState('tips siap nikah for gen z mager'); const [targetAudience, setTargetAudience] = useState('gen z muslim/ muslimah yang kepo about nikah but males denger ceramah'); const [contentPrinciples, setContentPrinciples] = useState('1. Sesuai kaidah syar’i\n2. Anti pacaran\n3. Anti musik\n4. Full bahasa gen z biar relate tapi gak sok asik'); const [topic, setTopic] = useState(''); // State untuk form const [recipe, setRecipe] = useState('Kisah Nyata dari Lapangan'); const [contentType, setContentType] = useState('Utas Berbobot'); const [contentLimit, setContentLimit] = useState(5); const [maxCharsPerBlock, setMaxCharsPerBlock] = useState(500); const [maxCharsPerBlockArray, setMaxCharsPerBlockArray] = useState(Array(5).fill(500)); const [style, setStyle] = useState('Santai & Humoris'); const [bookInsight, setBookInsight] = useState(''); const [bookDetails, setBookDetails] = useState(''); // State untuk struktur konten const [hookType, setHookType] = useState('Pertanyaan Retoris'); const [bodyType, setBodyType] = useState('Penjelasan Langsung'); const [ctaType, setCtaType] = useState('Ajak Diskusi'); // State untuk 'Bumbu Cerita' const [povPenghulu, setPovPenghulu] = useState(''); const [povSyariah, setPovSyariah] = useState(''); const [povPribadi, setPovPribadi] = useState(''); // State untuk hasil dari AI const [generatedContent, setGeneratedContent] = useState([]); const [generatedTiktokScript, setGeneratedTiktokScript] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [copySuccess, setCopySuccess] = useState(''); // State untuk fitur balas komentar const [commentInput, setCommentInput] = useState(''); const [generatedReply, setGeneratedReply] = useState(''); const [isReplying, setIsReplying] = useState(false); const [replyError, setReplyError] = useState(null); const [copyReplySuccess, setCopyReplySuccess] = useState(''); const [replyStyle, setReplyStyle] = useState('Santai & Humoris'); // State untuk rekomendasi & pengurutan dinamis const [recommendedTopics, setRecommendedTopics] = useState([]); const [isRecommendingTopics, setIsRecommendingTopics] = useState(false); const [recommendationError, setRecommendationError] = useState(null); const [languageStyles, setLanguageStyles] = useState(defaultLanguageStyles); const [isFetchingStyles, setIsFetchingStyles] = useState(false); const debounceTimeout = useRef(null); const sortOptionsDebounce = useRef(null); // State untuk draf tersimpan & konversi const [savedDrafts, setSavedDrafts] = useState([]); const [saveSuccess, setSaveSuccess] = useState(false); const [isConverting, setIsConverting] = useState(false); const [conversionTarget, setConversionTarget] = useState('Instagram'); const [convertedContent, setConvertedContent] = useState(''); const [copyConvertedSuccess, setCopyConvertedSuccess] = useState(false); // Konfigurasi Statis const contentTypes = {'Utas Berbobot': 'Utas/blok bersambung mendalam.','Carousel': 'Konten visual geser.','Motivasi/Mindset': 'Single post motivasi singkat.','Practical Tips': 'Single post berisi tips praktis.','Utas Bersambung': 'Konten bersambung dalam beberapa blok.','Single Post': 'Satu postingan tunggal.','Storytelling': 'Menceritakan sebuah kisah.'}; const isMultiBlock = platformConfig[platform]?.blocks > 1; const hookOptions = {'Pertanyaan Retoris': 'Ajukan pertanyaan yang menusuk.','Fakta Mengejutkan': 'Sajikan data tak terduga.','Kutipan Kuat': 'Gunakan kutipan berpengaruh.','Cerita Personal Singkat': 'Awali dengan kisah pribadi.','Statistik Lokal': 'Sebutkan data spesifik.','"Bayangkan Jika..."': 'Ajak audiens berimajinasi.','Humor Pembuka': 'Gunakan lelucon relevan.','Definisi Ulang': 'Berikan perspektif segar.'}; const bodyOptions = {'Penjelasan Langsung': 'Jelaskan poin utama.','Studi Kasus/Contoh': 'Gunakan contoh nyata.','Poin-poin (Listicle)': 'Sajikan dalam bentuk daftar.','Analogi/Metafora': 'Gunakan perumpamaan mudah.','Analogi Main Game': 'Gunakan perumpamaan dari game.','Tanya Jawab (Q&A)': 'Strukturkan seperti tanya jawab.','Perbandingan (Pros & Cons)': 'Bandingkan dua sisi topik.','Membantah Mitos': 'Bantah mitos umum dengan fakta.','Narasi Kronologis': 'Ceritakan secara berurutan.'}; const ctaOptions = {'Ajak Diskusi': 'Minta pendapat di komentar.','Pertanyaan Langsung': 'Tanyakan sesuatu yang spesifik.','Bagikan & Simpan': 'Ajak untuk menyimpan/membagikan.','Tantangan Kecil': 'Berikan tantangan praktis.','Ajakan Beraksi (Spesifik)': 'Minta audiens melakukan aksi.','Refleksi Diri': 'Ajak audiens merenung.','🛍️ Jualan Langsung': 'Arahkan untuk membeli produk.'}; const viralRecipes = {'Kisah Nyata dari Lapangan': 'Ceritakan kisah nyata.','Konsep Rumit Jadi Simpel': 'Jelaskan konsep rumit.','Sudut Pandang Personal': 'Bagikan pengalaman pribadi.','Solusi Masalah Spesifik': 'Fokus pada satu masalah audiens.','Membantah Mitos Umum': 'Bantah mitos populer.','Niche x Tren Terkini': 'Hubungkan niche dengan tren.','Insight dari Buku/Bacaan': 'Ambil ide dari sebuah buku.','Edukasi Mendalam': 'Buat konten edukasi A-Z.'}; // State untuk opsi yang diurutkan const [sortedRecipes, setSortedRecipes] = useState(Object.keys(viralRecipes)); const [sortedHooks, setSortedHooks] = useState(Object.keys(hookOptions)); const [sortedBodies, setSortedBodies] = useState(Object.keys(bodyOptions)); const [sortedCtas, setSortedCtas] = useState(Object.keys(ctaOptions)); const [isSortingOptions, setIsSortingOptions] = useState(false); // --- EFEK APLIKASI --- useEffect(() => { const config = platformConfig[platform]; if (config && config.type === 'text') { setContentLimit(config.blocks); setMaxCharsPerBlock(config.chars); } else if (platform === 'Threads') { setContentLimit(5); setMaxCharsPerBlock(500); } }, [platform]); useEffect(() => { try { const d = localStorage.getItem('savedContentDrafts'); if (d) setSavedDrafts(JSON.parse(d)); } catch (e) { console.error("Gagal memuat draf", e); } }, []); useEffect(() => { try { localStorage.setItem('savedContentDrafts', JSON.stringify(savedDrafts)); } catch (e) { console.error("Gagal menyimpan draf", e); } }, [savedDrafts]); const fetchLanguageStyles = useCallback(async (currentNiche) => { if (!currentNiche) { setLanguageStyles(defaultLanguageStyles); return; } setIsFetchingStyles(true); const prompt = `Berdasarkan niche "${currentNiche}", berikan 7 gaya bahasa yang relevan. Format JSON: {"styles": ["gaya 1", ...]}`; const schema = { type: "OBJECT", properties: { styles: { type: "ARRAY", items: { type: "STRING" } } }, required: ["styles"] }; try { const r = await callGeminiAPI(prompt, schema); if (r && Array.isArray(r.styles)) { setLanguageStyles([...new Set([...defaultLanguageStyles, ...r.styles])]); } } catch (e) { console.error("Gagal fetch gaya bahasa:", e); setLanguageStyles(defaultLanguageStyles); } finally { setIsFetchingStyles(false); } }, []); useEffect(() => { if (debounceTimeout.current) clearTimeout(debounceTimeout.current); debounceTimeout.current = setTimeout(() => { fetchLanguageStyles(niche); }, 1000); return () => { if (debounceTimeout.current) clearTimeout(debounceTimeout.current); }; }, [niche, fetchLanguageStyles]); useEffect(() => { const fetchAndSortOptions = async () => { if (!niche && !topic) return; setIsSortingOptions(true); const finalPlatform = platform === 'Ketik Sendiri...' ? customPlatform : platform; const prompt = `Anda ahli strategi konten. Berdasarkan konteks Platform: "${finalPlatform}", Niche: "${niche}", Topik: "${topic}", urutkan daftar strategi ini dari PALING berpotensi viral ke kurang. Format JSON: {"recipes": [...], "hooks": [...], "bodies": [...], "ctas": [...]}. Isi array harus string dari daftar asli, jangan menambah/mengurangi item. Daftar Resep: ${JSON.stringify(Object.keys(viralRecipes))}. Daftar Hook: ${JSON.stringify(Object.keys(hookOptions))}. Daftar Isi: ${JSON.stringify(Object.keys(bodyOptions))}. Daftar CTA: ${JSON.stringify(Object.keys(ctaOptions))}.`; const schema = { type: "OBJECT", properties: { recipes: { type: "ARRAY", items: { type: "STRING" } }, hooks: { type: "ARRAY", items: { type: "STRING" } }, bodies: { type: "ARRAY", items: { type: "STRING" } }, ctas: { type: "ARRAY", items: { type: "STRING" } } }, required: ["recipes", "hooks", "bodies", "ctas"] }; try { const result = await callGeminiAPI(prompt, schema); if (result.recipes.length === Object.keys(viralRecipes).length) setSortedRecipes(result.recipes); if (result.hooks.length === Object.keys(hookOptions).length) setSortedHooks(result.hooks); if (result.bodies.length === Object.keys(bodyOptions).length) setSortedBodies(result.bodies); if (result.ctas.length === Object.keys(ctaOptions).length) setSortedCtas(result.ctas); } catch (e) { console.error("Gagal mengurutkan opsi:", e); setSortedRecipes(Object.keys(viralRecipes)); setSortedHooks(Object.keys(hookOptions)); setSortedBodies(Object.keys(bodyOptions)); setSortedCtas(Object.keys(ctaOptions)); } finally { setIsSortingOptions(false); } }; if (sortOptionsDebounce.current) clearTimeout(sortOptionsDebounce.current); sortOptionsDebounce.current = setTimeout(() => { fetchAndSortOptions(); }, 1500); return () => { if (sortOptionsDebounce.current) clearTimeout(sortOptionsDebounce.current); }; }, [niche, topic, platform, customPlatform]); useEffect(() => { if (isFetchingStyles) return; setStyle(cs => (cs === 'Ketik Sendiri...' || languageStyles.includes(cs)) ? cs : (languageStyles[0] || '')); setReplyStyle(crs => (crs === 'Ketik Sendiri...' || languageStyles.includes(crs)) ? crs : (languageStyles[0] || '')); }, [languageStyles, isFetchingStyles]); useEffect(() => { const newSize = Number(contentLimit) || 1; setMaxCharsPerBlockArray(oldArray => { const newArray = new Array(newSize).fill(maxCharsPerBlock); for (let i = 0; i < Math.min(newSize, oldArray.length); i++) { newArray[i] = oldArray[i]; } return newArray; }); }, [contentLimit, maxCharsPerBlock]); // --- FUNGSI HANDLER UTAMA --- const handleMaxCharsChange = (index, value) => { const newArray = [...maxCharsPerBlockArray]; newArray[index] = Number(value); setMaxCharsPerBlockArray(newArray); }; const handleCopy = (text, type, id = '') => { navigator.clipboard.writeText(text).then(() => { if (type === 'content') { setCopySuccess(`content-${id}`); setTimeout(() => setCopySuccess(''), 2000); } else if (type === 'reply') { setCopyReplySuccess(text); setTimeout(() => setCopyReplySuccess(''), 2000); } else if (type === 'converted') { setCopyConvertedSuccess(true); setTimeout(() => setCopyConvertedSuccess(false), 2000); } }).catch(err => console.error('Gagal menyalin:', err)); }; const handleSaveDraft = () => { if (generatedContent.length === 0 && !generatedTiktokScript) return; const newDraft = { id: Date.now(), title: topic || "Draf Tanpa Judul", platform, content: generatedContent, script: generatedTiktokScript, timestamp: new Date().toISOString() }; setSavedDrafts(p => [newDraft, ...p]); setSaveSuccess(true); setTimeout(() => setSaveSuccess(false), 2000); }; const handleGetRecommendations = async () => { setIsRecommendingTopics(true); setRecommendationError(null); setRecommendedTopics([]); const finalPlatform = platform === 'Ketik Sendiri...' ? customPlatform : platform; const prompt = `Anda ahli strategi konten. Beri 5 ide topik viral untuk Platform: "${finalPlatform}", Niche: "${niche}", Audiens: "${targetAudience}", Resep: "${recipe}". Format JSON: {"topics": ["ide 1", ...]}`; const schema = { type: "OBJECT", properties: { topics: { type: "ARRAY", items: { type: "STRING" } } }, required: ["topics"] }; try { const r = await callGeminiAPI(prompt, schema); if (r && Array.isArray(r.topics)) { setRecommendedTopics(r.topics); } else { throw new Error("Format respons tidak valid."); } } catch (e) { console.error(e); setRecommendationError("Gagal mencari ide."); } finally { setIsRecommendingTopics(false); } }; const handleGenerate = async () => { setIsLoading(true); setError(null); setGeneratedContent([]); setGeneratedTiktokScript(null); const finalPlatform = platform === 'Ketik Sendiri...' ? customPlatform : platform; const isTikTok = platform === 'TikTok'; let prompt; let schema; if (isTikTok) { prompt = `Anda adalah seorang sutradara dan penulis skrip TikTok viral. Buat ide konten TikTok lengkap berdasarkan detail berikut:\n\nPlatform: ${finalPlatform}\nNiche: ${niche}\nTarget Audiens: ${targetAudience}\nTopik: ${topic}\nGaya: ${style}\n\nTugas: Hasilkan ide skrip video pendek (15-60 detik) yang menarik. Fokus pada hook visual yang kuat di 3 detik pertama.\n\nATURAN WAJIB:\n1. FORMAT OUTPUT: HARUS berupa JSON dengan struktur: {"visual_hook": "...", "on_screen_text": "...", "voiceover_script": "...", "cta": "...", "sound_suggestion": "..."}.\n2. Bahasa: Indonesia.`; schema = { type: "OBJECT", properties: { visual_hook: { type: "STRING" }, on_screen_text: { type: "STRING" }, voiceover_script: { type: "STRING" }, cta: { type: "STRING" }, sound_suggestion: { type: "STRING" } }, required: ["visual_hook", "on_screen_text", "voiceover_script", "cta", "sound_suggestion"] }; } else { let contentAndCharRules = ''; if (!isMultiBlock) { const charLimit = Math.min(maxCharsPerBlock, 15000); contentAndCharRules = `4. **ATURAN KARAKTER:** Batas karakter untuk post ini adalah ${charLimit} karakter.`; } else { const limitsDetail = maxCharsPerBlockArray.map((limit, index) => `- Post ${index + 1}: HARUS KURANG DARI ${Math.min(limit, 500)} karakter.`).join('\n'); contentAndCharRules = `4. **ATURAN KARAKTER:**\n - Jumlah post tidak boleh melebihi ${contentLimit} blok.\n - Patuhi batasan karakter ini: ${limitsDetail}`; } prompt = `Anda adalah copywriter ahli untuk platform ${finalPlatform}. Buat draf konten viral.\n\n--- ATURAN PALING KRITIS ---\n1. **INTEGRITAS KALIMAT PRIORITAS #1:** JANGAN PERNAH menghasilkan teks yang berakhir dengan kalimat terpotong. Setiap blok HARUS berakhir dengan titik (.), tanda tanya (?), atau seru (!).\n2. **SESUAIKAN, JANGAN POTONG:** Untuk mematuhi batas karakter, ringkas dan susun ulang kalimat secara cerdas. Lebih baik konten lebih pendek tapi utuh.\n\n--- KONTEKS ---\nPlatform: ${finalPlatform}\nNiche: ${niche}\nTarget Audiens: ${targetAudience}\nPrinsip: ${contentPrinciples}\n\n--- ATURAN TEKNIS ---\n1. Fokus pada Audiens.\n2. Gaya 'saya ke kamu'.\n3. FORMAT OUTPUT: JSON {"threads": ["post 1", ...]}.\n${contentAndCharRules}\n\n--- DETAIL KONTEN ---\nTopik: ${topic}\nJenis Konten: ${contentType}\nResep Viral: ${recipe}\nGaya Bahasa: ${style}\nStruktur: Hook '${hookType}', Isi '${bodyType}', CTA '${ctaType}'.\nInspirasi Tambahan: ${bookInsight || povPribadi || povPenghulu || povSyariah || ''}`; schema = { type: "OBJECT", properties: { threads: { type: "ARRAY", items: { type: "STRING" } } }, required: ["threads"] }; } try { const result = await callGeminiAPI(prompt, schema); if (isTikTok) { setGeneratedTiktokScript(result); } else { if (result && Array.isArray(result.threads)) { setGeneratedContent(result.threads); } else { throw new Error("Format respons tidak sesuai."); } } } catch (e) { console.error(e); setError("Gagal membuat konten. Detail: " + e.message); } finally { setIsLoading(false); } }; const handleConversion = async () => { if (generatedContent.length === 0 && !generatedTiktokScript) return; setIsConverting(true); setConvertedContent(''); const originalPlatform = platform === 'Ketik Sendiri...' ? customPlatform : platform; const contentToConvert = platform === 'TikTok' ? `Skrip TikTok:\nVisual Hook: ${generatedTiktokScript.visual_hook}\nTeks di Layar: ${generatedTiktokScript.on_screen_text}\nNarasi: ${generatedTiktokScript.voiceover_script}\nCTA: ${generatedTiktokScript.cta}\nSaran Suara: ${generatedTiktokScript.sound_suggestion}` : generatedContent.join('\n\n'); const prompt = `Anda adalah ahli adaptasi konten multi-platform. Ubah konten berikut dari format ${originalPlatform} menjadi format yang optimal untuk ${conversionTarget}.\n\nPerhatikan:\n- Nada bicara yang sesuai untuk ${conversionTarget}.\n- Batasan karakter dan format.\n- Penggunaan hashtag, emoji, dan gaya CTA yang relevan.\n\nKonten Asli:\n"""\n${contentToConvert}\n"""\n\nKonten Hasil Adaptasi untuk ${conversionTarget}:`; try { const result = await callGeminiAPI(prompt); setConvertedContent(result); } catch (e) { console.error(e); setConvertedContent("Gagal melakukan konversi. Coba lagi."); } finally { setIsConverting(false); } }; return (

Content Suite Cerdas

by @ikmalogic

0. Pilih Platform Tujuan

{platform === 'Ketik Sendiri...' && (
setCustomPlatform(e.target.value)} placeholder="Tulis nama platform Anda di sini..." className="w-full bg-slate-900 border-slate-600 rounded-lg p-2 pr-8 focus:ring-2 focus:ring-cyan-500 focus:outline-none" /> {customPlatform && setCustomPlatform('')} className="absolute right-2 top-1/2 -translate-y-1/2 h-5 w-5 text-slate-400 hover:text-white cursor-pointer" />}
)}
{/* Kolom Input */}

1. Tentukan Persona Anda

setNiche(e.target.value)} placeholder="Contoh: Keuangan Pribadi" className="w-full bg-slate-700 border-slate-600 rounded-lg p-2 pr-8 focus:ring-2 focus:ring-cyan-500 focus:outline-none" />{niche && setNiche('')} className="absolute right-2 top-1/2 -translate-y-1/2 h-5 w-5 text-slate-400 hover:text-white cursor-pointer" />}
setTargetAudience(e.target.value)} placeholder="Contoh: Mahasiswa" className="w-full bg-slate-700 border-slate-600 rounded-lg p-2 pr-8 focus:ring-2 focus:ring-cyan-500 focus:outline-none" />{targetAudience && setTargetAudience('')} className="absolute right-2 top-1/2 -translate-y-1/2 h-5 w-5 text-slate-400 hover:text-white cursor-pointer" />}
{povPenghulu && ( setPovPenghulu('')} className="absolute right-2 top-2 h-5 w-5 text-slate-400 hover:text-white cursor-pointer" />)}
{povSyariah && ( setPovSyariah('')} className="absolute right-2 top-2 h-5 w-5 text-slate-400 hover:text-white cursor-pointer" />)}
{povPribadi && ( setPovPribadi('')} className="absolute right-2 top-2 h-5 w-5 text-slate-400 hover:text-white cursor-pointer" />)}
)}
{isFetchingStyles && }
{/* Kolom Output */}

3. Hasil Draf Anda

{(generatedContent.length > 0 || generatedTiktokScript) && !isLoading && ()}
{saveSuccess &&
Draf berhasil disimpan!
}
{isLoading &&

AI sedang meracik konten terbaik untuk {platform}...

} {error &&
{error}
} {!isLoading && !error && generatedContent.length === 0 && !generatedTiktokScript && (

Draf konten akan muncul di sini.

)} {generatedContent.map((thread, index) => (

{formatForReadability(thread)}

{thread.length} Karakter
))} {generatedTiktokScript && (
Visual Hook (3 detik pertama):

{generatedTiktokScript.visual_hook}

Teks di Layar:

{generatedTiktokScript.on_screen_text}

Narasi / Voiceover Script:

{generatedTiktokScript.voiceover_script}

CTA (Audio/Visual):

{generatedTiktokScript.cta}

Saran Sound/Musik:

{generatedTiktokScript.sound_suggestion}

)}
{(generatedContent.length > 0 || generatedTiktokScript) && !isLoading && (

Ubah Format ke Platform Lain

{convertedContent && (

{convertedContent}

)}
)}
{/* Kolom Fitur Tambahan */}

4. Fitur Tambahan

Balas Komentar Audiens

{commentInput && ( setCommentInput('')} className="absolute right-2 top-2 h-5 w-5 text-slate-400 hover:text-white cursor-pointer" />)}
{replyError &&

{replyError}

} {generatedReply &&

{generatedReply}

}
); }; export default App;