Victor AI - Local code complete

This commit is contained in:
thecyberlearn 2025-06-08 23:10:23 +05:30
commit 28467c4ce2
15 changed files with 6250 additions and 0 deletions

813
assets/css/styles.css Normal file
View File

@ -0,0 +1,813 @@
/* Common Styles for AI Services Hub */
/* Import fonts */
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap');
/* Reset and base styles */
* {
box-sizing: border-box;
}
body {
font-family: 'Plus Jakarta Sans', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
margin: 0;
padding: 0;
}
/* Layout utilities */
.container {
max-width: 7xl;
margin: 0 auto;
padding: 0 1rem;
}
@media (min-width: 640px) {
.container {
padding: 0 1.5rem;
}
}
@media (min-width: 1024px) {
.container {
padding: 0 2rem;
}
}
/* Component styles */
.glass-effect {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.card-hover {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.card-hover:hover {
transform: translateY(-4px);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}
.service-card {
background: white;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
border: 1px solid #e5e7eb;
}
.service-card:hover {
transform: translateY(-8px);
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
}
/* Custom scrollbar */
.custom-scrollbar::-webkit-scrollbar {
width: 4px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
border-radius: 2px;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.3);
border-radius: 2px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.5);
}
/* Loading skeleton */
.loading-skeleton {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: loading 1.5s infinite;
}
@keyframes loading {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
/* Animations */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeLine {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 20px rgba(102, 126, 234, 0.4); }
50% { box-shadow: 0 0 30px rgba(102, 126, 234, 0.8); }
}
@keyframes pulse {
0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7); }
70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(16, 185, 129, 0); }
100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }
}
.animate-pulse-soft {
animation: pulse-soft 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse-soft {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
.fade-in {
animation: fadeIn 0.4s ease-out;
}
.animate-slide-up {
animation: slideUp 0.4s ease-out;
}
.animate-fade {
animation: fadeLine 0.6s ease-in;
}
.float-animation {
animation: float 3s ease-in-out infinite;
}
.pulse-glow {
animation: pulse-glow 2s ease-in-out infinite;
}
/* Status indicator */
.status-indicator {
position: relative;
}
.status-indicator::before {
content: '';
position: absolute;
top: -2px;
right: -2px;
width: 12px;
height: 12px;
background: #10b981;
border-radius: 50%;
border: 2px solid white;
animation: pulse 2s infinite;
}
/* CONSOLIDATED MOBILE STYLES - REPLACE ALL EXISTING MOBILE CSS */
/* Mobile responsive utilities */
@media (max-width: 768px) {
.mobile-stack {
flex-direction: column;
}
.mobile-full {
width: 100%;
}
.mobile-stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0.5rem;
}
.service-grid {
grid-template-columns: 1fr;
gap: 1.5rem;
}
/* Header Section */
.text-center.mb-8 h1 {
font-size: 2rem !important;
line-height: 1.2;
margin-bottom: 1rem;
}
/* Enhanced Search Command Center */
.bg-white.rounded-2xl.p-6.mb-8 {
padding: 1rem !important;
margin-bottom: 1.5rem !important;
}
/* Trade AI Command Header */
.flex.items-center.gap-3.mb-4 h2 {
font-size: 1.125rem !important;
}
/* Search Input */
#query {
font-size: 16px !important;
padding: 0.875rem !important;
}
/* Search Button */
.bg-blue-600.hover\:bg-blue-700 {
padding: 0.875rem 1.5rem !important;
min-width: auto !important;
}
/* Search button inline with text input - only lens icon */
.flex.flex-col.sm\:flex-row.gap-3.mb-4 {
flex-direction: row !important;
gap: 0.75rem !important;
align-items: stretch !important;
}
.flex.flex-col.sm\:flex-row.gap-3.mb-4 .flex-1 {
flex: 1 !important;
}
.flex.flex-col.sm\:flex-row.gap-3.mb-4 button {
width: auto !important;
min-width: 50px !important;
padding: 0.875rem 1rem !important;
flex-shrink: 0 !important;
}
/* Hide search button text on mobile, show only icon */
.flex.flex-col.sm\:flex-row.gap-3.mb-4 button span {
display: none !important;
}
.flex.flex-col.sm\:flex-row.gap-3.mb-4 button i {
margin-right: 0 !important;
font-size: 1rem !important;
}
/* Quick searches in single row with horizontal scroll */
.flex.flex-wrap.gap-2 {
flex-direction: row !important;
flex-wrap: nowrap !important;
overflow-x: auto !important;
overflow-y: hidden !important;
align-items: center !important;
padding: 0.5rem 0 !important;
margin-bottom: 0.75rem !important;
-webkit-overflow-scrolling: touch !important;
scrollbar-width: none !important;
-ms-overflow-style: none !important;
gap: 0.5rem !important;
position: relative !important;
}
/* Hide scrollbar on mobile */
.flex.flex-wrap.gap-2::-webkit-scrollbar {
display: none !important;
}
/* Quick searches label */
.flex.flex-wrap.gap-2 span.text-sm.text-gray-500 {
flex-shrink: 0 !important;
white-space: nowrap !important;
margin-right: 0.5rem !important;
font-size: 0.875rem !important;
color: #6b7280 !important;
align-self: center !important;
}
/* Quick search buttons mobile */
.flex.flex-wrap.gap-2 button {
flex-shrink: 0 !important;
white-space: nowrap !important;
font-size: 0.75rem !important;
padding: 0.5rem 0.75rem !important;
min-width: fit-content !important;
width: auto !important;
}
/* Advanced Filters Section */
.border-t.border-gray-200.pt-4 {
padding-top: 1rem !important;
}
/* Advanced Filters Grid */
.grid.grid-cols-1.md\:grid-cols-3.gap-4 {
grid-template-columns: 1fr !important;
gap: 0.75rem !important;
}
/* Form Labels */
.block.text-sm.font-medium.text-gray-700.mb-2 {
margin-bottom: 0.5rem !important;
font-size: 0.875rem !important;
}
/* Form Inputs and Selects */
.w-full.px-3.py-2 {
padding: 0.75rem !important;
font-size: 16px !important;
}
/* Advanced Search Buttons - Mobile Override */
.flex.flex-wrap.gap-3 {
display: grid !important;
grid-template-columns: 1fr 1fr !important;
gap: 0.75rem !important;
}
/* Hide Reset button on mobile */
.flex.flex-wrap.gap-3 button:nth-child(3) {
display: none !important;
}
/* Style remaining buttons */
.flex.flex-wrap.gap-3 button:nth-child(1),
.flex.flex-wrap.gap-3 button:nth-child(2) {
width: 100% !important;
justify-content: center !important;
padding: 0.75rem 0.5rem !important;
font-size: 0.875rem !important;
}
/* Main Content Grid - Stack on mobile */
.grid.grid-cols-1.lg\:grid-cols-3.gap-6 {
grid-template-columns: 1fr !important;
gap: 1rem !important;
}
/* Results Section */
.lg\:col-span-2 {
grid-column: span 1 !important;
}
/* Search Results Container */
#resultsSection .bg-white.rounded-2xl {
padding: 1rem !important;
margin-bottom: 1rem !important;
}
/* Search Results Header */
#resultsSection .flex.items-center.justify-between {
flex-direction: column !important;
align-items: flex-start !important;
gap: 1rem !important;
margin-bottom: 1rem !important;
}
#resultsSection .flex.items-center.justify-between h3 {
font-size: 1.25rem !important;
margin-bottom: 0 !important;
}
/* Results Count and Controls */
#resultsSection .flex.items-center.gap-2 {
width: 100% !important;
justify-content: space-between !important;
flex-wrap: wrap !important;
gap: 0.5rem !important;
}
#resultsCount {
font-size: 0.875rem !important;
color: #059669 !important;
background: #ecfdf5 !important;
padding: 0.25rem 0.5rem !important;
border-radius: 0.375rem !important;
border: 1px solid #a7f3d0 !important;
font-weight: 500 !important;
order: 1 !important;
width: 100% !important;
}
/* Sort Dropdown */
#sortBy {
font-size: 0.875rem !important;
padding: 0.5rem !important;
order: 2 !important;
flex: 1 !important;
min-width: 120px !important;
background: white !important;
border: 1px solid #d1d5db !important;
border-radius: 0.5rem !important;
font-weight: 500 !important;
}
#sortBy:focus {
border-color: #3b82f6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}
/* Export Button */
.bg-gray-100.hover\:bg-gray-200 {
font-size: 0.875rem !important;
padding: 0.5rem 0.75rem !important;
order: 3 !important;
flex-shrink: 0 !important;
background: #f3f4f6 !important;
border: 1px solid #d1d5db !important;
border-radius: 0.5rem !important;
font-weight: 500 !important;
transition: all 0.15s ease !important;
}
/* ===== SEARCH RESULTS MOBILE STYLING ===== */
/* Main search results container */
#results {
grid-template-columns: 1fr !important;
gap: 1rem !important;
}
/* Individual result cards - SIMPLE DESKTOP-LIKE LAYOUT */
#results > div {
border: 1px solid #e5e7eb !important;
border-radius: 0.5rem !important;
padding: 1rem !important;
margin-bottom: 0.75rem !important;
background: #ffffff !important;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06) !important;
transition: all 0.2s ease !important;
}
/* Company header with flag and name - KEEP DESKTOP LAYOUT */
#results .flex.items-center.gap-3 {
gap: 0.75rem !important;
margin-bottom: 0.75rem !important;
flex-direction: row !important;
align-items: center !important;
}
/* Flag element */
#results .w-8.h-6 {
flex-shrink: 0 !important;
width: 2rem !important;
height: 1.5rem !important;
}
/* Company name */
#results .text-base.font-bold,
#results .text-lg.font-bold {
flex: 1 !important;
font-size: 1rem !important;
line-height: 1.3 !important;
word-break: break-word !important;
color: #1f2937 !important;
font-weight: 600 !important;
}
/* Contact information section - KEEP DESKTOP STRUCTURE */
#results .space-y-2 {
margin-top: 0.75rem !important;
display: flex !important;
flex-direction: column !important;
gap: 0.5rem !important;
}
/* Individual contact items - CLEAN ROWS LIKE DESKTOP */
#results .flex.items-center.gap-2,
#results .flex.items-start.gap-2 {
margin-bottom: 0 !important;
align-items: center !important;
padding: 0.25rem 0 !important;
background: transparent !important;
border: none !important;
border-radius: 0 !important;
box-shadow: none !important;
gap: 0.75rem !important;
}
/* Icons - ensure they display properly */
#results .fas,
#results .fa {
width: 1rem !important;
text-align: center !important;
flex-shrink: 0 !important;
margin-right: 0.5rem !important;
font-size: 0.875rem !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
}
/* Icon colors - same as desktop */
#results .fa-phone { color: #059669 !important; }
#results .fa-envelope { color: #2563eb !important; }
#results .fa-globe { color: #7c3aed !important; }
#results .fa-map-marker-alt { color: #dc2626 !important; }
/* Contact text */
#results .flex.items-center.gap-2 span,
#results .flex.items-center.gap-2 a,
#results .flex.items-start.gap-2 span {
word-break: break-word !important;
line-height: 1.3 !important;
font-size: 0.875rem !important;
flex: 1 !important;
margin: 0 !important;
}
/* Text colors - same as desktop */
#results .text-green-600 { color: #059669 !important; }
#results .text-blue-600 { color: #2563eb !important; }
#results .text-purple-600 { color: #7c3aed !important; }
#results .text-gray-600 { color: #4b5563 !important; }
#results .text-blue-700 { color: #1d4ed8 !important; }
/* Product tags - same as desktop structure */
#results .flex.flex-wrap.gap-1 {
margin-top: 0.75rem !important;
gap: 0.375rem !important;
padding-top: 0.75rem !important;
border-top: 1px solid #f3f4f6 !important;
}
/* Product tag styling - same as desktop */
#results .bg-blue-50,
#results .bg-blue-100 {
font-size: 0.75rem !important;
padding: 0.25rem 0.5rem !important;
background: linear-gradient(135deg, #dbeafe, #bfdbfe) !important;
color: #1e40af !important;
border: 1px solid #93c5fd !important;
border-radius: 9999px !important;
display: inline-block !important;
margin: 0.25rem 0.25rem 0.25rem 0 !important;
font-weight: 500 !important;
}
/* Hover effects - same as desktop */
#results > div:hover {
transform: translateY(-2px) !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
}
/* Remove hover effects on contact items */
#results .flex.items-center.gap-2:hover,
#results .flex.items-start.gap-2:hover {
background: transparent !important;
border: none !important;
transform: none !important;
}
/* Links - ensure they're touch-friendly */
#results a {
min-height: 32px !important;
display: inline-flex !important;
align-items: center !important;
text-decoration: none !important;
}
#results a:hover {
opacity: 0.8 !important;
}
/* CRUD Wrench Button */
.fixed.bottom-6.right-6 {
bottom: 1rem !important;
right: 1rem !important;
}
.w-14.h-14 {
width: 3rem !important;
height: 3rem !important;
}
/* CRUD Modal Mobile Adjustments */
.max-w-4xl {
max-width: calc(100vw - 2rem) !important;
margin: 1rem !important;
}
.max-h-\[90vh\] {
max-height: calc(100vh - 2rem) !important;
}
/* CRUD Modal Content */
.p-6 {
padding: 1rem !important;
}
/* CRUD Form Grids */
.grid.grid-cols-1.md\:grid-cols-2.gap-4 {
grid-template-columns: 1fr !important;
gap: 0.75rem !important;
}
/* Toast Notifications */
.fixed.top-4.right-4 {
top: 1rem !important;
right: 1rem !important;
left: 1rem !important;
}
.max-w-sm {
max-width: none !important;
}
}
/* Very small screens */
@media (max-width: 480px) {
#results > div {
padding: 0.875rem !important;
}
#results .text-base.font-bold,
#results .text-lg.font-bold {
font-size: 0.9375rem !important;
}
#results .flex.items-center.gap-2 span,
#results .flex.items-center.gap-2 a {
font-size: 0.8125rem !important;
}
}
/* Tablet and larger screens */
@media (min-width: 769px) and (max-width: 1024px) {
.service-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1025px) {
.service-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* IMMEDIATE MOBILE FIXES - Add to end of styles.css */
@media (max-width: 768px) {
/* Fix search button staying inline with input */
.flex.flex-col.sm\:flex-row.gap-3.mb-4 {
flex-direction: row !important;
align-items: stretch !important;
gap: 0.5rem !important;
}
.flex.flex-col.sm\:flex-row.gap-3.mb-4 .flex-1 {
flex: 1 !important;
}
.flex.flex-col.sm\:flex-row.gap-3.mb-4 button {
width: auto !important;
min-width: 50px !important;
flex-shrink: 0 !important;
padding: 0.875rem 1rem !important;
}
/* Hide button text on mobile, show only icon */
.flex.flex-col.sm\:flex-row.gap-3.mb-4 button span {
display: none !important;
}
/* Fix advanced search buttons */
.flex.flex-wrap.gap-3 {
display: grid !important;
grid-template-columns: 1fr 1fr !important;
gap: 0.5rem !important;
}
/* Hide reset button on mobile for cleaner look */
.flex.flex-wrap.gap-3 button:nth-child(3) {
grid-column: span 2 !important;
font-size: 0.8rem !important;
}
/* Fix modal sizing */
.max-w-4xl, .max-w-2xl {
max-width: calc(100vw - 1rem) !important;
margin: 0.5rem !important;
}
/* Improve touch targets */
button, .cursor-pointer {
min-height: 44px !important;
}
}
/* Very small screens (phones in portrait) */
@media (max-width: 480px) {
.px-4 {
padding-left: 0.75rem !important;
padding-right: 0.75rem !important;
}
.text-3xl, .text-4xl {
font-size: 1.5rem !important;
line-height: 1.3 !important;
}
/* Stack stats in 2x2 grid instead of 4x1 */
.grid.grid-cols-2.lg\:grid-cols-4 {
grid-template-columns: repeat(2, 1fr) !important;
gap: 0.5rem !important;
}
}
/* Searchable Country Dropdown Styles - Add to end of styles.css */
/* Input with search icon */
.relative input[id$="_input"] {
padding-right: 2.5rem !important;
}
/* Search icon positioning */
.relative .absolute.right-3 {
pointer-events: none;
z-index: 5;
}
/* Dropdown menu */
.relative .absolute.z-20 {
border: 1px solid #d1d5db;
border-radius: 0.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
background: white;
max-height: 12rem;
overflow-y: auto;
margin-top: 0.25rem;
}
/* Dropdown options */
.relative .absolute.z-20 > div {
padding: 0.75rem;
cursor: pointer;
font-size: 0.875rem;
border-bottom: 1px solid #f3f4f6;
transition: all 0.15s ease;
}
.relative .absolute.z-20 > div:last-child {
border-bottom: none;
}
.relative .absolute.z-20 > div:hover {
background-color: #eff6ff;
color: #1d4ed8;
}
/* Highlighted option (keyboard navigation) */
.relative .absolute.z-20 > div.bg-blue-100 {
background-color: #dbeafe !important;
color: #1e40af !important;
}
/* Custom scrollbar for dropdown */
.relative .absolute.z-20::-webkit-scrollbar {
width: 6px;
}
.relative .absolute.z-20::-webkit-scrollbar-track {
background: #f1f5f9;
border-radius: 3px;
}
.relative .absolute.z-20::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 3px;
}
.relative .absolute.z-20::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
/* Mobile improvements */
@media (max-width: 768px) {
.relative input[id$="_input"] {
font-size: 16px !important; /* Prevents zoom on iOS */
padding: 0.875rem 2.5rem 0.875rem 0.75rem !important;
}
.relative .absolute.z-20 > div {
padding: 1rem 0.75rem;
min-height: 44px; /* Better touch targets */
display: flex;
align-items: center;
}
.relative .absolute.z-20 {
max-height: 10rem; /* Smaller on mobile */
}
}
/* Focus styles for accessibility */
.relative input[id$="_input"]:focus {
outline: none !important;
border-color: #3b82f6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}
/* Animation for icon change */
.relative .absolute.right-3 i {
transition: all 0.2s ease;
}

198
assets/js/calendar-agent.js Normal file
View File

@ -0,0 +1,198 @@
/**
* Calendar Agent Specific Functions
*/
class CalendarAgent {
constructor() {
this.totalActions = 0;
this.init();
}
init() {
Utils.time.updateLastUpdated('lastSync');
this.initializeEventListeners();
}
initializeEventListeners() {
Utils.events.onEnterKey('calendarCommand', () => this.executeCalendarCommand());
}
setCalendarCommand(command) {
Utils.form.setInputValue('calendarCommand', command);
this.executeCalendarCommand();
}
async executeCalendarCommand() {
const command = Utils.form.getInputValue('calendarCommand');
if (!command) {
Utils.toast.warning('Please enter a command');
return;
}
Utils.button.setLoading('calendarAiBtn', 'Processing...', 'fa-spinner fa-spin');
try {
// Simulate AI processing
await new Promise(resolve => setTimeout(resolve, 1500));
const response = this.generateCalendarAIResponse(command);
Utils.modal.showAI(response);
this.updateCalendarStats();
Utils.time.updateLastUpdated('lastSync');
} catch (error) {
Utils.toast.error('Error processing command: ' + error.message);
} finally {
Utils.button.restore('calendarAiBtn', 'Execute', 'fa-robot');
Utils.form.clearInput('calendarCommand');
}
}
generateCalendarAIResponse(command) {
const lowerCommand = command.toLowerCase();
if (lowerCommand.includes('schedule') && lowerCommand.includes('meeting')) {
return `
<div class="space-y-4">
<h4 class="text-lg font-semibold text-gray-800">📅 Schedule Meeting</h4>
<div class="bg-green-50 border border-green-200 p-4 rounded-lg">
<h5 class="font-medium text-green-800 mb-2"> Optimal Time Found</h5>
<p class="text-sm text-green-700 mb-3">Best time for all attendees: <strong>Tomorrow 3:30 PM - 4:30 PM</strong></p>
<div class="space-y-2 text-sm text-green-700">
<div class="flex items-center gap-2">
<i class="fas fa-users text-green-600"></i>
<span>5 attendees available</span>
</div>
<div class="flex items-center gap-2">
<i class="fas fa-map-marker-alt text-green-600"></i>
<span>Conference Room B reserved</span>
</div>
<div class="flex items-center gap-2">
<i class="fas fa-video text-green-600"></i>
<span>Zoom link generated</span>
</div>
</div>
</div>
<div class="bg-blue-50 border border-blue-200 p-4 rounded-lg">
<h5 class="font-medium text-blue-800 mb-2">📋 Meeting Details</h5>
<div class="space-y-2 text-sm text-blue-700">
<p><strong>Title:</strong> Team Strategy Discussion</p>
<p><strong>Duration:</strong> 1 hour</p>
<p><strong>Attendees:</strong> Sarah, John, Mike, Lisa, David</p>
<p><strong>Agenda:</strong> Q1 planning and resource allocation</p>
</div>
</div>
<div class="flex gap-3">
<button class="flex-1 bg-green-600 text-white py-2 px-4 rounded-lg hover:bg-green-700 transition-colors">Confirm & Send Invites</button>
<button class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors">Modify Details</button>
</div>
</div>
`;
}
return `
<div class="space-y-4">
<h4 class="text-lg font-semibold text-gray-800">🤖 Calendar AI Response</h4>
<div class="bg-green-50 border border-green-200 p-4 rounded-lg">
<p class="text-green-700">Processing your request: "<em>${command}</em>"</p>
<p class="text-sm text-green-600 mt-2">I can help you with:</p>
<ul class="mt-3 space-y-1 text-sm text-green-700">
<li> Smart meeting scheduling and optimization</li>
<li> Finding optimal free time slots</li>
<li> Conflict detection and resolution</li>
<li> Focus time blocking and protection</li>
<li> Calendar analysis and insights</li>
</ul>
</div>
</div>
`;
}
updateCalendarStats() {
Utils.stats.increment('aiScheduled');
this.totalActions++;
}
// Quick action functions
scheduleMeeting() {
Utils.modal.showAI(`
<div class="space-y-4">
<h4 class="text-lg font-semibold text-gray-800">📅 Schedule New Meeting</h4>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Meeting Title:</label>
<input type="text" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-green-500" placeholder="Team Strategy Discussion">
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Date:</label>
<input type="date" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-green-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Duration:</label>
<select class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-green-500">
<option value="30">30 minutes</option>
<option value="60" selected>1 hour</option>
<option value="90">1.5 hours</option>
<option value="120">2 hours</option>
</select>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Attendees:</label>
<input type="text" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-green-500" placeholder="sarah@company.com, john@company.com">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Meeting Type:</label>
<div class="grid grid-cols-2 gap-3">
<label class="flex items-center p-3 border border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50">
<input type="radio" name="meetingType" value="inPerson" class="mr-2">
<span class="text-sm">In-Person</span>
</label>
<label class="flex items-center p-3 border border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50">
<input type="radio" name="meetingType" value="virtual" class="mr-2" checked>
<span class="text-sm">Virtual</span>
</label>
</div>
</div>
<button class="w-full bg-green-600 text-white py-3 px-4 rounded-lg hover:bg-green-700 transition-colors font-medium">
🤖 Find Optimal Time & Schedule
</button>
</div>
</div>
`);
}
findFreeTime() {
this.updateCalendarStats();
Utils.toast.info('🔍 Found 3 optimal time slots this week for your requirements');
}
blockFocusTime() {
this.updateCalendarStats();
Utils.toast.success('🧠 Protected 2-hour focus block scheduled for tomorrow 10-12 AM');
}
optimizeSchedule() {
if (confirm('Let AI optimize your schedule for maximum productivity?')) {
this.updateCalendarStats();
Utils.toast.success('✨ Schedule optimized! Moved 3 meetings to create better focus blocks and reduced meeting fragmentation by 40%.');
}
}
}
// Initialize Calendar Agent when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
window.calendarAgent = new CalendarAgent();
// Make functions globally available for onclick handlers
window.executeCalendarCommand = () => calendarAgent.executeCalendarCommand();
window.setCalendarCommand = (cmd) => calendarAgent.setCalendarCommand(cmd);
window.scheduleMeeting = () => calendarAgent.scheduleMeeting();
window.findFreeTime = () => calendarAgent.findFreeTime();
window.blockFocusTime = () => calendarAgent.blockFocusTime();
window.optimizeSchedule = () => calendarAgent.optimizeSchedule();
window.closeAIModal = () => Utils.modal.hideAI();
window.goHome = () => Utils.navigation.goHome();
});

