mirror of
https://github.com/immich-app/data.immich.app.git
synced 2026-09-30 13:23:26 +08:00
feat: SSR, metadata, and more (#199)
This commit is contained in:
Generated
+6
-19
@@ -8,7 +8,7 @@
|
||||
"name": "data.immich.app",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@immich/ui": "^0.35.0",
|
||||
"@immich/ui": "^0.36.0",
|
||||
"@mdi/js": "^7.4.47",
|
||||
"luxon": "^3.5.0",
|
||||
"simple-icons": "^15.11.0",
|
||||
@@ -707,9 +707,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@immich/ui": {
|
||||
"version": "0.35.0",
|
||||
"resolved": "https://registry.npmjs.org/@immich/ui/-/ui-0.35.0.tgz",
|
||||
"integrity": "sha512-dyjYLzJUNzR1aIQZEqPwfHutjuvK5t3wy3pp19Vm5bcQ4ira4Gk75flCgd9oEON5mlaxtlaUJVMeNor66bK9pg==",
|
||||
"version": "0.36.0",
|
||||
"resolved": "https://registry.npmjs.org/@immich/ui/-/ui-0.36.0.tgz",
|
||||
"integrity": "sha512-9Ucj2hvMtPgXDIcfCyZPDDs5F49ooueUiPn/sJyppo+xKPEFjMdwYlebPM5nv7rbQ8VFIviWRIWOPV4cPKTy8g==",
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"dependencies": {
|
||||
"@mdi/js": "^7.4.47",
|
||||
@@ -1162,7 +1162,6 @@
|
||||
"integrity": "sha512-J1fd80WokLzIm6EAV7z7C2+/C02qVAX645LZomARARTRJkbbJSY1Jln3wtBZYibUB8c9/5Z6xqLAV39VdbtWCQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@standard-schema/spec": "^1.0.0",
|
||||
"@sveltejs/acorn-typescript": "^1.0.5",
|
||||
@@ -1202,7 +1201,6 @@
|
||||
"integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@sveltejs/vite-plugin-svelte-inspector": "^5.0.0",
|
||||
"debug": "^4.4.1",
|
||||
@@ -1241,6 +1239,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
|
||||
"integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
@@ -1640,7 +1639,6 @@
|
||||
"integrity": "sha512-anNG/V/Efn/YZY4pRzbACnKxNKoBng2VTFydVu8RRs5hQjikP8CQfaeAV59VFSCzKNp90mXiVXW2QzV56rwMrg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
@@ -1691,7 +1689,6 @@
|
||||
"integrity": "sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.46.0",
|
||||
"@typescript-eslint/types": "8.46.0",
|
||||
@@ -2024,7 +2021,6 @@
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -2452,7 +2448,6 @@
|
||||
"integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@@ -3586,7 +3581,6 @@
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -3614,7 +3608,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
@@ -3745,7 +3738,6 @@
|
||||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
@@ -4073,7 +4065,6 @@
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.39.11.tgz",
|
||||
"integrity": "sha512-8MxWVm2+3YwrFbPaxOlT1bbMi6OTenrAgks6soZfiaS8Fptk4EVyRIFhJc3RpO264EeSNwgjWAdki0ufg4zkGw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/remapping": "^2.3.4",
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||
@@ -4203,7 +4194,6 @@
|
||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz",
|
||||
"integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/dcastil"
|
||||
@@ -4232,8 +4222,7 @@
|
||||
"version": "4.1.14",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz",
|
||||
"integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tapable": {
|
||||
"version": "2.2.2",
|
||||
@@ -4380,7 +4369,6 @@
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -4448,7 +4436,6 @@
|
||||
"integrity": "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.5.0",
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@immich/ui": "^0.35.0",
|
||||
"@immich/ui": "^0.36.0",
|
||||
"@mdi/js": "^7.4.47",
|
||||
"luxon": "^3.5.0",
|
||||
"simple-icons": "^15.11.0",
|
||||
|
||||
+34
-2
@@ -1,13 +1,45 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html lang="en" class="dark">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Immich - Data</title>
|
||||
<meta name="theme-color" content="currentColor" />
|
||||
<meta name="description" content="Graphs and charts for data around Immich" />
|
||||
%sveltekit.head%
|
||||
<style>
|
||||
/* prevent FOUC */
|
||||
html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
/**
|
||||
* Prevent FOUC on page load.
|
||||
*/
|
||||
const THEME_KEY = 'immich-ui-theme';
|
||||
let value;
|
||||
try {
|
||||
value = JSON.parse(localStorage.getItem(THEME_KEY)).value;
|
||||
if (value !== 'light' && value !== 'dark') {
|
||||
value = undefined;
|
||||
}
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
|
||||
if (value === 'light') {
|
||||
document.documentElement.classList.remove('dark');
|
||||
document.documentElement.classList.add('light');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover" class="bg-light text-dark">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<script lang="ts">
|
||||
import { Card, CardBody, CardHeader, CardTitle, Link, Text } from '@immich/ui';
|
||||
import { DateTime } from 'luxon';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
href: string;
|
||||
date: DateTime | Snippet;
|
||||
};
|
||||
|
||||
const { title, href, date }: Props = $props();
|
||||
</script>
|
||||
|
||||
<Card color="secondary">
|
||||
<CardHeader class="text-center">
|
||||
<CardTitle>
|
||||
<Link {href}>{title}</Link>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div class="flex justify-around align-middle h-full">
|
||||
<div class="text-center flex flex-col justify-between align-middle">
|
||||
{#if typeof date === 'function'}
|
||||
{@render date()}
|
||||
{:else}
|
||||
<Text class="text-4xl">{date.toRelative()}</Text>
|
||||
<Text color="muted">{date.toLocaleString(DateTime.DATE_FULL)}</Text>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
+1
-1
@@ -64,7 +64,7 @@
|
||||
id,
|
||||
padding: [8, 8, 8, 8],
|
||||
cursor: cursorOpts,
|
||||
width: 500,
|
||||
width: 200,
|
||||
height: 300,
|
||||
scales: {},
|
||||
legend: {
|
||||
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { Card, CardBody, CardHeader, CardTitle, HStack, Icon, type IconLike } from '@immich/ui';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
icon: IconLike;
|
||||
children: Snippet;
|
||||
};
|
||||
|
||||
const { title, icon, children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<Card color="secondary">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<HStack>
|
||||
<Icon {icon} />
|
||||
<span>{title}</span>
|
||||
</HStack>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
{@render children()}
|
||||
</CardBody>
|
||||
</Card>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
children: Snippet;
|
||||
};
|
||||
|
||||
const { children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-4">{@render children()}</div>
|
||||
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { Heading, Text, Link } from '@immich/ui';
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
link: {
|
||||
title: string;
|
||||
href: string;
|
||||
};
|
||||
};
|
||||
|
||||
const { title, link }: Props = $props();
|
||||
</script>
|
||||
|
||||
<Heading size="large" tag="h1">{title}</Heading>
|
||||
<Text color="muted" class="mb-4">
|
||||
<Link href={link.href} underline={false}>{link.title}</Link>
|
||||
</Text>
|
||||
@@ -1 +1,8 @@
|
||||
// place files you want to import through the `$lib` alias in this folder.
|
||||
import type { Metadata } from '@immich/ui';
|
||||
|
||||
export const siteMetadata: Metadata = {
|
||||
title: 'Immich Data',
|
||||
description:
|
||||
'Interesting data about the growth of Immich, the open-source self-hosted photo and video management solution.',
|
||||
imageUrl: '/img/social-preview.png',
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ export const githubPullRequests = $state<{ value?: DataRecord[] }>({});
|
||||
export const githubDiscussions = $state<{ value?: DataRecord[] }>({});
|
||||
export const githubMergedPullRequests = $state<{ value?: DataRecord[] }>({});
|
||||
|
||||
export const loadGithubData = async () => {
|
||||
const loadGithubData = async () => {
|
||||
const response = await fetch('/api/github');
|
||||
if (response.ok) {
|
||||
const { stars, issues, pullRequests, discussions, mergedPullRequests } =
|
||||
@@ -45,7 +45,7 @@ export const discordOnline = $state<{ value?: DataRecord[] }>({});
|
||||
export const discordNitro = $state<{ value?: DataRecord[] }>({});
|
||||
export const discordServerTier = $state<{ value?: DataRecord[] }>({});
|
||||
|
||||
export const loadRedditData = async () => {
|
||||
const loadRedditData = async () => {
|
||||
const response = await fetch('/api/reddit');
|
||||
if (response.ok) {
|
||||
const { subscribers } = (await response.json()) as RedditDataResponse;
|
||||
@@ -53,7 +53,7 @@ export const loadRedditData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
export const loadDiscordData = async () => {
|
||||
const loadDiscordData = async () => {
|
||||
const response = await fetch('/api/discord');
|
||||
if (response.ok) {
|
||||
const { members, online, nitro, serverTier } = (await response.json()) as DiscordDataResponse;
|
||||
@@ -63,3 +63,9 @@ export const loadDiscordData = async () => {
|
||||
discordServerTier.value = serverTier;
|
||||
}
|
||||
};
|
||||
|
||||
export const load = () => {
|
||||
void loadGithubData();
|
||||
void loadRedditData();
|
||||
void loadDiscordData();
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
let { children }: Props = $props();
|
||||
|
||||
initializeTheme();
|
||||
initializeTheme({ selector: 'html', lightClass: 'light', darkClass: 'dark' });
|
||||
|
||||
console.log(`Backend URL: ${backendUrl}`);
|
||||
</script>
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const ssr = false;
|
||||
export const prerender = true;
|
||||
|
||||
@@ -1,33 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { siteMetadata } from '$lib';
|
||||
import '$lib/app.css';
|
||||
import GithubGraph from '$lib/components/graphs/github-graph.svelte';
|
||||
import DateCard from '$lib/components/DateCard.svelte';
|
||||
import GraphCard from '$lib/components/GraphCard.svelte';
|
||||
import Graph from '$lib/components/Graph.svelte';
|
||||
import SectionGrid from '$lib/components/SectionGrid.svelte';
|
||||
import SectionTitle from '$lib/components/SectionTitle.svelte';
|
||||
import {
|
||||
discordMembers,
|
||||
githubDiscussions,
|
||||
githubIssues,
|
||||
githubMergedPullRequests,
|
||||
githubPullRequests,
|
||||
githubStars,
|
||||
githubMergedPullRequests,
|
||||
loadGithubData,
|
||||
loadRedditData,
|
||||
load,
|
||||
redditMembers,
|
||||
loadDiscordData,
|
||||
discordMembers,
|
||||
} from '$lib/services/api.svelte';
|
||||
import {
|
||||
Card,
|
||||
CardBody,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
Container,
|
||||
Heading,
|
||||
HStack,
|
||||
Icon,
|
||||
Link,
|
||||
Stack,
|
||||
Text,
|
||||
} from '@immich/ui';
|
||||
import { Constants, Container, Heading, SiteMetadata, Text } from '@immich/ui';
|
||||
import { mdiAccountGroup, mdiBugOutline, mdiMessageOutline, mdiSourceBranch, mdiStarOutline } from '@mdi/js';
|
||||
import { DateTime } from 'luxon';
|
||||
import { onMount } from 'svelte';
|
||||
import uPlot from 'uplot';
|
||||
import 'uplot/dist/uPlot.min.css';
|
||||
|
||||
@@ -42,206 +34,97 @@
|
||||
},
|
||||
};
|
||||
|
||||
const commit = DateTime.fromISO('2022-02-03T15:56:28.000Z', { zone: 'America/Chicago' });
|
||||
const futo = DateTime.fromObject({ year: 2024, month: 5, day: 1 }, { zone: 'America/Chicago' });
|
||||
onMount(() => {
|
||||
load();
|
||||
});
|
||||
|
||||
void loadGithubData();
|
||||
void loadRedditData();
|
||||
void loadDiscordData();
|
||||
const milestones = [
|
||||
{
|
||||
title: '1st Commit',
|
||||
href: 'https://github.com/immich-app/immich/commit/af2efbdbbddc27cd06142f22253ccbbbbeec1f55',
|
||||
date: DateTime.fromISO('2022-02-03T15:56:28.000Z', { zone: 'America/Chicago' }),
|
||||
},
|
||||
{
|
||||
title: 'Joined FUTO',
|
||||
href: 'https://immich.app/blog/2024/immich-core-team-goes-fulltime',
|
||||
date: DateTime.fromObject({ year: 2024, month: 5, day: 1 }, { zone: 'America/Chicago' }),
|
||||
},
|
||||
{
|
||||
title: 'Stable Release',
|
||||
href: 'https://immich.app/blog/stable-release',
|
||||
date: DateTime.fromObject({ year: 2025, month: 10, day: 1 }, { zone: 'America/Chicago' }),
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<SiteMetadata site={siteMetadata} />
|
||||
|
||||
<Container size="giant" center>
|
||||
<Stack gap={8}>
|
||||
<Heading size="title">Immich Data</Heading>
|
||||
<Heading size="giant" class="mb-1">{siteMetadata.title}</Heading>
|
||||
<Text color="muted" class="mb-8">{siteMetadata.description}</Text>
|
||||
|
||||
<section class="flex flex-col gap-4">
|
||||
<Heading size="large" tag="h1">Statistics</Heading>
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-3">
|
||||
<Card color="secondary">
|
||||
<CardHeader class="text-center">
|
||||
<CardTitle>
|
||||
<Link href="https://github.com/immich-app/immich/commit/af2efbdbbddc27cd06142f22253ccbbbbeec1f55"
|
||||
>1st Commit</Link
|
||||
>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div class="flex justify-around align-middle h-full">
|
||||
<div class="text-center flex flex-col justify-between align-middle">
|
||||
<Text class="text-4xl">{commit.toRelative()}</Text>
|
||||
<Text color="muted">{commit.toLocaleString(DateTime.DATETIME_MED)}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card color="secondary">
|
||||
<CardHeader class="text-center">
|
||||
<CardTitle>
|
||||
<Link href="https://immich.app/blog/2024/immich-core-team-goes-fulltime">Joined FUTO</Link>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div class="flex justify-around align-middle h-full">
|
||||
<div class="text-center flex flex-col justify-between align-middle">
|
||||
<Text class="text-4xl">{futo.toRelative()}</Text>
|
||||
<Text color="muted">{futo.toLocaleString(DateTime.DATE_FULL)}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card color="secondary">
|
||||
<CardHeader class="text-center">
|
||||
<CardTitle>Last timezone issue</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div class="flex justify-around align-middle h-full">
|
||||
<div class="text-center flex flex-col justify-between align-middle">
|
||||
<Text class="text-6xl">-1</Text>
|
||||
<Text color="muted">days ago</Text>
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
<SectionTitle title="Milestones" link={{ title: 'Important dates for Immich', href: Constants.Pages.Roadmap }} />
|
||||
<div class="grid grid-cols-1 md:gric-cols-2 lg:grid-cols-4 gap-4 mb-4">
|
||||
{#each milestones as milestone (milestone.title)}
|
||||
<DateCard title={milestone.title} href={milestone.href} date={milestone.date} />
|
||||
{/each}
|
||||
<DateCard title="Last timezone issue" href={Constants.Pages.CursedKnowledge}>
|
||||
{#snippet date()}
|
||||
<Text class="text-4xl">-1</Text>
|
||||
<Text color="muted">days ago</Text>
|
||||
{/snippet}
|
||||
</DateCard>
|
||||
</div>
|
||||
|
||||
<section class="flex flex-col gap-4">
|
||||
<div>
|
||||
<Heading size="large" tag="h1">GitHub</Heading>
|
||||
<Text color="muted">immich-app/immich</Text>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<Card color="secondary">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<HStack>
|
||||
<Icon icon={mdiStarOutline} />
|
||||
Stars
|
||||
</HStack>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<GithubGraph color="yellow" id="stars-chart" data={githubStars.value} {cursorOpts} label="Stars" />
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card color="secondary">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<HStack>
|
||||
<Icon icon={mdiBugOutline} />
|
||||
<span>Issues</span>
|
||||
</HStack>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<GithubGraph color="blue" id="issues-chart" data={githubIssues.value} {cursorOpts} label="Issues" />
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card color="secondary">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<HStack>
|
||||
<Icon icon={mdiSourceBranch} />
|
||||
<span>Open Pull Requests</span>
|
||||
</HStack>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<GithubGraph
|
||||
color="green"
|
||||
id="pull-requests-chart"
|
||||
data={githubPullRequests.value}
|
||||
{cursorOpts}
|
||||
label="PR"
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card color="secondary">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<HStack>
|
||||
<Icon icon={mdiMessageOutline} />
|
||||
<span>Total Discussions</span>
|
||||
</HStack>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<GithubGraph
|
||||
color="purple"
|
||||
id="discussions-chart"
|
||||
data={githubDiscussions.value}
|
||||
{cursorOpts}
|
||||
label="Topics"
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card color="secondary">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<HStack>
|
||||
<Icon icon={mdiSourceBranch} />
|
||||
<span>Total PRs Merged (Cumulative)</span>
|
||||
</HStack>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<GithubGraph
|
||||
color="green"
|
||||
id="merged-prs-chart"
|
||||
data={githubMergedPullRequests.value}
|
||||
{cursorOpts}
|
||||
label="Merged PRs"
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
<SectionTitle title="GitHub" link={{ title: 'immich-app/immich', href: Constants.Socials.Github }} />
|
||||
<SectionGrid>
|
||||
<GraphCard title="Stars" icon={mdiStarOutline}>
|
||||
<Graph color="yellow" id="stars-chart" data={githubStars.value} {cursorOpts} label="Stars" />
|
||||
</GraphCard>
|
||||
<GraphCard title="Issues" icon={mdiBugOutline}>
|
||||
<Graph color="blue" id="issues-chart" data={githubIssues.value} {cursorOpts} label="Issues" />
|
||||
</GraphCard>
|
||||
<GraphCard title="Open Pull Requests" icon={mdiSourceBranch}>
|
||||
<Graph
|
||||
color="green"
|
||||
id="pull-requests-chart"
|
||||
data={githubPullRequests.value}
|
||||
{cursorOpts}
|
||||
label="Open pull requests"
|
||||
/>
|
||||
</GraphCard>
|
||||
<GraphCard title="Merged Pull Requests" icon={mdiSourceBranch}>
|
||||
<Graph
|
||||
color="green"
|
||||
id="merged-prs-chart"
|
||||
data={githubMergedPullRequests.value}
|
||||
{cursorOpts}
|
||||
label="Merged pull requests"
|
||||
/>
|
||||
</GraphCard>
|
||||
<GraphCard title="Discussions" icon={mdiMessageOutline}>
|
||||
<Graph
|
||||
color="purple"
|
||||
id="discussions-chart"
|
||||
data={githubDiscussions.value}
|
||||
{cursorOpts}
|
||||
label="Total discussions"
|
||||
/>
|
||||
</GraphCard>
|
||||
</SectionGrid>
|
||||
|
||||
<section class="flex flex-col gap-4">
|
||||
<div>
|
||||
<Heading size="large" tag="h1">Community</Heading>
|
||||
<Text color="muted">r/immich • discord.gg/immich</Text>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<Card color="secondary">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<HStack>
|
||||
<Icon icon={mdiAccountGroup} />
|
||||
<span>Reddit Members</span>
|
||||
</HStack>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<GithubGraph
|
||||
color="orange"
|
||||
id="reddit-members"
|
||||
data={redditMembers.value}
|
||||
{cursorOpts}
|
||||
label="Reddit members"
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card color="secondary">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<HStack>
|
||||
<Icon icon={mdiAccountGroup} />
|
||||
<span>Discord Members</span>
|
||||
</HStack>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<GithubGraph
|
||||
color="purple"
|
||||
id="discord-members"
|
||||
data={discordMembers.value}
|
||||
{cursorOpts}
|
||||
label="Discord members"
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</Stack>
|
||||
<SectionGrid>
|
||||
<div>
|
||||
<SectionTitle title="Reddit" link={{ title: 'r/immich', href: Constants.Socials.Reddit }} />
|
||||
<GraphCard title="Reddit Members" icon={mdiAccountGroup}>
|
||||
<Graph color="orange" id="reddit-members" data={redditMembers.value} {cursorOpts} label="Reddit members" />
|
||||
</GraphCard>
|
||||
</div>
|
||||
<div>
|
||||
<SectionTitle title="Discord" link={{ title: 'discord.immich.app', href: Constants.Socials.Discord }} />
|
||||
<GraphCard title="Discord Members" icon={mdiAccountGroup}>
|
||||
<Graph color="purple" id="discord-members" data={discordMembers.value} {cursorOpts} label="Discord members" />
|
||||
</GraphCard>
|
||||
</div>
|
||||
</SectionGrid>
|
||||
</Container>
|
||||
|
||||
@@ -5,13 +5,10 @@ process.env.PUBLIC_IMMICH_BACKEND_URL = process.env.PUBLIC_IMMICH_BACKEND_URL ||
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess(),
|
||||
|
||||
kit: {
|
||||
adapter: adapter({
|
||||
fallback: 'index.html',
|
||||
pages: '../dist/frontend',
|
||||
}),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user