Skip to content

Commit cca4043

Browse files
committed
gdpr stuff and finalizations
1 parent b0fbef3 commit cca4043

File tree

10 files changed

+354
-58
lines changed

10 files changed

+354
-58
lines changed

packages/client/src/api/hooks/authHooks.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ export const useUserDataQuery = (enabled: boolean) =>
1010

1111
export const useValidateUserRolesMutation = () =>
1212
useMutation<AuthToken, PontozoError>(async () => (await functionAxios.get<AuthToken>('auth/verify')).data)
13+
14+
export const usePurgeUserMutation = () => useMutation<unknown, PontozoError>(async () => (await functionAxios.delete('users')).data)

packages/client/src/api/hooks/emailRecipientHooks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ export const useUpdateEmailPreferencesMutation = () => {
88
)
99
}
1010

11+
export const useOptOutEmailPreferencesMutation = () => {
12+
return useMutation<unknown, PontozoError>(async () => (await functionAxios.patch(`/emails/optOut`)).data)
13+
}
14+
1115
export const useFetchEmailPreferencesMutation = () => {
1216
return useMutation<EmailRecipient, PontozoError>(async () => (await functionAxios.get(`/emails/mine`)).data)
1317
}

packages/client/src/components/Footer.tsx

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,58 @@
1-
import { Box, Container, Flex, HStack, Link, Stack, Text } from '@chakra-ui/react'
1+
import { Box, Container, Flex, HStack, Link, Stack, Text, VStack } from '@chakra-ui/react'
22
import { FC } from 'react'
33
import { FaEnvelope, FaGithub, FaGlobe, FaLinkedin } from 'react-icons/fa'
4-
import { HashLink } from 'react-router-hash-link'
54
import { ColorfulExternalLink } from './commons/ColorfulExternalLink'
5+
import { ColorfulHashLink } from './commons/ColorfulHashLink'
66