546
assets/js/email-agent.js Normal file
View File

@ -0,0 +1,546 @@
/**
* Email Agent - Webhook Integration
* Connects to your n8n email analysis workflow
*/
class EmailAgent {
constructor() {
this.apiEndpoint = 'https://thecyberlearn.app.n8n.cloud/webhook/email-agent';
this.currentEmails = [];
this.currentFilter = 'all';
this.totalActions = 0;
this.init();
}
init() {
this.updateLastSync();
this.initializeEventListeners();
this.loadEmails(); // Auto-load emails on page load
}
initializeEventListeners() {
// Search on Enter key
const searchInput = document.getElementById('searchQuery');
if (searchInput) {
searchInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
this.searchEmails();
}
});
}
}
updateLastSync() {
const element = document.getElementById('lastSync');
if (element) {
element.textContent = new Date().toLocaleTimeString();
}
}
// Main function to load emails from webhook
async loadEmails(action = 'get_inbox', params = {}) {
const loadingState = document.getElementById('loadingState');
const emailList = document.getElementById('emailList');
const emptyState = document.getElementById('emptyState');
try {
// Show loading state
this.showLoading(true);
// Build API URL
const url = new URL(this.apiEndpoint);
url.searchParams.append('action', action);
// Add additional parameters
Object.keys(params).forEach(key => {
if (params[key]) {
url.searchParams.append(key, params[key]);
}
});
console.log('Loading emails from:', url.toString());
const response = await fetch(url.toString());
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
console.log('Email data received:', data);
if (data.success && data.emails) {
this.currentEmails = data.emails;
this.displayEmails(data.emails);
this.updateStats(data);
this.addToRecentActivity(`Loaded ${data.emails.length} emails`, 'load');
// Hide empty state, show email list
if (emptyState) emptyState.classList.add('hidden');
if (emailList) emailList.classList.remove('hidden');
} else {
this.showEmptyState();
console.log('No emails found or API error');
}
} catch (error) {
console.error('Error loading emails:', error);
this.showError('Failed to load emails: ' + error.message);
} finally {
this.showLoading(false);
this.updateLastSync();
}
}
// Display emails in the UI
displayEmails(emails) {
const emailList = document.getElementById('emailList');
if (!emailList) return;
if (emails.length === 0) {
this.showEmptyState();
return;
}
const emailHTML = emails.map((email, index) => {
return this.generateEmailCard(email, index);
}).join('');
emailList.innerHTML = emailHTML;
emailList.classList.remove('hidden');
// Add click handlers
this.attachEmailClickHandlers();
}
// Generate individual email card HTML
generateEmailCard(email, index) {
const priorityClass = `priority-${email.priority.toLowerCase()}`;
const unreadClass = email.unread ? 'email-unread' : 'email-read';
const typeIcon = this.getTypeIcon(email.type);
const typeColor = this.getTypeColor(email.type);
return `
<div class="email-card ${unreadClass} ${priorityClass} p-4 rounded-lg border border-gray-200 cursor-pointer fade-in"
onclick="emailAgent.viewEmailDetails('${email.id}')"
data-email-id="${email.id}">
<div class="flex items-start justify-between mb-3">
<div class="flex items-center gap-3 flex-1 min-w-0">
<!-- Type Icon -->
<div class="w-8 h-8 bg-${typeColor}-100 rounded-lg flex items-center justify-center flex-shrink-0">
<i class="${typeIcon} text-${typeColor}-600"></i>
</div>
<!-- Sender & Subject -->
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<span class="font-semibold text-gray-800 truncate">${email.sender}</span>
${email.priority === 'High' ? '<span class="px-2 py-1 bg-red-100 text-red-700 text-xs rounded-full">High Priority</span>' : ''}
${email.priority === 'Medium' ? '<span class="px-2 py-1 bg-orange-100 text-orange-700 text-xs rounded-full">Medium</span>' : ''}
${email.unread ? '<span class="w-2 h-2 bg-blue-500 rounded-full"></span>' : ''}
</div>
<h4 class="font-medium text-gray-800 mb-1 line-clamp-1">${email.subject}</h4>
<p class="text-sm text-gray-600 line-clamp-2">${email.summary}</p>
</div>
</div>
<!-- Time & Actions -->
<div class="text-right ml-4 flex-shrink-0">
<div class="text-sm text-gray-500 mb-1">${email.timestamp}</div>
<div class="flex items-center gap-1 justify-end">
${email.attachments > 0 ? `<i class="fas fa-paperclip text-gray-400 text-xs"></i><span class="text-xs text-gray-500">${email.attachments}</span>` : ''}
<span class="text-xs px-2 py-1 bg-${typeColor}-50 text-${typeColor}-700 rounded">${email.type.toUpperCase()}</span>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="flex gap-2 pt-2 border-t border-gray-100">
<button onclick="event.stopPropagation(); emailAgent.viewEmailDetails('${email.id}')"
class="flex-1 text-xs bg-blue-600 text-white py-2 px-3 rounded-lg hover:bg-blue-700 transition-colors">
View Details
</button>
<button onclick="event.stopPropagation(); emailAgent.markAsRead('${email.id}')"
class="text-xs px-3 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors">
${email.unread ? 'Mark Read' : 'Mark Unread'}
</button>
<button onclick="event.stopPropagation(); emailAgent.shareEmail('${email.id}')"
class="text-xs px-3 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors">
<i class="fas fa-share"></i>
</button>
</div>
</div>
`;
}
// Get type icon for email type
getTypeIcon(type) {
const icons = {
'email': 'fas fa-envelope',
'pdf': 'fas fa-file-pdf',
'image': 'fas fa-image'
};
return icons[type] || 'fas fa-file';
}
// Get type color for email type
getTypeColor(type) {
const colors = {
'email': 'blue',
'pdf': 'red',
'image': 'green'
};
return colors[type] || 'gray';
}
// Search emails
async searchEmails() {
const searchQuery = document.getElementById('searchQuery');
const query = searchQuery ? searchQuery.value.trim() : '';
if (!query) {
this.loadEmails(); // Load all if no search query
return;
}
await this.loadEmails('search', { query: query });
this.addToRecentActivity(`Searched for "${query}"`, 'search');
}
// Filter emails by type
async filterEmails(type) {
this.currentFilter = type;
// Update filter button styles
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.classList.remove('active', 'bg-blue-100', 'text-blue-700');
btn.classList.add('bg-gray-100', 'text-gray-700');
});
const activeBtn = document.querySelector(`[data-filter="${type}"]`);
if (activeBtn) {
activeBtn.classList.remove('bg-gray-100', 'text-gray-700');
activeBtn.classList.add('active', 'bg-blue-100', 'text-blue-700');
}
if (type === 'all') {
await this.loadEmails('get_inbox');
} else {
await this.loadEmails('filter', { type: type });
}
this.addToRecentActivity(`Filtered by ${type}`, 'filter');
}
// Refresh emails
async refreshEmails() {
await this.loadEmails(this.currentFilter === 'all' ? 'get_inbox' : 'filter',
this.currentFilter === 'all' ? {} : { type: this.currentFilter });
this.addToRecentActivity('Refreshed emails', 'refresh');
}
// View email details in modal
viewEmailDetails(emailId) {
const email = this.currentEmails.find(e => e.id === emailId);
if (!email) return;
const modal = document.getElementById('emailModal');
const content = document.getElementById('emailContent');
if (!modal || !content) return;
const detailHTML = `
<div class="space-y-6">
<!-- Email Header -->
<div class="border-b border-gray-200 pb-4">
<div class="flex items-center gap-3 mb-3">
<div class="w-12 h-12 bg-${this.getTypeColor(email.type)}-100 rounded-lg flex items-center justify-center">
<i class="${this.getTypeIcon(email.type)} text-${this.getTypeColor(email.type)}-600 text-lg"></i>
</div>
<div class="flex-1">
<h2 class="text-xl font-bold text-gray-800">${email.subject}</h2>
<p class="text-gray-600">From: ${email.sender} (${email.senderEmail})</p>
</div>
<div class="text-right">
<span class="px-3 py-1 bg-${email.priorityColor}-100 text-${email.priorityColor}-700 rounded-full text-sm">
${email.priority} Priority
</span>
<p class="text-sm text-gray-500 mt-1">${email.timestamp}</p>
</div>
</div>
</div>
<!-- Email Content -->
<div class="space-y-4">
<div>
<h3 class="text-lg font-semibold text-gray-800 mb-2">AI Summary</h3>
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
<p class="text-blue-800">${email.summary}</p>
</div>
</div>
${email.fullSummary && email.fullSummary !== email.summary ? `
<div>
<h3 class="text-lg font-semibold text-gray-800 mb-2">Full Analysis</h3>
<div class="bg-gray-50 border border-gray-200 rounded-lg p-4">
<p class="text-gray-700 whitespace-pre-wrap">${email.fullSummary}</p>
</div>
</div>
` : ''}
<!-- Email Meta Info -->
<div class="grid grid-cols-2 gap-4">
<div class="bg-gray-50 p-4 rounded-lg">
<h4 class="font-medium text-gray-700 mb-2">AI Analysis</h4>
<p class="text-sm text-gray-600">Priority: ${email.priority}</p>
<p class="text-sm text-gray-600">Attachments: ${email.attachments}</p>
<p class="text-sm text-gray-600">Auto-processed: Yes</p>
</div>
</div>
</div>
</div>
`;
content.innerHTML = detailHTML;
modal.classList.remove('hidden');
this.addToRecentActivity(`Viewed "${email.subject}"`, 'view');
}
// Close email modal
closeEmailModal() {
const modal = document.getElementById('emailModal');
if (modal) {
modal.classList.add('hidden');
}
}
// Mark email as read/unread (simulated)
markAsRead(emailId) {
const email = this.currentEmails.find(e => e.id === emailId);
if (email) {
email.unread = !email.unread;
this.displayEmails(this.currentEmails); // Refresh display
this.addToRecentActivity(`Marked "${email.subject}" as ${email.unread ? 'unread' : 'read'}`, 'mark');
}
}
// Share email (copy to clipboard)
shareEmail(emailId) {
const email = this.currentEmails.find(e => e.id === emailId);
if (email) {
const shareText = `${email.subject}\nFrom: ${email.sender}\nSummary: ${email.summary}`;
if (navigator.clipboard) {
navigator.clipboard.writeText(shareText).then(() => {
this.showToast('Email details copied to clipboard!', 'success');
});
} else {
// Fallback for older browsers
const textArea = document.createElement('textarea');
textArea.value = shareText;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
this.showToast('Email details copied to clipboard!', 'success');
}
this.addToRecentActivity(`Shared "${email.subject}"`, 'share');
}
}
// Export emails to CSV
exportEmails() {
if (this.currentEmails.length === 0) {
this.showToast('No emails to export', 'warning');
return;
}
const headers = ['Date', 'Sender', 'Subject', 'Type', 'Priority', 'Summary'];
const csvContent = [
headers.join(','),
...this.currentEmails.map(email => [
`"${email.date}"`,
`"${email.sender}"`,
`"${email.subject}"`,
`"${email.type}"`,
`"${email.priority}"`,
`"${email.summary.replace(/"/g, '""')}"`
].join(','))
].join('\n');
const blob = new Blob([csvContent], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `email_summaries_${new Date().toISOString().split('T')[0]}.csv`;
a.click();
window.URL.revokeObjectURL(url);
this.showToast('Email data exported successfully!', 'success');
this.addToRecentActivity(`Exported ${this.currentEmails.length} emails`, 'export');
}
// Update statistics
updateStats(data) {
const stats = data.stats || {};
// Update stat counters
this.updateElement('totalCount', stats.total || this.currentEmails.length);
this.updateElement('priorityCount', stats.high_priority || 0);
this.updateElement('processedCount', stats.total || this.currentEmails.length);
this.updateElement('aiActionsCount', stats.total || this.currentEmails.length);
}
// Helper function to update element text
updateElement(id, value) {
const element = document.getElementById(id);
if (element) {
element.textContent = value;
}
}
// Add activity to recent activity panel
addToRecentActivity(message, type = 'info') {
const recentActivity = document.getElementById('recentActivity');
if (!recentActivity) return;
const iconMap = {
'load': 'fa-download',
'search': 'fa-search',
'filter': 'fa-filter',
'refresh': 'fa-sync-alt',
'view': 'fa-eye',
'mark': 'fa-check',
'share': 'fa-share',
'export': 'fa-file-export'
};
const colorMap = {
'load': 'blue',
'search': 'green',
'filter': 'purple',
'refresh': 'orange',
'view': 'indigo',
'mark': 'green',
'share': 'blue',
'export': 'red'
};
const icon = iconMap[type] || 'fa-info-circle';
const color = colorMap[type] || 'blue';
const time = new Date().toLocaleTimeString();
// Clear default message if exists
if (recentActivity.children.length === 1 && recentActivity.textContent.includes('Load emails')) {
recentActivity.innerHTML = '';
}
const activityItem = document.createElement('div');
activityItem.className = 'flex items-start gap-3 p-2 bg-gray-50 rounded-lg fade-in';
activityItem.innerHTML = `
<div class="w-6 h-6 bg-${color}-100 rounded flex items-center justify-center flex-shrink-0 mt-1">
<i class="fas ${icon} text-${color}-600 text-xs"></i>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-800 truncate">${message}</p>
<p class="text-xs text-gray-500">${time}</p>
</div>
`;
recentActivity.insertBefore(activityItem, recentActivity.firstChild);
// Keep only last 5 activities
while (recentActivity.children.length > 5) {
recentActivity.removeChild(recentActivity.lastChild);
}
this.totalActions++;
}
// Show/hide loading state
showLoading(show) {
const loadingState = document.getElementById('loadingState');
const emailList = document.getElementById('emailList');
if (loadingState) {
if (show) {
loadingState.classList.remove('hidden');
} else {
loadingState.classList.add('hidden');
}
}
if (emailList && show) {
emailList.classList.add('hidden');
}
}
// Show empty state
showEmptyState() {
const emailList = document.getElementById('emailList');
const emptyState = document.getElementById('emptyState');
if (emailList) emailList.classList.add('hidden');
if (emptyState) emptyState.classList.remove('hidden');
}
// Show error message
showError(message) {
this.showToast(message, 'error');
this.showEmptyState();
}
// Toast notification system
showToast(message, type = 'info') {
const colors = {
success: 'bg-green-100 border-green-300 text-green-800',
error: 'bg-red-100 border-red-300 text-red-800',
warning: 'bg-yellow-100 border-yellow-300 text-yellow-800',
info: 'bg-blue-100 border-blue-300 text-blue-800'
};
const icons = {
success: 'fa-check-circle',
error: 'fa-times-circle',
warning: 'fa-exclamation-triangle',
info: 'fa-info-circle'
};
const toast = document.createElement('div');
toast.className = `fixed bottom-4 right-4 z-50 ${colors[type]} border rounded-lg shadow-lg p-4 max-w-sm`;
toast.innerHTML = `
<div class="flex items-center gap-3">
<i class="fas ${icons[type]} text-lg"></i>
<span class="font-medium">${message}</span>
<button onclick="this.parentElement.parentElement.remove()" class="ml-auto text-lg hover:opacity-70">×</button>
</div>
`;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 5000);
}
// Attach click handlers to email cards
attachEmailClickHandlers() {
// Click handlers are already in the HTML via onclick attributes
// This method can be used for additional event handling if needed
}
}
// Initialize Email Agent when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
window.emailAgent = new EmailAgent();
// Make functions globally available for onclick handlers
window.loadEmails = () => emailAgent.loadEmails();
window.searchEmails = () => emailAgent.searchEmails();
window.filterEmails = (type) => emailAgent.filterEmails(type);
window.refreshEmails = () => emailAgent.refreshEmails();
window.exportEmails = () => emailAgent.exportEmails();
window.closeEmailModal = () => emailAgent.closeEmailModal();
});

