Skip to content

Commit 784166f

Browse files
authored
feat: add styled error pages, fix type errors, add svelte-check CI (#65)
* feat: add styled error pages, fix all type errors, and add svelte-check to CI Closes #42 * fix: use yarn instead of npm in svelte-check CI job * fix: run svelte-kit sync before svelte-check in CI * docs: fix dev server URL to localhost:8080 in README
1 parent 6be8792 commit 784166f

16 files changed

Lines changed: 153 additions & 12 deletions

File tree

.github/workflows/ci.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ on:
1717

1818
jobs:
1919

20+
# Run svelte-check for type errors and warnings.
21+
svelte-check:
22+
name: Svelte Check
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v6
26+
- uses: actions/setup-node@v6
27+
with:
28+
node-version: 24
29+
cache: yarn
30+
- run: yarn install --frozen-lockfile
31+
- run: yarn svelte-kit sync
32+
- run: yarn svelte-check --threshold warning
33+
2034
# Create a GitHub release (and tag) when conventional commits warrant one.
2135
release-please:
2236
name: Release Please

.mcp.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"mcpServers": {
3+
"svelte": {
4+
"type": "stdio",
5+
"command": "npx",
6+
"args": [
7+
"-y",
8+
"@sveltejs/mcp"
9+
],
10+
"env": {}
11+
}
12+
}
13+
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ docker-compose up
1616
# Connect phone with USB debugging enabled, Yivi app in developer mode, then:
1717
adb reverse tcp:8088 tcp:8088
1818

19-
# Postguard website at http://localhost:5173
19+
# Postguard website at http://localhost:8080
2020
# Mailcrab UI at http://localhost:1080
2121

2222

src/lib/components/Chip.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
disabled = false
1818
}: props = $props()
1919
20-
const isInteractive = onclick !== undefined
20+
let isInteractive = $derived(onclick !== undefined)
2121
</script>
2222

2323
{#if isInteractive}

src/lib/components/fallback/Decrypt.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@
179179
body: JSON.stringify(keyRequest),
180180
},
181181
result: {
182-
url: (o, { sessionToken }) =>
182+
url: (o, /** @type {any} */ { sessionToken }) =>
183183
`${o.url}/v2/request/jwt/${sessionToken}`,
184184
parseResponse: (r) => {
185185
return r

src/lib/components/filesharing/EncryptionProgress.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
abort,
2727
}: props = $props()
2828
29-
const to = recipients.map(({ email }) => email).join(', ')
29+
let to = $derived(recipients.map(({ email }) => email).join(', '))
3030
let timeEstimateRepr = $derived(() => {
3131
const deltaT = Date.now() - encryptStartTime
3232
const totalSize = files

src/lib/components/filesharing/inputs/FileInput.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import { EncryptionState } from '$lib/types/filesharing/attributes'
1010
1111
// Disable auto-discover to prevent Dropzone from automatically attaching to all .dropzone elements
12-
Dropzone.autoDiscover = false
12+
Dropzone.discover = () => []
1313
1414
let myDropzone: Dropzone | null = null
1515
let isDragging = $state(false)

src/lib/locales/en.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,13 @@
194194
"pbdf.gemeente.personalData.dateofbirth.placeholder": "15-01-1990"
195195
}
196196
},
197+
"error": {
198+
"title": "Page not found",
199+
"message": "The page you are looking for does not exist or has been moved.",
200+
"back": "Go to home page",
201+
"serverTitle": "Something went wrong",
202+
"serverMessage": "Our server encountered an unexpected error. Please try again later."
203+
},
197204
"yivi": {
198205
"iosHref": "https://apps.apple.com/us/app/yivi/id1294092994",
199206
"androidHref": "https://play.google.com/store/apps/details?id=org.irmacard.cardemu&hl=en"

src/lib/locales/nl.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,13 @@
193193
"pbdf.gemeente.personalData.dateofbirth.placeholder": "15-01-1990"
194194
}
195195
},
196+
"error": {
197+
"title": "Pagina niet gevonden",
198+
"message": "De pagina die je zoekt bestaat niet of is verplaatst.",
199+
"back": "Ga naar de homepagina",
200+
"serverTitle": "Er is iets misgegaan",
201+
"serverMessage": "Onze server heeft een onverwachte fout ondervonden. Probeer het later opnieuw."
202+
},
196203
"yivi": {
197204
"iosHref": "https://apps.apple.com/nl/app/yivi/id1294092994",
198205
"androidHref": "https://play.google.com/store/apps/details?id=org.irmacard.cardemu&hl=nl"

src/routes/+error.svelte

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<script lang="ts">
2+
import { page } from '$app/state'
3+
import { _ } from 'svelte-i18n'
4+
</script>
5+
6+
<div class="error-page">
7+
<div class="error-card">
8+
<span class="error-code">{page.status}</span>
9+
<h2>
10+
{#if page.status === 404}
11+
{$_('error.title')}
12+
{:else}
13+
{$_('error.serverTitle')}
14+
{/if}
15+
</h2>
16+
<p>
17+
{#if page.status === 404}
18+
{$_('error.message')}
19+
{:else}
20+
{$_('error.serverMessage')}
21+
{/if}
22+
</p>
23+
<a href="/" class="home-btn">{$_('error.back')}</a>
24+
</div>
25+
</div>
26+
27+
<style>
28+
.error-page {
29+
flex: 1;
30+
display: flex;
31+
align-items: center;
32+
justify-content: center;
33+
padding: 1.5rem 1rem;
34+
}
35+
36+
.error-card {
37+
display: flex;
38+
flex-direction: column;
39+
align-items: center;
40+
text-align: center;
41+
max-width: 420px;
42+
padding: 2.5rem 2rem;
43+
background: var(--pg-soft-background);
44+
border: 1px solid var(--pg-strong-background);
45+
border-radius: var(--pg-border-radius-lg);
46+
box-shadow: 0 2px 8px rgba(48, 149, 222, 0.08);
47+
gap: 0.75rem;
48+
}
49+
50+
.error-code {
51+
font-size: 4rem;
52+
font-weight: var(--pg-font-weight-extrabold);
53+
color: var(--pg-primary);
54+
line-height: 1;
55+
}
56+
57+
h2 {
58+
font-size: var(--pg-font-size-xl);
59+
font-weight: var(--pg-font-weight-bold);
60+
color: var(--pg-text);
61+
margin: 0;
62+
}
63+
64+
p {
65+
font-size: var(--pg-font-size-base);
66+
color: var(--pg-text-secondary);
67+
line-height: 1.5;
68+
margin: 0;
69+
}
70+
71+
.home-btn {
72+
margin-top: 0.75rem;
73+
padding: 0.75rem 2rem;
74+
background-color: var(--pg-text);
75+
color: var(--pg-general-background);
76+
border: none;
77+
border-radius: var(--pg-border-radius-sm);
78+
cursor: pointer;
79+
font-size: var(--pg-font-size-base);
80+
font-family: var(--pg-font-family);
81+
font-weight: var(--pg-font-weight-medium);
82+
text-decoration: none;
83+
transition: all 0.2s ease;
84+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
85+
}
86+
87+
.home-btn:hover {
88+
background-color: var(--pg-input-active);
89+
transform: translateY(-1px);
90+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
91+
}
92+
93+
.home-btn:active {
94+
transform: translateY(0);
95+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
96+
}
97+
</style>

0 commit comments

Comments
 (0)