Compare commits
13 commits
Author | SHA1 | Date | |
---|---|---|---|
3439336019 | |||
b0e535f2ab | |||
6b0190f1c0 | |||
cabb157ea3 | |||
02a429c8be | |||
9e1168d091 | |||
7c3e3eb845 | |||
d585a42d05 | |||
7dd26608d2 | |||
6646d3b075 | |||
d7c7db0ef9 | |||
c7d3c27a30 | |||
d7e7654686 |
21 changed files with 1036 additions and 1195 deletions
.forgejo/workflows
Dockerfilepackage.jsonsrc
unlighthouse.config.tsvite.config.tsyarn.lock
|
@ -12,11 +12,9 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checking Out Repository Code
|
- name: Checking Out Repository Code
|
||||||
uses: https://code.forgejo.org/actions/checkout@v3
|
uses: https://code.forgejo.org/actions/checkout@v3
|
||||||
|
|
||||||
- name: Get Yarn Cache Directory
|
- name: Get Yarn Cache Directory
|
||||||
id: yarn-cache-dir-path
|
id: yarn-cache-dir-path
|
||||||
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Set Up Yarn Cache
|
- name: Set Up Yarn Cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||||
|
@ -25,65 +23,11 @@ jobs:
|
||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-yarn-
|
${{ runner.os }}-yarn-
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: yarn install
|
run: yarn install
|
||||||
|
|
||||||
- name: Install Chromium for Unlighthouse
|
|
||||||
run: |
|
|
||||||
echo "apt update && apt install -y chromium"
|
|
||||||
apt update && apt install -y chromium
|
|
||||||
echo 'export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --no-sandbox" >> /etc/chromium.d/default-flags'
|
|
||||||
echo 'export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --no-sandbox"' >> /etc/chromium.d/default-flags
|
|
||||||
|
|
||||||
- name: Add Unlighthouse
|
|
||||||
run: |
|
|
||||||
echo "yarn global add @unlighthouse/cli"
|
|
||||||
yarn global add @unlighthouse/cli
|
|
||||||
|
|
||||||
- name: Run Linter
|
- name: Run Linter
|
||||||
run: yarn lint
|
run: yarn lint
|
||||||
|
|
||||||
- name: Check if Version in package.json matches Tag
|
|
||||||
run: |
|
|
||||||
VERSION=$(cat package.json | grep "version" | sed 's/.*://' | tr -d , | tr -d \" | tr -d " " )
|
|
||||||
if test $VERSION != "${{ github.ref_name }}"; then
|
|
||||||
echo "Expected Version is: '${{ github.ref_name }}' actual Version is: '$VERSION'";
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "Version is: '$VERSION'";
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Build Site
|
|
||||||
run: yarn build
|
|
||||||
|
|
||||||
- name: Start Server
|
|
||||||
run: |
|
|
||||||
export KUMA_USERNAME=${{ secrets.KUMA_USERNAME }}
|
|
||||||
export KUMA_PASSWORD=${{ secrets.KUMA_PASSWORD }}
|
|
||||||
yarn preview &
|
|
||||||
|
|
||||||
- name: Run Unlighthouse for Desktop
|
|
||||||
run: unlighthouse-ci --build-static --desktop --outputPath reports/desktop
|
|
||||||
|
|
||||||
- name: Refresh Server
|
|
||||||
run: |
|
|
||||||
if ! pgrep -f "node /usr/bin/yarn" ; then
|
|
||||||
export KUMA_USERNAME=${{ secrets.KUMA_USERNAME }}
|
|
||||||
export KUMA_PASSWORD=${{ secrets.KUMA_PASSWORD }}
|
|
||||||
yarn preview &
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Run Unlighthouse for Mobile
|
|
||||||
run: unlighthouse-ci --build-static --mobile --outputPath reports/mobile
|
|
||||||
|
|
||||||
- name: Uploading Lighthouse Reports
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: lighthouse
|
|
||||||
path: reports
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
needs: test
|
needs: test
|
||||||
if: success()
|
if: success()
|
||||||
|
|
|
@ -12,11 +12,9 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checking Out Repository Code
|
- name: Checking Out Repository Code
|
||||||
uses: https://code.forgejo.org/actions/checkout@v3
|
uses: https://code.forgejo.org/actions/checkout@v3
|
||||||
|
|
||||||
- name: Get Yarn Cache Directory
|
- name: Get Yarn Cache Directory
|
||||||
id: yarn-cache-dir-path
|
id: yarn-cache-dir-path
|
||||||
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Set Up Yarn Cache
|
- name: Set Up Yarn Cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||||
|
@ -25,51 +23,7 @@ jobs:
|
||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-yarn-
|
${{ runner.os }}-yarn-
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: yarn install
|
run: yarn install
|
||||||
|
|
||||||
- name: Install Chromium for Unlighthouse
|
|
||||||
run: |
|
|
||||||
echo "apt update && apt install -y chromium"
|
|
||||||
apt update && apt install -y chromium
|
|
||||||
echo 'export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --no-sandbox" >> /etc/chromium.d/default-flags'
|
|
||||||
echo 'export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --no-sandbox"' >> /etc/chromium.d/default-flags
|
|
||||||
|
|
||||||
- name: Add Unlighthouse
|
|
||||||
run: |
|
|
||||||
echo "yarn global add @unlighthouse/cli"
|
|
||||||
yarn global add @unlighthouse/cli
|
|
||||||
|
|
||||||
- name: Run Linter
|
- name: Run Linter
|
||||||
run: yarn lint
|
run: yarn lint
|
||||||
|
|
||||||
- name: Build Site
|
|
||||||
run: yarn build
|
|
||||||
|
|
||||||
- name: Start Server
|
|
||||||
run: |
|
|
||||||
export KUMA_USERNAME=${{ secrets.KUMA_USERNAME }}
|
|
||||||
export KUMA_PASSWORD=${{ secrets.KUMA_PASSWORD }}
|
|
||||||
yarn preview &
|
|
||||||
|
|
||||||
- name: Run Unlighthouse for Desktop
|
|
||||||
run: unlighthouse-ci --build-static --desktop --outputPath reports/desktop
|
|
||||||
|
|
||||||
- name: Refresh Server
|
|
||||||
run: |
|
|
||||||
if ! pgrep -f "node /usr/bin/yarn" ; then
|
|
||||||
export KUMA_USERNAME=${{ secrets.KUMA_USERNAME }}
|
|
||||||
export KUMA_PASSWORD=${{ secrets.KUMA_PASSWORD }}
|
|
||||||
yarn preview &
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Run Unlighthouse for Mobile
|
|
||||||
run: unlighthouse-ci --build-static --mobile --outputPath reports/mobile
|
|
||||||
|
|
||||||
- name: Uploading Lighthouse Reports
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: lighthouse
|
|
||||||
path: reports
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
75
.forgejo/workflows/unlighthouse.yml
Normal file
75
.forgejo/workflows/unlighthouse.yml
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
name: 'Test Docker Image with Unlighthouse'
|
||||||
|
author: 'Neshura'
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
- '[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: docker
|
||||||
|
steps:
|
||||||
|
- name: Checking Out Repository Code
|
||||||
|
uses: https://code.forgejo.org/actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Get Yarn Cache Directory
|
||||||
|
id: yarn-cache-dir-path
|
||||||
|
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Set Up Yarn Cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||||
|
with:
|
||||||
|
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-yarn-
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: yarn install
|
||||||
|
|
||||||
|
- name: Install Chromium for Unlighthouse
|
||||||
|
run: |
|
||||||
|
echo "apt update && apt install -y chromium"
|
||||||
|
apt update && apt install -y chromium
|
||||||
|
echo 'export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --no-sandbox" >> /etc/chromium.d/default-flags'
|
||||||
|
echo 'export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --no-sandbox"' >> /etc/chromium.d/default-flags
|
||||||
|
|
||||||
|
- name: Add Unlighthouse
|
||||||
|
run: |
|
||||||
|
echo "yarn global add @unlighthouse/cli"
|
||||||
|
yarn global add @unlighthouse/cli
|
||||||
|
|
||||||
|
- name: Build Site
|
||||||
|
run: yarn build
|
||||||
|
|
||||||
|
- name: Start Server
|
||||||
|
run: |
|
||||||
|
export KUMA_USERNAME=${{ secrets.KUMA_USERNAME }}
|
||||||
|
export KUMA_PASSWORD=${{ secrets.KUMA_PASSWORD }}
|
||||||
|
yarn preview &
|
||||||
|
|
||||||
|
- name: Run Unlighthouse for Desktop
|
||||||
|
run: unlighthouse-ci --build-static --desktop --outputPath reports/desktop
|
||||||
|
|
||||||
|
- name: Refresh Server
|
||||||
|
run: |
|
||||||
|
if ! pgrep -f "node /usr/bin/yarn" ; then
|
||||||
|
export KUMA_USERNAME=${{ secrets.KUMA_USERNAME }}
|
||||||
|
export KUMA_PASSWORD=${{ secrets.KUMA_PASSWORD }}
|
||||||
|
yarn preview &
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Run Unlighthouse for Mobile
|
||||||
|
run: unlighthouse-ci --build-static --mobile --outputPath reports/mobile
|
||||||
|
|
||||||
|
- name: Uploading Lighthouse Reports
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: lighthouse
|
||||||
|
path: reports
|
||||||
|
if-no-files-found: error
|
|
@ -14,8 +14,6 @@ WORKDIR /app
|
||||||
COPY --from=build /app .
|
COPY --from=build /app .
|
||||||
|
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
ENV KUMA_USERNAME ''
|
|
||||||
ENV KUMA_PASSWORD ''
|
|
||||||
|
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
CMD ["yarn", "preview"]
|
CMD ["yarn", "preview"]
|
17
package.json
17
package.json
|
@ -2,7 +2,7 @@
|
||||||
"name": "main-site",
|
"name": "main-site",
|
||||||
"author": "Neshura",
|
"author": "Neshura",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"version": "1.0.2",
|
"version": "1.0.9",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
|
@ -16,11 +16,11 @@
|
||||||
"ui": "npx shadcn-svelte@latest"
|
"ui": "npx shadcn-svelte@latest"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^3.0.0",
|
"@sveltejs/adapter-auto": "^6.0.0",
|
||||||
"@sveltejs/kit": "^2.0.0",
|
"@sveltejs/kit": "^2.0.0",
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||||
"@types/eslint": "8.56.0",
|
"@types/eslint": "9.6.1",
|
||||||
"@types/socket.io": "^3.0.2",
|
"@types/sanitize-html": "^2.15.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||||
"@typescript-eslint/parser": "^6.0.0",
|
"@typescript-eslint/parser": "^6.0.0",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.16",
|
||||||
|
@ -32,20 +32,19 @@
|
||||||
"prettier": "^3.1.1",
|
"prettier": "^3.1.1",
|
||||||
"prettier-plugin-svelte": "^3.1.2",
|
"prettier-plugin-svelte": "^3.1.2",
|
||||||
"prettier-plugin-tailwindcss": "^0.5.9",
|
"prettier-plugin-tailwindcss": "^0.5.9",
|
||||||
"svelte": "^5.0.0-next.1",
|
"svelte": "^5.0.0",
|
||||||
"svelte-check": "^3.6.0",
|
"svelte-check": "^3.6.0",
|
||||||
"tailwindcss": "^3.3.6",
|
"tailwindcss": "^3.3.6",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"vite": "^5.0.3"
|
"vite": "^6.2.5"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bits-ui": "^0.13.2",
|
"bits-ui": "1.3.16",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
"radix-icons-svelte": "^1.2.1",
|
"radix-icons-svelte": "^1.2.1",
|
||||||
"sanitize-html": "^2.11.0",
|
"sanitize-html": "^2.11.0",
|
||||||
"socket.io": "^4.7.2",
|
|
||||||
"socket.io-client": "^4.7.2",
|
"socket.io-client": "^4.7.2",
|
||||||
"tailwind-merge": "^2.2.0",
|
"tailwind-merge": "^2.2.0",
|
||||||
"tailwind-variants": "^0.1.19"
|
"tailwind-variants": "^0.1.19"
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
<svelte:options runes={true} />
|
<svelte:options runes={true} />
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Clipboard, Copy, OpenInNewWindow } from 'radix-icons-svelte';
|
import { Copy, OpenInNewWindow } from 'radix-icons-svelte';
|
||||||
import { quintInOut } from 'svelte/easing';
|
import { quintInOut } from 'svelte/easing';
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import { IconType, type Server } from '$lib/types/data-types';
|
import { IconType, type Server } from '$lib/types/data-types';
|
||||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||||
import type { Heartbeat } from '$lib/types/uptime-kuma-types';
|
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
|
||||||
let { server, icons, monitor } = $props<{
|
let { server, icons } = $props<{
|
||||||
server: Server;
|
server: Server;
|
||||||
icons: Array<string>;
|
icons: Array<string>;
|
||||||
}>();
|
}>();
|
||||||
|
@ -38,12 +37,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (typeof server.id === 'undefined') {
|
|
||||||
status = 99;
|
|
||||||
}
|
|
||||||
if (typeof monitor !== 'undefined') {
|
|
||||||
status = monitor.status;
|
|
||||||
}
|
|
||||||
if (icons.length != 0 && typeof server.icon !== 'undefined') {
|
if (icons.length != 0 && typeof server.icon !== 'undefined') {
|
||||||
const rootSplit = server.icon.split('/');
|
const rootSplit = server.icon.split('/');
|
||||||
const root = rootSplit[rootSplit.length - 1];
|
const root = rootSplit[rootSplit.length - 1];
|
||||||
|
@ -67,8 +60,9 @@
|
||||||
<div class="flex flex-row justify-between">
|
<div class="flex flex-row justify-between">
|
||||||
<div
|
<div
|
||||||
class="flex flex-row items-center gap-1"
|
class="flex flex-row items-center gap-1"
|
||||||
on:mouseover={() => (hover.title = true)}
|
onmouseover={() => (hover.title = true)}
|
||||||
on:mouseleave={() => (hover.title = false)}
|
onfocus={() => (hover.title = true)}
|
||||||
|
onmouseleave={() => (hover.title = false)}
|
||||||
>
|
>
|
||||||
{#if typeof server.icon !== 'undefined'}
|
{#if typeof server.icon !== 'undefined'}
|
||||||
{#if img_source != ''}
|
{#if img_source != ''}
|
||||||
|
@ -120,8 +114,9 @@
|
||||||
<a
|
<a
|
||||||
class="flex flex-row rounded-md border-x-2 px-2 text-sm hover:border-secondary hover:text-secondary"
|
class="flex flex-row rounded-md border-x-2 px-2 text-sm hover:border-secondary hover:text-secondary"
|
||||||
href={server.href}
|
href={server.href}
|
||||||
on:mouseover={() => (hover.link = true)}
|
onmouseover={() => (hover.link = true)}
|
||||||
on:mouseleave={() => (hover.link = false)}
|
onfocus={() => (hover.title = true)}
|
||||||
|
onmouseleave={() => (hover.link = false)}
|
||||||
>
|
>
|
||||||
Open
|
Open
|
||||||
{#if hover.link}
|
{#if hover.link}
|
||||||
|
@ -141,8 +136,9 @@
|
||||||
<a
|
<a
|
||||||
class="flex flex-row rounded-md border-x-2 px-2 text-sm hover:border-secondary hover:text-secondary"
|
class="flex flex-row rounded-md border-x-2 px-2 text-sm hover:border-secondary hover:text-secondary"
|
||||||
href={server.extLink}
|
href={server.extLink}
|
||||||
on:mouseover={() => (hover.ext = true)}
|
onmouseover={() => (hover.ext = true)}
|
||||||
on:mouseleave={() => (hover.ext = false)}
|
onfocus={() => (hover.title = true)}
|
||||||
|
onmouseleave={() => (hover.ext = false)}
|
||||||
>
|
>
|
||||||
Official Site
|
Official Site
|
||||||
{#if hover.ext}
|
{#if hover.ext}
|
||||||
|
|
|
@ -6,16 +6,12 @@
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import { IconType, type Service } from '$lib/types/data-types';
|
import { IconType, type Service } from '$lib/types/data-types';
|
||||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||||
import type { Heartbeat } from '$lib/types/uptime-kuma-types';
|
|
||||||
|
|
||||||
let { service, icons, monitor } = $props<{
|
let { service, icons, monitor } = $props<{
|
||||||
service: Service;
|
service: Service;
|
||||||
icons: Array<string>;
|
icons: Array<string>;
|
||||||
monitor: Heartbeat;
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
let status = $state(4);
|
|
||||||
|
|
||||||
let hover = $state({
|
let hover = $state({
|
||||||
title: false,
|
title: false,
|
||||||
link: false,
|
link: false,
|
||||||
|
@ -36,9 +32,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (typeof monitor !== 'undefined') {
|
|
||||||
status = monitor.status;
|
|
||||||
}
|
|
||||||
if (icons.length != 0) {
|
if (icons.length != 0) {
|
||||||
const rootSplit = service.icon.split('/');
|
const rootSplit = service.icon.split('/');
|
||||||
const root = rootSplit[rootSplit.length - 1];
|
const root = rootSplit[rootSplit.length - 1];
|
||||||
|
@ -62,8 +55,9 @@
|
||||||
<div class="flex flex-row justify-between">
|
<div class="flex flex-row justify-between">
|
||||||
<div
|
<div
|
||||||
class="flex flex-row items-center gap-1"
|
class="flex flex-row items-center gap-1"
|
||||||
on:mouseover={() => (hover.title = true)}
|
onmouseover={() => (hover.title = true)}
|
||||||
on:mouseleave={() => (hover.title = false)}
|
onfocus={() => (hover.title = true)}
|
||||||
|
onmouseleave={() => (hover.title = false)}
|
||||||
>
|
>
|
||||||
{#if service.icon}
|
{#if service.icon}
|
||||||
{#if img_source != ''}
|
{#if img_source != ''}
|
||||||
|
@ -97,8 +91,9 @@
|
||||||
<a
|
<a
|
||||||
class="flex flex-row rounded-md border-x-2 px-2 text-sm hover:border-secondary hover:text-secondary"
|
class="flex flex-row rounded-md border-x-2 px-2 text-sm hover:border-secondary hover:text-secondary"
|
||||||
href={service.href}
|
href={service.href}
|
||||||
on:mouseover={() => (hover.link = true)}
|
onmouseover={() => (hover.link = true)}
|
||||||
on:mouseleave={() => (hover.link = false)}
|
onfocus={() => (hover.title = true)}
|
||||||
|
onmouseleave={() => (hover.link = false)}
|
||||||
>
|
>
|
||||||
Open
|
Open
|
||||||
{#if hover.link}
|
{#if hover.link}
|
||||||
|
@ -117,8 +112,9 @@
|
||||||
<a
|
<a
|
||||||
class="flex flex-row rounded-md border-x-2 px-2 text-sm hover:border-secondary hover:text-secondary"
|
class="flex flex-row rounded-md border-x-2 px-2 text-sm hover:border-secondary hover:text-secondary"
|
||||||
href={service.extLink}
|
href={service.extLink}
|
||||||
on:mouseover={() => (hover.ext = true)}
|
onmouseover={() => (hover.ext = true)}
|
||||||
on:mouseleave={() => (hover.ext = false)}
|
onfocus={() => (hover.title = true)}
|
||||||
|
onmouseleave={() => (hover.ext = false)}
|
||||||
>
|
>
|
||||||
Official Site
|
Official Site
|
||||||
{#if hover.ext}
|
{#if hover.ext}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Button as ButtonPrimitive } from 'bits-ui';
|
import { Button as ButtonPrimitive } from 'bits-ui';
|
||||||
import { cn } from '$lib/utils';
|
import { type Events, type Props, buttonVariants } from './index.js';
|
||||||
import { buttonVariants, type Props, type Events } from '.';
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
type $$Props = Props;
|
type $$Props = Props;
|
||||||
type $$Events = Events;
|
type $$Events = Events;
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import type { Button as ButtonPrimitive } from 'bits-ui';
|
import type { Button as ButtonPrimitive } from 'bits-ui';
|
||||||
import { tv, type VariantProps } from 'tailwind-variants';
|
import { type VariantProps, tv } from 'tailwind-variants';
|
||||||
import Root from './button.svelte';
|
import Root from './button.svelte';
|
||||||
|
|
||||||
const buttonVariants = tv({
|
const buttonVariants = tv({
|
||||||
base: 'inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',
|
base: 'focus-visible:ring-ring inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50',
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',
|
default: 'bg-primary text-primary-foreground hover:bg-primary/90 shadow',
|
||||||
destructive: 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
|
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm',
|
||||||
outline:
|
outline:
|
||||||
'border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground',
|
'border-input bg-background hover:bg-accent hover:text-accent-foreground border shadow-sm',
|
||||||
secondary: 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
|
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-sm',
|
||||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||||
link: 'text-primary underline-offset-4 hover:underline'
|
link: 'text-primary underline-offset-4 hover:underline'
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Separator as SeparatorPrimitive } from 'bits-ui';
|
import { Separator as SeparatorPrimitive } from 'bits-ui';
|
||||||
import { cn } from '$lib/utils';
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
type $$Props = SeparatorPrimitive.Props;
|
type $$Props = SeparatorPrimitive.Props;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
<SeparatorPrimitive.Root
|
<SeparatorPrimitive.Root
|
||||||
class={cn(
|
class={cn(
|
||||||
'shrink-0 bg-border',
|
'shrink-0 bg-border',
|
||||||
orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',
|
orientation === 'horizontal' ? 'h-[1px] w-full' : 'min-h-full w-[1px]',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{orientation}
|
{orientation}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn } from '$lib/utils';
|
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||||
|
|
||||||
|
@ -8,4 +8,4 @@
|
||||||
export { className as class };
|
export { className as class };
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class={cn('animate-pulse rounded-md bg-primary/10', className)} {...$$restProps} />
|
<div class={cn('animate-pulse rounded-md bg-primary/10', className)} {...$$restProps}></div>
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
import { io } from 'socket.io-client';
|
|
||||||
|
|
||||||
export let socketStore = writable(io('https://status.neshweb.net/'));
|
|
|
@ -1,4 +0,0 @@
|
||||||
import { type Writable, writable } from 'svelte/store';
|
|
||||||
import type { Heartbeat } from '$lib/types/uptime-kuma-types';
|
|
||||||
|
|
||||||
export let uptimeStore: Writable<Map<number, Heartbeat>> = writable(new Map());
|
|
|
@ -1,9 +0,0 @@
|
||||||
export type Heartbeat = {
|
|
||||||
readonly monitorID: number;
|
|
||||||
readonly status: number;
|
|
||||||
readonly time: string;
|
|
||||||
readonly msg: string;
|
|
||||||
readonly ping: number;
|
|
||||||
readonly important: boolean;
|
|
||||||
readonly duration: number;
|
|
||||||
};
|
|
|
@ -3,27 +3,15 @@
|
||||||
<script>
|
<script>
|
||||||
import '../app.pcss';
|
import '../app.pcss';
|
||||||
import Header from './Header.svelte';
|
import Header from './Header.svelte';
|
||||||
import { socketStore } from '$lib/stores/socketStore';
|
|
||||||
import { beforeNavigate } from '$app/navigation';
|
|
||||||
import Footer from './Footer.svelte';
|
import Footer from './Footer.svelte';
|
||||||
|
|
||||||
$effect(() => {
|
let { children } = $props();
|
||||||
beforeNavigate((navigation) => {
|
|
||||||
const servers =
|
|
||||||
navigation.to.url.pathname === '/servers' || navigation.from.url.pathname === '/servers';
|
|
||||||
const services =
|
|
||||||
navigation.to.url.pathname === '/services' || navigation.from.url.pathname === '/services';
|
|
||||||
if (!(servers && services)) {
|
|
||||||
$socketStore.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
|
|
||||||
<div class="h-full pb-8 pt-16">
|
<div class="h-full pb-8 pt-16">
|
||||||
<slot />
|
{@render children()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
|
||||||
const button = 'border-t-2 bg-black/55 hover:bg-black/70 hover:border-secondary w-28';
|
const button = 'border-t-2 bg-black/55 hover:bg-black/70 hover:border-secondary w-28';
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
href="/"
|
href="/"
|
||||||
class="{button} + {!($page.url.pathname === '/') || 'border-secondary text-secondary'}"
|
class="{button} + {!(page.url.pathname === '/') || 'border-secondary text-secondary'}"
|
||||||
>
|
>
|
||||||
Home
|
Home
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
href="/servers"
|
href="/servers"
|
||||||
class="{button} + {!$page.url.pathname.startsWith('/servers') ||
|
class="{button} + {!page.url.pathname.startsWith('/servers') ||
|
||||||
'border-secondary text-secondary'}"
|
'border-secondary text-secondary'}"
|
||||||
>
|
>
|
||||||
Servers
|
Servers
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
href="/services"
|
href="/services"
|
||||||
class="{button} + {!$page.url.pathname.startsWith('/services') ||
|
class="{button} + {!page.url.pathname.startsWith('/services') ||
|
||||||
'border-secondary text-secondary'}"
|
'border-secondary text-secondary'}"
|
||||||
>
|
>
|
||||||
Services
|
Services
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
href="/about"
|
href="/about"
|
||||||
class="{button} + {!$page.url.pathname.startsWith('/about') ||
|
class="{button} + {!page.url.pathname.startsWith('/about') ||
|
||||||
'border-secondary text-secondary'}"
|
'border-secondary text-secondary'}"
|
||||||
>
|
>
|
||||||
About
|
About
|
||||||
|
|
|
@ -2,15 +2,11 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Server } from '$lib/types/data-types';
|
import type { Server } from '$lib/types/data-types';
|
||||||
import { io } from 'socket.io-client';
|
|
||||||
import type { Heartbeat } from '$lib/types/uptime-kuma-types';
|
|
||||||
import ServerCard from '$lib/components/ServerCard.svelte';
|
import ServerCard from '$lib/components/ServerCard.svelte';
|
||||||
import { socketStore } from '$lib/stores/socketStore';
|
|
||||||
import { uptimeStore } from '$lib/stores/uptimeStore';
|
|
||||||
|
|
||||||
let servers: readonly Server[] = $state.frozen([]);
|
let servers: readonly Server[] = $state.raw([]);
|
||||||
|
|
||||||
let icons: readonly string[] = $state.frozen([]);
|
let icons: readonly string[] = $state.raw([]);
|
||||||
|
|
||||||
async function get(url: string): Promise<any> {
|
async function get(url: string): Promise<any> {
|
||||||
let res = await fetch(url);
|
let res = await fetch(url);
|
||||||
|
|
|
@ -3,15 +3,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ServiceCard from '$lib/components/ServiceCard.svelte';
|
import ServiceCard from '$lib/components/ServiceCard.svelte';
|
||||||
import type { Service } from '$lib/types/data-types';
|
import type { Service } from '$lib/types/data-types';
|
||||||
import { io } from 'socket.io-client';
|
|
||||||
import type { Heartbeat } from '$lib/types/uptime-kuma-types';
|
|
||||||
import { socketStore } from '$lib/stores/socketStore';
|
|
||||||
import { onDestroy } from 'svelte';
|
|
||||||
import { uptimeStore } from '$lib/stores/uptimeStore';
|
|
||||||
|
|
||||||
let services: readonly Service[] = $state.frozen([]);
|
let services: readonly Service[] = $state.raw([]);
|
||||||
|
|
||||||
let icons: readonly string[] = $state.frozen([]);
|
let icons: readonly string[] = $state.raw([]);
|
||||||
|
|
||||||
async function get(url: string): Promise<any> {
|
async function get(url: string): Promise<any> {
|
||||||
let res = await fetch(url);
|
let res = await fetch(url);
|
||||||
|
|
|
@ -2,7 +2,7 @@ export default {
|
||||||
site: 'http://localhost:8000',
|
site: 'http://localhost:8000',
|
||||||
ci: {
|
ci: {
|
||||||
budget: {
|
budget: {
|
||||||
performance: 90,
|
performance: 60,
|
||||||
accessibility: 100,
|
accessibility: 100,
|
||||||
'best-practices': 90,
|
'best-practices': 90,
|
||||||
seo: 90
|
seo: 90
|
||||||
|
|
|
@ -10,5 +10,6 @@ export default defineConfig({
|
||||||
preview: {
|
preview: {
|
||||||
host: true,
|
host: true,
|
||||||
port: 8000,
|
port: 8000,
|
||||||
|
allowedHosts: true,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue