Skip to content

Commit e045017

Browse files
committed
feat: enhance useNotices hook to support dynamic fetching of notices with URL and arguments
1 parent b07778c commit e045017

2 files changed

Lines changed: 46 additions & 2 deletions

File tree

src/components/wordpress/AdminNotice.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export interface Notice {
4141
interface AdminNoticeProps {
4242
interval?: number;
4343
notices?: Notice[];
44+
noticesUrl?: string;
45+
noticesUrlArgs?: Record<string, string>;
4446
actionUrl?: string;
4547
}
4648

@@ -160,7 +162,7 @@ const ConfirmModal = ({ open, action, loading, onConfirm, onClose }: ConfirmModa
160162
</Modal>
161163
);
162164

163-
const AdminNotice = ({ interval = 5000, notices: initialNotices = [], actionUrl }: AdminNoticeProps) => {
165+
const AdminNotice = ({ interval = 5000, notices: initialNotices = [], noticesUrl, noticesUrlArgs, actionUrl }: AdminNoticeProps) => {
164166
const [modalOpen, setModalOpen] = useState(false);
165167
const [pendingAction, setPendingAction] = useState<{
166168
action: NoticeAction;
@@ -177,7 +179,7 @@ const AdminNotice = ({ interval = 5000, notices: initialNotices = [], actionUrl
177179
resumeAutoSlide,
178180
executeAction,
179181
actionLoading
180-
} = useNotices({ interval, notices: initialNotices, actionUrl });
182+
} = useNotices({ interval, notices: initialNotices, noticesUrl, noticesUrlArgs, actionUrl });
181183

182184
if (error || !notices.length) {
183185
return null;

src/hooks/use-notices.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,64 @@ interface NoticesOptions {
55
interval?: number;
66
autoSlide?: boolean;
77
notices?: Notice[];
8+
noticesUrl?: string;
9+
noticesUrlArgs?: Record<string, string>;
810
actionUrl?: string;
911
}
1012

1113
export const useNotices = ({
1214
interval = 5000,
1315
autoSlide = true,
1416
notices: staticNotices = [],
17+
noticesUrl,
18+
noticesUrlArgs,
1519
actionUrl
1620
}: NoticesOptions = {}) => {
1721
const [notices, setNotices] = useState<Notice[]>([...staticNotices]);
1822
const [error, setError] = useState<string | null>(null);
23+
const [isLoading, setIsLoading] = useState(!!noticesUrl);
1924
const [currentNotice, setCurrentNotice] = useState(1);
2025
const [isAutoSliding, setIsAutoSliding] = useState(autoSlide);
2126
const [actionLoading, setActionLoading] = useState<{
2227
[key: number]: boolean;
2328
}>({});
2429

30+
const fetchNotices = async () => {
31+
setIsLoading(true);
32+
33+
try {
34+
const url = new URL(noticesUrl as string, window.location.href);
35+
36+
if (noticesUrlArgs) {
37+
Object.entries(noticesUrlArgs).forEach(([key, value]) => {
38+
url.searchParams.set(key, value);
39+
});
40+
}
41+
42+
const res = await fetch(url.toString());
43+
44+
if (!res.ok) {
45+
throw new Error(`Failed to fetch notices: ${res.status}`);
46+
}
47+
48+
const data: Notice[] | { success: boolean; data: Notice[] } = await res.json();
49+
const fetched = Array.isArray(data) ? data : data.data;
50+
setNotices(fetched);
51+
} catch (err) {
52+
setError(err instanceof Error ? err.message : 'Failed to fetch notices');
53+
} finally {
54+
setIsLoading(false);
55+
}
56+
};
57+
58+
useEffect(() => {
59+
if (!noticesUrl) {
60+
return;
61+
}
62+
63+
fetchNotices();
64+
}, [noticesUrl, noticesUrlArgs]);
65+
2566
useEffect(() => {
2667
if (!isAutoSliding || notices.length <= 1) {
2768
return;
@@ -118,6 +159,7 @@ export const useNotices = ({
118159
return {
119160
notices,
120161
error,
162+
isLoading,
121163
currentNotice,
122164
nextNotice,
123165
prevNotice,

0 commit comments

Comments
 (0)