first commit
This commit is contained in:
commit
b54624be96
226 files changed
+108840
No files matched your search
@@ -0,0 +1,97 @@
|
||||
import React from 'react';
|
||||
import { formatNumber } from '../../utils/format.ts';
|
||||
import { formatChillFactor, type ExperienceCalc } from './chillFactor.ts';
|
||||
|
||||
const DEGREE_C = '\u00B0C';
|
||||
|
||||
const oneDecimal = (value: number | null): string =>
|
||||
value === null ? '--' : formatNumber(value, 1);
|
||||
|
||||
const formatSigned = (value: number | null): string => {
|
||||
if (value === null) return '--';
|
||||
const sign = value > 0 ? '+' : '';
|
||||
return `${sign}${oneDecimal(value)} ${DEGREE_C}`;
|
||||
};
|
||||
|
||||
export interface IotPanelExperienceTempCardProps {
|
||||
calc: ExperienceCalc;
|
||||
apiExperienceTemp: number | null | undefined;
|
||||
}
|
||||
|
||||
const IotPanelExperienceTempCard: React.FC<IotPanelExperienceTempCardProps> = ({
|
||||
calc,
|
||||
apiExperienceTemp,
|
||||
}) => {
|
||||
const calculationRows = [
|
||||
{
|
||||
label: 'Kecepatan angin',
|
||||
value: calc.windSpeed === null ? '--' : `${oneDecimal(calc.windSpeed)} m/s`,
|
||||
note: 'Dari sensor angin kandang',
|
||||
},
|
||||
{
|
||||
label: 'Chill factor',
|
||||
value: formatChillFactor(calc.chillFactor),
|
||||
note: 'Berdasarkan grafik chill factor',
|
||||
},
|
||||
{
|
||||
label: 'Koreksi RH',
|
||||
value: formatSigned(calc.humidityAdjustment),
|
||||
note: '(RH - 70) / 5',
|
||||
},
|
||||
{
|
||||
label: 'Suhu rata-rata',
|
||||
value: calc.averageTemp === null ? '--' : `${oneDecimal(calc.averageTemp)} ${DEGREE_C}`,
|
||||
note: 'Suhu rata-rata dari Panel',
|
||||
},
|
||||
{
|
||||
label: 'Chill effect',
|
||||
value: formatSigned(calc.chillEffect),
|
||||
note: '(Angin x chill factor) - koreksi RH',
|
||||
},
|
||||
];
|
||||
|
||||
const apiDiffers =
|
||||
apiExperienceTemp != null &&
|
||||
calc.experienceTemp != null &&
|
||||
Math.abs(apiExperienceTemp - calc.experienceTemp) > 0.05;
|
||||
|
||||
return (
|
||||
<article className="rounded-xl border border-sky-200 bg-gradient-to-br from-sky-50 to-blue-50 p-4 shadow-sm">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-slate-800">
|
||||
<i className="fa-solid fa-temperature-half mr-2 text-sky-600" />
|
||||
Experience Suhu
|
||||
</h2>
|
||||
<p className="mt-1 text-xs text-slate-500">Suhu yang dirasakan oleh ayam.</p>
|
||||
</div>
|
||||
<p className="shrink-0 text-3xl font-bold text-sky-600">
|
||||
{calc.experienceTemp === null ? 'N/A' : `${oneDecimal(calc.experienceTemp)} ${DEGREE_C}`}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-3 grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
{calculationRows.map((item) => (
|
||||
<div key={item.label} className="rounded-lg border border-sky-100 bg-white/70 p-2">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="text-xs font-medium text-slate-500">{item.label}</span>
|
||||
<strong className="text-sm text-slate-800">{item.value}</strong>
|
||||
</div>
|
||||
<p className="mt-1 text-[11px] text-slate-400">{item.note}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-3 rounded-lg bg-white/60 px-3 py-2 text-xs text-slate-500">
|
||||
Experience suhu = Suhu rata-rata - chill effect.
|
||||
{apiDiffers && apiExperienceTemp != null && (
|
||||
<span className="mt-1 block">
|
||||
Nilai tercatat Panel: {oneDecimal(apiExperienceTemp)} {DEGREE_C}.
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
};
|
||||
|
||||
export default IotPanelExperienceTempCard;
|
||||
Reference in new issue
Block a user