|
| 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