Skip to content

Commit c6f9010

Browse files
Merge pull request #211 from CodeForPhilly/branding-ux-updates
feat: Updated styling of Navbars and Header to Match BDT branding more closely
2 parents 4dde377 + 1d36806 commit c6f9010

File tree

7 files changed

+172
-79
lines changed

7 files changed

+172
-79
lines changed

builder-frontend/src/assets/logos/bdt-logo-large-mono-dark.svg

Lines changed: 28 additions & 0 deletions
Loading

builder-frontend/src/assets/logos/bdt-logo-large-mono-light.svg

Lines changed: 28 additions & 0 deletions
Loading

builder-frontend/src/components/Header.tsx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { useAuth } from "../context/AuthContext";
2-
import { useNavigate } from "@solidjs/router";
2+
import { useLocation, useNavigate } from "@solidjs/router";
3+
4+
import bdtLogo from "../assets/logos/bdt-logo-large-mono-light.svg";
5+
import { Show } from "solid-js";
36

47

58
const HeaderButton = ({ buttonText, onClick }: { buttonText: string; onClick: () => void }) => {
69
return (
710
<div
811
onClick={onClick}
912
class="
10-
h-full px-4 text-sm font-bold text-gray-500
13+
px-4 py-3 text-md font-bold text-gray-700 rounded-md
1114
flex items-center
1215
hover:bg-gray-300 cursor-pointer select-none"
1316
>
@@ -20,20 +23,23 @@ export default function Header() {
2023
const { logout } = useAuth();
2124
const navigate = useNavigate();
2225

26+
const location = useLocation();
27+
const isNotRoot = location.pathname !== "/";
28+
2329
const handleLogout = () => {
2430
logout();
2531
navigate("/login", { replace: true });
2632
};
2733

2834
return (
29-
<header class="bg-gray-200 min-h-18 h-18 px-4 flex items-center justify-between">
35+
<header class="bg-gray-200 min-h-24 h-24 px-4 flex items-center justify-between border-b-2 border-gray-300">
3036
<div class="flex items-center space-x-6">
31-
<span class="text-lg font-bold text-gray-600">
32-
Benefit Decision Toolkit
33-
</span>
37+
<img src={bdtLogo} alt="" class="w-36" />
3438
</div>
3539
<div class="flex items-center h-full">
36-
<HeaderButton buttonText="← Back to Home" onClick={() => navigate("/")} />
40+
<Show when={isNotRoot}>
41+
<HeaderButton buttonText="← Back to Home" onClick={() => navigate("/")} />
42+
</Show>
3743
<HeaderButton buttonText="Logout" onClick={handleLogout} />
3844
</div>
3945
</header>

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

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

33
import EligibilityChecksList from "./eligibilityCheckList/EligibilityChecksList";
44
import ProjectsList from "./ProjectsList"
55
import Header from "../Header";
66

7+
import BdtNavbar, { NavbarProps } from "@/components/shared/BdtNavbar";0
8+
79
const HomeScreen = () => {
8-
const [screenMode, setScreenMode] = createSignal<"projects" | "checks">("projects");
10+
const [screenMode, setScreenMode] = createSignal<"screeners" | "checks">("screeners");
11+
12+
const navbarDefs: Accessor<NavbarProps> = () => {
13+
return {
14+
tabDefs: [
15+
{ key: "screeners", label: "Screeners", onClick: () => setScreenMode("screeners") },
16+
{ key: "checks", label: "Eligibility checks", onClick: () => setScreenMode("checks") },
17+
],
18+
activeTabKey: () => screenMode(),
19+
titleDef: null,
20+
}
21+
};
22+
923
return (
1024
<div>
1125
<Header/>
12-
<div class="flex space-x-4 p-4 border-b-2 border-gray-200">
13-
<div
14-
class={`btn-default ${screenMode() === "projects" ? "btn-blue" : "btn-gray"}`}
15-
onClick={() => setScreenMode("projects")}
16-
>
17-
Projects List
18-
</div>
19-
<div
20-
class={`btn-default ${screenMode() === "checks" ? "btn-blue" : "btn-gray"}`}
21-
onClick={() => setScreenMode("checks")}
22-
>
23-
Eligibility Checks List
24-
</div>
25-
</div>
26+
<BdtNavbar navProps={navbarDefs} />
2627
<Switch>
27-
<Match when={screenMode() === "projects"}>
28+
<Match when={screenMode() === "screeners"}>
2829
<ProjectsList />
2930
</Match>
3031
<Match when={screenMode() === "checks"}>

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

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createSignal, Match, Show, Switch } from "solid-js";
1+
import { Accessor, createSignal, Match, Show, Switch } from "solid-js";
22
import { useParams } from "@solidjs/router";
33

44
import { clsx } from "clsx";
@@ -11,18 +11,19 @@ import EligibilityCheckTest from "./checkTesting/EligibilityCheckTest";
1111
import PublishCheck from "./PublishCheck";
1212

1313
import eligibilityCheckDetailResource from "./eligibilityCheckDetailResource";
14+
import ParametersConfiguration from "./ParametersConfiguration";
1415

1516
import ErrorDisplayModal from "@/components/shared/ErrorModal";
16-
import ParametersConfiguration from "./ParametersConfiguration";
17+
import BdtNavbar, { NavbarProps } from "@/components/shared/BdtNavbar";
1718

1819

19-
type CheckDetailScreenMode = "Parameter Configuration" | "DMN Definition" | "Testing" | "Publish";
20+
type CheckDetailScreenMode = "paramConfig" | "dmnDefinition" | "testing" | "publish";
2021

2122
const EligibilityCheckDetail = () => {
2223
const { checkId } = useParams();
2324

2425
const [currentDmnModel, setCurrentDmnModel] = createSignal<string>("");
25-
const [screenMode, setScreenMode] = createSignal<CheckDetailScreenMode>("Parameter Configuration");
26+
const [screenMode, setScreenMode] = createSignal<CheckDetailScreenMode>("paramConfig");
2627

2728
const [validationErrors, setValidationErrors] = createSignal<string[]>([]);
2829
const [showingErrorModal, setShowingErrorModal] = createSignal<boolean>(false);
@@ -44,40 +45,40 @@ const EligibilityCheckDetail = () => {
4445
}
4546
}
4647

48+
const navbarDefs: Accessor<NavbarProps> = () => {
49+
return {
50+
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") },
55+
],
56+
activeTabKey: () => screenMode(),
57+
titleDef: { label: eligibilityCheck().name },
58+
};
59+
};
60+
4761
return (
4862
<div class="h-screen flex flex-col">
4963
<Show when={initialLoadStatus.loading() || actionInProgress()}>
5064
<Loading />
5165
</Show>
5266
<Header />
53-
<div class="flex border-b border-gray-200">
54-
{["Parameter Configuration", "DMN Definition", "Testing", "Publish"].map((tab: CheckDetailScreenMode) => (
55-
<button
56-
class={`px-4 py-2 -mb-px text-sm font-medium border-b-2 transition-colors ${
57-
screenMode() === tab
58-
? "border-b border-gray-700 text-gray-700 hover:bg-gray-200"
59-
: "border-transparent text-gray-500 hover:text-gray-700 hover:bg-gray-200"
60-
}`}
61-
onClick={() => setScreenMode(tab)}
62-
>
63-
{tab.charAt(0).toUpperCase() + tab.slice(1)}
64-
</button>
65-
))}
66-
</div>
6767

68+
<BdtNavbar navProps={navbarDefs} />
6869
<Show when={ eligibilityCheck().id !== undefined && !initialLoadStatus.loading() }>
6970
<Switch>
70-
<Match when={screenMode() === "Parameter Configuration"}>
71+
<Match when={screenMode() === "paramConfig"}>
7172
<ParametersConfiguration
7273
eligibilityCheck={eligibilityCheck}
7374
addParameter={actions.addParameter}
7475
editParameter={actions.updateParameter}
7576
removeParameter={actions.removeParameter}
7677
/>
7778
</Match>
78-
<Match when={screenMode() === "DMN Definition"}>
79+
<Match when={screenMode() === "dmnDefinition"}>
7980
<>
80-
<div class="flex space-x-4 p-4 border-b-2 border-gray-200">
81+
<div class="flex space-x-4 px-4 py-3 border-b-2 border-gray-200">
8182
<div
8283
class="btn-default btn-blue"
8384
onClick={() => validateDmnModel(currentDmnModel())}
@@ -97,13 +98,13 @@ const EligibilityCheckDetail = () => {
9798
/>
9899
</>
99100
</Match>
100-
<Match when={screenMode() === "Testing"}>
101+
<Match when={screenMode() === "testing"}>
101102
<EligibilityCheckTest
102103
eligibilityCheck={eligibilityCheck}
103104
testEligibility={actions.testEligibility}
104105
/>
105106
</Match>
106-
<Match when={screenMode() === "Publish"}>
107+
<Match when={screenMode() === "publish"}>
107108
<PublishCheck
108109
eligibilityCheck={eligibilityCheck}
109110
publishCheck={actions.publishCheck}

builder-frontend/src/components/project/Project.tsx

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createSignal, createResource } from "solid-js";
1+
import { createSignal, createResource, Accessor } from "solid-js";
22
import { useParams } from "@solidjs/router";
33

44
import FormEditorView from "./FormEditorView";
@@ -9,14 +9,15 @@ import Preview from "./preview/Preview";
99
import Publish from "./Publish";
1010

1111
import { fetchProject } from "@/api/screener";
12+
import BdtNavbar, { NavbarProps } from "@/components/shared/BdtNavbar";
1213

1314

14-
type TabOption = "Manage Benefits" | "Form Editor" | "Preview" | "Publish";
15+
type TabOption = "manageBenefits" | "formEditor" | "preview" | "publish";
1516

1617
function Project() {
1718
const params = useParams();
1819

19-
const [activeTab, setActiveTab] = createSignal<TabOption>("Manage Benefits");
20+
const [activeTab, setActiveTab] = createSignal<TabOption>("manageBenefits");
2021
const [formSchema, setFormSchema] = createSignal();
2122
const [forceUpdate, setForceUpdate] = createSignal(0);
2223

@@ -36,8 +37,17 @@ function Project() {
3637
fetchAndCacheProject
3738
);
3839

39-
const handleSelectTab = (tab) => {
40-
setActiveTab(tab);
40+
const navbarDefs: Accessor<NavbarProps> = () => {
41+
return {
42+
tabDefs: [
43+
{ key: "manageBenefits", label: "Manage Benefits", onClick: () => setActiveTab("manageBenefits") },
44+
{ key: "formEditor", label: "Form Editor", onClick: () => setActiveTab("formEditor") },
45+
{ key: "preview", label: "Preview", onClick: () => setActiveTab("preview") },
46+
{ key: "publish", label: "Publish", onClick: () => setActiveTab("publish") },
47+
],
48+
activeTabKey: () => activeTab(),
49+
titleDef: { label: project().screenerName },
50+
};
4151
};
4252

4353
return (
@@ -47,42 +57,20 @@ function Project() {
4757
<Loading/>
4858
) : (
4959
<>
50-
<div class="flex border-b border-gray-200">
51-
<span class="py-2 px-4 font-bold text-gray-600">
52-
{" "}
53-
{project().screenerName}
54-
</span>
55-
{[
56-
"Manage Benefits",
57-
"Form Editor",
58-
"Preview",
59-
"Publish",
60-
].map((tab) => (
61-
<button
62-
class={`px-4 py-2 -mb-px text-sm font-medium border-b-2 transition-colors ${
63-
activeTab() === tab
64-
? "border-b border-gray-700 text-gray-700 hover:bg-gray-200"
65-
: "border-transparent text-gray-500 hover:text-gray-700 hover:bg-gray-200"
66-
}`}
67-
onClick={() => handleSelectTab(tab)}
68-
>
69-
{tab.charAt(0).toUpperCase() + tab.slice(1)}
70-
</button>
71-
))}
72-
</div>
73-
{activeTab() == "Form Editor" && (
60+
<BdtNavbar navProps={navbarDefs} />
61+
{activeTab() == "formEditor" && (
7462
<FormEditorView
7563
formSchema={formSchema}
7664
setFormSchema={setFormSchema}
7765
/>
7866
)}
79-
{activeTab() == "Manage Benefits" && (
67+
{activeTab() == "manageBenefits" && (
8068
<ManageBenefits />
8169
)}
82-
{activeTab() == "Preview" && (
70+
{activeTab() == "preview" && (
8371
<Preview project={project} formSchema={formSchema}/>
8472
)}
85-
{activeTab() == "Publish" && (
73+
{activeTab() == "publish" && (
8674
<Publish
8775
project={project}
8876
refetchProject={() => setForceUpdate((prev) => prev + 1)}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Accessor, Show } from "solid-js";
2+
3+
export interface NavbarProps {
4+
tabDefs: NavbarButtonDef[];
5+
activeTabKey: Accessor<string>;
6+
titleDef: NavbarTitleDef | null;
7+
}
8+
interface NavbarTitleDef {
9+
label: string;
10+
}
11+
interface NavbarButtonDef {
12+
key: string;
13+
label: string;
14+
onClick: () => void;
15+
};
16+
17+
const BdtNavbar = ({navProps}: {navProps: Accessor<NavbarProps>}) => {
18+
return (
19+
<div class="flex border-b border-gray-300">
20+
<Show when={navProps().titleDef !== null}>
21+
<div class="py-2 px-4 font-bold text-gray-700 cursor-default">
22+
{navProps().titleDef!.label}
23+
</div>
24+
</Show>
25+
{navProps().tabDefs.map((tab) => (
26+
<button
27+
class={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
28+
navProps().activeTabKey() === tab.key
29+
? "border-b border-gray-700 text-gray-700 hover:bg-gray-200"
30+
: "border-transparent text-gray-500 hover:text-gray-700 hover:bg-gray-200"
31+
}`}
32+
onClick={tab.onClick}
33+
>
34+
{tab.label.charAt(0).toUpperCase() + tab.label.slice(1)}
35+
</button>
36+
))}
37+
</div>
38+
);
39+
}
40+
41+
export default BdtNavbar;

0 commit comments

Comments
 (0)