Files
tilbudgivern/CalendarView_clean.js
T

180 lines
7.8 KiB
JavaScript

// Clean CalendarView Component - Optimized for Morning Meeting Overview
const CalendarView = ({ calendarData, employees, activeOrders, onCreateAllocation, onUpdateAllocation, onDeleteAllocation }) => {
const [viewMode, setViewMode] = useState('morning');
// Generate employee colors for visual distinction
const employeeColors = employees.reduce((colors, employee, index) => {
const hue = (index * 137.5) % 360;
colors[employee.id] = `hsl(${hue}, 70%, 55%)`;
return colors;
}, {});
// Helper function to get employee name
const getEmployeeName = (employeeId) => {
const employee = employees.find(emp => emp.id === employeeId);
return employee ? `${employee.first_name} ${employee.last_name}` : `Medarbejder ${employeeId}`;
};
return (
<div className="calendar-view morning-meeting-view">
{/* View Mode Selector */}
<div className="view-selector">
<button
className={`view-btn ${viewMode === 'morning' ? 'active' : ''}`}
onClick={() => setViewMode('morning')}
>
🌅 Morgenmøde Oversigt
</button>
</div>
{/* Morning Meeting View */}
{viewMode === 'morning' && (
<div className="morning-meeting-dashboard">
{/* Header with Date and Stats */}
<div className="meeting-header">
<div className="date-section">
<h2 className="meeting-date">📅 {new Date().toLocaleDateString('da-DK')}</h2>
<p className="meeting-subtitle">Morgenmøde Oversigt - Hvem arbejder hvad og hvor længe</p>
</div>
<div className="stats-section">
<div className="stat-card">
<div className="stat-number">{calendarData.entries?.length || 0}</div>
<div className="stat-label">Opgaver i dag</div>
</div>
<div className="stat-card">
<div className="stat-number">{employees.length}</div>
<div className="stat-label">Medarbejdere</div>
</div>
<div className="stat-card">
<div className="stat-number">{calendarData.totalHours || 0}</div>
<div className="stat-label">Timer planlagt</div>
</div>
</div>
</div>
{/* Today's Schedule */}
<div className="schedule-section">
<h3 className="section-title">📋 Dagens Arbejdsplan</h3>
<div className="schedule-grid">
{calendarData.entries && calendarData.entries.length > 0 ? (
calendarData.entries.slice(0, 12).map((entry, index) => (
<div key={index} className="schedule-item today">
<div
className="employee-badge"
style={{ backgroundColor: employeeColors[entry.employee_id] || '#3b82f6' }}
>
{getEmployeeName(entry.employee_id)?.split(' ').map(n => n[0]).join('') || 'M'}
</div>
<div className="schedule-details">
<div className="schedule-time">
{new Date(entry.start_time).toLocaleTimeString('da-DK', {
hour: '2-digit',
minute: '2-digit'
})} - {new Date(entry.end_time).toLocaleTimeString('da-DK', {
hour: '2-digit',
minute: '2-digit'
})}
</div>
<div className="schedule-employee">{getEmployeeName(entry.employee_id)}</div>
<div className="schedule-description">
{entry.description || entry.title || 'Arbejdsopgave'}
</div>
<div className="schedule-duration">
{Math.round((new Date(entry.end_time) - new Date(entry.start_time)) / (1000 * 60 * 60 * 10)) / 10}h
</div>
</div>
</div>
))
) : (
<div className="no-tasks">
<span className="no-tasks-icon">📋</span>
<div>
<strong>Ingen kalenderdata tilgængelig</strong>
<br />
Kontroller at kalender sync kører korrekt
</div>
</div>
)}
</div>
</div>
{/* Employee Workload Overview */}
<div className="workload-section">
<h3 className="section-title">👷 Medarbejder Arbejdsbelastning</h3>
<div className="employee-workload-grid">
{employees.map((employee) => {
const employeeTasks = calendarData.entries?.filter(entry =>
entry.employee_id === employee.id
) || [];
const totalHours = employeeTasks.reduce((sum, task) => {
const duration = (new Date(task.end_time) - new Date(task.start_time)) / (1000 * 60 * 60);
return sum + duration;
}, 0);
return (
<div key={employee.id} className={`employee-card ${employeeTasks.length > 0 ? 'active' : 'available'}`}>
<div
className="employee-avatar"
style={{ backgroundColor: employeeColors[employee.id] || '#64748b' }}
>
{employee.first_name?.charAt(0)}{employee.last_name?.charAt(0)}
</div>
<div className="employee-info">
<div className="employee-name">
{employee.first_name} {employee.last_name}
</div>
<div className="employee-tasks">
<span className="task-count today">
{employeeTasks.length} opgaver
</span>
<span className="task-hours">
{totalHours.toFixed(1)}h i dag
</span>
</div>
<div className={`employee-status ${employeeTasks.length > 0 ? 'active' : 'available'}`}>
{employeeTasks.length > 0 ? '🔥 Aktiv' : '✅ Ledig'}
</div>
</div>
</div>
);
})}
</div>
</div>
{/* Calendar Statistics */}
<div className="calendar-stats-section">
<h3 className="section-title">📊 Dagens Statistik</h3>
<div className="stats-grid">
<div className="stat-item">
<label>Synkroniserede indtastninger:</label>
<span>{calendarData.entries?.length || 0}</span>
</div>
<div className="stat-item">
<label>Sidste sync:</label>
<span>{calendarData.lastSync ? new Date(calendarData.lastSync).toLocaleString('da-DK') : 'Aldrig'}</span>
</div>
<div className="stat-item">
<label>Aktive medarbejdere:</label>
<span>
{employees.filter(emp =>
calendarData.entries?.some(entry => entry.employee_id === emp.id)
).length} / {employees.length}
</span>
</div>
<div className="stat-item">
<label>Total arbejdstimer:</label>
<span>
{calendarData.entries?.reduce((sum, entry) => {
const duration = (new Date(entry.end_time) - new Date(entry.start_time)) / (1000 * 60 * 60);
return sum + duration;
}, 0).toFixed(1) || 0}h
</span>
</div>
</div>
</div>
</div>
)}
</div>
);
};