177
assets/js/index.js Normal file
View File

@ -0,0 +1,177 @@
/**
* Main Index Page Functions
*/
class AIServicesHub {
constructor() {
this.init();
}
init() {
this.addAnimations();
this.initializeEventListeners();
}
initializeEventListeners() {
// Service card click handlers are handled via onclick attributes
// But we can add keyboard navigation here if needed
this.addKeyboardNavigation();
}
addAnimations() {
// Add staggered animation to service cards
const cards = document.querySelectorAll('.service-card');
cards.forEach((card, index) => {
card.style.animationDelay = `${index * 0.1}s`;
card.classList.add('opacity-0');
setTimeout(() => {
card.style.animation = 'fadeInUp 0.6s ease-out forwards';
card.classList.remove('opacity-0');
}, index * 100);
});
}
addKeyboardNavigation() {
// Add keyboard navigation for service cards
const serviceCards = document.querySelectorAll('.service-card');
serviceCards.forEach((card, index) => {
card.setAttribute('tabindex', '0');
card.addEventListener('keypress', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
card.click();
}
});
});
}
navigateToService(service) {
// Map service names to actual HTML files
const serviceUrls = {
'trade-intelligence': 'trade-intelligence.html',
'email-agent': 'email-agent.html',
'calendar-agent': 'calendar-agent.html',
'task-agent': 'task-agent.html'
};
const url = serviceUrls[service];
if (url) {
// Check if file exists by trying to navigate
try {
window.location.href = url;
} catch (error) {
// Fallback to showing information if file doesn't exist
this.showServiceInfo(service);
}
} else {
this.showServiceInfo(service);
}
}
showServiceInfo(service) {
const services = {
'trade-intelligence': {
name: 'Trade Intelligence',
description: 'Find exporters, importers, and trade data from around the world',
features: ['50K+ Companies', '150+ Countries', 'Real-time Search', 'Export Data'],
icon: 'fas fa-ship',
color: 'blue'
},
'email-agent': {
name: 'Email Agent',
description: 'Smart email management and summarization with AI',
features: ['Email Summarization', 'Priority Detection', 'Auto-categorization', 'Smart Replies'],
icon: 'fas fa-envelope',
color: 'purple'
},
'calendar-agent': {
name: 'Calendar Agent',
description: 'Intelligent scheduling and meeting management',
features: ['Smart Scheduling', 'Conflict Detection', 'Meeting Optimization', 'Time Blocking'],
icon: 'fas fa-calendar',
color: 'green'
},
'task-agent': {
name: 'Task Agent',
description: 'Smart task management and prioritization',
features: ['AI Prioritization', 'Progress Tracking', 'Deadline Management', 'Workload Balancing'],
icon: 'fas fa-tasks',
color: 'orange'
}
};
const serviceData = services[service];
if (serviceData) {
Utils.modal.show('demoModal', `
<div class="text-center">
<div class="w-16 h-16 bg-${serviceData.color}-100 rounded-xl flex items-center justify-center mx-auto mb-4">
<i class="${serviceData.icon} text-${serviceData.color}-600 text-2xl"></i>
</div>
<h3 class="text-xl font-bold text-gray-800 mb-2">${serviceData.name}</h3>
<p class="text-gray-600 mb-6">${serviceData.description}</p>
<div class="grid grid-cols-2 gap-3 mb-6">
${serviceData.features.map(feature => `
<div class="bg-${serviceData.color}-50 p-3 rounded-lg">
<p class="text-sm text-${serviceData.color}-700 font-medium">${feature}</p>
</div>
`).join('')}
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<p class="text-sm text-gray-600">
<strong>Coming Soon!</strong><br>
This agent is currently in development.
<br>Check back soon for the full experience.
</p>
</div>
</div>
`);
}
}
showDemo() {
Utils.modal.show('demoModal');
}
showDocumentation() {
Utils.modal.show('docModal');
}
closeDemoModal() {
Utils.modal.hide('demoModal');
}
closeDocModal() {
Utils.modal.hide('docModal');
}
}
// Add CSS for fade in animation
const style = document.createElement('style');
style.textContent = `
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
`;
document.head.appendChild(style);
// Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
window.aiServicesHub = new AIServicesHub();
// Make functions globally available for onclick handlers
window.navigateToService = (service) => aiServicesHub.navigateToService(service);
window.showDemo = () => aiServicesHub.showDemo();
window.showDocumentation = () => aiServicesHub.showDocumentation();
window.closeDemoModal = () => aiServicesHub.closeDemoModal();
window.closeDocModal = () => aiServicesHub.closeDocModal();
});

45
assets/js/navigation.js Normal file
View File

@ -0,0 +1,45 @@
/**
* Minimal Navigation Component
* Only creates breadcrumbs for your existing HTML
*/
document.addEventListener('DOMContentLoaded', function() {
createBreadcrumbs();
});
function createBreadcrumbs() {
const breadcrumbContainer = document.querySelector('.breadcrumbs');
if (!breadcrumbContainer) return;
// Detect current page
const path = window.location.pathname;
const filename = path.split('/').pop() || 'index.html';
const currentPage = filename.replace('.html', '');
const pages = {
'index': { name: 'Home', icon: 'fas fa-home' },
'trade-intelligence': { name: 'Trade Intelligence', icon: 'fas fa-ship' },
'email-agent': { name: 'Email Agent', icon: 'fas fa-envelope' },
'calendar-agent': { name: 'Calendar Agent', icon: 'fas fa-calendar' },
'task-agent': { name: 'Task Agent', icon: 'fas fa-tasks' }
};
const currentPageInfo = pages[currentPage];
if (!currentPageInfo) return;
breadcrumbContainer.innerHTML = `
<div class="flex items-center space-x-2 text-sm">
<a href="index.html" class="text-indigo-600 hover:text-indigo-800 flex items-center gap-1 transition-colors">
<i class="fas fa-home"></i>
<span>Home</span>
</a>
${currentPage !== 'index' ? `
<i class="fas fa-chevron-right text-gray-400"></i>
<span class="text-gray-600 flex items-center gap-1">
<i class="${currentPageInfo.icon}"></i>
<span>${currentPageInfo.name}</span>
</span>
` : ''}
</div>
`;
}

887
assets/js/task-agent.js Normal file
View File

