Skip to content

Commit f7cdea0

Browse files
committed
fix(users-table): url params
1 parent 98a9212 commit f7cdea0

File tree

7 files changed

+318
-100
lines changed

7 files changed

+318
-100
lines changed

dashboard/src/components/dialogs/user-subscription-clients-modal.tsx

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,29 @@ const formatTimeAgo = (timestamp: number, t: (key: string, options?: Record<stri
2727
return t('justNow', { defaultValue: 'Just now' })
2828
}
2929

30-
const duration = dayjs.duration(diffInSeconds, 'seconds')
30+
// Use calendar-aware diff methods for accurate calculations
31+
// pastTime is always earlier than currentTime
32+
const years = Math.abs(currentTime.diff(pastTime, 'year'))
33+
const months = Math.abs(currentTime.diff(pastTime.add(years, 'year'), 'month'))
34+
const days = Math.abs(currentTime.diff(pastTime.add(years, 'year').add(months, 'month'), 'day'))
35+
const hours = Math.abs(currentTime.diff(pastTime.add(years, 'year').add(months, 'month').add(days, 'day'), 'hour'))
36+
const minutes = Math.abs(currentTime.diff(pastTime.add(years, 'year').add(months, 'month').add(days, 'day').add(hours, 'hour'), 'minute'))
37+
const seconds = Math.abs(currentTime.diff(pastTime.add(years, 'year').add(months, 'month').add(days, 'day').add(hours, 'hour').add(minutes, 'minute'), 'second'))
38+
3139
let timeText = ''
3240

33-
if (duration.years() > 0) {
34-
timeText = `${duration.years()} ${t(`time.${duration.years() !== 1 ? 'years' : 'year'}`)} ${t('time.ago')}`
35-
} else if (duration.months() > 0) {
36-
timeText = `${duration.months()} ${t(`time.${duration.months() !== 1 ? 'months' : 'month'}`)} ${t('time.ago')}`
37-
} else if (duration.days() > 0) {
38-
timeText = `${duration.days()} ${t(`time.${duration.days() !== 1 ? 'days' : 'day'}`)} ${t('time.ago')}`
39-
} else if (duration.hours() > 0) {
40-
timeText = `${duration.hours()} ${t(`time.${duration.hours() !== 1 ? 'hours' : 'hour'}`)} ${t('time.ago')}`
41-
} else if (duration.minutes() > 0) {
42-
timeText = `${duration.minutes()} ${t(`time.${duration.minutes() !== 1 ? 'mins' : 'min'}`)} ${t('time.ago')}`
41+
if (years > 0) {
42+
timeText = `${years} ${t(`time.${years !== 1 ? 'years' : 'year'}`)} ${t('time.ago')}`
43+
} else if (months > 0) {
44+
timeText = `${months} ${t(`time.${months !== 1 ? 'months' : 'month'}`)} ${t('time.ago')}`
45+
} else if (days > 0) {
46+
timeText = `${days} ${t(`time.${days !== 1 ? 'days' : 'day'}`)} ${t('time.ago')}`
47+
} else if (hours > 0) {
48+
timeText = `${hours} ${t(`time.${hours !== 1 ? 'hours' : 'hour'}`)} ${t('time.ago')}`
49+
} else if (minutes > 0) {
50+
timeText = `${minutes} ${t(`time.${minutes !== 1 ? 'mins' : 'min'}`)} ${t('time.ago')}`
4351
} else {
44-
timeText = `${duration.seconds()} ${t(`time.${duration.seconds() !== 1 ? 'seconds' : 'second'}`)} ${t('time.ago')}`
52+
timeText = `${seconds} ${t(`time.${seconds !== 1 ? 'seconds' : 'second'}`)} ${t('time.ago')}`
4553
}
4654

4755
return timeText

dashboard/src/components/users/columns.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,26 @@ export const setupColumns = ({
5454
if (isOnline) {
5555
return null
5656
} else {
57-
const duration = dayjs.duration(diffInSeconds, 'seconds')
57+
// Use calendar-aware diff methods for accurate calculations
58+
const years = Math.abs(currentTime.diff(lastOnlineTime, 'year'))
59+
const months = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year'), 'month'))
60+
const days = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month'), 'day'))
61+
const hours = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month').add(days, 'day'), 'hour'))
62+
const minutes = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month').add(days, 'day').add(hours, 'hour'), 'minute'))
63+
const seconds = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month').add(days, 'day').add(hours, 'hour').add(minutes, 'minute'), 'second'))
5864

59-
if (duration.days() > 0) {
60-
return `${duration.days()}d`
61-
} else if (duration.hours() > 0) {
62-
return `${duration.hours()}h`
63-
} else if (duration.minutes() > 0) {
64-
return `${duration.minutes()}m`
65+
if (years > 0) {
66+
return `${years}y`
67+
} else if (months > 0) {
68+
return `${months}mo`
69+
} else if (days > 0) {
70+
return `${days}d`
71+
} else if (hours > 0) {
72+
return `${hours}h`
73+
} else if (minutes > 0) {
74+
return `${minutes}m`
6575
} else {
66-
return `${duration.seconds()}s`
76+
return `${seconds}s`
6777
}
6878
}
6979
}

dashboard/src/components/users/filters.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import useDirDetection from '@/hooks/use-dir-detection'
99
import { cn } from '@/lib/utils'
1010
import { useDebouncedSearch } from '@/hooks/use-debounced-search'
1111
import { RefreshCw, SearchIcon, Filter, X, ArrowUpDown, User, Calendar, ChartPie, ChevronDown, Check, Clock } from 'lucide-react'
12-
import { useState, useEffect, useCallback } from 'react'
12+
import { useState, useEffect, useCallback, useRef } from 'react'
1313
import { useTranslation } from 'react-i18next'
1414
import { useGetUsers, UserStatus } from '@/service/api'
1515
import { RefetchOptions } from '@tanstack/react-query'
@@ -90,6 +90,7 @@ export const Filters = ({ filters, onFilterChange, refetch, autoRefetch, advance
9090
const [autoRefreshInterval, setAutoRefreshInterval] = useState<number>(() => getUsersAutoRefreshIntervalSeconds())
9191
const { refetch: queryRefetch, isFetching } = useGetUsers(filters)
9292
const { search, debouncedSearch, setSearch } = useDebouncedSearch(filters.search || '', 300)
93+
const prevDebouncedSearchRef = useRef<string | undefined>(filters.search || undefined)
9394

9495
const refetchUsers = useCallback(
9596
async (showLoading = false, isAutoRefresh = false) => {
@@ -142,10 +143,14 @@ export const Filters = ({ filters, onFilterChange, refetch, autoRefetch, advance
142143

143144
// Update filters when debounced search changes
144145
useEffect(() => {
145-
onFilterChange({
146-
search: debouncedSearch || '',
147-
offset: 0,
148-
})
146+
// Only update if search actually changed to avoid resetting page on initial load
147+
if (debouncedSearch !== prevDebouncedSearchRef.current) {
148+
prevDebouncedSearchRef.current = debouncedSearch
149+
onFilterChange({
150+
search: debouncedSearch || '',
151+
offset: 0,
152+
})
153+
}
149154
}, [debouncedSearch, onFilterChange])
150155

151156
// Handle input change

dashboard/src/components/users/online-badge.tsx

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,41 @@ export const OnlineBadge: FC<UserStatusProps> = ({ lastOnline }) => {
2525
if (isOnline) {
2626
return t('online')
2727
} else {
28-
// Format the time difference for offline status
29-
const duration = dayjs.duration(diffInSeconds, 'seconds')
30-
let timeText = ''
28+
// Format the time difference for offline status using calendar-aware diff methods
29+
const years = Math.abs(currentTime.diff(lastOnlineTime, 'year'))
30+
const months = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year'), 'month'))
31+
const days = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month'), 'day'))
32+
const hours = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month').add(days, 'day'), 'hour'))
33+
const minutes = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month').add(days, 'day').add(hours, 'hour'), 'minute'))
34+
const seconds = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month').add(days, 'day').add(hours, 'hour').add(minutes, 'minute'), 'second'))
3135

32-
if (duration.years() > 0) {
33-
timeText = `${duration.years()} ${t(`time.${duration.years() !== 1 ? 'years' : 'year'}`)} ${t('time.ago')}`
34-
} else if (duration.months() > 0) {
35-
timeText = `${duration.months()} ${t(`time.${duration.months() !== 1 ? 'months' : 'month'}`)} ${t('time.ago')}`
36-
} else if (duration.days() > 0) {
37-
timeText = `${duration.days()} ${t(`time.${duration.days() !== 1 ? 'days' : 'day'}`)} ${t('time.ago')}`
38-
} else if (duration.hours() > 0) {
39-
timeText = `${duration.hours()} ${t(`time.${duration.hours() !== 1 ? 'hours' : 'hour'}`)} ${t('time.ago')}`
40-
} else if (duration.minutes() > 0) {
41-
timeText = `${duration.minutes()} ${t(`time.${duration.minutes() !== 1 ? 'mins' : 'min'}`)} ${t('time.ago')}`
42-
} else {
43-
timeText = `${duration.seconds()} ${t(`time.${duration.seconds() !== 1 ? 'seconds' : 'second'}`)} ${t('time.ago')}`
36+
const parts: string[] = []
37+
38+
if (years > 0) {
39+
parts.push(`${years} ${t(`time.${years !== 1 ? 'years' : 'year'}`)}`)
40+
}
41+
if (months > 0) {
42+
parts.push(`${months} ${t(`time.${months !== 1 ? 'months' : 'month'}`)}`)
43+
}
44+
if (days > 0) {
45+
parts.push(`${days} ${t(`time.${days !== 1 ? 'days' : 'day'}`)}`)
46+
}
47+
if (hours > 0 && parts.length < 2) {
48+
parts.push(`${hours} ${t(`time.${hours !== 1 ? 'hours' : 'hour'}`)}`)
49+
}
50+
if (minutes > 0 && parts.length < 2) {
51+
parts.push(`${minutes} ${t(`time.${minutes !== 1 ? 'mins' : 'min'}`)}`)
52+
}
53+
if (seconds > 0 && parts.length === 0) {
54+
parts.push(`${seconds} ${t(`time.${seconds !== 1 ? 'seconds' : 'second'}`)}`)
55+
}
56+
57+
if (parts.length === 0) {
58+
return t('time.ago')
4459
}
4560

46-
return timeText
61+
const timeText = parts.join(', ')
62+
return `${timeText} ${t('time.ago')}`
4763
}
4864
}
4965

dashboard/src/components/users/online-status.tsx

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,28 @@ export const OnlineStatus: FC<UserStatusProps> = ({ lastOnline }) => {
2626
if (isOnline) {
2727
return <span className={cn('inline-block text-xs font-medium', dir === 'rtl' ? 'mr-0.5 md:mr-2' : 'ml-0.5 md:ml-2', 'text-gray-600 dark:text-gray-400')}>{t('online')}</span>
2828
} else {
29-
// Format the time difference for offline status
30-
const duration = dayjs.duration(diffInSeconds, 'seconds')
29+
// Format the time difference for offline status using calendar-aware diff methods
30+
const years = Math.abs(currentTime.diff(lastOnlineTime, 'year'))
31+
const months = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year'), 'month'))
32+
const days = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month'), 'day'))
33+
const hours = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month').add(days, 'day'), 'hour'))
34+
const minutes = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month').add(days, 'day').add(hours, 'hour'), 'minute'))
35+
const seconds = Math.abs(currentTime.diff(lastOnlineTime.add(years, 'year').add(months, 'month').add(days, 'day').add(hours, 'hour').add(minutes, 'minute'), 'second'))
36+
3137
let timeText = ''
3238

33-
if (duration.years() > 0) {
34-
timeText = `${duration.years()} ${t(`time.${duration.years() !== 1 ? 'years' : 'year'}`)} ${t('time.ago')}`
35-
} else if (duration.months() > 0) {
36-
timeText = `${duration.months()} ${t(`time.${duration.months() !== 1 ? 'months' : 'month'}`)} ${t('time.ago')}`
37-
} else if (duration.days() > 0) {
38-
timeText = `${duration.days()} ${t(`time.${duration.days() !== 1 ? 'days' : 'day'}`)} ${t('time.ago')}`
39-
} else if (duration.hours() > 0) {
40-
timeText = `${duration.hours()} ${t(`time.${duration.hours() !== 1 ? 'hours' : 'hour'}`)} ${t('time.ago')}`
41-
} else if (duration.minutes() > 0) {
42-
timeText = `${duration.minutes()} ${t(`time.${duration.minutes() !== 1 ? 'mins' : 'min'}`)} ${t('time.ago')}`
39+
if (years > 0) {
40+
timeText = `${years} ${t(`time.${years !== 1 ? 'years' : 'year'}`)} ${t('time.ago')}`
41+
} else if (months > 0) {
42+
timeText = `${months} ${t(`time.${months !== 1 ? 'months' : 'month'}`)} ${t('time.ago')}`
43+
} else if (days > 0) {
44+
timeText = `${days} ${t(`time.${days !== 1 ? 'days' : 'day'}`)} ${t('time.ago')}`
45+
} else if (hours > 0) {
46+
timeText = `${hours} ${t(`time.${hours !== 1 ? 'hours' : 'hour'}`)} ${t('time.ago')}`
47+
} else if (minutes > 0) {
48+
timeText = `${minutes} ${t(`time.${minutes !== 1 ? 'mins' : 'min'}`)} ${t('time.ago')}`
4349
} else {
44-
timeText = `${duration.seconds()} ${t(`time.${duration.seconds() !== 1 ? 'seconds' : 'second'}`)} ${t('time.ago')}`
50+
timeText = `${seconds} ${t(`time.${seconds !== 1 ? 'seconds' : 'second'}`)} ${t('time.ago')}`
4551
}
4652

4753
return <span className={cn('inline-block text-xs font-medium', dir === 'rtl' ? 'mr-0.5 md:mr-2' : 'ml-0.5 md:ml-2', 'text-gray-600 dark:text-gray-400')}>{timeText}</span>

0 commit comments

Comments
 (0)