Add Dashboard for users with specific role.
This commit is contained in:
184
templates/team_hours.html
Normal file
184
templates/team_hours.html
Normal file
@@ -0,0 +1,184 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="timetrack-container">
|
||||
<h2>Team Hours</h2>
|
||||
|
||||
<div class="date-filter">
|
||||
<form id="date-range-form" method="GET" action="{{ url_for('team_hours') }}">
|
||||
<div class="form-group">
|
||||
<label for="start-date">Start Date:</label>
|
||||
<input type="date" id="start-date" name="start_date" value="{{ start_date.strftime('%Y-%m-%d') }}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="end-date">End Date:</label>
|
||||
<input type="date" id="end-date" name="end_date" value="{{ end_date.strftime('%Y-%m-%d') }}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="include-self">
|
||||
<input type="checkbox" id="include-self" name="include_self" {% if request.args.get('include_self') %}checked{% endif %}> Include my hours
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit" class="btn">Apply Filter</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="team-hours-container">
|
||||
<div id="loading">Loading team data...</div>
|
||||
<div id="team-info" style="display: none;">
|
||||
<h3>Team: <span id="team-name"></span></h3>
|
||||
<p id="team-description"></p>
|
||||
</div>
|
||||
|
||||
<div id="team-hours-table" style="display: none;">
|
||||
<table class="time-history">
|
||||
<thead id="table-header">
|
||||
<tr>
|
||||
<th>Team Member</th>
|
||||
{% for date in date_range %}
|
||||
<th>{{ date.strftime('%a, %b %d') }}</th>
|
||||
{% endfor %}
|
||||
<th>Total Hours</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="table-body">
|
||||
<!-- Team member data will be added dynamically -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="no-data" style="display: none;">
|
||||
<p>No time entries found for the selected date range.</p>
|
||||
</div>
|
||||
|
||||
<div id="error-message" style="display: none;" class="error-message">
|
||||
<!-- Error messages will be displayed here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="team-hours-details" id="member-details" style="display: none;">
|
||||
<h3>Detailed Entries for <span id="selected-member"></span></h3>
|
||||
<table class="time-history">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Arrival</th>
|
||||
<th>Departure</th>
|
||||
<th>Work Duration</th>
|
||||
<th>Break Duration</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="details-body">
|
||||
<!-- Entry details will be added dynamically -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Load team hours data when the page loads
|
||||
loadTeamHoursData();
|
||||
|
||||
// Handle date filter form submission
|
||||
document.getElementById('date-range-form').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
loadTeamHoursData();
|
||||
});
|
||||
|
||||
function loadTeamHoursData() {
|
||||
// Show loading indicator
|
||||
document.getElementById('loading').style.display = 'block';
|
||||
document.getElementById('team-hours-table').style.display = 'none';
|
||||
document.getElementById('team-info').style.display = 'none';
|
||||
document.getElementById('no-data').style.display = 'none';
|
||||
document.getElementById('error-message').style.display = 'none';
|
||||
document.getElementById('member-details').style.display = 'none';
|
||||
|
||||
// Get filter values
|
||||
const startDate = document.getElementById('start-date').value;
|
||||
const endDate = document.getElementById('end-date').value;
|
||||
const includeSelf = document.getElementById('include-self').checked;
|
||||
|
||||
// Build API URL with query parameters
|
||||
const apiUrl = `/api/team/hours_data?start_date=${startDate}&end_date=${endDate}&include_self=${includeSelf}`;
|
||||
|
||||
// Fetch data from API
|
||||
fetch(apiUrl)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
return response.json().then(data => {
|
||||
throw new Error(data.message || 'Failed to load team hours data');
|
||||
});
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
displayTeamData(data);
|
||||
} else {
|
||||
showError(data.message || 'Failed to load team hours data.');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching team hours data:', error);
|
||||
showError(error.message || 'An error occurred while loading the team hours data.');
|
||||
});
|
||||
}
|
||||
|
||||
function displayTeamData(data) {
|
||||
// Populate team info
|
||||
document.getElementById('team-name').textContent = data.team.name;
|
||||
document.getElementById('team-description').textContent = data.team.description || '';
|
||||
document.getElementById('team-info').style.display = 'block';
|
||||
|
||||
// Populate team hours table
|
||||
const tableHeader = document.getElementById('table-header').querySelector('tr');
|
||||
tableHeader.innerHTML = '<th>Team Member</th>';
|
||||
data.date_range.forEach(dateStr => {
|
||||
const th = document.createElement('th');
|
||||
th.textContent = new Date(dateStr).toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });
|
||||
tableHeader.appendChild(th);
|
||||
});
|
||||
const totalHoursTh = document.createElement('th');
|
||||
totalHoursTh.textContent = 'Total Hours';
|
||||
tableHeader.appendChild(totalHoursTh);
|
||||
|
||||
const tableBody = document.getElementById('table-body');
|
||||
tableBody.innerHTML = '';
|
||||
data.team_data.forEach(memberData => {
|
||||
const row = document.createElement('tr');
|
||||
|
||||
// Add username cell
|
||||
const usernameCell = document.createElement('td');
|
||||
usernameCell.textContent = memberData.user.username;
|
||||
row.appendChild(usernameCell);
|
||||
|
||||
// Add daily hours cells
|
||||
data.date_range.forEach(dateStr => {
|
||||
const cell = document.createElement('td');
|
||||
cell.textContent = `${memberData.daily_hours[dateStr] || 0}h`;
|
||||
row.appendChild(cell);
|
||||
});
|
||||
|
||||
// Add total hours cell
|
||||
const totalCell = document.createElement('td');
|
||||
totalCell.innerHTML = `<strong>${memberData.total_hours}h</strong>`;
|
||||
row.appendChild(totalCell);
|
||||
|
||||
tableBody.appendChild(row);
|
||||
});
|
||||
|
||||
// Populate detailed entries
|
||||
document.getElementById('team-hours-table').style.display = 'block';
|
||||
document.getElementById('loading').style.display = 'none';
|
||||
}
|
||||
|
||||
function showError(message) {
|
||||
document.getElementById('error-message').textContent = message;
|
||||
document.getElementById('error-message').style.display = 'block';
|
||||
document.getElementById('loading').style.display = 'none';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user