@ -0,0 +1,887 @@
/**
* Task Agent Specific Functions - Fixed Version
*/
class TaskAgent {
constructor() {
this.totalActions = 0;
this.tasks = [];
this.stats = {
total: 0,
overdue: 0,
dueToday: 0,
completed: 0,
inProgress: 0,
toDo: 0
};
// Set default API URL - you can override this
this.apiUrl = 'https://thecyberlearn.app.n8n.cloud/webhook/tasks';
this.init();
}
init() {
// Wait for DOM to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => this.initializeAfterDOM());
} else {
this.initializeAfterDOM();
}
}
initializeAfterDOM() {
this.updateLastUpdated('lastUpdate');
this.initializeEventListeners();
// Load sample tasks if API URL is not configured
if (this.apiUrl.includes('your-n8n-instance.com')) {
console.log('Using sample data - configure apiUrl for real data');
this.loadSampleTasks();
} else {
this.loadTasks(); // Load tasks from API
}
}
updateLastUpdated(elementId) {
const element = document.getElementById(elementId);
if (element) {
element.textContent = new Date().toLocaleTimeString();
}
}
initializeEventListeners() {
const taskCommandInput = document.getElementById('taskCommand');
if (taskCommandInput) {
taskCommandInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
this.executeTaskCommand();
}
});
}
const searchInput = document.getElementById('taskSearchInput');
if (searchInput) {
searchInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
this.handleSearch();
}
});
}
}
setTaskCommand(command) {
const element = document.getElementById('taskCommand');
if (element) {
element.value = command;
this.executeTaskCommand();
}
}
async executeTaskCommand() {
const element = document.getElementById('taskCommand');
const command = element ? element.value : '';
if (!command) {
this.showToast('Please enter a command', 'warning');
return;
}
this.setButtonLoading('taskAiBtn', 'Processing...', 'fa-spinner fa-spin');
try {
// Simulate AI processing
await new Promise(resolve => setTimeout(resolve, 1500));
const response = this.generateTaskAIResponse(command);
this.showAIModal(response);
this.updateTaskStats();
this.updateLastUpdated('lastUpdate');
} catch (error) {
this.showToast('Error processing command: ' + error.message, 'error');
} finally {
this.restoreButton('taskAiBtn', 'Execute', 'fa-robot');
this.clearInput('taskCommand');
}
}
generateTaskAIResponse(command) {
const lowerCommand = command.toLowerCase();
if (lowerCommand.includes('overdue') || lowerCommand.includes('urgent')) {
return `
<div class="space-y-4">
<h4 class="text-lg font-semibold text-gray-800"> Overdue Tasks Analysis</h4>
<div class="bg-red-50 border border-red-200 p-4 rounded-lg">
<h5 class="font-medium text-red-800 mb-2">🚨 Immediate Action Required</h5>
<p class="text-sm text-red-700 mb-3">Found <strong>${this.stats.overdue}</strong> overdue tasks that need immediate attention</p>
<div class="space-y-2 text-sm text-red-700">
<div class="flex items-center gap-2">
<i class="fas fa-exclamation-triangle text-red-600"></i>
<span>Website Security Audit - 2 days overdue</span>
</div>
<div class="flex items-center gap-2">
<i class="fas fa-clock text-red-600"></i>
<span>Client Presentation - Due today</span>
</div>
</div>
</div>
<div class="bg-orange-50 border border-orange-200 p-4 rounded-lg">
<h5 class="font-medium text-orange-800 mb-2">💡 AI Recommendations</h5>
<div class="space-y-2 text-sm text-orange-700">
<p> Prioritize security audit first - highest business risk</p>
<p> Delegate or reschedule lower priority tasks</p>
<p> Block 2-hour focus time for urgent items</p>
</div>
</div>
</div>
`;
}
return `
<div class="space-y-4">
<h4 class="text-lg font-semibold text-gray-800">🤖 Task AI Response</h4>
<div class="bg-orange-50 border border-orange-200 p-4 rounded-lg">
<p class="text-orange-700">Processing your request: "<em>${command}</em>"</p>
<p class="text-sm text-orange-600 mt-2">I can help you with:</p>
<ul class="mt-3 space-y-1 text-sm text-orange-700">
<li> Smart task prioritization and scheduling</li>
<li> Deadline tracking and alerts</li>
<li> Progress analysis and reporting</li>
<li> Workload balancing and optimization</li>
<li> Task automation and workflows</li>
</ul>
</div>
</div>
`;
}
// Real API integration functions
async loadTasks(filters = {}) {
try {
this.showLoading(true);
const params = new URLSearchParams({
action: 'get_tasks',
...filters
});
console.log('Loading tasks from:', this.apiUrl);
const response = await fetch(`${this.apiUrl}?${params}`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (data.success) {
this.tasks = data.tasks || [];
this.stats = data.stats || this.stats;
this.updateUI();
this.renderTasks();
console.log('✅ Tasks loaded successfully:', this.tasks.length);
} else {
throw new Error(data.message || 'Failed to load tasks');
}
} catch (error) {
console.error('❌ Error loading tasks:', error);
this.showError('Failed to load tasks: ' + error.message);
} finally {
this.showLoading(false);
}
}
// Load sample tasks for demonstration
loadSampleTasks() {
console.log('Loading sample tasks...');
this.tasks = [
{
id: 'task_1',
name: 'Website Security Audit',
description: 'Complete security assessment and vulnerability report',
dueDate: '02-01-2025',
dueDateFormatted: '2 days overdue',
timeEstimate: '3 hrs',
status: 'To Do',
priority: 'High',
priorityColor: 'red',
progress: 0,
type: 'Security',
isOverdue: true,
isDueToday: false
},
{
id: 'task_2',
name: 'Write Blog Article',
description: 'Article on "Top 5 AI Tools for Creators"',
dueDate: '06-01-2025',
dueDateFormatted: 'Due tomorrow',
timeEstimate: '2 hrs',
status: 'In Progress',
priority: 'Medium',
priorityColor: 'orange',
progress: 65,
type: 'Writing',
isOverdue: false,
isDueToday: false
},
{
id: 'task_3',
name: 'Design Landing Page',
description: 'Create a responsive landing page using Tailwind',
dueDate: '05-01-2025',
dueDateFormatted: 'Due today',
timeEstimate: '3 hrs',
status: 'To Do',
priority: 'Medium',
priorityColor: 'orange',
progress: 0,
type: 'Design',
isOverdue: false,
isDueToday: true
},
{
id: 'task_4',
name: 'Deploy Production Update',
description: 'Release v2.1.3 to production servers',
dueDate: '03-01-2025',
dueDateFormatted: 'Completed yesterday',
timeEstimate: '1 hr',
status: 'Done',
priority: 'High',
priorityColor: 'red',
progress: 100,
type: 'Development',
isOverdue: false,
isDueToday: false
}
];
this.stats = {
total: this.tasks.length,
overdue: this.tasks.filter(t => t.isOverdue).length,
dueToday: this.tasks.filter(t => t.isDueToday).length,
completed: this.tasks.filter(t => t.status === 'Done').length,
inProgress: this.tasks.filter(t => t.status === 'In Progress').length,
toDo: this.tasks.filter(t => t.status === 'To Do').length
};
this.updateUI();
this.renderTasks();
this.showLoading(false);
}
async searchTasks(query) {
if (!query.trim()) {
this.loadTasks();
return;
}
// Filter current tasks for demo
const filtered = this.tasks.filter(task =>
task.name.toLowerCase().includes(query.toLowerCase()) ||
task.description.toLowerCase().includes(query.toLowerCase())
);
this.renderFilteredTasks(filtered);
this.showToast(`Found ${filtered.length} tasks matching "${query}"`, 'info');
}
async filterTasks(status) {
console.log('Filtering by status:', status);
if (status === 'all') {
this.renderTasks();
return;
}
const statusMap = {
'todo': 'To Do',
'inprogress': 'In Progress',
'done': 'Done'
};
const targetStatus = statusMap[status] || status;
const filtered = this.tasks.filter(task => task.status === targetStatus);
this.renderFilteredTasks(filtered);
this.showToast(`Showing ${filtered.length} ${targetStatus} tasks`, 'info');
}
renderTasks() {
this.renderFilteredTasks(this.tasks);
}
renderFilteredTasks(tasks) {
const todoColumn = document.querySelector('#todoColumn .kanban-column');
const inProgressColumn = document.querySelector('#inProgressColumn .kanban-column');
const doneColumn = document.querySelector('#doneColumn .kanban-column');
if (!todoColumn || !inProgressColumn || !doneColumn) {
console.error('Kanban columns not found');
return;
}
// Clear existing tasks
todoColumn.innerHTML = '';
inProgressColumn.innerHTML = '';
doneColumn.innerHTML = '';
// Group tasks by status
const tasksByStatus = {
'To Do': [],
'In Progress': [],
'Done': []
};
tasks.forEach(task => {
if (tasksByStatus[task.status]) {
tasksByStatus[task.status].push(task);
}
});
// Render tasks in each column
Object.keys(tasksByStatus).forEach(status => {
const column = status === 'To Do' ? todoColumn :
status === 'In Progress' ? inProgressColumn : doneColumn;
tasksByStatus[status].forEach(task => {
column.appendChild(this.createTaskCard(task));
});
});
// Update column counts
this.updateColumnCounts(tasksByStatus);
}
createTaskCard(task) {
const card = document.createElement('div');
let cardClass = 'task-card bg-gray-50 p-4 rounded-lg border border-gray-200 cursor-pointer hover:shadow-md transition-all';
if (task.isOverdue) {
cardClass = 'task-card task-overdue bg-red-50 p-4 rounded-lg border border-red-200 cursor-pointer hover:shadow-md transition-all';
} else if (task.isDueToday) {
cardClass = 'task-card task-due-today bg-orange-50 p-4 rounded-lg border border-orange-200 cursor-pointer hover:shadow-md transition-all';
} else if (task.status === 'Done') {
cardClass = 'task-card task-completed bg-green-50 p-4 rounded-lg border border-green-200 cursor-pointer hover:shadow-md transition-all';
}
card.className = cardClass;
card.setAttribute('data-task-id', task.id);
const priorityBadgeColor = task.priority === 'High' ? 'red' :
task.priority === 'Medium' ? 'orange' : 'green';
let progressBar = '';
if (task.status === 'In Progress') {
progressBar = `
<div class="w-full bg-gray-200 rounded-full h-2 mb-2">
<div class="bg-orange-500 h-2 rounded-full transition-all duration-300" style="width: ${task.progress}%"></div>
</div>
<div class="flex items-center justify-between text-xs text-gray-500">
<span>${task.progress}% complete</span>
<span>${task.dueDateFormatted}</span>
</div>
`;
} else {
progressBar = `
<div class="flex items-center justify-between text-xs text-gray-500">
<span><i class="fas fa-clock mr-1"></i>${task.dueDateFormatted}</span>
${task.type ? `<span><i class="fas fa-tag mr-1"></i>${task.type}</span>` : ''}
</div>
`;
}
card.innerHTML = `
<div class="flex items-start justify-between mb-2">
<h4 class="font-medium text-gray-800 text-sm ${task.status === 'Done' ? 'line-through' : ''}">${task.name}</h4>
<span class="px-2 py-1 bg-${priorityBadgeColor}-100 text-${priorityBadgeColor}-700 text-xs rounded-full">${task.priority}</span>
</div>
<p class="text-xs text-gray-600 mb-3">${task.description}</p>
${progressBar}
${task.timeEstimate !== 'Not specified' ? `
<div class="text-xs text-gray-500 mt-2">
<i class="fas fa-hourglass-half mr-1"></i>Estimated: ${task.timeEstimate}
</div>
` : ''}
${task.status === 'Done' ? `
<div class="flex items-center justify-between text-xs text-gray-500 mt-2">
<span><i class="fas fa-check mr-1"></i>Completed</span>
<span>Yesterday</span>
</div>
` : ''}
`;
// Add click handler for task details
card.addEventListener('click', () => this.showTaskDetails(task));
return card;
}
updateColumnCounts(tasksByStatus) {
const todoCountEl = document.querySelector('#todoColumn .text-gray-500');
const inProgressCountEl = document.querySelector('#inProgressColumn .text-gray-500');
const doneCountEl = document.querySelector('#doneColumn .text-gray-500');
if (todoCountEl) todoCountEl.textContent = tasksByStatus['To Do'].length;
if (inProgressCountEl) inProgressCountEl.textContent = tasksByStatus['In Progress'].length;
if (doneCountEl) doneCountEl.textContent = tasksByStatus['Done'].length;
}
updateUI() {
// Update stats dashboard
this.updateElement('overdueCount', this.stats.overdue);
this.updateElement('dueTodayCount', this.stats.dueToday);
this.updateElement('totalTasks', this.stats.total);
this.updateElement('completedToday', this.stats.completed);
this.updateLastUpdated('lastUpdate');
}
updateElement(id, value) {
const element = document.getElementById(id);
if (element) {
element.textContent = value;
}
}
showTaskDetails(task) {
const modalContent = `
<div class="space-y-4">
<div class="flex items-center justify-between">
<h4 class="text-xl font-bold text-gray-800">${task.name}</h4>
<span class="px-3 py-1 bg-${task.priorityColor}-100 text-${task.priorityColor}-700 text-sm rounded-full">${task.priority} Priority</span>
</div>
<div class="bg-gray-50 rounded-lg p-4">
<h5 class="font-medium text-gray-700 mb-2">Description</h5>
<p class="text-gray-600">${task.description}</p>
</div>
<div class="grid grid-cols-2 gap-4">
<div class="bg-blue-50 rounded-lg p-3">
<h5 class="font-medium text-blue-700 mb-1">Status</h5>
<p class="text-blue-600">${task.status}</p>
</div>
<div class="bg-green-50 rounded-lg p-3">
<h5 class="font-medium text-green-700 mb-1">Due Date</h5>
<p class="text-green-600">${task.dueDateFormatted}</p>
</div>
</div>
${task.status === 'In Progress' ? `
<div class="bg-orange-50 rounded-lg p-3">
<h5 class="font-medium text-orange-700 mb-1">Progress</h5>
<div class="w-full bg-gray-200 rounded-full h-3 mb-2">
<div class="bg-orange-500 h-3 rounded-full" style="width: ${task.progress}%"></div>
</div>
<p class="text-orange-600">${task.progress}% Complete</p>
</div>
` : ''}
<div class="grid grid-cols-2 gap-4">
<div class="bg-purple-50 rounded-lg p-3">
<h5 class="font-medium text-purple-700 mb-1">Type</h5>
<p class="text-purple-600">${task.type}</p>
</div>
<div class="bg-indigo-50 rounded-lg p-3">
<h5 class="font-medium text-indigo-700 mb-1">Time Estimate</h5>
<p class="text-indigo-600">${task.timeEstimate}</p>
</div>
</div>
<div class="flex gap-3 pt-4">
<button onclick="taskAgent.updateTaskStatus('${task.id}', 'In Progress')" class="flex-1 bg-orange-600 text-white py-2 px-4 rounded-lg hover:bg-orange-700 transition-colors">
Mark In Progress
</button>
<button onclick="taskAgent.updateTaskStatus('${task.id}', 'Done')" class="flex-1 bg-green-600 text-white py-2 px-4 rounded-lg hover:bg-green-700 transition-colors">
Mark Complete
</button>
</div>
</div>
`;
this.showAIModal(modalContent);
}
showLoading(show) {
const loadingElement = document.getElementById('loadingState');
const kanbanColumns = document.querySelectorAll('.kanban-column');
if (loadingElement) {
loadingElement.classList.toggle('hidden', !show);
}
if (show) {
kanbanColumns.forEach(column => {
column.innerHTML = '<div class="text-center text-gray-500 py-8"><i class="fas fa-spinner fa-spin"></i> Loading...</div>';
});
}
}
showError(message) {
const todoColumn = document.querySelector('#todoColumn .kanban-column');
if (todoColumn) {
todoColumn.innerHTML = `
<div class="text-center py-8">
<div class="w-12 h-12 bg-red-100 rounded-full flex items-center justify-center mx-auto mb-3">
<i class="fas fa-exclamation-triangle text-red-500"></i>
</div>
<h3 class="text-sm font-semibold text-red-600 mb-2">Error Loading Tasks</h3>
<p class="text-xs text-gray-500 mb-3">${message}</p>
<button onclick="taskAgent.loadSampleTasks()" class="text-xs bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded transition-colors">
Load Sample Data
</button>
</div>
`;
}
}
updateTaskStats() {
this.totalActions++;
}
// Utility functions
setButtonLoading(elementId, text, iconClass) {
const element = document.getElementById(elementId);
if (element) {
element.innerHTML = `<i class="${iconClass}"></i> ${text}`;
element.disabled = true;
}
}
restoreButton(elementId, text, iconClass) {
const element = document.getElementById(elementId);
if (element) {
element.innerHTML = `<i class="${iconClass}"></i> <span>${text}</span>`;
element.disabled = false;
}
}
clearInput(elementId) {
const element = document.getElementById(elementId);
if (element) {
element.value = '';
}
}
showAIModal(content) {
const modal = document.getElementById('aiModal');
const responseDiv = document.getElementById('aiResponse');
if (modal && responseDiv) {
responseDiv.innerHTML = content;
modal.classList.remove('hidden');
}
}
hideAIModal() {
const modal = document.getElementById('aiModal');
if (modal) {
modal.classList.add('hidden');
}
}
showToast(message, type = 'info') {
const toast = document.createElement('div');
toast.className = `fixed top-4 right-4 z-50 max-w-sm w-full transform transition-all duration-300`;
const bgColor = {
success: 'bg-green-500',
error: 'bg-red-500',
warning: 'bg-yellow-500',
info: 'bg-blue-500'
}[type] || 'bg-gray-500';
const icon = {
success: 'fas fa-check-circle',
error: 'fas fa-exclamation-circle',
warning: 'fas fa-exclamation-triangle',
info: 'fas fa-info-circle'
}[type] || 'fas fa-info-circle';
toast.innerHTML = `
<div class="${bgColor} text-white px-4 py-3 rounded-lg shadow-lg flex items-center gap-3">
<i class="${icon}"></i>
<span class="text-sm font-medium">${message}</span>
<button onclick="this.parentElement.parentElement.remove()" class="ml-auto text-white hover:text-gray-200">
<i class="fas fa-times text-xs"></i>
</button>
</div>
`;
document.body.appendChild(toast);
// Animate in
setTimeout(() => {
toast.style.transform = 'translateX(0)';
}, 100);
// Auto remove after 4 seconds
setTimeout(() => {
toast.style.transform = 'translateX(100%)';
setTimeout(() => {
if (toast.parentElement) {
toast.remove();
}
}, 300);
}, 4000);
}
// Quick action functions
createTask() {
this.showAIModal(`
<div class="space-y-4">
<h4 class="text-lg font-semibold text-gray-800"> Create New Task</h4>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Task Name:</label>
<input type="text" id="newTaskName" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500" placeholder="Enter task name">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Description:</label>
<textarea id="newTaskDescription" rows="3" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500" placeholder="Describe the task..."></textarea>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Due Date:</label>
<input type="date" id="newTaskDue" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Priority:</label>
<select id="newTaskPriority" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500">
<option value="Low">Low Priority</option>
<option value="Medium" selected>Medium Priority</option>
<option value="High">High Priority</option>
</select>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Time Estimate:</label>
<select id="newTaskTime" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500">
<option value="30 mins">30 minutes</option>
<option value="1 hr" selected>1 hour</option>
<option value="2 hrs">2 hours</option>
<option value="4 hrs">4 hours</option>
<option value="1 day">1 day</option>
<option value="2-3 days">2-3 days</option>
<option value="1 week">1 week</option>
</select>
</div>
<button onclick="taskAgent.submitNewTask()" class="w-full bg-orange-600 text-white py-3 px-4 rounded-lg hover:bg-orange-700 transition-colors font-medium">
🚀 Create Task
</button>
</div>
</div>
`);
}
async submitNewTask() {
const name = document.getElementById('newTaskName')?.value || '';
const description = document.getElementById('newTaskDescription')?.value || '';
const dueDate = document.getElementById('newTaskDue')?.value || '';
const priority = document.getElementById('newTaskPriority')?.value || 'Medium';
const timeEstimate = document.getElementById('newTaskTime')?.value || '1 hr';
if (!name.trim()) {
this.showToast('Please enter a task name', 'warning');
return;
}
try {
// In a real implementation, you would send this to your n8n workflow
// For now, we'll simulate success and add to local data
await new Promise(resolve => setTimeout(resolve, 1000));
// Add new task to local data for demo
const newTask = {
id: 'task_' + Date.now(),
name: name,
description: description || 'No description provided',
dueDate: dueDate,
dueDateFormatted: dueDate ? 'Due ' + new Date(dueDate).toLocaleDateString() : 'No due date',
timeEstimate: timeEstimate,
status: 'To Do',
priority: priority,
priorityColor: priority === 'High' ? 'red' : priority === 'Medium' ? 'orange' : 'green',
progress: 0,
type: 'General',
isOverdue: false,
isDueToday: false
};
this.tasks.unshift(newTask);
this.stats.total++;
this.stats.toDo++;
this.hideAIModal();
this.showToast(`Task "${name}" created successfully!`, 'success');
this.updateUI();
this.renderTasks();
} catch (error) {
this.showToast('Failed to create task: ' + error.message, 'error');
}
}
async updateTaskStatus(taskId, newStatus) {
try {
const task = this.tasks.find(t => t.id === taskId);
if (task) {
const oldStatus = task.status;
task.status = newStatus;
if (newStatus === 'Done') {
task.progress = 100;
} else if (newStatus === 'In Progress' && task.progress === 0) {
task.progress = 25;
}
// Update stats
if (oldStatus === 'To Do') this.stats.toDo--;
else if (oldStatus === 'In Progress') this.stats.inProgress--;
else if (oldStatus === 'Done') this.stats.completed--;
if (newStatus === 'To Do') this.stats.toDo++;
else if (newStatus === 'In Progress') this.stats.inProgress++;
else if (newStatus === 'Done') this.stats.completed++;
this.hideAIModal();
this.showToast(`Task status updated to ${newStatus}`, 'success');
this.updateUI();
this.renderTasks();
}
} catch (error) {
this.showToast('Failed to update task: ' + error.message, 'error');
}
}
prioritizeTasks() {
this.updateTaskStats();
this.showToast('🎯 Tasks automatically prioritized by AI algorithm!', 'success');
// Sort tasks by priority and overdue status
this.tasks.sort((a, b) => {
if (a.isOverdue && !b.isOverdue) return -1;
if (!a.isOverdue && b.isOverdue) return 1;
const priorityOrder = { 'High': 0, 'Medium': 1, 'Low': 2 };
return (priorityOrder[a.priority] || 2) - (priorityOrder[b.priority] || 2);
});
this.renderTasks();
}
bulkUpdate() {
this.updateTaskStats();
this.showToast('📝 Bulk update feature coming soon!', 'info');
}
generateReport() {
const completionRate = this.stats.total > 0 ? Math.round((this.stats.completed / this.stats.total) * 100) : 0;
this.showAIModal(`
<div class="space-y-4">
<h4 class="text-lg font-semibold text-gray-800">📊 Progress Report</h4>
<div class="grid grid-cols-2 gap-4">
<div class="bg-blue-50 rounded-lg p-4 text-center">
<div class="text-2xl font-bold text-blue-600">${this.stats.total}</div>
<div class="text-sm text-blue-600">Total Tasks</div>
</div>
<div class="bg-green-50 rounded-lg p-4 text-center">
<div class="text-2xl font-bold text-green-600">${completionRate}%</div>
<div class="text-sm text-green-600">Completion Rate</div>
</div>
</div>
<div class="bg-gray-50 rounded-lg p-4">
<h5 class="font-medium text-gray-700 mb-3">Task Breakdown</h5>
<div class="space-y-2">
<div class="flex justify-between">
<span class="text-gray-600">Completed:</span>
<span class="font-medium text-green-600">${this.stats.completed}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">In Progress:</span>
<span class="font-medium text-orange-600">${this.stats.inProgress}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">To Do:</span>
<span class="font-medium text-blue-600">${this.stats.toDo}</span>
</div>
<div class="flex justify-between">
<span class="text-red-600">Overdue:</span>
<span class="font-medium text-red-600">${this.stats.overdue}</span>
</div>
</div>
</div>
<div class="bg-orange-50 border border-orange-200 p-4 rounded-lg">
<h5 class="font-medium text-orange-800 mb-2">💡 AI Insights</h5>
<ul class="text-sm text-orange-700 space-y-1">
<li> Your completion rate is ${completionRate > 70 ? 'excellent' : completionRate > 50 ? 'good' : 'needs improvement'}</li>
<li> ${this.stats.overdue > 0 ? `Focus on ${this.stats.overdue} overdue tasks first` : 'Great job staying on top of deadlines!'}</li>
<li> Consider breaking down large tasks into smaller chunks</li>
</ul>
</div>
</div>
`);
}
// Search and filter functions
async handleSearch() {
const searchInput = document.getElementById('taskSearchInput');
if (searchInput) {
await this.searchTasks(searchInput.value);
}
}
async handleFilter(status) {
await this.filterTasks(status);
// Update filter button states
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.classList.remove('bg-orange-200', 'text-orange-800');
btn.classList.add('bg-gray-100', 'text-gray-700');
});
const activeBtn = document.querySelector(`[data-status="${status}"]`);
if (activeBtn) {
activeBtn.classList.remove('bg-gray-100', 'text-gray-700');
activeBtn.classList.add('bg-orange-200', 'text-orange-800');
}
}
}
// Initialize Task Agent when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
console.log('Initializing Task Agent...');
window.taskAgent = new TaskAgent();
// Make functions globally available for onclick handlers
window.executeTaskCommand = () => taskAgent.executeTaskCommand();
window.setTaskCommand = (cmd) => taskAgent.setTaskCommand(cmd);
window.createTask = () => taskAgent.createTask();
window.prioritizeTasks = () => taskAgent.prioritizeTasks();
window.bulkUpdate = () => taskAgent.bulkUpdate();
window.generateReport = () => taskAgent.generateReport();
window.closeAIModal = () => taskAgent.hideAIModal();
console.log('✅ Task Agent initialized successfully');
});
// Global helper functions
function goHome() {
window.location.href = 'index.html';
}
console.log('✅ Task Agent JS loaded successfully');

File diff suppressed because it is too large Load Diff

634
assets/js/utils.js Normal file
View File

