fixed (i think)
This commit is contained in:
@@ -1,14 +1,6 @@
|
|||||||
import { Typewriter } from "./Typewriter";
|
import { Typewriter } from "./Typewriter";
|
||||||
import { useBars } from "~/context/bars";
|
import { useBars } from "~/context/bars";
|
||||||
import {
|
import { onMount, createEffect, createSignal, Show, For } from "solid-js";
|
||||||
onMount,
|
|
||||||
createEffect,
|
|
||||||
createSignal,
|
|
||||||
createResource,
|
|
||||||
Show,
|
|
||||||
For,
|
|
||||||
Suspense
|
|
||||||
} from "solid-js";
|
|
||||||
import { api } from "~/lib/api";
|
import { api } from "~/lib/api";
|
||||||
import { TerminalSplash } from "./TerminalSplash";
|
import { TerminalSplash } from "./TerminalSplash";
|
||||||
import { insertSoftHyphens } from "~/lib/client-utils";
|
import { insertSoftHyphens } from "~/lib/client-utils";
|
||||||
@@ -18,40 +10,47 @@ import { RecentCommits } from "./RecentCommits";
|
|||||||
import { ActivityHeatmap } from "./ActivityHeatmap";
|
import { ActivityHeatmap } from "./ActivityHeatmap";
|
||||||
import { DarkModeToggle } from "./DarkModeToggle";
|
import { DarkModeToggle } from "./DarkModeToggle";
|
||||||
|
|
||||||
|
interface GitCommit {
|
||||||
|
sha: string;
|
||||||
|
message: string;
|
||||||
|
author: string;
|
||||||
|
date: string;
|
||||||
|
repo: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ContributionDay {
|
||||||
|
date: string;
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
|
||||||
export function RightBarContent() {
|
export function RightBarContent() {
|
||||||
const [githubCommits] = createResource(async () => {
|
const [githubCommits, setGithubCommits] = createSignal<GitCommit[]>([]);
|
||||||
try {
|
const [giteaCommits, setGiteaCommits] = createSignal<GitCommit[]>([]);
|
||||||
return await api.gitActivity.getGitHubCommits.query({ limit: 3 });
|
const [githubActivity, setGithubActivity] = createSignal<ContributionDay[]>(
|
||||||
} catch (error) {
|
[]
|
||||||
console.error("Failed to fetch GitHub commits:", error);
|
);
|
||||||
return [];
|
const [giteaActivity, setGiteaActivity] = createSignal<ContributionDay[]>([]);
|
||||||
}
|
const [loading, setLoading] = createSignal(true);
|
||||||
});
|
|
||||||
|
|
||||||
const [giteaCommits] = createResource(async () => {
|
onMount(async () => {
|
||||||
|
// Fetch all data client-side only to avoid hydration mismatch
|
||||||
try {
|
try {
|
||||||
return await api.gitActivity.getGiteaCommits.query({ limit: 3 });
|
const [ghCommits, gtCommits, ghActivity, gtActivity] = await Promise.all([
|
||||||
} catch (error) {
|
api.gitActivity.getGitHubCommits.query({ limit: 3 }).catch(() => []),
|
||||||
console.error("Failed to fetch Gitea commits:", error);
|
api.gitActivity.getGiteaCommits.query({ limit: 3 }).catch(() => []),
|
||||||
return [];
|
api.gitActivity.getGitHubActivity.query().catch(() => []),
|
||||||
}
|
api.gitActivity.getGiteaActivity.query().catch(() => [])
|
||||||
});
|
]);
|
||||||
|
|
||||||
const [githubActivity] = createResource(async () => {
|
setGithubCommits(ghCommits);
|
||||||
try {
|
setGiteaCommits(gtCommits);
|
||||||
return await api.gitActivity.getGitHubActivity.query();
|
setGithubActivity(ghActivity);
|
||||||
|
setGiteaActivity(gtActivity);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch GitHub activity:", error);
|
console.error("Failed to fetch git activity:", error);
|
||||||
return [];
|
} finally {
|
||||||
}
|
setLoading(false);
|
||||||
});
|
|
||||||
|
|
||||||
const [giteaActivity] = createResource(async () => {
|
|
||||||
try {
|
|
||||||
return await api.gitActivity.getGiteaActivity.query();
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to fetch Gitea activity:", error);
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -111,29 +110,27 @@ export function RightBarContent() {
|
|||||||
</Typewriter>
|
</Typewriter>
|
||||||
|
|
||||||
{/* Git Activity Section */}
|
{/* Git Activity Section */}
|
||||||
<Suspense fallback={<TerminalSplash />}>
|
<hr class="border-overlay0" />
|
||||||
<hr class="border-overlay0" />
|
<div class="flex min-w-0 flex-col gap-6 px-4 pt-6">
|
||||||
<div class="flex min-w-0 flex-col gap-6 px-4 pt-6">
|
<RecentCommits
|
||||||
<RecentCommits
|
commits={githubCommits()}
|
||||||
commits={githubCommits()}
|
title="Recent GitHub Commits"
|
||||||
title="Recent GitHub Commits"
|
loading={loading()}
|
||||||
loading={githubCommits.loading}
|
/>
|
||||||
/>
|
<ActivityHeatmap
|
||||||
<ActivityHeatmap
|
contributions={githubActivity()}
|
||||||
contributions={githubActivity()}
|
title="GitHub Activity"
|
||||||
title="GitHub Activity"
|
/>
|
||||||
/>
|
<RecentCommits
|
||||||
<RecentCommits
|
commits={giteaCommits()}
|
||||||
commits={giteaCommits()}
|
title="Recent Gitea Commits"
|
||||||
title="Recent Gitea Commits"
|
loading={loading()}
|
||||||
loading={giteaCommits.loading}
|
/>
|
||||||
/>
|
<ActivityHeatmap
|
||||||
<ActivityHeatmap
|
contributions={giteaActivity()}
|
||||||
contributions={giteaActivity()}
|
title="Gitea Activity"
|
||||||
title="Gitea Activity"
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ const spinnerChars = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "
|
|||||||
export function TerminalSplash() {
|
export function TerminalSplash() {
|
||||||
const [showing, setShowing] = createSignal(0);
|
const [showing, setShowing] = createSignal(0);
|
||||||
|
|
||||||
// Only run animation on client
|
onMount(() => {
|
||||||
if (!isServer) {
|
// Only run animation on client
|
||||||
onMount(() => {
|
if (isServer) return;
|
||||||
const interval = setInterval(() => {
|
|
||||||
setShowing((prev) => (prev + 1) % spinnerChars.length);
|
|
||||||
}, 50);
|
|
||||||
|
|
||||||
onCleanup(() => {
|
const interval = setInterval(() => {
|
||||||
clearInterval(interval);
|
setShowing((prev) => (prev + 1) % spinnerChars.length);
|
||||||
});
|
}, 50);
|
||||||
|
|
||||||
|
onCleanup(() => {
|
||||||
|
clearInterval(interval);
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="bg-base flex min-h-screen w-full flex-col items-center justify-center overflow-hidden">
|
<div class="bg-base flex min-h-screen w-full flex-col items-center justify-center overflow-hidden">
|
||||||
|
|||||||
51
src/env/server.ts
vendored
51
src/env/server.ts
vendored
@@ -177,29 +177,42 @@ export const validateClientEnv = (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Environment validation for server startup with better error reporting
|
// Lazy environment validation - only validates when accessed
|
||||||
export const env = (() => {
|
let _cachedEnv: ServerEnv | null = null;
|
||||||
try {
|
let _validationAttempted = false;
|
||||||
// Validate server environment variables using process.env
|
|
||||||
const validatedServerEnv = validateServerEnv(process.env);
|
|
||||||
|
|
||||||
console.log("✅ Environment validation successful");
|
export const env = new Proxy({} as ServerEnv, {
|
||||||
return validatedServerEnv;
|
get(_target, prop: string) {
|
||||||
} catch (error) {
|
// Only validate once
|
||||||
if (error instanceof EnvironmentError) {
|
if (!_validationAttempted) {
|
||||||
console.error("❌ Environment validation failed:", error.message);
|
_validationAttempted = true;
|
||||||
if (error.errors) {
|
try {
|
||||||
console.error(
|
// Validate server environment variables using process.env
|
||||||
"Detailed errors:",
|
_cachedEnv = validateServerEnv(process.env);
|
||||||
JSON.stringify(error.errors, null, 2)
|
console.log("✅ Environment validation successful");
|
||||||
);
|
} catch (error) {
|
||||||
|
if (error instanceof EnvironmentError) {
|
||||||
|
console.error("❌ Environment validation failed:", error.message);
|
||||||
|
if (error.errors) {
|
||||||
|
console.error(
|
||||||
|
"Detailed errors:",
|
||||||
|
JSON.stringify(error.errors, null, 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw new Error(`Environment validation failed: ${error.message}`);
|
||||||
|
}
|
||||||
|
console.error("❌ Unexpected environment validation error:", error);
|
||||||
|
throw new Error("Unexpected environment validation error occurred");
|
||||||
}
|
}
|
||||||
throw new Error(`Environment validation failed: ${error.message}`);
|
|
||||||
}
|
}
|
||||||
console.error("❌ Unexpected environment validation error:", error);
|
|
||||||
throw new Error("Unexpected environment validation error occurred");
|
if (!_cachedEnv) {
|
||||||
|
throw new Error("Environment validation has not been performed yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cachedEnv[prop as keyof ServerEnv];
|
||||||
}
|
}
|
||||||
})();
|
});
|
||||||
|
|
||||||
// For client-side validation (useful in components)
|
// For client-side validation (useful in components)
|
||||||
export const getClientEnvValidation = () => {
|
export const getClientEnvValidation = () => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { createTRPCProxyClient, httpBatchLink, loggerLink } from "@trpc/client";
|
import { createTRPCProxyClient, httpBatchLink, loggerLink } from "@trpc/client";
|
||||||
import { env } from "~/env/server";
|
|
||||||
import { AppRouter } from "~/server/api/root";
|
import { AppRouter } from "~/server/api/root";
|
||||||
|
|
||||||
export const api = createTRPCProxyClient<AppRouter>({
|
export const api = createTRPCProxyClient<AppRouter>({
|
||||||
@@ -7,6 +6,6 @@ export const api = createTRPCProxyClient<AppRouter>({
|
|||||||
// will print out helpful logs when using client
|
// will print out helpful logs when using client
|
||||||
loggerLink(),
|
loggerLink(),
|
||||||
// identifies what url will handle trpc requests
|
// identifies what url will handle trpc requests
|
||||||
httpBatchLink({ url: `${env.VITE_DOMAIN}/api/trpc` })
|
httpBatchLink({ url: `${import.meta.env.VITE_DOMAIN}/api/trpc` })
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user