Initial commit, most things work
Some checks failed
Build and deploy / deploy (push) Failing after 46s

This commit is contained in:
2025-04-26 20:56:56 +01:00
commit 35c8964fe5
25 changed files with 1232 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import type { NextRequest } from "next/server";
import { env } from "@/env";
import { appRouter } from "@/server/api/root";
import { createTRPCContext } from "@/server/api/trpc";
/**
* This wraps the `createTRPCContext` helper and provides the required context for the tRPC API when
* handling a HTTP request (e.g. when you make requests from Client Components).
*/
const createContext = async (req: NextRequest) => {
return createTRPCContext({
headers: req.headers,
});
};
const handler = (req: NextRequest) =>
fetchRequestHandler({
endpoint: "/api/trpc",
req,
router: appRouter,
createContext: () => createContext(req),
onError:
env.NODE_ENV === "development"
? ({ path, error }) => {
console.error(
`❌ tRPC failed on ${path ?? "<no-path>"}: ${error.message}`,
);
}
: undefined,
});
export { handler as GET, handler as POST };

29
src/app/layout.tsx Normal file
View File

@@ -0,0 +1,29 @@
import "@/styles/globals.css";
import type { Metadata } from "next";
import { Geist } from "next/font/google";
import { TRPCReactProvider } from "@/trpc/react";
export const metadata: Metadata = {
title: "Create T3 App",
description: "Generated by create-t3-app",
icons: [{ rel: "icon", url: "/favicon.ico" }],
};
const geist = Geist({
subsets: ["latin"],
variable: "--font-geist-sans",
});
export default function RootLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return (
<html lang="en" className={`${geist.variable}`}>
<body>
<TRPCReactProvider>{children}</TRPCReactProvider>
</body>
</html>
);
}

70
src/app/page.tsx Normal file
View File

@@ -0,0 +1,70 @@
import { HydrateClient, api } from "@/trpc/server";
export default async function Home() {
const list = await api.docker.list();
void api.docker.list.prefetch();
return (
<HydrateClient>
<main className="flex min-h-screen flex-col items-center justify-center">
<div className="container flex flex-col items-center justify-center gap-12 px-4 py-16">
{list ? (
<div className="overflow-x-auto rounded-md border border-base-content/15 bg-base-100">
<table className="table-s table">
<thead>
<tr>
<th>Name</th>
<th>Image</th>
<th>Version</th>
<th>Short Hash</th>
<th>Version</th>
<th>Short Hash</th>
</tr>
</thead>
<tbody>
{list
.sort((ca, cb) => {
if (ca.Names[0] < cb.Names[0]) {
return -1;
}
if (ca.Names[0] > cb.Names[0]) {
return 1;
}
return 0;
})
.map((containerInfo) => {
const outdated =
containerInfo.current.version !==
containerInfo.latest.version ||
containerInfo.current.hash !==
containerInfo.latest.hash;
return (
<tr
key={containerInfo.Image.split(":")[0]}
className={`${outdated ? "bg-base-200" : null}`}
>
<td
className={`border-l-8 ${outdated ? "border-l-error/80" : "border-l-info/80"}`}
>
{containerInfo.Names[0]?.substring(1)}
</td>
<td>{containerInfo.Image.split(":")[0]}</td>
<td>{containerInfo.current.version}</td>
<td>{containerInfo.current.hash}</td>
<td>{containerInfo.latest.version}</td>
<td>{containerInfo.latest.hash}</td>
</tr>
);
})}
</tbody>
</table>
</div>
) : (
"Loading tRPC query..."
)}
</div>
</main>
</HydrateClient>
);
}