login time

This commit is contained in:
Sone
2025-11-05 20:11:34 +01:00
parent b43aec6b9a
commit fdcc42007a
21 changed files with 1363 additions and 843 deletions
@@ -0,0 +1,39 @@
import { View, Text } from "react-native";
import { UserLoginLog } from "@/store/api/usersApi";
import { formatDate, formatTimeWithSeconds } from "@/utils/dateUtils";
import { reasonLabel } from "@/utils/loginUtils";
interface LoginListItemProps {
log: UserLoginLog;
}
export const LoginListItem = ({ log }: LoginListItemProps) => {
const isSuccess = log.status === "SUCCESS";
const isFailure = log.status === "FAILURE";
return (
<View className="bg-white rounded-lg p-1 mb-3 shadow-sm">
<View className="flex-row items-center">
<Text
className="text-sm font-medium text-gray-700 flex-1"
numberOfLines={1}
ellipsizeMode="tail"
>
{formatDate(log.lastLoginAt)} -{" "}
{formatTimeWithSeconds(log.lastLoginAt)} {" | "}
<Text
style={{
color: isSuccess ? "#22C927" : "#F83434",
fontWeight: "bold",
}}
>
{isSuccess
? log.activity
: reasonLabel(log.failureReason) || "Failed"}
</Text>
</Text>
</View>
</View>
);
};
@@ -1,16 +1,37 @@
import { View, Text } from "react-native";
import { User } from "@/store/models/User.model";
import { useGetUserLogsByIdQuery } from "@/store/api/usersApi";
import { LoginListItem } from "@/components/features/accounts/LoginListItem";
interface PersonalLoginListProps {
user: User;
}
export const PersonalLoginList = ({ user }: PersonalLoginListProps) => {
const { data, isLoading, isError } = useGetUserLogsByIdQuery(
{ userId: user.id, page: 1, limit: 10 },
{ skip: !user?.id }
);
const items = data?.items ?? [];
return (
<View className="bg-lightGray rounded-md">
<Text className="font-medium my-4 text-gray-600">Log-in List:</Text>
<Text className="font-medium text-black">No logins assigned</Text>
<Text className="font-medium mb-4 mt-0 text-gray-600">Log-in List:</Text>
{isLoading ? (
<Text className="text-black">Loading...</Text>
) : isError ? (
<Text className="text-black">-</Text>
) : items.length === 0 ? (
<Text className="font-medium text-black">No logins history</Text>
) : (
<View style={{ gap: 8 }}>
{items.map((log, idx) => (
<LoginListItem key={`${log.id}-${idx}`} log={log} />
))}
</View>
)}
</View>
);
};
@@ -5,7 +5,7 @@ import { InfoRow } from "./InfoRow";
import { useAppSelector } from "@/store/hooks";
import { selectIsMobile } from "@/store/screen/screenSizeSlice";
import { useGetUserLogsQuery } from "@/store/api/usersApi";
import { formatDate, formatTime } from "@/utils/dateUtils";
import { formatDate, formatTimeWithSeconds } from "@/utils/dateUtils";
import { RiskIndicator } from "@/components/ui/RiskIndicator";
import { SizeEnum } from "@/constants/sizeEnum";
import { RiskEnum, RiskLabels } from "@/constants/riskEnum";
@@ -35,7 +35,7 @@ export const PersonalMetrics = ({ user }: PersonalMetricsProps) => {
: logsError
? "-"
: lastLoginAt
? `${formatDate(lastLoginAt)} ${formatTime(lastLoginAt)}`
? `${formatDate(lastLoginAt)} ${formatTimeWithSeconds(lastLoginAt)}`
: "-";
const lastPasswordChangeDisplay = logsLoading
@@ -43,7 +43,7 @@ export const PersonalMetrics = ({ user }: PersonalMetricsProps) => {
: logsError
? "-"
: activity === "Password reset" && lastLoginAt
? `${formatDate(lastLoginAt)} ${formatTime(lastLoginAt)}`
? `${formatDate(lastLoginAt)} ${formatTimeWithSeconds(lastLoginAt)}`
: "-";
return (
@@ -23,7 +23,7 @@ export const PersonalTodoList = ({ user }: PersonalTodoListProps) => {
return (
<View className="bg-lightGray rounded-md">
<Text className="font-medium my-4 text-gray-600">To-Do List:</Text>
<Text className="font-medium mt-0 mb-4 text-gray-600">To-Do List:</Text>
{isLoading ? (
<LoadingSpinner />
) : error ? (
+12 -3
View File
@@ -2,9 +2,10 @@ import { DataTable, Text } from "react-native-paper";
import { View } from "react-native";
import { UserLoginLog } from "@/store/api/usersApi";
import { formatDate, formatTime } from "@/utils/dateUtils";
import { formatDate, formatTimeWithSeconds } from "@/utils/dateUtils";
import { LogsTableHeader } from "@/components/features/logs/LogsTableHeader";
import { TableSortDirection } from "@/constants/tableSortDirectionEnum";
import { reasonLabel } from "@/utils/loginUtils";
interface DesktopLogsTableProps {
logs: UserLoginLog[];
@@ -42,13 +43,21 @@ export const DesktopLogsTable = ({
<DataTable.Cell>
<View className="flex-row items-center flex-shrink pr-2">
<Text numberOfLines={1}>
{formatDate(log.lastLoginAt)} {formatTime(log.lastLoginAt)}
{formatDate(log.lastLoginAt)} {formatTimeWithSeconds(log.lastLoginAt)}
</Text>
</View>
</DataTable.Cell>
<DataTable.Cell>
<View className="flex-row items-center flex-shrink pr-2">
<Text numberOfLines={1}>{log.activity}</Text>
<Text
numberOfLines={1}
style={{ color: log.status === "FAILURE" ? "#F83434" : "#22C927" }}
>
{log.activity}
{log.status === "FAILURE" && reasonLabel(log.failureReason)
? ` - ${reasonLabel(log.failureReason)}`
: ""}
</Text>
</View>
</DataTable.Cell>
</DataTable.Row>
+10 -3
View File
@@ -1,7 +1,8 @@
import { ScrollView, Text, View } from "react-native";
import { UserLoginLog } from "@/store/api/usersApi";
import { formatDate, formatTime } from "@/utils/dateUtils";
import { formatDate, formatTimeWithSeconds } from "@/utils/dateUtils";
import { reasonLabel } from "@/utils/loginUtils";
interface MobileLogsTableProps {
logs: UserLoginLog[];
@@ -21,10 +22,16 @@ export const MobileLogsTable = ({ logs }: MobileLogsTableProps) => {
<Text className="font-normal text-gray-600">({log.email})</Text>
</Text>
<Text className="text-sm text-gray-700 mt-1">
Time: {formatDate(log.lastLoginAt)} {formatTime(log.lastLoginAt)}
Time: {formatDate(log.lastLoginAt)} {formatTimeWithSeconds(log.lastLoginAt)}
</Text>
<Text className="text-sm text-gray-700 mt-1">
<Text
className="text-sm mt-1"
style={{ color: log.status === "FAILURE" ? "#F83434" : "#22C927" }}
>
Login activity: {log.activity}
{log.status === "FAILURE" && reasonLabel(log.failureReason)
? ` - ${reasonLabel(log.failureReason)}`
: ""}
</Text>
</View>
))}