mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 09:12:08 +01:00
Improves dashboard data handling and settings
Refactors the dashboard to improve data fetching, error handling, and overall user experience. - Prevents errors on refresh by validating company ID. - Improves date handling from CSV by using a `safeParseDate` function to avoid "Invalid Date" errors. - Adds a timestamp for when metrics were last updated. - Fixes a bug where the refresh was failing silently. - Improves settings page by wrapping form elements with form tags. - Adds autocomplete attributes on settings page. - Adds database files to `.gitignore`.
This commit is contained in:
@ -27,21 +27,21 @@ function DashboardContent() {
|
||||
const [metrics, setMetrics] = useState<MetricsResult | null>(null);
|
||||
const [company, setCompany] = useState<Company | null>(null);
|
||||
const [, setLoading] = useState<boolean>(false);
|
||||
const [csvUrl, setCsvUrl] = useState<string>("");
|
||||
// Remove unused csvUrl state variable
|
||||
const [refreshing, setRefreshing] = useState<boolean>(false);
|
||||
|
||||
const isAdmin = session?.user?.role === "admin";
|
||||
const isAuditor = session?.user?.role === "auditor";
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch metrics, company, and CSV URL on mount
|
||||
// Fetch metrics and company on mount
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
const res = await fetch("/api/dashboard/metrics");
|
||||
const data = await res.json();
|
||||
setMetrics(data.metrics);
|
||||
setCompany(data.company);
|
||||
setCsvUrl(data.csvUrl);
|
||||
// Removed unused csvUrl assignment
|
||||
setLoading(false);
|
||||
};
|
||||
fetchData();
|
||||
@ -51,15 +51,27 @@ function DashboardContent() {
|
||||
if (isAuditor) return; // Prevent auditors from refreshing
|
||||
try {
|
||||
setRefreshing(true);
|
||||
|
||||
// Make sure we have a company ID to send
|
||||
if (!company?.id) {
|
||||
console.error("Cannot refresh: Company ID is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await fetch("/api/admin/refresh-sessions", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ companyId: company.id }),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
// Refetch metrics
|
||||
const metricsRes = await fetch("/api/dashboard/metrics");
|
||||
const data = await metricsRes.json();
|
||||
setMetrics(data.metrics);
|
||||
} else {
|
||||
const errorData = await res.json();
|
||||
console.error("Failed to refresh sessions:", errorData.error);
|
||||
}
|
||||
} finally {
|
||||
setRefreshing(false);
|
||||
@ -127,11 +139,11 @@ function DashboardContent() {
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="bg-white p-4 rounded-xl shadow">
|
||||
<h3 className="font-bold text-lg mb-3">Sessions by Day</h3>
|
||||
<SessionsLineChart data={metrics.days || {}} />
|
||||
<SessionsLineChart sessionsPerDay={metrics.days || {}} />
|
||||
</div>
|
||||
<div className="bg-white p-4 rounded-xl shadow">
|
||||
<h3 className="font-bold text-lg mb-3">Categories</h3>
|
||||
<CategoriesBarChart data={metrics.categories || {}} />
|
||||
<CategoriesBarChart categories={metrics.categories || {}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -42,18 +42,26 @@ export default function DashboardSettings({
|
||||
return (
|
||||
<div className="bg-white p-6 rounded-xl shadow mb-6">
|
||||
<h2 className="font-bold text-lg mb-4">Company Config</h2>
|
||||
<div className="grid gap-4">
|
||||
<form
|
||||
className="grid gap-4"
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
handleSave();
|
||||
}}
|
||||
>
|
||||
<input
|
||||
className="border px-3 py-2 rounded"
|
||||
placeholder="CSV URL"
|
||||
value={csvUrl}
|
||||
onChange={(e) => setCsvUrl(e.target.value)}
|
||||
autoComplete="url"
|
||||
/>
|
||||
<input
|
||||
className="border px-3 py-2 rounded"
|
||||
placeholder="CSV Username"
|
||||
value={csvUsername}
|
||||
onChange={(e) => setCsvUsername(e.target.value)}
|
||||
autoComplete="username"
|
||||
/>
|
||||
<input
|
||||
className="border px-3 py-2 rounded"
|
||||
@ -61,6 +69,7 @@ export default function DashboardSettings({
|
||||
placeholder="CSV Password"
|
||||
value={csvPassword}
|
||||
onChange={(e) => setCsvPassword(e.target.value)}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
<input
|
||||
className="border px-3 py-2 rounded"
|
||||
@ -69,14 +78,11 @@ export default function DashboardSettings({
|
||||
value={sentimentThreshold}
|
||||
onChange={(e) => setSentimentThreshold(e.target.value)}
|
||||
/>
|
||||
<button
|
||||
className="bg-blue-600 text-white rounded py-2"
|
||||
onClick={handleSave}
|
||||
>
|
||||
<button type="submit" className="bg-blue-600 text-white rounded py-2">
|
||||
Save Settings
|
||||
</button>
|
||||
<div>{message}</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user