Skip to content

Commit cc37f0c

Browse files
committed
Add ALL campus filter, multiple campus selection, person links in new tabs, and reposition growing arrow
1 parent dd9f5b1 commit cc37f0c

6 files changed

Lines changed: 65 additions & 29 deletions

File tree

src/App.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ import TeamNodeDrawer from "./components/TeamNodeDrawer.tsx";
77
import { PathwayProvider } from "./contexts/PathwayProvider.tsx";
88

99
function App() {
10-
const [selectedCampusId, setSelectedCampusId] = useState<string | null>("3");
10+
const [selectedCampusIds, setSelectedCampusIds] = useState<string[]>(["3"]);
1111

1212
return (
1313
<PathwayProvider>
1414
<ReactFlowProvider>
1515
<div className="h-screen w-screen flex flex-col overflow-hidden">
1616
{/* Campus Filter Buttons */}
1717
<CampusFilterButtons
18-
onCampusFilter={setSelectedCampusId}
19-
selectedCampusId={selectedCampusId}
18+
onCampusFilter={setSelectedCampusIds}
19+
selectedCampusIds={selectedCampusIds}
2020
/>
2121

2222
{/* React Flow Container */}
2323
<div className="flex-1 w-full overflow-hidden">
24-
<PeopleFlow campusFilter={selectedCampusId} />
24+
<PeopleFlow campusFilter={selectedCampusIds} />
2525
</div>
2626

2727
{/* Team Node Drawer */}

src/components/CampusFilterButtons.tsx

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,65 @@
11
interface CampusFilterButtonsProps {
2-
onCampusFilter: (campusId: string | null) => void;
3-
selectedCampusId?: string | null;
2+
onCampusFilter: (campusIds: string[]) => void;
3+
selectedCampusIds: string[];
44
}
55

66
const CampusFilterButtons = ({
77
onCampusFilter,
8-
selectedCampusId,
8+
selectedCampusIds,
99
}: CampusFilterButtonsProps) => {
1010
const campuses = [
1111
{ id: "3", label: "Central" },
1212
{ id: "2", label: "North" },
1313
{ id: "4", label: "Unichurch" },
1414
];
1515

16+
const handleCampusToggle = (campusId: string) => {
17+
if (selectedCampusIds.includes(campusId)) {
18+
// Remove campus from selection
19+
onCampusFilter(selectedCampusIds.filter((id) => id !== campusId));
20+
} else {
21+
// Add campus to selection
22+
onCampusFilter([...selectedCampusIds, campusId]);
23+
}
24+
};
25+
26+
const handleAllToggle = () => {
27+
if (selectedCampusIds.length === campuses.length) {
28+
// If all are selected, deselect all
29+
onCampusFilter([]);
30+
} else {
31+
// Select all campuses
32+
onCampusFilter(campuses.map((campus) => campus.id));
33+
}
34+
};
35+
36+
const allSelected = selectedCampusIds.length === campuses.length;
37+
1638
return (
1739
<div className="absolute z-10 bottom-2 left-2 sm:bottom-4 sm:left-4 flex flex-row gap-1 sm:gap-2">
40+
{/* ALL Button */}
41+
<button
42+
type="button"
43+
onClick={handleAllToggle}
44+
className={`font-bold py-1.5 px-3 sm:py-2 sm:px-4 rounded-md shadow-lg text-sm sm:text-base border-0 focus:outline-none ${
45+
allSelected
46+
? "bg-green-500 text-white"
47+
: "bg-gray-300 hover:bg-gray-400 text-white cursor-pointer"
48+
}`}
49+
>
50+
ALL
51+
</button>
52+
53+
{/* Individual Campus Buttons */}
1854
{campuses.map((campus) => (
1955
<button
2056
key={campus.id}
2157
type="button"
22-
onClick={() =>
23-
{ onCampusFilter(selectedCampusId === campus.id ? null : campus.id); }
24-
}
25-
className={`font-bold py-1 px-2 sm:py-1.5 sm:px-3 rounded-md shadow-lg text-xs sm:text-sm border-0 focus:outline-none ${
26-
selectedCampusId === campus.id
58+
onClick={() => {
59+
handleCampusToggle(campus.id);
60+
}}
61+
className={`font-bold py-1.5 px-3 sm:py-2 sm:px-4 rounded-md shadow-lg text-sm sm:text-base border-0 focus:outline-none ${
62+
selectedCampusIds.includes(campus.id)
2763
? "bg-blue-500 text-white"
2864
: "bg-gray-300 hover:bg-gray-400 text-white cursor-pointer"
2965
}`}

src/components/PeopleFlow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const nodeTypes = {
2323
};
2424

2525
interface PeopleFlowProps {
26-
campusFilter?: string | null;
26+
campusFilter?: string[];
2727
}
2828

2929
const PeopleFlow = ({ campusFilter }: PeopleFlowProps) => {

src/components/PeopleList/PeopleListItem/PeopleListItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function PeopleListItem({ person, survey, label }: PeopleListItemProps) {
1616
<a
1717
className="flex items-center gap-2 grow cursor-pointer"
1818
href={`https://rock.ev.church/Person/${person.id.toString()}`}
19-
target="_parent"
19+
target="_blank"
2020
rel="noopener noreferrer"
2121
>
2222
<img
@@ -47,7 +47,7 @@ function PeopleListItem({ person, survey, label }: PeopleListItemProps) {
4747
{hasDoneSurvey ? (
4848
<a
4949
href={`https://rock.ev.church/Workflow/${survey.formId}`}
50-
target="_parent"
50+
target="_blank"
5151
rel="noopener noreferrer"
5252
className={`text-xs p-1 font-semibold cursor-pointer transition-colors flex items-center justify-center w-6 rounded ${
5353
person.isServing

src/hooks/usePeopleFlowData.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const messageEventDataSchema = z.object({
4141
data: z.unknown(),
4242
});
4343

44-
export function usePeopleFlowData(campusFilter?: string | null): {
44+
export function usePeopleFlowData(campusFilter?: string[]): {
4545
data: PeopleFlowData;
4646
isLoading: boolean;
4747
error: Error | undefined;
@@ -54,14 +54,14 @@ export function usePeopleFlowData(campusFilter?: string | null): {
5454
});
5555
const filteredData = useMemo(() => {
5656
let filteredConnectionStatuses = connectionStatuses;
57-
if (campusFilter != null) {
57+
if (campusFilter && campusFilter.length > 0) {
5858
filteredConnectionStatuses = Object.fromEntries(
5959
Object.entries(connectionStatuses).map(([key, status]) => [
6060
key,
6161
{
6262
...status,
63-
people: status.people.filter(
64-
(person) => person.primaryCampusId?.toString() === campusFilter
63+
people: status.people.filter((person) =>
64+
campusFilter.includes(person.primaryCampusId?.toString() || "")
6565
),
6666
},
6767
])

src/utils/layoutUtils.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export const getCustomLayout = (nodes: Node<NodeData>[], edges: Edge[]) => {
8080
{
8181
id: "churchLife",
8282
type: "staticNode",
83-
position: { x: 1650, y: 400 },
83+
position: { x: 1600, y: 400 },
8484
draggable: false,
8585
data: {
8686
label: "Church Life",
@@ -91,7 +91,7 @@ export const getCustomLayout = (nodes: Node<NodeData>[], edges: Edge[]) => {
9191
{
9292
id: "growth",
9393
type: "staticNode",
94-
position: { x: 2150, y: 400 },
94+
position: { x: 2000, y: 400 },
9595
draggable: false,
9696
data: {
9797
label: "Growth",
@@ -102,7 +102,7 @@ export const getCustomLayout = (nodes: Node<NodeData>[], edges: Edge[]) => {
102102
{
103103
id: "serving",
104104
type: "staticNode",
105-
position: { x: 2550, y: 400 },
105+
position: { x: 2400, y: 400 },
106106
draggable: false,
107107
data: {
108108
label: "Serving",
@@ -113,7 +113,7 @@ export const getCustomLayout = (nodes: Node<NodeData>[], edges: Edge[]) => {
113113
{
114114
id: "sending",
115115
type: "staticNode",
116-
position: { x: 2900, y: 400 },
116+
position: { x: 2800, y: 400 },
117117
draggable: false,
118118
data: {
119119
label: "Sending",
@@ -207,19 +207,19 @@ export const getCustomLayout = (nodes: Node<NodeData>[], edges: Edge[]) => {
207207
{
208208
id: "custom-position-integration-churchLife",
209209
type: "staticNode",
210-
position: { x: 1550, y: 400 },
210+
position: { x: 1500, y: 400 },
211211
draggable: false,
212212
data: {
213213
label: "",
214214
description: "",
215215
isStatic: true,
216216
},
217217
},
218-
// Custom position node for the midpoint of Church Life to Growth edge
218+
// Custom position node for the midpoint of Growth to Serving edge
219219
{
220220
id: "custom-position-churchLife-growth",
221221
type: "staticNode",
222-
position: { x: 2000, y: 400 },
222+
position: { x: 2300, y: 400 },
223223
draggable: false,
224224
data: {
225225
label: "",
@@ -501,7 +501,7 @@ export const getCustomLayout = (nodes: Node<NodeData>[], edges: Edge[]) => {
501501
color: "#e5e7eb",
502502
},
503503
},
504-
// Edge from Growing to the edge between Church Life and Growth
504+
// Edge from Growing to the midpoint of Growth to Serving edge
505505
{
506506
id: "edge-growing-to-churchLife-growth",
507507
source: "1229",
@@ -545,12 +545,12 @@ export const getCustomLayout = (nodes: Node<NodeData>[], edges: Edge[]) => {
545545
case "Attending":
546546
return {
547547
...node,
548-
position: { x: 1350, y: 600 },
548+
position: { x: 1300, y: 600 },
549549
};
550550
case "Growing":
551551
return {
552552
...node,
553-
position: { x: 1850, y: 600 },
553+
position: { x: 2110, y: 600 },
554554
};
555555
case "Investigating":
556556
return {

0 commit comments

Comments
 (0)