@churchapps/apphelper 0.5.10 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ErrorMessages.js +1 -1
- package/dist/components/ErrorMessages.js.map +1 -1
- package/dist/components/FormCardPayment.js +2 -2
- package/dist/components/FormCardPayment.js.map +1 -1
- package/dist/components/ImageEditor.d.ts.map +1 -1
- package/dist/components/ImageEditor.js +13 -8
- package/dist/components/ImageEditor.js.map +1 -1
- package/dist/components/PageHeader.js +1 -1
- package/dist/components/PageHeader.js.map +1 -1
- package/dist/components/QuestionEdit.js +2 -2
- package/dist/components/QuestionEdit.js.map +1 -1
- package/dist/components/SmallButton.js +1 -1
- package/dist/components/SmallButton.js.map +1 -1
- package/dist/components/gallery/GalleryModal.d.ts.map +1 -1
- package/dist/components/gallery/GalleryModal.js +2 -6
- package/dist/components/gallery/GalleryModal.js.map +1 -1
- package/dist/components/header/SecondaryMenu.js +2 -2
- package/dist/components/header/SecondaryMenu.js.map +1 -1
- package/dist/components/header/SiteHeader.d.ts.map +1 -1
- package/dist/components/header/SiteHeader.js +0 -3
- package/dist/components/header/SiteHeader.js.map +1 -1
- package/dist/components/notes/Note.js +1 -1
- package/dist/components/notes/Note.js.map +1 -1
- package/dist/components/wrapper/ChurchList.d.ts.map +1 -1
- package/dist/components/wrapper/ChurchList.js +0 -7
- package/dist/components/wrapper/ChurchList.js.map +1 -1
- package/dist/components/wrapper/NewPrivateMessage.d.ts.map +1 -1
- package/dist/components/wrapper/NewPrivateMessage.js +1 -2
- package/dist/components/wrapper/NewPrivateMessage.js.map +1 -1
- package/dist/components/wrapper/Notifications.js +1 -1
- package/dist/components/wrapper/Notifications.js.map +1 -1
- package/dist/components/wrapper/PrivateMessageDetails.d.ts.map +1 -1
- package/dist/components/wrapper/PrivateMessageDetails.js +0 -2
- package/dist/components/wrapper/PrivateMessageDetails.js.map +1 -1
- package/dist/components/wrapper/PrivateMessages.js +1 -1
- package/dist/components/wrapper/PrivateMessages.js.map +1 -1
- package/dist/components/wrapper/UserMenu.d.ts.map +1 -1
- package/dist/components/wrapper/UserMenu.js +0 -13
- package/dist/components/wrapper/UserMenu.js.map +1 -1
- package/dist/helpers/ErrorHelper.d.ts.map +1 -1
- package/dist/helpers/ErrorHelper.js +0 -2
- package/dist/helpers/ErrorHelper.js.map +1 -1
- package/dist/helpers/NotificationService.d.ts +0 -18
- package/dist/helpers/NotificationService.d.ts.map +1 -1
- package/dist/helpers/NotificationService.js +0 -65
- package/dist/helpers/NotificationService.js.map +1 -1
- package/dist/helpers/SlugHelper.d.ts.map +1 -1
- package/dist/helpers/SlugHelper.js +5 -19
- package/dist/helpers/SlugHelper.js.map +1 -1
- package/dist/helpers/SocketHelper.d.ts.map +1 -1
- package/dist/helpers/SocketHelper.js +1 -53
- package/dist/helpers/SocketHelper.js.map +1 -1
- package/dist/helpers/UserHelper.d.ts.map +1 -1
- package/dist/helpers/UserHelper.js +0 -4
- package/dist/helpers/UserHelper.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ErrorMessages.tsx +1 -1
- package/src/components/FormCardPayment.tsx +1 -1
- package/src/components/ImageEditor.tsx +167 -161
- package/src/components/PageHeader.tsx +2 -2
- package/src/components/QuestionEdit.tsx +2 -2
- package/src/components/SmallButton.tsx +1 -1
- package/src/components/gallery/GalleryModal.tsx +169 -173
- package/src/components/header/SecondaryMenu.tsx +2 -2
- package/src/components/header/SiteHeader.tsx +204 -207
- package/src/components/notes/Note.tsx +2 -2
- package/src/components/wrapper/ChurchList.tsx +145 -154
- package/src/components/wrapper/NewPrivateMessage.tsx +1 -2
- package/src/components/wrapper/Notifications.tsx +1 -1
- package/src/components/wrapper/PrivateMessageDetails.tsx +2 -6
- package/src/components/wrapper/PrivateMessages.tsx +1 -1
- package/src/components/wrapper/UserMenu.tsx +3 -17
- package/src/helpers/ErrorHelper.ts +41 -43
- package/src/helpers/NotificationService.ts +232 -296
- package/src/helpers/SlugHelper.ts +5 -19
- package/src/helpers/SocketHelper.ts +247 -296
- package/src/helpers/UserHelper.ts +2 -6
|
@@ -1,207 +1,204 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { AppBar, Link, styled, Toolbar } from "@mui/material";
|
|
3
|
-
import { UserMenu } from "../wrapper/UserMenu";
|
|
4
|
-
import { PersonHelper } from "../../helpers/PersonHelper";
|
|
5
|
-
import { PrimaryMenu } from "./PrimaryMenu";
|
|
6
|
-
import { SecondaryMenu } from "./SecondaryMenu";
|
|
7
|
-
import { SecondaryMenuAlt } from "./SecondaryMenuAlt";
|
|
8
|
-
import { SupportDrawer } from "./SupportDrawer";
|
|
9
|
-
import { UserContextInterface } from "@churchapps/helpers";
|
|
10
|
-
import { NotificationService } from "../../helpers/NotificationService";
|
|
11
|
-
|
|
12
|
-
type Props = {
|
|
13
|
-
primaryMenuLabel: string;
|
|
14
|
-
primaryMenuItems:{ url: string, icon:string, label: string }[];
|
|
15
|
-
secondaryMenuLabel: string;
|
|
16
|
-
secondaryMenuItems:{ url: string, label: string }[];
|
|
17
|
-
context: UserContextInterface;
|
|
18
|
-
appName: string;
|
|
19
|
-
onNavigate: (url: string) => void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const SiteHeader = React.memo((props:Props) => {
|
|
23
|
-
// Initialize NotificationService without subscribing to count changes to prevent re-renders
|
|
24
|
-
React.useEffect(() => {
|
|
25
|
-
const initializeNotifications = async () => {
|
|
26
|
-
if (props.context?.person?.id && props.context?.userChurch?.church?.id) {
|
|
27
|
-
const service = NotificationService.getInstance();
|
|
28
|
-
await service.initialize(props.context);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
initializeNotifications();
|
|
33
|
-
}, [props.context?.person?.id, props.context?.userChurch?.church?.id]);
|
|
34
|
-
|
|
35
|
-
const refresh = React.useCallback(async () => {
|
|
36
|
-
// Direct access to NotificationService for refresh functionality
|
|
37
|
-
await NotificationService.getInstance().refresh();
|
|
38
|
-
}, []);
|
|
39
|
-
|
|
40
|
-
// Memoize userName to prevent recreation
|
|
41
|
-
const userName = React.useMemo(() => {
|
|
42
|
-
if (props.context?.user) {
|
|
43
|
-
return `${props.context.user.firstName} ${props.context.user.lastName}`;
|
|
44
|
-
}
|
|
45
|
-
return '';
|
|
46
|
-
}, [props.context?.user?.firstName, props.context?.user?.lastName]);
|
|
47
|
-
|
|
48
|
-
// Memoize profilePicture URL
|
|
49
|
-
const profilePicture = React.useMemo(() => {
|
|
50
|
-
return PersonHelper.getPhotoUrl(props.context?.person);
|
|
51
|
-
}, [props.context?.person]);
|
|
52
|
-
|
|
53
|
-
// Create a stable context object to prevent UserMenu recreation
|
|
54
|
-
const stableContext = React.useMemo(() => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
props.context?.
|
|
73
|
-
props.context?.
|
|
74
|
-
props.context?.
|
|
75
|
-
props.context?.
|
|
76
|
-
props.context?.
|
|
77
|
-
props.context?.
|
|
78
|
-
props.context?.
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (props.primaryMenuLabel === "
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
'--
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
SiteHeader.displayName = 'SiteHeader';
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { AppBar, Link, styled, Toolbar } from "@mui/material";
|
|
3
|
+
import { UserMenu } from "../wrapper/UserMenu";
|
|
4
|
+
import { PersonHelper } from "../../helpers/PersonHelper";
|
|
5
|
+
import { PrimaryMenu } from "./PrimaryMenu";
|
|
6
|
+
import { SecondaryMenu } from "./SecondaryMenu";
|
|
7
|
+
import { SecondaryMenuAlt } from "./SecondaryMenuAlt";
|
|
8
|
+
import { SupportDrawer } from "./SupportDrawer";
|
|
9
|
+
import { UserContextInterface } from "@churchapps/helpers";
|
|
10
|
+
import { NotificationService } from "../../helpers/NotificationService";
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
primaryMenuLabel: string;
|
|
14
|
+
primaryMenuItems:{ url: string, icon:string, label: string }[];
|
|
15
|
+
secondaryMenuLabel: string;
|
|
16
|
+
secondaryMenuItems:{ url: string, label: string }[];
|
|
17
|
+
context: UserContextInterface;
|
|
18
|
+
appName: string;
|
|
19
|
+
onNavigate: (url: string) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const SiteHeader = React.memo((props:Props) => {
|
|
23
|
+
// Initialize NotificationService without subscribing to count changes to prevent re-renders
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
const initializeNotifications = async () => {
|
|
26
|
+
if (props.context?.person?.id && props.context?.userChurch?.church?.id) {
|
|
27
|
+
const service = NotificationService.getInstance();
|
|
28
|
+
await service.initialize(props.context);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
initializeNotifications();
|
|
33
|
+
}, [props.context?.person?.id, props.context?.userChurch?.church?.id]);
|
|
34
|
+
|
|
35
|
+
const refresh = React.useCallback(async () => {
|
|
36
|
+
// Direct access to NotificationService for refresh functionality
|
|
37
|
+
await NotificationService.getInstance().refresh();
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
40
|
+
// Memoize userName to prevent recreation
|
|
41
|
+
const userName = React.useMemo(() => {
|
|
42
|
+
if (props.context?.user) {
|
|
43
|
+
return `${props.context.user.firstName} ${props.context.user.lastName}`;
|
|
44
|
+
}
|
|
45
|
+
return '';
|
|
46
|
+
}, [props.context?.user?.firstName, props.context?.user?.lastName]);
|
|
47
|
+
|
|
48
|
+
// Memoize profilePicture URL
|
|
49
|
+
const profilePicture = React.useMemo(() => {
|
|
50
|
+
return PersonHelper.getPhotoUrl(props.context?.person);
|
|
51
|
+
}, [props.context?.person]);
|
|
52
|
+
|
|
53
|
+
// Create a stable context object to prevent UserMenu recreation
|
|
54
|
+
const stableContext = React.useMemo(() => {
|
|
55
|
+
|
|
56
|
+
if (!props.context) return undefined;
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
user: props.context.user,
|
|
60
|
+
person: props.context.person,
|
|
61
|
+
userChurch: props.context.userChurch,
|
|
62
|
+
userChurches: props.context.userChurches,
|
|
63
|
+
setUser: props.context.setUser,
|
|
64
|
+
setPerson: props.context.setPerson,
|
|
65
|
+
setUserChurch: props.context.setUserChurch,
|
|
66
|
+
setUserChurches: props.context.setUserChurches
|
|
67
|
+
};
|
|
68
|
+
}, [
|
|
69
|
+
props.context?.user?.id,
|
|
70
|
+
props.context?.user?.firstName,
|
|
71
|
+
props.context?.user?.lastName,
|
|
72
|
+
props.context?.person?.id,
|
|
73
|
+
props.context?.userChurch?.church?.id,
|
|
74
|
+
props.context?.userChurches,
|
|
75
|
+
props.context?.setUser,
|
|
76
|
+
props.context?.setPerson,
|
|
77
|
+
props.context?.setUserChurch,
|
|
78
|
+
props.context?.setUserChurches
|
|
79
|
+
]);
|
|
80
|
+
|
|
81
|
+
const CustomAppBar = styled(AppBar)(
|
|
82
|
+
({ theme }) => ({
|
|
83
|
+
zIndex: theme.zIndex.drawer + 1,
|
|
84
|
+
backgroundColor: "var(--c1, #1565C0)",
|
|
85
|
+
transition: theme.transitions.create(["width", "margin"], {
|
|
86
|
+
easing: theme.transitions.easing.sharp,
|
|
87
|
+
duration: theme.transitions.duration.leavingScreen
|
|
88
|
+
}),
|
|
89
|
+
"& .MuiIcon-root": { color: "#FFFFFF" }
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const getRelatedArticles = () => {
|
|
94
|
+
let result: any [] = [];
|
|
95
|
+
if (props.appName === "B1Admin") {
|
|
96
|
+
if (props.primaryMenuLabel === "People") {
|
|
97
|
+
if (props.secondaryMenuLabel === "People") result = ["b1admin/adding-people", "b1admin/advanced-search", "b1admin/assigning-roles"];
|
|
98
|
+
else if (props.secondaryMenuLabel === "Groups") result = ["b1admin/group-roster", "b1admin/groups", "b1admin/group-calendar"];
|
|
99
|
+
else if (props.secondaryMenuLabel === "Attendance") result = ["b1admin/attendance", "b1admin/checkin"];
|
|
100
|
+
}
|
|
101
|
+
else if (props.primaryMenuLabel === "Donations") {
|
|
102
|
+
if (props.secondaryMenuLabel === "Summary") result = ["b1admin/donation-report"];
|
|
103
|
+
else if (props.secondaryMenuLabel === "Batches" || props.secondaryMenuLabel === "Funds") result = ["b1admin/giving", "b1admin/manual-input"];
|
|
104
|
+
}
|
|
105
|
+
else if (props.primaryMenuLabel === "Serving") {
|
|
106
|
+
if (props.secondaryMenuLabel === "Plans") result = ["b1admin/plans"];
|
|
107
|
+
else if (props.secondaryMenuLabel === "Tasks") result = ["b1admin/tasks", "b1admin/automations"];
|
|
108
|
+
}
|
|
109
|
+
else if (props.primaryMenuLabel === "Settings") {
|
|
110
|
+
if (props.secondaryMenuLabel === "Settings") result = ["b1admin/assigning-roles", "b1admin/exporting-data", "b1admin/import-csv", "b1admin/import-from-breeze"];
|
|
111
|
+
else if (props.secondaryMenuLabel === "Forms") result = ["b1admin/forms"];
|
|
112
|
+
}
|
|
113
|
+
} else if (props.appName === "B1") {
|
|
114
|
+
if (props.primaryMenuLabel === "Mobile App") result = ["b1/admin/portal", "b1/mobile/setup"];
|
|
115
|
+
else if (props.primaryMenuLabel === "Website") result = ["b1/admin/portal", "b1/admin/website-elements", "b1/admin/website-setup"];
|
|
116
|
+
else if (props.primaryMenuLabel === "Sermons") result = ["b1/admin/sermons", "b1/admin/stream-setup"];
|
|
117
|
+
else if (props.primaryMenuLabel === "Calendars") result = ["b1/portal/calendars"];
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/*<Typography variant="h6" noWrap>{UserHelper.currentUserChurch?.church?.name || ""}</Typography>*/
|
|
123
|
+
return (<>
|
|
124
|
+
<div id="site-header" style={{
|
|
125
|
+
'--c1': '#1565C0',
|
|
126
|
+
'--c1d1': '#1358AD',
|
|
127
|
+
'--c1d2': '#114A99',
|
|
128
|
+
'--c1l2': '#568BDA',
|
|
129
|
+
backgroundColor:"var(--c1)",
|
|
130
|
+
color: "#FFF"
|
|
131
|
+
} as React.CSSProperties}>
|
|
132
|
+
<CustomAppBar id="site-app-bar" position="absolute">
|
|
133
|
+
<Toolbar id="site-toolbar" sx={{ pr: "24px", backgroundColor: "var(--c1)", minHeight: "64px !important" }}>
|
|
134
|
+
<PrimaryMenu label={props.primaryMenuLabel} menuItems={props.primaryMenuItems} onNavigate={props.onNavigate} />
|
|
135
|
+
<SecondaryMenu label={props.secondaryMenuLabel} menuItems={props.secondaryMenuItems} onNavigate={props.onNavigate} />
|
|
136
|
+
<div id="secondary-menu-container" style={{ flex: 1 }}>
|
|
137
|
+
<SecondaryMenuAlt label={props.secondaryMenuLabel} menuItems={props.secondaryMenuItems} onNavigate={props.onNavigate} />
|
|
138
|
+
</div>
|
|
139
|
+
{props.context?.user?.id && (
|
|
140
|
+
<UserMenu
|
|
141
|
+
key="user-menu-stable"
|
|
142
|
+
profilePicture={profilePicture}
|
|
143
|
+
userName={userName}
|
|
144
|
+
context={stableContext}
|
|
145
|
+
appName={props.appName}
|
|
146
|
+
loadCounts={refresh}
|
|
147
|
+
notificationCounts={{notificationCount: 0, pmCount: 0}}
|
|
148
|
+
onNavigate={props.onNavigate}
|
|
149
|
+
/>
|
|
150
|
+
)}
|
|
151
|
+
{!props.context?.user?.id && <Link id="login-link" href="/login" color="inherit" style={{ textDecoration: "none" }}>Login</Link>}
|
|
152
|
+
<SupportDrawer appName={props.appName} relatedArticles={getRelatedArticles()} />
|
|
153
|
+
</Toolbar>
|
|
154
|
+
</CustomAppBar>
|
|
155
|
+
<div id="app-bar-spacer" style={{ height: '64px' }}></div>
|
|
156
|
+
</div>
|
|
157
|
+
</>
|
|
158
|
+
);
|
|
159
|
+
}, (prevProps, nextProps) => {
|
|
160
|
+
// Custom comparison to prevent unnecessary re-renders
|
|
161
|
+
|
|
162
|
+
// Check if essential props have changed
|
|
163
|
+
if (prevProps.primaryMenuLabel !== nextProps.primaryMenuLabel ||
|
|
164
|
+
prevProps.secondaryMenuLabel !== nextProps.secondaryMenuLabel ||
|
|
165
|
+
prevProps.appName !== nextProps.appName) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Check if menu items arrays have changed (shallow comparison)
|
|
170
|
+
if (prevProps.primaryMenuItems?.length !== nextProps.primaryMenuItems?.length ||
|
|
171
|
+
prevProps.secondaryMenuItems?.length !== nextProps.secondaryMenuItems?.length) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Check if user context has actually changed (deep comparison of essential parts)
|
|
176
|
+
const prevUser = prevProps.context?.user;
|
|
177
|
+
const nextUser = nextProps.context?.user;
|
|
178
|
+
|
|
179
|
+
if (prevUser?.id !== nextUser?.id ||
|
|
180
|
+
prevUser?.firstName !== nextUser?.firstName ||
|
|
181
|
+
prevUser?.lastName !== nextUser?.lastName) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Check if person context has changed
|
|
186
|
+
if (prevProps.context?.person?.id !== nextProps.context?.person?.id) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Check if church context has changed
|
|
191
|
+
if (prevProps.context?.userChurch?.church?.id !== nextProps.context?.userChurch?.church?.id) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Check if onNavigate function reference has changed
|
|
196
|
+
if (prevProps.onNavigate !== nextProps.onNavigate) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// All essential props are the same, skip re-render
|
|
201
|
+
return true;
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
SiteHeader.displayName = 'SiteHeader';
|
|
@@ -59,11 +59,11 @@ export const Note: React.FC<Props> = (props) => {
|
|
|
59
59
|
</Stack>
|
|
60
60
|
<Box>
|
|
61
61
|
{contents.map((c, i) => c ? (
|
|
62
|
-
<Typography key={i} variant="body2" sx={{ mb: 0.5 }}>
|
|
62
|
+
<Typography key={`content-${i}-${c.substring(0, 20)}`} variant="body2" sx={{ mb: 0.5 }}>
|
|
63
63
|
{c}
|
|
64
64
|
</Typography>
|
|
65
65
|
) : (
|
|
66
|
-
<Box key={i} sx={{ height: '1em' }} />
|
|
66
|
+
<Box key={`empty-${i}`} sx={{ height: '1em' }} />
|
|
67
67
|
))}
|
|
68
68
|
</Box>
|
|
69
69
|
</Box>
|