@ -0,0 +1,634 @@
/**
* Universal Utilities for All AI Agent Pages
* Compatible with: Task Agent, Email Agent, Calendar Agent, Trade Intelligence
* Enhanced with offline handling, performance optimizations, and better error handling
*/
// Create Utils object if it doesn't exist
window.Utils = window.Utils || {};
// Time utilities
Utils.time = {
updateLastUpdated: function(elementId) {
const element = document.getElementById(elementId);
if (element) {
element.textContent = new Date().toLocaleTimeString();
}
},
formatTimestamp: function(date) {
if (!date) return 'Unknown';
try {
return new Date(date).toLocaleString();
} catch (e) {
return date;
}
}
};
// Form utilities
Utils.form = {
setInputValue: function(elementId, value) {
const element = document.getElementById(elementId);
if (element) {
element.value = value;
}
},
getInputValue: function(elementId) {
const element = document.getElementById(elementId);
return element ? element.value : '';
},
clearInput: function(elementId) {
const element = document.getElementById(elementId);
if (element) {
element.value = '';
}
}
};
// Button utilities
Utils.button = {
setLoading: function(elementId, text, iconClass) {
const element = document.getElementById(elementId);
if (element) {
element.innerHTML = `<i class="${iconClass}"></i> ${text}`;
element.disabled = true;
}
},
restore: function(elementId, text, iconClass) {
const element = document.getElementById(elementId);
if (element) {
element.innerHTML = `<i class="${iconClass}"></i> <span>${text}</span>`;
element.disabled = false;
}
}
};
// Event utilities
Utils.events = {
onEnterKey: function(elementId, callback) {
const element = document.getElementById(elementId);
if (element) {
element.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
callback();
}
});
}
}
};
// Stats utilities
Utils.stats = {
increment: function(statName) {
console.log('Incrementing stat:', statName);
const element = document.getElementById(statName);
if (element) {
const currentValue = parseInt(element.textContent) || 0;
element.textContent = currentValue + 1;
}
},
update: function(statName, value) {
const element = document.getElementById(statName);
if (element) {
element.textContent = value;
}
}
};
// Enhanced API utilities with offline handling
Utils.api = {
// Enhanced request with better offline detection
async request(url, options = {}) {
try {
console.log('🔄 Making API request to:', url);
// Check if browser is online
if (!navigator.onLine) {
throw new Error('OFFLINE');
}
const defaultOptions = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
// Add timeout to detect slow/failed connections
signal: AbortSignal.timeout(30000) // 30 second timeout
};
const response = await fetch(url, { ...defaultOptions, ...options });
if (!response.ok) {
throw new Error(`HTTP_${response.status}`);
}
const data = await response.json();
console.log('✅ API request successful');
return data;
} catch (error) {
console.error('❌ API Request failed:', error);
// Handle different types of errors with user-friendly messages
let userMessage = '';
let errorType = 'error';
if (error.message === 'OFFLINE' || !navigator.onLine) {
userMessage = '📱 You appear to be offline. Please check your internet connection and try again.';
errorType = 'warning';
} else if (error.name === 'TimeoutError' || error.message.includes('timeout')) {
userMessage = '⏱️ Request timed out. The server may be busy. Please try again.';
errorType = 'warning';
} else if (error.message.includes('Failed to fetch')) {
userMessage = '🌐 Unable to connect to server. Please check your connection and try again.';
errorType = 'warning';
} else if (error.message.includes('HTTP_5')) {
userMessage = '🔧 Server error (5xx). Please try again in a few moments.';
errorType = 'error';
} else if (error.message.includes('HTTP_4')) {
userMessage = '⚠️ Request error (4xx). Please check your input and try again.';
errorType = 'warning';
} else {
userMessage = '❌ Something went wrong. Please try again.';
errorType = 'error';
}
// Show user-friendly toast
Utils.toast.show(userMessage, errorType);
// Re-throw for handling by calling function
throw error;
}
},
// Quick method for GET requests with parameters
async get(url, params = {}) {
const urlWithParams = new URL(url);
Object.keys(params).forEach(key => {
if (params[key] !== undefined && params[key] !== null) {
urlWithParams.searchParams.append(key, params[key]);
}
});
return this.request(urlWithParams.toString());
},
// Test connection method
async testConnection() {
try {
await fetch('https://httpbin.org/status/200', {
method: 'HEAD',
signal: AbortSignal.timeout(5000)
});
return true;
} catch (error) {
return false;
}
}
};
// Network status detection
Utils.network = {
isOnline: navigator.onLine,
init() {
// Listen for online/offline events
window.addEventListener('online', () => {
this.isOnline = true;
Utils.toast.success('🌐 Connection restored!');
console.log('✅ Back online');
});
window.addEventListener('offline', () => {
this.isOnline = false;
Utils.toast.warning('📱 You are now offline. Some features may not work.');
console.log('⚠️ Gone offline');
});
},
// Check if we should even attempt API calls
canMakeRequests() {
if (!this.isOnline) {
Utils.toast.warning('📱 No internet connection. Please check your network.');
return false;
}
return true;
}
};
// Performance utilities
Utils.performance = {
// Debounce function for search inputs (prevents too many API calls)
debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
},
// Throttle function for scroll events
throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
},
// Optimize search inputs automatically
optimizeSearchInputs() {
const searchInputs = document.querySelectorAll('#query, #searchQuery, #taskSearchInput, #taskCommand, #calendarCommand');
searchInputs.forEach(input => {
if (input) {
// Remove any existing event listeners to avoid duplicates
const newInput = input.cloneNode(true);
input.parentNode.replaceChild(newInput, input);
// Add optimized event listener
newInput.addEventListener('input', this.debounce((e) => {
// Only trigger if user has typed something meaningful
if (e.target.value.length >= 2) {
console.log('Optimized search triggered for:', e.target.value);
}
}, 300));
}
});
}
};
// Modal utilities
Utils.modal = {
showAI: function(content) {
const modal = document.getElementById('aiModal');
const responseDiv = document.getElementById('aiResponse');
if (modal && responseDiv) {
responseDiv.innerHTML = content;
modal.classList.remove('hidden');
}
},
hideAI: function() {
const modal = document.getElementById('aiModal');
if (modal) {
modal.classList.add('hidden');
}
},
show: function(modalId, content) {
const modal = document.getElementById(modalId);
if (modal) {
if (content) {
const contentDiv = modal.querySelector('.modal-content') ||
modal.querySelector('#aiResponse') ||
modal.querySelector('.p-6:last-child');
if (contentDiv) {
contentDiv.innerHTML = content;
}
}
modal.classList.remove('hidden');
}
},
hide: function(modalId) {
const modal = document.getElementById(modalId);
if (modal) {
modal.classList.add('hidden');
}
}
};
// Enhanced toast notifications
Utils.toast = {
show: function(message, type = 'info') {
// Remove existing toasts
document.querySelectorAll('.utils-toast').forEach(toast => toast.remove());
const toast = document.createElement('div');
toast.className = 'utils-toast fixed top-4 right-4 z-50 max-w-sm transform transition-all duration-300 translate-x-full';
const styles = {
success: { bg: 'bg-green-500', icon: 'fas fa-check-circle' },
error: { bg: 'bg-red-500', icon: 'fas fa-exclamation-circle' },
warning: { bg: 'bg-yellow-500', icon: 'fas fa-exclamation-triangle' },
info: { bg: 'bg-blue-500', icon: 'fas fa-info-circle' }
};
const style = styles[type] || styles.info;
toast.innerHTML = `
<div class="${style.bg} text-white px-4 py-3 rounded-lg shadow-lg flex items-center gap-3">
<i class="${style.icon}"></i>
<span class="text-sm font-medium flex-1">${message}</span>
<button onclick="this.parentElement.parentElement.remove()" class="text-white hover:text-gray-200">
<i class="fas fa-times text-xs"></i>
</button>
</div>
`;
document.body.appendChild(toast);
// Animate in
requestAnimationFrame(() => {
toast.classList.remove('translate-x-full');
});
// Auto remove after 5 seconds
setTimeout(() => {
if (toast.parentElement) {
toast.classList.add('translate-x-full');
setTimeout(() => toast.remove(), 300);
}
}, 5000);
},
success: function(message) { this.show(message, 'success'); },
error: function(message) { this.show(message, 'error'); },
warning: function(message) { this.show(message, 'warning'); },
info: function(message) { this.show(message, 'info'); }
};
// Navigation utilities
Utils.navigation = {
goHome: function() {
window.location.href = 'index.html';
},
goToPage: function(page) {
window.location.href = page;
}
};
// Validation utilities
Utils.validation = {
isEmail: function(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
},
isEmpty: function(value) {
return !value || value.toString().trim().length === 0;
},
isValidDate: function(date) {
return date instanceof Date && !isNaN(date);
}
};
// Loading utilities
Utils.loading = {
show: function(elementId, message = 'Loading...') {
const element = document.getElementById(elementId);
if (element) {
element.classList.remove('hidden');
const messageEl = element.querySelector('.loading-message');
if (messageEl) {
messageEl.textContent = message;
}
}
},
hide: function(elementId) {
const element = document.getElementById(elementId);
if (element) {
element.classList.add('hidden');
}
},
toggle: function(elementId, show, message) {
if (show) {
this.show(elementId, message);
} else {
this.hide(elementId);
}
}
};
// Storage utilities (for local data)
Utils.storage = {
set: function(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (e) {
console.warn('localStorage not available, using memory storage');
this._memoryStorage = this._memoryStorage || {};
this._memoryStorage[key] = value;
}
},
get: function(key, defaultValue = null) {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : defaultValue;
} catch (e) {
this._memoryStorage = this._memoryStorage || {};
return this._memoryStorage[key] || defaultValue;
}
},
remove: function(key) {
try {
localStorage.removeItem(key);
} catch (e) {
if (this._memoryStorage) {
delete this._memoryStorage[key];
}
}
}
};
// Formatting utilities
Utils.format = {
currency: function(amount, currency = 'USD') {
try {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency
}).format(amount);
} catch (e) {
return `$${amount}`;
}
},
number: function(num, decimals = 0) {
return Number(num).toFixed(decimals);
},
date: function(date, format = 'short') {
try {
return new Date(date).toLocaleDateString('en-US', {
dateStyle: format
});
} catch (e) {
return date;
}
},
time: function(date) {
try {
return new Date(date).toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit'
});
} catch (e) {
return date;
}
}
};
// Searchable dropdown utility for countries
Utils.dropdown = {
createSearchableCountryDropdown: function(selectElement, countries) {
if (!selectElement) return;
const container = selectElement.parentNode;
const wrapper = document.createElement('div');
wrapper.className = 'relative';
// Create input field
const input = document.createElement('input');
input.type = 'text';
input.placeholder = 'Type to search countries...';
input.className = selectElement.className;
input.id = selectElement.id + '_input';
// Create dropdown
const dropdown = document.createElement('div');
dropdown.className = 'absolute z-10 w-full bg-white border border-gray-300 rounded-lg shadow-lg max-h-48 overflow-y-auto hidden';
dropdown.style.top = '100%';
// Create options
const createOptions = (filteredCountries) => {
dropdown.innerHTML = '';
if (filteredCountries.length === 0) {
dropdown.innerHTML = '<div class="p-3 text-gray-500 text-sm">No countries found</div>';
return;
}
filteredCountries.forEach(country => {
const option = document.createElement('div');
option.className = 'p-3 hover:bg-gray-100 cursor-pointer text-sm border-b border-gray-100 last:border-b-0';
option.textContent = country;
option.addEventListener('click', () => {
input.value = country;
selectElement.value = country;
dropdown.classList.add('hidden');
// Trigger change event
const event = new Event('change', { bubbles: true });
selectElement.dispatchEvent(event);
});
dropdown.appendChild(option);
});
};
// Initialize with all countries
createOptions(countries);
// Handle input changes
input.addEventListener('input', (e) => {
const query = e.target.value.toLowerCase();
const filtered = countries.filter(country =>
country.toLowerCase().includes(query)
);
createOptions(filtered);
dropdown.classList.remove('hidden');
});
// Show dropdown on focus
input.addEventListener('focus', () => {
dropdown.classList.remove('hidden');
});
// Hide dropdown when clicking outside
document.addEventListener('click', (e) => {
if (!wrapper.contains(e.target)) {
dropdown.classList.add('hidden');
}
});
// Build wrapper
wrapper.appendChild(input);
wrapper.appendChild(dropdown);
// Replace original select
container.replaceChild(wrapper, selectElement);
// Keep original select hidden for form submission
selectElement.style.display = 'none';
wrapper.appendChild(selectElement);
return wrapper;
}
};
// Global convenience functions for backward compatibility
function goHome() {
Utils.navigation.goHome();
}
function updateLastUpdated(elementId) {
Utils.time.updateLastUpdated(elementId);
}
function showToast(message, type = 'info') {
Utils.toast.show(message, type);
}
// Global error handler
window.addEventListener('error', function(event) {
console.error('Global error caught:', event.error);
Utils.toast.error('An unexpected error occurred. Please refresh the page.');
});
// Global unhandled promise rejection handler
window.addEventListener('unhandledrejection', function(event) {
console.error('Unhandled promise rejection:', event.reason);
Utils.toast.error('A network or processing error occurred.');
});
// Export for global use
window.goHome = goHome;
window.updateLastUpdated = updateLastUpdated;
window.showToast = showToast;
// Initialize everything when DOM loads
document.addEventListener('DOMContentLoaded', function() {
// Initialize network detection
Utils.network.init();
// Apply performance optimizations
setTimeout(() => {
Utils.performance.optimizeSearchInputs();
console.log('✅ Performance optimizations applied');
}, 1000);
// Update any "Last updated" timestamps on the page
const timestampElements = document.querySelectorAll('[id*="last"], [id*="Last"], [id*="update"], [id*="Update"], [id*="sync"], [id*="Sync"]');
timestampElements.forEach(element => {
if (element.id) {
Utils.time.updateLastUpdated(element.id);
}
});
console.log('✅ Universal Utils.js loaded and initialized');
});
console.log('✅ Universal Utils.js loaded successfully');

400
calendar-agent.html Normal file
View File

