CG-Feedback-Monitor/src/pages/RatingWeightConfig.tsx

80 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useState } from 'react'
import { db } from '../db'
import { DEFAULT_RATING_TREND_WEIGHT_STEP } from '../config/constants'
import { previewWeights } from '../utils/ratingTrend'
export default function RatingWeightConfig() {
const [weightStep, setWeightStep] = useState(DEFAULT_RATING_TREND_WEIGHT_STEP)
const [saved, setSaved] = useState(false)
useEffect(() => {
const load = async () => {
let settings = await db.appSettings.get(1)
if (!settings) {
await db.appSettings.add({ id: 1, ratingTrendWeightStep: DEFAULT_RATING_TREND_WEIGHT_STEP })
settings = await db.appSettings.get(1)
}
setWeightStep(settings?.ratingTrendWeightStep ?? DEFAULT_RATING_TREND_WEIGHT_STEP)
}
load()
}, [])
const save = async () => {
await db.appSettings.put({ id: 1, ratingTrendWeightStep: weightStep })
setSaved(true)
setTimeout(() => setSaved(false), 2500)
}
return (
<div className="bg-white rounded-xl border border-gray-100 shadow-sm p-5 space-y-4">
<div>
<h2 className="font-semibold text-gray-800">Zeitgewichtung des Bewertungs-Vorschlags</h2>
<p className="text-sm text-gray-500 mt-1">
Steuert, wie stark spätere Meetings in den Bewertungs-Vorschlag auf der Auswertungs- und
Feedback-Seite einfließen. 0 = alle Meetings gleich gewichtet, höher = stärkere Gewichtung
späterer Bewertungen.
</p>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium text-gray-700">Gewichtungsfaktor</label>
<span className="text-sm font-semibold text-brand">{weightStep.toFixed(1)}</span>
</div>
<input
type="range"
min={0}
max={2}
step={0.1}
value={weightStep}
onChange={e => setWeightStep(Number(e.target.value))}
className="w-full"
/>
</div>
<div className="bg-gray-50 rounded-lg border border-gray-100 p-3">
<div className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-1.5">
Beispiel bei 3 bewerteten Meetings
</div>
<div className="flex gap-2 text-sm text-gray-600">
{previewWeights(3, weightStep).map((w, i) => (
<span key={i} className="bg-white border border-gray-200 rounded px-2 py-1">
Meeting {i + 1}: ×{w.toFixed(1)}
</span>
))}
</div>
</div>
<button onClick={save}
className="w-full py-2.5 bg-brand text-white rounded-xl text-sm font-semibold">
Speichern
</button>
{saved && (
<div className="text-xs text-green-700 bg-green-50 border border-green-200 rounded-lg px-3 py-2 text-center">
Gespeichert.
</div>
)}
</div>
)
}