Skip to content

Commit

Permalink
feat: Add last login timestamp in user settings
Browse files Browse the repository at this point in the history
  • Loading branch information
dogukanoksuz committed Jan 28, 2025
1 parent a17c329 commit 27f5f26
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 30 deletions.
2 changes: 2 additions & 0 deletions public/locales/de/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@
"otp": "Zwei-Faktor-Authentifizierung",
"otp_enabled": "Aktiviert",
"otp_disabled": "Deaktiviert",
"last_login_at": "Letzter Login",
"never": "Nie",
"toasts": {
"edit_success_msg": "Der Benutzer wurde erfolgreich bearbeitet.",
"edit_error_msg": "Beim Bearbeiten des Benutzers ist ein Fehler aufgetreten.",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/en/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@
"otp": "Two-Factor Authentication",
"otp_enabled": "Enabled",
"otp_disabled": "Disabled",
"last_login_at": "Last Login",
"never": "Never",
"toasts": {
"success_msg": "The user has been created successfully.",
"edit_success_msg": "The user has been edited successfully.",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/tr/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@
"otp": "İki Aşamalı Giriş",
"otp_enabled": "Aktif",
"otp_disabled": "Pasif",
"last_login_at": "Son Giriş",
"never": "Hiç",
"toasts": {
"success_msg": "Kullanıcı başarıyla oluşturuldu.",
"edit_success_msg": "Kullanıcı başarıyla düzenlendi.",
Expand Down
13 changes: 13 additions & 0 deletions src/components/ui/data-table/data-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ const DataTable = <TData, TValue>({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rowSelection])

React.useEffect(() => {
columns.forEach((column: any) => {
// Check if meta.hidden exists, if it's set column will be hidden
const meta = column.meta
if (meta && meta.hidden) {
setColumnVisibility((prev) => ({
...prev,
[column.accessorKey]: false,
}))
}
})
}, [])

return (
<div className="data-table space-y-4">
<div className="flex items-center justify-between">
Expand Down
25 changes: 25 additions & 0 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,28 @@ export function setFormErrors(e: Error, form: UseFormReturn<any>) {

return false
}

export function getRelativeTimeString(
date: Date | number | string,
lang = "tr"
): string {
const now = new Date().getTime()
const time = new Date(date).getTime()
const diff = now - time

const seconds = Math.floor(diff / 1000)
const minutes = Math.floor(seconds / 60)
const hours = Math.floor(minutes / 60)
const days = Math.floor(hours / 24)
const months = Math.floor(days / 30)
const years = Math.floor(days / 365)

const rtf = new Intl.RelativeTimeFormat(lang, { numeric: "auto" })

if (seconds < 60) return rtf.format(-seconds, "second")
if (minutes < 60) return rtf.format(-minutes, "minute")
if (hours < 24) return rtf.format(-hours, "hour")
if (days < 30) return rtf.format(-days, "day")
if (months < 12) return rtf.format(-months, "month")
return rtf.format(-years, "year")
}
77 changes: 47 additions & 30 deletions src/pages/settings/users/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { useEffect, useState } from "react"
import { useRouter } from "next/router"
import { http } from "@/services"
import { Check, Footprints, User2, UserCog2, X } from "lucide-react"
import { useRouter } from "next/router"
import { useEffect, useState } from "react"
import { useTranslation } from "react-i18next"

import CreateUser from "@/components/settings/create-user"
import EditUser from "@/components/settings/edit-user"
import { UserRowActions } from "@/components/settings/user-actions"
import { DivergentColumn } from "@/types/table"
import { IAuthLog, IUser } from "@/types/user"
import { getRelativeTimeString } from "@/lib/utils"
import { useEmitter } from "@/hooks/useEmitter"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import DataTable from "@/components/ui/data-table/data-table"
Expand All @@ -19,9 +20,9 @@ import {
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip"
import { useEmitter } from "@/hooks/useEmitter"
import { DivergentColumn } from "@/types/table"
import { IAuthLog, IUser } from "@/types/user"
import CreateUser from "@/components/settings/create-user"
import EditUser from "@/components/settings/edit-user"
import { UserRowActions } from "@/components/settings/user-actions"

const getType = (type: string) => {
switch (type) {
Expand All @@ -41,7 +42,7 @@ export default function UserSettingsPage() {
const [data, setData] = useState<IUser[]>([])
const router = useRouter()
const emitter = useEmitter()
const { t } = useTranslation("settings")
const { t, i18n } = useTranslation("settings")

const columns: DivergentColumn<IUser, string>[] = [
{
Expand Down Expand Up @@ -107,6 +108,23 @@ export default function UserSettingsPage() {
</>
),
},
{
accessorKey: "last_login_at",
header: ({ column }) => (
<DataTableColumnHeader
column={column}
title={t("users.last_login_at")}
/>
),
title: t("users.last_login_at"),
cell: ({ row }) => (
<>
{row.original.last_login_at
? getRelativeTimeString(row.original.last_login_at, i18n.language)
: t("users.never")}
</>
),
},
{
accessorKey: "auth_type",
header: ({ column }) => (
Expand Down Expand Up @@ -175,6 +193,9 @@ export default function UserSettingsPage() {
)}
</>
),
meta: {
hidden: true,
},
},
{
id: "actions",
Expand All @@ -187,12 +208,10 @@ export default function UserSettingsPage() {
]

const fetchData = () => {
http
.get(`/settings/users`)
.then((res) => {
setData(res.data)
setLoading(false)
})
http.get(`/settings/users`).then((res) => {
setData(res.data)
setLoading(false)
})
}

useEffect(() => {
Expand Down Expand Up @@ -301,15 +320,15 @@ function AuthLogDialog() {
<>
{row.original.created_at
? new Date(row.original.created_at).toLocaleDateString(
i18n.language,
{
day: "2-digit",
month: "long",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
}
)
i18n.language,
{
day: "2-digit",
month: "long",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
}
)
: t("users.auth_log.unknown")}
</>
),
Expand All @@ -320,12 +339,10 @@ function AuthLogDialog() {
setLoading(true)
setOpen(true)

http
.get(`/settings/users/auth_logs/${user_id}`)
.then((res) => {
setData(res.data)
setLoading(false)
})
http.get(`/settings/users/auth_logs/${user_id}`).then((res) => {
setData(res.data)
setLoading(false)
})
})

return (
Expand Down

0 comments on commit 27f5f26

Please sign in to comment.