Skip to content

Commit 730ae24

Browse files
authored
Merge pull request #336 from CodeForPhilly/feat/display-account-in-header
Feat/display account in header * New <HamburgerMenu> component * Added account email (and name if Google account) to menu * Moved logout and docs links to menu
2 parents 3b8cf57 + c454b3e commit 730ae24

File tree

14 files changed

+391
-91
lines changed

14 files changed

+391
-91
lines changed

builder-frontend/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builder-frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"fast-xml-parser": "^5.2.5",
2323
"firebase": "^11.9.1",
2424
"lodash.debounce": "^4.0.8",
25+
"lucide-solid": "^1.7.0",
2526
"solid-bootstrap": "^1.0.21",
2627
"solid-js": "^1.9.5",
2728
"solid-toast": "^0.5.0",

builder-frontend/src/components/Header.tsx

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@import "tailwindcss";
2+
3+
.header-user-email {
4+
width: 75%;
5+
overflow-wrap: break-word;
6+
@apply mt-2;
7+
}
8+
9+
.header-menu ul {
10+
@apply p-0;
11+
}
12+
.header-menu-item {
13+
width: 100%;
14+
@apply p-2 rounded-sm list-none;
15+
}
16+
.header-menu-item:hover {
17+
@apply bg-slate-200 cursor-pointer;
18+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { useAuth } from "../../context/AuthContext";
2+
import { useLocation, useNavigate } from "@solidjs/router";
3+
import { Component, For, Show } from "solid-js";
4+
5+
import bdtLogo from "@/assets/logos/bdt-logo-large-mono-light.svg";
6+
import { HamburgerMenu } from "@/components/shared/HamburgerMenu";
7+
8+
import "./Header.css";
9+
import { Menu } from "lucide-solid";
10+
11+
const HeaderButton = ({
12+
buttonText,
13+
onClick,
14+
}: {
15+
buttonText: string;
16+
onClick: () => void;
17+
}) => {
18+
return (
19+
<div
20+
onClick={onClick}
21+
class="
22+
px-4 py-3 text-md font-bold text-gray-700 rounded-md
23+
flex items-center
24+
hover:bg-gray-300 cursor-pointer select-none"
25+
>
26+
{buttonText}
27+
</div>
28+
);
29+
};
30+
31+
interface MenuProps {
32+
userEmail: string;
33+
displayName: string | null;
34+
logout: () => void;
35+
}
36+
37+
const HeaderMenu: Component<MenuProps> = (props) => {
38+
const menuItems: { label: string; onClick: () => void }[] = [
39+
{
40+
label: "User Guide",
41+
onClick: () => window.open("https://bdt-docs.web.app/", "_blank"),
42+
},
43+
{ label: "Logout", onClick: props.logout },
44+
];
45+
46+
return (
47+
<div class="header-menu">
48+
<div class="header-user-email" title={props.userEmail}>
49+
Welcome {props.displayName} {props.userEmail}
50+
</div>
51+
<hr />
52+
<ul>
53+
<For each={menuItems}>
54+
{(menuItem) => (
55+
<li class="header-menu-item" onClick={menuItem.onClick}>
56+
{menuItem.label}
57+
</li>
58+
)}
59+
</For>
60+
</ul>
61+
</div>
62+
);
63+
};
64+
65+
export default function Header() {
66+
const auth = useAuth();
67+
const userEmail = auth.user().email;
68+
const displayName = auth.user().displayName;
69+
const { logout } = auth;
70+
71+
const navigate = useNavigate();
72+
73+
const location = useLocation();
74+
const isNotRoot = location.pathname !== "/";
75+
76+
const handleLogout = () => {
77+
logout();
78+
navigate("/login", { replace: true });
79+
};
80+
81+
return (
82+
<header class="bg-gray-200 min-h-24 h-24 px-4 flex items-center justify-between border-b-2 border-gray-300">
83+
<div class="flex items-center space-x-6">
84+
<img
85+
src={bdtLogo}
86+
alt="BDT logo"
87+
class="w-36 cursor-pointer"
88+
onClick={() => navigate("/")}
89+
/>
90+
</div>
91+
<div class="flex items-center h-full">
92+
<Show when={isNotRoot}>
93+
<HeaderButton
94+
buttonText="← Back to Home"
95+
onClick={() => navigate("/")}
96+
/>
97+
</Show>
98+
99+
<HamburgerMenu>
100+
<HamburgerMenu.Button>
101+
<Menu />
102+
</HamburgerMenu.Button>
103+
<HamburgerMenu.Panel>
104+
<HeaderMenu
105+
userEmail={userEmail}
106+
displayName={displayName}
107+
logout={handleLogout}
108+
/>
109+
</HamburgerMenu.Panel>
110+
</HamburgerMenu>
111+
</div>
112+
</header>
113+
);
114+
}

builder-frontend/src/components/homeScreen/HomeScreen.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { Accessor, createSignal, Match, Switch } from "solid-js";
22

33
import EligibilityChecksList from "./eligibilityCheckList/EligibilityChecksList";
44
import ProjectsList from "./ProjectsList";
5-
import Header from "../Header";
5+
import Header from "../Header/Header";
66

77
import BdtNavbar, { NavbarProps } from "@/components/shared/BdtNavbar";
88
0;
99

1010
const HomeScreen = () => {
1111
const [screenMode, setScreenMode] = createSignal<"screeners" | "checks">(
12-
"screeners"
12+
"screeners",
1313
);
1414

1515
const navbarDefs: Accessor<NavbarProps> = () => {

builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckDetail/EligibilityCheckDetail.tsx

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useParams } from "@solidjs/router";
44
import { clsx } from "clsx";
55
import toast from "solid-toast";
66

7-
import Header from "../../../Header";
7+
import Header from "../../../Header/Header";
88
import Loading from "../../../Loading";
99
import KogitoDmnEditorView from "./KogitoDmnEditorView";
1010
import EligibilityCheckTest from "./checkTesting/EligibilityCheckTest";
@@ -16,17 +16,22 @@ import ParametersConfiguration from "./ParametersConfiguration";
1616
import ErrorDisplayModal from "@/components/shared/ErrorModal";
1717
import BdtNavbar, { NavbarProps } from "@/components/shared/BdtNavbar";
1818

19-
20-
type CheckDetailScreenMode = "paramConfig" | "dmnDefinition" | "testing" | "publish";
19+
type CheckDetailScreenMode =
20+
| "paramConfig"
21+
| "dmnDefinition"
22+
| "testing"
23+
| "publish";
2124

2225
const EligibilityCheckDetail = () => {
2326
const { checkId } = useParams();
2427

2528
const [currentDmnModel, setCurrentDmnModel] = createSignal<string>("");
26-
const [screenMode, setScreenMode] = createSignal<CheckDetailScreenMode>("paramConfig");
29+
const [screenMode, setScreenMode] =
30+
createSignal<CheckDetailScreenMode>("paramConfig");
2731

2832
const [validationErrors, setValidationErrors] = createSignal<string[]>([]);
29-
const [showingErrorModal, setShowingErrorModal] = createSignal<boolean>(false);
33+
const [showingErrorModal, setShowingErrorModal] =
34+
createSignal<boolean>(false);
3035

3136
const { eligibilityCheck, actions, actionInProgress, initialLoadStatus } =
3237
eligibilityCheckDetailResource(() => checkId);
@@ -43,15 +48,31 @@ const EligibilityCheckDetail = () => {
4348
} else {
4449
toast.success("No validation errors found in DMN model.");
4550
}
46-
}
51+
};
4752

4853
const navbarDefs: Accessor<NavbarProps> = () => {
4954
return {
5055
tabDefs: [
51-
{ key: "paramConfig", label: "Parameter Configuration", onClick: () => setScreenMode("paramConfig") },
52-
{ key: "dmnDefinition", label: "DMN Definition", onClick: () => setScreenMode("dmnDefinition") },
53-
{ key: "testing", label: "Testing", onClick: () => setScreenMode("testing") },
54-
{ key: "publish", label: "Publish", onClick: () => setScreenMode("publish") },
56+
{
57+
key: "paramConfig",
58+
label: "Parameter Configuration",
59+
onClick: () => setScreenMode("paramConfig"),
60+
},
61+
{
62+
key: "dmnDefinition",
63+
label: "DMN Definition",
64+
onClick: () => setScreenMode("dmnDefinition"),
65+
},
66+
{
67+
key: "testing",
68+
label: "Testing",
69+
onClick: () => setScreenMode("testing"),
70+
},
71+
{
72+
key: "publish",
73+
label: "Publish",
74+
onClick: () => setScreenMode("publish"),
75+
},
5576
],
5677
activeTabKey: () => screenMode(),
5778
titleDef: { label: eligibilityCheck().name },
@@ -66,7 +87,11 @@ const EligibilityCheckDetail = () => {
6687
<Header />
6788

6889
<BdtNavbar navProps={navbarDefs} />
69-
<Show when={ eligibilityCheck().id !== undefined && !initialLoadStatus.loading() }>
90+
<Show
91+
when={
92+
eligibilityCheck().id !== undefined && !initialLoadStatus.loading()
93+
}
94+
>
7095
<Switch>
7196
<Match when={screenMode() === "paramConfig"}>
7297
<ParametersConfiguration
@@ -86,7 +111,11 @@ const EligibilityCheckDetail = () => {
86111
Validate Current DMN
87112
</div>
88113
<div
89-
class={clsx("btn-default", { "btn-blue": !hasDmnModelChanged() }, { "btn-yellow": hasDmnModelChanged() })}
114+
class={clsx(
115+
"btn-default",
116+
{ "btn-blue": !hasDmnModelChanged() },
117+
{ "btn-yellow": hasDmnModelChanged() },
118+
)}
90119
onClick={() => actions.saveDmnModel(currentDmnModel())}
91120
>
92121
Save Changes

0 commit comments

Comments
 (0)