| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Voice-Powered Smart Personal Assistant</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .gradient-bg { |
| background: linear-gradient(135deg, #6e8efb, #a777e3); |
| } |
| .voice-pulse { |
| animation: pulse 2s infinite; |
| } |
| @keyframes pulse { |
| 0% { box-shadow: 0 0 0 0 rgba(110, 142, 251, 0.7); } |
| 70% { box-shadow: 0 0 0 15px rgba(110, 142, 251, 0); } |
| 100% { box-shadow: 0 0 0 0 rgba(110, 142, 251, 0); } |
| } |
| .feature-card:hover { |
| transform: translateY(-5px); |
| transition: all 0.3s ease; |
| } |
| .language-flag { |
| width: 30px; |
| height: 20px; |
| object-fit: cover; |
| border-radius: 3px; |
| margin-right: 8px; |
| } |
| .manual-controls-form { |
| display: none; |
| position: fixed; |
| top: 0; |
| left: 0; |
| right: 0; |
| bottom: 0; |
| background-color: rgba(0,0,0,0.5); |
| z-index: 1000; |
| justify-content: center; |
| align-items: center; |
| } |
| .manual-controls-form.active { |
| display: flex; |
| } |
| </style> |
| </head> |
| <body class="font-sans bg-gray-50"> |
| |
| <header class="gradient-bg text-white py-12 px-4 md:px-8 relative"> |
| |
| <div class="absolute top-4 right-4 flex items-center space-x-2"> |
| <div class="bg-white bg-opacity-20 px-4 py-1 rounded-full flex items-center" id="userStatus"> |
| <i class="fas fa-user-circle mr-2"></i> |
| <span>Guest</span> |
| </div> |
| <div class="relative group"> |
| <button class="bg-white bg-opacity-20 p-2 rounded-full hover:bg-opacity-30"> |
| <i class="fas fa-cog"></i> |
| </button> |
| <div class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-10 hidden group-hover:block"> |
| <a href="#" class="block px-4 py-2 text-gray-800 hover:bg-purple-100" id="adminPanelLink">Admin Panel</a> |
| <a href="#" class="block px-4 py-2 text-gray-800 hover:bg-purple-100" id="resetData">Reset All Data</a> |
| <a href="#" class="block px-4 py-2 text-gray-800 hover:bg-purple-100" id="logoutBtn">Logout</a> |
| </div> |
| </div> |
| </div> |
| <div class="container mx-auto max-w-6xl"> |
| <div class="flex flex-col md:flex-row items-center justify-between"> |
| <div class="md:w-1/2 mb-8 md:mb-0"> |
| <h1 class="text-4xl md:text-5xl font-bold mb-4">Voice-Powered Smart Personal Assistant</h1> |
| <p class="text-xl mb-6">Manage finances, appointments, and reminders through natural voice commands in multiple languages.</p> |
| <div class="flex flex-wrap gap-3 mb-6"> |
| <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full flex items-center"> |
| <img src="https://flagcdn.com/w20/us.png" class="language-flag"> English |
| </span> |
| <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full flex items-center"> |
| <img src="https://flagcdn.com/w20/eg.png" class="language-flag"> Arabic |
| </span> |
| <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full flex items-center"> |
| <img src="https://flagcdn.com/w20/es.png" class="language-flag"> Spanish |
| </span> |
| </div> |
| <button class="bg-white text-purple-700 font-bold px-6 py-3 rounded-lg hover:bg-gray-100 transition"> |
| <i class="fas fa-microphone mr-2"></i> Try Voice Demo |
| </button> |
| </div> |
| <div class="md:w-1/2 flex justify-center"> |
| <div class="relative"> |
| <div class="bg-white bg-opacity-20 rounded-3xl p-2 inline-block"> |
| <img src="https://i.imgur.com/JYw0lY7.png" alt="App Mockup" class="h-80 md:h-96 rounded-2xl"> |
| </div> |
| <div class="absolute -bottom-6 -right-6 bg-white p-4 rounded-full shadow-xl voice-pulse"> |
| <i class="fas fa-microphone text-purple-600 text-2xl"></i> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="mt-8 bg-white bg-opacity-20 rounded-xl p-6 max-w-md mx-auto"> |
| <h3 class="text-xl font-bold mb-4 text-center">Login to Your Account</h3> |
| <form class="space-y-4" id="loginForm"> |
| <div> |
| <label class="block text-sm font-medium mb-1">Username</label> |
| <input type="text" name="username" class="w-full px-4 py-2 bg-white bg-opacity-20 border border-white border-opacity-30 rounded-lg focus:outline-none focus:ring-2 focus:ring-white" placeholder="Enter username"> |
| </div> |
| <div> |
| <label class="block text-sm font-medium mb-1">Password</label> |
| <input type="password" name="password" class="w-full px-4 py-2 bg-white bg-opacity-20 border border-white border-opacity-30 rounded-lg focus:outline-none focus:ring-2 focus:ring-white" placeholder="Enter password"> |
| </div> |
| <div class="flex items-center"> |
| <input type="checkbox" id="adminLogin" name="admin" class="mr-2"> |
| <label for="adminLogin" class="text-sm">Login as Admin</label> |
| </div> |
| <button type="submit" class="w-full bg-white text-purple-700 font-bold px-6 py-2 rounded-lg hover:bg-gray-100 transition"> |
| Login |
| </button> |
| <p class="text-sm text-center"> |
| Don't have an account? |
| <a href="#" class="font-medium hover:underline">Sign up</a> |
| </p> |
| </form> |
| </div> |
| </div> |
| </div> |
| </header> |
|
|
| |
| <section id="dashboard" class="py-16 px-4 md:px-8 hidden"> |
| <div class="container mx-auto max-w-6xl"> |
| <h2 class="text-3xl font-bold mb-8">Dashboard Overview</h2> |
| |
| |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-12"> |
| |
| <div class="bg-white rounded-xl shadow-lg p-6"> |
| <div class="flex items-center justify-between"> |
| <div> |
| <p class="text-gray-500">Current Balance</p> |
| <h3 class="text-2xl font-bold" id="currentBalance">€0.00</h3> |
| </div> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center"> |
| <i class="fas fa-wallet text-white text-xl"></i> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="bg-white rounded-xl shadow-lg p-6"> |
| <div class="flex items-center justify-between"> |
| <div> |
| <p class="text-gray-500">Upcoming</p> |
| <h3 class="text-2xl font-bold" id="upcomingCount">0</h3> |
| <p class="text-sm text-gray-500">Appointments</p> |
| </div> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center"> |
| <i class="fas fa-calendar-alt text-white text-xl"></i> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="bg-white rounded-xl shadow-lg p-6"> |
| <div class="flex items-center justify-between"> |
| <div> |
| <p class="text-gray-500">You Owe</p> |
| <h3 class="text-2xl font-bold text-red-600" id="youOwe">€0.00</h3> |
| </div> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center"> |
| <i class="fas fa-hand-holding-usd text-white text-xl"></i> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="bg-white rounded-xl shadow-lg p-6"> |
| <div class="flex items-center justify-between"> |
| <div> |
| <p class="text-gray-500">Owed to You</p> |
| <h3 class="text-2xl font-bold text-green-600" id="owedToYou">€0.00</h3> |
| </div> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center"> |
| <i class="fas fa-money-bill-wave text-white text-xl"></i> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="bg-white rounded-xl shadow-lg p-6 mb-8"> |
| <div class="flex justify-between items-center mb-6"> |
| <h3 class="text-xl font-bold">Financial Overview</h3> |
| <div class="flex space-x-2"> |
| <button class="px-3 py-1 bg-purple-100 text-purple-700 rounded-lg text-sm">Monthly</button> |
| <button class="px-3 py-1 bg-gray-100 text-gray-700 rounded-lg text-sm">Yearly</button> |
| </div> |
| </div> |
| <div class="h-64 bg-gray-50 rounded-lg flex items-center justify-center"> |
| <p class="text-gray-400">Charts will appear here</p> |
| </div> |
| </div> |
| |
| |
| <div class="bg-white rounded-xl shadow-lg p-6"> |
| <div class="flex justify-between items-center mb-6"> |
| <h3 class="text-xl font-bold">Upcoming Appointments</h3> |
| <button class="px-3 py-1 bg-purple-600 text-white rounded-lg text-sm flex items-center"> |
| <i class="fas fa-plus mr-1"></i> Add |
| </button> |
| </div> |
| <div class="overflow-x-auto"> |
| <table class="min-w-full"> |
| <thead> |
| <tr class="text-left border-b"> |
| <th class="pb-3">Date</th> |
| <th class="pb-3">Contact</th> |
| <th class="pb-3">Location</th> |
| <th class="pb-3">Notes</th> |
| </tr> |
| </thead> |
| <tbody id="appointmentsTable"> |
| <tr class="border-b"> |
| <td class="py-3">No upcoming appointments</td> |
| <td></td> |
| <td></td> |
| <td></td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="py-16 px-4 md:px-8"> |
| <div class="container mx-auto max-w-6xl"> |
| <h2 class="text-3xl font-bold text-center mb-12">Core Features</h2> |
| |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> |
| |
| <div class="feature-card bg-white rounded-xl shadow-lg p-6 hover:shadow-xl"> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center mb-4"> |
| <i class="fas fa-microphone text-white text-xl"></i> |
| </div> |
| <h3 class="text-xl font-bold mb-3">Voice Commands</h3> |
| <p class="text-gray-600 mb-4">Control everything with natural voice in multiple languages. Example: "Add 100 euros to Sarah for the wedding, due next Friday."</p> |
| <div class="bg-gray-100 rounded-lg p-3 text-sm"> |
| <p class="font-mono text-purple-700">"Set meeting with Alex tomorrow at 3pm at coffee shop"</p> |
| </div> |
| </div> |
| |
| |
| <div class="feature-card bg-white rounded-xl shadow-lg p-6 hover:shadow-xl"> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center mb-4"> |
| <i class="fas fa-user-friends text-white text-xl"></i> |
| </div> |
| <h3 class="text-xl font-bold mb-3">Personal Profiles</h3> |
| <p class="text-gray-600 mb-4">Each contact has a dedicated profile with full financial history, appointments, and balance tracking.</p> |
| <div class="flex items-center mt-4"> |
| <div class="w-8 h-8 rounded-full bg-purple-100 flex items-center justify-center mr-2"> |
| <i class="fas fa-user text-purple-600 text-sm"></i> |
| </div> |
| <div> |
| <p class="font-medium">New User</p> |
| <p class="text-xs text-gray-500">Balance: <span class="text-gray-500">€0</span></p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="feature-card bg-white rounded-xl shadow-lg p-6 hover:shadow-xl"> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center mb-4"> |
| <i class="fas fa-hand-holding-usd text-white text-xl"></i> |
| </div> |
| <h3 class="text-xl font-bold mb-3">Dual-Sided Debt Tracking</h3> |
| <p class="text-gray-600 mb-4">Track both what others owe you and what you owe others with timestamps and categorization.</p> |
| <div class="flex justify-between text-sm mt-4"> |
| <div class="text-center"> |
| <div class="w-10 h-10 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-1"> |
| <i class="fas fa-arrow-down text-green-600"></i> |
| </div> |
| <p>You Owe</p> |
| <p class="font-bold text-green-600">€0</p> |
| </div> |
| <div class="text-center"> |
| <div class="w-10 h-10 bg-red-100 rounded-full flex items-center justify-center mx-auto mb-1"> |
| <i class="fas fa-arrow-up text-red-600"></i> |
| </div> |
| <p>Owed to You</p> |
| <p class="font-bold text-red-600">€0</p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="feature-card bg-white rounded-xl shadow-lg p-6 hover:shadow-xl"> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center mb-4"> |
| <i class="fas fa-calendar-alt text-white text-xl"></i> |
| </div> |
| <h3 class="text-xl font-bold mb-3">Appointment Scheduler</h3> |
| <p class="text-gray-600 mb-4">Schedule meetings with date, time, location and reason - all by voice command.</p> |
| <div class="bg-blue-50 rounded-lg p-3 text-sm mt-4"> |
| <div class="flex items-center mb-1"> |
| <i class="fas fa-clock text-blue-500 mr-2"></i> |
| <p>No upcoming</p> |
| </div> |
| <div class="flex items-center"> |
| <i class="fas fa-map-marker-alt text-blue-500 mr-2"></i> |
| <p>No location</p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="feature-card bg-white rounded-xl shadow-lg p-6 hover:shadow-xl"> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center mb-4"> |
| <i class="fas fa-bell text-white text-xl"></i> |
| </div> |
| <h3 class="text-xl font-bold mb-3">Smart Reminders</h3> |
| <p class="text-gray-600 mb-4">Get automatic reminders for due payments and upcoming appointments.</p> |
| <div class="bg-yellow-50 rounded-lg p-3 text-sm mt-4"> |
| <div class="flex items-start"> |
| <i class="fas fa-exclamation-circle text-yellow-500 mt-1 mr-2"></i> |
| <div> |
| <p class="font-medium">No reminders</p> |
| <p class="text-xs">No pending payments</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="feature-card bg-white rounded-xl shadow-lg p-6 hover:shadow-xl"> |
| <div class="w-12 h-12 gradient-bg rounded-lg flex items-center justify-center mb-4"> |
| <i class="fas fa-edit text-white text-xl"></i> |
| </div> |
| <h3 class="text-xl font-bold mb-3">Manual Controls</h3> |
| <p class="text-gray-600 mb-4">Add, edit, or delete transactions, debts, or appointments manually through an intuitive interface.</p> |
| <div class="flex flex-col space-y-2 mt-4"> |
| <button onclick="showManualForm('transaction')" class="bg-purple-100 text-purple-700 px-3 py-2 rounded-lg text-sm flex items-center"> |
| <i class="fas fa-exchange-alt mr-2"></i> Add Transaction |
| </button> |
| <button onclick="showManualForm('debt')" class="bg-blue-100 text-blue-700 px-3 py-2 rounded-lg text-sm flex items-center"> |
| <i class="fas fa-hand-holding-usd mr-2"></i> Add Debt |
| </button> |
| <button onclick="showManualForm('appointment')" class="bg-green-100 text-green-700 px-3 py-2 rounded-lg text-sm flex items-center"> |
| <i class="fas fa-calendar-plus mr-2"></i> Add Appointment |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <div id="adminPanel" class="manual-controls-form"> |
| <div class="bg-white rounded-xl shadow-2xl p-6 w-full max-w-2xl"> |
| <div class="flex justify-between items-center mb-4"> |
| <h3 class="text-xl font-bold">Admin Panel - All Users</h3> |
| <button onclick="hideAdminPanel()" class="text-gray-500 hover:text-gray-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| |
| <div class="overflow-y-auto max-h-96"> |
| <table class="min-w-full divide-y divide-gray-200"> |
| <thead class="bg-gray-50"> |
| <tr> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Username</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Balance</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Last Login</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th> |
| </tr> |
| </thead> |
| <tbody class="bg-white divide-y divide-gray-200" id="usersTableBody"> |
| |
| </tbody> |
| </table> |
| </div> |
| |
| <div class="mt-4 flex justify-end"> |
| <button onclick="hideAdminPanel()" class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50"> |
| Close |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="addContactForm" class="manual-controls-form"> |
| <div class="bg-white rounded-xl shadow-2xl p-6 w-full max-w-md"> |
| <div class="flex justify-between items-center mb-4"> |
| <h3 class="text-xl font-bold">Add New Contact</h3> |
| <button onclick="hideAddContactForm()" class="text-gray-500 hover:text-gray-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| |
| <form id="contactForm" class="space-y-4"> |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Name</label> |
| <input type="text" id="contactName" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="Enter contact name"> |
| </div> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Phone (Optional)</label> |
| <input type="text" id="contactPhone" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="Enter phone number"> |
| </div> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Email (Optional)</label> |
| <input type="email" id="contactEmail" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="Enter email address"> |
| </div> |
| |
| <div class="flex justify-end space-x-3 pt-4"> |
| <button type="button" onclick="hideAddContactForm()" class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50"> |
| Cancel |
| </button> |
| <button type="submit" class="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700"> |
| Save Contact |
| </button> |
| </div> |
| </form> |
| </div> |
| </div> |
|
|
| |
| <div id="manualControlsForm" class="manual-controls-form"> |
| <div class="bg-white rounded-xl shadow-2xl p-6 w-full max-w-md"> |
| <div class="flex justify-between items-center mb-4"> |
| <h3 class="text-xl font-bold" id="formTitle">Add Transaction</h3> |
| <button onclick="hideManualForm()" class="text-gray-500 hover:text-gray-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| |
| <form id="manualForm" class="space-y-4"> |
| <div id="contactField"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Contact</label> |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"> |
| <option>Select contact</option> |
| <option>New Contact 1</option> |
| <option>New Contact 2</option> |
| <option>New Contact 3</option> |
| </select> |
| </div> |
| |
| <div id="amountField"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Amount</label> |
| <div class="flex"> |
| <select class="w-20 px-3 py-2 border border-gray-300 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-purple-500"> |
| <option>€</option> |
| <option>$</option> |
| <option>£</option> |
| </select> |
| <input type="number" class="flex-1 px-3 py-2 border-t border-b border-r border-gray-300 rounded-r-lg focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="0.00"> |
| </div> |
| </div> |
| |
| <div id="typeField"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Type</label> |
| <div class="grid grid-cols-2 gap-2"> |
| <button type="button" class="bg-green-100 text-green-700 px-3 py-2 rounded-lg text-sm flex items-center justify-center"> |
| <i class="fas fa-arrow-up mr-2"></i> You Owe |
| </button> |
| <button type="button" class="bg-red-100 text-red-700 px-3 py-2 rounded-lg text-sm flex items-center justify-center"> |
| <i class="fas fa-arrow-down mr-2"></i> They Owe |
| </button> |
| </div> |
| </div> |
| |
| <div id="dateField"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Date</label> |
| <input type="date" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"> |
| </div> |
| |
| <div id="descriptionField"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Description</label> |
| <textarea class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" rows="2" placeholder="Enter description..."></textarea> |
| </div> |
| |
| <div id="locationField" class="hidden"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Location</label> |
| <input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="Enter location..."> |
| </div> |
| |
| <div class="flex justify-end space-x-3 pt-4"> |
| <button type="button" onclick="hideManualForm()" class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50"> |
| Cancel |
| </button> |
| <button type="submit" class="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700"> |
| Save |
| </button> |
| </div> |
| </form> |
| </div> |
| </div> |
|
|
| |
| <section class="py-16 px-4 md:px-8 bg-gray-100"> |
| <div class="container mx-auto max-w-6xl"> |
| <h2 class="text-3xl font-bold text-center mb-12">Advanced Features</h2> |
| |
| <div class="overflow-x-auto"> |
| <table class="min-w-full bg-white rounded-xl overflow-hidden"> |
| <thead class="gradient-bg text-white"> |
| <tr> |
| <th class="py-3 px-4 text-left">Feature</th> |
| <th class="py-3 px-4 text-left">Description</th> |
| </tr> |
| </thead> |
| <tbody class="divide-y divide-gray-200"> |
| <tr class="hover:bg-gray-50"> |
| <td class="py-4 px-4 font-medium">📈 Smart Analytics</td> |
| <td class="py-4 px-4">Financial trends, summaries, and spending patterns</td> |
| </tr> |
| <tr class="hover:bg-gray-50"> |
| <td class="py-4 px-4 font-medium">🔁 Recurring Transactions</td> |
| <td class="py-4 px-4">Automate regular payments like rent or subscriptions</td> |
| </tr> |
| <tr class="hover:bg-gray-50"> |
| <td class="py-4 px-4 font-medium">🗂️ Tagging & Filtering</td> |
| <td class="py-4 px-4">Organize with custom tags and advanced search</td> |
| </tr> |
| <tr class="hover:bg-gray-50"> |
| <td class="py-4 px-4 font-medium">🌍 Multi-Currency</td> |
| <td class="py-4 px-4">Support for USD, EUR, EGP with live conversion</td> |
| </tr> |
| <tr class="hover:bg-gray-50"> |
| <td class="py-4 px-4 font-medium">📤 Export Options</td> |
| <td class="py-4 px-4">PDF/Excel export for accounting or backup</td> |
| </tr> |
| <tr class="hover:bg-gray-50"> |
| <td class="py-4 px-4 font-medium">🧠 AI Suggestions</td> |
| <td class="py-4 px-4">Proactive reminders and financial insights</td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="py-16 px-4 md:px-8 bg-gray-50"> |
| <div class="container mx-auto max-w-6xl"> |
| <h2 class="text-3xl font-bold text-center mb-12">Calendar Integration</h2> |
| |
| <div class="bg-white rounded-xl shadow-lg p-8 max-w-3xl mx-auto"> |
| <div class="flex flex-col md:flex-row gap-8"> |
| <div class="md:w-1/2"> |
| <h3 class="text-xl font-bold mb-4">Google Calendar</h3> |
| <p class="text-gray-600 mb-4">Sync your appointments and reminders with Google Calendar</p> |
| <button id="googleAuthBtn" class="bg-blue-500 text-white px-4 py-2 rounded-lg flex items-center"> |
| <i class="fab fa-google mr-2"></i> Connect Google |
| </button> |
| </div> |
| <div class="md:w-1/2"> |
| <h3 class="text-xl font-bold mb-4">Apple Calendar</h3> |
| <p class="text-gray-600 mb-4">Sync with your iOS/Mac Calendar app</p> |
| <button id="appleAuthBtn" class="bg-black text-white px-4 py-2 rounded-lg flex items-center"> |
| <i class="fab fa-apple mr-2"></i> Connect Apple |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="py-16 px-4 md:px-8"> |
| <div class="container mx-auto max-w-6xl"> |
| <h2 class="text-3xl font-bold text-center mb-12">Technology Stack</h2> |
| |
| <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-6"> |
| <div class="flex flex-col items-center p-4 bg-white rounded-lg shadow"> |
| <img src="https://i.imgur.com/5H5uK5x.png" alt="Flutter" class="h-12 mb-2"> |
| <span class="text-sm font-medium">Flutter</span> |
| </div> |
| <div class="flex flex-col items-center p-4 bg-white rounded-lg shadow"> |
| <img src="https://i.imgur.com/3QZxJ7d.png" alt="Firebase" class="h-12 mb-2"> |
| <span class="text-sm font-medium">Firebase</span> |
| </div> |
| <div class="flex flex-col items-center p-4 bg-white rounded-lg shadow"> |
| <img src="https://i.imgur.com/7Z5vXZa.png" alt="OpenAI" class="h-12 mb-2"> |
| <span class="text-sm font-medium">OpenAI</span> |
| </div> |
| <div class="flex flex-col items-center p-4 bg-white rounded-lg shadow"> |
| <img src="https://i.imgur.com/9m7bwXk.png" alt="Hugging Face" class="h-12 mb-2"> |
| <span class="text-sm font-medium">Hugging Face</span> |
| </div> |
| <div class="flex flex-col items-center p-4 bg-white rounded-lg shadow"> |
| <img src="https://i.imgur.com/1YhZp9L.png" alt="Google Cloud" class="h-12 mb-2"> |
| <span class="text-sm font-medium">Google Cloud</span> |
| </div> |
| <div class="flex flex-col items-center p-4 bg-white rounded-lg shadow"> |
| <img src="https://i.imgur.com/vTnQ2Uw.png" alt="Dialogflow" class="h-12 mb-2"> |
| <span class="text-sm font-medium">Dialogflow</span> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="gradient-bg text-white py-16 px-4 md:px-8"> |
| <div class="container mx-auto max-w-4xl text-center"> |
| <h2 class="text-3xl font-bold mb-6">Ready to Transform Your Personal Management?</h2> |
| <p class="text-xl mb-8">Integrate with Hugging Face to enhance multilingual voice understanding and smart suggestions.</p> |
| <div class="flex flex-col sm:flex-row justify-center gap-4"> |
| <button class="bg-white text-purple-700 font-bold px-6 py-3 rounded-lg hover:bg-gray-100 transition"> |
| <i class="fas fa-code mr-2"></i> View API Documentation |
| </button> |
| <button class="bg-transparent border-2 border-white font-bold px-6 py-3 rounded-lg hover:bg-white hover:bg-opacity-10 transition"> |
| <i class="fas fa-comment mr-2"></i> Contact Support |
| </button> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <footer class="bg-gray-900 text-white py-8 px-4 md:px-8"> |
| <div class="container mx-auto max-w-6xl"> |
| <div class="flex flex-col md:flex-row justify-between items-center"> |
| <div class="mb-6 md:mb-0"> |
| <h3 class="text-xl font-bold mb-2">Voice Personal Assistant</h3> |
| <p class="text-gray-400">Smart financial and appointment management through voice</p> |
| </div> |
| <div class="flex space-x-6"> |
| <a href="#" class="text-gray-400 hover:text-white"> |
| <i class="fab fa-github text-xl"></i> |
| </a> |
| <a href="#" class="text-gray-400 hover:text-white"> |
| <i class="fab fa-twitter text-xl"></i> |
| </a> |
| <a href="#" class="text-gray-400 hover:text-white"> |
| <i class="fab fa-linkedin text-xl"></i> |
| </a> |
| </div> |
| </div> |
| <div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400 text-sm"> |
| <p>© 2023 Voice Personal Assistant. All rights reserved.</p> |
| <p class="mt-1">Designed by John Fayez</p> |
| </div> |
| </div> |
| </footer> |
|
|
| <script> |
| |
| function registerVoicePrint() { |
| if (!('webkitSpeechRecognition' in window)) { |
| alert('Voice authentication not supported in your browser'); |
| return; |
| } |
| |
| const recognition = new webkitSpeechRecognition(); |
| recognition.lang = 'en-US'; |
| recognition.interimResults = false; |
| |
| alert('Please say your passphrase 3 times for voice authentication'); |
| let samples = []; |
| |
| recognition.onresult = function(event) { |
| const transcript = event.results[0][0].transcript; |
| samples.push(transcript); |
| |
| if (samples.length < 3) { |
| alert(`Sample ${samples.length} recorded. Please say it again.`); |
| recognition.start(); |
| } else { |
| localStorage.setItem('voicePrint', JSON.stringify(samples)); |
| alert('Voice print registered successfully!'); |
| } |
| }; |
| |
| recognition.start(); |
| } |
| |
| function authenticateWithVoice() { |
| return new Promise((resolve) => { |
| if (!localStorage.getItem('voicePrint')) { |
| resolve(true); |
| return; |
| } |
| |
| const recognition = new webkitSpeechRecognition(); |
| recognition.lang = 'en-US'; |
| recognition.interimResults = false; |
| |
| alert('Please say your passphrase to authenticate'); |
| |
| recognition.onresult = function(event) { |
| const transcript = event.results[0][0].transcript; |
| const savedSamples = JSON.parse(localStorage.getItem('voicePrint')); |
| |
| |
| const isMatch = savedSamples.some(sample => |
| sample.toLowerCase() === transcript.toLowerCase() |
| ); |
| |
| resolve(isMatch); |
| }; |
| |
| recognition.start(); |
| }); |
| } |
| |
| |
| let contacts = JSON.parse(localStorage.getItem('contacts')) || []; |
| |
| function loadContacts() { |
| const select = document.getElementById('contactSelect'); |
| select.innerHTML = '<option>Select contact</option>'; |
| contacts.forEach(contact => { |
| const option = document.createElement('option'); |
| option.value = contact.name; |
| option.textContent = contact.name; |
| select.appendChild(option); |
| }); |
| } |
| |
| function showAddContactForm() { |
| document.getElementById('addContactForm').classList.add('active'); |
| } |
| |
| function hideAddContactForm() { |
| document.getElementById('addContactForm').classList.remove('active'); |
| document.getElementById('contactForm').reset(); |
| } |
| |
| document.getElementById('contactForm').addEventListener('submit', function(e) { |
| e.preventDefault(); |
| const name = document.getElementById('contactName').value.trim(); |
| const phone = document.getElementById('contactPhone').value.trim(); |
| const email = document.getElementById('contactEmail').value.trim(); |
| |
| if (!name) { |
| alert('Please enter a contact name'); |
| return; |
| } |
| |
| const newContact = { |
| name, |
| phone, |
| email, |
| createdAt: new Date().toISOString() |
| }; |
| |
| contacts.push(newContact); |
| localStorage.setItem('contacts', JSON.stringify(contacts)); |
| |
| loadContacts(); |
| hideAddContactForm(); |
| alert('Contact added successfully!'); |
| }); |
| |
| |
| document.addEventListener('DOMContentLoaded', loadContacts); |
| |
| |
| function showManualForm(type) { |
| const form = document.getElementById('manualControlsForm'); |
| const formTitle = document.getElementById('formTitle'); |
| const locationField = document.getElementById('locationField'); |
| const typeField = document.getElementById('typeField'); |
| |
| |
| if (type === 'transaction') { |
| formTitle.textContent = 'Add Transaction'; |
| typeField.classList.remove('hidden'); |
| locationField.classList.add('hidden'); |
| } else if (type === 'debt') { |
| formTitle.textContent = 'Add Debt'; |
| typeField.classList.remove('hidden'); |
| locationField.classList.add('hidden'); |
| } else if (type === 'appointment') { |
| formTitle.textContent = 'Add Appointment'; |
| typeField.classList.add('hidden'); |
| locationField.classList.remove('hidden'); |
| } |
| |
| form.classList.add('active'); |
| } |
| |
| function hideManualForm() { |
| document.getElementById('manualControlsForm').classList.remove('active'); |
| } |
| |
| |
| document.getElementById('manualControlsForm').addEventListener('click', function(e) { |
| if (e.target === this) { |
| hideManualForm(); |
| } |
| }); |
| |
| |
| function encryptData(data, key) { |
| |
| return btoa(JSON.stringify(data)); |
| } |
| |
| function decryptData(encrypted, key) { |
| try { |
| return JSON.parse(atob(encrypted)); |
| } catch { |
| return null; |
| } |
| } |
| |
| |
| const SECURE_KEY = 'voice-assistant-secure-key'; |
| let users = []; |
| const encryptedUsers = localStorage.getItem('users'); |
| if (encryptedUsers) { |
| users = decryptData(encryptedUsers, SECURE_KEY) || []; |
| } |
| let currentUser = null; |
| let isAdmin = false; |
| |
| |
| const enableCloudBackup = true; |
| let isOnline = navigator.onLine; |
| |
| |
| const firebaseConfig = { |
| apiKey: "YOUR_API_KEY", |
| authDomain: "YOUR_AUTH_DOMAIN", |
| projectId: "YOUR_PROJECT_ID", |
| storageBucket: "YOUR_STORAGE_BUCKET", |
| messagingSenderId: "YOUR_SENDER_ID", |
| appId: "YOUR_APP_ID" |
| }; |
| |
| |
| if (enableCloudBackup && isOnline) { |
| firebase.initializeApp(firebaseConfig); |
| const db = firebase.firestore(); |
| |
| |
| function syncWithCloud() { |
| if (!currentUser) return; |
| |
| const userRef = db.collection('users').doc(currentUser.username); |
| userRef.set({ |
| contacts: currentUser.contacts || [], |
| transactions: currentUser.transactions || [], |
| reminders: currentUser.reminders || [], |
| lastSync: new Date().toISOString() |
| }, { merge: true }); |
| } |
| |
| |
| function loadFromCloud() { |
| if (!currentUser) return; |
| |
| const userRef = db.collection('users').doc(currentUser.username); |
| userRef.get().then(doc => { |
| if (doc.exists) { |
| const data = doc.data(); |
| currentUser.contacts = data.contacts || []; |
| currentUser.transactions = data.transactions || []; |
| currentUser.reminders = data.reminders || []; |
| localStorage.setItem('users', JSON.stringify(users)); |
| } |
| }); |
| } |
| } |
| |
| |
| window.addEventListener('online', () => { |
| isOnline = true; |
| if (enableCloudBackup) syncWithCloud(); |
| }); |
| |
| window.addEventListener('offline', () => { |
| isOnline = false; |
| alert('Offline mode activated. Some features may be limited.'); |
| }); |
| |
| |
| if (users.length === 0) { |
| users.push({ |
| username: 'admin', |
| password: 'admin123', |
| isAdmin: true, |
| balance: 0, |
| transactions: [], |
| contacts: [ |
| {name: 'New Contact 1', phone: '', email: ''}, |
| {name: 'New Contact 2', phone: '', email: ''}, |
| {name: 'New Contact 3', phone: '', email: ''} |
| ] |
| }); |
| localStorage.setItem('users', JSON.stringify(users)); |
| } |
| |
| |
| const loginForm = document.getElementById('loginForm'); |
| const userStatus = document.getElementById('userStatus'); |
| const adminPanelLink = document.getElementById('adminPanelLink'); |
| const logoutBtn = document.getElementById('logoutBtn'); |
| const resetDataBtn = document.getElementById('resetData'); |
| |
| if (loginForm) { |
| loginForm.addEventListener('submit', function(e) { |
| e.preventDefault(); |
| const formData = new FormData(this); |
| const username = formData.get('username'); |
| const password = formData.get('password'); |
| const adminLogin = formData.get('admin') === 'on'; |
| |
| const user = users.find(u => u.username === username && u.password === password); |
| |
| if (user) { |
| |
| authenticateWithVoice().then(voiceAuthenticated => { |
| if (!voiceAuthenticated) { |
| alert('Voice authentication failed'); |
| return; |
| } |
| |
| if (adminLogin && !user.isAdmin) { |
| alert('You are not authorized as admin'); |
| return; |
| } |
| |
| currentUser = user; |
| isAdmin = adminLogin && user.isAdmin; |
| |
| userStatus.querySelector('span').textContent = username + (isAdmin ? ' (Admin)' : ''); |
| this.reset(); |
| |
| |
| user.lastLogin = new Date().toISOString(); |
| localStorage.setItem('users', JSON.stringify(encryptData(users, SECURE_KEY))); |
| |
| |
| adminPanelLink.style.display = isAdmin ? 'block' : 'none'; |
| |
| |
| document.getElementById('dashboard').classList.remove('hidden'); |
| document.querySelector('header .container > div:last-child').classList.add('hidden'); |
| |
| |
| updateDashboard(); |
| |
| alert('Login successful!'); |
| } else { |
| alert('Invalid username or password'); |
| } |
| }); |
| } |
| |
| |
| function showBillManagement() { |
| const bills = currentUser?.bills || []; |
| const billForm = ` |
| <div class="bg-white rounded-xl shadow-lg p-6 w-full max-w-3xl"> |
| <div class="flex justify-between items-center mb-6"> |
| <h3 class="text-xl font-bold">Bill Management</h3> |
| <button onclick="hideModal()" class="text-gray-500 hover:text-gray-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6"> |
| <button class="bg-purple-600 text-white px-4 py-2 rounded-lg flex items-center justify-center"> |
| <i class="fas fa-plus mr-2"></i> Create Bill |
| </button> |
| <button class="bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center justify-center"> |
| <i class="fas fa-paper-plane mr-2"></i> Send Bill |
| </button> |
| <button class="bg-green-600 text-white px-4 py-2 rounded-lg flex items-center justify-center"> |
| <i class="fas fa-file-export mr-2"></i> Export Bills |
| </button> |
| </div> |
| <div class="overflow-x-auto"> |
| <table class="min-w-full"> |
| <thead> |
| <tr class="text-left border-b"> |
| <th class="pb-3">Bill #</th> |
| <th class="pb-3">Amount</th> |
| <th class="pb-3">Due Date</th> |
| <th class="pb-3">Status</th> |
| <th class="pb-3">Actions</th> |
| </tr> |
| </thead> |
| <tbody> |
| ${bills.length > 0 ? |
| bills.map(bill => ` |
| <tr class="border-b"> |
| <td class="py-3">${bill.id}</td> |
| <td>${bill.amount} ${bill.currency}</td> |
| <td>${new Date(bill.dueDate).toLocaleDateString()}</td> |
| <td> |
| <span class="px-2 py-1 rounded-full text-xs ${bill.paid ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'}"> |
| ${bill.paid ? 'Paid' : 'Pending'} |
| </span> |
| </td> |
| <td> |
| <button class="text-blue-600 hover:text-blue-800 mr-2"> |
| <i class="fas fa-eye"></i> |
| </button> |
| <button class="text-purple-600 hover:text-purple-800"> |
| <i class="fas fa-edit"></i> |
| </button> |
| </td> |
| </tr> |
| `).join('') : |
| `<tr><td colspan="5" class="py-4 text-center text-gray-500">No bills found</td></tr>` |
| } |
| </tbody> |
| </table> |
| </div> |
| </div> |
| `; |
| showModal(billForm); |
| } |
| |
| |
| function showAdminPanel() { |
| if (!isAdmin) return; |
| |
| const panel = document.getElementById('adminPanel'); |
| const tbody = document.getElementById('usersTableBody'); |
| |
| |
| tbody.innerHTML = users.map(user => ` |
| <tr> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <div class="flex items-center"> |
| <div class="text-sm font-medium text-gray-900">${user.username}</div> |
| ${user.isAdmin ? '<span class="ml-2 px-2 py-1 text-xs bg-purple-100 text-purple-800 rounded">Admin</span>' : ''} |
| </div> |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> |
| ${user.balance} € |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> |
| ${user.lastLogin ? new Date(user.lastLogin).toLocaleString() : 'Never'} |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> |
| <button onclick="viewUserTransactions('${user.username}')" class="text-purple-600 hover:text-purple-900 mr-3">View</button> |
| <button onclick="editUserBalance('${user.username}')" class="text-green-600 hover:text-green-900">Edit</button> |
| </td> |
| </tr> |
| `).join(''); |
| |
| panel.classList.add('active'); |
| } |
| |
| function hideAdminPanel() { |
| document.getElementById('adminPanel').classList.remove('active'); |
| } |
| |
| function viewUserTransactions(username) { |
| const user = users.find(u => u.username === username); |
| if (!user) return; |
| |
| alert(`Transactions for ${username}:\n\n${ |
| user.transactions.map(t => |
| `${t.amount}€ - ${t.type} - ${new Date(t.date).toLocaleDateString()}\nReason: ${t.reason}` |
| ).join('\n\n') || 'No transactions yet' |
| }`); |
| } |
| |
| function editUserBalance(username) { |
| const user = users.find(u => u.username === username); |
| if (!user) return; |
| |
| const amount = prompt(`Enter new balance for ${username}:`, user.balance); |
| if (amount !== null && !isNaN(amount)) { |
| user.balance = parseFloat(amount); |
| localStorage.setItem('users', JSON.stringify(users)); |
| showAdminPanel(); |
| } |
| } |
| |
| |
| resetDataBtn.addEventListener('click', function() { |
| if (confirm('Are you sure you want to reset ALL data? This cannot be undone!')) { |
| users = [{ |
| username: 'admin', |
| password: 'admin123', |
| isAdmin: true, |
| balance: 0, |
| transactions: [] |
| }]; |
| localStorage.setItem('users', JSON.stringify(users)); |
| alert('All data has been reset. Only admin account remains.'); |
| if (currentUser) logout(); |
| } |
| }); |
| |
| |
| logoutBtn.addEventListener('click', logout); |
| |
| function updateDashboard() { |
| if (!currentUser) return; |
| |
| |
| document.getElementById('currentBalance').textContent = `€${currentUser.balance.toFixed(2)}`; |
| |
| |
| const debts = currentUser.transactions?.filter(t => t.type === 'debt') || []; |
| const youOwe = debts.filter(d => d.direction === 'you').reduce((sum, d) => sum + d.amount, 0); |
| const owedToYou = debts.filter(d => d.direction === 'them').reduce((sum, d) => sum + d.amount, 0); |
| |
| document.getElementById('youOwe').textContent = `€${youOwe.toFixed(2)}`; |
| document.getElementById('owedToYou').textContent = `€${owedToYou.toFixed(2)}`; |
| |
| |
| const appointments = currentUser.appointments?.filter(a => |
| new Date(a.date) > new Date() |
| ) || []; |
| |
| document.getElementById('upcomingCount').textContent = appointments.length; |
| |
| const appointmentsTable = document.getElementById('appointmentsTable'); |
| appointmentsTable.innerHTML = appointments.length > 0 ? |
| appointments.map(a => ` |
| <tr class="border-b"> |
| <td class="py-3">${new Date(a.date).toLocaleDateString()}</td> |
| <td>${a.contact || 'N/A'}</td> |
| <td>${a.location || 'N/A'}</td> |
| <td>${a.notes || ''}</td> |
| </tr> |
| `).join('') : |
| `<tr class="border-b"><td class="py-3" colspan="4">No upcoming appointments</td></tr>`; |
| } |
| |
| function logout() { |
| currentUser = null; |
| isAdmin = false; |
| userStatus.querySelector('span').textContent = 'Guest'; |
| adminPanelLink.style.display = 'none'; |
| |
| |
| document.getElementById('dashboard').classList.add('hidden'); |
| document.querySelector('header .container > div:last-child').classList.remove('hidden'); |
| } |
| |
| |
| document.getElementById('googleAuthBtn').addEventListener('click', () => { |
| if (!isOnline) { |
| alert('Internet connection required for calendar integration'); |
| return; |
| } |
| |
| |
| alert('Redirecting to Google for authentication...'); |
| |
| |
| |
| |
| }); |
| |
| |
| document.getElementById('appleAuthBtn').addEventListener('click', () => { |
| if (!isOnline) { |
| alert('Internet connection required for calendar integration'); |
| return; |
| } |
| |
| |
| alert('Redirecting to Apple for authentication...'); |
| }); |
| |
| |
| adminPanelLink.addEventListener('click', function(e) { |
| e.preventDefault(); |
| showAdminPanel(); |
| }); |
| |
| |
| document.getElementById('adminPanel').addEventListener('click', function(e) { |
| if (e.target === this) { |
| hideAdminPanel(); |
| } |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=JOHNFAYEZ/voice-powered-smart-personal-assistant-2" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |
|
|
|
|