Add integritetspolicy page with Phase 0 privacy copy.

- Create PrivacyPolicyPage with sections on data, rights, and letter recipients
- Use plain Swedish without technical jargon or operational detail
- Link to kontakt page and mailto for privacy questions
- Add PrivacyPolicyPage unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Joakim Mörling 2026-05-22 13:51:20 +02:00
parent bce2447238
commit 258f6f5a17
2 changed files with 293 additions and 0 deletions

View file

@ -0,0 +1,54 @@
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import { createRouter, createMemoryHistory } from 'vue-router'
import PrivacyPolicyPage from '@/pages/PrivacyPolicyPage.vue'
function createTestRouter() {
return createRouter({
history: createMemoryHistory(),
routes: [
{
path: '/integritetspolicy',
name: 'privacy',
component: PrivacyPolicyPage,
},
{
path: '/kontakt',
name: 'contact',
component: { template: '<div>Kontakt</div>' },
},
],
})
}
describe('PrivacyPolicyPage', () => {
it('renders title and lead', () => {
const router = createTestRouter()
const wrapper = mount(PrivacyPolicyPage, {
global: { plugins: [router] },
})
expect(wrapper.text()).toContain('Integritetspolicy')
expect(wrapper.text()).toContain('personuppgifter')
})
it('describes sender and recipient data handling', () => {
const router = createTestRouter()
const wrapper = mount(PrivacyPolicyPage, {
global: { plugins: [router] },
})
expect(wrapper.text()).toContain('Mottagarens postadress')
expect(wrapper.text()).toContain('sparas inte efter utskick')
expect(wrapper.text()).toContain('varken vi eller obehöriga')
})
it('links to contact email and contact page', () => {
const router = createTestRouter()
const wrapper = mount(PrivacyPolicyPage, {
global: { plugins: [router] },
})
expect(wrapper.find('a[href="mailto:kontakt@bilhej.se"]').exists()).toBe(
true,
)
expect(wrapper.find('a.policy__link').attributes('href')).toBe('/kontakt')
})
})

View file

