feat: Added AppFooter component displaying app version, build date, com…
- "frontend/src/components/AppFooter.tsx" - "frontend/vite.config.ts" - "frontend/src/App.tsx" - "frontend/src/App.css" - "frontend/src/vite-env.d.ts" GSD-Task: S06/T01
This commit is contained in:
parent
96d7bc6e75
commit
ec9e307538
6 changed files with 123 additions and 1 deletions
|
|
@ -159,6 +159,12 @@ body {
|
||||||
|
|
||||||
/* ── App shell ────────────────────────────────────────────────────────────── */
|
/* ── App shell ────────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.app {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
.app-header {
|
.app-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -191,11 +197,41 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-main {
|
.app-main {
|
||||||
|
flex: 1;
|
||||||
max-width: 72rem;
|
max-width: 72rem;
|
||||||
margin: 1.5rem auto;
|
margin: 1.5rem auto;
|
||||||
padding: 0 1.5rem;
|
padding: 0 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── App footer ───────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.app-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
font-size: 0.6875rem;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
border-top: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-footer__sep {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-footer__commit,
|
||||||
|
.app-footer__repo {
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.app-footer__commit:hover,
|
||||||
|
a.app-footer__repo:hover {
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Queue header ─────────────────────────────────────────────────────────── */
|
/* ── Queue header ─────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
.queue-header {
|
.queue-header {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import MomentDetail from "./pages/MomentDetail";
|
||||||
import AdminReports from "./pages/AdminReports";
|
import AdminReports from "./pages/AdminReports";
|
||||||
import AdminPipeline from "./pages/AdminPipeline";
|
import AdminPipeline from "./pages/AdminPipeline";
|
||||||
import AdminDropdown from "./components/AdminDropdown";
|
import AdminDropdown from "./components/AdminDropdown";
|
||||||
|
import AppFooter from "./components/AppFooter";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -50,6 +51,8 @@ export default function App() {
|
||||||
<Route path="*" element={<Navigate to="/" replace />} />
|
<Route path="*" element={<Navigate to="/" replace />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<AppFooter />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
47
frontend/src/components/AppFooter.tsx
Normal file
47
frontend/src/components/AppFooter.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
const REPO_URL = "https://github.com/xpltdco/chrysopedia";
|
||||||
|
|
||||||
|
export default function AppFooter() {
|
||||||
|
const commitUrl =
|
||||||
|
__GIT_COMMIT__ !== "dev"
|
||||||
|
? `${REPO_URL}/commit/${__GIT_COMMIT__}`
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<footer className="app-footer">
|
||||||
|
<span className="app-footer__version">
|
||||||
|
v{__APP_VERSION__}
|
||||||
|
</span>
|
||||||
|
<span className="app-footer__sep">·</span>
|
||||||
|
<span className="app-footer__date">
|
||||||
|
Built {__BUILD_DATE__.slice(0, 10)}
|
||||||
|
</span>
|
||||||
|
{commitUrl ? (
|
||||||
|
<>
|
||||||
|
<span className="app-footer__sep">·</span>
|
||||||
|
<a
|
||||||
|
href={commitUrl}
|
||||||
|
className="app-footer__commit"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{__GIT_COMMIT__}
|
||||||
|
</a>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span className="app-footer__sep">·</span>
|
||||||
|
<span className="app-footer__commit">{__GIT_COMMIT__}</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<span className="app-footer__sep">·</span>
|
||||||
|
<a
|
||||||
|
href={REPO_URL}
|
||||||
|
className="app-footer__repo"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
4
frontend/src/vite-env.d.ts
vendored
4
frontend/src/vite-env.d.ts
vendored
|
|
@ -1 +1,5 @@
|
||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
declare const __APP_VERSION__: string;
|
||||||
|
declare const __BUILD_DATE__: string;
|
||||||
|
declare const __GIT_COMMIT__: string;
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/client.ts","./src/api/public-client.ts","./src/components/AdminDropdown.tsx","./src/components/ModeToggle.tsx","./src/components/ReportIssueModal.tsx","./src/components/StatusBadge.tsx","./src/pages/AdminPipeline.tsx","./src/pages/AdminReports.tsx","./src/pages/CreatorDetail.tsx","./src/pages/CreatorsBrowse.tsx","./src/pages/Home.tsx","./src/pages/MomentDetail.tsx","./src/pages/ReviewQueue.tsx","./src/pages/SearchResults.tsx","./src/pages/TechniquePage.tsx","./src/pages/TopicsBrowse.tsx"],"version":"5.6.3"}
|
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/client.ts","./src/api/public-client.ts","./src/components/AdminDropdown.tsx","./src/components/AppFooter.tsx","./src/components/ModeToggle.tsx","./src/components/ReportIssueModal.tsx","./src/components/StatusBadge.tsx","./src/pages/AdminPipeline.tsx","./src/pages/AdminReports.tsx","./src/pages/CreatorDetail.tsx","./src/pages/CreatorsBrowse.tsx","./src/pages/Home.tsx","./src/pages/MomentDetail.tsx","./src/pages/ReviewQueue.tsx","./src/pages/SearchResults.tsx","./src/pages/TechniquePage.tsx","./src/pages/TopicsBrowse.tsx"],"version":"5.6.3"}
|
||||||
|
|
@ -1,8 +1,40 @@
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
|
import { execSync } from "child_process";
|
||||||
|
import { readFileSync } from "fs";
|
||||||
|
import { resolve } from "path";
|
||||||
|
|
||||||
|
function getGitCommit(): string {
|
||||||
|
// In Docker builds, VITE_GIT_COMMIT is set via ENV from the build ARG
|
||||||
|
if (process.env.VITE_GIT_COMMIT) {
|
||||||
|
return process.env.VITE_GIT_COMMIT;
|
||||||
|
}
|
||||||
|
// Local dev: try git
|
||||||
|
try {
|
||||||
|
return execSync("git rev-parse --short HEAD", { encoding: "utf-8" }).trim();
|
||||||
|
} catch {
|
||||||
|
return "dev";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAppVersion(): string {
|
||||||
|
try {
|
||||||
|
const pkg = JSON.parse(
|
||||||
|
readFileSync(resolve(__dirname, "package.json"), "utf-8"),
|
||||||
|
);
|
||||||
|
return pkg.version ?? "0.0.0";
|
||||||
|
} catch {
|
||||||
|
return "0.0.0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
|
define: {
|
||||||
|
__APP_VERSION__: JSON.stringify(getAppVersion()),
|
||||||
|
__BUILD_DATE__: JSON.stringify(new Date().toISOString()),
|
||||||
|
__GIT_COMMIT__: JSON.stringify(getGitCommit()),
|
||||||
|
},
|
||||||
server: {
|
server: {
|
||||||
proxy: {
|
proxy: {
|
||||||
"/api": {
|
"/api": {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue