From 99e79e54a4749306c8fbd51774f032f18b4a5211 Mon Sep 17 00:00:00 2001 From: Vassshhh Date: Fri, 20 Jun 2025 19:40:20 +0700 Subject: [PATCH] ok --- public/no-brand.jpg | Bin 0 -> 12866 bytes src/ChatBot.js | 31 +++--- src/Dashboard.js | 72 +++++++------- src/Dashboard.module.css | 10 +- src/DiscussedTopics.js | 4 +- src/FollowUps.js | 1 - src/FollowUps.module.css | 1 - src/ProfileTab.js | 189 ++++++++++++++++++++--------------- src/ProfileTab.module.css | 200 ++++++++++++++++++++++---------------- 9 files changed, 293 insertions(+), 215 deletions(-) create mode 100644 public/no-brand.jpg diff --git a/public/no-brand.jpg b/public/no-brand.jpg new file mode 100644 index 0000000000000000000000000000000000000000..de7feead9e45c6074997150627ed628b442c6410 GIT binary patch literal 12866 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 { console.error('Fetch error:', error); } }; +function formatBoldText(text) { + const parts = text.split(/(\*\*[^\*]+\*\*)/g); + + return parts.map((part, index) => { + if (part.startsWith('**') && part.endsWith('**')) { + return {part.slice(2, -2)}; + } else { + return {part}; + } + }); +} return (
@@ -127,19 +138,15 @@ const ChatBot = ({ existingConversation, readOnly, hh }) => { >
{msg.sender !== 'bot' - ? msg.text - : (() => { - try { - let cleanText = msg.text.replace(/`/g, ''); // Remove backticks - cleanText = cleanText.substring(4); // Remove first 4 characters - let parsedObj = JSON.parse(cleanText); + ? msg.text + : (() => { + try { + return formatBoldText(msg.text); // Apply formatting here + } catch (e) { + return msg.text; + } + })()} - return parsedObj.jawaban; - } catch (e) { - return msg.text; // Return an empty string if there is an error - } - - })()} {msg.quickReplies && (
{msg.quickReplies.map((reply, i) => ( diff --git a/src/Dashboard.js b/src/Dashboard.js index a17db14..c68be67 100644 --- a/src/Dashboard.js +++ b/src/Dashboard.js @@ -145,7 +145,7 @@ const Dashboard = () => { setCheckOnce(true); if (subscription === null) { // Not subscribed yet — show modal asking user to subscribe - setModalContent(setModalContent('')} />); + setModalContent( setModalContent('')} />); } else { // Already subscribed setModalContent('') @@ -228,17 +228,17 @@ const Dashboard = () => { }; const prefixes = Object.keys(prefixLabelMap); -const parsedHours = rawData.map(d => new Date(d.hour)); -parsedHours.sort((a, b) => a - b); + const parsedHours = rawData.map(d => new Date(d.hour)); + parsedHours.sort((a, b) => a - b); -// Extract only the date (no timezone shifting) -const getDateStr = date => date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0'); + // Extract only the date (no timezone shifting) + const getDateStr = date => date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0'); -const hours = parsedHours.map((date, index) => { - const timeStr = date.getHours().toString().padStart(2, '0') + ':' + date.getMinutes().toString().padStart(2, '0'); - return index === parsedHours.length - 1 ? 'Sekarang' : timeStr; -}); + const hours = parsedHours.map((date, index) => { + const timeStr = date.getHours().toString().padStart(2, '0') + ':' + date.getMinutes().toString().padStart(2, '0'); + return index === parsedHours.length - 1 ? 'Now' : timeStr; + }); const counts = {}; prefixes.forEach(prefix => { @@ -303,25 +303,25 @@ const hours = parsedHours.map((date, index) => { return (
-
- +
+ - {isMenuOpen && ( -
- - -
- )} -
+ {isMenuOpen && ( +
+ + +
+ )} +
Bot Avatar

Dermalounge AI Admin Dashboard

@@ -329,26 +329,26 @@ const hours = parsedHours.map((date, index) => {
-
+

{stats.totalChats}

-

Total Percakapan selama 24 jam

+

TOTAL USER PER DAY

{stats.botMessages}

-

Respons Bot

+

AI RESPONSE

-
setModalContent()}> +
setModalContent()}>

{followUps.length}

-

Follow up

+

BOOKING REQUEST

{discussedTopics[0]?.topic}

-

Paling sering ditanyakan

+

Top topic

-

Grafik Interaksi

+

Interactions

@@ -371,9 +371,9 @@ const hours = parsedHours.map((date, index) => { }} >

- Seret file ke sini, atau Klik untuk unggah + Drop file here, or Click to upload

-

Klik untuk unggah

+

Click to upload

{selectedFile && ( <> diff --git a/src/Dashboard.module.css b/src/Dashboard.module.css index 860f527..7f8b06e 100644 --- a/src/Dashboard.module.css +++ b/src/Dashboard.module.css @@ -55,11 +55,17 @@ margin-top: 20px; } +.statsGrid p { + text-transform: uppercase; +} .statCard { background: #ece5dd; border-radius: 10px; padding: 20px; box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); + display: flex; + flex-direction: column; + justify-content: space-around; } .statCard h2 { @@ -200,8 +206,8 @@ position: absolute; position: relative; display: inline-block; position: absolute; - top: 10px; - right: 10px; + bottom: 5px; + right: 5px; } .dropdownToggle { diff --git a/src/DiscussedTopics.js b/src/DiscussedTopics.js index 7cdb9d5..723b10d 100644 --- a/src/DiscussedTopics.js +++ b/src/DiscussedTopics.js @@ -5,10 +5,10 @@ import React from 'react'; const DiscussedTopics = ({ topics }) => { return (
-

Topik yang Sering Ditanyakan

+

Top Topic

    {topics.map((topic, idx) => ( -
  • {topic.topic} - {topic.count} kali
  • +
  • {topic.topic} - {topic.count} x
  • ))}
diff --git a/src/FollowUps.js b/src/FollowUps.js index 4fe0020..16d177a 100644 --- a/src/FollowUps.js +++ b/src/FollowUps.js @@ -4,7 +4,6 @@ import styles from './FollowUps.module.css'; const FollowUps = ({ data }) => { return (
-

User yang tertarik

{data.map(user => (
diff --git a/src/FollowUps.module.css b/src/FollowUps.module.css index 348a108..8b88130 100644 --- a/src/FollowUps.module.css +++ b/src/FollowUps.module.css @@ -1,5 +1,4 @@ .container { - padding: 24px; background-color: #f7f9fa; font-family: 'Amazon Ember', sans-serif; } diff --git a/src/ProfileTab.js b/src/ProfileTab.js index bfcfec2..1ba46fc 100644 --- a/src/ProfileTab.js +++ b/src/ProfileTab.js @@ -1,43 +1,41 @@ import React, { useState, useRef, useEffect } from 'react'; -import { FaPen } from 'react-icons/fa'; -import styles from './ProfileTab.module.css'; import { useNavigate } from 'react-router-dom'; +import styles from './ProfileTab.module.css'; const ProfileTab = () => { const menuRef = useRef(null); const navigate = useNavigate(); const [isEditing, setIsEditing] = useState(false); const [isMenuOpen, setIsMenuOpen] = useState(false); + const [profile, setProfile] = useState({}); + const [profileTemp, setProfileTemp] = useState({}); + + const licenses = [ + { id: 1, type: "Current Subscription", number: "DRML-2025-AI001", validUntil: "June 30 2025" }, + ]; - // Close dropdown if click outside useEffect(() => { const handleClickOutside = (event) => { if (menuRef.current && !menuRef.current.contains(event.target)) { setIsMenuOpen(false); } }; - document.addEventListener('mousedown', handleClickOutside); - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; + return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const handleLogout = () => { localStorage.removeItem('token'); localStorage.removeItem('user'); - navigator.serviceWorker.ready.then(function (registration) { - registration.pushManager.getSubscription().then(function (subscription) { + navigator.serviceWorker.ready.then((registration) => { + registration.pushManager.getSubscription().then((subscription) => { if (subscription) { - subscription.unsubscribe().then(function (successful) { - console.log('Push subscription unsubscribed on logout:', successful); - // Optional: also notify backend to clear the token + subscription.unsubscribe().then((successful) => { + console.log('Unsubscribed from push notifications:', successful); fetch('/api/clear-subscription', { method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ endpoint: subscription.endpoint }), }); }); @@ -48,73 +46,79 @@ const ProfileTab = () => { window.location.reload(); }; - useEffect(() => { - const fetchData = async () => { - const token = localStorage.getItem('token'); + useEffect(() => { + const fetchData = async () => { + const token = localStorage.getItem('token'); - try { - const response = await fetch('https://bot.kediritechnopark.com/webhook/dashboard?profileOnly=true', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${token}`, - }, - }); + try { + const response = await fetch('https://bot.kediritechnopark.com/webhook/dashboard?profileOnly=true', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}`, + }, + }); - if (response.status === 401 || response.status === 403) { - handleLogout(); - return; - } + if (response.status === 401 || response.status === 403) { + handleLogout(); + return; + } - if (!response.ok) { - throw new Error('Fetch gagal dengan status: ' + response.status); - } + if (!response.ok) { + throw new Error('Fetch gagal dengan status: ' + response.status); + } - const data = await response.json(); - console.log(data); + const data = await response.json(); + setProfile(data.profile_data); + setProfileTemp(data.profile_data); + } catch (error) { + console.error('Fetch error:', error); + navigate('/login'); + } + }; - setProfile(data.profile_data); - } catch (error) { - console.error('Error:', error); - navigate('/login'); - } - }; - - fetchData(); // Jalankan langsung saat komponen di-mount - - }, [navigate]); - - const [profile, setProfile] = useState({}); - - const licenses = [ - { id: 1, type: "AI Bot License", number: "DL-2025-AI001", validUntil: "2026-12-31" }, - { id: 2, type: "Clinic Data Access", number: "DL-2025-CL002", validUntil: "2026-06-30" } - ]; + fetchData(); + }, [navigate]); const handleChange = (e) => { const { name, value } = e.target; - setProfile((prev) => ({ ...prev, [name]: value })); + setProfile(prev => ({ ...prev, [name]: value })); }; + const handleSave = async () => { try { const token = localStorage.getItem('token'); + if (profile.newPassword && profile.newPassword !== profile.confirmPassword) { + alert('Password dan konfirmasi tidak sama.'); + return; + } + + const payload = { ...profile }; + if (!payload.newPassword) { + delete payload.newPassword; + delete payload.confirmPassword; + } else { + payload.password = payload.newPassword; + delete payload.newPassword; + delete payload.confirmPassword; + } + const response = await fetch('https://bot.kediritechnopark.com/webhook/profile', { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, - body: JSON.stringify(profile), + body: JSON.stringify(payload), }); if (!response.ok) throw new Error('Gagal menyimpan profil'); const result = await response.json(); - console.log('Profil berhasil diperbarui:', result); setIsEditing(false); - alert('Profil berhasil disimpan!'); + alert('Profile saved!'); } catch (error) { console.error('Error saat menyimpan profil:', error); alert('Terjadi kesalahan saat menyimpan profil.'); @@ -123,8 +127,7 @@ const ProfileTab = () => { return (
-
-

Profil Perusahaan

+
- - - - -
)}
+ Bot Avatar +
+

Dermalounge AI Admin Profile

+
- Company Logo
{["name", "company", "address", "email", "phone"].map((field) => (
@@ -164,35 +161,75 @@ const ProfileTab = () => { -
))} - {isEditing && -
+
+ + +
+
+ + +
+ + )} + + {!isEditing && +
setIsEditing(true)} > - Simpan + Edit +
+ } + {isEditing && + +
+ {/*
{ + setIsEditing(false); + setProfile(profileTemp); + }}> + Batal +
*/} +
+ Save +
}
-

License

{licenses.map((item) => (

{item.type}

-

No: {item.number}

-

Berlaku sampai: {item.validUntil}

+

{item.number}

+

Free License Valid until: {item.validUntil}

))}
+ +
+ © 2025 Kediri Technopark +
); }; diff --git a/src/ProfileTab.module.css b/src/ProfileTab.module.css index b14a068..75c14f2 100644 --- a/src/ProfileTab.module.css +++ b/src/ProfileTab.module.css @@ -1,40 +1,31 @@ -/* Container */ +/* Container Utama */ .dashboardContainer { - width: 100%; + max-width: 900px; + margin: 30px auto; + background: #fff; + border-radius: 10px; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); padding: 20px; - max-width: 1200px; - margin: 0 auto; - box-sizing: border-box; } -/* Header */ -.profileHeader { +.dashboardHeader { display: flex; - justify-content: space-between; align-items: center; - flex-wrap: wrap; - margin-bottom: 20px; - gap: 12px; -} - -.editButton { - background-color: #075e54; + gap: 15px; + background: #075e54; color: white; - padding: 6px 12px; - font-size: 12px; - border: none; - border-radius: 8px; - display: flex; - align-items: center; - gap: 6px; - cursor: pointer; - transition: background-color 0.3s ease; + padding: 20px; + border-radius: 10px 10px 0 0; + position: relative; } -.editButton:hover { - background-color: #0f9b8a; +.dashboardHeader img { + width: 75px; + height: 75px; + border-radius: 50%; } + /* Profile Section */ .profileSection { display: flex; @@ -43,6 +34,7 @@ gap: 20px; flex-wrap: wrap; margin-bottom: 30px; + margin-top: 20px; } .companyImage { @@ -80,64 +72,42 @@ color: white; padding: 16px; border-radius: 12px; - box-shadow: 0 4px 8px rgba(0,0,0,0.1); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); font-size: 14px; } -/* ==================== - Responsive Breakpoints -==================== */ - -/* Tablet (768px – 1023px) */ -@media screen and (max-width: 1023px) { - .profileSection { - flex-direction: row; - justify-content: flex-start; - } - - .profileDetails { - min-width: 100%; - } - - .licenseCards { - grid-template-columns: repeat(2, 1fr); - } +.profileHeader { + flex-direction: column; + align-items: flex-start; } -/* Mobile (≤ 767px) */ -@media screen and (max-width: 767px) { - .profileHeader { - flex-direction: column; - align-items: flex-start; - } - - .editButton { - align-self: flex-end; - } - - .profileSection { - flex-direction: column; - align-items: center; - text-align: center; - } - - .companyImage { - margin-bottom: 12px; - } - - .profileDetails { - text-align: left; - width: 100%; - } - - .licenseCards { - grid-template-columns: 1fr; - } - - .licenseCard { - font-size: 13px; - } +.editButton { + align-self: flex-end; } + +.profileSection { + flex-direction: column; + align-items: center; + text-align: center; +} + +.companyImage { + margin-bottom: 12px; +} + +.profileDetails { + text-align: left; + width: 100%; +} + +.licenseCards { + grid-template-columns: 1fr; +} + +.licenseCard { + font-size: 13px; +} + .profileInputGroup { display: flex; align-items: center; @@ -147,7 +117,8 @@ } .profileInputGroup label { - min-width: 100px; /* atau sesuai label terpanjang */ + min-width: 110px; + /* atau sesuai label terpanjang */ font-size: 14px; } @@ -162,7 +133,8 @@ width: auto; max-width: 100%; - flex: 1; /* biar input bisa melar jika ruang tersedia */ + flex: 1; + /* biar input bisa melar jika ruang tersedia */ } /* Saat tidak dalam mode editing */ @@ -173,18 +145,17 @@ color: #000; } - .dropdownContainer { position: relative; display: inline-block; position: absolute; - top: 37px; - right: 10px; + bottom: 5px; + right: 5px; } .dropdownToggle { - color: #ffff; - background-color: #255e54; + background-color: #ffff; + color: #255e54; padding: 8px 12px; border: none; border-radius: 4px; @@ -216,3 +187,62 @@ background-color: #f0f0f0; } + +/* Input Profil */ +.profileForm { + display: flex; + flex-direction: column; + gap: 16px; + padding: 20px 0; +} + +.editableInput { + font-size: 14px; + padding: 8px 12px; + border: 1px solid #ccc; + border-radius: 8px; + background-color: #f9f9f9; + color: #333; + transition: border-color 0.3s; + flex: 1; +} + +.readOnly { + border-color: transparent; + background-color: transparent; + pointer-events: none; + color: #000; +} + +/* Footer (optional) */ +.footer { + text-align: center; + margin-top: 30px; + font-size: 13px; + color: #777; +} + + +/* Mobile styles */ +@media (max-width: 768px) { +.h1 { + color: white; + font-size: 23px; +} +.dashboardContainer { + max-width: 900px; + margin: 30px auto; + background: #fff; + border-radius: 10px; + box-shadow: none; + padding: 20px; +} + + .desktopText { + display: none; + } + + .mobileText { + display: block; + } +} \ No newline at end of file