add footer and build info
This commit is contained in:
parent
37e2b305ff
commit
e9b17327a8
@ -24,6 +24,10 @@ WORKDIR /app
|
|||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
ENV NEXT_TELEMETRY_DISABLED 1
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
# Add the commit hash
|
||||||
|
ARG GIT_REV
|
||||||
|
ENV GIT_REV ${GIT_REV}
|
||||||
|
|
||||||
RUN addgroup --system --gid 1001 nodejs
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
RUN adduser --system --uid 1001 nextjs
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
@ -1,4 +1,23 @@
|
|||||||
|
import nextBuildId from "next-build-id";
|
||||||
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
|
||||||
|
const __dirname = path.dirname(__filename); // get the name of the directory
|
||||||
|
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {};
|
const nextConfig = {
|
||||||
|
env: {
|
||||||
|
NEXT_PUBLIC_BUILD_ID: process.env.GIT_REV || nextBuildId.sync({ dir: __dirname }),
|
||||||
|
NEXT_PUBLIC_BUILD_TIME: new Date().toLocaleDateString("en-US", {
|
||||||
|
year: "numeric",
|
||||||
|
month: "long",
|
||||||
|
day: "numeric",
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "numeric",
|
||||||
|
timeZoneName: "short",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
"ky": "^1.7.2",
|
"ky": "^1.7.2",
|
||||||
"lucide-react": "^0.440.0",
|
"lucide-react": "^0.440.0",
|
||||||
"next": "14.2.11",
|
"next": "14.2.11",
|
||||||
|
"next-build-id": "^3.0.0",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-chartjs-2": "^5.2.0",
|
"react-chartjs-2": "^5.2.0",
|
||||||
|
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@ -68,6 +68,9 @@ dependencies:
|
|||||||
next:
|
next:
|
||||||
specifier: 14.2.11
|
specifier: 14.2.11
|
||||||
version: 14.2.11(react-dom@18.3.1)(react@18.3.1)
|
version: 14.2.11(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
next-build-id:
|
||||||
|
specifier: ^3.0.0
|
||||||
|
version: 3.0.0
|
||||||
next-themes:
|
next-themes:
|
||||||
specifier: ^0.3.0
|
specifier: ^0.3.0
|
||||||
version: 0.3.0(react-dom@18.3.1)(react@18.3.1)
|
version: 0.3.0(react-dom@18.3.1)(react@18.3.1)
|
||||||
@ -2679,6 +2682,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/next-build-id@3.0.0:
|
||||||
|
resolution: {integrity: sha512-B3JCsL/9Z/wkmo3EySukQHCgx89Aw0i4LPi2MEhCboQBJ6wpkYTIu1z6hOYKuw/S1Wy8ZRqCEq0dVY/ST6jGqg==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/next-themes@0.3.0(react-dom@18.3.1)(react@18.3.1):
|
/next-themes@0.3.0(react-dom@18.3.1)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==}
|
resolution: {integrity: sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -10,6 +10,7 @@ import { ThemeProvider } from "@/components/providers/theme-provider";
|
|||||||
import { Toaster } from "@/components/ui/toaster";
|
import { Toaster } from "@/components/ui/toaster";
|
||||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
import Footer from "@/components/footer";
|
||||||
|
|
||||||
const siteFont = localFont({
|
const siteFont = localFont({
|
||||||
src: "./fonts/JetBrainsMono-Regular.woff2",
|
src: "./fonts/JetBrainsMono-Regular.woff2",
|
||||||
@ -78,9 +79,12 @@ export default function RootLayout({
|
|||||||
>
|
>
|
||||||
<QueryProvider>
|
<QueryProvider>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
<main className="z-[9999] m-auto flex h-screen flex-col items-center md:max-w-[1200px]">
|
<main className="flex flex-col min-h-screen gap-2">
|
||||||
<NavBar />
|
<NavBar />
|
||||||
{children}
|
<div className="z-[1] m-auto flex flex-col flex-grow items-center md:max-w-[1200px]">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
</main>
|
</main>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</QueryProvider>
|
</QueryProvider>
|
||||||
|
@ -6,3 +6,26 @@
|
|||||||
export function setPlayerIdCookie(playerId: string) {
|
export function setPlayerIdCookie(playerId: string) {
|
||||||
document.cookie = `playerId=${playerId}`;
|
document.cookie = `playerId=${playerId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets if we're in production
|
||||||
|
*/
|
||||||
|
export function isProduction() {
|
||||||
|
return process.env.NODE_ENV === "production";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the build information
|
||||||
|
*
|
||||||
|
* @returns the build information
|
||||||
|
*/
|
||||||
|
export function getBuildInformation() {
|
||||||
|
const buildId = process.env.NEXT_PUBLIC_BUILD_ID
|
||||||
|
? isProduction()
|
||||||
|
? process.env.NEXT_PUBLIC_BUILD_ID.slice(0, 7)
|
||||||
|
: "dev"
|
||||||
|
: "";
|
||||||
|
const buildTime = process.env.NEXT_PUBLIC_BUILD_TIME;
|
||||||
|
|
||||||
|
return { buildId, buildTime };
|
||||||
|
}
|
||||||
|
40
src/components/footer.tsx
Normal file
40
src/components/footer.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import NavbarButton from "@/components/navbar/navbar-button";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { getBuildInformation } from "@/common/website-utils";
|
||||||
|
|
||||||
|
type NavbarItem = {
|
||||||
|
name: string;
|
||||||
|
link: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const items: NavbarItem[] = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: "/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Source",
|
||||||
|
link: "https://git.fascinated.cc/Fascinated/scoresaber-reloadedv3",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
const { buildId, buildTime } = getBuildInformation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center w-full flex-col gap-1">
|
||||||
|
<p className="text-input text-sm">
|
||||||
|
Build: {buildId} ({buildTime})
|
||||||
|
</p>
|
||||||
|
<div className="h-14 w-full flex items-center justify-center bg-secondary/95 divide-x divide-input">
|
||||||
|
{items.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<Link className="px-2 text-pp hover:brightness-75" href={item.link}>
|
||||||
|
{item.name}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -34,8 +34,8 @@ const renderNavbarItem = (item: NavbarItem) => (
|
|||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
return (
|
return (
|
||||||
<div className="w-full py-2">
|
<div className="w-full sticky top-0 z-[999]">
|
||||||
<div className="h-10 rounded-md items-center flex justify-between bg-secondary/90">
|
<div className="h-10 items-center flex justify-between bg-secondary/95">
|
||||||
{/* Left-aligned items */}
|
{/* Left-aligned items */}
|
||||||
<div className="flex items-center h-full">
|
<div className="flex items-center h-full">
|
||||||
<ProfileButton />
|
<ProfileButton />
|
||||||
|
Reference in New Issue
Block a user