diff --git a/web/src/lib/components/layouts/user-page-layout.svelte b/web/src/lib/components/layouts/user-page-layout.svelte new file mode 100644 index 0000000000..3c02e9dcc9 --- /dev/null +++ b/web/src/lib/components/layouts/user-page-layout.svelte @@ -0,0 +1,47 @@ + + +
+ {#if !hideNavbar} + openFileUploadDialog()} + /> + {/if} + + +
+ +
+ + + +
+ {#if title} +
+

{title}

+ + +
+ +
+
+
+ {/if} + + +
+
+
diff --git a/web/src/lib/components/shared-components/navigation-bar/navigation-bar.svelte b/web/src/lib/components/shared-components/navigation-bar/navigation-bar.svelte index 67aadfc045..29f01a5aee 100644 --- a/web/src/lib/components/shared-components/navigation-bar/navigation-bar.svelte +++ b/web/src/lib/components/shared-components/navigation-bar/navigation-bar.svelte @@ -40,14 +40,14 @@
diff --git a/web/src/lib/components/shared-components/search-bar/search-bar.svelte b/web/src/lib/components/shared-components/search-bar/search-bar.svelte index fb9b53c425..13201fb887 100644 --- a/web/src/lib/components/shared-components/search-bar/search-bar.svelte +++ b/web/src/lib/components/shared-components/search-bar/search-bar.svelte @@ -25,7 +25,7 @@
(value = '')} on:submit|preventDefault={onSearch} diff --git a/web/src/routes/(user)/albums/+page.server.ts b/web/src/routes/(user)/albums/+page.server.ts index eb3b6f9b13..d138401487 100644 --- a/web/src/routes/(user)/albums/+page.server.ts +++ b/web/src/routes/(user)/albums/+page.server.ts @@ -1,14 +1,13 @@ +import { AppRoute } from '$lib/constants'; import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; -export const load = (async ({ parent, locals: { api } }) => { +export const load = (async ({ locals: { api, user } }) => { + if (!user) { + throw redirect(302, AppRoute.AUTH_LOGIN); + } + try { - const { user } = await parent(); - - if (!user) { - throw Error('User is not logged in'); - } - const { data: albums } = await api.albumApi.getAllAlbums(); return { @@ -19,6 +18,6 @@ export const load = (async ({ parent, locals: { api } }) => { } }; } catch (e) { - throw redirect(302, '/auth/login'); + throw redirect(302, AppRoute.AUTH_LOGIN); } }) satisfies PageServerLoad; diff --git a/web/src/routes/(user)/albums/+page.svelte b/web/src/routes/(user)/albums/+page.svelte index 4ff482c986..cf4385aa60 100644 --- a/web/src/routes/(user)/albums/+page.svelte +++ b/web/src/routes/(user)/albums/+page.svelte @@ -5,11 +5,10 @@ import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte'; import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte'; import type { PageData } from './$types'; - import NavigationBar from '$lib/components/shared-components/navigation-bar/navigation-bar.svelte'; - import SideBar from '$lib/components/shared-components/side-bar/side-bar.svelte'; import PlusBoxOutline from 'svelte-material-icons/PlusBoxOutline.svelte'; import { useAlbums } from './albums.bloc'; import empty1Url from '$lib/assets/empty-1.svg'; + import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte'; export let data: PageData; @@ -31,84 +30,57 @@ }; -
- -
- -
- - - - -
-
+
+ +
-
- -
-
+ +
+ {#each $albums as album} + {#key album.id} + + showAlbumContextMenu(e.detail, album)} + /> + + {/key} + {/each} +
-
-
-
+ + {#if $albums.length === 0} +
+ Empty shared album - -
- {#each $albums as album} - {#key album.id} - - showAlbumContextMenu(e.detail, album)} - /> - - {/key} - {/each} -
- - - {#if $albums.length === 0} -
- Empty shared album - -

- Create an album to organize your photos and videos -

-
- {/if} -
- - - - {#if $isShowContextMenu} - - - - -

Delete album

-
-
-
+

+ Create an album to organize your photos and videos +

+ {/if} - + + + +{#if $isShowContextMenu} + + + + +

Delete album

+
+
+
+{/if} diff --git a/web/src/routes/(user)/albums/[albumId]/+page.server.ts b/web/src/routes/(user)/albums/[albumId]/+page.server.ts index 4ab870f1a2..47a304ffa8 100644 --- a/web/src/routes/(user)/albums/[albumId]/+page.server.ts +++ b/web/src/routes/(user)/albums/[albumId]/+page.server.ts @@ -1,11 +1,10 @@ +import { AppRoute } from '$lib/constants'; import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; -export const load = (async ({ parent, params, locals: { api } }) => { - const { user } = await parent(); - +export const load = (async ({ params, locals: { api, user } }) => { if (!user) { - throw redirect(302, '/auth/login'); + throw redirect(302, AppRoute.AUTH_LOGIN); } const albumId = params['albumId']; @@ -19,6 +18,6 @@ export const load = (async ({ parent, params, locals: { api } }) => { } }; } catch (e) { - throw redirect(302, '/albums'); + throw redirect(302, AppRoute.ALBUMS); } }) satisfies PageServerLoad; diff --git a/web/src/routes/(user)/explore/+page.svelte b/web/src/routes/(user)/explore/+page.svelte index c9cf4a48b9..40af686ba4 100644 --- a/web/src/routes/(user)/explore/+page.svelte +++ b/web/src/routes/(user)/explore/+page.svelte @@ -1,7 +1,6 @@ -
- -
- -
- - -
-
- -
+ +
+ {#if places.length > 0} +
-

Explore

+

Places

-
- -
-
-
- -
- {#if places.length > 0} -
-
-

Places

-
-
- {#each places as item} - -
- -
- - {item.value} - -
- {/each} -
-
- {/if} - - {#if things.length > 0} -
-
-

Things

-
-
- {#each things as item} - -
- -
- - {item.value} - -
- {/each} -
-
- {/if} - -
- -
- -
-

CATEGORIES

-
- - - Videos - -
- - - Motion photos - +
+ {#each places as item} + +
+
-
+ + {item.value} + + + {/each} +
+
+ {/if} + + {#if things.length > 0} +
+
+

Things

+
+
+ {#each things as item} + +
+ +
+ + {item.value} + +
+ {/each} +
+
+ {/if} + +
+ +
+ + -
-
-
+ + + diff --git a/web/src/routes/(user)/favorites/+page.server.ts b/web/src/routes/(user)/favorites/+page.server.ts index a541983ce7..5ac8e27121 100644 --- a/web/src/routes/(user)/favorites/+page.server.ts +++ b/web/src/routes/(user)/favorites/+page.server.ts @@ -1,21 +1,16 @@ import type { PageServerLoad } from './$types'; -import { redirect, error } from '@sveltejs/kit'; +import { redirect } from '@sveltejs/kit'; +import { AppRoute } from '$lib/constants'; -export const load: PageServerLoad = async ({ parent }) => { - try { - const { user } = await parent(); - if (!user) { - throw error(400, 'Not logged in'); - } - - return { - user, - meta: { - title: 'Favorites' - } - }; - } catch (e) { - console.log('Photo page load error', e); - throw redirect(302, '/auth/login'); +export const load = (async ({ locals: { user } }) => { + if (!user) { + throw redirect(302, AppRoute.AUTH_LOGIN); } -}; + + return { + user, + meta: { + title: 'Favorites' + } + }; +}) satisfies PageServerLoad; diff --git a/web/src/routes/(user)/favorites/+page.svelte b/web/src/routes/(user)/favorites/+page.svelte index 9f97cfab5c..ae110ca27c 100644 --- a/web/src/routes/(user)/favorites/+page.svelte +++ b/web/src/routes/(user)/favorites/+page.svelte @@ -3,8 +3,6 @@ import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte'; import CreateSharedLinkModal from '$lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte'; import GalleryViewer from '$lib/components/shared-components/gallery-viewer/gallery-viewer.svelte'; - import NavigationBar from '$lib/components/shared-components/navigation-bar/navigation-bar.svelte'; - import SideBar from '$lib/components/shared-components/side-bar/side-bar.svelte'; import { handleError } from '$lib/utils/handle-error'; import { api, AssetResponseDto, SharedLinkType } from '@api'; import { onMount } from 'svelte'; @@ -12,15 +10,16 @@ import ShareVariantOutline from 'svelte-material-icons/ShareVariantOutline.svelte'; import StarMinusOutline from 'svelte-material-icons/StarMinusOutline.svelte'; import Error from '../../+error.svelte'; - import type { PageData } from './$types'; import empty1Url from '$lib/assets/empty-1.svg'; - - export let data: PageData; + import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte'; + import type { PageData } from './$types'; let favorites: AssetResponseDto[] = []; let isShowCreateSharedLinkModal = false; let selectedAssets: Set = new Set(); + export let data: PageData; + $: isMultiSelectionMode = selectedAssets.size > 0; onMount(async () => { @@ -61,81 +60,57 @@ }; -
- -
+ +{#if isMultiSelectionMode} + + +

+ Selected {selectedAssets.size} +

+
+ + + + +
+{/if} -
- + +{#if isShowCreateSharedLinkModal} + +{/if} - - {#if isMultiSelectionMode} - - -

- Selected {selectedAssets.size} + +

+ + {#if favorites.length === 0} +
+ Empty shared album + +

+ Add favorites to quickly find your best pictures and videos

- - - - - - - {/if} - - - {#if isShowCreateSharedLinkModal} - - {/if} - - -
-
-
-
-

Favorites

-
+ {/if} -
-
-
- - - {#if favorites.length === 0} -
- Empty shared album - -

- Add favorites to quickly find your best pictures and videos -

-
- {/if} - - -
+
-
+ diff --git a/web/src/routes/(user)/photos/+page.server.ts b/web/src/routes/(user)/photos/+page.server.ts index 726bcc8ef7..db2e0b5391 100644 --- a/web/src/routes/(user)/photos/+page.server.ts +++ b/web/src/routes/(user)/photos/+page.server.ts @@ -1,21 +1,16 @@ import type { PageServerLoad } from './$types'; -import { redirect, error } from '@sveltejs/kit'; +import { redirect } from '@sveltejs/kit'; +import { AppRoute } from '$lib/constants'; -export const load: PageServerLoad = async ({ parent }) => { - try { - const { user } = await parent(); - if (!user) { - throw error(400, 'Not logged in'); - } - - return { - user, - meta: { - title: 'Photos' - } - }; - } catch (e) { - console.log('Photo page load error', e); - throw redirect(302, '/auth/login'); +export const load = (async ({ locals: { user } }) => { + if (!user) { + throw redirect(302, AppRoute.AUTH_LOGIN); } -}; + + return { + user, + meta: { + title: 'Photos' + } + }; +}) satisfies PageServerLoad; diff --git a/web/src/routes/(user)/photos/+page.svelte b/web/src/routes/(user)/photos/+page.svelte index d19ac96ca5..fd46a69430 100644 --- a/web/src/routes/(user)/photos/+page.svelte +++ b/web/src/routes/(user)/photos/+page.svelte @@ -7,12 +7,10 @@ import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte'; import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte'; import CreateSharedLinkModal from '$lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte'; - import NavigationBar from '$lib/components/shared-components/navigation-bar/navigation-bar.svelte'; import { notificationController, NotificationType } from '$lib/components/shared-components/notification/notification'; - import SideBar from '$lib/components/shared-components/side-bar/side-bar.svelte'; import { assetInteractionStore, isMultiSelectStoreState, @@ -20,17 +18,18 @@ } from '$lib/stores/asset-interaction.store'; import { assetStore } from '$lib/stores/assets.store'; import { addAssetsToAlbum, bulkDownload } from '$lib/utils/asset-utils'; - import { openFileUploadDialog } from '$lib/utils/file-uploader'; import { AlbumResponseDto, api, SharedLinkType } from '@api'; import Close from 'svelte-material-icons/Close.svelte'; import CloudDownloadOutline from 'svelte-material-icons/CloudDownloadOutline.svelte'; import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte'; import Plus from 'svelte-material-icons/Plus.svelte'; import ShareVariantOutline from 'svelte-material-icons/ShareVariantOutline.svelte'; - import type { PageData } from './$types'; import { locale } from '$lib/stores/preferences.store'; + import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte'; + import type { PageData } from './$types'; export let data: PageData; + let isShowCreateSharedLinkModal = false; const deleteSelectedAssetHandler = async () => { try { @@ -144,73 +143,68 @@ }; -
- {#if $isMultiSelectStoreState} - assetInteractionStore.clearMultiselect()} - backIcon={Close} - tailwindClasses={'bg-white shadow-md'} - > - -

- Selected {$selectedAssets.size.toLocaleString($locale)} -

-
- - - - - - -
- {:else} - openFileUploadDialog()} /> - {/if} + + + {#if $isMultiSelectStoreState} + assetInteractionStore.clearMultiselect()} + backIcon={Close} + tailwindClasses={'bg-white shadow-md'} + > + +

+ Selected {$selectedAssets.size.toLocaleString($locale)} +

+
+ + + + + + +
+ {/if} - {#if isShowAddMenu} - (isShowAddMenu = false)}> -
- - handleShowAlbumPicker(false)} text="Add to Album" /> - handleShowAlbumPicker(true)} text="Add to Shared Album" /> -
-
- {/if} + {#if isShowAddMenu} + (isShowAddMenu = false)}> +
+ + handleShowAlbumPicker(false)} text="Add to Album" /> + handleShowAlbumPicker(true)} text="Add to Shared Album" /> +
+
+ {/if} - {#if isShowAlbumPicker} - (isShowAlbumPicker = false)} - /> - {/if} + {#if isShowAlbumPicker} + (isShowAlbumPicker = false)} + /> + {/if} - {#if isShowCreateSharedLinkModal} - - {/if} -
+ {#if isShowCreateSharedLinkModal} + + {/if} +
-
- - -
+ + diff --git a/web/src/routes/(user)/share/[key]/+page.server.ts b/web/src/routes/(user)/share/[key]/+page.server.ts index 3db0b8740d..4948ccb49f 100644 --- a/web/src/routes/(user)/share/[key]/+page.server.ts +++ b/web/src/routes/(user)/share/[key]/+page.server.ts @@ -1,14 +1,10 @@ -export const prerender = false; import { error } from '@sveltejs/kit'; - import { getThumbnailUrl } from '$lib/utils/asset-utils'; import { ThumbnailFormat } from '@api'; import type { PageServerLoad } from './$types'; import featurePanelUrl from '$lib/assets/feature-panel.png'; -export const load: PageServerLoad = async ({ params, parent, locals: { api } }) => { - const { user } = await parent(); - +export const load = (async ({ params, locals: { api } }) => { const { key } = params; try { @@ -25,12 +21,11 @@ export const load: PageServerLoad = async ({ params, parent, locals: { api } }) imageUrl: assetId ? getThumbnailUrl(assetId, ThumbnailFormat.Webp, sharedLink.key) : featurePanelUrl - }, - user + } }; } catch (e) { throw error(404, { message: 'Invalid shared link' }); } -}; +}) satisfies PageServerLoad; diff --git a/web/src/routes/(user)/sharing/+page.server.ts b/web/src/routes/(user)/sharing/+page.server.ts index 837a39f550..f52be4ba99 100644 --- a/web/src/routes/(user)/sharing/+page.server.ts +++ b/web/src/routes/(user)/sharing/+page.server.ts @@ -1,25 +1,23 @@ -export const prerender = false; - +import { AppRoute } from '$lib/constants'; import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; -export const load = (async ({ parent, locals: { api } }) => { - try { - const { user } = await parent(); - if (!user) { - throw redirect(302, '/auth/login'); - } +export const load = (async ({ locals: { api, user } }) => { + if (!user) { + throw redirect(302, AppRoute.AUTH_LOGIN); + } + try { const { data: sharedAlbums } = await api.albumApi.getAllAlbums(true); return { - user: user, + user, sharedAlbums, meta: { title: 'Albums' } }; } catch (e) { - throw redirect(302, '/auth/login'); + throw redirect(302, AppRoute.AUTH_LOGIN); } }) satisfies PageServerLoad; diff --git a/web/src/routes/(user)/sharing/+page.svelte b/web/src/routes/(user)/sharing/+page.svelte index f4c4a3c0f0..d84848a2e9 100644 --- a/web/src/routes/(user)/sharing/+page.svelte +++ b/web/src/routes/(user)/sharing/+page.svelte @@ -1,9 +1,6 @@ -
- -
- -
- - -
-
+
+ -
- + +
- -
+
+ +
+ {#each data.sharedAlbums as album} + + + + {/each} +
+ + + {#if data.sharedAlbums.length === 0} +
+ Empty shared album +

+ Create a shared album to share photos and videos with people in your network +

- -
-
-
- - -
- {#each data.sharedAlbums as album} - - - - {/each} -
- - - {#if data.sharedAlbums.length === 0} -
- Empty shared album -

- Create a shared album to share photos and videos with people in your network -

-
- {/if} -
+ {/if}
-
+ diff --git a/web/src/routes/(user)/sharing/sharedlinks/+page.server.ts b/web/src/routes/(user)/sharing/sharedlinks/+page.server.ts index 7eec887b52..ec3d8ee664 100644 --- a/web/src/routes/(user)/sharing/sharedlinks/+page.server.ts +++ b/web/src/routes/(user)/sharing/sharedlinks/+page.server.ts @@ -1,21 +1,16 @@ +import { AppRoute } from '$lib/constants'; import { redirect } from '@sveltejs/kit'; -export const prerender = false; import type { PageServerLoad } from './$types'; -export const load: PageServerLoad = async ({ parent }) => { - try { - const { user } = await parent(); - if (!user) { - throw redirect(302, '/auth/login'); - } - - return { - user, - meta: { - title: 'Shared Links' - } - }; - } catch (e) { - throw redirect(302, '/auth/login'); +export const load = (async ({ locals: { user } }) => { + if (!user) { + throw redirect(302, AppRoute.AUTH_LOGIN); } -}; + + return { + user, + meta: { + title: 'Shared Links' + } + }; +}) satisfies PageServerLoad; diff --git a/web/src/routes/(user)/user-settings/+page.server.ts b/web/src/routes/(user)/user-settings/+page.server.ts index 0ddbe346d9..80784c7b84 100644 --- a/web/src/routes/(user)/user-settings/+page.server.ts +++ b/web/src/routes/(user)/user-settings/+page.server.ts @@ -1,21 +1,16 @@ +import { AppRoute } from '$lib/constants'; import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; -export const load: PageServerLoad = async ({ parent }) => { - try { - const { user } = await parent(); - - if (!user) { - throw Error('User is not logged in'); - } - - return { - user, - meta: { - title: 'Settings' - } - }; - } catch (e) { - throw redirect(302, '/auth/login'); +export const load = (async ({ locals: { user } }) => { + if (!user) { + throw redirect(302, AppRoute.AUTH_LOGIN); } -}; + + return { + user, + meta: { + title: 'Settings' + } + }; +}) satisfies PageServerLoad; diff --git a/web/src/routes/(user)/user-settings/+page.svelte b/web/src/routes/(user)/user-settings/+page.svelte index ca91e85651..0cc87046f2 100644 --- a/web/src/routes/(user)/user-settings/+page.svelte +++ b/web/src/routes/(user)/user-settings/+page.svelte @@ -1,36 +1,15 @@ -
- -
- -
- - -
-
-

- User Settings -

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