nextzendailylife / index.html
nextzendev2's picture
undefined - Initial Deployment
c831ba7 verified
Raw
History Blame
76.9 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Multi-Functional Dashboard</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>
/* Custom CSS for features not covered by Tailwind */
.calendar-day:hover {
background-color: #e2e8f0;
cursor: pointer;
}
.calendar-day.selected {
background-color: #3b82f6;
color: white;
}
.task-completed {
text-decoration: line-through;
color: #9ca3af;
}
#calculator {
grid-template-columns: repeat(4, 1fr);
}
.calculator-btn {
transition: all 0.2s;
}
.calculator-btn:hover {
transform: scale(1.05);
}
.transaction-income {
border-left: 4px solid #10b981;
}
.transaction-expense {
border-left: 4px solid #ef4444;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
</style>
</head>
<body class="bg-gray-100">
<!-- Auth Modal -->
<div id="authModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div class="bg-white rounded-lg p-6 w-full max-w-md">
<div class="flex justify-between items-center mb-4">
<h2 class="text-2xl font-bold" id="authModalTitle">Login</h2>
<button onclick="closeAuthModal()" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div id="authTabs" class="flex border-b mb-4">
<button class="px-4 py-2 font-medium text-blue-500 border-b-2 border-blue-500" onclick="switchAuthTab('login')">Login</button>
<button class="px-4 py-2 font-medium text-gray-500" onclick="switchAuthTab('signup')">Sign Up</button>
</div>
<form id="loginForm" class="space-y-4">
<div>
<label for="loginEmail" class="block text-sm font-medium text-gray-700">Email</label>
<input type="email" id="loginEmail" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<div>
<label for="loginPassword" class="block text-sm font-medium text-gray-700">Password</label>
<input type="password" id="loginPassword" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<button type="button" onclick="loginUser()" class="w-full bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition">Login</button>
</form>
<form id="signupForm" class="space-y-4 hidden">
<div>
<label for="signupName" class="block text-sm font-medium text-gray-700">Name</label>
<input type="text" id="signupName" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<div>
<label for="signupEmail" class="block text-sm font-medium text-gray-700">Email</label>
<input type="email" id="signupEmail" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<div>
<label for="signupPassword" class="block text-sm font-medium text-gray-700">Password</label>
<input type="password" id="signupPassword" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<div>
<label for="signupConfirmPassword" class="block text-sm font-medium text-gray-700">Confirm Password</label>
<input type="password" id="signupConfirmPassword" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<button type="button" onclick="registerUser()" class="w-full bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition">Sign Up</button>
</form>
</div>
</div>
<!-- Main App Container -->
<div class="container mx-auto p-4" id="appContainer" style="display: none;">
<!-- Header -->
<header class="flex justify-between items-center mb-8">
<h1 class="text-3xl font-bold text-blue-600">My Dashboard</h1>
<div class="flex items-center space-x-4">
<span id="userGreeting" class="font-medium"></span>
<button onclick="logoutUser()" class="bg-red-500 text-white px-4 py-2 rounded-md hover:bg-red-600 transition">Logout</button>
</div>
</header>
<!-- Navigation Tabs -->
<div class="flex border-b mb-6">
<button class="px-4 py-2 font-medium text-blue-500 border-b-2 border-blue-500" onclick="switchTab('dashboard')">Dashboard</button>
<button class="px-4 py-2 font-medium text-gray-500" onclick="switchTab('calendar')">Calendar</button>
<button class="px-4 py-2 font-medium text-gray-500" onclick="switchTab('todo')">To-Do</button>
<button class="px-4 py-2 font-medium text-gray-500" onclick="switchTab('notes')">Notes</button>
<button class="px-4 py-2 font-medium text-gray-500" onclick="switchTab('music')">Music</button>
<button class="px-4 py-2 font-medium text-gray-500" onclick="switchTab('transactions')">Transactions</button>
<button class="px-4 py-2 font-medium text-gray-500" onclick="switchTab('calculator')">Calculator</button>
</div>
<!-- Dashboard Tab -->
<div id="dashboard" class="tab-content active">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Calendar Widget -->
<div class="bg-white rounded-lg shadow p-4">
<h2 class="text-xl font-bold mb-4">Today's Date</h2>
<div id="dashboardCalendar" class="text-center">
<div class="text-2xl font-bold" id="dashboardDate"></div>
<div class="text-gray-500" id="dashboardDay"></div>
</div>
</div>
<!-- Todo Summary -->
<div class="bg-white rounded-lg shadow p-4">
<h2 class="text-xl font-bold mb-4">Tasks Summary</h2>
<div id="todoSummary">
<p>Loading tasks...</p>
</div>
</div>
<!-- Recent Transactions -->
<div class="bg-white rounded-lg shadow p-4">
<h2 class="text-xl font-bold mb-4">Recent Transactions</h2>
<div id="transactionSummary">
<p>Loading transactions...</p>
</div>
</div>
</div>
</div>
<!-- Calendar Tab -->
<div id="calendar" class="tab-content">
<div class="bg-white rounded-lg shadow p-4">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold">Calendar</h2>
<div class="flex space-x-2">
<button onclick="prevMonth()" class="bg-gray-200 p-2 rounded-md hover:bg-gray-300">
<i class="fas fa-chevron-left"></i>
</button>
<button onclick="nextMonth()" class="bg-gray-200 p-2 rounded-md hover:bg-gray-300">
<i class="fas fa-chevron-right"></i>
</button>
<button onclick="goToToday()" class="bg-blue-500 text-white px-3 py-1 rounded-md hover:bg-blue-600">
Today
</button>
</div>
</div>
<div class="mb-4">
<h3 class="text-lg font-semibold" id="currentMonthYear"></h3>
</div>
<div class="grid grid-cols-7 gap-1">
<div class="text-center font-medium py-2">Sun</div>
<div class="text-center font-medium py-2">Mon</div>
<div class="text-center font-medium py-2">Tue</div>
<div class="text-center font-medium py-2">Wed</div>
<div class="text-center font-medium py-2">Thu</div>
<div class="text-center font-medium py-2">Fri</div>
<div class="text-center font-medium py-2">Sat</div>
</div>
<div class="grid grid-cols-7 gap-1" id="calendarDays"></div>
</div>
</div>
<!-- Todo Tab -->
<div id="todo" class="tab-content">
<div class="bg-white rounded-lg shadow p-4">
<h2 class="text-xl font-bold mb-4">To-Do List</h2>
<div class="flex mb-4">
<input type="text" id="newTaskInput" placeholder="Add a new task..." class="flex-grow p-2 border rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<button onclick="addTask()" class="bg-blue-500 text-white px-4 py-2 rounded-r-md hover:bg-blue-600 transition">Add</button>
</div>
<div class="space-y-2" id="taskList">
<!-- Tasks will be loaded here -->
</div>
</div>
</div>
<!-- Notes Tab -->
<div id="notes" class="tab-content">
<div class="bg-white rounded-lg shadow p-4">
<h2 class="text-xl font-bold mb-4">Notes</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6" id="notesList">
<!-- Notes will be loaded here -->
</div>
<div class="mt-4">
<h3 class="text-lg font-semibold mb-2">Add New Note</h3>
<input type="text" id="noteTitle" placeholder="Note title" class="w-full p-2 border rounded-md mb-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
<textarea id="noteContent" placeholder="Note content" class="w-full p-2 border rounded-md h-32 focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea>
<button onclick="saveNote()" class="mt-2 bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600 transition">Save Note</button>
</div>
</div>
</div>
<!-- Music Tab -->
<div id="music" class="tab-content">
<div class="bg-white rounded-lg shadow p-4">
<h2 class="text-xl font-bold mb-4">Music Collection</h2>
<div class="flex mb-4">
<input type="text" id="songSearch" placeholder="Search songs..." class="flex-grow p-2 border rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<button onclick="searchSongs()" class="bg-blue-500 text-white px-4 py-2 rounded-r-md hover:bg-blue-600 transition">Search</button>
</div>
<div class="mb-4">
<button onclick="showAddSongForm()" class="bg-green-500 text-white px-4 py-2 rounded-md hover:bg-green-600 transition">Add New Song</button>
</div>
<div class="overflow-x-auto">
<table class="min-w-full bg-white">
<thead>
<tr>
<th class="py-2 px-4 border-b">Title</th>
<th class="py-2 px-4 border-b">Artist</th>
<th class="py-2 px-4 border-b">Album</th>
<th class="py-2 px-4 border-b">Year</th>
<th class="py-2 px-4 border-b">Actions</th>
</tr>
</thead>
<tbody id="songsTable">
<!-- Songs will be loaded here -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Add Song Form (Hidden by default) -->
<div id="addSongForm" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-40 hidden">
<div class="bg-white rounded-lg p-6 w-full max-w-md">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold">Add New Song</h2>
<button onclick="hideAddSongForm()" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="space-y-4">
<div>
<label for="songTitle" class="block text-sm font-medium text-gray-700">Title</label>
<input type="text" id="songTitle" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<div>
<label for="songArtist" class="block text-sm font-medium text-gray-700">Artist</label>
<input type="text" id="songArtist" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<div>
<label for="songAlbum" class="block text-sm font-medium text-gray-700">Album</label>
<input type="text" id="songAlbum" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<div>
<label for="songYear" class="block text-sm font-medium text-gray-700">Year</label>
<input type="number" id="songYear" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<div>
<label for="songGenre" class="block text-sm font-medium text-gray-700">Genre</label>
<input type="text" id="songGenre" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border">
</div>
<button onclick="addNewSong()" class="w-full bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition">Save Song</button>
</div>
</div>
</div>
<!-- Transactions Tab -->
<div id="transactions" class="tab-content">
<div class="bg-white rounded-lg shadow p-4">
<h2 class="text-xl font-bold mb-4">Daily Transactions</h2>
<div class="mb-6">
<div class="flex mb-4">
<select id="transactionType" class="p-2 border rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="income">Income</option>
<option value="expense">Expense</option>
</select>
<input type="number" id="transactionAmount" placeholder="Amount" class="p-2 border-t border-b focus:outline-none focus:ring-2 focus:ring-blue-500">
<select id="transactionCategory" class="p-2 border-t border-b focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="salary">Salary</option>
<option value="freelance">Freelance</option>
<option value="investment">Investment</option>
<option value="food">Food</option>
<option value="transport">Transport</option>
<option value="entertainment">Entertainment</option>
<option value="shopping">Shopping</option>
<option value="other">Other</option>
</select>
<input type="text" id="transactionDescription" placeholder="Description" class="p-2 border-t border-b focus:outline-none focus:ring-2 focus:ring-blue-500">
<button onclick="addTransaction()" class="bg-blue-500 text-white px-4 py-2 rounded-r-md hover:bg-blue-600 transition">Add</button>
</div>
</div>
<div class="mb-4">
<h3 class="text-lg font-semibold">Transaction History</h3>
<div class="flex justify-between items-center mb-2">
<div>
<label for="transactionMonth" class="mr-2">Month:</label>
<select id="transactionMonth" class="p-1 border rounded">
<option value="01">January</option>
<option value="02">February</option>
<option value="03">March</option>
<option value="04">April</option>
<option value="05">May</option>
<option value="06">June</option>
<option value="07">July</option>
<option value="08">August</option>
<option value="09">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
</div>
<button onclick="loadTransactions()" class="bg-blue-500 text-white px-3 py-1 rounded-md hover:bg-blue-600">Filter</button>
</div>
</div>
<div class="space-y-2" id="transactionsList">
<!-- Transactions will be loaded here -->
</div>
<div class="mt-4 p-4 bg-gray-100 rounded-md">
<h3 class="text-lg font-semibold mb-2">Summary</h3>
<div class="grid grid-cols-2 gap-4">
<div>
<p class="text-green-600 font-medium">Total Income: <span id="totalIncome">₹0</span></p>
</div>
<div>
<p class="text-red-600 font-medium">Total Expenses: <span id="totalExpenses">₹0</span></p>
</div>
<div class="col-span-2">
<p class="font-bold">Balance: <span id="balance">₹0</span></p>
</div>
</div>
</div>
</div>
</div>
<!-- Calculator Tab -->
<div id="calculator" class="tab-content">
<div class="bg-white rounded-lg shadow p-4 max-w-md mx-auto">
<h2 class="text-xl font-bold mb-4 text-center">Calculator</h2>
<div class="mb-4">
<input type="text" id="calculatorDisplay" class="w-full p-4 text-right text-2xl border rounded-md bg-gray-50" readonly>
</div>
<div class="grid grid-cols-4 gap-2" id="calculatorButtons">
<button onclick="appendToDisplay('7')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">7</button>
<button onclick="appendToDisplay('8')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">8</button>
<button onclick="appendToDisplay('9')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">9</button>
<button onclick="clearDisplay()" class="calculator-btn bg-red-500 text-white p-4 rounded-md hover:bg-red-600">C</button>
<button onclick="appendToDisplay('4')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">4</button>
<button onclick="appendToDisplay('5')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">5</button>
<button onclick="appendToDisplay('6')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">6</button>
<button onclick="appendToDisplay('+')" class="calculator-btn bg-blue-500 text-white p-4 rounded-md hover:bg-blue-600">+</button>
<button onclick="appendToDisplay('1')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">1</button>
<button onclick="appendToDisplay('2')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">2</button>
<button onclick="appendToDisplay('3')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">3</button>
<button onclick="appendToDisplay('-')" class="calculator-btn bg-blue-500 text-white p-4 rounded-md hover:bg-blue-600">-</button>
<button onclick="appendToDisplay('0')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">0</button>
<button onclick="appendToDisplay('.')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">.</button>
<button onclick="calculate()" class="calculator-btn bg-green-500 text-white p-4 rounded-md hover:bg-green-600">=</button>
<button onclick="appendToDisplay('*')" class="calculator-btn bg-blue-500 text-white p-4 rounded-md hover:bg-blue-600">×</button>
<button onclick="appendToDisplay('/')" class="calculator-btn bg-blue-500 text-white p-4 rounded-md hover:bg-blue-600">÷</button>
<button onclick="backspace()" class="calculator-btn bg-gray-300 p-4 rounded-md hover:bg-gray-400"></button>
<button onclick="appendToDisplay('(')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">(</button>
<button onclick="appendToDisplay(')')" class="calculator-btn bg-gray-200 p-4 rounded-md hover:bg-gray-300">)</button>
</div>
</div>
</div>
</div>
<script>
// Global variables
let currentUser = null;
let currentDate = new Date();
let currentMonth = currentDate.getMonth();
let currentYear = currentDate.getFullYear();
// Initialize the app when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
checkAuthStatus();
updateDashboardDate();
generateCalendar(currentMonth, currentYear);
// Show auth modal if not logged in
if (!currentUser) {
document.getElementById('authModal').classList.remove('hidden');
}
});
// Authentication functions
function checkAuthStatus() {
// In a real app, this would check localStorage or cookies for auth token
// For demo purposes, we'll just check if currentUser is set
if (currentUser) {
document.getElementById('appContainer').style.display = 'block';
document.getElementById('authModal').classList.add('hidden');
document.getElementById('userGreeting').textContent = `Hello, ${currentUser.name}`;
loadInitialData();
} else {
document.getElementById('appContainer').style.display = 'none';
}
}
function switchAuthTab(tab) {
if (tab === 'login') {
document.getElementById('loginForm').classList.remove('hidden');
document.getElementById('signupForm').classList.add('hidden');
document.querySelector('#authTabs button:first-child').classList.add('text-blue-500', 'border-blue-500');
document.querySelector('#authTabs button:first-child').classList.remove('text-gray-500');
document.querySelector('#authTabs button:last-child').classList.add('text-gray-500');
document.querySelector('#authTabs button:last-child').classList.remove('text-blue-500', 'border-blue-500');
document.getElementById('authModalTitle').textContent = 'Login';
} else {
document.getElementById('loginForm').classList.add('hidden');
document.getElementById('signupForm').classList.remove('hidden');
document.querySelector('#authTabs button:first-child').classList.add('text-gray-500');
document.querySelector('#authTabs button:first-child').classList.remove('text-blue-500', 'border-blue-500');
document.querySelector('#authTabs button:last-child').classList.add('text-blue-500', 'border-blue-500');
document.querySelector('#authTabs button:last-child').classList.remove('text-gray-500');
document.getElementById('authModalTitle').textContent = 'Sign Up';
}
}
function closeAuthModal() {
document.getElementById('authModal').classList.add('hidden');
}
function loginUser() {
const email = document.getElementById('loginEmail').value;
const password = document.getElementById('loginPassword').value;
if (!email || !password) {
alert('Please enter both email and password');
return;
}
// In a real app, this would make an API call to your PHP backend
// For demo purposes, we'll simulate a successful login
simulateApiCall('login', {email, password})
.then(response => {
if (response.success) {
currentUser = response.user;
checkAuthStatus();
closeAuthModal();
} else {
alert(response.message || 'Login failed');
}
})
.catch(error => {
console.error('Login error:', error);
alert('An error occurred during login');
});
}
function registerUser() {
const name = document.getElementById('signupName').value;
const email = document.getElementById('signupEmail').value;
const password = document.getElementById('signupPassword').value;
const confirmPassword = document.getElementById('signupConfirmPassword').value;
if (!name || !email || !password || !confirmPassword) {
alert('Please fill in all fields');
return;
}
if (password !== confirmPassword) {
alert('Passwords do not match');
return;
}
// In a real app, this would make an API call to your PHP backend
simulateApiCall('register', {name, email, password})
.then(response => {
if (response.success) {
alert('Registration successful! Please login.');
switchAuthTab('login');
// Clear the form
document.getElementById('signupName').value = '';
document.getElementById('signupEmail').value = '';
document.getElementById('signupPassword').value = '';
document.getElementById('signupConfirmPassword').value = '';
} else {
alert(response.message || 'Registration failed');
}
})
.catch(error => {
console.error('Registration error:', error);
alert('An error occurred during registration');
});
}
function logoutUser() {
// In a real app, this would also clear the auth token from storage
currentUser = null;
checkAuthStatus();
document.getElementById('authModal').classList.remove('hidden');
}
// Tab navigation
function switchTab(tabId) {
// Hide all tab contents
document.querySelectorAll('.tab-content').forEach(tab => {
tab.classList.remove('active');
});
// Show the selected tab
document.getElementById(tabId).classList.add('active');
// Update tab buttons styling
const tabButtons = document.querySelectorAll('.flex.border-b button');
tabButtons.forEach(button => {
if (button.textContent.toLowerCase().includes(tabId)) {
button.classList.add('text-blue-500', 'border-b-2', 'border-blue-500');
button.classList.remove('text-gray-500');
} else {
button.classList.add('text-gray-500');
button.classList.remove('text-blue-500', 'border-b-2', 'border-blue-500');
}
});
// Load data for the tab if needed
if (tabId === 'todo') {
loadTasks();
} else if (tabId === 'notes') {
loadNotes();
} else if (tabId === 'music') {
loadSongs();
} else if (tabId === 'transactions') {
loadTransactions();
}
}
// Dashboard functions
function updateDashboardDate() {
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const today = new Date();
document.getElementById('dashboardDate').textContent = today.getDate();
document.getElementById('dashboardDay').textContent = `${days[today.getDay()]}, ${months[today.getMonth()]} ${today.getFullYear()}`;
}
function loadInitialData() {
loadTasks();
loadNotes();
loadSongs();
loadTransactions();
// Update dashboard summaries
updateTodoSummary();
updateTransactionSummary();
}
// Calendar functions
function generateCalendar(month, year) {
const calendarDays = document.getElementById('calendarDays');
calendarDays.innerHTML = '';
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
const daysInMonth = lastDay.getDate();
const startingDay = firstDay.getDay();
// Update month/year display
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
document.getElementById('currentMonthYear').textContent = `${months[month]} ${year}`;
// Add empty cells for days before the first day of the month
for (let i = 0; i < startingDay; i++) {
const emptyDay = document.createElement('div');
emptyDay.className = 'p-2 text-center text-gray-400';
calendarDays.appendChild(emptyDay);
}
// Add cells for each day of the month
for (let day = 1; day <= daysInMonth; day++) {
const dayElement = document.createElement('div');
dayElement.className = 'p-2 text-center calendar-day rounded-md';
dayElement.textContent = day;
// Highlight today
const today = new Date();
if (day === today.getDate() && month === today.getMonth() && year === today.getFullYear()) {
dayElement.classList.add('bg-blue-100', 'font-bold');
}
// Add click event
dayElement.addEventListener('click', function() {
document.querySelectorAll('.calendar-day').forEach(el => el.classList.remove('selected'));
this.classList.add('selected');
// You could load events for this day here
});
calendarDays.appendChild(dayElement);
}
}
function prevMonth() {
currentMonth--;
if (currentMonth < 0) {
currentMonth = 11;
currentYear--;
}
generateCalendar(currentMonth, currentYear);
}
function nextMonth() {
currentMonth++;
if (currentMonth > 11) {
currentMonth = 0;
currentYear++;
}
generateCalendar(currentMonth, currentYear);
}
function goToToday() {
const today = new Date();
currentMonth = today.getMonth();
currentYear = today.getFullYear();
generateCalendar(currentMonth, currentYear);
}
// Todo functions
function loadTasks() {
// In a real app, this would fetch tasks from your PHP backend
simulateApiCall('getTasks', {userId: currentUser?.id})
.then(response => {
const taskList = document.getElementById('taskList');
taskList.innerHTML = '';
if (response.tasks && response.tasks.length > 0) {
response.tasks.forEach(task => {
const taskElement = document.createElement('div');
taskElement.className = 'flex items-center p-2 border rounded-md';
if (task.completed) {
taskElement.classList.add('bg-gray-100');
}
taskElement.innerHTML = `
<input type="checkbox" ${task.completed ? 'checked' : ''}
onchange="toggleTaskCompletion(${task.id}, this)"
class="mr-2 h-5 w-5">
<span class="flex-grow ${task.completed ? 'task-completed' : ''}">${task.title}</span>
<button onclick="deleteTask(${task.id}, this.parentNode)" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash"></i>
</button>
`;
taskList.appendChild(taskElement);
});
} else {
taskList.innerHTML = '<p class="text-gray-500">No tasks found. Add a task to get started!</p>';
}
// Update dashboard summary
updateTodoSummary();
})
.catch(error => {
console.error('Error loading tasks:', error);
document.getElementById('taskList').innerHTML = '<p class="text-red-500">Error loading tasks. Please try again.</p>';
});
}
function addTask() {
const taskInput = document.getElementById('newTaskInput');
const taskTitle = taskInput.value.trim();
if (!taskTitle) {
alert('Please enter a task');
return;
}
// In a real app, this would send the task to your PHP backend
simulateApiCall('addTask', {userId: currentUser?.id, title: taskTitle})
.then(response => {
if (response.success) {
taskInput.value = '';
loadTasks();
} else {
alert(response.message || 'Failed to add task');
}
})
.catch(error => {
console.error('Error adding task:', error);
alert('An error occurred while adding the task');
});
}
function toggleTaskCompletion(taskId, checkbox) {
const completed = checkbox.checked;
// In a real app, this would update the task status via your PHP backend
simulateApiCall('updateTask', {taskId, completed})
.then(response => {
if (!response.success) {
// Revert the checkbox if the update failed
checkbox.checked = !completed;
alert(response.message || 'Failed to update task');
} else {
const taskText = checkbox.nextElementSibling;
if (completed) {
taskText.classList.add('task-completed');
checkbox.parentNode.classList.add('bg-gray-100');
} else {
taskText.classList.remove('task-completed');
checkbox.parentNode.classList.remove('bg-gray-100');
}
// Update dashboard summary
updateTodoSummary();
}
})
.catch(error => {
console.error('Error updating task:', error);
checkbox.checked = !completed;
alert('An error occurred while updating the task');
});
}
function deleteTask(taskId, taskElement) {
if (!confirm('Are you sure you want to delete this task?')) {
return;
}
// In a real app, this would delete the task via your PHP backend
simulateApiCall('deleteTask', {taskId})
.then(response => {
if (response.success) {
taskElement.remove();
// Check if there are no tasks left
const taskList = document.getElementById('taskList');
if (taskList.children.length === 0) {
taskList.innerHTML = '<p class="text-gray-500">No tasks found. Add a task to get started!</p>';
}
// Update dashboard summary
updateTodoSummary();
} else {
alert(response.message || 'Failed to delete task');
}
})
.catch(error => {
console.error('Error deleting task:', error);
alert('An error occurred while deleting the task');
});
}
function updateTodoSummary() {
// In a real app, this would fetch task stats from your PHP backend
simulateApiCall('getTaskStats', {userId: currentUser?.id})
.then(response => {
const summaryElement = document.getElementById('todoSummary');
if (response.totalTasks === 0) {
summaryElement.innerHTML = '<p>You have no tasks yet.</p>';
} else {
const completionPercentage = Math.round((response.completedTasks / response.totalTasks) * 100);
summaryElement.innerHTML = `
<div class="mb-2">
<p>Total tasks: ${response.totalTasks}</p>
<p>Completed: ${response.completedTasks}</p>
<p>Pending: ${response.totalTasks - response.completedTasks}</p>
</div>
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div class="bg-blue-600 h-2.5 rounded-full" style="width: ${completionPercentage}%"></div>
</div>
<p class="mt-1 text-sm text-gray-600">${completionPercentage}% completed</p>
`;
}
})
.catch(error => {
console.error('Error loading task summary:', error);
document.getElementById('todoSummary').innerHTML = '<p class="text-red-500">Error loading task summary</p>';
});
}
// Notes functions
function loadNotes() {
// In a real app, this would fetch notes from your PHP backend
simulateApiCall('getNotes', {userId: currentUser?.id})
.then(response => {
const notesList = document.getElementById('notesList');
notesList.innerHTML = '';
if (response.notes && response.notes.length > 0) {
response.notes.forEach(note => {
const noteElement = document.createElement('div');
noteElement.className = 'border rounded-md p-4 bg-white shadow-sm';
noteElement.innerHTML = `
<h4 class="font-bold mb-2">${note.title}</h4>
<p class="text-gray-700 mb-3">${note.content.substring(0, 100)}${note.content.length > 100 ? '...' : ''}</p>
<div class="flex justify-between text-sm text-gray-500">
<span>${new Date(note.created_at).toLocaleDateString()}</span>
<div>
<button onclick="editNote(${note.id})" class="text-blue-500 hover:text-blue-700 mr-2">
<i class="fas fa-edit"></i>
</button>
<button onclick="deleteNote(${note.id})" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
`;
notesList.appendChild(noteElement);
});
} else {
notesList.innerHTML = '<p class="text-gray-500 col-span-3">No notes found. Create your first note!</p>';
}
})
.catch(error => {
console.error('Error loading notes:', error);
document.getElementById('notesList').innerHTML = '<p class="text-red-500 col-span-3">Error loading notes. Please try again.</p>';
});
}
function saveNote() {
const title = document.getElementById('noteTitle').value.trim();
const content = document.getElementById('noteContent').value.trim();
if (!title || !content) {
alert('Please enter both title and content');
return;
}
// In a real app, this would save the note via your PHP backend
simulateApiCall('saveNote', {userId: currentUser?.id, title, content})
.then(response => {
if (response.success) {
// Clear the form
document.getElementById('noteTitle').value = '';
document.getElementById('noteContent').value = '';
// Reload notes
loadNotes();
} else {
alert(response.message || 'Failed to save note');
}
})
.catch(error => {
console.error('Error saving note:', error);
alert('An error occurred while saving the note');
});
}
function editNote(noteId) {
// In a real app, this would fetch the note details from your PHP backend
simulateApiCall('getNote', {noteId})
.then(response => {
if (response.note) {
document.getElementById('noteTitle').value = response.note.title;
document.getElementById('noteContent').value = response.note.content;
// Change the save button to update
const saveButton = document.querySelector('#notes button');
saveButton.textContent = 'Update Note';
saveButton.onclick = function() {
updateNote(noteId);
};
// Scroll to the form
document.getElementById('noteTitle').scrollIntoView({behavior: 'smooth'});
} else {
alert('Note not found');
}
})
.catch(error => {
console.error('Error fetching note:', error);
alert('An error occurred while fetching the note');
});
}
function updateNote(noteId) {
const title = document.getElementById('noteTitle').value.trim();
const content = document.getElementById('noteContent').value.trim();
if (!title || !content) {
alert('Please enter both title and content');
return;
}
// In a real app, this would update the note via your PHP backend
simulateApiCall('updateNote', {noteId, title, content})
.then(response => {
if (response.success) {
// Clear the form
document.getElementById('noteTitle').value = '';
document.getElementById('noteContent').value = '';
// Change the button back to save
const saveButton = document.querySelector('#notes button');
saveButton.textContent = 'Save Note';
saveButton.onclick = saveNote;
// Reload notes
loadNotes();
} else {
alert(response.message || 'Failed to update note');
}
})
.catch(error => {
console.error('Error updating note:', error);
alert('An error occurred while updating the note');
});
}
function deleteNote(noteId) {
if (!confirm('Are you sure you want to delete this note?')) {
return;
}
// In a real app, this would delete the note via your PHP backend
simulateApiCall('deleteNote', {noteId})
.then(response => {
if (response.success) {
loadNotes();
} else {
alert(response.message || 'Failed to delete note');
}
})
.catch(error => {
console.error('Error deleting note:', error);
alert('An error occurred while deleting the note');
});
}
// Music functions
function loadSongs() {
// In a real app, this would fetch songs from your PHP backend
simulateApiCall('getSongs', {userId: currentUser?.id})
.then(response => {
const songsTable = document.getElementById('songsTable');
songsTable.innerHTML = '';
if (response.songs && response.songs.length > 0) {
response.songs.forEach(song => {
const songRow = document.createElement('tr');
songRow.className = 'hover:bg-gray-50';
songRow.innerHTML = `
<td class="py-2 px-4 border-b">${song.title}</td>
<td class="py-2 px-4 border-b">${song.artist}</td>
<td class="py-2 px-4 border-b">${song.album}</td>
<td class="py-2 px-4 border-b">${song.year}</td>
<td class="py-2 px-4 border-b">
<button onclick="showSongDetails(${song.id})" class="text-blue-500 hover:text-blue-700 mr-2">
<i class="fas fa-eye"></i>
</button>
<button onclick="deleteSong(${song.id})" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash"></i>
</button>
</td>
`;
songsTable.appendChild(songRow);
});
} else {
songsTable.innerHTML = `
<tr>
<td colspan="5" class="py-4 text-center text-gray-500">No songs found. Add your first song!</td>
</tr>
`;
}
})
.catch(error => {
console.error('Error loading songs:', error);
document.getElementById('songsTable').innerHTML = `
<tr>
<td colspan="5" class="py-4 text-center text-red-500">Error loading songs. Please try again.</td>
</tr>
`;
});
}
function showAddSongForm() {
document.getElementById('addSongForm').classList.remove('hidden');
}
function hideAddSongForm() {
document.getElementById('addSongForm').classList.add('hidden');
// Clear the form
document.getElementById('songTitle').value = '';
document.getElementById('songArtist').value = '';
document.getElementById('songAlbum').value = '';
document.getElementById('songYear').value = '';
document.getElementById('songGenre').value = '';
}
function addNewSong() {
const title = document.getElementById('songTitle').value.trim();
const artist = document.getElementById('songArtist').value.trim();
const album = document.getElementById('songAlbum').value.trim();
const year = document.getElementById('songYear').value.trim();
const genre = document.getElementById('songGenre').value.trim();
if (!title || !artist) {
alert('Please at least enter title and artist');
return;
}
// In a real app, this would save the song via your PHP backend
simulateApiCall('addSong', {userId: currentUser?.id, title, artist, album, year, genre})
.then(response => {
if (response.success) {
hideAddSongForm();
loadSongs();
} else {
alert(response.message || 'Failed to add song');
}
})
.catch(error => {
console.error('Error adding song:', error);
alert('An error occurred while adding the song');
});
}
function showSongDetails(songId) {
// In a real app, this would fetch song details from your PHP backend
simulateApiCall('getSongDetails', {songId})
.then(response => {
if (response.song) {
const song = response.song;
alert(`Song Details:\n\nTitle: ${song.title}\nArtist: ${song.artist}\nAlbum: ${song.album}\nYear: ${song.year}\nGenre: ${song.genre}`);
} else {
alert('Song not found');
}
})
.catch(error => {
console.error('Error fetching song details:', error);
alert('An error occurred while fetching song details');
});
}
function deleteSong(songId) {
if (!confirm('Are you sure you want to delete this song?')) {
return;
}
// In a real app, this would delete the song via your PHP backend
simulateApiCall('deleteSong', {songId})
.then(response => {
if (response.success) {
loadSongs();
} else {
alert(response.message || 'Failed to delete song');
}
})
.catch(error => {
console.error('Error deleting song:', error);
alert('An error occurred while deleting the song');
});
}
function searchSongs() {
const searchTerm = document.getElementById('songSearch').value.trim();
if (!searchTerm) {
loadSongs();
return;
}
// In a real app, this would search songs via your PHP backend
simulateApiCall('searchSongs', {userId: currentUser?.id, searchTerm})
.then(response => {
const songsTable = document.getElementById('songsTable');
songsTable.innerHTML = '';
if (response.songs && response.songs.length > 0) {
response.songs.forEach(song => {
const songRow = document.createElement('tr');
songRow.className = 'hover:bg-gray-50';
songRow.innerHTML = `
<td class="py-2 px-4 border-b">${song.title}</td>
<td class="py-2 px-4 border-b">${song.artist}</td>
<td class="py-2 px-4 border-b">${song.album}</td>
<td class="py-2 px-4 border-b">${song.year}</td>
<td class="py-2 px-4 border-b">
<button onclick="showSongDetails(${song.id})" class="text-blue-500 hover:text-blue-700 mr-2">
<i class="fas fa-eye"></i>
</button>
<button onclick="deleteSong(${song.id})" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash"></i>
</button>
</td>
`;
songsTable.appendChild(songRow);
});
} else {
songsTable.innerHTML = `
<tr>
<td colspan="5" class="py-4 text-center text-gray-500">No songs found matching "${searchTerm}"</td>
</tr>
`;
}
})
.catch(error => {
console.error('Error searching songs:', error);
document.getElementById('songsTable').innerHTML = `
<tr>
<td colspan="5" class="py-4 text-center text-red-500">Error searching songs. Please try again.</td>
</tr>
`;
});
}
// Transaction functions
function loadTransactions() {
const month = document.getElementById('transactionMonth').value;
// In a real app, this would fetch transactions from your PHP backend
simulateApiCall('getTransactions', {userId: currentUser?.id, month})
.then(response => {
const transactionsList = document.getElementById('transactionsList');
transactionsList.innerHTML = '';
if (response.transactions && response.transactions.length > 0) {
response.transactions.forEach(transaction => {
const transactionElement = document.createElement('div');
transactionElement.className = `p-3 bg-white rounded-md shadow-sm ${transaction.type === 'income' ? 'transaction-income' : 'transaction-expense'}`;
transactionElement.innerHTML = `
<div class="flex justify-between items-center">
<div>
<p class="font-medium">${transaction.description}</p>
<p class="text-sm text-gray-500">${transaction.category}${new Date(transaction.date).toLocaleDateString()}</p>
</div>
<div class="text-right">
<p class="${transaction.type === 'income' ? 'text-green-600' : 'text-red-600'} font-medium">
${transaction.type === 'income' ? '+' : '-'}${transaction.amount.toFixed(2)}
</p>
<button onclick="deleteTransaction(${transaction.id}, this.parentNode.parentNode)" class="text-red-500 text-sm hover:text-red-700">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
`;
transactionsList.appendChild(transactionElement);
});
} else {
transactionsList.innerHTML = '<p class="text-gray-500">No transactions found for this month.</p>';
}
// Update summary
updateTransactionSummary(response.summary);
})
.catch(error => {
console.error('Error loading transactions:', error);
document.getElementById('transactionsList').innerHTML = '<p class="text-red-500">Error loading transactions. Please try again.</p>';
});
}
function addTransaction() {
const type = document.getElementById('transactionType').value;
const amount = parseFloat(document.getElementById('transactionAmount').value);
const category = document.getElementById('transactionCategory').value;
const description = document.getElementById('transactionDescription').value.trim();
if (!amount || isNaN(amount) || amount <= 0) {
alert('Please enter a valid amount');
return;
}
if (!description) {
alert('Please enter a description');
return;
}
// In a real app, this would save the transaction via your PHP backend
simulateApiCall('addTransaction', {userId: currentUser?.id, type, amount, category, description})
.then(response => {
if (response.success) {
// Clear the form
document.getElementById('transactionAmount').value = '';
document.getElementById('transactionDescription').value = '';
// Reload transactions
loadTransactions();
// Update dashboard summary
updateTransactionSummary();
} else {
alert(response.message || 'Failed to add transaction');
}
})
.catch(error => {
console.error('Error adding transaction:', error);
alert('An error occurred while adding the transaction');
});
}
function deleteTransaction(transactionId, transactionElement) {
if (!confirm('Are you sure you want to delete this transaction?')) {
return;
}
// In a real app, this would delete the transaction via your PHP backend
simulateApiCall('deleteTransaction', {transactionId})
.then(response => {
if (response.success) {
transactionElement.remove();
// Check if there are no transactions left
const transactionsList = document.getElementById('transactionsList');
if (transactionsList.children.length === 0) {
transactionsList.innerHTML = '<p class="text-gray-500">No transactions found for this month.</p>';
}
// Update summary
updateTransactionSummary();
} else {
alert(response.message || 'Failed to delete transaction');
}
})
.catch(error => {
console.error('Error deleting transaction:', error);
alert('An error occurred while deleting the transaction');
});
}
function updateTransactionSummary(summary) {
// If summary is not provided, fetch it from the server
if (!summary) {
const month = document.getElementById('transactionMonth').value;
// In a real app, this would fetch transaction stats from your PHP backend
simulateApiCall('getTransactionSummary', {userId: currentUser?.id, month})
.then(response => {
displayTransactionSummary(response);
})
.catch(error => {
console.error('Error loading transaction summary:', error);
document.getElementById('transactionSummary').innerHTML = '<p class="text-red-500">Error loading summary</p>';
});
} else {
displayTransactionSummary(summary);
}
}
function displayTransactionSummary(summary) {
const summaryElement = document.getElementById('transactionSummary');
if (summary.totalTransactions === 0) {
summaryElement.innerHTML = '<p>No transactions this month.</p>';
} else {
const balance = summary.totalIncome - summary.totalExpenses;
const balanceClass = balance >= 0 ? 'text-green-600' : 'text-red-600';
summaryElement.innerHTML = `
<div class="grid grid-cols-2 gap-4">
<div class="bg-green-50 p-3 rounded-md">
<p class="text-sm text-green-600">Income</p>
<p class="text-xl font-bold text-green-600">₹${summary.totalIncome.toFixed(2)}</p>
</div>
<div class="bg-red-50 p-3 rounded-md">
<p class="text-sm text-red-600">Expenses</p>
<p class="text-xl font-bold text-red-600">₹${summary.totalExpenses.toFixed(2)}</p>
</div>
</div>
<div class="mt-4 p-3 bg-blue-50 rounded-md">
<p class="text-sm text-blue-600">Balance</p>
<p class="text-xl font-bold ${balanceClass}">₹${Math.abs(balance).toFixed(2)} ${balance >= 0 ? '(Surplus)' : '(Deficit)'}</p>
</div>
`;
// Update the summary in the transactions tab
document.getElementById('totalIncome').textContent = `₹${summary.totalIncome.toFixed(2)}`;
document.getElementById('totalExpenses').textContent = `₹${summary.totalExpenses.toFixed(2)}`;
const tabBalance = summary.totalIncome - summary.totalExpenses;
const tabBalanceClass = tabBalance >= 0 ? 'text-green-600' : 'text-red-600';
document.getElementById('balance').className = tabBalanceClass;
document.getElementById('balance').textContent = `₹${Math.abs(tabBalance).toFixed(2)}`;
}
}
// Calculator functions
function appendToDisplay(value) {
const display = document.getElementById('calculatorDisplay');
display.value += value;
}
function clearDisplay() {
document.getElementById('calculatorDisplay').value = '';
}
function backspace() {
const display = document.getElementById('calculatorDisplay');
display.value = display.value.slice(0, -1);
}
function calculate() {
const display = document.getElementById('calculatorDisplay');
try {
// Replace × with * and ÷ with / for evaluation
const expression = display.value.replace(/×/g, '*').replace(/÷/g, '/');
display.value = eval(expression);
} catch (error) {
display.value = 'Error';
}
}
// Helper function to simulate API calls (in a real app, these would be actual API calls to your PHP backend)
function simulateApiCall(endpoint, data) {
console.log(`Simulating API call to ${endpoint}`, data);
// Return a promise to simulate async API call
return new Promise((resolve) => {
setTimeout(() => {
// Simulate different responses based on endpoint
switch(endpoint) {
case 'login':
if (data.email === 'user@example.com' && data.password === 'password') {
resolve({
success: true,
user: {
id: 1,
name: 'Demo User',
email: data.email
}
});
} else {
resolve({
success: false,
message: 'Invalid email or password'
});
}
break;
case 'register':
resolve({
success: true,
message: 'Registration successful'
});
break;
case 'getTasks':
resolve({
tasks: [
{ id: 1, title: 'Complete project proposal', completed: false },
{ id: 2, title: 'Buy groceries', completed: true },
{ id: 3, title: 'Call mom', completed: false }
]
});
break;
case 'addTask':
resolve({
success: true,
taskId: Math.floor(Math.random() * 1000) + 4
});
break;
case 'updateTask':
resolve({ success: true });
break;
case 'deleteTask':
resolve({ success: true });
break;
case 'getTaskStats':
resolve({
totalTasks: 3,
completedTasks: 1
});
break;
case 'getNotes':
resolve({
notes: [
{ id: 1, title: 'Meeting Notes', content: 'Discussed project timeline and deliverables.', created_at: '2023-05-15' },
{ id: 2, title: 'Shopping List', content: 'Milk, Eggs, Bread, Fruits', created_at: '2023-05-10' }
]
});
break;
case 'saveNote':
case 'updateNote':
resolve({ success: true });
break;
case 'getNote':
resolve({
note: {
id: 1,
title: 'Meeting Notes',
content: 'Discussed project timeline and deliverables.',
created_at: '2023-05-15'
}
});
break;
case 'deleteNote':
resolve({ success: true });
break;
case 'getSongs':
resolve({
songs: [
{ id: 1, title: 'Bohemian Rhapsody', artist: 'Queen', album: 'A Night at the Opera', year: 1975 },
{ id: 2, title: 'Hotel California', artist: 'Eagles', album: 'Hotel California', year: 1976 }
]
});
break;
case 'addSong':
resolve({ success: true });
break;
case 'getSongDetails':
resolve({
song: {
id: 1,
title: 'Bohemian Rhapsody',
artist: 'Queen',
album: 'A Night at the Opera',
year: 1975,
genre: 'Rock'
}
});
break;
case 'deleteSong':
resolve({ success: true });
break;
case 'searchSongs':
if (data.searchTerm.toLowerCase() === 'queen') {
resolve({
songs: [
{ id: 1, title: 'Bohemian Rhapsody', artist: 'Queen', album: 'A Night at the Opera', year: 1975 }
]
});
} else {
resolve({ songs: [] });
}
break;
case 'getTransactions':
const transactions = [
{ id: 1, type: 'income', amount: 50000, category: 'salary', description: 'Monthly Salary', date: '2023-05-01' },
{ id: 2, type: 'expense', amount: 1500, category: 'food', description: 'Grocery Shopping', date: '2023-05-05' },
{ id: 3, type: 'expense', amount: 2000, category: 'transport', description: 'Fuel', date: '2023-05-10' },
{ id: 4, type: 'income', amount: 8000, category: 'freelance', description: 'Website Project', date: '2023-05-15' }
];
resolve({
transactions: transactions,
summary: {
totalTransactions: transactions.length,
totalIncome: 58000,
totalExpenses: 3500
}
});
break;
case 'addTransaction':
resolve({ success: true });
break;
case 'deleteTransaction':
resolve({ success: true });
break;
case 'getTransactionSummary':
resolve({
totalTransactions: 4,
totalIncome: 58000,
totalExpenses: 3500
});
break;
default:
resolve({ success: false, message: 'Unknown endpoint' });
}
}, 500); // Simulate network delay
});
}
</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=nextzendev2/nextzendailylife" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>