diff --git a/web/src/lib/components/add-media-card.svelte b/web/src/lib/components/add-media-card.svelte index 4a7ad7d..17b6d44 100644 --- a/web/src/lib/components/add-media-card.svelte +++ b/web/src/lib/components/add-media-card.svelte @@ -7,11 +7,12 @@ import { base } from '$app/paths'; import type { MetaDataProviderSearchResult } from '$lib/types.js'; import { SvelteURLSearchParams } from 'svelte/reactivity'; + import type {components} from "$lib/api/api"; const apiUrl = env.PUBLIC_API_URL; let loading = $state(false); let errorMessage = $state(null); - let { result, isShow = true }: { result: MetaDataProviderSearchResult; isShow: boolean } = + let { result, isShow = true }: { result: components['schemas']['MetaDataProviderSearchResult']; isShow: boolean } = $props(); console.log('Add Show Card Result: ', result); diff --git a/web/src/lib/components/recommended-media-carousel.svelte b/web/src/lib/components/recommended-media-carousel.svelte index ad433da..92cb71f 100644 --- a/web/src/lib/components/recommended-media-carousel.svelte +++ b/web/src/lib/components/recommended-media-carousel.svelte @@ -5,13 +5,14 @@ import { Button } from '$lib/components/ui/button'; import { ChevronRight } from 'lucide-svelte'; import { base } from '$app/paths'; + import type {components} from "$lib/api/api"; let { media, isShow, isLoading }: { - media: MetaDataProviderSearchResult[]; + media: components['schemas']['MetaDataProviderSearchResult'][]; isShow: boolean; isLoading: boolean; } = $props(); diff --git a/web/src/routes/dashboard/+layout.ts b/web/src/routes/dashboard/+layout.ts index 5ccdadc..b460e92 100644 --- a/web/src/routes/dashboard/+layout.ts +++ b/web/src/routes/dashboard/+layout.ts @@ -4,17 +4,13 @@ import { redirect } from '@sveltejs/kit'; import { base } from '$app/paths'; import { browser } from '$app/environment'; import { goto } from '$app/navigation'; +import client from "$lib/api"; const apiUrl = env.PUBLIC_API_URL; export const load: LayoutLoad = async ({ fetch }) => { - const response = await fetch(apiUrl + '/users/me', { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - }, - credentials: 'include' - }); + const { data, response } = await client.GET('/api/v1/users/me', { fetch: fetch }); + if (!response.ok) { console.log('unauthorized, redirecting to login'); if (browser) { @@ -23,5 +19,5 @@ export const load: LayoutLoad = async ({ fetch }) => { throw redirect(303, base + '/login'); } } - return { user: await response.json() }; + return { user: data }; }; diff --git a/web/src/routes/dashboard/+page.svelte b/web/src/routes/dashboard/+page.svelte index 74e324f..de25e99 100644 --- a/web/src/routes/dashboard/+page.svelte +++ b/web/src/routes/dashboard/+page.svelte @@ -1,90 +1,79 @@ - Dashboard - MediaManager - + Dashboard - MediaManager +
-
- - - - - - - -
+
+ + + + + + + +
-

- Dashboard -

-
-
-

Trending Shows

- +

+ Dashboard +

+
+
+

Trending Shows

+ -

Trending Movies

- -
-
+

Trending Movies

+ +
+
- -
-
-

