Skip to content

Commit

Permalink
feat: next.immich.app
Browse files Browse the repository at this point in the history
  • Loading branch information
jrasm91 committed Jan 18, 2025
1 parent d830164 commit 299b573
Show file tree
Hide file tree
Showing 40 changed files with 14,316 additions and 15 deletions.
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
IMMICH_APP=docs.immich.app
PUBLIC_IMMICH_PAY_HOST=https://futopay-test.azurewebsites.net
PUBLIC_IMMICH_API_HOST=http://localhost:8080
# PUBLIC_IMMICH_API_HOST=https://api.immich.app
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
app_name: ['my', 'buy', 'get']
app_name: ['my', 'buy', 'get', 'next']

steps:
- name: Checkout code
Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
fail-fast: false
max-parallel: 1
matrix:
app_name: ['my', 'buy', 'get']
app_name: ['my', 'buy', 'get', 'next']
env:
TF_VAR_app_name: ${{ matrix.app_name }}
TF_VAR_stage: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || '' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/destroy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
max-parallel: 1
matrix:
environment: ['dev', 'prod']
name: ['my', 'buy', 'get']
name: ['my', 'buy', 'get', 'next']
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
app_name: [my, buy, get]
app_name: [my, buy, get, next]

steps:
- name: Checkout code
Expand Down
32 changes: 32 additions & 0 deletions apps/next.immich.app/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script lang="ts">
import { afterNavigate, beforeNavigate } from '$app/navigation';
import { page } from '$app/state';
import '$lib/app.css';
import { onMount, type Snippet } from 'svelte';
interface Props {
children?: Snippet;
}
let { children }: Props = $props();
let pathname = '';
onMount(() => {
pathname = page.url.pathname;
});
beforeNavigate(() => {
const newPathname = $state.snapshot(page.url.pathname);
pathname = newPathname;
});
afterNavigate(() => {
const newPathname = $state.snapshot(page.url.pathname);
if (pathname === newPathname) {
return;
}
window.scrollTo({ top: 0, behavior: 'auto' });
});
</script>

{@render children?.()}
62 changes: 62 additions & 0 deletions apps/next.immich.app/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script lang="ts">
import qrCode from '$lib/assets/img/app-qr-code-dark.svg';
import screenshot from '$lib/assets/img/screenshot-dark.webp';
import DocsHeader from '$lib/components/DocsHeader.svelte';
import PageContent from '$lib/components/PageContent.svelte';
import {
AppShell,
AppShellHeader,
appStoreBadge,
Button,
Heading,
HStack,
Icon,
Logo,
playStoreBadge,
Text,
VStack,
} from '@immich/ui';
import { mdiOpenInNew } from '@mdi/js';
</script>

<AppShell>
<AppShellHeader>
<DocsHeader />
</AppShellHeader>

<PageContent class="mx-auto max-w-screen-lg">
<VStack gap={8} class="p-8 text-center">
<Logo size="giant" variant="logo" class="border" />
<Heading size="title"
>Self-hosted <span class="text-primary">photo and<br /> video management</span> solution</Heading
>
<Text
>Easily back up, organize, and manage your photos on your own server. Immich helps you<br /> browse, search and organize
your photos and videos with ease, without sacrificing your privacy.</Text
>
<HStack>
<Button size="large" href="/download">Download</Button>
<Button size="large" href="https://demo.immich.app/" color="secondary">
<span>Open Demo</span>
<Icon icon={mdiOpenInNew} />
</Button>
</HStack>
<Button size="large" variant="ghost">Join our Discord</Button>

<img src={screenshot} alt="Immich application" />

<hr class="border-t w-full max-w-screen-sm m-8" />
<Heading size="title">Download mobile app</Heading>
<Text>Download Immich app and start backing up your photos and videos securely to your own server</Text>
<HStack gap={0}>
<Button href="" variant="ghost" class="p-0">
<img src={playStoreBadge} alt="Playstore Badge" class="h-24" />
</Button>
<Button href="" variant="ghost" class="p-0">
<img src={appStoreBadge} alt="Playstore Badge" class="h-24 p-4" />
</Button>
</HStack>
<img src={qrCode} alt="QRCode" class="h-36" />
</VStack>
</PageContent>
</AppShell>
18 changes: 18 additions & 0 deletions apps/next.immich.app/routes/about/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script lang="ts">
import DocsHeader from '$lib/components/DocsHeader.svelte';
import PageContent from '$lib/components/PageContent.svelte';
import { AppShell, AppShellHeader, Heading, Stack, Text } from '@immich/ui';
</script>

<AppShell>
<AppShellHeader>
<DocsHeader />
</AppShellHeader>

<PageContent class="mx-auto max-w-screen-lg">
<Stack>
<Heading size="title">About</Heading>
<Text>Meet the team</Text>
</Stack>
</PageContent>
</AppShell>
6 changes: 6 additions & 0 deletions apps/next.immich.app/routes/api/+layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { loadOpenApi } from '$lib/services/open-api.svelte';
import type { LayoutLoad } from '../$types';