@ -0,0 +1,239 @@
<script setup lang="ts">
import { RouterLink } from 'vue-router'
const sections = [
{
id: 'ansvarig',
title: 'Personuppgiftsansvarig',
paragraphs: [
'Bilhej (bilhej.se) är personuppgiftsansvarig för den behandling som sker när du använder tjänsten som avsändare.',
'Frågor om integritet: kontakt@bilhej.se. Klagomål som rör tjänsten: klagomal@bilhej.se.',
],
},
{
id: 'vilka-uppgifter',
title: 'Vilka uppgifter behandlar vi?',
paragraphs: [
'Kontouppgifter: e-postadress och lösenord. Lösenordet lagras så att varken vi eller obehöriga kan läsa det.',
'Beställningar: registreringsnummer, brevtext, status, betalningsbelopp och eventuellt spårningsnummer kopplat till utskick.',
'Fordonsuppgifter: märke och modell för att du ska kunna verifiera nummerplåten. Vi lagrar inte mottagarens namn eller adress i tjänsten.',
'Mottagarens postadress används enbart för att posta brevet och sparas inte efter utskick.',
],
},
{
id: 'varfor',
title: 'Varför behandlar vi uppgifterna?',
paragraphs: [
'För att tillhandahålla tjänsten: konto, beställning, betalning och utskick av brev.',
'För att uppfylla rättsliga skyldigheter, till exempel bokföring av betalningar där så krävs.',
'För att skicka nödvändiga meddelanden till dig, till exempel återställning av lösenord.',
'Mottagaren informeras i brevets fot om att brevet skickats via Bilhej och hur hen kan kontakta oss.',
],
},
{
id: 'delning',
title: 'Vem delar vi uppgifter med?',
paragraphs: [
'Leverantörer som hjälper oss att skicka e-post, ta emot supportmail och driva webbplatsen.',
'Behörig myndighet och postoperatör i den utsträckning som krävs för att posta brevet till rätt mottagare.',
'Offentliga fordonsregister när du verifierar registreringsnummer (endast fordonsdata, inte ägaruppgifter).',
'Vi säljer inte personuppgifter och visar inte mottagarens identitet eller adress för dig som avsändare.',
],
},
{
id: 'lagring',
title: 'Hur länge sparar vi uppgifterna?',
paragraphs: [
'Kontouppgifter sparas tills du ber oss radera kontot.',
'Beställningshistorik (nummerplåt, brevtext, status) sparas så att du kan se Mina beställningar och så att vi kan hantera support.',
'Mottagarens adress sparas inte efter utskick.',
'Lösenordsåterställning gäller under begränsad tid och upphör efter användning.',
],
},
{
id: 'rattigheter',
title: 'Dina rättigheter',
paragraphs: [
'Du kan begära tillgång till, rättelse eller radering av dina uppgifter, begränsa behandling eller invända mot viss behandling.',
'Du kan begära radering av ditt konto genom att kontakta oss.',
'Du har rätt att lämna klagomål till Integritetsskyddsmyndigheten (IMY), imy.se.',
'Kontakta kontakt@bilhej.se för att utöva dina rättigheter. Vi svarar inom en månad om inte något annat anges.',
],
},
{
id: 'mottagare',
title: 'Om du fått ett brev via Bilhej',
paragraphs: [
'Din adress användes en gång för att posta brevet och ska ha raderats hos oss efter utskick.',
'För frågor eller invändning mot att få brev via tjänsten: kontakt@bilhej.se. Ange registreringsnummer om du kan.',
],
},
{
id: 'andringar',
title: 'Ändringar',
paragraphs: [
'Vi kan uppdatera denna policy när tjänsten utvecklas. Datum för senaste version anges nedan.',
],
},
]
</script>
<template>
<div class="policy">
<section class="policy__hero">
<p class="policy__eyebrow">Integritet</p>
<h1 class="policy__title">Integritetspolicy</h1>
<p class="policy__lead">
Här beskriver vi hur Bilhej behandlar personuppgifter när du skickar brev
via tjänsten, och vilka rättigheter du har.
</p>
<p class="policy__updated">Senast uppdaterad: 22 maj 2026</p>
</section>
<section
v-for="section in sections"
:key="section.id"
:id="section.id"
class="policy__section"
>
<h2 class="policy__section-title">{{ section.title }}</h2>
<div class="policy__prose">
<p v-for="(paragraph, index) in section.paragraphs" :key="index">
{{ paragraph }}
</p>
</div>
</section>
<section class="policy__section policy__section--cta">
<div class="policy__cta-box">
<h2 class="policy__cta-title">Frågor om integritet?</h2>
<p class="policy__cta-text">
Hör av dig via
<a class="policy__mailto" href="mailto:kontakt@bilhej.se"
>kontakt@bilhej.se</a
>
eller vår
<RouterLink to="/kontakt" class="policy__link">kontaktsida</RouterLink>.
</p>
</div>
</section>
</div>
</template>
<style scoped>
.policy {
max-width: 48rem;
margin: 0 auto;
padding: var(--space-3xl) var(--space-lg) var(--space-3xl);
}
.policy__hero {
margin-bottom: var(--space-2xl);
padding: var(--space-2xl);
background: linear-gradient(
145deg,
var(--color-surface) 0%,
#f8faff 55%,
var(--color-paper) 100%
);
border: 1px solid var(--color-border);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-lg);
}
.policy__eyebrow {
display: inline-block;
margin: 0 0 var(--space-md) 0;
font-size: 0.8125rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--color-primary-dark);
background: var(--color-primary-soft);
border: 1px solid #bfdbfe;
padding: 0.35rem 0.75rem;
border-radius: var(--radius-full);
}
.policy__title {
margin: 0 0 var(--space-md) 0;
font-size: clamp(1.75rem, 4vw, 2.25rem);
font-weight: 800;
letter-spacing: -0.02em;
color: var(--color-ink);
}
.policy__lead {
margin: 0 0 var(--space-md) 0;
font-size: 1.0625rem;
line-height: 1.75;
color: var(--color-muted);
}
.policy__updated {
margin: 0;
font-size: 0.8125rem;
color: var(--color-soft);
}
.policy__section {
margin-bottom: var(--space-2xl);
scroll-margin-top: var(--space-lg);
}
.policy__section-title {
margin: 0 0 var(--space-md) 0;
font-size: 1.25rem;
font-weight: 700;
color: var(--color-ink);
}
.policy__prose p {
margin: 0 0 var(--space-md) 0;
font-size: 0.9375rem;
line-height: 1.75;
color: var(--color-muted);
}
.policy__prose p:last-child {
margin-bottom: 0;
}
.policy__cta-box {
padding: var(--space-xl);
text-align: center;
background: linear-gradient(
135deg,
var(--color-primary-soft) 0%,
#eef2ff 100%
);
border: 1px solid #bfdbfe;
border-radius: var(--radius-xl);
}
.policy__cta-title {
margin: 0 0 var(--space-sm) 0;
font-size: 1.25rem;
color: var(--color-primary-dark);
}
.policy__cta-text {
margin: 0;
font-size: 0.9375rem;
line-height: 1.65;
color: var(--color-primary-dark);
}
.policy__mailto,
.policy__link {
font-weight: 600;
color: var(--color-primary);
text-decoration: underline;
text-underline-offset: 2px;
}
.policy__mailto:hover,
.policy__link:hover {
color: var(--color-primary-dark);
}
</style>