diff --git a/app/(dashboard)/salary/employees/page.tsx b/app/(dashboard)/salary/employees/page.tsx
index c1e7ea9d..fa73969c 100644
--- a/app/(dashboard)/salary/employees/page.tsx
+++ b/app/(dashboard)/salary/employees/page.tsx
@@ -84,7 +84,7 @@ export default function EmployeesPage() {
Namn
Personnummer
Typ
- Månadslön
+ Lön
Sysselsättningsgrad
Skattetabell
@@ -104,7 +104,9 @@ export default function EmployeesPage() {
{EMPLOYMENT_LABELS[emp.employment_type] || emp.employment_type}
- {emp.monthly_salary ? formatCurrency(emp.monthly_salary) : '—'}
+ {emp.salary_type === 'hourly'
+ ? emp.hourly_rate ? `${formatCurrency(emp.hourly_rate)}/tim` : '—'
+ : emp.monthly_salary ? formatCurrency(emp.monthly_salary) : '—'}
{emp.employment_degree}%
diff --git a/app/(dashboard)/salary/runs/[id]/employees/[employeeId]/page.tsx b/app/(dashboard)/salary/runs/[id]/employees/[employeeId]/page.tsx
index 31d35a2d..05c4b6bb 100644
--- a/app/(dashboard)/salary/runs/[id]/employees/[employeeId]/page.tsx
+++ b/app/(dashboard)/salary/runs/[id]/employees/[employeeId]/page.tsx
@@ -2,10 +2,10 @@
import { use, useEffect, useMemo, useState } from 'react'
import Link from 'next/link'
-import { ArrowLeft, Loader2 } from 'lucide-react'
+import { ArrowLeft, Calculator, Loader2 } from 'lucide-react'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
-import { AbsenceCalendar } from '@/components/salary/AbsenceCalendar'
+import { SalaryCalendar } from '@/components/salary/SalaryCalendar'
import { formatCurrency } from '@/lib/utils'
import type { SalaryRun, SalaryRunEmployee, SalaryLineItem, SalaryLineItemType, Employee } from '@/types'
@@ -54,6 +54,10 @@ export default function SalaryRunEmployeeDetailPage({
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
+ const [calculating, setCalculating] = useState(false)
+ // Live counts pushed from the calendar — overrides the stale snapshot from
+ // the last calculation so badges update immediately on absence save.
+ const [liveCounts, setLiveCounts] = useState<{ sick: number; vab: number; parental: number } | null>(null)
const load = async () => {
setLoading(true)
@@ -80,6 +84,23 @@ export default function SalaryRunEmployeeDetailPage({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [runId, employeeId])
+ const handleCalculate = async () => {
+ setCalculating(true)
+ setError(null)
+ try {
+ const res = await fetch(`/api/salary/runs/${runId}/calculate`, { method: 'POST' })
+ const json = await res.json().catch(() => ({}))
+ if (!res.ok) {
+ throw new Error(json.error || 'Beräkning misslyckades')
+ }
+ await load()
+ } catch (e) {
+ setError(e instanceof Error ? e.message : 'Okänt fel')
+ } finally {
+ setCalculating(false)
+ }
+ }
+
const periodStart = useMemo(() => {
if (!data) return ''
const y = data.run.period_year
@@ -144,8 +165,18 @@ export default function SalaryRunEmployeeDetailPage({
{employee.personnummer} · Lönespecifikation {periodLabel}
-