diff --git a/frontend/package.json b/frontend/package.json index ff8a67e3..a4c6a197 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,7 +15,7 @@ "devDependencies": { "@sveltejs/adapter-auto": "^2.0.0", "@sveltejs/adapter-node": "^1.3.1", - "@sveltejs/kit": "^1.27.4", + "@sveltejs/kit": "1.30.0", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "@types/luxon": "^3.3.7", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index f46e477e..daaa645c 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -33,13 +33,13 @@ dependencies: devDependencies: '@sveltejs/adapter-auto': specifier: ^2.0.0 - version: 2.0.0(@sveltejs/kit@1.27.4) + version: 2.0.0(@sveltejs/kit@1.30.0) '@sveltejs/adapter-node': specifier: ^1.3.1 - version: 1.3.1(@sveltejs/kit@1.27.4) + version: 1.3.1(@sveltejs/kit@1.30.0) '@sveltejs/kit': - specifier: ^1.27.4 - version: 1.27.4(svelte@4.2.7)(vite@4.4.2) + specifier: 1.30.0 + version: 1.30.0(svelte@4.2.7)(vite@4.4.2) '@types/luxon': specifier: ^3.3.7 version: 3.3.7 @@ -534,16 +534,16 @@ packages: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true - /@sveltejs/adapter-auto@2.0.0(@sveltejs/kit@1.27.4): + /@sveltejs/adapter-auto@2.0.0(@sveltejs/kit@1.30.0): resolution: {integrity: sha512-b+gkHFZgD771kgV3aO4avHFd7y1zhmMYy9i6xOK7m/rwmwaRO8gnF5zBc0Rgca80B2PMU1bKNxyBTHA14OzUAQ==} peerDependencies: '@sveltejs/kit': ^1.0.0 dependencies: - '@sveltejs/kit': 1.27.4(svelte@4.2.7)(vite@4.4.2) + '@sveltejs/kit': 1.30.0(svelte@4.2.7)(vite@4.4.2) import-meta-resolve: 2.2.2 dev: true - /@sveltejs/adapter-node@1.3.1(@sveltejs/kit@1.27.4): + /@sveltejs/adapter-node@1.3.1(@sveltejs/kit@1.30.0): resolution: {integrity: sha512-A0VgRQDCDPzdLNoiAbcOxGw4zT1Mc+n1LwT1OmO350R7WxrEqdMUChPPOd1iMfIDWlP4ie6E2d/WQf5es2d4Zw==} peerDependencies: '@sveltejs/kit': ^1.0.0 @@ -551,12 +551,12 @@ packages: '@rollup/plugin-commonjs': 25.0.7(rollup@3.29.4) '@rollup/plugin-json': 6.0.1(rollup@3.29.4) '@rollup/plugin-node-resolve': 15.2.3(rollup@3.29.4) - '@sveltejs/kit': 1.27.4(svelte@4.2.7)(vite@4.4.2) + '@sveltejs/kit': 1.30.0(svelte@4.2.7)(vite@4.4.2) rollup: 3.29.4 dev: true - /@sveltejs/kit@1.27.4(svelte@4.2.7)(vite@4.4.2): - resolution: {integrity: sha512-Vxl8Jf0C1+/8i/slsxFOnwJntCBDLueO/O6GJ0390KUnyW3Zs+4ZiIinD+cEcYnJPQQ9CRzVSr9Bn6DbmTn4Dw==} + /@sveltejs/kit@1.30.0(svelte@4.2.7)(vite@4.4.2): + resolution: {integrity: sha512-HK7XE8ZAL7cGreRRxCCVEpcNA3x2KM0mfJlDv7geEyCElYjJsdBoANEb00HcYlvs/2ShNAsX8lY/A60s9Xdfew==} engines: {node: ^16.14 || >=18} hasBin: true requiresBuild: true diff --git a/frontend/src/lib/components/header/item.svelte b/frontend/src/lib/components/header-item.svelte similarity index 100% rename from frontend/src/lib/components/header/item.svelte rename to frontend/src/lib/components/header-item.svelte diff --git a/frontend/src/lib/components/header.svelte b/frontend/src/lib/components/header.svelte index 41f2294a..a494d324 100644 --- a/frontend/src/lib/components/header.svelte +++ b/frontend/src/lib/components/header.svelte @@ -1,9 +1,10 @@
-
+
-
+
test
-

{plexDebridItem.title}

-

{plexDebridItem.aired_at}

+

+ {plexDebridItem.title} +

+

{plexDebridItem.aired_at.slice(0, -3)}

+
+ {#each plexDebridItem.genres as genre} + + {formatState(genre)} + + {/each} +
-
+

Status

- - {itemState.text} + + {itemState.text ?? formatState(plexDebridItem.state)}
diff --git a/frontend/src/lib/helpers.ts b/frontend/src/lib/helpers.ts index 6a2f7573..3efa5772 100644 --- a/frontend/src/lib/helpers.ts +++ b/frontend/src/lib/helpers.ts @@ -1,4 +1,4 @@ -import { DateTime, Settings } from 'luxon'; +import { DateTime } from 'luxon'; import type { PlexDebridItem } from '$lib/types'; // only works with real-debrid dates because of CET format provided by RD diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index 74965ad0..2befbeac 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -30,7 +30,7 @@ export interface PlexDebridItem { } export interface StatusInterface { - text: string; + text?: string; color: string; bg: string; description: string; diff --git a/frontend/src/routes/+error.svelte b/frontend/src/routes/+error.svelte new file mode 100644 index 00000000..b225a59b --- /dev/null +++ b/frontend/src/routes/+error.svelte @@ -0,0 +1,9 @@ + + +
+

Something went wrong

+

Error code: {$page.status}

+

Error message: {$page.error?.message}

+
diff --git a/frontend/src/routes/+page.server.ts b/frontend/src/routes/+page.server.ts new file mode 100644 index 00000000..b2cfb462 --- /dev/null +++ b/frontend/src/routes/+page.server.ts @@ -0,0 +1,22 @@ +import type { PageServerLoad } from './$types'; +import type { UserResponse } from '$lib/types'; +import { error } from '@sveltejs/kit'; + +export const load: PageServerLoad = async ({ fetch }) => { + async function getUserData() { + try { + const res = await fetch('http://localhost:8080/user'); + if (res.ok) { + return (await res.json()) as UserResponse; + } + throw error(res.status, `Unable to fetch user data: ${res.status} ${res.statusText}`); + } catch (e) { + console.error(e); + throw error(500, 'Unable to fetch user data. API is down.'); + } + } + + return { + user: await getUserData() + }; +}; diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 1950df05..cea2a73c 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -1,7 +1,12 @@ @@ -9,13 +14,9 @@
- {#if data.user}

Welcome {data.user?.username}

{data.user?.email}

Premium expires on {formatDate(data.user?.expiration, 'short')}

- {:else} -

You are not logged in.

- {/if}
diff --git a/frontend/src/routes/+page.ts b/frontend/src/routes/+page.ts deleted file mode 100644 index b261cab4..00000000 --- a/frontend/src/routes/+page.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { PageLoad } from './$types'; -import type { UserResponse } from '$lib/types'; - -export const load: PageLoad = async ({ fetch }) => { - const getUserData = async () => { - const res = await fetch('http://localhost:8080/user'); - if (res.ok) { - return await res.json() as UserResponse; - } - return null; - }; - - return { - user: getUserData() - }; -}; diff --git a/frontend/src/routes/settings/+page.svelte b/frontend/src/routes/settings/+page.svelte new file mode 100644 index 00000000..cac21117 --- /dev/null +++ b/frontend/src/routes/settings/+page.svelte @@ -0,0 +1,10 @@ + + +
+
+ +

This page is under construction

+
+
diff --git a/frontend/src/routes/status/+page.server.ts b/frontend/src/routes/status/+page.server.ts new file mode 100644 index 00000000..374b63e7 --- /dev/null +++ b/frontend/src/routes/status/+page.server.ts @@ -0,0 +1,37 @@ +import type { PageServerLoad } from './$types'; +import { error } from '@sveltejs/kit'; + +export const load: PageServerLoad = async ({ fetch }) => { + async function getStates() { + try { + const res = await fetch('http://localhost:8080/items/states'); + if (res.ok) { + return await res.json(); + } + throw error(res.status, `Unable to fetch states data: ${res.status} ${res.statusText}`); + } catch (e) { + console.error(e); + throw error(500, 'Unable to fetch states data. API is down.'); + } + } + + async function getItems() { + try { + const res = await fetch('http://localhost:8080/items/'); + if (res.ok) { + return await res.json(); + } + throw error(res.status, `Unable to fetch items data: ${res.status} ${res.statusText}`); + } catch (e) { + console.error(e); + throw error(500, 'Unable to fetch items data. API is down.'); + } + } + + return { + streamed: { + items: getItems() + }, + states: await getStates() + }; +}; diff --git a/frontend/src/routes/status/+page.svelte b/frontend/src/routes/status/+page.svelte index eb97bdad..89ca2a27 100644 --- a/frontend/src/routes/status/+page.svelte +++ b/frontend/src/routes/status/+page.svelte @@ -20,50 +20,45 @@ toast.success('Refreshed data'); } - const statusInfo: StatusInfo = { - UNKNOWN: { - text: formatState('Unknown'), - color: 'text-red-500', - bg: 'bg-red-500', - description: 'Unknown status' - }, - CONTENT: { - text: 'Requested', - color: 'text-purple-500', - bg: 'bg-purple-500', - description: 'Item is requested from external service' - }, - SCRAPE: { - text: formatState('Scraped'), - color: 'text-yellow-500', - bg: 'bg-yellow-500', - description: 'Item is scraped and will be downloaded' - }, - DOWNLOAD: { - text: formatState('Download'), - color: 'text-yellow-500', - bg: 'bg-yellow-500', - description: 'Item is currently downloading' - }, - SYMLINK: { - text: formatState('Symlink'), - color: 'text-yellow-500', - bg: 'bg-yellow-500', - description: 'Item is currently being symmlinked' - }, - LIBRARY: { - text: 'In Library', - color: 'text-green-400', - bg: 'bg-green-400', - description: 'Item is in your library' - }, - LIBRARY_PARTIAL: { - text: formatState('Library Partial'), - color: 'text-blue-400', - bg: 'bg-blue-400', - description: 'Item is in your library and is ongoing' - }, - }; + const statusInfo: StatusInfo = { + UNKNOWN: { + color: 'text-red-500', + bg: 'bg-red-500', + description: 'Unknown status' + }, + CONTENT: { + text: 'Requested', + color: 'text-purple-500', + bg: 'bg-purple-500', + description: 'Item is requested from external service' + }, + SCRAPE: { + color: 'text-yellow-500', + bg: 'bg-yellow-500', + description: 'Item is scraped and will be downloaded' + }, + DOWNLOAD: { + color: 'text-yellow-500', + bg: 'bg-yellow-500', + description: 'Item is currently downloading' + }, + SYMLINK: { + color: 'text-yellow-500', + bg: 'bg-yellow-500', + description: 'Item is currently being symmlinked' + }, + LIBRARY: { + text: 'In Library', + color: 'text-green-400', + bg: 'bg-green-400', + description: 'Item is in your library' + }, + LIBRARY_PARTIAL: { + color: 'text-blue-400', + bg: 'bg-blue-400', + description: 'Item is in your library and is ongoing' + } + }; @@ -136,12 +131,12 @@
    {#each Object.keys(statusInfo) as key (key)} - {#if key !== 'ERROR' && key !== 'UNKNOWN'} -
  • - {statusInfo[key].text}: - {statusInfo[key].description} -
  • - {/if} +
  • + + {statusInfo[key].text ?? formatState(key)} + + {statusInfo[key].description} +
  • {/each}
@@ -156,6 +151,9 @@
{/each} {:catch error} -

{error.message}

+
+

Something went wrong

+

Error message: {error.message}

+
{/await}
diff --git a/frontend/src/routes/status/+page.ts b/frontend/src/routes/status/+page.ts deleted file mode 100644 index 2a1e6f1c..00000000 --- a/frontend/src/routes/status/+page.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { PageLoad } from './$types'; - -export const load: PageLoad = async ({ fetch }) => { - const getItems = async () => { - const res = await fetch('http://localhost:8080/items/'); - if (res.ok) { - return await res.json(); - } - return null; - }; - - const getStates = async () => { - const res = await fetch('http://localhost:8080/items/states'); - if (res.ok) { - return await res.json(); - } - return null; - } - - return { - streamed: { - items: getItems(), - }, - states: getStates() - }; -};