your sessions

master
alex 2024-01-27 21:04:09 +01:00
parent dc82975575
commit e99613e767
4 changed files with 140 additions and 6 deletions

View File

@ -270,7 +270,17 @@
"buttonInfo": "Nachdem Sie Ihr Passwort geändert haben, werden Sie abgemeldet und müssen sich erneut anmelden." "buttonInfo": "Nachdem Sie Ihr Passwort geändert haben, werden Sie abgemeldet und müssen sich erneut anmelden."
}, },
"yourSessions": { "yourSessions": {
"cardTitle": "Ihre Sitzungen" "cardTitle": "Ihre Sitzungen",
"tagCurrentSession": "Aktuelle Sitzung",
"tableColumns": {
"device": "Gerät",
"browser": "Browser",
"lastUsed": "Zuletzt verwendet"
},
"popconfirm": {
"title": "Sitzung abmelden",
"description": "Möchten Sie diese Sitzung wirklich abmelden?"
}
}, },
"deleteAccount": { "deleteAccount": {
"cardTitle": "Konto löschen" "cardTitle": "Konto löschen"

View File

@ -279,7 +279,17 @@
} }
}, },
"yourSessions": { "yourSessions": {
"cardTitle": "Your sessions" "cardTitle": "Your sessions",
"tagCurrentSession": "Current session",
"tableColumns": {
"device": "Device",
"browser": "Browser",
"lastUsed": "Last used"
},
"popconfirm": {
"title": "Delete session",
"description": "Are you sure you want to delete this session?"
}
}, },
"deleteAccount": { "deleteAccount": {
"cardTitle": "Delete account" "cardTitle": "Delete account"

View File

@ -2,15 +2,18 @@ import {
Button, Button,
Card, Card,
Form, Form,
Popconfirm,
Select, Select,
Skeleton, Skeleton,
Space, Space,
Switch, Switch,
Tabs, Tabs,
Tag,
notification, notification,
} from "antd"; } from "antd";
import { import {
EncodeStringToBase64, EncodeStringToBase64,
FormatDatetime,
handleLogout, handleLogout,
myFetch, myFetch,
showInputsInvalidNotification, showInputsInvalidNotification,
@ -29,6 +32,7 @@ import {
} from "../../Components/MyFormInputs"; } from "../../Components/MyFormInputs";
import { MySupsenseFallback } from "../../Components/MySupsenseFallback"; import { MySupsenseFallback } from "../../Components/MySupsenseFallback";
import { useSideBarContext } from "../../Contexts/SideBarContext"; import { useSideBarContext } from "../../Contexts/SideBarContext";
import MyTable from "../../Components/MyTable";
const globalRequestStatePreview = { const globalRequestStatePreview = {
global: RequestState.INIT, global: RequestState.INIT,
@ -472,11 +476,113 @@ function ChangePassword({
} }
function YourSessions() { function YourSessions() {
useEffect(() => { const { t } = useTranslation();
console.log("your sessions");
}, []);
return <h1>Test</h1>; const [isRequesting, setIsRequesting] = useState(true);
const [requestData, setRequestData] = useState({
sessions: [],
currentSession: "",
});
const getTableColumns = () => {
return [
{
title: t("userProfile.yourSessions.tableColumns.device"),
dataIndex: "device",
key: "device",
},
{
title: t("userProfile.yourSessions.tableColumns.browser"),
dataIndex: "browser",
key: "browser",
},
{
title: t("userProfile.yourSessions.tableColumns.lastUsed"),
dataIndex: "last_used",
key: "last_used",
},
{
title: t("common.action"),
dataIndex: "actions",
key: "actions",
},
];
};
const getTableItems = () => {
return requestData.sessions.map((item) => {
return {
key: item.id,
device: item.os,
browser: item.browser,
last_used: (
<Space>
{FormatDatetime(item.last_used)}
{requestData.currentSession === item.id && (
<Tag color="green">
{t("userProfile.yourSessions.tagCurrentSession")}
</Tag>
)}
</Space>
),
actions: (
<Popconfirm
title={t("userProfile.yourSessions.popconfirm.title")}
description={t("userProfile.yourSessions.popconfirm.description")}
onConfirm={() => {
setIsRequesting(true);
myFetch({
url: `/user/profile/sessions/${item.id}`,
method: "DELETE",
})
.then(() => {
setIsRequesting(false);
// If the current session is deleted, reload the page
if (item.id === requestData.currentSession) {
window.location.reload();
}
requestSessions();
})
.catch(() => setIsRequesting(false));
}}
okText={t("common.button.logout")}
cancelText={t("common.button.cancel")}
>
<Button type="link">{t("common.button.delete")}</Button>
</Popconfirm>
),
};
});
};
const requestSessions = () => {
setIsRequesting(true);
myFetch({
url: "/user/profile/sessions",
method: "GET",
})
.then((res) => {
setIsRequesting(false);
setRequestData(res);
})
.catch(() => setIsRequesting(false));
};
useEffect(() => requestSessions(), []);
return (
<MyTable
props={{
loading: isRequesting,
columns: getTableColumns(),
dataSource: getTableItems(),
}}
/>
);
} }
function DeleteAccount() { function DeleteAccount() {

View File

@ -251,3 +251,11 @@ export function handleLogout({ setUserSession }) {
setUserSession(); setUserSession();
window.location.href = "/"; window.location.href = "/";
} }
export function FormatDatetime(datetime) {
if (datetime === undefined || datetime === "0001-01-01T00:00:00Z") {
return Constants.TEXT_EMPTY_PLACEHOLDER;
}
return new Date(datetime).toLocaleString("de-DE");
}