From 36ad38f670efd232a73d17cb96691d4d474c6974 Mon Sep 17 00:00:00 2001 From: Stephen Adamson Date: Fri, 5 Jun 2026 12:13:07 +0100 Subject: [PATCH] feat(frontend): add /gdpr page with PDF export and JSON download New /gdpr route: skeleton loading state, 2s polling for async export, styled report cards/tables matching /schedule and /account styling. 16 data sections with conditional rendering (empty sections hidden). VAT breakdowns hidden until any payment has non-zero VAT. Deposits Required hidden when 0. PDF export via window.print() with print CSS hiding navbar and verification banner. Raw JSON download button. Export My Data button added to Account page under Change Password. Vite worker format set to 'es' for WASM encoder compatibility. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- frontend/src/routes/+layout.svelte | 14 + frontend/src/routes/account/+page.svelte | 18 + frontend/src/routes/gdpr/+page.svelte | 1014 ++++++++++++++++++++++ frontend/vite.config.ts | 3 + 4 files changed, 1049 insertions(+) create mode 100644 frontend/src/routes/gdpr/+page.svelte diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 5976dd8..a4f0511 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -68,3 +68,17 @@ {/if} {@render children?.()} + + diff --git a/frontend/src/routes/account/+page.svelte b/frontend/src/routes/account/+page.svelte index 0827b08..c57ee18 100644 --- a/frontend/src/routes/account/+page.svelte +++ b/frontend/src/routes/account/+page.svelte @@ -1550,6 +1550,24 @@ + +
+

Data Privacy

+

+ View and export all personal data we hold about you +

+ +
+ + + {#if authStore.currentUser?.role !== 'admin'}
diff --git a/frontend/src/routes/gdpr/+page.svelte b/frontend/src/routes/gdpr/+page.svelte new file mode 100644 index 0000000..4cda041 --- /dev/null +++ b/frontend/src/routes/gdpr/+page.svelte @@ -0,0 +1,1014 @@ + + + + Your Personal Data — Crussell + + +
+ {#if pageState === 'loading' || pageState === 'generating'} +

Your Personal Data Report

+
+
+ Loading… +
+

Generating report…

+
+
+ {#each [1, 2, 3] as _i (_i)} +
+ +
+ + + +
+
+ {/each} +
+ {:else if pageState === 'error'} +
+

Something went wrong

+

{errorMessage}

+
+ + +
+
+ {:else if pageState === 'loaded' && gdprData} + + {/if} +
+ + diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 37bb642..9fb2c09 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -7,5 +7,8 @@ export default defineConfig({ assetsInclude: ['**/*.wasm'], optimizeDeps: { exclude: ['@discourse/jxl', '@jsquash/avif', '@jsquash/webp', '@jsquash/jpeg'] + }, + worker: { + format: 'es' } });