Files
app/app/admin/YouthAttendanceRow.tsx
T

96 lines
5.4 KiB
TypeScript

// app/admin/YouthAttendanceRow.tsx
"use client";
import { CheckCircle, ClipboardCheck, Edit3, Undo } from 'lucide-react';
import Image from 'next/image';
import React from 'react';
import falconIcon from '../assets/falcon.svg';
import porpoiseIcon from '../assets/porpoise.svg';
import { formatTimeHHMM, parseTimeInput, type Youth } from './adminTypes';
interface YouthAttendanceRowProps {
youth: Youth;
entry: any;
currentDate: string;
shiftId: 'MORNING' | 'AFTERNOON';
team: 'PF' | 'TU';
actualDuration: number;
onMarkStandard: () => void;
setManualAttendance: (date: string, youthId: string, shiftId: 'MORNING' | 'AFTERNOON', status: 'Absent' | 'Late' | 'Present', hours: number, note?: string) => void;
removeAttendanceEntry: (date: string, youthId: string, shiftId: 'MORNING' | 'AFTERNOON') => void;
}
export const YouthAttendanceRow: React.FC<YouthAttendanceRowProps> = ({
youth,
entry,
currentDate,
shiftId,
team,
actualDuration,
onMarkStandard,
setManualAttendance,
removeAttendanceEntry
}) => {
// Logic moved inside the component
const isExtra = youth.team !== team;
const isPending = entry?.status === 'Pending';
const isCompleted = !!entry && !isPending;
return (
<div className={`flex flex-col md:flex-row md:justify-between md:items-center p-3 rounded-2xl border transition-colors ${isCompleted ? 'bg-moss/5 border-moss/20' : (isPending ? 'bg-goldenrod/5 border-goldenrod/30' : 'bg-white border-slate-teal/5 shadow-sm')}`}>
<div className="flex items-center gap-3 mb-3 md:mb-0">
{isCompleted ? <CheckCircle size={20} className="text-moss shrink-0" /> : <div className="w-5 h-5 rounded-full border-2 border-slate-teal/20 shrink-0 bg-white"></div>}
<div className={`flex items-center justify-center w-6 h-6 rounded-full ${youth.team === 'PF' ? 'bg-gold' : 'bg-seafoam'} shrink-0 shadow-inner`}>
<Image src={youth.team === 'PF' ? falconIcon : porpoiseIcon} alt={youth.team === 'PF' ? 'PF' : 'TU'} width={12} height={12} />
</div>
<span className={`font-bold text-base ${isCompleted ? 'text-moss' : 'text-ebony'}`}>
{youth.name} {isExtra && <span className="ml-2 text-[10px] text-slate-teal bg-slate-teal/10 px-2 py-0.5 rounded-lg uppercase tracking-widest">Extra pass</span>}
</span>
</div>
<div className="flex items-center justify-end gap-3 w-full md:w-auto flex-wrap">
{isPending && <span className="text-[10px] font-black uppercase tracking-widest bg-goldenrod/10 text-goldenrod px-3 py-1.5 rounded-xl">Väntar...</span>}
{isCompleted && (
<span className="text-xs font-black uppercase tracking-widest bg-white text-moss px-3 py-1.5 rounded-xl border border-moss/10 shadow-sm">
{entry.status === 'Absent' ? entry.note : `${formatTimeHHMM(entry.hoursWorked)} (+${entry.weightedHours.toFixed(1)}h)`}
</span>
)}
{(!entry || isPending) && (
<>
<button onClick={onMarkStandard} className="bg-slate-teal/10 text-slate-teal hover:bg-slate-teal hover:text-white px-3 py-1.5 rounded-xl font-black uppercase tracking-widest text-[10px] flex items-center gap-1.5 transition-colors shadow-sm">
<ClipboardCheck size={14} /> Hela passet
</button>
<button onClick={() => {
const input = prompt(`Timmar arbetade:`, formatTimeHHMM(actualDuration));
const hrs = input ? parseTimeInput(input) : 0;
if (hrs > 0) setManualAttendance(currentDate, youth.id, shiftId, 'Present', hrs);
}} className="bg-goldenrod/10 text-goldenrod hover:bg-goldenrod hover:text-white p-1.5 rounded-xl transition-colors shadow-sm">
<Edit3 size={16} />
</button>
<select
value=""
onChange={(e) => {
if (!e.target.value) return;
let reason = e.target.value;
if (reason === 'Custom') reason = prompt('Ange anledning:') || 'Frånvarande';
setManualAttendance(currentDate, youth.id, shiftId, 'Absent', 0, reason);
}}
className="bg-goldenrod/10 text-goldenrod px-2 py-1.5 rounded-xl font-black uppercase tracking-widest text-[10px] outline-none shadow-sm"
>
<option value="">+ Frånvaro</option>
<option value="Sjuk">Sjuk</option><option value="Uteblev">Uteblev</option><option value="Ledig">Ledig</option><option value="Custom">Annan...</option>
</select>
</>
)}
{entry && (
<button onClick={() => removeAttendanceEntry(currentDate, youth.id, shiftId)} className="text-emergency/60 hover:text-emergency p-1.5 bg-white rounded-xl border border-emergency/10 transition-colors shadow-sm">
<Undo size={16} />
</button>
)}
</div>
</div>
);
};