This commit is contained in:
@@ -10,36 +10,45 @@
|
|||||||
let session = $derived($page.data?.session);
|
let session = $derived($page.data?.session);
|
||||||
let user = $derived(session?.user);
|
let user = $derived(session?.user);
|
||||||
|
|
||||||
// Get Bible quote from SSR via handleError hook
|
// Get Bible quote and language from SSR via handleError hook
|
||||||
let bibleQuote = $derived($page.error?.bibleQuote);
|
let bibleQuote = $derived($page.error?.bibleQuote);
|
||||||
|
let isEnglish = $derived($page.error?.lang === 'en');
|
||||||
|
|
||||||
function getErrorTitle(status) {
|
function getErrorTitle(status) {
|
||||||
|
if (isEnglish) {
|
||||||
|
switch (status) {
|
||||||
|
case 401: return 'Login Required';
|
||||||
|
case 403: return 'Access Denied';
|
||||||
|
case 404: return 'Page Not Found';
|
||||||
|
case 500: return 'Server Error';
|
||||||
|
default: return 'Error';
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 401:
|
case 401: return 'Anmeldung erforderlich';
|
||||||
return 'Anmeldung erforderlich';
|
case 403: return 'Zugriff verweigert';
|
||||||
case 403:
|
case 404: return 'Seite nicht gefunden';
|
||||||
return 'Zugriff verweigert';
|
case 500: return 'Serverfehler';
|
||||||
case 404:
|
default: return 'Fehler';
|
||||||
return 'Seite nicht gefunden';
|
|
||||||
case 500:
|
|
||||||
return 'Serverfehler';
|
|
||||||
default:
|
|
||||||
return 'Fehler';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getErrorDescription(status) {
|
function getErrorDescription(status) {
|
||||||
|
if (isEnglish) {
|
||||||
|
switch (status) {
|
||||||
|
case 401: return 'You must be logged in to access this page.';
|
||||||
|
case 403: return 'You do not have permission for this area.';
|
||||||
|
case 404: return 'The requested page could not be found.';
|
||||||
|
case 500: return 'An unexpected error occurred. Please try again later.';
|
||||||
|
default: return 'An unexpected error occurred.';
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 401:
|
case 401: return 'Du musst angemeldet sein, um auf diese Seite zugreifen zu können.';
|
||||||
return 'Du musst angemeldet sein, um auf diese Seite zugreifen zu können.';
|
case 403: return 'Du hast keine Berechtigung für diesen Bereich.';
|
||||||
case 403:
|
case 404: return 'Die angeforderte Seite konnte nicht gefunden werden.';
|
||||||
return 'Du hast keine Berechtigung für diesen Bereich.';
|
case 500: return 'Es ist ein unerwarteter Fehler aufgetreten. Bitte versuche es später erneut.';
|
||||||
case 404:
|
default: return 'Es ist ein unerwarteter Fehler aufgetreten.';
|
||||||
return 'Die angeforderte Seite konnte nicht gefunden werden.';
|
|
||||||
case 500:
|
|
||||||
return 'Es ist ein unerwarteter Fehler aufgetreten. Bitte versuche es später erneut.';
|
|
||||||
default:
|
|
||||||
return 'Es ist ein unerwarteter Fehler aufgetreten.';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +105,7 @@
|
|||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div class="error-code">
|
<div class="error-code">
|
||||||
Fehler {status}
|
{isEnglish ? 'Error' : 'Fehler'} {status}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="error-description">
|
<p class="error-description">
|
||||||
@@ -112,38 +121,24 @@
|
|||||||
<div class="error-actions">
|
<div class="error-actions">
|
||||||
{#if status === 401}
|
{#if status === 401}
|
||||||
<button class="btn btn-primary" onclick={login}>
|
<button class="btn btn-primary" onclick={login}>
|
||||||
Anmelden
|
{isEnglish ? 'Log In' : 'Anmelden'}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary" onclick={goHome}>
|
<button class="btn btn-secondary" onclick={goHome}>
|
||||||
Zur Startseite
|
{isEnglish ? 'Go to Homepage' : 'Zur Startseite'}
|
||||||
</button>
|
|
||||||
{:else if status === 403}
|
|
||||||
<button class="btn btn-primary" onclick={goHome}>
|
|
||||||
Zur Startseite
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-secondary" onclick={goBack}>
|
|
||||||
Zurück
|
|
||||||
</button>
|
|
||||||
{:else if status === 404}
|
|
||||||
<button class="btn btn-primary" onclick={goHome}>
|
|
||||||
Zur Startseite
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-secondary" onclick={goBack}>
|
|
||||||
Zurück
|
|
||||||
</button>
|
</button>
|
||||||
{:else if status === 500}
|
{:else if status === 500}
|
||||||
<button class="btn btn-primary" onclick={goHome}>
|
<button class="btn btn-primary" onclick={goHome}>
|
||||||
Zur Startseite
|
{isEnglish ? 'Go to Homepage' : 'Zur Startseite'}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary" onclick={goBack}>
|
<button class="btn btn-secondary" onclick={goBack}>
|
||||||
Erneut versuchen
|
{isEnglish ? 'Try Again' : 'Erneut versuchen'}
|
||||||
</button>
|
</button>
|
||||||
{:else}
|
{:else}
|
||||||
<button class="btn btn-primary" onclick={goHome}>
|
<button class="btn btn-primary" onclick={goHome}>
|
||||||
Zur Startseite
|
{isEnglish ? 'Go to Homepage' : 'Zur Startseite'}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary" onclick={goBack}>
|
<button class="btn btn-secondary" onclick={goBack}>
|
||||||
Zurück
|
{isEnglish ? 'Go Back' : 'Zurück'}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@@ -152,7 +147,7 @@
|
|||||||
{#if bibleQuote}
|
{#if bibleQuote}
|
||||||
<div class="bible-quote">
|
<div class="bible-quote">
|
||||||
<div class="quote-text">
|
<div class="quote-text">
|
||||||
„{bibleQuote.text}"
|
{isEnglish ? '"' : '„'}{bibleQuote.text}{isEnglish ? '"' : '"'}
|
||||||
</div>
|
</div>
|
||||||
<div class="quote-reference">
|
<div class="quote-reference">
|
||||||
— {bibleQuote.reference}
|
— {bibleQuote.reference}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { mysteryVerseData } from '$lib/data/mysteryVerseData';
|
import { mysteryVerseDataDe, mysteryVerseDataEn } from '$lib/data/mysteryVerseData';
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
interface StreakData {
|
interface StreakData {
|
||||||
@@ -36,7 +36,7 @@ function getMysteryForWeekday(date: Date, includeLuminous: boolean): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ url, fetch, locals }) => {
|
export const load: PageServerLoad = async ({ url, fetch, locals, params }) => {
|
||||||
const session = await locals.auth();
|
const session = await locals.auth();
|
||||||
|
|
||||||
// Read toggle/mystery state from URL search params (for no-JS progressive enhancement)
|
// Read toggle/mystery state from URL search params (for no-JS progressive enhancement)
|
||||||
@@ -76,7 +76,7 @@ export const load: PageServerLoad = async ({ url, fetch, locals }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mysteryDescriptions: mysteryVerseData,
|
mysteryDescriptions: params.faithLang === 'faith' ? mysteryVerseDataEn : mysteryVerseDataDe,
|
||||||
streakData,
|
streakData,
|
||||||
initialMystery,
|
initialMystery,
|
||||||
todaysMystery,
|
todaysMystery,
|
||||||
|
|||||||
@@ -1884,5 +1884,5 @@ h1 {
|
|||||||
|
|
||||||
<!-- Bible citation modal -->
|
<!-- Bible citation modal -->
|
||||||
{#if showModal}
|
{#if showModal}
|
||||||
<BibleModal reference={selectedReference} title={selectedTitle} verseData={selectedVerseData} onClose={() => showModal = false} />
|
<BibleModal reference={selectedReference} title={selectedTitle} verseData={selectedVerseData} lang={data.lang} onClose={() => showModal = false} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import { json, error } from '@sveltejs/kit';
|
import { json, error } from '@sveltejs/kit';
|
||||||
import type { RequestHandler } from './$types';
|
import type { RequestHandler } from './$types';
|
||||||
import { lookupReference } from '$lib/server/bible';
|
import { lookupReference } from '$lib/server/bible';
|
||||||
|
import { resolve } from 'path';
|
||||||
|
|
||||||
|
const tsvFiles: Record<string, string> = {
|
||||||
|
glaube: 'static/allioli.tsv',
|
||||||
|
faith: 'static/drb.tsv'
|
||||||
|
};
|
||||||
|
|
||||||
export const GET: RequestHandler = async ({ params }) => {
|
export const GET: RequestHandler = async ({ params }) => {
|
||||||
const reference = params.reference;
|
const reference = params.reference;
|
||||||
@@ -9,8 +15,10 @@ export const GET: RequestHandler = async ({ params }) => {
|
|||||||
return error(400, 'Missing reference parameter');
|
return error(400, 'Missing reference parameter');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tsvPath = resolve(tsvFiles[params.faithLang]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = lookupReference(reference);
|
const result = lookupReference(reference, tsvPath);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return error(404, 'No verses found for the given reference');
|
return error(404, 'No verses found for the given reference');
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { json, error } from '@sveltejs/kit';
|
import { json, error } from '@sveltejs/kit';
|
||||||
import type { RequestHandler } from './$types';
|
import type { RequestHandler } from './$types';
|
||||||
|
import { resolve } from 'path';
|
||||||
|
|
||||||
interface BibleVerse {
|
interface BibleVerse {
|
||||||
bookName: string;
|
bookName: string;
|
||||||
@@ -10,23 +11,27 @@ interface BibleVerse {
|
|||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache for parsed verses to avoid reading file repeatedly
|
const tsvFiles: Record<string, string> = {
|
||||||
let cachedVerses: BibleVerse[] | null = null;
|
glaube: '/allioli.tsv',
|
||||||
|
faith: '/drb.tsv'
|
||||||
|
};
|
||||||
|
|
||||||
async function loadVerses(fetch: typeof globalThis.fetch): Promise<BibleVerse[]> {
|
// Cache for parsed verses per language
|
||||||
if (cachedVerses) {
|
const versesCache = new Map<string, BibleVerse[]>();
|
||||||
return cachedVerses;
|
|
||||||
}
|
async function loadVerses(fetch: typeof globalThis.fetch, tsvFile: string): Promise<BibleVerse[]> {
|
||||||
|
const cached = versesCache.get(tsvFile);
|
||||||
|
if (cached) return cached;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/allioli.tsv');
|
const response = await fetch(tsvFile);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
const content = await response.text();
|
const content = await response.text();
|
||||||
const lines = content.trim().split('\n');
|
const lines = content.trim().split('\n');
|
||||||
|
|
||||||
cachedVerses = lines.map(line => {
|
const verses = lines.map(line => {
|
||||||
const [bookName, abbreviation, bookNumber, chapter, verseNumber, text] = line.split('\t');
|
const [bookName, abbreviation, bookNumber, chapter, verseNumber, text] = line.split('\t');
|
||||||
return {
|
return {
|
||||||
bookName,
|
bookName,
|
||||||
@@ -38,7 +43,8 @@ async function loadVerses(fetch: typeof globalThis.fetch): Promise<BibleVerse[]>
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return cachedVerses;
|
versesCache.set(tsvFile, verses);
|
||||||
|
return verses;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error loading Bible verses:', err);
|
console.error('Error loading Bible verses:', err);
|
||||||
throw new Error('Failed to load Bible verses');
|
throw new Error('Failed to load Bible verses');
|
||||||
@@ -54,9 +60,11 @@ function formatVerse(verse: BibleVerse): string {
|
|||||||
return `${verse.bookName} ${verse.chapter}:${verse.verseNumber}`;
|
return `${verse.bookName} ${verse.chapter}:${verse.verseNumber}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GET: RequestHandler = async ({ fetch }) => {
|
export const GET: RequestHandler = async ({ fetch, params }) => {
|
||||||
|
const tsvFile = tsvFiles[params.faithLang];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const verses = await loadVerses(fetch);
|
const verses = await loadVerses(fetch, tsvFile);
|
||||||
const randomVerse = getRandomVerse(verses);
|
const randomVerse = getRandomVerse(verses);
|
||||||
|
|
||||||
return json({
|
return json({
|
||||||
Reference in New Issue
Block a user