@ -0,0 +1,400 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calendar Agent - AI Calendar Management</title>
<!-- External Dependencies -->
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<!-- Your Custom Files -->
<link rel="stylesheet" href="assets/css/styles.css">
</head>
<body>
<!-- Navigation Header -->
<nav class="bg-white shadow-sm border-b sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center py-4">
<div class="flex items-center gap-3">
<button onclick="goHome()" class="w-10 h-10 bg-indigo-100 rounded-lg flex items-center justify-center hover:bg-indigo-200 transition-colors">
<i class="fas fa-home text-indigo-600"></i>
</button>
<div class="w-10 h-10 bg-green-600 rounded-xl flex items-center justify-center shadow-lg">
<i class="fas fa-calendar-alt text-white text-lg"></i>
</div>
<div>
<h1 class="text-lg font-bold text-gray-800">Calendar Agent</h1>
<p class="text-sm text-gray-500">AI Calendar Management</p>
</div>
</div>
<div class="hidden md:flex items-center gap-6">
<div class="text-right">
<p class="text-sm text-gray-500">Last sync</p>
<p class="font-semibold text-gray-800" id="lastSync">Just now</p>
</div>
<div class="flex items-center gap-2">
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
<span class="text-sm text-green-600 font-medium">Synced</span>
</div>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 bg-gray-50 min-h-screen">
<!-- Header Section -->
<div class="text-center mb-8">
<h1 class="text-3xl lg:text-4xl font-bold text-gray-800 mb-4">AI Calendar Management</h1>
<p class="text-xl text-gray-600 max-w-2xl mx-auto">
Smart scheduling, optimal time finding, and intelligent meeting management powered by AI.
</p>
</div>
<!-- Calendar Command Center -->
<div class="bg-white rounded-2xl p-6 mb-8 shadow-lg border border-gray-200">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-green-600 rounded-lg flex items-center justify-center">
<i class="fas fa-brain text-white"></i>
</div>
<h2 class="text-xl font-bold text-gray-800">Calendar AI Command</h2>
</div>
<div class="flex flex-col sm:flex-row gap-3">
<div class="flex-1">
<input
id="calendarCommand"
type="text"
placeholder="Ask AI: 'Schedule team meeting tomorrow 2PM', 'Find free time this week', 'Reschedule conflicting meetings'"
class="w-full px-4 py-3 rounded-xl border border-gray-300 bg-white text-gray-800 placeholder-gray-500 focus:border-green-400 focus:ring-2 focus:ring-green-400/50 outline-none transition-all"
/>
</div>
<button
onclick="executeCalendarCommand()"
class="w-full sm:w-auto bg-green-600 hover:bg-green-700 text-white px-6 py-3 rounded-xl font-semibold transition-all flex items-center justify-center gap-2 min-w-[120px]"
id="calendarAiBtn"
>
<i class="fas fa-robot"></i>
<span>Execute</span>
</button>
</div>
<!-- Quick Commands -->
<div class="mt-4 flex flex-wrap gap-2">
<span class="text-sm text-gray-500 mr-2">Quick commands:</span>
<button onclick="setCalendarCommand('Show today\'s schedule')" class="text-xs bg-green-100 hover:bg-green-200 text-green-700 px-3 py-1 rounded-full transition-colors">
Today's Schedule
</button>
<button onclick="setCalendarCommand('Find free time this week')" class="text-xs bg-green-100 hover:bg-green-200 text-green-700 px-3 py-1 rounded-full transition-colors">
Find Free Time
</button>
<button onclick="setCalendarCommand('Schedule team meeting')" class="text-xs bg-green-100 hover:bg-green-200 text-green-700 px-3 py-1 rounded-full transition-colors">
Schedule Meeting
</button>
</div>
</div>
<!-- Stats Dashboard -->
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-calendar-day text-blue-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="todayMeetings">5</div>
<div class="text-sm text-gray-500">Today</div>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-orange-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-clock text-orange-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="nextMeeting">2:30 PM</div>
<div class="text-sm text-gray-500">Next</div>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-check-circle text-green-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="freeSlots">3</div>
<div class="text-sm text-gray-500">Free Slots</div>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-robot text-purple-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="aiScheduled">12</div>
<div class="text-sm text-gray-500">AI Scheduled</div>
</div>
</div>
</div>
<!-- Main Calendar Interface -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Calendar View & Today's Schedule -->
<div class="lg:col-span-2 space-y-6">
<!-- Mini Calendar -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-bold text-gray-800">December 2024</h3>
<div class="flex items-center gap-2">
<button class="p-2 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors">
<i class="fas fa-chevron-left text-gray-600"></i>
</button>
<button class="p-2 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors">
<i class="fas fa-chevron-right text-gray-600"></i>
</button>
</div>
</div>
<div class="grid grid-cols-7 gap-1 mb-2">
<div class="text-center text-sm font-medium text-gray-500 py-2">Sun</div>
<div class="text-center text-sm font-medium text-gray-500 py-2">Mon</div>
<div class="text-center text-sm font-medium text-gray-500 py-2">Tue</div>
<div class="text-center text-sm font-medium text-gray-500 py-2">Wed</div>
<div class="text-center text-sm font-medium text-gray-500 py-2">Thu</div>
<div class="text-center text-sm font-medium text-gray-500 py-2">Fri</div>
<div class="text-center text-sm font-medium text-gray-500 py-2">Sat</div>
</div>
<div class="grid grid-cols-7 gap-1">
<!-- Calendar days -->
<div class="calendar-day rounded-lg p-2 text-center text-gray-500 bg-gray-50">1</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 today bg-blue-100 border-2 border-blue-500">2</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 has-events bg-green-100">3</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 hover:bg-gray-100">4</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 has-events bg-green-100">5</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 hover:bg-gray-100">6</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 hover:bg-gray-100">7</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 hover:bg-gray-100">8</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 has-events bg-green-100">9</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 hover:bg-gray-100">10</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 hover:bg-gray-100">11</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 has-events bg-green-100">12</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 hover:bg-gray-100">13</div>
<div class="calendar-day rounded-lg p-2 text-center text-gray-800 hover:bg-gray-100">14</div>
</div>
</div>
<!-- Today's Schedule -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-bold text-gray-800">Today's Schedule</h3>
<span class="text-sm text-gray-500">Monday, Dec 2, 2024</span>
</div>
<div class="space-y-4 custom-scrollbar max-h-96 overflow-y-auto" id="scheduleList">
<!-- Current Meeting -->
<div class="meeting-current p-4 rounded-lg border border-red-200">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center gap-2">
<div class="w-3 h-3 bg-red-500 rounded-full animate-pulse"></div>
<span class="font-semibold text-gray-800">Team Standup</span>
<span class="px-2 py-1 bg-red-100 text-red-700 text-xs rounded-full">Live</span>
</div>
<span class="text-sm text-gray-500">9:00 - 9:30 AM</span>
</div>
<p class="text-sm text-gray-600 mb-2">Daily sync with development team</p>
<div class="flex items-center gap-4 text-xs text-gray-500">
<span><i class="fas fa-users mr-1"></i>8 attendees</span>
<span><i class="fas fa-video mr-1"></i>Zoom Meeting</span>
</div>
</div>
<!-- Upcoming Meetings -->
<div class="meeting-upcoming p-4 rounded-lg border border-blue-200">
<div class="flex items-center justify-between mb-2">
<span class="font-semibold text-gray-800">Client Presentation</span>
<span class="text-sm text-gray-500">2:30 - 3:30 PM</span>
</div>
<p class="text-sm text-gray-600 mb-2">Q4 strategy review with ABC Corp</p>
<div class="flex items-center gap-4 text-xs text-gray-500 mb-2">
<span><i class="fas fa-users mr-1"></i>5 attendees</span>
<span><i class="fas fa-map-marker-alt mr-1"></i>Conference Room A</span>
</div>
<div class="flex gap-2">
<button class="px-3 py-1 bg-blue-600 text-white text-xs rounded-lg hover:bg-blue-700 transition-colors">Join</button>
<button class="px-3 py-1 bg-gray-100 text-gray-700 text-xs rounded-lg hover:bg-gray-200 transition-colors">Reschedule</button>
</div>
</div>
<div class="meeting-upcoming p-4 rounded-lg border border-blue-200">
<div class="flex items-center justify-between mb-2">
<span class="font-semibold text-gray-800">Budget Review</span>
<span class="text-sm text-gray-500">4:00 - 5:00 PM</span>
</div>
<p class="text-sm text-gray-600 mb-2">Monthly financial planning session</p>
<div class="flex items-center gap-4 text-xs text-gray-500">
<span><i class="fas fa-users mr-1"></i>3 attendees</span>
<span><i class="fas fa-video mr-1"></i>Teams Meeting</span>
</div>
</div>
<!-- Free Time Block -->
<div class="p-4 rounded-lg border-2 border-dashed border-green-400 bg-green-50">
<div class="flex items-center justify-between mb-2">
<span class="font-semibold text-green-700">Focus Time</span>
<span class="text-sm text-green-600">10:00 - 12:00 PM</span>
</div>
<p class="text-sm text-green-600">2-hour block reserved for deep work</p>
<div class="flex items-center gap-2 text-xs text-green-600 mt-2">
<i class="fas fa-brain mr-1"></i>AI Protected Time
</div>
</div>
</div>
</div>
</div>
<!-- AI Actions Panel -->
<div class="space-y-6">
<!-- Quick Actions -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">Quick Actions</h3>
<div class="space-y-3">
<button onclick="scheduleMeeting()" class="w-full p-3 bg-green-600 hover:bg-green-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-plus"></i>
<span>Schedule Meeting</span>
</button>
<button onclick="findFreeTime()" class="w-full p-3 bg-blue-600 hover:bg-blue-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-search"></i>
<span>Find Free Time</span>
</button>
<button onclick="blockFocusTime()" class="w-full p-3 bg-purple-600 hover:bg-purple-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-brain"></i>
<span>Block Focus Time</span>
</button>
<button onclick="optimizeSchedule()" class="w-full p-3 bg-orange-600 hover:bg-orange-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-magic"></i>
<span>Optimize Schedule</span>
</button>
</div>
</div>
<!-- Time Analysis -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">Time Analysis</h3>
<div class="space-y-4">
<div class="bg-blue-50 rounded-lg p-3 border border-blue-200">
<h4 class="font-medium text-blue-700 mb-1">Meeting Load</h4>
<div class="w-full bg-gray-200 rounded-full h-2 mb-1">
<div class="bg-blue-500 h-2 rounded-full" style="width: 65%"></div>
</div>
<p class="text-sm text-blue-600">65% of day in meetings</p>
</div>
<div class="bg-green-50 rounded-lg p-3 border border-green-200">
<h4 class="font-medium text-green-700 mb-1">Focus Time</h4>
<div class="w-full bg-gray-200 rounded-full h-2 mb-1">
<div class="bg-green-500 h-2 rounded-full" style="width: 35%"></div>
</div>
<p class="text-sm text-green-600">2.8 hours available</p>
</div>
<div class="bg-orange-50 rounded-lg p-3 border border-orange-200">
<h4 class="font-medium text-orange-700 mb-1">Efficiency Score</h4>
<p class="text-2xl font-bold text-orange-600">87%</p>
<p class="text-sm text-orange-600">Above average</p>
</div>
</div>
</div>
<!-- Upcoming Conflicts -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">AI Insights</h3>
<div class="space-y-3">
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-3">
<h4 class="font-medium text-yellow-700 mb-1">⚠️ Potential Conflict</h4>
<p class="text-sm text-yellow-600">Tomorrow 3PM: Two meetings scheduled</p>
</div>
<div class="bg-blue-50 border border-blue-200 rounded-lg p-3">
<h4 class="font-medium text-blue-700 mb-1">💡 Suggestion</h4>
<p class="text-sm text-blue-600">Move standup to 8:30 AM for better flow</p>
</div>
<div class="bg-green-50 border border-green-200 rounded-lg p-3">
<h4 class="font-medium text-green-700 mb-1">✨ Opportunity</h4>
<p class="text-sm text-green-600">Friday 2-4 PM available for deep work</p>
</div>
</div>
</div>
<!-- Recent AI Actions -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">Recent AI Actions</h3>
<div class="space-y-3 custom-scrollbar max-h-48 overflow-y-auto">
<div class="flex items-start gap-3 p-2 bg-gray-50 rounded-lg">
<div class="w-6 h-6 bg-green-100 rounded flex items-center justify-center flex-shrink-0 mt-1">
<i class="fas fa-calendar-plus text-green-600 text-xs"></i>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-800">Scheduled team meeting</p>
<p class="text-xs text-gray-500">3 minutes ago</p>
</div>
</div>
<div class="flex items-start gap-3 p-2 bg-gray-50 rounded-lg">
<div class="w-6 h-6 bg-blue-100 rounded flex items-center justify-center flex-shrink-0 mt-1">
<i class="fas fa-search text-blue-600 text-xs"></i>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-800">Found optimal meeting time</p>
<p class="text-xs text-gray-500">8 minutes ago</p>
</div>
</div>
<div class="flex items-start gap-3 p-2 bg-gray-50 rounded-lg">
<div class="w-6 h-6 bg-purple-100 rounded flex items-center justify-center flex-shrink-0 mt-1">
<i class="fas fa-brain text-purple-600 text-xs"></i>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-800">Protected focus time</p>
<p class="text-xs text-gray-500">15 minutes ago</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- AI Response Modal -->
<div id="aiModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl max-w-2xl w-full max-h-[80vh] overflow-hidden">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center">
<i class="fas fa-robot text-green-600"></i>
</div>
<h3 class="text-lg font-bold text-gray-800">Calendar AI Response</h3>
</div>
<button onclick="closeAIModal()" class="text-gray-400 hover:text-gray-600">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="p-6 overflow-y-auto custom-scrollbar" id="aiResponse">
<!-- AI response content will be loaded here -->
</div>
</div>
</div>
<!-- Scripts at the end -->
<script src="assets/js/utils.js"></script>
<script src="assets/js/navigation.js"></script>
<script src="assets/js/calendar-agent.js"></script>
</body>
</html>

253
email-agent.html Normal file
View File

@ -0,0 +1,253 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email Agent - AI Email Management</title>
<!-- External Dependencies -->
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<!-- Your Custom Files -->
<link rel="stylesheet" href="assets/css/styles.css">
</head>
<body>
<!-- Navigation Header -->
<nav class="bg-white shadow-sm border-b sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center py-4">
<div class="flex items-center gap-3">
<button onclick="goHome()" class="w-10 h-10 bg-indigo-100 rounded-lg flex items-center justify-center hover:bg-indigo-200 transition-colors">
<i class="fas fa-home text-indigo-600"></i>
</button>
<div class="w-10 h-10 bg-blue-600 rounded-xl flex items-center justify-center shadow-lg">
<i class="fas fa-envelope text-white text-lg"></i>
</div>
<div>
<h1 class="text-lg font-bold text-gray-800">Email Agent</h1>
<p class="text-sm text-gray-500">AI Email Management</p>
</div>
</div>
<div class="hidden md:flex items-center gap-6">
<div class="text-right">
<p class="text-sm text-gray-500">Last sync</p>
<p class="font-semibold text-gray-800" id="lastSync">Just now</p>
</div>
<div class="flex items-center gap-2">
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
<span class="text-sm text-green-600 font-medium">Online</span>
</div>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 bg-gray-50 min-h-screen">
<!-- Header Section -->
<div class="text-center mb-8">
<h1 class="text-3xl lg:text-4xl font-bold text-gray-800 mb-4">AI Email Management</h1>
</div>
<!-- Email Search & Filter -->
<div class="bg-white rounded-2xl p-6 mb-8 shadow-lg border border-gray-200">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-blue-600 rounded-lg flex items-center justify-center">
<i class="fas fa-search text-white"></i>
</div>
<h2 class="text-xl font-bold text-gray-800">Email Summary Search</h2>
</div>
<div class="flex flex-col sm:flex-row gap-3 mb-4">
<div class="flex-1">
<input
id="searchQuery"
type="text"
placeholder="Search emails by subject, sender, or content..."
class="w-full px-4 py-3 rounded-xl border border-gray-300 bg-white text-gray-800 placeholder-gray-500 focus:border-blue-400 focus:ring-2 focus:ring-blue-400/50 outline-none transition-all"
/>
</div>
<button
onclick="searchEmails()"
class="w-full sm:w-auto bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-xl font-semibold transition-all flex items-center justify-center gap-2 min-w-[120px]"
id="searchBtn"
>
<i class="fas fa-search"></i>
<span>Search</span>
</button>
</div>
<!-- Filter Buttons -->
<div class="flex flex-wrap gap-2">
<span class="text-sm text-gray-500 mr-2">Filter by:</span>
<button onclick="filterEmails('all')" class="filter-btn active text-xs bg-blue-100 hover:bg-blue-200 text-blue-700 px-3 py-1 rounded-full transition-colors" data-filter="all">
All Items
</button>
<button onclick="filterEmails('email')" class="filter-btn text-xs bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-1 rounded-full transition-colors" data-filter="email">
<i class="fas fa-envelope mr-1"></i>Emails
</button>
<button onclick="filterEmails('pdf')" class="filter-btn text-xs bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-1 rounded-full transition-colors" data-filter="pdf">
<i class="fas fa-file-pdf mr-1"></i>PDFs
</button>
<button onclick="filterEmails('image')" class="filter-btn text-xs bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-1 rounded-full transition-colors" data-filter="image">
<i class="fas fa-image mr-1"></i>Images
</button>
</div>
</div>
<!-- Stats Dashboard -->
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-envelope text-blue-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="totalCount">0</div>
<div class="text-sm text-gray-500">Total Items</div>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-orange-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-exclamation-triangle text-orange-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="priorityCount">0</div>
<div class="text-sm text-gray-500">High Priority</div>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-check-circle text-green-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="processedCount">0</div>
<div class="text-sm text-gray-500">Processed</div>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-robot text-purple-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="aiActionsCount">0</div>
<div class="text-sm text-gray-500">AI Analyzed</div>
</div>
</div>
</div>
<!-- Main Email Interface -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Email List -->
<div class="lg:col-span-2">
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-bold text-gray-800">Summarised Emails</h3>
<div class="flex items-center gap-2">
<button onclick="refreshEmails()" class="p-2 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" title="Refresh">
<i class="fas fa-sync-alt text-gray-600"></i>
</button>
<button onclick="exportEmails()" class="text-sm bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-2 rounded-lg transition-colors flex items-center gap-2" title="Export">
<i class="fas fa-download text-xs"></i>
Export
</button>
</div>
</div>
<!-- Loading State -->
<div id="loadingState" class="hidden">
<div class="space-y-3">
<div class="loading-skeleton rounded-lg p-4 h-20"></div>
<div class="loading-skeleton rounded-lg p-4 h-20"></div>
<div class="loading-skeleton rounded-lg p-4 h-20"></div>
</div>
</div>
<!-- Email List Container -->
<div id="emailList" class="space-y-3 custom-scrollbar max-h-96 overflow-y-auto">
<!-- Emails will be loaded here -->
</div>
<!-- Empty State -->
<div id="emptyState" class="text-center py-12">
<div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
<i class="fas fa-inbox text-gray-400 text-2xl"></i>
</div>
<h3 class="text-lg font-semibold text-gray-600 mb-2">No emails found</h3>
<p class="text-gray-500">Your processed emails will appear here</p>
<button onclick="loadEmails()" class="mt-4 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors">
Load Emails
</button>
</div>
</div>
</div>
<!-- AI Actions Panel -->
<div class="space-y-6">
<!-- Quick Actions -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">Quick Actions</h3>
<div class="space-y-3">
<button onclick="loadEmails()" class="w-full p-3 bg-blue-600 hover:bg-blue-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-refresh"></i>
<span>Refresh Emails</span>
</button>
<button onclick="filterEmails('email')" class="w-full p-3 bg-green-600 hover:bg-green-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-envelope"></i>
<span>Show Emails Only</span>
</button>
<button onclick="filterEmails('pdf')" class="w-full p-3 bg-red-600 hover:bg-red-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-file-pdf"></i>
<span>Show PDFs Only</span>
</button>
<button onclick="filterEmails('image')" class="w-full p-3 bg-purple-600 hover:bg-purple-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-image"></i>
<span>Show Images Only</span>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Email Detail Modal -->
<div id="emailModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl max-w-4xl w-full max-h-[80vh] overflow-hidden">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center">
<i class="fas fa-envelope text-blue-600"></i>
</div>
<h3 class="text-lg font-bold text-gray-800">Email Details</h3>
</div>
<button onclick="closeEmailModal()" class="text-gray-400 hover:text-gray-600">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="p-6 overflow-y-auto custom-scrollbar" id="emailContent">
<!-- Email details will be loaded here -->
</div>
</div>
</div>
<!-- Scripts at the end -->
<script src="assets/js/utils.js"></script>
<script src="assets/js/navigation.js"></script>
<script src="assets/js/email-agent.js"></script>
</body>
</html>

250
index.html Normal file
View File

