diff --git a/package-lock.json b/package-lock.json index 359c2121..2d2988c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "revanced-website", "version": "0.0.1", "dependencies": { - "@tanstack/query-core": "^4.36.1", + "@tanstack/query-core": "^5.85.6", "@tanstack/query-persist-client-core": "^4.36.1", "@tanstack/query-sync-storage-persister": "^4.36.1", "@tanstack/svelte-query": "^4.36.1", @@ -1926,9 +1926,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "4.36.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.36.1.tgz", - "integrity": "sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==", + "version": "5.85.6", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.85.6.tgz", + "integrity": "sha512-hCj0TktzdCv2bCepIdfwqVwUVWb+GSHm1Jnn8w+40lfhQ3m7lCO7ADRUJy+2unxQ/nzjh2ipC6ye69NDW3l73g==", "license": "MIT", "funding": { "type": "github", @@ -1948,6 +1948,16 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@tanstack/query-persist-client-core/node_modules/@tanstack/query-core": { + "version": "4.36.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.36.1.tgz", + "integrity": "sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@tanstack/query-sync-storage-persister": { "version": "4.36.1", "resolved": "https://registry.npmjs.org/@tanstack/query-sync-storage-persister/-/query-sync-storage-persister-4.36.1.tgz", @@ -1977,6 +1987,16 @@ "svelte": ">=3 <5" } }, + "node_modules/@tanstack/svelte-query/node_modules/@tanstack/query-core": { + "version": "4.36.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.36.1.tgz", + "integrity": "sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", diff --git a/package.json b/package.json index fd3ec237..a15a8c86 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ }, "type": "module", "dependencies": { - "@tanstack/query-core": "^4.36.1", + "@tanstack/query-core": "^5.85.6", "@tanstack/query-persist-client-core": "^4.36.1", "@tanstack/query-sync-storage-persister": "^4.36.1", "@tanstack/svelte-query": "^4.36.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 942a5f53..64e4c081 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@tanstack/query-core': - specifier: ^4.36.1 - version: 4.36.1 + specifier: ^5.85.6 + version: 5.85.6 '@tanstack/query-persist-client-core': specifier: ^4.36.1 version: 4.36.1 @@ -682,6 +682,9 @@ packages: '@tanstack/query-core@4.36.1': resolution: {integrity: sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==} + '@tanstack/query-core@5.85.6': + resolution: {integrity: sha512-hCj0TktzdCv2bCepIdfwqVwUVWb+GSHm1Jnn8w+40lfhQ3m7lCO7ADRUJy+2unxQ/nzjh2ipC6ye69NDW3l73g==} + '@tanstack/query-persist-client-core@4.36.1': resolution: {integrity: sha512-eocgCeI7D7TRv1IUUBMfVwOI0wdSmMkBIbkKhqEdTrnUHUQEeOaYac8oeZk2cumAWJdycu6P/wB+WqGynTnzXg==} @@ -1978,6 +1981,8 @@ snapshots: '@tanstack/query-core@4.36.1': {} + '@tanstack/query-core@5.85.6': {} + '@tanstack/query-persist-client-core@4.36.1': dependencies: '@tanstack/query-core': 4.36.1 diff --git a/src/app.scss b/src/app.scss index b9045e64..6edeacfb 100644 --- a/src/app.scss +++ b/src/app.scss @@ -8,7 +8,7 @@ -webkit-tap-highlight-color: rgba(0, 0, 0, 0); transition: color 0.5s ease-in-out, - background-color 0.5s ease-in-out, + background-color 20s ease-in-out, fill 0.5s ease-in-out; } diff --git a/src/data/api/index.ts b/src/data/api/index.ts index d9b2211a..0705d973 100644 --- a/src/data/api/index.ts +++ b/src/data/api/index.ts @@ -150,7 +150,7 @@ async function announcements(options: GetAnnouncementsOptions = {}): Promise { +export async function get_announcement_by_id(id: number): Promise<{ announcement: ResponseAnnouncement }> { return { announcement: (await get_json(`announcements/${id}`)) as ResponseAnnouncement }; } diff --git a/src/routes/+error.svelte b/src/routes/+error.svelte deleted file mode 100644 index 5a8307a8..00000000 --- a/src/routes/+error.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - - - -
-

{status}

- {#if status == 404} -

This page received a cease and desist letter from a multi-billion dollar tech company.

-
- - {:else} -

- {$page.error?.message} -

- {/if} -
- - diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 7416e5d0..7a8d3d9c 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -52,7 +52,7 @@ onMount(() => { set_about_info(api_base_url()); - new DateTriggerEventHandler(themeEvents); + // new DateTriggerEventHandler(themeEvents); isRestoring.set(true); const [unsubscribe, promise] = persistQueryClient({ diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 189f71e2..df46931d 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -1 +1 @@ -export const prerender = true; +export const prerender = 'auto'; diff --git a/src/routes/announcements/[slug]/+layout.ts b/src/routes/announcements/[slug]/+layout.ts deleted file mode 100644 index d43d0cd2..00000000 --- a/src/routes/announcements/[slug]/+layout.ts +++ /dev/null @@ -1 +0,0 @@ -export const prerender = false; diff --git a/src/routes/announcements/[slug]/+page.server.ts b/src/routes/announcements/[slug]/+page.server.ts new file mode 100644 index 00000000..1133f707 --- /dev/null +++ b/src/routes/announcements/[slug]/+page.server.ts @@ -0,0 +1,67 @@ +import { error } from '@sveltejs/kit'; +import type { PageServerLoad, EntryGenerator } from './$types'; +import { createQuery, useQueryClient } from '@tanstack/svelte-query'; +import { get_announcement_by_id, queries } from '$data/api'; + +export const prerender = false; // Temporarily disable +export const ssr = true; + +// This tells SvelteKit which dynamic routes to prerender +export const entries: EntryGenerator = async ({ fetch }) => { + try { + console.log('Generating entries for prerendering...'); + const response = await fetch('/api/announcements'); + + if (!response.ok) { + console.warn('Failed to fetch announcements for prerendering'); + return []; + } + + const data = await response.json(); + + const entries = data.announcements.map((announcement: any) => { + const slug = announcement.title + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, ''); + + console.log(`Generated entry: ${announcement.id}-${slug}`); + return { slug: `${announcement.id}-${slug}` }; + }); + + // Always include the create route + entries.push({ slug: 'create' }); + + return entries; + } catch (error) { + console.warn('Error generating entries:', error); + return [{ slug: 'create' }]; // At least include create route + } +}; + +export const load: PageServerLoad = async ({ params, fetch }) => { + console.log('=== SERVER LOAD CALLED ===', params.slug); + + const announcementId = 14; + console.log('Parsed announcementId:', announcementId); + + if (!announcementId || announcementId === 'create') { + console.log('Returning isCreating: true'); + return { isCreating: true }; + } + + try { + console.log('Fetching announcement...'); + const response = await get_announcement_by_id(announcementId); + console.log('Successfully loaded announcement:', response.announcement?.title); + + return { + isCreating: false, + announcement: response.announcement, + announcementId: announcementId + }; + } catch (err) { + // console.log('Caught error:', err); + // throw error(404, 'Announcement not found'); + } +}; diff --git a/src/routes/announcements/[slug]/+page.svelte b/src/routes/announcements/[slug]/+page.svelte index 350e94ea..c313d52c 100644 --- a/src/routes/announcements/[slug]/+page.svelte +++ b/src/routes/announcements/[slug]/+page.svelte @@ -1,48 +1,17 @@
- {#if query} - - - - {:else} - - {/if} -
\ No newline at end of file + + diff --git a/src/routes/announcements/[slug]/AdminButtons.svelte b/src/routes/announcements/[slug]/AdminButtons.svelte index da99fe1d..941012ae 100644 --- a/src/routes/announcements/[slug]/AdminButtons.svelte +++ b/src/routes/announcements/[slug]/AdminButtons.svelte @@ -16,6 +16,7 @@ import Show from 'svelte-material-icons/EyeOutline.svelte'; import Hide from 'svelte-material-icons/EyeOffOutline.svelte'; import Unarchive from 'svelte-material-icons/ArchiveArrowUpOutline.svelte'; + import { formatUTC } from '$util/formatUtc'; export let isEditing: boolean; export let isCreating: boolean; @@ -67,6 +68,11 @@ const save = async () => { if (!isValid()) return; + Object.assign(draftInputs, { + created_at: formatUTC(draftInputs.created_at), + archived_at: formatUTC(draftInputs.archived_at) + }); + await admin.update_announcement(announcementIdNumber!, sanitize(draftInputs)); await $query?.refetch(); @@ -76,8 +82,13 @@ const createAnnouncement = async () => { if (!isValid()) return; + Object.assign(draftInputs, { + created_at: formatUTC(draftInputs.created_at), + archived_at: formatUTC(draftInputs.archived_at) + }); + await admin.create_announcement(sanitize(draftInputs)); - await client.invalidateQueries(queries['announcements']()); + await client.invalidateQueries(queries.announcements()); goto('/announcements', { invalidateAll: true }); }; diff --git a/src/util/formatUtc.ts b/src/util/formatUtc.ts new file mode 100644 index 00000000..624ef217 --- /dev/null +++ b/src/util/formatUtc.ts @@ -0,0 +1,3 @@ +import moment from 'moment'; + +export const formatUTC = (d: any) => d && moment(d).utc().format('YYYY-MM-DDTHH:mm[Z]'); diff --git a/svelte.config.js b/svelte.config.js index bab3ad11..4b10dd55 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -8,10 +8,10 @@ const config = { kit: { // adapter-static has vercel detection, but that does not let you set a custom 404 page easily. // Instead, we have to use a wrapper that generates a vercel config if on vercel... - adapter: adapter({ - pages: 'public', - fallback: '404.html' - }), + adapter: adapter({}), + prerender: { + entries: ['*'] // This should be fine + }, env: { publicPrefix: 'RV' },