Initial setup
This commit is contained in:
@@ -60,12 +60,22 @@ export const PageHeader: React.FC<PageHeaderProps> = ({
|
||||
const setNavOpen = onNavOpenChange ?? setInternalNavOpen;
|
||||
const { version, updateAvailable } = useVersionCheck();
|
||||
|
||||
const handleNavClick = (to: string, activePaths?: string[]) => {
|
||||
const handleNavClick = (
|
||||
to: string,
|
||||
activePaths?: string[],
|
||||
external?: boolean,
|
||||
) => {
|
||||
if (isNavActive(location.pathname, to, activePaths)) {
|
||||
setNavOpen(false);
|
||||
return;
|
||||
}
|
||||
setNavOpen(false);
|
||||
if (external) {
|
||||
setTimeout(() => {
|
||||
window.location.href = to;
|
||||
}, 150);
|
||||
return;
|
||||
}
|
||||
setTimeout(() => navigate(to), 150);
|
||||
};
|
||||
|
||||
@@ -85,22 +95,24 @@ export const PageHeader: React.FC<PageHeaderProps> = ({
|
||||
<SheetTitle>JobOps</SheetTitle>
|
||||
</SheetHeader>
|
||||
<nav className="mt-6 flex flex-col gap-2">
|
||||
{NAV_LINKS.map(({ to, label, icon: NavIcon, activePaths }) => (
|
||||
<button
|
||||
key={to}
|
||||
type="button"
|
||||
onClick={() => handleNavClick(to, activePaths)}
|
||||
className={cn(
|
||||
"flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground text-left",
|
||||
isNavActive(location.pathname, to, activePaths)
|
||||
? "bg-accent text-accent-foreground"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
<NavIcon className="h-4 w-4" />
|
||||
{label}
|
||||
</button>
|
||||
))}
|
||||
{NAV_LINKS.map(
|
||||
({ to, label, icon: NavIcon, activePaths, external }) => (
|
||||
<button
|
||||
key={to}
|
||||
type="button"
|
||||
onClick={() => handleNavClick(to, activePaths, external)}
|
||||
className={cn(
|
||||
"flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground text-left",
|
||||
isNavActive(location.pathname, to, activePaths)
|
||||
? "bg-accent text-accent-foreground"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
<NavIcon className="h-4 w-4" />
|
||||
{label}
|
||||
</button>
|
||||
),
|
||||
)}
|
||||
</nav>
|
||||
{showVersionFooter && (
|
||||
<div className="mt-auto pt-6 pb-2">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
BookOpen,
|
||||
Columns3,
|
||||
Home,
|
||||
Inbox,
|
||||
@@ -12,6 +13,7 @@ export type NavLink = {
|
||||
label: string;
|
||||
icon: typeof Home;
|
||||
activePaths?: string[];
|
||||
external?: boolean;
|
||||
};
|
||||
|
||||
export const NAV_LINKS: NavLink[] = [
|
||||
@@ -34,6 +36,7 @@ export const NAV_LINKS: NavLink[] = [
|
||||
activePaths: ["/applications/in-progress"],
|
||||
},
|
||||
{ to: "/tracking-inbox", label: "Tracking Inbox", icon: Inbox },
|
||||
{ to: "/docs", label: "Documentation", icon: BookOpen, external: true },
|
||||
{ to: "/visa-sponsors", label: "Visa Sponsors", icon: Shield },
|
||||
{ to: "/settings", label: "Settings", icon: Settings },
|
||||
];
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
* Express app factory (useful for tests).
|
||||
*/
|
||||
|
||||
import { existsSync } from "node:fs";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { dirname, join } from "node:path";
|
||||
import { dirname, extname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { unauthorized } from "@infra/errors";
|
||||
import {
|
||||
@@ -136,6 +137,33 @@ export function createApp() {
|
||||
|
||||
// Serve client app in production
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
const packagedDocsDir = join(__dirname, "../../dist/docs");
|
||||
const workspaceDocsDir = join(__dirname, "../../../docs-site/build");
|
||||
const docsDir = existsSync(packagedDocsDir)
|
||||
? packagedDocsDir
|
||||
: workspaceDocsDir;
|
||||
const docsIndexPath = join(docsDir, "index.html");
|
||||
let cachedDocsIndexHtml: string | null = null;
|
||||
|
||||
if (existsSync(docsIndexPath)) {
|
||||
app.use("/docs", express.static(docsDir));
|
||||
app.get("/docs/*", async (req, res, next) => {
|
||||
if (!req.accepts("html")) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
if (extname(req.path)) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
if (!cachedDocsIndexHtml) {
|
||||
cachedDocsIndexHtml = await readFile(docsIndexPath, "utf-8");
|
||||
}
|
||||
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
||||
res.send(cachedDocsIndexHtml);
|
||||
});
|
||||
}
|
||||
|
||||
const clientDir = join(__dirname, "../../dist/client");
|
||||
app.use(express.static(clientDir));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user