@ -0,0 +1,250 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Victor AI - AI Services Hub</title>
<!-- External Dependencies -->
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<!-- Your Custom Files -->
<link rel="stylesheet" href="assets/css/styles.css">
</head>
<body>
<!-- Header -->
<nav class="bg-white/10 backdrop-blur-md border-b border-white/20 sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center py-4">
<div class="flex items-center gap-3">
<div class="w-[180px] h-12 flex items-center">
<img src="/logo.png" alt="Logo" class="w-full h-full object-contain" />
</div>
</div>
<div class="hidden md:flex items-center gap-6">
<div class="text-right">
<p class="text-sm text-gray-200">System Status</p>
<div class="flex items-center gap-2">
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
<span class="text-sm font-medium text-white">All Systems Online</span>
</div>
</div>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 lg:py-16">
<!-- Hero Section -->
<div class="text-center mb-16">
<div class="float-animation mb-8">
<div class="w-24 h-24 bg-indigo-600 rounded-3xl flex items-center justify-center mx-auto shadow-2xl pulse-glow">
<i class="fas fa-rocket text-white text-4xl"></i>
</div>
</div>
<h1 class="text-4xl lg:text-6xl font-bold text-white mb-6">
Welcome to <span class="text-indigo-200">Victor AI</span>
</h1>
<!-- Services Grid -->
<div class="service-grid grid gap-8 lg:gap-12">
<!-- AI Agents Section -->
<div class="col-span-full">
<h2 class="text-2xl font-bold text-white text-center mb-8">AI Agents</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<!-- Trade Intelligence Agent -->
<div class="service-card rounded-2xl p-6 group cursor-pointer shadow-lg" onclick="navigateToService('trade-intelligence')">
<div class="text-center">
<div class="w-12 h-12 bg-blue-600 rounded-xl flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform shadow-lg">
<i class="fas fa-ship text-white text-xl"></i>
</div>
<h3 class="text-lg font-bold text-gray-800 mb-2">Trade Intelligence</h3>
<p class="text-gray-600 text-sm mb-4">Find exporters, importers, and trade data worldwide</p>
<div class="bg-blue-50 rounded-lg p-3 mb-4">
<div class="text-lg font-bold text-blue-600">50K+</div>
<div class="text-xs text-gray-600">Companies</div>
</div>
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg text-sm transition-colors">
Open Trade Intelligence
</button>
</div>
</div>
<!-- Email Agent -->
<div class="service-card rounded-2xl p-6 group cursor-pointer shadow-lg" onclick="navigateToService('email-agent')">
<div class="text-center">
<div class="w-12 h-12 bg-purple-600 rounded-xl flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform shadow-lg">
<i class="fas fa-envelope text-white text-xl"></i>
</div>
<h3 class="text-lg font-bold text-gray-800 mb-2">Email Agent</h3>
<p class="text-gray-600 text-sm mb-4">Smart email management and summarization</p>
<div class="bg-purple-50 rounded-lg p-3 mb-4">
<div class="text-lg font-bold text-purple-600">23</div>
<div class="text-xs text-gray-600">Unread Emails</div>
</div>
<button class="w-full bg-purple-600 hover:bg-purple-700 text-white py-2 px-4 rounded-lg text-sm transition-colors">
Open Email Agent
</button>
</div>
</div>
<!-- Calendar Agent -->
<div class="service-card rounded-2xl p-6 group cursor-pointer shadow-lg" onclick="navigateToService('calendar-agent')">
<div class="text-center">
<div class="w-12 h-12 bg-green-600 rounded-xl flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform shadow-lg">
<i class="fas fa-calendar text-white text-xl"></i>
</div>
<h3 class="text-lg font-bold text-gray-800 mb-2">Calendar Agent</h3>
<p class="text-gray-600 text-sm mb-4">Intelligent scheduling and meeting management</p>
<div class="bg-green-50 rounded-lg p-3 mb-4">
<div class="text-lg font-bold text-green-600">2:30 PM</div>
<div class="text-xs text-gray-600">Next Meeting</div>
</div>
<button class="w-full bg-green-600 hover:bg-green-700 text-white py-2 px-4 rounded-lg text-sm transition-colors">
Open Calendar
</button>
</div>
</div>
<!-- Task Agent -->
<div class="service-card rounded-2xl p-6 group cursor-pointer shadow-lg" onclick="navigateToService('task-agent')">
<div class="text-center">
<div class="w-12 h-12 bg-orange-600 rounded-xl flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform shadow-lg">
<i class="fas fa-tasks text-white text-xl"></i>
</div>
<h3 class="text-lg font-bold text-gray-800 mb-2">Task Agent</h3>
<p class="text-gray-600 text-sm mb-4">Smart task management and prioritization</p>
<div class="bg-orange-50 rounded-lg p-3 mb-4">
<div class="text-lg font-bold text-orange-600">4</div>
<div class="text-xs text-gray-600">Due Today</div>
</div>
<button class="w-full bg-orange-600 hover:bg-orange-700 text-white py-2 px-4 rounded-lg text-sm transition-colors">
Open Tasks
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Demo Modal -->
<div id="demoModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl max-w-4xl w-full max-h-[80vh] overflow-hidden">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<h3 class="text-lg font-bold text-gray-800">Victor AI Demo</h3>
<button onclick="closeDemoModal()" class="text-gray-400 hover:text-gray-600">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="p-6">
<div class="aspect-video bg-gray-100 rounded-lg flex items-center justify-center mb-4">
<div class="text-center">
<i class="fas fa-play-circle text-6xl text-indigo-600 mb-4"></i>
<p class="text-gray-600">Demo video would be embedded here</p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-blue-50 p-4 rounded-lg">
<h4 class="font-semibold text-blue-800 mb-2">🚢 Trade Intelligence</h4>
<p class="text-blue-600 text-sm">Search 50K+ companies across 150+ countries</p>
</div>
<div class="bg-purple-50 p-4 rounded-lg">
<h4 class="font-semibold text-purple-800 mb-2">📧 Email Management</h4>
<p class="text-purple-600 text-sm">AI-powered email summarization and organization</p>
</div>
<div class="bg-green-50 p-4 rounded-lg">
<h4 class="font-semibold text-green-800 mb-2">📅 Smart Calendar</h4>
<p class="text-green-600 text-sm">Intelligent meeting scheduling and optimization</p>
</div>
<div class="bg-orange-50 p-4 rounded-lg">
<h4 class="font-semibold text-orange-800 mb-2">✅ Task Management</h4>
<p class="text-orange-600 text-sm">AI-driven task prioritization and tracking</p>
</div>
</div>
</div>
</div>
</div>
<!-- Documentation Modal -->
<div id="docModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl max-w-2xl w-full max-h-[80vh] overflow-hidden">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<h3 class="text-lg font-bold text-gray-800">Documentation</h3>
<button onclick="closeDocModal()" class="text-gray-400 hover:text-gray-600">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="p-6 overflow-y-auto">
<div class="space-y-6">
<div>
<h4 class="text-lg font-semibold text-gray-800 mb-3">Getting Started</h4>
<ul class="space-y-2 text-gray-600">
<li>• Choose an AI agent from the main dashboard</li>
<li>• Use natural language commands to interact</li>
<li>• View results in real-time</li>
<li>• Export data as needed</li>
</ul>
</div>
<div>
<h4 class="text-lg font-semibold text-gray-800 mb-3">AI Agents Overview</h4>
<div class="space-y-3">
<div class="border-l-4 border-blue-500 pl-4">
<h5 class="font-medium text-blue-700">Trade Intelligence</h5>
<p class="text-sm text-gray-600">Search global trade data, find exporters and importers</p>
</div>
<div class="border-l-4 border-purple-500 pl-4">
<h5 class="font-medium text-purple-700">Email Agent</h5>
<p class="text-sm text-gray-600">Manage emails, create summaries, organize inbox</p>
</div>
<div class="border-l-4 border-green-500 pl-4">
<h5 class="font-medium text-green-700">Calendar Agent</h5>
<p class="text-sm text-gray-600">Schedule meetings, find optimal times, manage calendar</p>
</div>
<div class="border-l-4 border-orange-500 pl-4">
<h5 class="font-medium text-orange-700">Task Agent</h5>
<p class="text-sm text-gray-600">Prioritize tasks, track progress, manage workload</p>
</div>
</div>
</div>
<div>
<h4 class="text-lg font-semibold text-gray-800 mb-3">Support</h4>
<p class="text-gray-600 mb-3">Need help? Contact our support team:</p>
<div class="bg-gray-50 p-4 rounded-lg">
<p class="text-sm text-gray-700">📧 support@victorai.com</p>
<p class="text-sm text-gray-700">💬 Live chat available 24/7</p>
<p class="text-sm text-gray-700">📞 +1 (555) 123-4567</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Scripts at the end -->
<script src="assets/js/utils.js"></script>
<script src="assets/js/navigation.js"></script>
<script src="assets/js/index.js"></script>
</body>
</html>

BIN
logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
logo1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

477
task-agent.html Normal file
View File

@ -0,0 +1,477 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Task Agent - AI Task Management</title>
<!-- External Dependencies -->
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<!-- Your Custom Files -->
<link rel="stylesheet" href="assets/css/styles.css">
</head>
<body>
<!-- Navigation Header -->
<nav class="bg-white shadow-sm border-b sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center py-4">
<div class="flex items-center gap-3">
<button onclick="goHome()" class="w-10 h-10 bg-indigo-100 rounded-lg flex items-center justify-center hover:bg-indigo-200 transition-colors">
<i class="fas fa-home text-indigo-600"></i>
</button>
<div class="w-10 h-10 bg-orange-600 rounded-xl flex items-center justify-center shadow-lg">
<i class="fas fa-tasks text-white text-lg"></i>
</div>
<div>
<h1 class="text-lg font-bold text-gray-800">Task Agent</h1>
<p class="text-sm text-gray-500">AI Task Management</p>
</div>
</div>
<div class="hidden md:flex items-center gap-6">
<div class="text-right">
<p class="text-sm text-gray-500">Last update</p>
<p class="font-semibold text-gray-800" id="lastUpdate">Loading...</p>
</div>
<div class="flex items-center gap-2">
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
<span class="text-sm text-green-600 font-medium">Connected</span>
</div>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 bg-gray-50 min-h-screen">
<!-- Header Section -->
<div class="text-center mb-8">
<h1 class="text-3xl lg:text-4xl font-bold text-gray-800 mb-4">AI Task Management</h1>
</div>
<!-- Task Command Center & Search -->
<div class="bg-white rounded-2xl p-6 mb-8 shadow-lg border border-gray-200">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-orange-600 rounded-lg flex items-center justify-center">
<i class="fas fa-brain text-white"></i>
</div>
<h2 class="text-xl font-bold text-gray-800">Task AI Command & Search</h2>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-4">
<!-- AI Command -->
<div class="flex flex-col sm:flex-row gap-3">
<div class="flex-1">
<input
id="taskCommand"
type="text"
placeholder="Ask AI: 'Show overdue tasks', 'Prioritize my tasks', 'Create daily standup task'"
class="w-full px-4 py-3 rounded-xl border border-gray-300 bg-white text-gray-800 placeholder-gray-500 focus:border-orange-400 focus:ring-2 focus:ring-orange-400/50 outline-none transition-all"
/>
</div>
<button
onclick="executeTaskCommand()"
class="w-full sm:w-auto bg-orange-600 hover:bg-orange-700 text-white px-6 py-3 rounded-xl font-semibold transition-all flex items-center justify-center gap-2 min-w-[120px]"
id="taskAiBtn"
>
<i class="fas fa-robot"></i>
<span>Execute</span>
</button>
</div>
<!-- Task Search -->
<div class="flex flex-col sm:flex-row gap-3">
<div class="flex-1">
<input
id="taskSearchInput"
type="text"
placeholder="Search tasks by name or description..."
class="w-full px-4 py-3 rounded-xl border border-gray-300 bg-white text-gray-800 placeholder-gray-500 focus:border-blue-400 focus:ring-2 focus:ring-blue-400/50 outline-none transition-all"
/>
</div>
<button
onclick="taskAgent && taskAgent.handleSearch()"
class="w-full sm:w-auto bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-xl font-semibold transition-all flex items-center justify-center gap-2 min-w-[120px]"
>
<i class="fas fa-search"></i>
<span>Search</span>
</button>
</div>
</div>
<!-- Quick Commands -->
<div class="flex flex-wrap gap-2 mb-4">
<span class="text-sm text-gray-500 mr-2">Quick commands:</span>
<button onclick="setTaskCommand('Show overdue tasks')" class="text-xs bg-orange-100 hover:bg-orange-200 text-orange-700 px-3 py-1 rounded-full transition-colors">
Overdue Tasks
</button>
<button onclick="setTaskCommand('Create daily standup task')" class="text-xs bg-orange-100 hover:bg-orange-200 text-orange-700 px-3 py-1 rounded-full transition-colors">
Create Task
</button>
<button onclick="setTaskCommand('Prioritize by deadline')" class="text-xs bg-orange-100 hover:bg-orange-200 text-orange-700 px-3 py-1 rounded-full transition-colors">
Smart Prioritize
</button>
</div>
<!-- Status Filters -->
<div class="flex flex-wrap gap-2">
<span class="text-sm text-gray-500 mr-2">Filter by status:</span>
<button onclick="taskAgent && taskAgent.handleFilter('all')" class="filter-btn text-xs bg-orange-200 text-orange-800 px-3 py-1 rounded-full transition-colors" data-status="all">
All Tasks
</button>
<button onclick="taskAgent && taskAgent.handleFilter('todo')" class="filter-btn text-xs bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-1 rounded-full transition-colors" data-status="todo">
To Do
</button>
<button onclick="taskAgent && taskAgent.handleFilter('inprogress')" class="filter-btn text-xs bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-1 rounded-full transition-colors" data-status="inprogress">
In Progress
</button>
<button onclick="taskAgent && taskAgent.handleFilter('done')" class="filter-btn text-xs bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-1 rounded-full transition-colors" data-status="done">
Completed
</button>
</div>
</div>
<!-- Stats Dashboard -->
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-red-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-exclamation-triangle text-red-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="overdueCount">0</div>
<div class="text-sm text-gray-500">Overdue</div>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-orange-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-clock text-orange-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="dueTodayCount">0</div>
<div class="text-sm text-gray-500">Due Today</div>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-list text-blue-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="totalTasks">0</div>
<div class="text-sm text-gray-500">Total</div>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow-lg border border-gray-200">
<div class="text-center">
<div class="w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center mx-auto mb-2">
<i class="fas fa-check-circle text-green-600"></i>
</div>
<div class="text-2xl font-bold text-gray-800" id="completedToday">0</div>
<div class="text-sm text-gray-500">Completed</div>
</div>
</div>
</div>
<!-- Loading State -->
<div id="loadingState" class="hidden bg-white rounded-2xl p-8 shadow-lg border border-gray-200 mb-8">
<div class="flex items-center justify-center">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-orange-600 mr-3"></div>
<span class="text-gray-600">Loading tasks...</span>
</div>
</div>
<!-- Main Task Interface -->
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
<!-- Kanban Board -->
<div class="lg:col-span-3">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- To Do Column -->
<div id="todoColumn" class="bg-white rounded-2xl p-4 shadow-lg border border-gray-200">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-bold text-gray-800 flex items-center gap-2">
<div class="w-3 h-3 bg-gray-400 rounded-full"></div>
To Do
</h3>
<span class="text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded-full">0</span>
</div>
<div class="space-y-3 kanban-column custom-scrollbar overflow-y-auto" style="min-height: 400px;">
<!-- Tasks will be loaded here -->
</div>
</div>
<!-- In Progress Column -->
<div id="inProgressColumn" class="bg-white rounded-2xl p-4 shadow-lg border border-gray-200">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-bold text-gray-800 flex items-center gap-2">
<div class="w-3 h-3 bg-orange-400 rounded-full"></div>
In Progress
</h3>
<span class="text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded-full">0</span>
</div>
<div class="space-y-3 kanban-column custom-scrollbar overflow-y-auto" style="min-height: 400px;">
<!-- Tasks will be loaded here -->
</div>
</div>
<!-- Done Column -->
<div id="doneColumn" class="bg-white rounded-2xl p-4 shadow-lg border border-gray-200">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-bold text-gray-800 flex items-center gap-2">
<div class="w-3 h-3 bg-green-400 rounded-full"></div>
Done
</h3>
<span class="text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded-full">0</span>
</div>
<div class="space-y-3 kanban-column custom-scrollbar overflow-y-auto" style="min-height: 400px;">
<!-- Tasks will be loaded here -->
</div>
</div>
</div>
</div>
<!-- AI Actions Panel -->
<div class="space-y-6">
<!-- Quick Actions -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">Quick Actions</h3>
<div class="space-y-3">
<button onclick="createTask()" class="w-full p-3 bg-orange-600 hover:bg-orange-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-plus"></i>
<span>Create Task</span>
</button>
<button onclick="prioritizeTasks()" class="w-full p-3 bg-purple-600 hover:bg-purple-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-sort-amount-down"></i>
<span>AI Prioritize</span>
</button>
<button onclick="bulkUpdate()" class="w-full p-3 bg-blue-600 hover:bg-blue-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-edit"></i>
<span>Bulk Update</span>
</button>
<button onclick="generateReport()" class="w-full p-3 bg-green-600 hover:bg-green-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-chart-bar"></i>
<span>Progress Report</span>
</button>
</div>
</div>
<!-- Connection Status -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">Data Source</h3>
<div class="flex items-center gap-3 p-3 bg-green-50 border border-green-200 rounded-lg">
<div class="w-8 h-8 bg-green-100 rounded flex items-center justify-center">
<i class="fas fa-table text-green-600"></i>
</div>
<div class="flex-1">
<p class="text-sm font-medium text-green-800">Sample Data</p>
<p class="text-xs text-green-600">Demo Mode Active</p>
</div>
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
</div>
<button onclick="taskAgent && taskAgent.loadSampleTasks()" class="w-full mt-3 text-sm bg-gray-100 hover:bg-gray-200 text-gray-700 py-2 px-3 rounded-lg transition-colors">
<i class="fas fa-sync-alt mr-1"></i>
Refresh Data
</button>
</div>
<!-- Productivity Insights -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">Productivity Insights</h3>
<div class="space-y-4">
<div class="bg-green-50 rounded-lg p-3 border border-green-200">
<h4 class="font-medium text-green-700 mb-1">Completion Rate</h4>
<div class="w-full bg-gray-200 rounded-full h-2 mb-1">
<div class="bg-green-500 h-2 rounded-full" style="width: 87%"></div>
</div>
<p class="text-sm text-green-600">87% (Above average)</p>
</div>
<div class="bg-blue-50 rounded-lg p-3 border border-blue-200">
<h4 class="font-medium text-blue-700 mb-1">Focus Score</h4>
<div class="text-2xl font-bold text-blue-600">8.2/10</div>
<p class="text-sm text-blue-600">Excellent focus</p>
</div>
<div class="bg-orange-50 rounded-lg p-3 border border-orange-200">
<h4 class="font-medium text-orange-700 mb-1">Avg Task Time</h4>
<p class="text-lg font-bold text-orange-600">2.3 days</p>
<p class="text-sm text-orange-600">15% faster this week</p>
</div>
</div>
</div>
<!-- AI Recommendations -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">AI Recommendations</h3>
<div class="space-y-3">
<div class="bg-red-50 border border-red-200 rounded-lg p-3">
<h4 class="font-medium text-red-700 mb-1">🚨 Urgent Action</h4>
<p class="text-sm text-red-600">Security audit is 2 days overdue</p>
</div>
<div class="bg-blue-50 border border-blue-200 rounded-lg p-3">
<h4 class="font-medium text-blue-700 mb-1">💡 Suggestion</h4>
<p class="text-sm text-blue-600">Break large tasks into smaller chunks</p>
</div>
<div class="bg-green-50 border border-green-200 rounded-lg p-3">
<h4 class="font-medium text-green-700 mb-1">✨ Optimization</h4>
<p class="text-sm text-green-600">Batch similar tasks for efficiency</p>
</div>
</div>
</div>
<!-- Recent AI Actions -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">Recent AI Actions</h3>
<div class="space-y-3 custom-scrollbar max-h-48 overflow-y-auto">
<div class="flex items-start gap-3 p-2 bg-gray-50 rounded-lg">
<div class="w-6 h-6 bg-orange-100 rounded flex items-center justify-center flex-shrink-0 mt-1">
<i class="fas fa-sort text-orange-600 text-xs"></i>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-800">Auto-prioritized 5 tasks</p>
<p class="text-xs text-gray-500">3 minutes ago</p>
</div>
</div>
<div class="flex items-start gap-3 p-2 bg-gray-50 rounded-lg">
<div class="w-6 h-6 bg-green-100 rounded flex items-center justify-center flex-shrink-0 mt-1">
<i class="fas fa-check text-green-600 text-xs"></i>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-800">Marked deployment complete</p>
<p class="text-xs text-gray-500">2 hours ago</p>
</div>
</div>
<div class="flex items-start gap-3 p-2 bg-gray-50 rounded-lg">
<div class="w-6 h-6 bg-blue-100 rounded flex items-center justify-center flex-shrink-0 mt-1">
<i class="fas fa-plus text-blue-600 text-xs"></i>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-800">Created 3 subtasks</p>
<p class="text-xs text-gray-500">4 hours ago</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- AI Response Modal -->
<div id="aiModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl max-w-2xl w-full max-h-[80vh] overflow-hidden">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-orange-100 rounded-lg flex items-center justify-center">
<i class="fas fa-robot text-orange-600"></i>
</div>
<h3 class="text-lg font-bold text-gray-800">Task AI Response</h3>
</div>
<button onclick="closeAIModal()" class="text-gray-400 hover:text-gray-600">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="p-6 overflow-y-auto custom-scrollbar" id="aiResponse">
<!-- AI response content will be loaded here -->
</div>
</div>
</div>
<!-- Scripts in correct order to fix loading issues -->
<script>
// Global functions that need to be available immediately
function goHome() {
window.location.href = 'index.html';
}
function executeTaskCommand() {
if (window.taskAgent) {
window.taskAgent.executeTaskCommand();
} else {
console.log('Task agent not ready yet');
}
}
function setTaskCommand(cmd) {
if (window.taskAgent) {
window.taskAgent.setTaskCommand(cmd);
} else {
console.log('Task agent not ready yet');
}
}
function createTask() {
if (window.taskAgent) {
window.taskAgent.createTask();
} else {
console.log('Task agent not ready yet');
}
}
function prioritizeTasks() {
if (window.taskAgent) {
window.taskAgent.prioritizeTasks();
} else {
console.log('Task agent not ready yet');
}
}
function bulkUpdate() {
if (window.taskAgent) {
window.taskAgent.bulkUpdate();
} else {
console.log('Task agent not ready yet');
}
}
function generateReport() {
if (window.taskAgent) {
window.taskAgent.generateReport();
} else {
console.log('Task agent not ready yet');
}
}
function closeAIModal() {
if (window.taskAgent) {
window.taskAgent.hideAIModal();
} else {
const modal = document.getElementById('aiModal');
if (modal) {
modal.classList.add('hidden');
}
}
}
console.log('✅ Global functions loaded');
</script>
<!-- Load Utils first, then Task Agent -->
<script src="assets/js/utils.js"></script>
<script src="assets/js/navigation.js"></script>
<script src="assets/js/task-agent.js"></script>
<script>
// Override API URL for your n8n instance (after task agent loads)
document.addEventListener('DOMContentLoaded', function() {
if (window.taskAgent) {
// Replace this URL with your actual n8n webhook URL
window.taskAgent.apiUrl = 'https://thecyberlearn.app.n8n.cloud/webhook/tasks';
console.log('✅ API URL configured');
}
});
</script>
</body>
</html>

