feat: add multi-day interval selection for dashboard data display in PublicDashboardPage and SiteDashboardPage
This commit is contained in:
@@ -42,6 +42,7 @@ export default function PublicDashboardPage() {
|
|||||||
const [dateRange, setDateRange] = useState(getDateRange(30))
|
const [dateRange, setDateRange] = useState(getDateRange(30))
|
||||||
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false)
|
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false)
|
||||||
const [todayInterval, setTodayInterval] = useState<'minute' | 'hour'>('hour')
|
const [todayInterval, setTodayInterval] = useState<'minute' | 'hour'>('hour')
|
||||||
|
const [multiDayInterval, setMultiDayInterval] = useState<'hour' | 'day'>('day')
|
||||||
|
|
||||||
// Auto-refresh interval (for realtime)
|
// Auto-refresh interval (for realtime)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -57,7 +58,7 @@ export default function PublicDashboardPage() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadDashboard()
|
loadDashboard()
|
||||||
}, [siteId, dateRange, todayInterval])
|
}, [siteId, dateRange, todayInterval, multiDayInterval])
|
||||||
|
|
||||||
const loadDashboard = async (silent = false) => {
|
const loadDashboard = async (silent = false) => {
|
||||||
try {
|
try {
|
||||||
@@ -68,7 +69,7 @@ export default function PublicDashboardPage() {
|
|||||||
dateRange.start,
|
dateRange.start,
|
||||||
dateRange.end,
|
dateRange.end,
|
||||||
10,
|
10,
|
||||||
dateRange.start === dateRange.end ? todayInterval : 'day',
|
dateRange.start === dateRange.end ? todayInterval : multiDayInterval,
|
||||||
password
|
password
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -236,6 +237,17 @@ export default function PublicDashboardPage() {
|
|||||||
className="min-w-[100px]"
|
className="min-w-[100px]"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{dateRange.start !== dateRange.end && (
|
||||||
|
<Select
|
||||||
|
value={multiDayInterval}
|
||||||
|
onChange={(value) => setMultiDayInterval(value as 'hour' | 'day')}
|
||||||
|
options={[
|
||||||
|
{ value: 'hour', label: '1 hour' },
|
||||||
|
{ value: 'day', label: '1 day' },
|
||||||
|
]}
|
||||||
|
className="min-w-[100px]"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{/* Powered by Ciphera Badge */}
|
{/* Powered by Ciphera Badge */}
|
||||||
<a
|
<a
|
||||||
href="https://ciphera.net"
|
href="https://ciphera.net"
|
||||||
@@ -267,7 +279,7 @@ export default function PublicDashboardPage() {
|
|||||||
data={safeDailyStats}
|
data={safeDailyStats}
|
||||||
prevData={[]}
|
prevData={[]}
|
||||||
stats={safeStats}
|
stats={safeStats}
|
||||||
interval={dateRange.start === dateRange.end ? todayInterval : 'day'}
|
interval={dateRange.start === dateRange.end ? todayInterval : multiDayInterval}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export default function SiteDashboardPage() {
|
|||||||
const [dateRange, setDateRange] = useState(getDateRange(30))
|
const [dateRange, setDateRange] = useState(getDateRange(30))
|
||||||
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false)
|
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false)
|
||||||
const [todayInterval, setTodayInterval] = useState<'minute' | 'hour'>('hour')
|
const [todayInterval, setTodayInterval] = useState<'minute' | 'hour'>('hour')
|
||||||
|
const [multiDayInterval, setMultiDayInterval] = useState<'hour' | 'day'>('day')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadData()
|
loadData()
|
||||||
@@ -51,7 +52,7 @@ export default function SiteDashboardPage() {
|
|||||||
loadRealtime()
|
loadRealtime()
|
||||||
}, 30000) // Update every 30 seconds
|
}, 30000) // Update every 30 seconds
|
||||||
return () => clearInterval(interval)
|
return () => clearInterval(interval)
|
||||||
}, [siteId, dateRange, todayInterval])
|
}, [siteId, dateRange, todayInterval, multiDayInterval])
|
||||||
|
|
||||||
const getPreviousDateRange = (start: string, end: string) => {
|
const getPreviousDateRange = (start: string, end: string) => {
|
||||||
const startDate = new Date(start)
|
const startDate = new Date(start)
|
||||||
@@ -80,7 +81,7 @@ export default function SiteDashboardPage() {
|
|||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
const interval = dateRange.start === dateRange.end ? todayInterval : 'day'
|
const interval = dateRange.start === dateRange.end ? todayInterval : multiDayInterval
|
||||||
|
|
||||||
const [data, prevStatsData, prevDailyStatsData] = await Promise.all([
|
const [data, prevStatsData, prevDailyStatsData] = await Promise.all([
|
||||||
getDashboard(siteId, dateRange.start, dateRange.end, 10, interval),
|
getDashboard(siteId, dateRange.start, dateRange.end, 10, interval),
|
||||||
@@ -209,6 +210,17 @@ export default function SiteDashboardPage() {
|
|||||||
className="min-w-[100px]"
|
className="min-w-[100px]"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{dateRange.start !== dateRange.end && (
|
||||||
|
<Select
|
||||||
|
value={multiDayInterval}
|
||||||
|
onChange={(value) => setMultiDayInterval(value as 'hour' | 'day')}
|
||||||
|
options={[
|
||||||
|
{ value: 'hour', label: '1 hour' },
|
||||||
|
{ value: 'day', label: '1 day' },
|
||||||
|
]}
|
||||||
|
className="min-w-[100px]"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push(`/sites/${siteId}/settings`)}
|
onClick={() => router.push(`/sites/${siteId}/settings`)}
|
||||||
className="btn-secondary text-sm"
|
className="btn-secondary text-sm"
|
||||||
@@ -226,7 +238,7 @@ export default function SiteDashboardPage() {
|
|||||||
prevData={prevDailyStats}
|
prevData={prevDailyStats}
|
||||||
stats={stats}
|
stats={stats}
|
||||||
prevStats={prevStats}
|
prevStats={prevStats}
|
||||||
interval={dateRange.start === dateRange.end ? todayInterval : 'day'}
|
interval={dateRange.start === dateRange.end ? todayInterval : multiDayInterval}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user