-
- {selectedFiles.length > 0 &&
- selectedFiles.map((file, index) => (
-
}
diff --git a/src/Dashboard.module.css b/src/Dashboard.module.css
index e0f1c9e..ddb0eb4 100644
--- a/src/Dashboard.module.css
+++ b/src/Dashboard.module.css
@@ -137,7 +137,7 @@
.fileUpload {
margin-top: 16px;
font-size: 14px;
- color: white;
+ color: #333;
background: #2bb438;
padding: 8px 12px;
border-radius: 8px;
diff --git a/src/DiscussedTopics.js b/src/DiscussedTopics.js
index 723b10d..7735ced 100644
--- a/src/DiscussedTopics.js
+++ b/src/DiscussedTopics.js
@@ -1,16 +1,37 @@
-
// DiscussedTopics.js
import React from 'react';
+import styles from './DiscussedTopics.module.css';
const DiscussedTopics = ({ topics }) => {
return (
-
-
Top Topic
-
- {topics.map((topic, idx) => (
- - {topic.topic} - {topic.count} x
- ))}
-
+
+
+
Top Topic
+
+ {topics.length} topik
+
+
+
+
+ {topics.length === 0 ? (
+
+
💬
+
Discussed Topic Is Empty
+
+ ) : (
+ topics.map((topic, idx) => (
+
+
+
{topic.topic}
+
+ {topic.count}
+ times
+
+
+
+ ))
+ )}
+
);
};
diff --git a/src/DiscussedTopics.module.css b/src/DiscussedTopics.module.css
new file mode 100644
index 0000000..86ae0e5
--- /dev/null
+++ b/src/DiscussedTopics.module.css
@@ -0,0 +1,187 @@
+/* DiscussedTopics.module.css */
+.container {
+ background-color: #f8fafc;
+ padding: 20px;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+}
+
+/* Header */
+.header {
+ background: white;
+ border-radius: 12px;
+ padding: 20px;
+ margin-bottom: 24px;
+ border: 1px solid #e2e8f0;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 12px;
+}
+
+.title {
+ font-size: 24px;
+ font-weight: 600;
+ color: #1f2937;
+ margin: 0;
+}
+
+.resultCount {
+ font-size: 13px;
+ color: #6b7280;
+ font-weight: 500;
+ padding: 8px 12px;
+ background: #f1f5f9;
+ border-radius: 6px;
+ display: inline-block;
+}
+
+/* Cards Grid */
+.grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 20px;
+}
+
+.card {
+ background: white;
+ border-radius: 12px;
+ border: 1px solid #e2e8f0;
+ overflow: hidden;
+ transition: all 0.2s ease;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+
+.card:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
+ border-color: #cbd5e1;
+}
+
+.cardContent {
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.topicName {
+ font-size: 18px;
+ font-weight: 600;
+ color: #1f2937;
+ margin: 0;
+ line-height: 1.4;
+ word-break: break-word;
+}
+
+.countBadge {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 4px;
+ padding: 12px 16px;
+ background: #f8fafc;
+ border-radius: 8px;
+ border-left: 3px solid #0b7366;
+}
+
+.countValue {
+ font-size: 24px;
+ font-weight: 700;
+ color: #0b7366;
+ line-height: 1;
+}
+
+.countLabel {
+ font-size: 12px;
+ color: #6b7280;
+ font-weight: 500;
+}
+
+/* Empty State */
+.emptyState {
+ grid-column: 1 / -1;
+ text-align: center;
+ padding: 60px 20px;
+ color: #6b7280;
+}
+
+.emptyIcon {
+ font-size: 48px;
+ margin-bottom: 16px;
+}
+
+.emptyState p {
+ font-size: 16px;
+ margin: 0;
+}
+
+/* Responsive Design */
+@media (max-width: 768px) {
+ .container {
+ padding: 16px;
+ }
+
+ .header {
+ padding: 16px;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 12px;
+ }
+
+ .title {
+ font-size: 20px;
+ }
+
+ .grid {
+ grid-template-columns: 1fr;
+ gap: 16px;
+ }
+
+ .cardContent {
+ padding: 16px;
+ }
+
+ .topicName {
+ font-size: 16px;
+ }
+
+ .countValue {
+ font-size: 20px;
+ }
+}
+
+@media (max-width: 480px) {
+ .container {
+ padding: 12px;
+ }
+
+ .header {
+ padding: 12px;
+ }
+
+ .title {
+ font-size: 18px;
+ }
+
+ .cardContent {
+ padding: 12px;
+ }
+
+ .topicName {
+ font-size: 15px;
+ }
+
+ .countBadge {
+ padding: 10px 12px;
+ }
+
+ .countValue {
+ font-size: 18px;
+ }
+
+ .countLabel {
+ font-size: 11px;
+ }
+}
\ No newline at end of file
diff --git a/src/FollowUps.js b/src/FollowUps.js
index 16d177a..6b6cf83 100644
--- a/src/FollowUps.js
+++ b/src/FollowUps.js
@@ -1,36 +1,194 @@
-import React from 'react';
+// FollowUps.js
+import React, { useState } from 'react';
import styles from './FollowUps.module.css';
-const FollowUps = ({ data }) => {
+const FollowUps = ({ data: initialData }) => {
+ const [data, setData] = useState(initialData);
+ const [statusFilter, setStatusFilter] = useState('all');
+ const [dateFilter, setDateFilter] = useState('all');
+ const [sortOrder, setSortOrder] = useState('latest');
+
+ const handleFollowUp = async (e, user) => {
+ e.preventDefault();
+
+ try {
+ await fetch('https://bot.kediritechnopark.com/webhook/set-follow-up', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ id: user.id,
+ isfollowup: user.isfollowup ? 'success' : 'followup'
+ })
+ });
+
+ if (user.isfollowup) {
+ setData(prev =>
+ prev.map(u =>
+ u.id === user.id ? { ...u, isfollowup: false, issuccess: true } : u
+ )
+ );
+ } else {
+ setData(prev =>
+ prev.map(u =>
+ u.id === user.id ? { ...u, isfollowup: true } : u
+ )
+ );
+ }
+
+ if (!user.isfollowup) {
+ window.open(`https://api.whatsapp.com/send?phone=${user.contact_info}`, '_blank');
+ }
+ } catch (error) {
+ console.error('Failed to set follow-up:', error);
+ alert('Failed to send follow-up status.');
+ }
+ };
+
+ // Filter & Sort
+ const now = new Date();
+ const filteredData = data
+ .filter(user => {
+ switch (statusFilter) {
+ case 'pending':
+ return !user.isfollowup && !user.issuccess;
+ case 'inProgress':
+ return user.isfollowup && !user.issuccess;
+ case 'success':
+ return user.issuccess;
+ default:
+ return true;
+ }
+ })
+ .filter(user => {
+ const created = new Date(user.created_at);
+ switch (dateFilter) {
+ case 'today':
+ return created.toDateString() === now.toDateString();
+ case 'week':
+ const aWeekAgo = new Date();
+ aWeekAgo.setDate(now.getDate() - 7);
+ return created >= aWeekAgo;
+ default:
+ return true;
+ }
+ })
+ .sort((a, b) => {
+ const dateA = new Date(a.created_at);
+ const dateB = new Date(b.created_at);
+ return sortOrder === 'latest' ? dateB - dateA : dateA - dateB;
+ });
+
return (
-
- {data.map(user => (
-
-
-
{user.name}
-
- {new Date(user.created_at).toLocaleString('id-ID', {
- dateStyle: 'medium',
- timeStyle: 'short',
- timeZone: 'Asia/Jakarta'
- })}
-
-
-
{user.notes}
-
+ {/* Filter Controls */}
+
+
+
+
+
- ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {filteredData.length} of {data.length} records
+
+
+
+ {/* Cards Grid */}
+
+ {filteredData.length === 0 ? (
+
+
📋
+
No data matches the filters
+
+ ) : (
+ filteredData.map(user => (
+
+
+
{user.name}
+
+ {user.issuccess ? (
+ ✓ Followed Up
+ ) : user.isfollowup ? (
+ ⏳ In Progress
+ ) : (
+ • Pending
+ )}
+
+
+
+
+
{user.notes}
+
+ Contact:
+ {user.contact_info}
+
+
+ {new Date(user.created_at).toLocaleString('id-ID', {
+ dateStyle: 'medium',
+ timeStyle: 'short',
+ timeZone: 'Asia/Jakarta'
+ })}
+
+
+
+
+
+
+
+ ))
+ )}
);
diff --git a/src/FollowUps.module.css b/src/FollowUps.module.css
index 8b88130..9c566c4 100644
--- a/src/FollowUps.module.css
+++ b/src/FollowUps.module.css
@@ -1,110 +1,316 @@
+/* FollowUps.module.css */
.container {
- background-color: #f7f9fa;
- font-family: 'Amazon Ember', sans-serif;
+ background-color: #f8fafc;
+ min-height: 100vh;
+ padding: 20px;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
-.title {
- font-size: 22px;
- font-weight: 600;
- color: #16191f;
- margin-bottom: 20px;
- text-align: center;
+/* Filter Section */
+.filterSection {
+ background: white;
+ border-radius: 12px;
+ padding: 20px;
+ margin-bottom: 24px;
+ border: 1px solid #e2e8f0;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
+.filterGroup {
+ display: flex;
+ gap: 20px;
+ flex-wrap: wrap;
+ align-items: end;
+ margin-bottom: 12px;
+}
+
+.filterItem {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ min-width: 160px;
+}
+
+.filterLabel {
+ font-size: 14px;
+ font-weight: 500;
+ color: #374151;
+ margin: 0;
+}
+
+.filterSelect {
+ padding: 10px 12px;
+ border: 2px solid #e2e8f0;
+ border-radius: 8px;
+ font-size: 14px;
+ background: white;
+ color: #374151;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ appearance: none;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3e%3c/svg%3e");
+ background-position: right 8px center;
+ background-repeat: no-repeat;
+ background-size: 16px;
+ padding-right: 36px;
+}
+
+.filterSelect:focus {
+ outline: none;
+ border-color: #3b82f6;
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
+}
+
+.filterSelect:hover {
+ border-color: #cbd5e1;
+}
+
+.resultCount {
+ font-size: 13px;
+ color: #6b7280;
+ font-weight: 500;
+ padding: 8px 12px;
+ background: #f1f5f9;
+ border-radius: 6px;
+ display: inline-block;
+}
+
+/* Cards Grid */
.grid {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
- gap: 16px;
+ grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
+ gap: 20px;
}
.card {
- background-color: #ffffff;
- border: 1px solid #d1d5db;
- border-radius: 8px;
- padding: 16px;
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- transition: box-shadow 0.2s ease;
+ background: white;
+ border-radius: 12px;
+ border: 1px solid #e2e8f0;
+ overflow: hidden;
+ transition: all 0.2s ease;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.card:hover {
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+ transform: translateY(-2px);
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
+ border-color: #cbd5e1;
}
-.header {
+.cardHeader {
+ padding: 20px 20px 12px;
+ border-bottom: 1px solid #f1f5f9;
display: flex;
justify-content: space-between;
align-items: flex-start;
- flex-wrap: wrap;
- gap: 4px;
+ gap: 12px;
}
-.header h3 {
+.userName {
font-size: 18px;
+ font-weight: 600;
+ color: #1f2937;
margin: 0;
- color: #232f3e;
+ flex: 1;
}
-.date {
+.statusBadge {
+ flex-shrink: 0;
+}
+
+.badgeSuccess {
+ background: #dcfce7;
+ color: #166534;
+ padding: 4px 8px;
+ border-radius: 6px;
font-size: 12px;
+ font-weight: 500;
+}
+
+.badgeProgress {
+ background: #fef3c7;
+ color: #92400e;
+ padding: 4px 8px;
+ border-radius: 6px;
+ font-size: 12px;
+ font-weight: 500;
+}
+
+.badgePending {
+ background: #f3f4f6;
color: #6b7280;
- white-space: nowrap;
+ padding: 4px 8px;
+ border-radius: 6px;
+ font-size: 12px;
+ font-weight: 500;
+}
+
+.cardContent {
+ padding: 12px 20px 20px;
}
.notes {
- margin: 12px 0;
- color: #374151;
+ color: #4b5563;
font-size: 14px;
+ line-height: 1.5;
+ margin: 0 0 16px 0;
+ word-break: break-word;
}
-.footer {
+.contactInfo {
display: flex;
- justify-content: space-between;
- align-items: center;
- flex-wrap: wrap;
- gap: 8px;
- margin-top: 8px;
+ flex-direction: column;
+ gap: 4px;
+ margin-bottom: 12px;
}
-.contact {
- font-size: 13px;
- color: #374151;
- word-break: break-all;
-}
-
-.chatBtn {
- background-color: #25d366;
- color: #ffffff;
- text-decoration: none;
- padding: 6px 12px;
- border-radius: 4px;
- font-size: 13px;
+.contactLabel {
+ font-size: 12px;
+ color: #6b7280;
font-weight: 500;
- transition: background-color 0.2s ease;
- white-space: nowrap;
}
-.chatBtn:hover {
- background-color: #1da851;
+.contactValue {
+ font-size: 14px;
+ color: #374151;
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
+}
+
+.dateInfo {
+ font-size: 12px;
+ color: #9ca3af;
+ padding: 8px 12px;
+ background: #f9fafb;
+ border-radius: 6px;
+ border-left: 3px solid #e5e7eb;
+}
+
+.cardActions {
+ padding: 16px 20px;
+ border-top: 1px solid #f1f5f9;
+ background: #fafbfc;
+}
+
+.actionBtn {
+ width: 100%;
+ padding: 12px 16px;
+ border: none;
+ border-radius: 8px;
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+}
+
+.btnPrimary {
+ background: #25d366;
+ color: white;
+}
+
+.btnPrimary:hover {
+ background: #1da851;
+ transform: translateY(-1px);
+}
+
+.btnComplete {
+ background: #3b82f6;
+ color: white;
+}
+
+.btnComplete:hover {
+ background: #2563eb;
+ transform: translateY(-1px);
+}
+
+.btnSuccess {
+ background: #10b981;
+ color: white;
+ cursor: default;
+}
+
+/* Empty State */
+.emptyState {
+ grid-column: 1 / -1;
+ text-align: center;
+ padding: 60px 20px;
+ color: #6b7280;
+}
+
+.emptyIcon {
+ font-size: 48px;
+ margin-bottom: 16px;
+}
+
+.emptyState p {
+ font-size: 16px;
+ margin: 0;
+}
+
+/* Responsive Design */
+@media (max-width: 768px) {
+ .container {
+ padding: 16px;
+ }
+
+ .filterSection {
+ padding: 16px;
+ }
+
+ .filterGroup {
+ flex-direction: column;
+ gap: 16px;
+ }
+
+ .filterItem {
+ min-width: auto;
+ width: 100%;
+ }
+
+ .grid {
+ grid-template-columns: 1fr;
+ gap: 16px;
+ }
+
+ .cardHeader {
+ padding: 16px 16px 10px;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 8px;
+ }
+
+ .cardContent {
+ padding: 10px 16px 16px;
+ }
+
+ .cardActions {
+ padding: 12px 16px;
+ }
+
+ .actionBtn {
+ padding: 10px 14px;
+ font-size: 13px;
+ }
}
@media (max-width: 480px) {
- .title {
- font-size: 18px;
- }
-
- .card {
+ .container {
padding: 12px;
}
-
+
+ .userName {
+ font-size: 16px;
+ }
+
.notes {
font-size: 13px;
}
-
- .chatBtn {
- padding: 6px 10px;
- font-size: 12px;
+
+ .statusBadge span {
+ font-size: 11px;
+ padding: 3px 6px;
}
-}
+}
\ No newline at end of file
diff --git a/src/Login.js b/src/Login.js
index c5c8db9..c306e11 100644
--- a/src/Login.js
+++ b/src/Login.js
@@ -69,7 +69,7 @@ const Login = () => {
- © 2025 Kediri Technopark
+ © 2025 Dermalounge
diff --git a/src/Modal.module.css b/src/Modal.module.css
index ef1ce36..0e2476e 100644
--- a/src/Modal.module.css
+++ b/src/Modal.module.css
@@ -16,10 +16,9 @@
background: white;
border-radius: 10px;
max-width: 700px;
- width: 70%;
+ width: 85%;
max-height: 80vh;
overflow-y: auto;
- padding: 20px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
position: relative;
}
diff --git a/src/NotificationPrompt.js b/src/NotificationPrompt.js
index 3bc4984..45cc6e7 100644
--- a/src/NotificationPrompt.js
+++ b/src/NotificationPrompt.js
@@ -5,19 +5,28 @@ export default function NotificationPrompt({ onAllow, onDismiss }) {
return (
-
Enable Notifications
-
- Stay up to date with important updates and alerts. Enable push notifications to never miss a thing.
-
+
+
+
+
Aktifkan Notifikasi
+
+ Tetap terhubung dengan update penting dan peringatan terbaru.
+ Aktifkan notifikasi push agar tidak ketinggalan informasi penting.
+
+
+
);
-}
+}
\ No newline at end of file
diff --git a/src/NotificationPrompt.module.css b/src/NotificationPrompt.module.css
index 5e26da1..fafd9fc 100644
--- a/src/NotificationPrompt.module.css
+++ b/src/NotificationPrompt.module.css
@@ -1,35 +1,67 @@
+/* NotificationPrompt.module.css */
.backdrop {
position: fixed;
inset: 0;
- background-color: rgba(0, 0, 0, 0.45);
+ background-color: rgba(0, 0, 0, 0.5);
+ backdrop-filter: blur(4px);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
+ animation: fadeIn 0.2s ease-out;
}
.modal {
background-color: #fff;
- border-radius: 8px;
+ border-radius: 12px;
padding: 32px;
max-width: 420px;
width: 90%;
- box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15);
+ border: 1px solid #e2e8f0;
text-align: center;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+ animation: slideUp 0.3s ease-out;
+ position: relative;
+}
+
+.iconWrapper {
+ margin-bottom: 24px;
+ display: flex;
+ justify-content: center;
+}
+
+.notificationIcon {
+ font-size: 48px;
+ background: #f1f5f9;
+ border-radius: 50%;
+ width: 80px;
+ height: 80px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid #e2e8f0;
+}
+
+.content {
+ margin-bottom: 32px;
}
.title {
margin-bottom: 16px;
- font-size: 22px;
+ font-size: 24px;
font-weight: 600;
color: #1f2937;
+ line-height: 1.3;
}
.description {
- margin-bottom: 24px;
+ margin: 0;
font-size: 16px;
color: #4b5563;
- line-height: 1.5;
+ line-height: 1.6;
+ max-width: 340px;
+ margin: 0 auto;
}
.actions {
@@ -39,30 +71,129 @@
}
.primaryButton {
- background-color: #0073bb;
+ background: #3b82f6;
color: white;
font-weight: 500;
- padding: 12px 20px;
+ padding: 14px 24px;
border: none;
- border-radius: 6px;
+ border-radius: 8px;
cursor: pointer;
- transition: background-color 0.2s;
+ font-size: 15px;
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ font-family: inherit;
}
.primaryButton:hover {
- background-color: #005a99;
+ background: #2563eb;
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
+}
+
+.primaryButton:active {
+ transform: translateY(0);
+}
+
+.buttonIcon {
+ font-size: 14px;
}
.secondaryButton {
background-color: transparent;
- color: #374151;
- border: 1px solid #d1d5db;
- padding: 12px 20px;
- border-radius: 6px;
+ color: #6b7280;
+ border: 2px solid #e2e8f0;
+ padding: 12px 24px;
+ border-radius: 8px;
cursor: pointer;
- transition: background-color 0.2s;
+ font-size: 15px;
+ font-weight: 500;
+ transition: all 0.2s ease;
+ font-family: inherit;
}
.secondaryButton:hover {
- background-color: #f3f4f6;
+ background-color: #f8fafc;
+ border-color: #cbd5e1;
+ color: #374151;
+ transform: translateY(-1px);
}
+
+.secondaryButton:active {
+ transform: translateY(0);
+}
+
+/* Animations */
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes slideUp {
+ from {
+ opacity: 0;
+ transform: translateY(20px) scale(0.95);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0) scale(1);
+ }
+}
+
+/* Responsive Design */
+@media (max-width: 480px) {
+ .modal {
+ padding: 24px 20px;
+ margin: 16px;
+ width: calc(100% - 32px);
+ }
+
+ .iconWrapper {
+ margin-bottom: 20px;
+ }
+
+ .notificationIcon {
+ width: 64px;
+ height: 64px;
+ font-size: 32px;
+ }
+
+ .title {
+ font-size: 20px;
+ margin-bottom: 12px;
+ }
+
+ .description {
+ font-size: 15px;
+ }
+
+ .content {
+ margin-bottom: 24px;
+ }
+
+ .primaryButton,
+ .secondaryButton {
+ padding: 12px 20px;
+ font-size: 14px;
+ }
+}
+
+@media (max-width: 320px) {
+ .modal {
+ padding: 20px 16px;
+ }
+
+ .title {
+ font-size: 18px;
+ }
+
+ .description {
+ font-size: 14px;
+ }
+}
\ No newline at end of file
diff --git a/src/StatCard.js b/src/StatCard.js
new file mode 100644
index 0000000..7a4df2c
--- /dev/null
+++ b/src/StatCard.js
@@ -0,0 +1,48 @@
+import React, { useEffect, useState } from 'react';
+import styles from './StatCard.module.css';
+import FollowUps from './FollowUps';
+
+const StatCard = ({ followUps, setModalContent }) => {
+ const [activeIndex, setActiveIndex] = useState(0); // 0 = booking request, 1 = sukses
+ const [direction, setDirection] = useState('right'); // for animation direction
+
+ const views = [
+ {
+ label: 'BOOKING REQUEST',
+ data: followUps.filter(u => !u.isfollowup && !u.issuccess),
+ },
+ {
+ label: 'FOLLOWED UP',
+ data: followUps.filter(u => u.issuccess),
+ }
+ ];
+
+ // Swipe timer
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setDirection(prev => (prev === 'right' ? 'left' : 'right'));
+ setActiveIndex(prev => 1 - prev);
+ }, 4000);
+ return () => clearInterval(interval);
+ }, []);
+
+ const handleClick = () => {
+ setModalContent(
);
+ };
+
+ return (
+
+
+
{views[activeIndex].data.length}
+
{views[activeIndex].label}
+
+
+ );
+};
+
+export default StatCard;
diff --git a/src/StatCard.module.css b/src/StatCard.module.css
new file mode 100644
index 0000000..cfbf42f
--- /dev/null
+++ b/src/StatCard.module.css
@@ -0,0 +1,57 @@
+
+.statCard {
+overflow: hidden;
+ 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 {
+ margin: 0;
+ font-size: 28px;
+ color: #075e54;
+}
+
+.statCard p {
+ margin: 5px 0 0;
+ font-size: 14px;
+}
+.cardContent {
+ position: relative;
+ animation-duration: 0.6s;
+ animation-fill-mode: both;
+}
+
+@keyframes slideInRight {
+ from {
+ opacity: 0;
+ transform: translateX(30%);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+@keyframes slideInLeft {
+ from {
+ opacity: 0;
+ transform: translateX(-30%);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+.slideInRight {
+ animation-name: slideInRight;
+}
+
+.slideInLeft {
+ animation-name: slideInLeft;
+}