Skip to content

Commit 8495d21

Browse files
feat(legal): add terms and privacy pages
1 parent 018f535 commit 8495d21

3 files changed

Lines changed: 441 additions & 0 deletions

File tree

src/pages/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const Home = () => (
4141
<meta name="photo-attribution" content="Photo by --todo (--url todo)" />
4242
<script
4343
type="application/ld+json"
44+
// biome-ignore lint/security/noDangerouslySetInnerHtml: JSON-LD is generated from static event metadata.
4445
dangerouslySetInnerHTML={{
4546
__html: JSON.stringify({
4647
"@context": "https://schema.org",

src/pages/privacy-policy.tsx

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
import Head from "next/head";
2+
import { Box, Container, Heading, Paragraph } from "theme-ui";
3+
4+
import { genericInformation } from "~/data/generic";
5+
6+
const CONTACT_EMAIL = "warsawpythonpizza@gmail.com";
7+
const DATA_CONTROLLER =
8+
"Piotr Grędowski, Dorota Ostrowska, and Natalia Traczewska, organizers of Warsaw Python Pizza";
9+
const TICKET_SELLER = "EuroPython Society";
10+
11+
const thirdPartyServices = [
12+
{
13+
name: "Gmail",
14+
description:
15+
"The Warsaw Python Pizza Team may rely on Gmail for direct and group emails to communicate internally and externally. If you email us, your information may be collected for the purpose of communicating with you about the Event.",
16+
},
17+
{
18+
name: "Google Forms",
19+
description:
20+
"We may use Google Forms for announcements, call for proposals, feedback, and similar forms.",
21+
},
22+
{
23+
name: "Google Drive, Docs, and Sheets",
24+
description:
25+
"We may use Google Drive to store documents, spreadsheets, and similar files needed to run the Event. Some of these files may include personal data.",
26+
},
27+
{
28+
name: "YouTube",
29+
description:
30+
"We may stream or publish talk recordings on YouTube after the Event.",
31+
},
32+
{
33+
name: "Pretix",
34+
description:
35+
"We use Pretix for ticketing services. If you buy a ticket, Pretix uses cookies to keep track of your cart and improve the ordering process. Data submitted to Pretix is stored on servers in Germany.",
36+
link: "https://pretix.eu/about/en/privacy",
37+
},
38+
];
39+
40+
const sections = [
41+
{
42+
title: "Handling of personal information",
43+
content: (
44+
<>
45+
<Paragraph>
46+
You authorize {DATA_CONTROLLER} (“Data Controller”) to handle personal
47+
information in connection with Warsaw Python Pizza (“Event”) for the
48+
purposes and for the period of time specified below.
49+
</Paragraph>
50+
<Paragraph>
51+
Tickets are sold by {TICKET_SELLER} through Pretix. Information
52+
submitted during ticket purchase may therefore be processed by{" "}
53+
{TICKET_SELLER} and Pretix as needed to complete ticket sales and
54+
operate admission.
55+
</Paragraph>
56+
<Paragraph>
57+
We process personal information only as needed to organize the Event,
58+
communicate with participants, manage proposals and feedback, sell and
59+
verify tickets, publish the Event programme, and keep participants
60+
safe.
61+
</Paragraph>
62+
<Paragraph>
63+
You can revoke your agreement at any time by sending an email to{" "}
64+
<a href={`mailto:${CONTACT_EMAIL}`}>{CONTACT_EMAIL}</a>.
65+
</Paragraph>
66+
</>
67+
),
68+
},
69+
{
70+
title: "Third-party services",
71+
content: (
72+
<>
73+
<Paragraph>
74+
A few third-party services help us run the website, ticketing, and the
75+
conference. We may share some information with them as part of their
76+
service. We select services that we believe comply with EU data
77+
privacy regulations, but this list might not be exhaustive.
78+
</Paragraph>
79+
<Box sx={{ display: "grid", gap: "secondary", mt: "secondary" }}>
80+
{thirdPartyServices.map((service) => (
81+
<Box
82+
key={service.name}
83+
sx={{
84+
borderLeft: "0.4rem solid",
85+
borderColor: "primary",
86+
pl: "secondary",
87+
}}
88+
>
89+
<Paragraph sx={{ mb: 1 }}>
90+
<strong>{service.name}</strong>
91+
</Paragraph>
92+
<Paragraph sx={{ m: 0 }}>
93+
{service.description}{" "}
94+
{service.link && (
95+
<a
96+
href={service.link}
97+
target="_blank"
98+
rel="noopener noreferrer"
99+
>
100+
Privacy policy
101+
</a>
102+
)}
103+
</Paragraph>
104+
</Box>
105+
))}
106+
</Box>
107+
</>
108+
),
109+
},
110+
{
111+
title: "Processors",
112+
content: (
113+
<>
114+
<Paragraph>
115+
The Data Controller handles personal information. The information may
116+
also be processed by:
117+
</Paragraph>
118+
<ul>
119+
<li>
120+
Google Ireland Ltd, Gordon House, Barrow Street, Dublin 4, Ireland
121+
</li>
122+
<li>YouTube, LLC, 901 Cherry Ave., San Bruno, CA 94066, USA</li>
123+
<li>
124+
pretix GmbH, Berthold-Mogel-Straße 1, 69126 Heidelberg, Germany
125+
</li>
126+
</ul>
127+
</>
128+
),
129+
},
130+
{
131+
title: "Your rights",
132+
content: (
133+
<>
134+
<Paragraph>
135+
Under applicable data protection laws, you have the right to:
136+
</Paragraph>
137+
<ul>
138+
<li>Revoke your agreement at any time.</li>
139+
<li>
140+
Request information about which personal information we process and
141+
why.
142+
</li>
143+
<li>Request access to your personal information.</li>
144+
<li>Ask us to correct or update your personal information.</li>
145+
<li>Ask us to delete your personal information.</li>
146+
<li>
147+
Contact us or the Polish data protection authority if you have
148+
concerns about our handling of your data.
149+
</li>
150+
</ul>
151+
</>
152+
),
153+
},
154+
];
155+
156+
const SectionHeading = ({
157+
children,
158+
index,
159+
}: {
160+
children: React.ReactNode;
161+
index: number;
162+
}) => (
163+
<Heading
164+
as="h2"
165+
sx={{
166+
alignItems: "baseline",
167+
color: "text",
168+
display: "flex",
169+
fontSize: "body",
170+
gap: "secondary",
171+
mb: "secondary",
172+
mt: 0,
173+
}}
174+
>
175+
<Box as="span" sx={{ color: "primary", fontFamily: "heading" }}>
176+
{String(index).padStart(2, "0")}
177+
</Box>
178+
{children}
179+
</Heading>
180+
);
181+
182+
const PrivacyPolicy = () => (
183+
<Container variant="smallContainer" sx={{ textAlign: "left" }}>
184+
<Head>
185+
<title>{`Privacy Policy | ${genericInformation.pageTitle}`}</title>
186+
<meta
187+
name="description"
188+
content="Privacy Policy for Warsaw Python Pizza."
189+
/>
190+
<meta name="robots" content="noindex, nofollow" />
191+
</Head>
192+
193+
<Heading as="h1" variant="heading" sx={{ textAlign: "center" }}>
194+
Privacy Policy
195+
</Heading>
196+
197+
<Box
198+
sx={{
199+
backgroundColor: "primary",
200+
borderRadius: "primary",
201+
color: "white",
202+
mb: "primary",
203+
p: "secondary",
204+
textAlign: "center",
205+
}}
206+
>
207+
<Paragraph sx={{ m: 0 }}>Last updated: 27 April 2026</Paragraph>
208+
<Paragraph sx={{ m: 0 }}>
209+
This policy explains how we handle personal information for Warsaw
210+
Python Pizza.
211+
</Paragraph>
212+
</Box>
213+
214+
{sections.map((section, index) => (
215+
<Box
216+
as="section"
217+
key={section.title}
218+
sx={{
219+
borderTop: "1px solid",
220+
borderColor: "primary",
221+
py: "secondary",
222+
}}
223+
>
224+
<SectionHeading index={index + 1}>{section.title}</SectionHeading>
225+
{section.content}
226+
</Box>
227+
))}
228+
</Container>
229+
);
230+
231+
export default PrivacyPolicy;

0 commit comments

Comments
 (0)