Implement comprehensive project time logging feature
Add complete project management system with role-based access control: **Core Features:** - Project creation and management for Admins/Supervisors - Time tracking with optional project selection and notes - Project-based filtering and reporting in history - Enhanced export functionality with project data - Team-specific project assignments **Database Changes:** - New Project model with full relationships - Enhanced TimeEntry model with project_id and notes - Updated migration scripts with rollback support - Sample project creation for testing **User Interface:** - Project management templates (create, edit, list) - Enhanced time tracking with project dropdown - Project filtering in history page - Updated navigation for role-based access - Modern styling with hover effects and responsive design **API Enhancements:** - Project validation and access control - Updated arrive endpoint with project support - Enhanced export functions with project data - Role-based route protection **Migration Support:** - Comprehensive migration scripts (migrate_projects.py) - Updated main migration script (migrate_db.py) - Detailed migration documentation - Rollback functionality for safe deployment **Role-Based Access:** - Admins: Full project CRUD operations - Supervisors: Project creation and management - Team Leaders: View team hours with projects - Team Members: Select projects when tracking time 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -58,20 +58,43 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Handle arrive button click
|
||||
if (arriveBtn) {
|
||||
arriveBtn.addEventListener('click', function() {
|
||||
// Get project and notes from the form
|
||||
const projectSelect = document.getElementById('project-select');
|
||||
const notesTextarea = document.getElementById('work-notes');
|
||||
|
||||
const projectId = projectSelect ? projectSelect.value : null;
|
||||
const notes = notesTextarea ? notesTextarea.value.trim() : null;
|
||||
|
||||
const requestData = {};
|
||||
if (projectId) {
|
||||
requestData.project_id = projectId;
|
||||
}
|
||||
if (notes) {
|
||||
requestData.notes = notes;
|
||||
}
|
||||
|
||||
fetch('/api/arrive', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
},
|
||||
body: JSON.stringify(requestData)
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
return response.json().then(data => {
|
||||
throw new Error(data.error || 'Failed to record arrival time');
|
||||
});
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// Reload the page to show the active timer
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Failed to record arrival time. Please try again.');
|
||||
alert('Failed to record arrival time: ' + error.message);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user