feat(whatWeKnowAboutYou): finished whatWeKnowAboutYou Seite
Build and Push Docker image / build-and-push (push) Successful in 5m53s
Details
Build and Push Docker image / build-and-push (push) Successful in 5m53s
Details
This commit is contained in:
parent
29c52d2638
commit
d605d17d06
|
@ -33,7 +33,7 @@ export default function Analytics() {
|
||||||
<div className={"group"}>
|
<div className={"group"}>
|
||||||
<Button
|
<Button
|
||||||
component={Link}
|
component={Link}
|
||||||
to={"/legal/privacy-policy"}
|
to={"/util/whatWeKnowAboutYou"}
|
||||||
size={"xs"}
|
size={"xs"}
|
||||||
color={"gray"}
|
color={"gray"}
|
||||||
>
|
>
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
import {Alert, Anchor, Button, Center, Collapse, SimpleGrid, Text, TextInput, Title} from "@mantine/core";
|
||||||
|
import {IconBug, IconEraser, IconGlobe, IconId, IconSlash, IconWorldWww} from "@tabler/icons-react";
|
||||||
|
import {
|
||||||
|
BrowserIcon,
|
||||||
|
DeviceTypeIcon,
|
||||||
|
OsIcon
|
||||||
|
} from "@/pages/admin/AnalyticsDashboard/AnalyticsSessions/AnalyticsSessionRow.tsx";
|
||||||
|
import DataItem from "@/pages/util/whatWeKnowAboutYou/DataItem.tsx";
|
||||||
|
import {useLocation} from "react-router-dom";
|
||||||
|
import {useCookies} from "react-cookie";
|
||||||
|
import {ANALYTICS_COOKIE_NAME, ANALYTICS_IP_API} from "../../../../config.ts";
|
||||||
|
import {UAParser} from "ua-parser-js";
|
||||||
|
import {usePreferredLanguage} from "@uidotdev/usehooks";
|
||||||
|
import {useMutation, useQuery} from "@tanstack/react-query";
|
||||||
|
import {ofetch} from "ofetch";
|
||||||
|
import {AnalyticsIpApiResult} from "@/models/AnalyticsTypes.ts";
|
||||||
|
import {usePB} from "@/lib/pocketbase.tsx";
|
||||||
|
import {pprintDate} from "@/lib/datetime.ts";
|
||||||
|
import {useDisclosure} from "@mantine/hooks";
|
||||||
|
import {hasLength, useForm} from "@mantine/form";
|
||||||
|
import {showErrorNotification, showSuccessNotification} from "@/components/util.tsx";
|
||||||
|
|
||||||
|
const DeleteDataRequest = () => {
|
||||||
|
const [cookies, , removeCookie] = useCookies([ANALYTICS_COOKIE_NAME])
|
||||||
|
const [showDialog, handler] = useDisclosure(false)
|
||||||
|
const {pb} = usePB()
|
||||||
|
|
||||||
|
const formValues = useForm({
|
||||||
|
initialValues: {
|
||||||
|
visitorId: ""
|
||||||
|
},
|
||||||
|
validate: {
|
||||||
|
visitorId: hasLength({min: 15, max: 15}, "Bitte gib eine gültige Analyse-ID ein")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const deleteDataMutation = useMutation({
|
||||||
|
mutationFn: async (visitorId: string) => {
|
||||||
|
await pb.collection("analyticsVisitors").delete(visitorId, {
|
||||||
|
credentials: "omit"
|
||||||
|
})
|
||||||
|
return visitorId
|
||||||
|
},
|
||||||
|
onSuccess: (visitorId) => {
|
||||||
|
if (cookies[ANALYTICS_COOKIE_NAME] === visitorId) {
|
||||||
|
removeCookie(ANALYTICS_COOKIE_NAME, {path: "/"})
|
||||||
|
}
|
||||||
|
formValues.reset()
|
||||||
|
showSuccessNotification(`Die Analysedaten wurden gelöscht.`)
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
showErrorNotification(`Die Analysedaten konnten nicht gelöscht werden.`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<Center className={"stack"}>
|
||||||
|
<Anchor
|
||||||
|
variant={"outline"}
|
||||||
|
component={"button"}
|
||||||
|
size={"sm"}
|
||||||
|
onClick={() => {
|
||||||
|
handler.toggle()
|
||||||
|
formValues.reset()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Löschung von Daten beantragen
|
||||||
|
</Anchor>
|
||||||
|
|
||||||
|
<Collapse in={showDialog}>
|
||||||
|
<form className={"group center"} onSubmit={formValues.onSubmit((val) => {
|
||||||
|
deleteDataMutation.mutate(val.visitorId)
|
||||||
|
})}>
|
||||||
|
<TextInput
|
||||||
|
placeholder={"Analyse-ID"}
|
||||||
|
leftSection={<IconId/>}
|
||||||
|
{...formValues.getInputProps("visitorId")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type={"submit"}
|
||||||
|
color={"red"}
|
||||||
|
size={"compact-md"}
|
||||||
|
leftSection={<IconEraser/>}
|
||||||
|
>
|
||||||
|
Daten löschen
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</Collapse>
|
||||||
|
</Center>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CollectedAnalyticsData() {
|
||||||
|
|
||||||
|
const {pb} = usePB()
|
||||||
|
|
||||||
|
const location = useLocation()
|
||||||
|
|
||||||
|
const [cookies] = useCookies([ANALYTICS_COOKIE_NAME])
|
||||||
|
const cookieValue = cookies[ANALYTICS_COOKIE_NAME]
|
||||||
|
|
||||||
|
const parserResult = new UAParser().getResult()
|
||||||
|
|
||||||
|
const preferredLanguage = usePreferredLanguage()
|
||||||
|
|
||||||
|
const ipQuery = useQuery({
|
||||||
|
queryKey: ['ip'],
|
||||||
|
queryFn: async () => {
|
||||||
|
return await ofetch<AnalyticsIpApiResult>(ANALYTICS_IP_API, {ignoreResponseError: true})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const visitorIdQuery = useQuery({
|
||||||
|
queryKey: ['visitorId', cookieValue],
|
||||||
|
queryFn: async () => {
|
||||||
|
const res = await pb.collection("analyticsVisitors").getOne(cookieValue)
|
||||||
|
|
||||||
|
return {
|
||||||
|
activeSince: res?.created,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enabled: !!cookieValue
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={"section-transparent stack"}>
|
||||||
|
<Center mt={"xl"}>
|
||||||
|
<Title order={2}>Anonyme Analysedaten</Title>
|
||||||
|
</Center>
|
||||||
|
|
||||||
|
<Center>
|
||||||
|
<Text ta={"center"} c={"dimmed"}>
|
||||||
|
Alle Analysedaten, die wir sammeln, sind anonymisiert und dienen dazu, diesen Dienst zu
|
||||||
|
verbessern
|
||||||
|
und zu personalisieren.
|
||||||
|
<br/>
|
||||||
|
Wir geben keine Daten an Dritte weiter. Die Daten liegen auf unseren eigenen Servern in
|
||||||
|
Deutschland.
|
||||||
|
<br/>
|
||||||
|
Nur Systemadministratoren haben Zugriff auf die Daten. Wir sammeln diese Daten erst, nachdem
|
||||||
|
Cookies
|
||||||
|
akzeptiert wurden.
|
||||||
|
</Text>
|
||||||
|
</Center>
|
||||||
|
|
||||||
|
<DeleteDataRequest/>
|
||||||
|
|
||||||
|
{!cookieValue && (
|
||||||
|
<Alert ta={"center"} fw={"600"} color={"green"}>
|
||||||
|
Solange du keine Cookies akzeptierst, sammeln wir keine Analysedaten.
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<SimpleGrid cols={{base: 1, sm: 2, md: 3}}>
|
||||||
|
{
|
||||||
|
[
|
||||||
|
{
|
||||||
|
icon: IconId,
|
||||||
|
title: "Analyse-ID",
|
||||||
|
data: cookieValue ?? "-",
|
||||||
|
description: <>
|
||||||
|
Du bist mit dieser ID aktiv
|
||||||
|
seit {pprintDate(visitorIdQuery.data?.activeSince ?? "")}.
|
||||||
|
Seit diesem Datum sammeln wir Analysedaten verknüpft mit dieser ID.
|
||||||
|
<br/>
|
||||||
|
Auf Basis dieser ID können wir die gespeicherten Analysedaten aggregieren und
|
||||||
|
analysieren.
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconSlash,
|
||||||
|
title: "Aktuelle Seite",
|
||||||
|
data: location.pathname,
|
||||||
|
description: "Der Pfad der aktuellen Seite, die du besuchst. Wir speichern diese Pfade um zu analysieren, welche Seiten am häufigsten besucht werden und wie Nutzende navigieren."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconBug,
|
||||||
|
title: "Fehler",
|
||||||
|
data: "-",
|
||||||
|
description: "Falls ein Fehler auftritt speichern wir die Fehlermeldung und den Zeitpunkt und dem entsprechenden Pfad, um die Stabilität der Seite zu verbessern."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconWorldWww,
|
||||||
|
title: "IP Adresse",
|
||||||
|
data: ipQuery.data?.ip || "-",
|
||||||
|
description: <>
|
||||||
|
Deine IP Adresse wird genutzt, um das Land zu bestimmen, aus dem du die Seite
|
||||||
|
besuchst.
|
||||||
|
<br/>
|
||||||
|
Folgende Daten können darüber hinaus anhand deiner IP Adresse bestimmt werden, <b>werden
|
||||||
|
aber nicht
|
||||||
|
gespeichert</b>:
|
||||||
|
Bundesland, Stadt, ungefährer Standort, Internetanbieter.
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconGlobe,
|
||||||
|
title: "Land",
|
||||||
|
data: ipQuery.data?.country_code || "-",
|
||||||
|
description: "Das Land, aus dem du die Seite besuchst. Diese Information wird genutzt, um die Seite zu personalisieren und um zu verstehen, woher die Nutzenden kommen."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: () => <BrowserIcon browser={parserResult.browser.name ?? ""}/>,
|
||||||
|
title: "Browser",
|
||||||
|
data: `${parserResult.browser.name} ${parserResult.browser.version}`,
|
||||||
|
description: "Dein Browser wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: () => <OsIcon os={parserResult.os.name ?? ""}/>,
|
||||||
|
title: "Betriebssystem",
|
||||||
|
data: `${parserResult.os.name} ${parserResult.os.version}`,
|
||||||
|
description: "Dein Betriebssystem wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconWorldWww,
|
||||||
|
title: "Bevorzugte Sprache",
|
||||||
|
data: preferredLanguage || "-",
|
||||||
|
description: "Deine bevorzugte Sprache wird genutzt, um zu verstehen, welche Sprachen Nutzende sprechen."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: () => <DeviceTypeIcon deviceType={parserResult.device.type ?? "desktop"}/>,
|
||||||
|
title: "Gerätetyp",
|
||||||
|
data: parserResult.device.type || "desktop",
|
||||||
|
description: "Dein Gerätetyp wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden."
|
||||||
|
}
|
||||||
|
|
||||||
|
].map((feature, index) => (
|
||||||
|
<DataItem key={index} {...feature}/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</SimpleGrid>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
import {usePB} from "@/lib/pocketbase.tsx";
|
||||||
|
import {Center, SimpleGrid, Text, Title} from "@mantine/core";
|
||||||
|
import {IconCalendarClock, IconGlobe, IconPassword, IconSignature, IconUser, IconUsers} from "@tabler/icons-react";
|
||||||
|
import {getUserName} from "@/components/users/modals/util.tsx";
|
||||||
|
import {LdapGroupModel} from "@/models/AuthTypes.ts";
|
||||||
|
import DataItem from "@/pages/util/whatWeKnowAboutYou/DataItem.tsx";
|
||||||
|
|
||||||
|
export default function CollectedUserData() {
|
||||||
|
const {user} = usePB()
|
||||||
|
|
||||||
|
if (!user) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={"section-transparent stack"}>
|
||||||
|
|
||||||
|
<Center mt={"xl"}>
|
||||||
|
<Title order={2}>Accountdaten</Title>
|
||||||
|
</Center>
|
||||||
|
|
||||||
|
<Center>
|
||||||
|
<Text ta={"center"} c={"dimmed"}>
|
||||||
|
Wenn du einen Account hast speichern wir zusätzlich zu den anonymen Analysedaten auch deine
|
||||||
|
Accountdaten.
|
||||||
|
</Text>
|
||||||
|
</Center>
|
||||||
|
|
||||||
|
<SimpleGrid
|
||||||
|
cols={{base: 1, sm: 2, md: 3}}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
[
|
||||||
|
{
|
||||||
|
icon: IconUser,
|
||||||
|
title: "Anmeldename und Realm",
|
||||||
|
data: `${user.username} (${user.REALM})`,
|
||||||
|
description: "Hiermit kannst du dich anmelden und deine Daten verwalten. Deine Realm wird genutzt, um zu bestimmen ob du einen StuVe-IT oder Gast-Account hast."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconPassword,
|
||||||
|
title: "Passwort",
|
||||||
|
data: '***********',
|
||||||
|
description: "Dein Passwort wird verschlüsselt auf unseren Servern gespeichert und kann nicht eingesehen werden."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconGlobe,
|
||||||
|
title: "E-Mail",
|
||||||
|
data: user.email,
|
||||||
|
description: "Deine E-Mail Adresse wird genutzt, um dich zu kontaktieren. Andere Nutzende können deine E-Mail Adresse nicht sehen."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconSignature,
|
||||||
|
title: "Name",
|
||||||
|
data: getUserName(user),
|
||||||
|
description: "Dein Name wird genutzt, um dich zu identifizieren. Andere Nutzende können deinen Namen sehen."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconCalendarClock,
|
||||||
|
title: "Account Ablaufdatum",
|
||||||
|
data: user?.accountExpires ? (
|
||||||
|
new Date(user?.accountExpires).getTime() > Date.now() ? (
|
||||||
|
"Account ist aktiv und läuft am " + new Date(user?.accountExpires).toLocaleDateString() + " ab"
|
||||||
|
) : (
|
||||||
|
"Account ist abgelaufen"
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
"Dein Account läuft nicht ab"
|
||||||
|
),
|
||||||
|
description: "Dein Account-Ablaufdatum wird genutzt, um zu bestimmen, ob dein Account noch aktiv ist."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconUsers,
|
||||||
|
title: "Gruppen",
|
||||||
|
data: user?.expand?.memberOf.map((group: LdapGroupModel) => group.cn).join(", ") || "Keine Gruppen",
|
||||||
|
description: "Dein Account-Ablaufdatum wird genutzt, um zu bestimmen, ob dein Account noch aktiv ist."
|
||||||
|
},
|
||||||
|
|
||||||
|
].map((feature, index) => (
|
||||||
|
<DataItem key={index} {...feature}/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</SimpleGrid>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
import {FC, ReactNode} from "react";
|
||||||
|
import {Code, rem, Text, ThemeIcon} from "@mantine/core";
|
||||||
|
|
||||||
|
interface FeatureProps {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
icon: FC<any>;
|
||||||
|
data: ReactNode;
|
||||||
|
title: ReactNode;
|
||||||
|
description: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DataItem({icon: Icon, data, title, description}: FeatureProps) {
|
||||||
|
return (
|
||||||
|
<div className={"paper"}>
|
||||||
|
<ThemeIcon variant="light" size={40} radius={40}>
|
||||||
|
<Icon style={{width: rem(18), height: rem(18)}} stroke={1.5}/>
|
||||||
|
</ThemeIcon>
|
||||||
|
<Text mt="sm" mb={7}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
<Text mt="sm" mb={7}>
|
||||||
|
<Code>
|
||||||
|
{data}
|
||||||
|
</Code>
|
||||||
|
</Text>
|
||||||
|
<Text size="sm" c="dimmed" lh={1.6}>
|
||||||
|
{description}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,81 +1,11 @@
|
||||||
import {Alert, Anchor, Center, Code, rem, SimpleGrid, Text, ThemeIcon, Title} from "@mantine/core";
|
import {Anchor, Center, Title} from "@mantine/core";
|
||||||
import {usePB} from "@/lib/pocketbase.tsx";
|
import {Link} from "react-router-dom";
|
||||||
import {FC, ReactNode} from "react";
|
import CollectedAnalyticsData from "@/pages/util/whatWeKnowAboutYou/CollectedAnalyticsData.tsx";
|
||||||
import {
|
import CollectedUserData from "@/pages/util/whatWeKnowAboutYou/CollectedUserData.tsx";
|
||||||
IconBug,
|
|
||||||
IconCalendarClock,
|
|
||||||
IconGlobe,
|
|
||||||
IconId,
|
|
||||||
IconPassword,
|
|
||||||
IconSignature,
|
|
||||||
IconSlash,
|
|
||||||
IconUser,
|
|
||||||
IconUsers,
|
|
||||||
IconWorldWww
|
|
||||||
} from "@tabler/icons-react";
|
|
||||||
import {useCookies} from "react-cookie";
|
|
||||||
import {ANALYTICS_COOKIE_NAME, ANALYTICS_IP_API} from "../../../../config.ts";
|
|
||||||
import {Link, useLocation} from "react-router-dom";
|
|
||||||
import {ofetch} from "ofetch";
|
|
||||||
import {AnalyticsIpApiResult} from "@/models/AnalyticsTypes.ts";
|
|
||||||
import {useQuery} from "@tanstack/react-query";
|
|
||||||
import {UAParser} from "ua-parser-js";
|
|
||||||
import {
|
|
||||||
BrowserIcon,
|
|
||||||
DeviceTypeIcon,
|
|
||||||
OsIcon
|
|
||||||
} from "@/pages/admin/AnalyticsDashboard/AnalyticsSessions/AnalyticsSessionRow.tsx";
|
|
||||||
import {usePreferredLanguage} from "@uidotdev/usehooks";
|
|
||||||
import {getUserName} from "@/components/users/modals/util.tsx";
|
|
||||||
import {LdapGroupModel} from "@/models/AuthTypes.ts";
|
|
||||||
|
|
||||||
interface FeatureProps {
|
|
||||||
icon: FC<any>;
|
|
||||||
data: ReactNode;
|
|
||||||
title: ReactNode;
|
|
||||||
description: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
function DataItem({icon: Icon, data, title, description}: FeatureProps) {
|
|
||||||
return (
|
|
||||||
<div className={"paper"}>
|
|
||||||
<ThemeIcon variant="light" size={40} radius={40}>
|
|
||||||
<Icon style={{width: rem(18), height: rem(18)}} stroke={1.5}/>
|
|
||||||
</ThemeIcon>
|
|
||||||
<Text mt="sm" mb={7}>
|
|
||||||
{title}
|
|
||||||
</Text>
|
|
||||||
<Text mt="sm" mb={7}>
|
|
||||||
<Code>
|
|
||||||
{data}
|
|
||||||
</Code>
|
|
||||||
</Text>
|
|
||||||
<Text size="sm" c="dimmed" lh={1.6}>
|
|
||||||
{description}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function WhatWeKnowAboutYou() {
|
export default function WhatWeKnowAboutYou() {
|
||||||
|
|
||||||
const {user} = usePB()
|
|
||||||
const location = useLocation()
|
|
||||||
|
|
||||||
const [cookies] = useCookies([ANALYTICS_COOKIE_NAME])
|
|
||||||
const cookieValue = cookies[ANALYTICS_COOKIE_NAME]
|
|
||||||
|
|
||||||
const parserResult = new UAParser().getResult()
|
|
||||||
|
|
||||||
const preferredLanguage = usePreferredLanguage()
|
|
||||||
|
|
||||||
const ipQuery = useQuery({
|
|
||||||
queryKey: ['ip'],
|
|
||||||
queryFn: async () => {
|
|
||||||
return await ofetch<AnalyticsIpApiResult>(ANALYTICS_IP_API, {ignoreResponseError: true})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<div className={"section-transparent stack"}>
|
<div className={"section-transparent stack"}>
|
||||||
<Center mt={"xl"} className={"stack"}>
|
<Center mt={"xl"} className={"stack"}>
|
||||||
|
@ -92,169 +22,8 @@ export default function WhatWeKnowAboutYou() {
|
||||||
</Center>
|
</Center>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={"section-transparent stack"}>
|
<CollectedAnalyticsData/>
|
||||||
|
|
||||||
<Center mt={"xl"}>
|
<CollectedUserData/>
|
||||||
<Title order={2}>Anonyme Analysedaten</Title>
|
|
||||||
</Center>
|
|
||||||
|
|
||||||
<Center>
|
|
||||||
<Text ta={"center"} c={"dimmed"}>
|
|
||||||
|
|
||||||
Alle Analysedaten, die wir sammeln, sind anonymisiert und dienen dazu, diesen Dienst zu verbessern
|
|
||||||
und zu personalisieren.
|
|
||||||
<br/>
|
|
||||||
Wir geben keine Daten an Dritte weiter. Die Daten liegen auf unseren eigenen Servern in Deutschland.
|
|
||||||
<br/>
|
|
||||||
Nur Systemadministratoren haben Zugriff auf die Daten. Wir sammeln diese Daten erst, nachdem Cookies
|
|
||||||
akzeptiert wurden.
|
|
||||||
</Text>
|
|
||||||
</Center>
|
|
||||||
|
|
||||||
{!cookieValue && (
|
|
||||||
<Alert ta={"center"} fw={"600"} color={"green"}>
|
|
||||||
Solange du keine Cookies akzeptierst, sammeln wir keine Analysedaten.
|
|
||||||
</Alert>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<SimpleGrid
|
|
||||||
cols={{base: 1, sm: 2, md: 3}}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
[
|
|
||||||
{
|
|
||||||
icon: IconId,
|
|
||||||
title: "Analyse-ID",
|
|
||||||
data: cookieValue || "-",
|
|
||||||
description: "Diese ID wird genutzt, um nachzuvollziehen, wie du über die Zeit verteilt die StuVe IT Tools nutzt."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconSlash,
|
|
||||||
title: "Aktuelle Seite",
|
|
||||||
data: location.pathname,
|
|
||||||
description: "Der Pfad der aktuellen Seite, die du besuchst. Wir speichern diese Pfade um zu analysieren, welche Seiten am häufigsten besucht werden und wie Nutzende navigieren."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconBug,
|
|
||||||
title: "Fehler",
|
|
||||||
data: "-",
|
|
||||||
description: "Falls ein Fehler auftritt speichern wir die Fehlermeldung und den Zeitpunkt und dem entsprechenden Pfad, um die Stabilität der Seite zu verbessern."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconWorldWww,
|
|
||||||
title: "IP Adresse",
|
|
||||||
data: ipQuery.data?.ip || "-",
|
|
||||||
description: "Deine IP Adresse wird genutzt, um das Land zu bestimmen, aus dem du die Seite besuchst."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconGlobe,
|
|
||||||
title: "Land",
|
|
||||||
data: ipQuery.data?.country_code || "-",
|
|
||||||
description: "Das Land, aus dem du die Seite besuchst. Diese Information wird genutzt, um die Seite zu personalisieren und um zu verstehen, woher die Nutzenden kommen."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: () => <BrowserIcon browser={parserResult.browser.name ?? ""}/>,
|
|
||||||
title: "Browser",
|
|
||||||
data: `${parserResult.browser.name} ${parserResult.browser.version}`,
|
|
||||||
description: "Dein Browser wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: () => <OsIcon os={parserResult.os.name ?? ""}/>,
|
|
||||||
title: "Betriebssystem",
|
|
||||||
data: `${parserResult.os.name} ${parserResult.os.version}`,
|
|
||||||
description: "Dein Betriebssystem wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconWorldWww,
|
|
||||||
title: "Bevorzugte Sprache",
|
|
||||||
data: preferredLanguage || "-",
|
|
||||||
description: "Deine bevorzugte Sprache wird genutzt, um zu verstehen, welche Sprachen Nutzende sprechen."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: () => <DeviceTypeIcon deviceType={parserResult.device.type ?? "desktop"}/>,
|
|
||||||
title: "Gerätetyp",
|
|
||||||
data: parserResult.device.type || "desktop",
|
|
||||||
description: "Dein Gerätetyp wird genutzt, um die Seite anzuzeigen. Diese Information wird genutzt, um die Seite zu optimieren und um zu verstehen, welche Technologien Nutzende verwenden."
|
|
||||||
}
|
|
||||||
|
|
||||||
].map((feature, index) => (
|
|
||||||
<DataItem key={index} {...feature}/>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</SimpleGrid>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{
|
|
||||||
user &&
|
|
||||||
<div className={"section-transparent stack"}>
|
|
||||||
|
|
||||||
<Center mt={"xl"}>
|
|
||||||
<Title order={2}>Accountdaten</Title>
|
|
||||||
</Center>
|
|
||||||
|
|
||||||
<Center>
|
|
||||||
<Text ta={"center"} c={"dimmed"}>
|
|
||||||
Wenn du einen Account hast speichern wir zusätzlich zu den anonymen Analysedaten auch deine
|
|
||||||
Accountdaten.
|
|
||||||
</Text>
|
|
||||||
</Center>
|
|
||||||
|
|
||||||
<SimpleGrid
|
|
||||||
cols={{base: 1, sm: 2, md: 3}}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
[
|
|
||||||
{
|
|
||||||
icon: IconUser,
|
|
||||||
title: "Anmeldename und Realm",
|
|
||||||
data: `${user.username} (${user.REALM})`,
|
|
||||||
description: "Hiermit kannst du dich anmelden und deine Daten verwalten. Deine Realm wird genutzt, um zu bestimmen ob du einen StuVe-IT oder Gast-Account hast."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconPassword,
|
|
||||||
title: "Passwort",
|
|
||||||
data: '***********',
|
|
||||||
description: "Dein Passwort wird verschlüsselt auf unseren Servern gespeichert und kann nicht eingesehen werden."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconGlobe,
|
|
||||||
title: "E-Mail",
|
|
||||||
data: user.email,
|
|
||||||
description: "Deine E-Mail Adresse wird genutzt, um dich zu kontaktieren. Andere Nutzende können deine E-Mail Adresse nicht sehen."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconSignature,
|
|
||||||
title: "Name",
|
|
||||||
data: getUserName(user),
|
|
||||||
description: "Dein Name wird genutzt, um dich zu identifizieren. Andere Nutzende können deinen Namen sehen."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconCalendarClock,
|
|
||||||
title: "Account Ablaufdatum",
|
|
||||||
data: user?.accountExpires ? (
|
|
||||||
new Date(user?.accountExpires).getTime() > Date.now() ? (
|
|
||||||
"Account ist aktiv und läuft am " + new Date(user?.accountExpires).toLocaleDateString() + " ab"
|
|
||||||
) : (
|
|
||||||
"Account ist abgelaufen"
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
"Dein Account läuft nicht ab"
|
|
||||||
),
|
|
||||||
description: "Dein Account-Ablaufdatum wird genutzt, um zu bestimmen, ob dein Account noch aktiv ist."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: IconUsers,
|
|
||||||
title: "Gruppen",
|
|
||||||
data: user?.expand?.memberOf.map((group: LdapGroupModel) => group.cn).join(", ") || "Keine Gruppen",
|
|
||||||
description: "Dein Account-Ablaufdatum wird genutzt, um zu bestimmen, ob dein Account noch aktiv ist."
|
|
||||||
},
|
|
||||||
|
|
||||||
].map((feature, index) => (
|
|
||||||
<DataItem key={index} {...feature}/>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</SimpleGrid>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
Loading…
Reference in New Issue