504
trade-intelligence.html Normal file
View File

@ -0,0 +1,504 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Trade Intelligence - AI Trade Management</title>
<!-- External Dependencies -->
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<!-- Link to your existing CSS file -->
<link rel="stylesheet" href="/assets/css/styles.css">
</head>
<body>
<!-- Navigation Header -->
<nav class="bg-white shadow-sm border-b sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center py-4">
<div class="flex items-center gap-3">
<button onclick="goHome()" class="w-10 h-10 bg-indigo-100 rounded-lg flex items-center justify-center hover:bg-indigo-200 transition-colors">
<i class="fas fa-home text-indigo-600"></i>
</button>
<div class="w-10 h-10 bg-blue-600 rounded-xl flex items-center justify-center shadow-lg">
<i class="fas fa-ship text-white text-lg"></i>
</div>
<div>
<h1 class="text-lg font-bold text-gray-800">Trade Intelligence</h1>
<p class="text-sm text-gray-500">Victor AI Agent</p>
</div>
</div>
<div class="hidden md:flex items-center gap-6">
<div class="text-right">
<p class="text-sm text-gray-500">Last updated</p>
<p class="font-semibold text-gray-800" id="lastUpdated">Just now</p>
</div>
<div class="flex items-center gap-2">
<div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
<span class="text-sm text-green-600 font-medium">Online</span>
</div>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 bg-gray-50 min-h-screen">
<!-- Header Section -->
<div class="text-center mb-8">
<h1 class="text-3xl lg:text-4xl font-bold text-gray-800 mb-4">AI Trade Intelligence</h1>
</div>
<!-- Enhanced Search Command Center -->
<div class="bg-white rounded-2xl p-6 mb-8 shadow-lg border border-gray-200">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-blue-600 rounded-lg flex items-center justify-center">
<i class="fas fa-brain text-white"></i>
</div>
<h2 class="text-xl font-bold text-gray-800">Trade AI Command</h2>
</div>
<!-- Main Search Bar -->
<div class="flex flex-col sm:flex-row gap-3 mb-4">
<div class="flex-1">
<input
id="query"
type="text"
placeholder="Ask AI: 'find seller from india', 'find buyer from uk', 'find coca cola sellers'"
class="w-full px-4 py-3 rounded-xl border border-gray-300 bg-white text-gray-800 placeholder-gray-500 focus:border-blue-400 focus:ring-2 focus:ring-blue-400/50 outline-none transition-all"
/>
</div>
<button
onclick="callWorkflow()"
class="w-full sm:w-auto bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-xl font-semibold transition-all flex items-center justify-center gap-2 min-w-[120px]"
id="searchBtn"
>
<i class="fas fa-search"></i>
<span>Search</span>
</button>
</div>
<!-- Quick Searches -->
<div class="mb-4">
<div class="flex flex-wrap gap-2">
<span class="text-sm text-gray-500 mr-2">Quick searches:</span>
<button onclick="setQuickSearch('find seller from india')" class="text-xs bg-blue-100 hover:bg-blue-200 text-blue-700 px-3 py-1 rounded-full transition-colors">
Sellers from India
</button>
<button onclick="setQuickSearch('find buyer from uk')" class="text-xs bg-blue-100 hover:bg-blue-200 text-blue-700 px-3 py-1 rounded-full transition-colors">
UK Buyers
</button>
<button onclick="setQuickSearch('find pepsi sellers')" class="text-xs bg-blue-100 hover:bg-blue-200 text-blue-700 px-3 py-1 rounded-full transition-colors">
Pepsi Sellers
</button>
<button onclick="setQuickSearch('find cosmetic buyers')" class="text-xs bg-blue-100 hover:bg-blue-200 text-blue-700 px-3 py-1 rounded-full transition-colors">
Cosmetic Buyers
</button>
</div>
</div>
<!-- Advanced Search Panel -->
<div class="border-t border-gray-200 pt-4">
<div class="flex items-center gap-2 mb-4">
<i class="fas fa-sliders-h text-gray-600"></i>
<h3 class="text-sm font-semibold text-gray-700">Advanced Filters</h3>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<!-- Search Type -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Search Type</label>
<select id="searchType" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="all">All Companies</option>
<option value="buyer">Buyers Only</option>
<option value="seller">Sellers Only</option>
<option value="product-match">Product Mapping</option>
</select>
</div>
<!-- Product/Brand -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Product/Brand</label>
<input
id="productSearch"
type="text"
placeholder="e.g., Pepsi, Coca Cola, FMCG"
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
/>
</div>
<!-- Country -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Country</label>
<select id="countryFilter" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="">All Countries</option>
<option value="India">India</option>
<option value="United Kingdom">United Kingdom</option>
<option value="United States">United States</option>
<option value="UAE">UAE</option>
<option value="China">China</option>
<option value="Germany">Germany</option>
<option value="France">France</option>
<option value="Italy">Italy</option>
</select>
</div>
</div>
<!-- Advanced Search Actions -->
<div class="flex flex-wrap gap-3">
<button
onclick="performAdvancedSearch()"
class="bg-green-600 hover:bg-green-700 text-white px-6 py-2 rounded-lg font-semibold transition-all flex items-center gap-2"
>
<i class="fas fa-search"></i>
Advanced Search
</button>
<button
onclick="performProductMatching()"
class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-2 rounded-lg font-semibold transition-all flex items-center gap-2"
>
<i class="fas fa-link"></i>
Find Product Mapping
</button>
<button
onclick="resetAdvancedFilters()"
class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg font-medium transition-all flex items-center gap-2"
>
<i class="fas fa-undo"></i>
Reset
</button>
</div>
</div>
</div>
<!-- Product Matching Results Section -->
<div id="productMatchingResults" class="hidden bg-white rounded-2xl p-6 shadow-lg border border-gray-200 mb-8">
<div class="flex items-center gap-3 mb-6">
<div class="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center">
<i class="fas fa-link text-purple-600"></i>
</div>
<div class="flex-1">
<h3 class="text-xl font-bold text-gray-800">Product Mapping Results</h3>
<p class="text-gray-600" id="productMatchingSubtitle">Find buyers and sellers for your products</p>
</div>
<button onclick="closeProductMatching()" class="text-gray-400 hover:text-gray-600 p-2">
<i class="fas fa-times"></i>
</button>
</div>
<!-- Product Info Header -->
<div class="bg-gradient-to-r from-purple-50 to-blue-50 rounded-lg p-4 mb-6" id="productInfoHeader">
<!-- Product details will be populated here -->
</div>
<!-- Buyers and Sellers Grid -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Buyers Section -->
<div class="bg-blue-50 rounded-lg p-4">
<div class="flex items-center gap-2 mb-4">
<i class="fas fa-shopping-cart text-blue-600"></i>
<h4 class="text-lg font-semibold text-blue-800" id="buyersTitle">Buyers (0)</h4>
</div>
<div class="space-y-3 max-h-96 overflow-y-auto custom-scrollbar" id="buyersList">
<!-- Buyers will be populated here -->
</div>
</div>
<!-- Sellers Section -->
<div class="bg-green-50 rounded-lg p-4">
<div class="flex items-center gap-2 mb-4">
<i class="fas fa-store text-green-600"></i>
<h4 class="text-lg font-semibold text-green-800" id="sellersTitle">Sellers (0)</h4>
</div>
<div class="space-y-3 max-h-96 overflow-y-auto custom-scrollbar" id="sellersList">
<!-- Sellers will be populated here -->
</div>
</div>
</div>
</div>
<!-- Main Content Grid -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Results Section -->
<div class="lg:col-span-2">
<!-- Results will show here -->
<div id="resultsSection" class="hidden">
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-bold text-gray-800">Search Results</h3>
<div class="flex items-center gap-2">
<p id="resultsCount" class="text-sm text-gray-600"></p>
<select id="sortBy" onchange="sortResults()" class="text-sm border border-gray-300 rounded px-2 py-1">
<option value="default">Default</option>
<option value="name">Sort by Name</option>
<option value="country">Sort by Country</option>
<option value="products">Sort by Products</option>
</select>
<button onclick="exportResults()" class="text-sm bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-2 rounded-lg transition-colors flex items-center gap-2">
<i class="fas fa-download text-xs"></i>
Export
</button>
</div>
</div>
<div id="results" class="grid grid-cols-1 gap-4 custom-scrollbar max-h-dvh overflow-y-auto"></div>
</div>
</div>
</div>
<!-- AI Actions Panel -->
<div class="space-y-6">
<!-- Quick Actions -->
<div class="bg-white rounded-2xl p-6 shadow-lg border border-gray-200">
<h3 class="text-lg font-bold text-gray-800 mb-4">Quick Actions</h3>
<div class="space-y-3">
<button onclick="quickSearch('all buyers')" class="w-full p-3 bg-blue-600 hover:bg-blue-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-search"></i>
<span>All Buyers</span>
</button>
<button onclick="quickSearch('all sellers')" class="w-full p-3 bg-green-600 hover:bg-green-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-ship"></i>
<span>All Sellers</span>
</button>
<button onclick="quickSearch('gulfood data')" class="w-full p-3 bg-orange-600 hover:bg-orange-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-globe"></i>
<span>Gulfood Data</span>
</button>
<button onclick="clearResults()" class="w-full p-3 bg-gray-600 hover:bg-gray-700 rounded-lg text-white font-medium transition-colors flex items-center gap-3">
<i class="fas fa-broom"></i>
<span>Clear Results</span>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- CRUD Elements - Fixed positioning outside main content -->
<!-- Minimal CRUD Wrench Icon -->
<div class="fixed bottom-6 right-6 z-50">
<button
onclick="toggleCrudModal()"
class="w-14 h-14 bg-indigo-600 hover:bg-indigo-700 text-white rounded-full shadow-lg hover:shadow-xl transition-all duration-300 flex items-center justify-center group"
id="crudWrenchBtn"
title="Data Management Tools"
>
<i class="fas fa-wrench text-xl group-hover:rotate-12 transition-transform"></i>
</button>
</div>
<!-- Enhanced CRUD Modal -->
<div id="crudModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden shadow-2xl">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-indigo-100 rounded-lg flex items-center justify-center">
<i class="fas fa-wrench text-indigo-600"></i>
</div>
<div>
<h3 class="text-xl font-bold text-gray-800">Data Management</h3>
<p class="text-gray-600">Create, update, or delete company records</p>
</div>
</div>
<button onclick="closeCrudModal()" class="text-gray-400 hover:text-gray-600 p-2">
<i class="fas fa-times text-xl"></i>
</button>
</div>
</div>
<div class="p-6 max-h-[calc(90vh-120px)] overflow-y-auto">
<!-- Operation Selector -->
<div class="flex bg-gray-100 rounded-lg p-1 mb-6">
<button
onclick="selectCrudOperation('create')"
class="flex-1 py-3 px-4 rounded-md font-medium transition-all flex items-center justify-center gap-2"
id="createTab"
>
<i class="fas fa-plus"></i>
Create
</button>
<button
onclick="selectCrudOperation('update')"
class="flex-1 py-3 px-4 rounded-md font-medium transition-all flex items-center justify-center gap-2"
id="updateTab"
>
<i class="fas fa-edit"></i>
Update
</button>
<button
onclick="selectCrudOperation('delete')"
class="flex-1 py-3 px-4 rounded-md font-medium transition-all flex items-center justify-center gap-2"
id="deleteTab"
>
<i class="fas fa-trash"></i>
Delete
</button>
</div>
<!-- Create Form -->
<div id="createOperation" class="hidden">
<div class="space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Type *</label>
<select id="createType" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500">
<option value="">Select Type</option>
<option value="importer">Importer</option>
<option value="exporter">Exporter</option>
<option value="gulfood">Gulfood</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Company Name *</label>
<input id="createName" type="text" placeholder="Company name" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500">
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Country</label>
<select id="createCountry" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500">
<option value="">Loading countries...</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Email</label>
<input id="createEmail" type="email" placeholder="company@example.com" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500">
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Phone</label>
<input id="createPhone" type="text" placeholder="+1234567890" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Website</label>
<input id="createWebsite" type="url" placeholder="https://company.com" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500">
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Products/Services</label>
<textarea id="createProducts" placeholder="List of products or services" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 h-24 resize-none"></textarea>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Address</label>
<textarea id="createAddress" placeholder="Company address" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 h-24 resize-none"></textarea>
</div>
</div>
<button onclick="executeCrud('create')" class="w-full bg-green-600 hover:bg-green-700 text-white py-3 rounded-lg font-semibold transition-colors" id="createBtn">
<i class="fas fa-plus mr-2"></i>Create Company
</button>
</div>
</div>
<!-- Update Form -->
<div id="updateOperation" class="hidden">
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Company Name *</label>
<input id="updateName" type="text" placeholder="Enter company name to update" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500">
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Field to Update *</label>
<select id="updateField" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500">
<option value="">Select Field</option>
<option value="email">Email</option>
<option value="phone">Phone</option>
<option value="country">Country</option>
<option value="website">Website</option>
<option value="products">Products/Services</option>
<option value="address">Address</option>
<option value="type">Type</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">New Value *</label>
<input id="updateValue" type="text" placeholder="Enter new value" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500">
</div>
</div>
<button onclick="executeCrud('update')" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-3 rounded-lg font-semibold transition-colors" id="updateBtn">
<i class="fas fa-edit mr-2"></i>Update Company
</button>
</div>
</div>
<!-- Delete Form -->
<div id="deleteOperation" class="hidden">
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Company Name *</label>
<input id="deleteName" type="text" placeholder="Enter company name to delete" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-red-500">
</div>
<div class="bg-red-50 border border-red-200 rounded-lg p-4">
<div class="flex items-start gap-3">
<i class="fas fa-exclamation-triangle text-red-600 mt-1"></i>
<div>
<p class="text-red-800 font-medium">Warning</p>
<p class="text-red-700 text-sm">This action cannot be undone. The company will be permanently deleted.</p>
</div>
</div>
</div>
<label class="flex items-center gap-2">
<input type="checkbox" id="deleteConfirm" class="rounded border-gray-300 text-red-600 focus:ring-red-500">
<span class="text-sm text-gray-700">I understand this action is permanent</span>
</label>
<button onclick="executeCrud('delete')" class="w-full bg-red-600 hover:bg-red-700 text-white py-3 rounded-lg font-semibold transition-colors opacity-50 cursor-not-allowed" id="deleteBtn" disabled>
<i class="fas fa-trash mr-2"></i>Delete Company
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Toast Notification Container -->
<div id="toastContainer" class="fixed top-4 right-4 z-50 space-y-2">
<!-- Toast notifications will be added here -->
</div>
<!-- AI Response Modal -->
<div id="aiModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl max-w-2xl w-full max-h-[80vh] overflow-hidden">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center">
<i class="fas fa-robot text-blue-600"></i>
</div>
<h3 class="text-lg font-bold text-gray-800">Trade AI Response</h3>
</div>
<button onclick="closeAIModal()" class="text-gray-400 hover:text-gray-600">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="p-6 overflow-y-auto custom-scrollbar" id="aiResponse">
<!-- AI response content will be loaded here -->
</div>
</div>
</div>
<!-- Scripts -->
<script src="assets/js/utils.js"></script>
<script src="assets/js/navigation.js"></script>
<script src="/assets/js/trade-intelligence.js"></script>
</body>
</html>