File size: 4,047 Bytes
7fabf33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { createContext, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
import { NavLink, useLocation } from "react-router-dom";
import type { PropsWithChildren, ReactNode } from "react";

const links = [
  {
    to: "/processos",
    label: "Processos",
    matches: (pathname: string) =>
      pathname === "/processos" ||
      pathname === "/backlog" ||
      pathname.startsWith("/trabalho/"),
  },
  { to: "/dashboard", label: "Fluxo de Processos", matches: (pathname: string) => pathname === "/dashboard" },
  {
    to: "/inscricoes",
    label: "Inscrições",
    matches: (pathname: string) => pathname === "/inscricoes" || pathname.startsWith("/inscricoes/"),
  },
  { to: "/visao-gs", label: "Visão GS", matches: (pathname: string) => pathname === "/visao-gs" },
  {
    to: "/cronogramas",
    label: "Cronogramas",
    matches: (pathname: string) =>
      pathname === "/cronogramas" ||
      pathname === "/equipe" ||
      pathname === "/metas" ||
      pathname.startsWith("/avaliadores/"),
  },
  { to: "/novo", label: "Novo processo", matches: (pathname: string) => pathname === "/novo" },
];

const PageHeaderActionContext = createContext<((action: ReactNode | null) => void) | null>(null);

export function usePageHeaderAction(action: ReactNode | null) {
  const setAction = useContext(PageHeaderActionContext);

  useLayoutEffect(() => {
    if (!setAction) return;
    setAction(action);
    return () => setAction(null);
  }, [action, setAction]);
}

export function Layout({ children }: PropsWithChildren) {
  const location = useLocation();
  const [headerAction, setHeaderAction] = useState<ReactNode | null>(null);
  const [headerCollapsed, setHeaderCollapsed] = useState(false);

  function pageTitle() {
    const { pathname } = location;
    if (pathname === "/processos" || pathname === "/backlog") return "Processos";
    if (pathname === "/dashboard") return "Fluxo de Processos";
    if (pathname === "/inscricoes") return "Inscrições";
    if (pathname === "/visao-gs") return "Visão GS";
    if (pathname === "/cronogramas" || pathname === "/equipe" || pathname === "/metas") return "Cronogramas";
    if (pathname === "/novo") return "Novo processo";
    if (pathname.startsWith("/avaliadores/")) return "Avaliador";
    if (pathname.startsWith("/trabalho/") && pathname.endsWith("/editar")) return "Editar processo";
    if (pathname.startsWith("/trabalho/")) return "Processo";
    return "SIPRAC";
  }

  const headerContextValue = useMemo(() => setHeaderAction, []);

  useEffect(() => {
    function handleScroll() {
      const currentScrollY = window.scrollY;
      setHeaderCollapsed(currentScrollY > 96);
    }

    handleScroll();
    window.addEventListener("scroll", handleScroll, { passive: true });

    return () => window.removeEventListener("scroll", handleScroll);
  }, [location.pathname]);

  return (
    <PageHeaderActionContext.Provider value={headerContextValue}>
      <div className={`app-shell${headerCollapsed ? " app-shell-header-collapsed" : ""}`}>
        <header className="app-header">
          <div className="app-header-inner">
            <div className="sidebar-brand">
              <h1>SIPRAC</h1>
              <p className="sidebar-copy">Sistema de Processos, Acompanhamento e Cronogramas</p>
            </div>

            <nav className="nav">
              {links.map((link) => (
                <NavLink
                  key={link.to}
                  to={link.to}
                  className={() => `nav-link${link.matches(location.pathname) ? " active" : ""}`}
                >
                  {link.label}
                </NavLink>
              ))}
            </nav>
          </div>
        </header>

        <main className="main-content">
          <header className="topbar">
            <h2>{pageTitle()}</h2>
            {headerAction ? <div className="topbar-action">{headerAction}</div> : null}
          </header>
          {children}
        </main>
      </div>
    </PageHeaderActionContext.Provider>
  );
}