eye / templates /staff_allocation.html
triflix's picture
Upload 23 files
0a515cd verified
{% extends "base.html" %}
{% block title %}Staff Allocation - Architecture PM System{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1><i class="bi bi-person-workspace"></i> Staff Allocation</h1>
<button class="btn btn-info" data-bs-toggle="modal" data-bs-target="#addAllocationModal">
<i class="bi bi-plus-circle"></i> Add Allocation
</button>
</div>
<!-- Summary Cards -->
<div class="row g-3 mb-4">
<div class="col-md-3">
<div class="card bg-info text-white">
<div class="card-body">
<h6 class="card-title">Total Allocations</h6>
<h3>{{ allocations|length }}</h3>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-primary text-white">
<div class="card-body">
<h6 class="card-title">Total Hours Allocated</h6>
<h3>{{ "{:,.0f}".format(allocations|sum(attribute='hours_allocated')|default(0)) }}</h3>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body">
<h6 class="card-title">Total Hours Worked</h6>
<h3>{{ "{:,.0f}".format(allocations|sum(attribute='hours_worked')|default(0)) }}</h3>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-dark">
<div class="card-body">
<h6 class="card-title">Avg Utilization</h6>
{% set total_allocated = allocations|sum(attribute='hours_allocated')|default(1) %}
{% set total_worked = allocations|sum(attribute='hours_worked')|default(0) %}
<h3>{{ "{:.1f}".format((total_worked / total_allocated * 100) if total_allocated > 0 else 0) }}%</h3>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover table-sm">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Project</th>
<th>Milestone</th>
<th>Employee</th>
<th>Role</th>
<th>Category</th>
<th>Hours Allocated</th>
<th>Hours Worked</th>
<th>Utilization %</th>
<th>Rate (AED/hr)</th>
<th>Cost (AED)</th>
<th>Skill Match</th>
<th>Availability</th>
<th>Performance</th>
<th>Start Date</th>
<th>End Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for alloc in allocations %}
<tr>
<td>{{ alloc.allocation_id }}</td>
<td><span class="badge bg-secondary">{{ alloc.project_id }}</span></td>
<td><small>{{ alloc.milestone_name or '-' }}</small></td>
<td>
<strong>{{ alloc.employee_name }}</strong>
<br><small class="text-muted">{{ alloc.employee_id }}</small>
</td>
<td><small>{{ alloc.role }}</small></td>
<td><span class="badge bg-info">{{ alloc.category or '-' }}</span></td>
<td>{{ alloc.hours_allocated }}</td>
<td><strong>{{ alloc.hours_worked }}</strong></td>
<td>
{% set utilization = (alloc.hours_worked / alloc.hours_allocated * 100) if alloc.hours_allocated > 0 else 0 %}
<div class="progress" style="height: 20px; min-width: 60px;">
<div class="progress-bar
{% if utilization >= 100 %}bg-success
{% elif utilization >= 75 %}bg-info
{% elif utilization >= 50 %}bg-warning
{% else %}bg-danger{% endif %}"
role="progressbar"
style="width: {{ [utilization, 100]|min }}%">
{{ "{:.0f}".format(utilization) }}%
</div>
</div>
</td>
<td>{{ alloc.hourly_rate_aed }}</td>
<td><strong>{{ "{:,.2f}".format(alloc.hours_worked * alloc.hourly_rate_aed) }}</strong></td>
<td>
{% if alloc.skill_match_score %}
<span class="badge
{% if alloc.skill_match_score >= 90 %}bg-success
{% elif alloc.skill_match_score >= 70 %}bg-info
{% else %}bg-warning{% endif %}">
{{ alloc.skill_match_score }}
</span>
{% else %}
-
{% endif %}
</td>
<td>
{% if alloc.availability_status == 'AVAILABLE' %}
<span class="badge bg-success">Available</span>
{% elif alloc.availability_status == 'BUSY' %}
<span class="badge bg-danger">Busy</span>
{% elif alloc.availability_status == 'PARTIALLY_AVAILABLE' %}
<span class="badge bg-warning text-dark">Partial</span>
{% elif alloc.availability_status == 'ON_LEAVE' %}
<span class="badge bg-secondary">On Leave</span>
{% else %}
<span class="badge bg-light text-dark">{{ alloc.availability_status or '-' }}</span>
{% endif %}
</td>
<td>
{% if alloc.performance_rating == 'EXCELLENT' %}
<span class="badge bg-success">⭐⭐⭐⭐⭐</span>
{% elif alloc.performance_rating == 'GOOD' %}
<span class="badge bg-info">⭐⭐⭐⭐</span>
{% elif alloc.performance_rating == 'AVERAGE' %}
<span class="badge bg-warning text-dark">⭐⭐⭐</span>
{% elif alloc.performance_rating == 'NEEDS_IMPROVEMENT' %}
<span class="badge bg-warning">⭐⭐</span>
{% elif alloc.performance_rating == 'POOR' %}
<span class="badge bg-danger"></span>
{% else %}
-
{% endif %}
</td>
<td>{{ alloc.start_date }}</td>
<td>{{ alloc.end_date or '-' }}</td>
<td>
<form method="post" action="/staff-allocation/delete/{{ alloc.allocation_id }}" style="display:inline;">
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure?')">
<i class="bi bi-trash"></i>
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Add Allocation Modal -->
<div class="modal fade" id="addAllocationModal" tabindex="-1">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header bg-info text-white">
<h5 class="modal-title">Add New Staff Allocation</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="post" action="/staff-allocation/create">
<div class="modal-body">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Project</label>
<select class="form-select" name="project_id" required>
<option value="">Select Project</option>
{% for project in projects %}
<option value="{{ project.project_id }}">{{ project.project_id }} - {{ project.project_name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-6">
<label class="form-label">Milestone (Optional)</label>
<select class="form-select" name="milestone_id">
<option value="">Select Milestone (Optional)</option>
{% for milestone in milestones %}
<option value="{{ milestone.milestone_id }}">{{ milestone.project_id }} - {{ milestone.milestone_name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-6">
<label class="form-label">Employee</label>
<select class="form-select" name="employee_id" id="employeeSelect" required>
<option value="">Select Employee</option>
{% for emp in employees %}
<option value="{{ emp.employee_id }}"
data-name="{{ emp.employee_name }}"
data-role="{{ emp.role }}"
data-rate="{{ emp.hourly_rate_aed }}">
{{ emp.employee_id }} - {{ emp.employee_name }} ({{ emp.role }})
</option>
{% endfor %}
</select>
</div>
<div class="col-md-6">
<label class="form-label">Employee Name (Auto-filled)</label>
<input type="text" class="form-control" name="employee_name" id="employeeName" required readonly>
</div>
<div class="col-md-6">
<label class="form-label">Role (Auto-filled)</label>
<input type="text" class="form-control" name="role" id="employeeRole" required readonly>
</div>
<div class="col-md-6">
<label class="form-label">Category</label>
<select class="form-select" name="category">
<option value="Architecture">Architecture</option>
<option value="Project Management">Project Management</option>
<option value="Engineering">Engineering</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">Hours Allocated</label>
<input type="number" step="0.01" class="form-control" name="hours_allocated" required placeholder="80.00">
</div>
<div class="col-md-6">
<label class="form-label">Hours Worked</label>
<input type="number" step="0.01" class="form-control" name="hours_worked" value="0" placeholder="0.00">
</div>
<div class="col-md-6">
<label class="form-label">Hourly Rate (AED) (Auto-filled)</label>
<input type="number" step="0.01" class="form-control" name="hourly_rate_aed" id="hourlyRate" required readonly>
</div>
<div class="col-md-6">
<label class="form-label">Skill Match Score (0-100)</label>
<input type="number" class="form-control" name="skill_match_score" min="0" max="100" placeholder="85">
</div>
<div class="col-md-6">
<label class="form-label">Availability Status</label>
<select class="form-select" name="availability_status">
<option value="AVAILABLE">Available</option>
<option value="BUSY">Busy</option>
<option value="PARTIALLY_AVAILABLE">Partially Available</option>
<option value="ON_LEAVE">On Leave</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">Performance Rating</label>
<select class="form-select" name="performance_rating">
<option value="">Not Rated</option>
<option value="EXCELLENT">Excellent</option>
<option value="GOOD">Good</option>
<option value="AVERAGE">Average</option>
<option value="NEEDS_IMPROVEMENT">Needs Improvement</option>
<option value="POOR">Poor</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">Start Date</label>
<input type="date" class="form-control" name="start_date" required>
</div>
<div class="col-md-6">
<label class="form-label">End Date (Optional)</label>
<input type="date" class="form-control" name="end_date">
</div>
<div class="col-md-12">
<label class="form-label">Notes (Optional)</label>
<textarea class="form-control" name="notes" rows="2" placeholder="Additional notes about this allocation..."></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-info">Add Allocation</button>
</div>
</form>
</div>
</div>
</div>
<script>
// Auto-fill employee details
document.getElementById('employeeSelect').addEventListener('change', function() {
const selectedOption = this.options[this.selectedIndex];
document.getElementById('employeeName').value = selectedOption.dataset.name || '';
document.getElementById('employeeRole').value = selectedOption.dataset.role || '';
document.getElementById('hourlyRate').value = selectedOption.dataset.rate || '';
});
</script>
{% endblock %}