2025-02-07 19:41:48 +05:30

184 lines
4.9 KiB
TypeScript

import React, { useState } from "react";
import "./HeadCount.css";
interface ApiResponse {
total_unique_faces: number;
daily_counts: { date: string; unique_faces: number }[];
}
interface DateTimeRange {
date: string;
time: string;
}
const HeadCount: React.FC = () => {
const [from, setFrom] = useState<DateTimeRange>({ date: "", time: "" });
const [to, setTo] = useState<DateTimeRange>({ date: "", time: "" });
const [count, setCount] = useState<number | null>(null);
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const [dailyCounts, setDailyCounts] = useState<
{ date: string; count: number }[]
>([]);
const handleInputChange = (
e: React.ChangeEvent<HTMLInputElement>,
field: "from" | "to"
) => {
const { name, value } = e.target;
if (field === "from") {
setFrom((prev) => ({ ...prev, [name]: value }));
} else {
setTo((prev) => ({ ...prev, [name]: value }));
}
};
const formatDateTime = (date: string, time: string) => {
return `${date}T${time}:00+00:00`;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!from.date || !from.time || !to.date || !to.time) {
setError("Please fill in all date and time fields.");
return;
}
setLoading(true);
setError(null);
const start = formatDateTime(from.date, from.time);
const end = formatDateTime(to.date, to.time);
console.log(start, end);
try {
const response = await fetch(
`${
process.env.NEXT_PUBLIC_BASE_URL
}/face/headcount?start_time=${encodeURIComponent(
start
)}&end_time=${encodeURIComponent(end)}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch data");
}
const data: ApiResponse = await response.json();
setCount(data.total_unique_faces);
if (data?.daily_counts) {
setDailyCounts(
data.daily_counts.map((d) => ({
date: d.date,
count: d.unique_faces,
}))
);
}
} catch (err) {
setError("An error occurred while fetching data.");
console.error(err);
} finally {
setLoading(false);
}
};
return (
<div className="headcount-container">
<h1 className="heading">Head Count</h1>
<form onSubmit={handleSubmit} className="form">
<div className="input-group">
<label htmlFor="from-date" className="label">
From Date:
</label>
<input
type="date"
id="from-date"
name="date"
value={from.date}
onChange={(e) => handleInputChange(e, "from")}
required
className="input"
/>
</div>
<div className="input-group">
<label htmlFor="from-time" className="label">
From Time:
</label>
<input
type="time"
id="from-time"
name="time"
value={from.time}
onChange={(e) => handleInputChange(e, "from")}
required
className="input"
/>
</div>
<div className="input-group">
<label htmlFor="to-date" className="label">
To Date:
</label>
<input
type="date"
id="to-date"
name="date"
value={to.date}
onChange={(e) => handleInputChange(e, "to")}
required
className="input"
/>
</div>
<div className="input-group">
<label htmlFor="to-time" className="label">
To Time:
</label>
<input
type="time"
id="to-time"
name="time"
value={to.time}
onChange={(e) => handleInputChange(e, "to")}
required
className="input"
/>
</div>
<button type="submit" disabled={loading} className="button">
{loading ? "Submitting..." : "Submit"}
</button>
</form>
{error && <p className="error">{error}</p>}
{count && (
<div className="names-container">
<h2 className="sub-heading">Total Unique Face Count:</h2>
<ul className="list">{count}</ul>
</div>
)}
{dailyCounts?.length > 0 && (
<div className="daily-counts-container">
<h2 className="sub-heading">Daily Counts:</h2>
<ul className="list">
{dailyCounts.map((item, index) => (
<li key={index} className="list-item">
<span className="date">{item.date}:</span>
<span className="count"> {item.count}</span>
</li>
))}
</ul>
</div>
)}
</div>
);
};
export default HeadCount;