From 85a92c9b23477281a0983b9321123a391c99dfd7 Mon Sep 17 00:00:00 2001 From: Vassshhh Date: Mon, 23 Jun 2025 17:14:40 +0700 Subject: [PATCH] ok --- src/ChatBot.js | 24 +++++++++++--- src/Dashboard.js | 79 ++++++++++++++++++++++++----------------------- src/ProfileTab.js | 14 +++------ src/index.js | 14 +++++++++ 4 files changed, 79 insertions(+), 52 deletions(-) diff --git a/src/ChatBot.js b/src/ChatBot.js index 3af1a87..7af0140 100644 --- a/src/ChatBot.js +++ b/src/ChatBot.js @@ -62,7 +62,7 @@ const ChatBot = ({ existingConversation, readOnly, hh }) => { setIsLoading(true); try { // Send to backend - const response = await fetch('https://bot.kediritechnopark.com/webhook/master-agent/ask/dev', { + const response = await fetch('https://bot.kediritechnopark.com/webhook/master-agent/ask', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pertanyaan: message, sessionId: JSON.parse(localStorage.getItem('session')).sessionId, lastSeen: new Date().toISOString(), name: JSON.parse(localStorage.getItem('session')).name, phoneNumber: JSON.parse(localStorage.getItem('session')).phoneNumber }), @@ -72,7 +72,7 @@ const ChatBot = ({ existingConversation, readOnly, hh }) => { console.log(data) // Assuming your backend sends back something like: { answer: "text" } // Adjust this according to your actual response shape - const botAnswer = data.jawaban || 'Maaf, saya tidak mengerti.'; + const botAnswer = data.jawaban || 'Maaf saya sedang tidak tersedia sekarang, coba lagi nanti'; // Add bot's reply setMessages(prev => [ @@ -106,15 +106,29 @@ const ChatBot = ({ existingConversation, readOnly, hh }) => { function formatBoldText(text) { const parts = text.split(/(\*\*[^\*]+\*\*)/g); - return parts.map((part, index) => { + return parts.flatMap((part, index) => { + const elements = []; + if (part.startsWith('**') && part.endsWith('**')) { - return {part.slice(2, -2)}; + // Bold text + part = part.slice(2, -2); + part.split('\n').forEach((line, i) => { + if (i > 0) elements.push(
); + elements.push({line}); + }); } else { - return {part}; + // Normal text + part.split('\n').forEach((line, i) => { + if (i > 0) elements.push(
); + elements.push({line}); + }); } + + return elements; }); } + return (
diff --git a/src/Dashboard.js b/src/Dashboard.js index c68be67..1266d82 100644 --- a/src/Dashboard.js +++ b/src/Dashboard.js @@ -22,7 +22,6 @@ const Dashboard = () => { const [modalContent, setModalContent] = useState(null); const [rawData, setRawData] = useState([]); const [loading, setLoading] = useState(true); // ⬅️ Tambahkan state loading - const [checkOnce, setCheckOnce] = useState(false); // ⬅️ Tambahkan state loading const [stats, setStats] = useState({ totalChats: 0, @@ -139,54 +138,58 @@ const Dashboard = () => { } }; - if (!checkOnce && 'serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(function (registration) { - registration.pushManager.getSubscription().then(function (subscription) { - setCheckOnce(true); - if (subscription === null) { - // Not subscribed yet — show modal asking user to subscribe - setModalContent( setModalContent('')} />); - } else { - // Already subscribed - setModalContent('') - console.log('User is already subscribed.'); - subscribeUser(); - } - }); - }); - } - fetchData(); // Jalankan langsung saat komponen di-mount const interval = setInterval(fetchData, 60000); // Jalankan setiap 30 detik return () => clearInterval(interval); // Bersihkan interval saat komponen unmount }, [navigate]); - const subscribeUser = async () => { - const registration = await navigator.serviceWorker.register('/sw.js', { - scope: '/', +useEffect(() => { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then(async (registration) => { + const subscription = await registration.pushManager.getSubscription(); + if (!subscription) { + // Belum subscribe → tampilkan prompt + setModalContent( + setModalContent('')} + /> + ); + } else { + // Sudah subscribe → tidak perlu panggil subscribeUser lagi + console.log('User is already subscribed.'); + setModalContent(''); + subscribeUser(); + } }); + } +}, []); - const subscription = await registration.pushManager.subscribe({ - userVisibleOnly: true, - applicationServerKey: urlBase64ToUint8Array('BPT-ypQB0Z7HndmeFhRR7AMjDujCLSbOQ21VoVHLQg9MOfWhEZ7SKH5cMjLqkXHl2sTuxdY2rjHDOAxhRK2G2K4'), - }); - const token = localStorage.getItem('token'); +const subscribeUser = async () => { + setModalContent(''); + const registration = await navigator.serviceWorker.ready; - await fetch('https://bot.kediritechnopark.com/webhook/subscribe', { - method: 'POST', - body: JSON.stringify({ - subscription, // ← push subscription object - }), - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${token}`, - }, - }); + const subscription = await registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlBase64ToUint8Array('BPT-ypQB0Z7HndmeFhRR7AMjDujCLSbOQ21VoVHLQg9MOfWhEZ7SKH5cMjLqkXHl2sTuxdY2rjHDOAxhRK2G2K4'), + }); + + const token = localStorage.getItem('token'); + + await fetch('https://bot.kediritechnopark.com/webhook/subscribe', { + method: 'POST', + body: JSON.stringify({ subscription }), + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}`, + }, + }); + + setModalContent(''); +}; - setModalContent('') - }; function urlBase64ToUint8Array(base64String) { const padding = '='.repeat((4 - base64String.length % 4) % 4); diff --git a/src/ProfileTab.js b/src/ProfileTab.js index 1ba46fc..928154b 100644 --- a/src/ProfileTab.js +++ b/src/ProfileTab.js @@ -89,19 +89,15 @@ const ProfileTab = () => { try { const token = localStorage.getItem('token'); - if (profile.newPassword && profile.newPassword !== profile.confirmPassword) { - alert('Password dan konfirmasi tidak sama.'); + if (profile.newPassword == '' || profile.oldPassword == '') { + alert('Password dan konfirmasi tidak boleh kosong.'); return; } const payload = { ...profile }; if (!payload.newPassword) { delete payload.newPassword; - delete payload.confirmPassword; - } else { - payload.password = payload.newPassword; - delete payload.newPassword; - delete payload.confirmPassword; + delete payload.oldPassword; } const response = await fetch('https://bot.kediritechnopark.com/webhook/profile', { @@ -175,7 +171,7 @@ const ProfileTab = () => { @@ -184,7 +180,7 @@ const ProfileTab = () => { diff --git a/src/index.js b/src/index.js index d563c0f..d6a93ec 100644 --- a/src/index.js +++ b/src/index.js @@ -5,12 +5,26 @@ import App from './App'; import reportWebVitals from './reportWebVitals'; const root = ReactDOM.createRoot(document.getElementById('root')); + +if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/sw.js', { scope: '/' }) + .then((registration) => { + console.log('✅ Service Worker registered successfully:', registration); + }) + .catch((error) => { + console.error('❌ Service Worker registration failed:', error); + }); + }); +} + root.render( ); + // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals