Skip to content

Commit 397a9e1

Browse files
committed
feat: add UserSessionsDataTableRowComponent for displaying individual user session details
1 parent 5eba72c commit 397a9e1

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"use client"
2+
3+
import React from "react";
4+
import {User, UserSession} from "@code0-tech/sagittarius-graphql-types";
5+
import {Button, DataTableColumn, Flex, Text, useService, useStore} from "@code0-tech/pictor";
6+
import {UserService} from "@edition/user/services/User.service";
7+
import {useUserSession} from "@edition/user/hooks/User.session.hook";
8+
import {formatDistanceToNow} from "date-fns";
9+
import {IconDeviceDesktop, IconLogout} from "@tabler/icons-react";
10+
import {addIslandSuccessNotification} from "@code0-tech/pictor/dist/components/island/Island.hook";
11+
12+
export interface UserSessionsDataTableRowComponentProps {
13+
userId: User['id']
14+
sessionId: UserSession['id']
15+
}
16+
17+
export const UserSessionsDataTableRowComponent: React.FC<UserSessionsDataTableRowComponentProps> = (props) => {
18+
19+
const {userId, sessionId} = props
20+
21+
const userService = useService(UserService)
22+
const userStore = useStore(UserService)
23+
const currentSession = useUserSession()
24+
25+
const session = React.useMemo(
26+
() => userService.getById(userId)?.sessions?.nodes?.find(session => session?.id === sessionId) as UserSession | undefined,
27+
[userStore, userId, sessionId]
28+
)
29+
30+
const isCurrent = !!sessionId && sessionId === currentSession?.id
31+
32+
const logout = React.useCallback(() => {
33+
if (!sessionId) return
34+
userService.usersLogout({userSessionId: sessionId}).then(payload => {
35+
if ((payload?.errors?.length ?? 0) <= 0) {
36+
addIslandSuccessNotification({
37+
message: "Logged out session"
38+
})
39+
}
40+
})
41+
}, [sessionId])
42+
43+
if (!session) return null
44+
45+
return <>
46+
<DataTableColumn pr={2.5}>
47+
<Flex align={"center"} style={{gap: "0.7rem"}}>
48+
<IconDeviceDesktop size={16}/>
49+
<Flex style={{flexDirection: "column"}}>
50+
<Text size={"md"} hierarchy={"primary"}>
51+
{isCurrent ? "This device" : "Session"}
52+
</Text>
53+
{session.createdAt && (
54+
<Text size={"xs"} hierarchy={"tertiary"}>
55+
Created {formatDistanceToNow(new Date(session.createdAt), {addSuffix: true})}
56+
</Text>
57+
)}
58+
</Flex>
59+
60+
</Flex>
61+
</DataTableColumn>
62+
<DataTableColumn pr={2.5}>
63+
{session.updatedAt && (
64+
<Text hierarchy={"tertiary"}>
65+
Last used {formatDistanceToNow(new Date(session.updatedAt), {addSuffix: true})}
66+
</Text>
67+
)}
68+
</DataTableColumn>
69+
<DataTableColumn>
70+
<Button p={0.5} color={"secondary"} variant={"none"} onClick={logout}>
71+
<IconLogout size={16}/>
72+
</Button>
73+
</DataTableColumn>
74+
</>
75+
}

0 commit comments

Comments
 (0)