- Unread Notifications{#if unreadNotifications.length > 0}: - {unreadNotifications.length} - {/if} -

-
+ {#if loading} +
+
+
+ {:else} + +
+
+

+ Unread Notifications + {#if unreadNotifications.length > 0}: + {unreadNotifications.length} + {/if} +

+
- {#if unreadNotifications.length === 0} -
-

All caught up!

-

No unread notifications

-
- {:else} -
- {#each unreadNotifications as notification (notification.id)} -
-
-
-
-

- {notification.message} -

-

- {formatTimestamp(notification.timestamp)} -

-
-
-
- -
-
-
- {/each} -
- {/if} -
+ {#if unreadNotifications.length === 0} +
+

All caught up!

+

No unread notifications

+
+ {:else} +
+ {#each unreadNotifications as notification (notification.id)} +
+
+
+
+

+ {notification.message} +

+

+ {new Date(notification.timestamp ?? 0).toLocaleDateString()} +

+
+
+
+ +
+
+
+ {/each} +
+ {/if} +
- -
- -
+ +
+ +
- - {#if showRead} -
- {#if readNotifications.length === 0} -
-

No read notifications

-
- {:else} -
- {#each readNotifications as notification (notification.id)} -
-
-
-
-

- {notification.message} -

-

- {formatTimestamp(notification.timestamp)} -

-
-
-
- -
-
-
- {/each} -
- {/if} -
- {/if} - {/if} + + {#if showRead} +
+ {#if readNotifications.length === 0} +
+

No read notifications

+
+ {:else} +
+ {#each readNotifications as notification (notification.id)} +
+
+
+
+

+ {notification.message} +

+

+ {new Date(notification.timestamp ?? 0).toLocaleDateString()} +

+
+
+
+ +
+
+
+ {/each} +
+ {/if} +
+ {/if} + {/if} diff --git a/web/src/routes/dashboard/settings/+page.ts b/web/src/routes/dashboard/settings/+page.ts index d0039b1..5d0d5e5 100644 --- a/web/src/routes/dashboard/settings/+page.ts +++ b/web/src/routes/dashboard/settings/+page.ts @@ -1,34 +1,12 @@ -import { env } from '$env/dynamic/public'; -import type { PageLoad } from './$types'; +import {env} from '$env/dynamic/public'; +import type {PageLoad} from './$types'; +import client from "$lib/api"; const apiUrl = env.PUBLIC_API_URL; -export const load: PageLoad = async ({ fetch }) => { - try { - const users = await fetch(apiUrl + '/users/all', { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - }, - credentials: 'include' - }); +export const load: PageLoad = async ({fetch}) => { + const {data} = await client.GET('/api/v1/users/all', {fetch: fetch}); - if (!users.ok) { - console.error(`Failed to fetch users: ${users.statusText}`); - return { - users: null - }; - } - - const usersData = await users.json(); - console.log('Fetched users:', usersData); - - return { - users: usersData - }; - } catch (error) { - console.error('Error fetching users:', error); - return { - users: null - }; - } + return { + users: data + }; }; diff --git a/web/src/routes/dashboard/tv/+page.svelte b/web/src/routes/dashboard/tv/+page.svelte index 73bc73c..0347e23 100644 --- a/web/src/routes/dashboard/tv/+page.svelte +++ b/web/src/routes/dashboard/tv/+page.svelte @@ -1,85 +1,64 @@ - TV Shows - MediaManager - + TV Shows - MediaManager +
-
- - - - - - - -
+
+ + + + + + + +
-{#snippet loadingbar()} - - - - - - - - - - - -{/snippet}
-

- TV Shows -

-
- {#await tvShowsPromise} - {@render loadingbar()} - {:then tvShowsJson} - {#await tvShowsJson.json()} - {@render loadingbar()} - {:then tvShows} - {#each tvShows as show (show.id)} - - - - {getFullyQualifiedMediaName(show)} - {show.overview} - - - - - - - {:else} -
No TV shows added yet.
- {/each} - {/await} - {/await} -
+

+ TV Shows +

+
)} + {#each tvShows as show (show.id)} + + + + {getFullyQualifiedMediaName(show)} + {show.overview} + + + + + + + {:else} +
No TV shows added yet.
+ {/each} +
diff --git a/web/src/routes/dashboard/tv/+page.ts b/web/src/routes/dashboard/tv/+page.ts index 0f0ba2d..1812c0f 100644 --- a/web/src/routes/dashboard/tv/+page.ts +++ b/web/src/routes/dashboard/tv/+page.ts @@ -1,16 +1,9 @@ -import { env } from '$env/dynamic/public'; -import type { PageLoad } from './$types'; +import {env} from '$env/dynamic/public'; +import client from '$lib/api'; +import type {PageLoad} from './$types'; -const apiUrl = env.PUBLIC_API_URL; -export const load: PageLoad = async ({ fetch }) => { - const response = fetch(apiUrl + '/tv/shows', { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - }, - credentials: 'include' - }); - - return { tvShows: response }; +export const load: PageLoad = async ({fetch}) => { + const {data} = await client.GET('/api/v1/tv/shows', {fetch: fetch}); + return {tvShows: data}; }; diff --git a/web/src/routes/dashboard/tv/[showId=uuid]/+layout.ts b/web/src/routes/dashboard/tv/[showId=uuid]/+layout.ts index 6505608..354a9cf 100644 --- a/web/src/routes/dashboard/tv/[showId=uuid]/+layout.ts +++ b/web/src/routes/dashboard/tv/[showId=uuid]/+layout.ts @@ -1,56 +1,20 @@ -import { env } from '$env/dynamic/public'; -import type { LayoutLoad } from './$types'; +import {env} from '$env/dynamic/public'; +import type {LayoutLoad} from './$types'; +import client from "$lib/api"; const apiUrl = env.PUBLIC_API_URL; -export const load: LayoutLoad = async ({ params, fetch }) => { - const showId = params.showId; +export const load: LayoutLoad = async ({params, fetch}) => { + const show = await client.GET('/api/v1/tv/shows/{show_id}', { + fetch: fetch, + params: {path: {show_id: params.showId}} + }); + const torrents = await client.GET('/api/v1/tv/shows/{show_id}/torrents', { + fetch: fetch, + params: {path: {show_id: params.showId}} + }); - if (!showId) { - return { - showData: null, - torrentsData: null - }; - } - - try { - const show = await fetch(`${apiUrl}/tv/shows/${showId}`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - }, - credentials: 'include' - }); - - const torrents = await fetch(`${apiUrl}/tv/shows/${showId}/torrents`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - }, - credentials: 'include' - }); - - if (!show.ok || !torrents.ok) { - console.error(`Failed to fetch show ${showId}: ${show.statusText}`); - return { - showData: null, - torrentsData: null - }; - } - - const showData = await show.json(); - const torrentsData = await torrents.json(); - console.log('Fetched show data:', showData); - console.log('Fetched torrents data:', torrentsData); - - return { - showData: showData, - torrentsData: torrentsData - }; - } catch (error) { - console.error('Error fetching show:', error); - return { - showData: null, - torrentsData: null - }; - } + return { + showData: show.data, + torrentsData: torrents.data + }; }; diff --git a/web/src/routes/dashboard/tv/[showId=uuid]/+page.svelte b/web/src/routes/dashboard/tv/[showId=uuid]/+page.svelte index 05be627..1a2a1bb 100644 --- a/web/src/routes/dashboard/tv/[showId=uuid]/+page.svelte +++ b/web/src/routes/dashboard/tv/[showId=uuid]/+page.svelte @@ -1,214 +1,211 @@ - {getFullyQualifiedMediaName(show())} - MediaManager - + name="description" + />
-
- - - - - - - -
+
+ + + + + + + +

- {getFullyQualifiedMediaName(show())} + {getFullyQualifiedMediaName(show())}

-
-
- {#if show().id} - - {:else} -
- -
- {/if} -
-
- - - Overview - - -

- {show().overview} -

-
-
-
-
- {#if user().is_superuser} - - - Administrator Controls - - - {#if !show().ended} -
- continuousDownloadEnabled, toggle_continuous_download} - id="continuous-download-checkbox" - /> - -
- {/if} - -
-
- {/if} - - - Download Options - - - {#if user().is_superuser} - - {/if} - - - -
-
-
- - - Season Details - - A list of all seasons for {getFullyQualifiedMediaName(show())}. - - - - - A list of all seasons. - - - Number - Exists on file - Title - Overview - - - - {#if show().seasons.length > 0} - {#each show().seasons as season (season.id)} - goto(base + '/dashboard/tv/' + show().id + '/' + season.id)} - > - {season.number} - - - - {season.name} - {season.overview} - - {/each} - {:else} - - No season data available. - - {/if} - - - - -
-
- - - Torrent Information - A list of all torrents associated with this show. - +
+
+ {#if show().id} + + {:else} +
+ +
+ {/if} +
+
+ + + Overview + + +

+ {show().overview} +

+
+
+
+
+ {#if user().is_superuser} + + + Administrator Controls + + + {#if !show().ended} +
+ continuousDownloadEnabled, toggle_continuous_download} + id="continuous-download-checkbox" + /> + +
+ {/if} + +
+
+ {/if} + + + Download Options + + + {#if user().is_superuser} + + {/if} + + + +
+
+
+ + + Season Details + + A list of all seasons for {getFullyQualifiedMediaName(show())}. + + + + + A list of all seasons. + + + Number + Exists on file + Title + Overview + + + + {#if show().seasons.length > 0} + {#each show().seasons as season (season.id)} + goto(base + '/dashboard/tv/' + show().id + '/' + season.id)} + > + {season.number} + + + + {season.name} + {season.overview} + + {/each} + {:else} + + No season data available. + + {/if} + + + + +
+
+ + + Torrent Information + A list of all torrents associated with this show. + - - - - -
+ + + +
+
diff --git a/web/src/routes/dashboard/tv/[showId=uuid]/[SeasonId=uuid]/+page.ts b/web/src/routes/dashboard/tv/[showId=uuid]/[SeasonId=uuid]/+page.ts index 41206cc..9ff5982 100644 --- a/web/src/routes/dashboard/tv/[showId=uuid]/[SeasonId=uuid]/+page.ts +++ b/web/src/routes/dashboard/tv/[showId=uuid]/[SeasonId=uuid]/+page.ts @@ -1,47 +1,28 @@ import { env } from '$env/dynamic/public'; import type { PageLoad } from './$types'; +import client from "$lib/api"; const apiUrl = env.PUBLIC_API_URL; export const load: PageLoad = async ({ fetch, params }) => { - const url = `${apiUrl}/tv/seasons/${params.SeasonId}/files`; - const url2 = `${apiUrl}/tv/seasons/${params.SeasonId}`; - - try { - console.log(`Fetching data from: ${url} and ${url2}`); - const response = await fetch(url, { - method: 'GET', - credentials: 'include' - }); - const response2 = await fetch(url2, { - method: 'GET', - credentials: 'include' - }); - - if (!response.ok) { - const errorText = await response.text(); - console.error(`API request failed with status ${response.status}: ${errorText}`); + const season = await client.GET('/api/v1/tv/seasons/{season_id}', { + fetch: fetch, + params: { + path: { + season_id: params.SeasonId + }, } - - if (!response2.ok) { - const errorText = await response.text(); - console.error(`API request failed with status ${response.status}: ${errorText}`); + }); + const seasonFiles = await client.GET('/api/v1/tv/seasons/{season_id}/files', { + fetch: fetch, + params: { + path: { + season_id: params.SeasonId + }, } - - const filesData = await response.json(); - const seasonData = await response2.json(); - console.log('received season_files data: ', filesData); - console.log('received season data: ', seasonData); - return { - files: filesData, - season: seasonData - }; - } catch (error) { - console.error('An error occurred while fetching TV show files:', error); - return { - error: `An unexpected error occurred: ${error instanceof Error ? error.message : 'Unknown error'}`, - files: [], - season: null - }; - } + }); + return { + files: seasonFiles.data, + season: season.data + }; }; diff --git a/web/src/routes/dashboard/tv/add-show/+page.svelte b/web/src/routes/dashboard/tv/add-show/+page.svelte index 3ba5ee8..83e65ad 100644 --- a/web/src/routes/dashboard/tv/add-show/+page.svelte +++ b/web/src/routes/dashboard/tv/add-show/+page.svelte @@ -1,155 +1,134 @@ - Add TV Show - MediaManager - + Add TV Show - MediaManager +
-
- - - - - - - -
+
+ + + + + + + +
-
-

- Add a Show -

-
- - -

Search for a Show to add.

-
-
- - -
-

Advanced Settings

- -
-
- - - -
- - -
-
- - -
-
-
-
-
-
- -
-
+
+

+ Add a Show +

+
+ + +

Search for a Show to add.

+
+
+ + +
+

Advanced Settings

+ +
+
+ + + +
+ + +
+
+ + +
+
+
+
+
+
+ +
+
- + - {#if results && results.length === 0} -

No Shows found.

- {:else if results} -
No Shows found. + {:else if data} +
- {#each results as result (result.external_id)} - - {/each} -
- {/if} + > + {#each data as dataItem (dataItem.external_id)} + + {/each} +
+ {/if}
diff --git a/web/src/routes/dashboard/tv/requests/+layout.ts b/web/src/routes/dashboard/tv/requests/+layout.ts index 761f297..56785e5 100644 --- a/web/src/routes/dashboard/tv/requests/+layout.ts +++ b/web/src/routes/dashboard/tv/requests/+layout.ts @@ -1,34 +1,11 @@ import { env } from '$env/dynamic/public'; import type { LayoutLoad } from './$types'; +import client from "$lib/api"; const apiUrl = env.PUBLIC_API_URL; export const load: LayoutLoad = async ({ fetch }) => { - try { - const requests = await fetch(`${apiUrl}/tv/seasons/requests`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - }, - credentials: 'include' - }); - - if (!requests.ok) { - console.error(`Failed to fetch season requests ${requests.statusText}`); - return { - requestsData: null - }; - } - - const requestsData = await requests.json(); - console.log('Fetched season requests:', requestsData); - - return { - requestsData: requestsData - }; - } catch (error) { - console.error('Error fetching season requests:', error); - return { - requestsData: null - }; - } + const { data, error } = await client.GET('/api/v1/tv/seasons/requests', { fetch: fetch }); + return { + requestsData: data + }; }; diff --git a/web/src/routes/dashboard/tv/torrents/+page.ts b/web/src/routes/dashboard/tv/torrents/+page.ts index 98fca73..5fcce98 100644 --- a/web/src/routes/dashboard/tv/torrents/+page.ts +++ b/web/src/routes/dashboard/tv/torrents/+page.ts @@ -1,12 +1,9 @@ import { env } from '$env/dynamic/public'; import type { PageLoad } from './$types'; +import client from "$lib/api"; -const apiUrl = env.PUBLIC_API_URL; export const load: PageLoad = async ({ fetch }) => { - const response = await fetch(apiUrl + '/tv/shows/torrents', { - method: 'GET', - credentials: 'include' - }); - return { shows: response.json() }; + const { data } = await client.GET('/api/v1/tv/shows/torrents', { fetch: fetch }); + return { shows: data }; }; diff --git a/web/src/routes/login/forgot-password/+page.svelte b/web/src/routes/login/forgot-password/+page.svelte index 8fc692f..7d99e36 100644 --- a/web/src/routes/login/forgot-password/+page.svelte +++ b/web/src/routes/login/forgot-password/+page.svelte @@ -1,128 +1,114 @@ - Forgot Password - MediaManager - + Forgot Password - MediaManager + - - Forgot Password - - {#if isSuccess} - We've sent a password reset link to your email address if a SMTP server is configured. Check - your inbox and follow the instructions to reset your password. If you didn't receive an - email, please contact an administrator, the reset link will be in the logs of MediaManager. - {:else} - Enter your email address and we'll send you a link to reset your password. - {/if} - - - - {#if isSuccess} -
-
-

- Password reset email sent successfully! -

-
-
-

Didn't receive the email? Check your spam folder or

- -
-
- {:else} -
-
- - -
- -
- {/if} - -
+ > + try again + +
+ + {:else} +
+
+ + +
+ +
+ {/if} +
+ Back to Login +
+ diff --git a/web/src/routes/login/reset-password/+page.svelte b/web/src/routes/login/reset-password/+page.svelte index d03699d..23fd874 100644 --- a/web/src/routes/login/reset-password/+page.svelte +++ b/web/src/routes/login/reset-password/+page.svelte @@ -1,129 +1,120 @@ - Reset Password - MediaManager - + Reset Password - MediaManager + - - Reset Password - Enter your new password below. - - -
-
- - -
-
- - -
- -
- -
+ + Reset Password + Enter your new password below. + + +
+
+ + +
+
+ + +
+ +
+ +