77
export const Footer: FC = () => {
88
return (
99
<Box as="footer" borderTop="1px" borderTopColor="gray.300" bg="white">
1010
<Container
1111
py={5}
1212
as={Flex}
13-
alignItems={{ base: 'center', md: 'flex-end' }}
13+
alignItems="center"
1414
justifyContent="space-around"
1515
direction={{ base: 'column', md: 'row' }}
1616
maxW="6xl"
17+
gap={2}
1718
>
18-
<Stack direction={{ base: 'column', md: 'row' }} spacing={2} justify="center" align="center">
19-
<Text textAlign="center">
20-
Készítette:{' '}
21-
<Link href="https://github.com/Tschonti" color="brand.500" isExternal>
22-
Fekete Sámuel
23-
</Link>{' '}
24-
az{' '}
25-
<Link href="https://mtfsz.hu" color="brand.500" isExternal>
26-
MTFSZ
27-
</Link>{' '}
28-
megbízásából.{' '}
29-
<HashLink to="/faq#impressum" style={{ color: '#0a723a' }}>
30-
Impresszum
31-
</HashLink>
32-
</Text>
33-
</Stack>
19+
<VStack spacing={0} justify="center" align="center">
20+
<ColorfulHashLink to="/faq#privacy-notice">Adatkezelési tájékoztató</ColorfulHashLink>
21+
<ColorfulHashLink to="/faq#cookie-notice">Süti tájékoztató</ColorfulHashLink>
22+
<ColorfulHashLink to="/faq#impressum">Impresszum</ColorfulHashLink>
23+
</VStack>
3424

35-
<HStack mt={{ base: 2, md: 0 }} spacing={2} justify="space-evenly">
36-
<Text textAlign="center">&copy; {new Date().getFullYear()}</Text>
37-
<ColorfulExternalLink url="https://github.com/Tschonti/pontozo" hoverColor="brand.500">
38-
<FaGithub size={25} />
39-
</ColorfulExternalLink>
40-
<ColorfulExternalLink url="https://github.com/Tschonti" hoverColor="brand.500">
41-
<FaGlobe size={25} />
42-
</ColorfulExternalLink>
43-
<ColorfulExternalLink url="mailto:feketesamu@gmail.com" hoverColor="brand.500">
44-
<FaEnvelope size={25} />
45-
</ColorfulExternalLink>
46-
<ColorfulExternalLink url="https://www.linkedin.com/in/samuel-fekete/" hoverColor="brand.500">
47-
<FaLinkedin size={25} />
48-
</ColorfulExternalLink>
49-
</HStack>
25+
<VStack spacing={0}>
26+
<Stack direction={{ base: 'column', md: 'row' }} spacing={0} justify="center" align="center">
27+
<Text textAlign="center">
28+
Készítette:{' '}
29+
<Link href="https://github.com/Tschonti" color="brand.500" isExternal>
30+
Fekete Sámuel
31+
</Link>{' '}
32+
az{' '}
33+
<Link href="https://mtfsz.hu" color="brand.500" isExternal>
34+
MTFSZ
35+
</Link>{' '}
36+
megbízásából.
37+
</Text>
38+
</Stack>
39+
<Text textAlign="center">&copy; 2023-{new Date().getFullYear()}</Text>
40+
41+
<HStack mt={2} spacing={2} justify="space-evenly">
42+
<ColorfulExternalLink url="https://github.com/Tschonti/pontozo" hoverColor="brand.500">
43+
<FaGithub size={25} />
44+
</ColorfulExternalLink>
45+
<ColorfulExternalLink url="https://github.com/Tschonti" hoverColor="brand.500">
46+
<FaGlobe size={25} />
47+
</ColorfulExternalLink>
48+
<ColorfulExternalLink url="mailto:feketesamu@gmail.com" hoverColor="brand.500">
49+
<FaEnvelope size={25} />
50+
</ColorfulExternalLink>
51+
<ColorfulExternalLink url="https://www.linkedin.com/in/samuel-fekete/" hoverColor="brand.500">
52+
<FaLinkedin size={25} />
53+
</ColorfulExternalLink>
54+
</HStack>
55+
</VStack>
5056
</Container>
5157
</Box>
5258
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { ReactNode, useState } from 'react'
2+
import { HashLink } from 'react-router-hash-link'
3+
4+
type Props = {
5+
to: string
6+
children: ReactNode
7+
}
8+
9+
export const ColorfulHashLink = ({ children, to }: Props) => {
10+
const [hovered, setHovered] = useState(false)
11+
return (
12+
<HashLink
13+
to={to}
14+
style={{ color: '#0a723a', textDecoration: hovered ? 'underline' : 'none' }}
15+
onMouseEnter={() => setHovered(true)}
16+
onMouseLeave={() => setHovered(false)}
17+
>
18+
{children}
19+
</HashLink>
20+
)
21+
}

packages/client/src/pages/faq/FAQ.page.tsx

Lines changed: 148 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,30 @@ import {
44
AccordionIcon,
55
AccordionItem,
66
AccordionPanel,
7+
AlertDialog,
8+
AlertDialogBody,
9+
AlertDialogContent,
10+
AlertDialogFooter,
11+
AlertDialogHeader,
12+
AlertDialogOverlay,
713
Box,
814
Button,
915
Heading,
1016
HStack,
1117
Image,
1218
Link,
1319
Text,
20+
useDisclosure,
21+
useToast,
1422
VStack,
1523
} from '@chakra-ui/react'
24+
import { useRef } from 'react'
1625
import { Helmet } from 'react-helmet'
17-
import { FaEnvelope, FaGithub, FaLinkedin } from 'react-icons/fa'
26+
import { FaEnvelope, FaExclamationTriangle, FaGithub, FaLinkedin } from 'react-icons/fa'
27+
import { useAuthContext } from 'src/api/contexts/useAuthContext'
28+
import { usePurgeUserMutation } from 'src/api/hooks/authHooks'
1829
import { ColorfulExternalLink } from 'src/components/commons/ColorfulExternalLink'
30+
import { PATHS } from 'src/util/paths'
1931

2032
const faqItems: { title: string; paragraphs: string[] }[] = [
2133
{
@@ -47,23 +59,53 @@ const faqItems: { title: string; paragraphs: string[] }[] = [
4759
Amennyiben senki sem értékelte a versenyt, nem fog megjelenni a listában.`,
4860
],
4961
},
62+
{
63+
title: 'Meg mernék esküdni, hogy az egyik verseny pontszáma korábban még más volt. Hogy lehetséges ez?',
64+
paragraphs: [
65+
`Habár próbáljuk elkerülni, időnként (főleg a kezdeti időszakban) előfordulhat, hogy szezon közben változtatunk a szempontok súlyain,
66+
majd újraszámoljuk a versenyek eredményeit. Egy verseny eredmény oldalán mindig látod, hogy mikor lett kiszámolva a jelenlegi ponszám.
67+
Azt azonban garantáljuk, hogy azonos szezonban lévő versenyek mindigy ugyanazon szempontok és súlyok alapján lettek kiértékelve.`,
68+
],
69+
},
5070
{
5171
title: 'Valóban anonim az értékelésem?',
5272
paragraphs: [
5373
`A rendszer felhasználókhoz kapcsol minden értékelést, ez elengedhetetlen ahhoz, hogy később szerkeszd vagy megtekintsd a saját értékelésed.
5474
Az értékelések publikus eredményei azonban csak az összesített értékeléseket tartalmazzák, azok soha nem vezethetőek vissza egy adott személyre.
5575
Az adatbázisban tárolt, felhasználókhoz köthető értékelési adatokat harmadik féllel (például versenyrendezői csapattal) soha nem osztjuk meg.
56-
Ez igaz a szempontokra leadott és a szöveges értékelésekre is. Fenntartjuk a jogát, hogy amennyiben egy szöveges értékelést nem tartunk konstruktívank, töröljük azt.`,
76+
Ez igaz a szempontokra leadott és a szöveges értékelésekre is. Fenntartjuk a jogát, hogy amennyiben egy szöveges értékelést nem tartunk konstruktívnak, töröljük azt.`,
5777
],
5878
},
5979
]
6080

6181
export const FAQPage = () => {
82+
const { isLoggedIn, onLogout } = useAuthContext()
83+
const { isLoading, mutateAsync } = usePurgeUserMutation()
84+
const { isOpen, onOpen, onClose } = useDisclosure()
85+
const cancelRef = useRef(null)
86+
const toast = useToast()
87+
88+
const onPurge = async () => {
89+
try {
90+
await mutateAsync()
91+
toast({ title: 'Az adataidat sikeresen töröltük.', status: 'success' })
92+
onClose()
93+
onLogout(PATHS.FAQ)
94+
} catch (e) {
95+
console.error(e)
96+
toast({ title: 'A fiókod törlése nem sikerült', status: 'error' })
97+
}
98+
}
6299
return (
63100
<VStack gap={4} alignItems="flex-start">
64101
<Helmet title="Pontoz-O | GYIK" />
65102
<Heading>Gyakran Ismételt Kérdések</Heading>
66-
<Accordion w="100%" bg="white" defaultIndex={[...faqItems.map((_, i) => i), faqItems.length]} allowMultiple>
103+
<Accordion
104+
w="100%"
105+
bg="white"
106+
defaultIndex={[...faqItems.map((_, i) => i), faqItems.length, faqItems.length + 1, faqItems.length + 2]}
107+
allowMultiple
108+
>
67109
{faqItems.map((q) => (
68110
<AccordionItem key={q.title}>
69111
<h2>
@@ -97,7 +139,7 @@ export const FAQPage = () => {
97139
<AccordionPanel pb={4} justifyItems="center">
98140
<VStack justifyItems="center">
99141
<Image width={250} height={250} src="/img/samu.jpg" rounded="100%" />
100-
<Heading fontSize={50} transform="auto" skewX={-10} style={{ fontVariant: 'small-caps' }}>
142+
<Heading textAlign="center" fontSize={50} transform="auto" skewX={-10} style={{ fontVariant: 'small-caps' }}>
101143
Fekete Sámuel
102144
</Heading>
103145
<HStack>
@@ -164,6 +206,108 @@ export const FAQPage = () => {
164206
</VStack>
165207
</AccordionPanel>
166208
</AccordionItem>
209+
<AccordionItem>
210+
<h2 id="privacy-notice">
211+
<AccordionButton>
212+
<Box fontWeight="bold" as="span" flex="1" textAlign="left">
213+
Hogyan kezeli az alkalmazás az adataimat?
214+
</Box>
215+
<AccordionIcon />
216+
</AccordionButton>
217+
</h2>
218+
<AccordionPanel pb={4} justifyItems="center">
219+
<VStack alignItems="flex-start">
220+
<Text textAlign="justify">
221+
A rendszer elsődleges adatforrása az MTFSZ adatbázisa. Bejelentkezéskor innen kérjük le a felhasználó adatait, azonban azok
222+
közül kizárólag az e-mail címet, az MTFSZ személy azonosítót és a születési dátumot tároljuk. Az e-mail címet kizárólag
223+
rendszerértesítések küldése érdekében tároljuk. Amennyiben semmiképpen nem szeretnél e-mailben értesítést kapni, a
224+
profilodon található Értesítési beállítások menüben törölheted az e-mail címed.
225+
</Text>
226+
227+
<Text textAlign="justify">
228+
Az adatokat a Microsoft Azure Poland Central nevű régiójában (adatközpontjában) tároljuk, harmadik félnek soha nem adjuk ki.
229+
Amennyiben szeretnéd az összes, hozzád kapcsolható adatot törölni a rendszerből, nyomd meg az alábbi gombot. Ezzel az e-mail
230+
címed és az általad leadott értékelések törlésre kerülnek, valamint ki leszel jelentkeztetve. Ha újra bejelentkezel, ismét
231+
használhatod az alkalmazást, azonban a korábban törölt értékeléseid nem visszaállíthatóak. Az általad értékelt versenyek
232+
értékelési eredményeit nem befolyásolja az értékeléseid törlése, hiszen azok az értékelés lezárultakor számolódnak ki és nem
233+
tartalmaznak személyre visszavezethető adatot. Ha viszont a későbbiekben egy verseny pontszáma valamilyen okból
234+
újraszámolódik, akkor már a te értékelésed nélkül fog ez megtörténni.
235+
</Text>
236+
<Button
237+
alignSelf="center"
238+
onClick={onOpen}
239+
isDisabled={!isLoggedIn}
240+
color="white"
241+
bg="black"
242+
_hover={{ bg: 'gray.700' }}
243+
leftIcon={<FaExclamationTriangle />}
244+
aria-label="Fiókom és adataim törlése"
245+
>
246+
Fiókom és adataim törlése
247+
</Button>
248+
<AlertDialog isOpen={isOpen} leastDestructiveRef={cancelRef} onClose={onClose}>
249+
<AlertDialogOverlay>
250+
<AlertDialogContent>
251+
<AlertDialogHeader fontSize="lg" fontWeight="bold">
252+
Fiókom és adataim törlése
253+
</AlertDialogHeader>
254+
255+
<AlertDialogBody textAlign="justify">
256+
Biztos vagy benne? Ezzel az e-mail címed és az általad leadott értékelések törlésre kerülnek, valamint ki leszel
257+
jelentkeztetve. Ha újra bejelentkezel, ismét használhatod az alkalmazást, azonban a korábban törölt értékeléseid nem
258+
visszaállíthatóak. Az általad értékelt versenyek értékelési eredményeit nem befolyásolja az értékeléseid törlése,
259+
hiszen azok az értékelés lezárultakor számolódnak ki és nem tartalmaznak személyre visszavezethető adatot. Ha viszont
260+
a későbbiekben egy verseny pontszáma valamilyen okból újraszámolódik, akkor már a te értékelésed nélkül fog ez
261+
megtörténni.
262+
</AlertDialogBody>
263+
264+
<AlertDialogFooter>
265+
<Button ref={cancelRef} onClick={onClose}>
266+
Mégse
267+
</Button>
268+
<Button
269+
colorScheme="red"
270+
onClick={onPurge}
271+
ml={3}
272+
color="white"
273+
bg="black"
274+
isLoading={isLoading}
275+
_hover={{ bg: 'gray.700' }}
276+
leftIcon={<FaExclamationTriangle />}
277+
>
278+
Törlés
279+
</Button>
280+
</AlertDialogFooter>
281+
</AlertDialogContent>
282+
</AlertDialogOverlay>
283+
</AlertDialog>
284+
</VStack>
285+
</AccordionPanel>
286+
</AccordionItem>
287+
<AccordionItem>
288+
<h2 id="cookie-notice">
289+
<AccordionButton>
290+
<Box fontWeight="bold" as="span" flex="1" textAlign="left">
291+
Használ sütiket az alkalmazás?
292+
</Box>
293+
<AccordionIcon />
294+
</AccordionButton>
295+
</h2>
296+
<AccordionPanel pb={4} justifyItems="center">
297+
<VStack alignItems="flex-start">
298+
<Text textAlign="justify">
299+
Az alkalmazás elsősorban a működéshez elegendhetetlen sütiket használ. Sütiben tároljuk a téged azonosító tokent, mely
300+
kijelentkezéskor vagy 7 nap után törlődik a böngésződből.
301+
</Text>
302+
303+
<Text textAlign="justify">
304+
Ezen kívül az oldal forgalmát a Microsoft Azure Application Insights rendszere méri, mely szintén használ sütiket a
305+
felhasználók azonosításához. Időnként az IP-cím is küldésre kerül, azonban ezt soha nem tárolja, csak az egyes kérésekhez ez
306+
alapján tud geolokációs információt (ország, régió, város) rendelni.
307+
</Text>
308+
</VStack>
309+
</AccordionPanel>
310+
</AccordionItem>
167311
</Accordion>
168312
</VStack>
169313
)

0 commit comments

Comments
 (0)