export const load = (async ({ fetch }) => {
await loadOpenApi(fetch);
}) satisfies LayoutLoad;
52 changes: 52 additions & 0 deletions apps/next.immich.app/routes/api/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script lang="ts">
import '$lib/app.css';
import DocsLayout from '$lib/layouts/DocsLayout.svelte';
import { Code, Heading, Link, Text } from '@immich/ui';
</script>

<DocsLayout>
<Heading size="large">Welcome</Heading>
<Text>This is documentation for the API that powers <Link href="https://immich.app">Immich</Link></Text>

<section class="mt-4">
<Heading size="small">Getting Started</Heading>
<Text>To get started, first create an <Link href="#">Api Key</Link></Text>
</section>

<section class="mt-4">
<Heading size="small">Authentication</Heading>
<Text>Users or applications can authenticate with the Immich Api using one of the methods listed below.</Text>

<Heading size="tiny">Session Token</Heading>

<Heading size="tiny">Api Key</Heading>
<Text
>Create an Api Key <Link href="#">here</Link> and then use it in http requests with the <Code
>x-api-key: {'<value>'}</Code
> header.</Text
>
<Text>For example,</Text>
</section>

<section class="mt-4">
<Heading size="small">Open API</Heading>
<Text
>Immich uses the <Code>nest-swagger</Code> library to automatically generate a Open API compatible JSON document. This
document is used to generate this documentation, as well as the <Code>@immich/sdk</Code> TypeScript client sdk</Text
>
</section>

<section class="mt-4">
<Heading size="small">SDK</Heading>
<Text
>For more information about the <Code>@immich/sdk</Code> package, see the <Link
href="https://www.npmjs.com/package/@immich/sdk">project on npm</Link
></Text
>
</section>

<section class="mt-4">
<Heading size="small">SDK</Heading>
<Text>Immich</Text>
</section>
</DocsLayout>
78 changes: 78 additions & 0 deletions apps/next.immich.app/routes/api/endpoints/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<script lang="ts">
import DocsHeader from '$lib/components/DocsHeader.svelte';
import PageContent from '$lib/components/PageContent.svelte';
import { getOpenApi } from '$lib/services/open-api.svelte';
import { AppShell, AppShellHeader, AppShellSidebar, Button, Icon, NavbarGroup, NavbarItem } from '@immich/ui';
import {
mdiAccountMultipleOutline,
mdiAccountOutline,
mdiArrowLeft,
mdiCodeJson,
mdiCommentOutline,
mdiDownloadOutline,
mdiFaceMan,
mdiImageAlbum,
mdiKeyOutline,
mdiLibraryOutline,
mdiListBoxOutline,
mdiLogin,
mdiMagnify,
mdiMap,
mdiMovieRoll,
mdiServerOutline,
} from '@mdi/js';
import type { Snippet } from 'svelte';
type Props = {
children?: Snippet;
};
const { children }: Props = $props();
const { tags } = getOpenApi();
const icons: Record<string, string> = {
'API Keys': mdiKeyOutline,
Activities: mdiCommentOutline,
Authentication: mdiLogin,
Albums: mdiImageAlbum,
Libraries: mdiLibraryOutline,
Download: mdiDownloadOutline,
Faces: mdiFaceMan,
Jobs: mdiListBoxOutline,
Map: mdiMap,
Memories: mdiMovieRoll,
People: mdiAccountOutline,
Partners: mdiAccountMultipleOutline,
Search: mdiMagnify,
Server: mdiServerOutline,
};
</script>

<AppShell>
<AppShellHeader>
<DocsHeader />
</AppShellHeader>

<AppShellSidebar class="min-w-[300px]">
<Button
variant="ghost"
color="secondary"
href="/api"
shape="rectangle"
class="flex justify-start py-4"
size="small"
>
<Icon icon={mdiArrowLeft} />
Back
</Button>
<NavbarGroup title="Endpoints" />
{#each tags as tag}
<NavbarItem title={tag.name} href={tag.href} icon={icons[tag.name] ?? mdiCodeJson} variant="compact" />
{/each}
</AppShellSidebar>

<PageContent>
{@render children?.()}
</PageContent>
</AppShell>
31 changes: 31 additions & 0 deletions apps/next.immich.app/routes/api/endpoints/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script lang="ts">
import { getOpenApi, getTagEndpointHref } from '$lib/services/open-api.svelte';
import { Card, CardBody, CardHeader, CardTitle, Heading, Link, Stack } from '@immich/ui';
const { tags } = getOpenApi();
</script>

<Stack gap={8}>
<Heading size="large">API Endpoints</Heading>

<div class="grid grid-cols-1 lg:grid-cols-3 gap-2">
{#each tags as tag}
<Card color="secondary">
<CardHeader>
<CardTitle>
<Link href={tag.href}>{tag.name}</Link>
</CardTitle>
</CardHeader>
<CardBody>
<Stack gap={1}>
{#each tag.endpoints as endpoint}
<Link href={getTagEndpointHref(tag, endpoint)} class="no-underline hover:underline"
>{endpoint.method} {endpoint.route}</Link
>
{/each}
</Stack>
</CardBody>
</Card>
{/each}
</div>
</Stack>
Loading

0 comments on commit 299b573

Please sign in to comment.