handleNavClick('profile')}
@@ -159,11 +155,6 @@ const Dashboard = () => {
Dashboard view is active. Select one of the buttons above.
)}
- {activeView === 'settings' && (
-
- Settings view - Configuration options will go here.
-
- )}
{activeView === 'profile' && (
Profile view - User information will go here.
diff --git a/src/components/ProfileForm.jsx b/src/components/ProfileForm.jsx
index 9a8521b..f8d1b51 100644
--- a/src/components/ProfileForm.jsx
+++ b/src/components/ProfileForm.jsx
@@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom';
import { tokenService } from '../services/TokenService';
import { userApi } from '../api/loginApi';
+import { APP_NAME } from '../constants/app';
import './ProfileForm.css';
@@ -224,7 +225,7 @@ const ProfileForm = () => {
{/* Navbar */}
- Dashboard
+ {APP_NAME}
{
>
Dashboard
- handleNavClick('settings')}
- >
- Settings
-
handleNavClick('profile')}
diff --git a/src/components/ViewSentMessages.css b/src/components/ViewSentMessages.css
index c17deca..8aacf71 100644
--- a/src/components/ViewSentMessages.css
+++ b/src/components/ViewSentMessages.css
@@ -355,3 +355,102 @@
.view-sent-message-list-container::-webkit-scrollbar-thumb:hover {
background: #a1a1a1;
}
+
+.view-sent-message-tabs {
+ display: flex;
+ margin-bottom: 20px;
+ border-bottom: 1px solid #e5e7eb;
+}
+
+.tab-button {
+ padding: 10px 20px;
+ background: none;
+ border: none;
+ border-bottom: 3px solid transparent;
+ cursor: pointer;
+ font-weight: 500;
+ color: #6b7280;
+ transition: all 0.3s ease;
+}
+
+.tab-button.active {
+ color: #3b82f6;
+ border-bottom-color: #3b82f6;
+}
+
+.tab-button:hover {
+ color: #374151;
+ background-color: #f9fafb;
+}
+
+.search-container {
+ margin-bottom: 20px;
+}
+
+.search-input {
+ width: 100%;
+ padding: 10px 12px;
+ border: 1px solid #d1d5db;
+ border-radius: 6px;
+ font-size: 14px;
+}
+
+.search-input:focus {
+ outline: none;
+ border-color: #3b82f6;
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
+}
+
+.section-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 16px;
+}
+
+.section-header h3 {
+ margin: 0;
+ color: #111827;
+ font-size: 18px;
+ font-weight: 600;
+}
+
+.last-updated {
+ font-size: 12px;
+ color: #6b7280;
+}
+
+.no-messages {
+ text-align: center;
+ padding: 40px;
+ color: #6b7280;
+ font-style: italic;
+}
+
+.status-badge {
+ padding: 4px 8px;
+ border-radius: 4px;
+ font-size: 12px;
+ font-weight: 500;
+ text-transform: uppercase;
+}
+
+.status-processing {
+ background-color: #fef3c7;
+ color: #92400e;
+}
+
+.status-sent {
+ background-color: #dcfce7;
+ color: #166534;
+}
+
+.status-failed {
+ background-color: #fee2e2;
+ color: #991b1b;
+}
+
+.status-default {
+ background-color: #f3f4f6;
+ color: #374151;
+}
diff --git a/src/components/ViewSentMessages.jsx b/src/components/ViewSentMessages.jsx
index f1503bb..330183d 100644
--- a/src/components/ViewSentMessages.jsx
+++ b/src/components/ViewSentMessages.jsx
@@ -1,20 +1,21 @@
import { useState, useEffect, useCallback } from 'react';
-
import { tokenService } from '../services/TokenService';
import { messageEventResponseApi } from '../api/messageEventResponseApi';
-
+import { scheduleApi } from '../api/scheduleApi';
import './ViewSentMessages.css';
const ViewSentMessages = ({
isOpen,
onClose,
- title = 'View Sent Messages ',
+ title = 'View Sent Messages',
}) => {
const [sentMessages, setSentMessages] = useState([]);
+ const [scheduledMessages, setScheduledMessages] = useState([]);
const [lastUpdated, setLastUpdated] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [searchTerm, setSearchTerm] = useState('');
+ const [activeTab, setActiveTab] = useState('sent');
// Fetch the sent messages or Message Event Responses
const fetchSentMessages = useCallback(async () => {
@@ -33,7 +34,6 @@ const ViewSentMessages = ({
setLastUpdated(new Date());
setSentMessages(response.data);
} else {
- setLoading(false);
throw new Error(response.message || 'Failed to load sent messages');
}
} catch (err) {
@@ -44,8 +44,32 @@ const ViewSentMessages = ({
}
}, []);
+ const fetchScheduledMessages = useCallback(async () => {
+ try {
+ const userId = tokenService.getUserId();
+ const response = await scheduleApi.getScheduledMessage(
+ userId,
+ tokenService.bearerToken()
+ );
+ if (response) {
+ const scheduledMessages = response.data;
+
+ setScheduledMessages(scheduledMessages);
+ } else {
+ throw new Error(response.message || 'Failed to get scheduled messages');
+ }
+ } catch (err) {
+ console.error('Failed to load scheduled messages:', err);
+ setScheduledMessages([]);
+ }
+ }, []);
+
const handleRefresh = () => {
- fetchSentMessages();
+ if (activeTab === 'sent') {
+ fetchSentMessages();
+ } else {
+ fetchScheduledMessages();
+ }
};
useEffect(() => {
@@ -55,6 +79,13 @@ const ViewSentMessages = ({
}
}, [isOpen, fetchSentMessages]);
+ // Fetch scheduled messages when tab is switched
+ useEffect(() => {
+ if (activeTab === 'scheduled' && isOpen) {
+ fetchScheduledMessages();
+ }
+ }, [activeTab, isOpen, fetchScheduledMessages]);
+
const filteredSentMessages = sentMessages.filter((sentMessage) => {
const searchLower = searchTerm.toLowerCase();
return (
@@ -66,6 +97,15 @@ const ViewSentMessages = ({
);
});
+ // Filter scheduled messages
+ const filteredScheduledMessages = scheduledMessages.filter((message) => {
+ const searchLower = searchTerm.toLowerCase();
+ return (
+ (message.status && message.status.toLowerCase().includes(searchLower)) ||
+ (message.id && message.id.toString().includes(searchTerm))
+ );
+ });
+
const formatLastUpdated = () => {
if (!lastUpdated) return 'Never';
return lastUpdated.toLocaleTimeString([], {
@@ -74,6 +114,25 @@ const ViewSentMessages = ({
});
};
+ // Format date for scheduled messages
+ const formatScheduledDate = (dateString) => {
+ return new Date(dateString).toLocaleString();
+ };
+
+ // Get status badge styling
+ const getStatusBadgeClass = (status) => {
+ switch (status) {
+ case 'PROCESSING':
+ return 'status-processing';
+ case 'SENT':
+ return 'status-sent';
+ case 'FAILED':
+ return 'status-failed';
+ default:
+ return 'status-default';
+ }
+ };
+
if (!isOpen) return null;
return (
@@ -90,13 +149,40 @@ const ViewSentMessages = ({
+ {/* Add tabs for navigation */}
+
+ setActiveTab('sent')}
+ >
+ Sent Messages
+
+ setActiveTab('scheduled')}
+ >
+ Scheduled Messages
+
+
+
+ {/* Search input */}
+
+ setSearchTerm(e.target.value)}
+ className="search-input"
+ />
+
+
{error && (
{error}
-
-
- Loading sent messages
-
+
+ Loading messages...
) : (
<>
-
-
- Refresh
-
-
-
setSearchTerm(e.target.value)}
- style={{
- flex: 1,
- minWidth: '200px',
- maxWidth: '300px',
- padding: '8px 12px',
- border: '1px solid #e5e7eb',
- borderRadius: '6px',
- fontSize: '14px',
- }}
- />
-
-
- Updated: {formatLastUpdated()}
-
-
-
-
- {/* Sent Messages List */}
- {filteredSentMessages.length === 0 ? (
-
-
- X
+ {/* Sent Messages Tab Content */}
+ {activeTab === 'sent' && (
+
+
+
Sent Messages
+
+ Last updated: {formatLastUpdated()}
+
-
- {searchTerm
- ? 'No matching sent messages found'
- : 'No sent messages available'}
-
-
- {searchTerm
- ? 'Try a different search term'
- : 'Create a contact and send a message to get started'}
-
- {searchTerm && (
-
setSearchTerm('')}
- style={{
- background: '#f3f4f6',
- color: '#4b5563',
- border: '1px solid #e5e7eb',
- borderRadius: '6px',
- padding: '8px 16px',
- cursor: 'pointer',
- fontSize: '14px',
- marginBottom: '10px',
- }}
- >
- Clear Search
-
+
+ {filteredSentMessages.length > 0 ? (
+
+
+
+
+ ID
+ Status
+ Sent Time
+
+
+
+ {filteredSentMessages.map((message) => (
+
+ {message.id.substring(0, 8)}...
+
+
+ {message.status}
+
+
+ {message.sent || 'N/A'}
+
+ ))}
+
+
+
+ ) : (
+
No sent messages found.
)}
- ) : (
- <>
-
-
- {filteredSentMessages.map((sentMessage, index) => (
-
-
-
-
- {index + 1}
-
-
-
- {sentMessage.status}
-
- Sent: {sentMessage.sent}
-
-
-
- Id: {sentMessage.id}
-
-
-
- ))}
-
+ )}
+
+ {/* Scheduled Messages Tab Content */}
+ {activeTab === 'scheduled' && (
+
+
+
Scheduled Messages
- >
+
+ {filteredScheduledMessages.length > 0 ? (
+
+
+
+
+ ID
+ Scheduled Time
+ Created Time
+ Status
+
+
+
+ {filteredScheduledMessages.map((message) => (
+
+ {message.id.substring(0, 8)}...
+
+ {formatScheduledDate(message.scheduled)}
+
+ {formatScheduledDate(message.created)}
+
+
+ {message.status}
+
+
+
+ ))}
+
+
+
+ ) : (
+
+ No scheduled messages found.
+
+ )}
+
)}
>
)}
-
-
- Close
-
-
- {loading ? 'Refreshing...' : 'Refresh List'}
-
-
diff --git a/src/constants/app.js b/src/constants/app.js
index 472518f..e533d0e 100644
--- a/src/constants/app.js
+++ b/src/constants/app.js
@@ -2,3 +2,4 @@ export const DATA_KEY_ACCESS_TOKEN = 'access_token';
export const DATA_KEY_REGISTERED_USER_ID = 'registered_user_id';
export const DATA_KEY_USER_ID = 'user_id';
export const DATA_KEY_ADDED_CONTACT_ID = 'added_contact_id';
+export const APP_NAME = 'textsender';