Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Productivity Automator</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> | |
.timer-active { | |
background-color: #ecfdf5; | |
border-left: 4px solid #10b981; | |
} | |
.task-completed { | |
text-decoration: line-through; | |
color: #9ca3af; | |
} | |
.email-preview { | |
min-height: 300px; | |
border: 1px solid #e5e7eb; | |
background-color: #f9fafb; | |
} | |
.timeline-item:not(:last-child)::after { | |
content: ''; | |
position: absolute; | |
left: 7px; | |
top: 24px; | |
height: 100%; | |
width: 2px; | |
background-color: #e5e7eb; | |
} | |
.tab-active { | |
border-bottom: 2px solid #3b82f6; | |
color: #3b82f6; | |
} | |
</style> | |
</head> | |
<body class="bg-gray-50 font-sans"> | |
<div class="container mx-auto px-4 py-8 max-w-6xl"> | |
<!-- Header --> | |
<header class="flex justify-between items-center mb-8"> | |
<div> | |
<h1 class="text-3xl font-bold text-gray-800">Productivity Automator</h1> | |
<p class="text-gray-600">Streamline your daily work routine</p> | |
</div> | |
<div class="flex items-center space-x-4"> | |
<div class="flex items-center"> | |
<span class="mr-2 text-gray-600">Auto Mode</span> | |
<label class="relative inline-flex items-center cursor-pointer"> | |
<input type="checkbox" id="autoModeToggle" class="sr-only peer"> | |
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div> | |
</label> | |
</div> | |
<button id="settingsBtn" class="p-2 rounded-full hover:bg-gray-200"> | |
<i class="fas fa-cog text-gray-600"></i> | |
</button> | |
</div> | |
</header> | |
<!-- Navigation Tabs --> | |
<div class="flex border-b border-gray-200 mb-6"> | |
<button class="tab-btn py-2 px-4 font-medium text-gray-600 hover:text-blue-500 tab-active" data-tab="daily-plan">Daily Plan</button> | |
<button class="tab-btn py-2 px-4 font-medium text-gray-600 hover:text-blue-500" data-tab="time-tracker">Time Tracker</button> | |
<button class="tab-btn py-2 px-4 font-medium text-gray-600 hover:text-blue-500" data-tab="email-preview">Email Preview</button> | |
<button class="tab-btn py-2 px-4 font-medium text-gray-600 hover:text-blue-500" data-tab="dashboard">Dashboard</button> | |
<button class="tab-btn py-2 px-4 font-medium text-gray-600 hover:text-blue-500" data-tab="reports">Reports</button> | |
</div> | |
<!-- Daily Plan Tab --> | |
<div id="daily-plan" class="tab-content"> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
<!-- Tasks Section --> | |
<div class="bg-white rounded-lg shadow p-6"> | |
<div class="flex justify-between items-center mb-4"> | |
<h2 class="text-xl font-semibold text-gray-800">Today's Tasks</h2> | |
<button id="fetchMeetingsBtn" class="flex items-center text-blue-600 hover:text-blue-800"> | |
<i class="fas fa-calendar-alt mr-2"></i> | |
Fetch Meetings | |
</button> | |
</div> | |
<div class="mb-4"> | |
<div class="flex mb-2"> | |
<input type="text" id="newTaskInput" placeholder="Add a new task..." class="flex-grow px-4 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
<button id="addTaskBtn" class="px-4 py-2 bg-blue-600 text-white rounded-r-md hover:bg-blue-700">Add</button> | |
</div> | |
<div class="flex space-x-2 mb-4"> | |
<select id="projectSelect" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
<option value="">Select Project</option> | |
<option value="Project A">Project A</option> | |
<option value="Project B">Project B</option> | |
<option value="Project C">Project C</option> | |
</select> | |
<input type="text" id="subTaskInput" placeholder="Sub-task (optional)" class="flex-grow px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
</div> | |
</div> | |
<div id="tasksList" class="space-y-2"> | |
<!-- Tasks will be added here dynamically --> | |
</div> | |
</div> | |
<!-- Meetings Section --> | |
<div class="bg-white rounded-lg shadow p-6"> | |
<h2 class="text-xl font-semibold text-gray-800 mb-4">Today's Meetings</h2> | |
<div id="meetingsList" class="space-y-3"> | |
<div class="text-gray-500 italic">No meetings fetched yet. Click "Fetch Meetings" to load your schedule.</div> | |
</div> | |
</div> | |
</div> | |
<div class="mt-6 flex justify-end"> | |
<button id="generatePlanBtn" class="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 flex items-center"> | |
<i class="fas fa-envelope mr-2"></i> | |
Generate Daily Plan Email | |
</button> | |
</div> | |
</div> | |
<!-- Time Tracker Tab --> | |
<div id="time-tracker" class="tab-content hidden"> | |
<div class="bg-white rounded-lg shadow p-6"> | |
<h2 class="text-xl font-semibold text-gray-800 mb-6">Project Time Tracker</h2> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6"> | |
<!-- Current Timer --> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<h3 class="font-medium text-gray-700 mb-2">Currently Tracking</h3> | |
<div id="currentTimerInfo" class="text-center py-4"> | |
<div class="text-gray-500 italic">No active timer</div> | |
</div> | |
<div class="flex justify-center space-x-2"> | |
<button id="startTimerBtn" class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700">Start</button> | |
<button id="pauseTimerBtn" class="px-4 py-2 bg-yellow-500 text-white rounded-md hover:bg-yellow-600 hidden">Pause</button> | |
<button id="stopTimerBtn" class="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 hidden">Stop</button> | |
</div> | |
</div> | |
<!-- New Timer --> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<h3 class="font-medium text-gray-700 mb-2">Start New Timer</h3> | |
<div class="space-y-3"> | |
<select id="timerProjectSelect" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
<option value="">Select Project</option> | |
<option value="Project A">Project A</option> | |
<option value="Project B">Project B</option> | |
<option value="Project C">Project C</option> | |
</select> | |
<select id="timerTaskSelect" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
<option value="">Select Task</option> | |
</select> | |
<input type="text" id="timerNotes" placeholder="Notes (optional)" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
</div> | |
</div> | |
<!-- Today's Summary --> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<h3 class="font-medium text-gray-700 mb-2">Today's Summary</h3> | |
<div id="todaysTimeSummary" class="space-y-2"> | |
<div class="flex justify-between"> | |
<span class="text-gray-600">Total Tracked:</span> | |
<span class="font-medium">0h 0m</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-gray-600">Active Projects:</span> | |
<span class="font-medium">0</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-gray-600">Tasks Completed:</span> | |
<span class="font-medium">0</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Active Timers List --> | |
<h3 class="font-medium text-gray-700 mb-3">Active Time Logs</h3> | |
<div id="activeTimersList" class="space-y-2 mb-6"> | |
<div class="text-gray-500 italic">No active time logs yet.</div> | |
</div> | |
<!-- Time Log History --> | |
<h3 class="font-medium text-gray-700 mb-3">Today's Time Logs</h3> | |
<div id="timeLogsList" class="space-y-2"> | |
<div class="text-gray-500 italic">No time logs recorded today.</div> | |
</div> | |
</div> | |
</div> | |
<!-- Email Preview Tab --> | |
<div id="email-preview" class="tab-content hidden"> | |
<div class="bg-white rounded-lg shadow p-6"> | |
<div class="flex justify-between items-center mb-4"> | |
<h2 class="text-xl font-semibold text-gray-800">Email Preview</h2> | |
<div class="flex space-x-2"> | |
<select id="emailTypeSelect" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
<option value="daily-plan">Daily Plan</option> | |
<option value="work-status">Work Status</option> | |
</select> | |
<button id="refreshEmailBtn" class="px-3 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300"> | |
<i class="fas fa-sync-alt"></i> | |
</button> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label for="emailRecipient" class="block text-sm font-medium text-gray-700 mb-1">Recipient</label> | |
<input type="text" id="emailRecipient" value="manager@example.com" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
</div> | |
<div class="mb-4"> | |
<label for="emailSubject" class="block text-sm font-medium text-gray-700 mb-1">Subject</label> | |
<input type="text" id="emailSubject" value="Daily Plan - [Your Name] - [Date]" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
</div> | |
<div class="email-preview rounded-md p-4 mb-4" id="emailContent"> | |
<p>Hello,</p> | |
<p class="mt-2">Here's my daily plan for [date]:</p> | |
<h3 class="font-medium mt-4">Planned Tasks:</h3> | |
<ul id="emailTasksList" class="list-disc pl-5 mt-2 space-y-1"> | |
<li>No tasks added yet</li> | |
</ul> | |
<h3 class="font-medium mt-4">Meetings:</h3> | |
<ul id="emailMeetingsList" class="list-disc pl-5 mt-2 space-y-1"> | |
<li>No meetings scheduled</li> | |
</ul> | |
<p class="mt-4">Regards,<br>[Your Name]</p> | |
</div> | |
<div class="flex justify-end space-x-3"> | |
<button id="editEmailBtn" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300"> | |
<i class="fas fa-edit mr-2"></i>Edit Content | |
</button> | |
<button id="sendEmailBtn" class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"> | |
<i class="fas fa-paper-plane mr-2"></i>Send via Outlook | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- Dashboard Tab --> | |
<div id="dashboard" class="tab-content hidden"> | |
<div class="bg-white rounded-lg shadow p-6"> | |
<h2 class="text-xl font-semibold text-gray-800 mb-6">Productivity Dashboard</h2> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6"> | |
<!-- Productivity Stats --> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<h3 class="font-medium text-gray-700 mb-3">Today's Productivity</h3> | |
<div class="space-y-4"> | |
<div> | |
<div class="flex justify-between mb-1"> | |
<span class="text-sm font-medium text-gray-600">Tasks Completed</span> | |
<span class="text-sm font-semibold">0/0</span> | |
</div> | |
<div class="w-full bg-gray-200 rounded-full h-2.5"> | |
<div class="bg-green-600 h-2.5 rounded-full" style="width: 0%"></div> | |
</div> | |
</div> | |
<div> | |
<div class="flex justify-between mb-1"> | |
<span class="text-sm font-medium text-gray-600">Time Utilization</span> | |
<span class="text-sm font-semibold">0%</span> | |
</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: 0%"></div> | |
</div> | |
</div> | |
<div> | |
<div class="flex justify-between mb-1"> | |
<span class="text-sm font-medium text-gray-600">Meeting Efficiency</span> | |
<span class="text-sm font-semibold">0%</span> | |
</div> | |
<div class="w-full bg-gray-200 rounded-full h-2.5"> | |
<div class="bg-purple-600 h-2.5 rounded-full" style="width: 0%"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Time Distribution --> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<h3 class="font-medium text-gray-700 mb-3">Time Distribution</h3> | |
<div id="timeDistributionChart" class="h-40 flex items-center justify-center"> | |
<div class="text-gray-500 italic">No time data available</div> | |
</div> | |
</div> | |
<!-- Quick Actions --> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<h3 class="font-medium text-gray-700 mb-3">Quick Actions</h3> | |
<div class="space-y-2"> | |
<button class="w-full flex items-center px-3 py-2 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200"> | |
<i class="fas fa-plus-circle mr-2 text-green-600"></i> | |
Add Quick Task | |
</button> | |
<button class="w-full flex items-center px-3 py-2 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200"> | |
<i class="fas fa-stopwatch mr-2 text-blue-600"></i> | |
Start Break Timer | |
</button> | |
<button class="w-full flex items-center px-3 py-2 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200"> | |
<i class="fas fa-file-export mr-2 text-purple-600"></i> | |
Export Today's Report | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- Timeline --> | |
<h3 class="font-medium text-gray-700 mb-3">Today's Timeline</h3> | |
<div id="timeline" class="space-y-4"> | |
<div class="relative pl-6 timeline-item"> | |
<div class="absolute left-0 w-4 h-4 bg-blue-500 rounded-full"></div> | |
<div class="bg-gray-50 p-3 rounded-lg"> | |
<div class="flex justify-between"> | |
<span class="font-medium">App Started</span> | |
<span class="text-sm text-gray-500">9:00 AM</span> | |
</div> | |
<p class="text-sm text-gray-600 mt-1">You started your workday</p> | |
</div> | |
</div> | |
<div class="relative pl-6 timeline-item"> | |
<div class="absolute left-0 w-4 h-4 bg-green-500 rounded-full"></div> | |
<div class="bg-gray-50 p-3 rounded-lg"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Daily Plan Created</span> | |
<span class="text-sm text-gray-500">9:05 AM</span> | |
</div> | |
<p class="text-sm text-gray-600 mt-1">You planned your tasks for the day</p> | |
</div> | |
</div> | |
<div class="text-center py-4"> | |
<button class="text-blue-600 hover:text-blue-800 text-sm font-medium"> | |
<i class="fas fa-chevron-down mr-1"></i>Load More Activities | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Reports Tab --> | |
<div id="reports" class="tab-content hidden"> | |
<div class="bg-white rounded-lg shadow p-6"> | |
<h2 class="text-xl font-semibold text-gray-800 mb-6">Reports & Analytics</h2> | |
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6"> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
<option>Today</option> | |
<option>Yesterday</option> | |
<option>This Week</option> | |
<option>This Month</option> | |
<option>Custom Range</option> | |
</select> | |
</div> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
<option>All Projects</option> | |
<option>Project A</option> | |
<option>Project B</option> | |
<option>Project C</option> | |
</select> | |
</div> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
<option>All Tasks</option> | |
<option>Completed</option> | |
<option>Pending</option> | |
</select> | |
</div> | |
<div class="border border-gray-200 rounded-lg p-4"> | |
<button class="w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"> | |
<i class="fas fa-filter mr-2"></i>Apply Filters | |
</button> | |
</div> | |
</div> | |
<div class="overflow-x-auto mb-6"> | |
<table class="min-w-full divide-y divide-gray-200"> | |
<thead class="bg-gray-50"> | |
<tr> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Project</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Task</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time Spent</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th> | |
<th scope="col" 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"> | |
<tr> | |
<td colspan="6" class="px-6 py-4 text-center text-gray-500 italic">No report data available</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
<div class="flex justify-between items-center"> | |
<div class="text-sm text-gray-500">Showing 0 of 0 entries</div> | |
<div class="flex space-x-2"> | |
<button class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 bg-white hover:bg-gray-50"> | |
<i class="fas fa-file-csv mr-2"></i>Export CSV | |
</button> | |
<button class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 bg-white hover:bg-gray-50"> | |
<i class="fas fa-file-pdf mr-2"></i>Export PDF | |
</button> | |
<button class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"> | |
<i class="fas fa-print mr-2"></i>Print | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Settings Modal --> | |
<div id="settingsModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50"> | |
<div class="bg-white rounded-lg shadow-xl w-full max-w-md"> | |
<div class="px-6 py-4 border-b border-gray-200"> | |
<h3 class="text-lg font-semibold text-gray-800">Settings</h3> | |
</div> | |
<div class="p-6"> | |
<div class="space-y-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Email Schedule</label> | |
<div class="grid grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-xs text-gray-500 mb-1">Morning Plan</label> | |
<input type="time" value="09:00" class="w-full px-3 py-2 border border-gray-300 rounded-md"> | |
</div> | |
<div> | |
<label class="block text-xs text-gray-500 mb-1">End of Day</label> | |
<input type="time" value="17:00" class="w-full px-3 py-2 border border-gray-300 rounded-md"> | |
</div> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Default Email Recipient</label> | |
<input type="text" value="manager@example.com" class="w-full px-3 py-2 border border-gray-300 rounded-md"> | |
</div> | |
<div> | |
<label class="flex items-center"> | |
<input type="checkbox" class="rounded text-blue-600"> | |
<span class="ml-2 text-sm text-gray-700">Enable desktop notifications</span> | |
</label> | |
</div> | |
</div> | |
</div> | |
<div class="px-6 py-4 border-t border-gray-200 flex justify-end space-x-3"> | |
<button id="cancelSettingsBtn" class="px-4 py-2 text-gray-700 hover:text-gray-900">Cancel</button> | |
<button id="saveSettingsBtn" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">Save Changes</button> | |
</div> | |
</div> | |
</div> | |
<script> | |
// DOM Elements | |
const tabButtons = document.querySelectorAll('.tab-btn'); | |
const tabContents = document.querySelectorAll('.tab-content'); | |
const autoModeToggle = document.getElementById('autoModeToggle'); | |
const settingsBtn = document.getElementById('settingsBtn'); | |
const settingsModal = document.getElementById('settingsModal'); | |
const cancelSettingsBtn = document.getElementById('cancelSettingsBtn'); | |
const saveSettingsBtn = document.getElementById('saveSettingsBtn'); | |
// Task Management Elements | |
const newTaskInput = document.getElementById('newTaskInput'); | |
const addTaskBtn = document.getElementById('addTaskBtn'); | |
const projectSelect = document.getElementById('projectSelect'); | |
const subTaskInput = document.getElementById('subTaskInput'); | |
const tasksList = document.getElementById('tasksList'); | |
const fetchMeetingsBtn = document.getElementById('fetchMeetingsBtn'); | |
const meetingsList = document.getElementById('meetingsList'); | |
const generatePlanBtn = document.getElementById('generatePlanBtn'); | |
// Time Tracker Elements | |
const timerProjectSelect = document.getElementById('timerProjectSelect'); | |
const timerTaskSelect = document.getElementById('timerTaskSelect'); | |
const timerNotes = document.getElementById('timerNotes'); | |
const startTimerBtn = document.getElementById('startTimerBtn'); | |
const pauseTimerBtn = document.getElementById('pauseTimerBtn'); | |
const stopTimerBtn = document.getElementById('stopTimerBtn'); | |
const currentTimerInfo = document.getElementById('currentTimerInfo'); | |
const activeTimersList = document.getElementById('activeTimersList'); | |
const timeLogsList = document.getElementById('timeLogsList'); | |
// Email Preview Elements | |
const emailTypeSelect = document.getElementById('emailTypeSelect'); | |
const refreshEmailBtn = document.getElementById('refreshEmailBtn'); | |
const emailRecipient = document.getElementById('emailRecipient'); | |
const emailSubject = document.getElementById('emailSubject'); | |
const emailContent = document.getElementById('emailContent'); | |
const emailTasksList = document.getElementById('emailTasksList'); | |
const emailMeetingsList = document.getElementById('emailMeetingsList'); | |
const editEmailBtn = document.getElementById('editEmailBtn'); | |
const sendEmailBtn = document.getElementById('sendEmailBtn'); | |
// Data Storage | |
let tasks = []; | |
let meetings = []; | |
let timeLogs = []; | |
let activeTimer = null; | |
let timerInterval = null; | |
// Tab Switching | |
tabButtons.forEach(button => { | |
button.addEventListener('click', () => { | |
const tabId = button.getAttribute('data-tab'); | |
// Update active tab button | |
tabButtons.forEach(btn => btn.classList.remove('tab-active')); | |
button.classList.add('tab-active'); | |
// Show corresponding tab content | |
tabContents.forEach(content => content.classList.add('hidden')); | |
document.getElementById(tabId).classList.remove('hidden'); | |
}); | |
}); | |
// Settings Modal | |
settingsBtn.addEventListener('click', () => { | |
settingsModal.classList.remove('hidden'); | |
}); | |
cancelSettingsBtn.addEventListener('click', () => { | |
settingsModal.classList.add('hidden'); | |
}); | |
saveSettingsBtn.addEventListener('click', () => { | |
settingsModal.classList.add('hidden'); | |
// In a real app, save settings to localStorage or backend | |
alert('Settings saved successfully!'); | |
}); | |
// Task Management | |
addTaskBtn.addEventListener('click', addTask); | |
newTaskInput.addEventListener('keypress', (e) => { | |
if (e.key === 'Enter') addTask(); | |
}); | |
function addTask() { | |
const taskText = newTaskInput.value.trim(); | |
if (!taskText) return; | |
const project = projectSelect.value; | |
const subTask = subTaskInput.value.trim(); | |
const task = { | |
id: Date.now(), | |
text: taskText, | |
project: project || 'No Project', | |
subTask: subTask || '', | |
completed: false, | |
createdAt: new Date() | |
}; | |
tasks.push(task); | |
renderTasks(); | |
// Clear inputs | |
newTaskInput.value = ''; | |
subTaskInput.value = ''; | |
newTaskInput.focus(); | |
} | |
function renderTasks() { | |
tasksList.innerHTML = ''; | |
if (tasks.length === 0) { | |
tasksList.innerHTML = '<div class="text-gray-500 italic">No tasks added yet.</div>'; | |
return; | |
} | |
tasks.forEach(task => { | |
const taskElement = document.createElement('div'); | |
taskElement.className = `flex items-center justify-between p-3 border border-gray-200 rounded-md ${task.completed ? 'bg-gray-50' : ''}`; | |
taskElement.innerHTML = ` | |
<div class="flex items-center"> | |
<input type="checkbox" ${task.completed ? 'checked' : ''} data-id="${task.id}" class="mr-3 h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"> | |
<div> | |
<div class="${task.completed ? 'task-completed' : 'font-medium'}">${task.text}</div> | |
${task.subTask ? `<div class="text-sm text-gray-500">${task.subTask}</div>` : ''} | |
<div class="text-xs text-gray-400 mt-1">${task.project}</div> | |
</div> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="text-gray-400 hover:text-gray-600" data-id="${task.id}"> | |
<i class="fas fa-stopwatch"></i> | |
</button> | |
<button class="text-gray-400 hover:text-gray-600" data-id="${task.id}"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
`; | |
tasksList.appendChild(taskElement); | |
}); | |
// Add event listeners for checkboxes | |
document.querySelectorAll('#tasksList input[type="checkbox"]').forEach(checkbox => { | |
checkbox.addEventListener('change', (e) => { | |
const taskId = parseInt(e.target.getAttribute('data-id')); | |
const task = tasks.find(t => t.id === taskId); | |
if (task) { | |
task.completed = e.target.checked; | |
renderTasks(); | |
} | |
}); | |
}); | |
// Add event listeners for delete buttons | |
document.querySelectorAll('#tasksList button:nth-child(2)').forEach(button => { | |
button.addEventListener('click', (e) => { | |
const taskId = parseInt(e.target.closest('button').getAttribute('data-id')); | |
tasks = tasks.filter(t => t.id !== taskId); | |
renderTasks(); | |
}); | |
}); | |
// Add event listeners for timer buttons | |
document.querySelectorAll('#tasksList button:nth-child(1)').forEach(button => { | |
button.addEventListener('click', (e) => { | |
const taskId = parseInt(e.target.closest('button').getAttribute('data-id')); | |
const task = tasks.find(t => t.id === taskId); | |
if (task) { | |
// Switch to Time Tracker tab | |
document.querySelector('.tab-btn[data-tab="time-tracker"]').click(); | |
// Set the project and task in the timer form | |
timerProjectSelect.value = task.project; | |
updateTaskSelect(); | |
timerTaskSelect.value = task.text; | |
} | |
}); | |
}); | |
} | |
// Fetch Meetings (mock) | |
fetchMeetingsBtn.addEventListener('click', () => { | |
// In a real app, this would fetch from Outlook/Teams API | |
meetings = [ | |
{ title: 'Team Standup', time: '10:00 AM - 10:30 AM', organizer: 'John Doe' }, | |
{ title: 'Project Review', time: '2:00 PM - 3:00 PM', organizer: 'Jane Smith' }, | |
{ title: 'Client Call', time: '4:30 PM - 5:00 PM', organizer: 'Mike Johnson' } | |
]; | |
renderMeetings(); | |
}); | |
function renderMeetings() { | |
meetingsList.innerHTML = ''; | |
if (meetings.length === 0) { | |
meetingsList.innerHTML = '<div class="text-gray-500 italic">No meetings scheduled.</div>'; | |
return; | |
} | |
meetings.forEach(meeting => { | |
const meetingElement = document.createElement('div'); | |
meetingElement.className = 'p-3 border border-gray-200 rounded-md'; | |
meetingElement.innerHTML = ` | |
<div class="font-medium">${meeting.title}</div> | |
<div class="text-sm text-gray-600">${meeting.time}</div> | |
<div class="text-xs text-gray-500 mt-1">Organizer: ${meeting.organizer}</div> | |
`; | |
meetingsList.appendChild(meetingElement); | |
}); | |
} | |
// Generate Daily Plan Email | |
generatePlanBtn.addEventListener('click', () => { | |
// Switch to Email Preview tab | |
document.querySelector('.tab-btn[data-tab="email-preview"]').click(); | |
// Update email subject with today's date | |
const today = new Date(); | |
const dateStr = today.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); | |
emailSubject.value = `Daily Plan - ${dateStr}`; | |
// Update email content | |
updateEmailContent(); | |
}); | |
function updateEmailContent() { | |
// Tasks list | |
if (tasks.length > 0) { | |
emailTasksList.innerHTML = ''; | |
tasks.forEach(task => { | |
const li = document.createElement('li'); | |
li.className = task.completed ? 'task-completed' : ''; | |
li.textContent = `${task.text}${task.subTask ? ` (${task.subTask})` : ''} - ${task.project}`; | |
emailTasksList.appendChild(li); | |
}); | |
} else { | |
emailTasksList.innerHTML = '<li>No tasks planned yet</li>'; | |
} | |
// Meetings list | |
if (meetings.length > 0) { | |
emailMeetingsList.innerHTML = ''; | |
meetings.forEach(meeting => { | |
const li = document.createElement('li'); | |
li.textContent = `${meeting.title} at ${meeting.time}`; | |
emailMeetingsList.appendChild(li); | |
}); | |
} else { | |
emailMeetingsList.innerHTML = '<li>No meetings scheduled</li>'; | |
} | |
} | |
// Time Tracker Functionality | |
timerProjectSelect.addEventListener('change', updateTaskSelect); | |
function updateTaskSelect() { | |
const selectedProject = timerProjectSelect.value; | |
const projectTasks = tasks.filter(task => task.project === selectedProject); | |
timerTaskSelect.innerHTML = '<option value="">Select Task</option>'; | |
if (selectedProject) { | |
projectTasks.forEach(task => { | |
const option = document.createElement('option'); | |
option.value = task.text; | |
option.textContent = task.text; | |
timerTaskSelect.appendChild(option); | |
}); | |
} | |
} | |
startTimerBtn.addEventListener('click', startTimer); | |
pauseTimerBtn.addEventListener('click', pauseTimer); | |
stopTimerBtn.addEventListener('click', stopTimer); | |
function startTimer() { | |
const project = timerProjectSelect.value; | |
const task = timerTaskSelect.value; | |
const notes = timerNotes.value; | |
if (!project || !task) { | |
alert('Please select both project and task'); | |
return; | |
} | |
// Stop any existing timer | |
if (activeTimer) { | |
stopTimer(); | |
} | |
activeTimer = { | |
id: Date.now(), | |
project, | |
task, | |
notes, | |
startTime: new Date(), | |
paused: false, | |
elapsedSeconds: 0 | |
}; | |
// Update UI | |
startTimerBtn.classList.add('hidden'); | |
pauseTimerBtn.classList.remove('hidden'); | |
stopTimerBtn.classList.remove('hidden'); | |
currentTimerInfo.innerHTML = ` | |
<div class="font-medium">${project}</div> | |
<div class="text-gray-600">${task}</div> | |
<div class="text-2xl font-mono mt-2" id="timerDisplay">00:00:00</div> | |
${notes ? `<div class="text-sm text-gray-500 mt-1">${notes}</div>` : ''} | |
`; | |
// Start the timer | |
timerInterval = setInterval(updateTimer, 1000); | |
// Add to active timers list | |
renderActiveTimers(); | |
} | |
function updateTimer() { | |
if (!activeTimer) return; | |
if (!activeTimer.paused) { | |
activeTimer.elapsedSeconds++; | |
const hours = Math.floor(activeTimer.elapsedSeconds / 3600); | |
const minutes = Math.floor((activeTimer.elapsedSeconds % 3600) / 60); | |
const seconds = activeTimer.elapsedSeconds % 60; | |
const timerDisplay = document.getElementById('timerDisplay'); | |
if (timerDisplay) { | |
timerDisplay.textContent = | |
`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; | |
} | |
} | |
} | |
function pauseTimer() { | |
if (!activeTimer) return; | |
activeTimer.paused = !activeTimer.paused; | |
if (activeTimer.paused) { | |
pauseTimerBtn.textContent = 'Resume'; | |
clearInterval(timerInterval); | |
} else { | |
pauseTimerBtn.textContent = 'Pause'; | |
timerInterval = setInterval(updateTimer, 1000); | |
} | |
} | |
function stopTimer() { | |
if (!activeTimer) return; | |
clearInterval(timerInterval); | |
// Calculate duration | |
const endTime = new Date(); | |
const duration = activeTimer.elapsedSeconds; | |
// Create time log | |
const timeLog = { | |
id: Date.now(), | |
project: activeTimer.project, | |
task: activeTimer.task, | |
notes: activeTimer.notes, | |
startTime: activeTimer.startTime, | |
endTime: endTime, | |
duration: duration | |
}; | |
timeLogs.push(timeLog); | |
// Reset UI | |
activeTimer = null; | |
startTimerBtn.classList.remove('hidden'); | |
pauseTimerBtn.classList.add('hidden'); | |
stopTimerBtn.classList.add('hidden'); | |
pauseTimerBtn.textContent = 'Pause'; | |
currentTimerInfo.innerHTML = '<div class="text-gray-500 italic">No active timer</div>'; | |
// Update time logs list | |
renderTimeLogs(); | |
} | |
function renderActiveTimers() { | |
if (!activeTimer) { | |
activeTimersList.innerHTML = '<div class="text-gray-500 italic">No active time logs yet.</div>'; | |
return; | |
} | |
const hours = Math.floor(activeTimer.elapsedSeconds / 3600); | |
const minutes = Math.floor((activeTimer.elapsedSeconds % 3600) / 60); | |
const seconds = activeTimer.elapsedSeconds % 60; | |
activeTimersList.innerHTML = ` | |
<div class="flex items-center justify-between p-3 border border-gray-200 rounded-md timer-active"> | |
<div> | |
<div class="font-medium">${activeTimer.project}</div> | |
<div class="text-gray-600">${activeTimer.task}</div> | |
${activeTimer.notes ? `<div class="text-sm text-gray-500 mt-1">${activeTimer.notes}</div>` : ''} | |
</div> | |
<div class="font-mono">${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</div> | |
</div> | |
`; | |
} | |
function renderTimeLogs() { | |
if (timeLogs.length === 0) { | |
timeLogsList.innerHTML = '<div class="text-gray-500 italic">No time logs recorded today.</div>'; | |
return; | |
} | |
timeLogsList.innerHTML = ''; | |
// Group by project | |
const projects = [...new Set(timeLogs.map(log => log.project))]; | |
projects.forEach(project => { | |
const projectLogs = timeLogs.filter(log => log.project === project); | |
const totalProjectTime = projectLogs.reduce((sum, log) => sum + log.duration, 0); | |
const projectHeader = document.createElement('div'); | |
projectHeader.className = 'flex justify-between items-center p-2 bg-gray-100 rounded-md mb-2'; | |
projectHeader.innerHTML = ` | |
<span class="font-medium">${project}</span> | |
<span class="text-sm font-mono">${formatDuration(totalProjectTime)}</span> | |
`; | |
timeLogsList.appendChild(projectHeader); | |
projectLogs.forEach(log => { | |
const logElement = document.createElement('div'); | |
logElement.className = 'flex justify-between items-center p-2 border-b border-gray-100'; | |
const startTimeStr = log.startTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); | |
const endTimeStr = log.endTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); | |
logElement.innerHTML = ` | |
<div> | |
<div class="text-sm">${log.task}</div> | |
${log.notes ? `<div class="text-xs text-gray-500">${log.notes}</div>` : ''} | |
</div> | |
<div class="text-right"> | |
<div class="text-xs font-mono">${startTimeStr} - ${endTimeStr}</div> | |
<div class="text-sm font-mono">${formatDuration(log.duration)}</div> | |
</div> | |
`; | |
timeLogsList.appendChild(logElement); | |
}); | |
}); | |
} | |
function formatDuration(seconds) { | |
const hours = Math.floor(seconds / 3600); | |
const minutes = Math.floor((seconds % 3600) / 60); | |
return `${hours}h ${minutes}m`; | |
} | |
// Email Preview | |
emailTypeSelect.addEventListener('change', () => { | |
updateEmailContent(); | |
}); | |
refreshEmailBtn.addEventListener('click', () => { | |
updateEmailContent(); | |
}); | |
editEmailBtn.addEventListener('click', () => { | |
emailContent.contentEditable = emailContent.contentEditable === 'true' ? 'false' : 'true'; | |
editEmailBtn.innerHTML = emailContent.contentEditable === 'true' | |
? '<i class="fas fa-check mr-2"></i>Save Edits' | |
: '<i class="fas fa-edit mr-2"></i>Edit Content'; | |
if (emailContent.contentEditable === 'true') { | |
emailContent.focus(); | |
} | |
}); | |
sendEmailBtn.addEventListener('click', () => { | |
// In a real app, this would integrate with Outlook API | |
alert('Email would be sent via Outlook in a real implementation'); | |
}); | |
// Initialize | |
renderTasks(); | |
renderTimeLogs(); | |
</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=Katiyar48/daily-tracker" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |