mirror of
https://github.com/tiennm99/exchange-rate-export.git
synced 2026-10-14 08:18:16 +00:00
feat: add loading progress indicator with day count and progress bar
Show total days being fetched and an animated progress bar during data loading to give users better feedback on long date ranges.
This commit is contained in:
1 parent
5d600e0ab9
commit
c1e37861d1
3 files changed
+12
-6
No files matched your search
@@ -180,7 +180,7 @@ export async function POST(request) {
|
||||
results.push(...chunkResults);
|
||||
}
|
||||
|
||||
return Response.json({ data: results, total: dates.length });
|
||||
return Response.json({ data: results, total: dates.length, chunks: Math.ceil(dates.length / PARALLEL_CHUNK_SIZE) });
|
||||
} catch (error) {
|
||||
console.error("Server error:", error);
|
||||
return Response.json(
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import DatePicker from "react-datepicker";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import { format, subDays, startOfMonth, isSameDay } from "date-fns";
|
||||
import { format, subDays, startOfMonth, isSameDay, differenceInCalendarDays } from "date-fns";
|
||||
import * as XLSX from "xlsx";
|
||||
import { LoadingSpinner, ErrorMessage, EmptyState } from "./exchange-rate-status";
|
||||
import { RateTable, ComparisonTable } from "./exchange-rate-table";
|
||||
@@ -146,7 +146,8 @@ export default function ExchangeRateViewer() {
|
||||
setIsLoading(true);
|
||||
setResults([]);
|
||||
setHasFetched(false);
|
||||
setProgress(null);
|
||||
const totalDays = differenceInCalendarDays(endDate, startDate) + 1;
|
||||
setProgress({ current: 0, total: totalDays });
|
||||
try {
|
||||
if (compareMode) {
|
||||
const [bidvData, tcbData] = await Promise.all([fetchBank("bidv"), fetchBank("tcb")]);
|
||||
|
||||
@@ -5,11 +5,16 @@ import React from "react";
|
||||
export function LoadingSpinner({ progress }) {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<div className="flex flex-col items-center gap-3 w-64">
|
||||
<div className="w-8 h-8 border-3 border-blue-200 border-t-blue-600 rounded-full animate-spin" />
|
||||
<p className="text-[var(--muted)]">
|
||||
{progress ? `Fetching ${progress.current}/${progress.total} days...` : "Fetching exchange rates..."}
|
||||
<p className="text-[var(--muted)] text-sm">
|
||||
{progress?.total ? `Fetching rates for ${progress.total} day${progress.total > 1 ? "s" : ""}...` : "Fetching exchange rates..."}
|
||||
</p>
|
||||
{progress?.total > 1 && (
|
||||
<div className="w-full h-1.5 rounded-full bg-[var(--card-border)] overflow-hidden">
|
||||
<div className="h-full bg-blue-500 rounded-full animate-pulse" style={{ width: "100%" }} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user