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:
parent
bce2447238
commit
258f6f5a17
2 changed files with 293 additions and 0 deletions
54
frontend/src/__tests__/PrivacyPolicyPage.spec.ts
Normal file
54
frontend/src/__tests__/PrivacyPolicyPage.spec.ts
Normal 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')
|
||||||
|
})
|
||||||
|
})
|
||||||
239
frontend/src/pages/PrivacyPolicyPage.vue
Normal file
239
frontend/src/pages/PrivacyPolicyPage.vue
Normal 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>
|
||||||
Loading…
Reference in a new issue