diff --git a/src/ChatBot.js b/src/ChatBot.js
index 03af59b..ec095bc 100644
--- a/src/ChatBot.js
+++ b/src/ChatBot.js
@@ -34,7 +34,7 @@ const isOpenCamera = searchParams.get('camera') === 'open';
}, [existingConversation]);
useEffect(() => {
- if (!localStorage.getItem('session')) {
+ if (!sessionStorage.getItem('session')) {
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0;
@@ -46,7 +46,7 @@ const isOpenCamera = searchParams.get('camera') === 'open';
const sessionId = generateUUID();
const dateNow = new Date().toISOString();
- localStorage.setItem('session', JSON.stringify({ sessionId: sessionId, lastSeen: dateNow }))
+ sessionStorage.setItem('session', JSON.stringify({ sessionId: sessionId, lastSeen: dateNow }))
}
}, []);
@@ -65,7 +65,7 @@ const isOpenCamera = searchParams.get('camera') === 'open';
}
const askToBot = async ({ type = 'text', content, tryCount = 0 }) => {
- const session = JSON.parse(localStorage.getItem('session'));
+ const session = JSON.parse(sessionStorage.getItem('session'));
if (!session || !session.sessionId) return;
let body;
@@ -143,7 +143,7 @@ const isOpenCamera = searchParams.get('camera') === 'open';
const message = textOverride || input.trim();
if (message === '') return;
- const session = JSON.parse(localStorage.getItem('session'));
+ const session = JSON.parse(sessionStorage.getItem('session'));
if ((!session || !session.name || !session.phoneNumber) && messages.length > 2) {
setIsPoppedUp(message);
setInput('');
@@ -331,10 +331,10 @@ const isOpenCamera = searchParams.get('camera') === 'open';
className={styles.nextButton}
onClick={() => {
if (name.length > 2 && phoneNumber.length >= 10) {
- const sessionData = JSON.parse(localStorage.getItem('session')) || {};
+ const sessionData = JSON.parse(sessionStorage.getItem('session')) || {};
sessionData.name = name;
sessionData.phoneNumber = phoneNumber;
- localStorage.setItem('session', JSON.stringify(sessionData));
+ sessionStorage.setItem('session', JSON.stringify(sessionData));
setIsPoppedUp('');
sendMessage(isPoppedUp);
}
diff --git a/src/Dashboard.js b/src/Dashboard.js
index 3c7eabf..31f931b 100644
--- a/src/Dashboard.js
+++ b/src/Dashboard.js
@@ -15,13 +15,18 @@ import NotificationPrompt from './NotificationPrompt';
const Dashboard = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
- const chartRef = useRef(null);
- const chartInstanceRef = useRef(null);
+ const weeklyChartRef = useRef(null);
+ const allTimeChartRef = useRef(null);
+ const weeklyChartInstanceRef = useRef(null);
+ const allTimeChartInstanceRef = useRef(null);
+
+ const [weeklyData, setWeeklyData] = useState([]);
+ const [allTimeData, setAllTimeData] = useState([]);
+
const [conversations, setConversations] = useState([]);
const [followUps, setFollowUps] = useState([]);
const [discussedTopics, setDiscussedTopics] = useState([]);
const [modalContent, setModalContent] = useState(null);
- const [rawData, setRawData] = useState([]);
const [loading, setLoading] = useState(true); // ⬅️ Tambahkan state loading
const [fileList, setFileList] = useState([]);
const [selectedKeys, setSelectedKeys] = useState([]);
@@ -177,6 +182,115 @@ const Dashboard = () => {
};
}, []);
+ // Helper parse data function
+function parseGraphData(graph) {
+ const prefixLabelMap = {
+ WEB: 'Web App',
+ TGG: 'Telegram',
+ WGG: 'Whatsapp',
+ IGG: 'Instagram',
+ };
+ const prefixColors = {
+ WEB: { border: '#e2b834', background: 'rgba(226,184,52,0.6)' },
+ TGG: { border: '#24A1DE', background: 'rgba(36,161,222,0.6)' },
+ WGG: { border: '#25d366', background: 'rgba(37,211,102,0.6)' },
+ IGG: { border: '#d62976', background: 'rgba(214,41,118,0.6)' },
+ };
+
+ const rawDataArray = Object.entries(graph).map(([date, sesi]) => ({
+ hour: date,
+ sesi,
+ }));
+
+ rawDataArray.sort((a, b) => new Date(a.hour) - new Date(b.hour));
+
+ const prefixes = Object.keys(prefixLabelMap);
+
+ // Format label: tanggal + nama bulan singkat Indonesia
+ const bulanIndoSingkat = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'];
+ const labels = rawDataArray.map(d => {
+ const date = new Date(d.hour);
+ const tgl = date.getDate().toString().padStart(2, '0');
+ const bln = bulanIndoSingkat[date.getMonth()];
+ return `${tgl} ${bln}`;
+ });
+
+ const counts = {};
+ prefixes.forEach(prefix => {
+ counts[prefix] = labels.map(() => 0);
+ });
+
+ rawDataArray.forEach(({ sesi }, index) => {
+ prefixes.forEach(prefix => {
+ if (typeof sesi[prefix] === 'number') {
+ counts[prefix][index] = sesi[prefix];
+ }
+ });
+ });
+
+ const datasets = prefixes.map(prefix => ({
+ label: prefixLabelMap[prefix],
+ data: counts[prefix],
+ borderColor: prefixColors[prefix].border,
+ backgroundColor: prefixColors[prefix].background,
+ fill: true,
+ tension: 0.3,
+ }));
+
+ return { labels, datasets };
+}
+
+
+ // Effect buat render weekly chart
+ useEffect(() => {
+ if (!weeklyData.labels || !weeklyChartRef.current) return;
+
+ if (weeklyChartInstanceRef.current) {
+ weeklyChartInstanceRef.current.destroy();
+ }
+
+ const ctx = weeklyChartRef.current.getContext('2d');
+ weeklyChartInstanceRef.current = new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: weeklyData.labels,
+ datasets: weeklyData.datasets,
+ },
+ options: {
+ responsive: true,
+ plugins: {
+ legend: { position: 'bottom' },
+ },
+ scales: { y: { beginAtZero: true } },
+ },
+ });
+ }, [weeklyData]);
+
+ // Effect buat render all-time chart
+ useEffect(() => {
+ if (!allTimeData.labels || !allTimeChartRef.current) return;
+
+ if (allTimeChartInstanceRef.current) {
+ allTimeChartInstanceRef.current.destroy();
+ }
+
+ const ctx = allTimeChartRef.current.getContext('2d');
+ allTimeChartInstanceRef.current = new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: allTimeData.labels,
+ datasets: allTimeData.datasets,
+ },
+ options: {
+ responsive: true,
+ plugins: {
+ legend: { position: 'bottom' },
+ },
+ scales: { y: { beginAtZero: true } },
+ },
+ });
+ }, [allTimeData]);
+
useEffect(() => {
const fetchData = async () => {
const token = localStorage.getItem('token');
@@ -207,13 +321,19 @@ const Dashboard = () => {
setFollowUps(data[0]?.graph[0]?.json?.result?.interested_users)
setFileList(data[0]?.files)
setUpdateDetected(data[1]?.updateDetected)
+
+
+ const result = data[0].graph[0].json.result;
+
+ setWeeklyData(parseGraphData(result.weekly_graph || {}));
+ setAllTimeData(parseGraphData(result.all_time_graph || {}));
+
const graphObj = data[0]?.graph[0]?.json?.result?.graph;
console.log(graphObj)
const rawDataArray = Object.entries(graphObj).map(([hour, sesi]) => ({
hour,
sesi,
}));
- setRawData(rawDataArray);
let totalSessions = new Set();
let botMessages = 0;
@@ -320,98 +440,6 @@ const Dashboard = () => {
setModalContent(
{item.type}
+CURRENT PLAN
{item.number}
-Free License Valid until: {item.validUntil}
+{item.type} Valid until: {item.validUntil}