|
|
@@ -1,8 +1,7 @@
|
|
|
"use client";
|
|
|
-import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
import { useEffect, useMemo, useState } from "react";
|
|
|
import toast from "react-hot-toast";
|
|
|
-import { del, get } from "../../lib/api";
|
|
|
+import { useAppContext } from "../providers/AppContext";
|
|
|
import ConfirmationDialog from "./ConfirmationDialog";
|
|
|
import LoadingCard from "./Loading";
|
|
|
import { useNotifications } from "./NotificationContext";
|
|
|
@@ -10,35 +9,8 @@ import Pagination from "./Pagination";
|
|
|
import SettingsCrud from "./SettingsCrud";
|
|
|
|
|
|
export default function SettingsList() {
|
|
|
- const queryClient = useQueryClient();
|
|
|
+ const { settings, isLoading, error, deleteSetting } = useAppContext();
|
|
|
const { addNotification } = useNotifications();
|
|
|
- const { data, isLoading, error } = useQuery({
|
|
|
- queryKey: ["settings"],
|
|
|
- queryFn: () => get("/config/settings")
|
|
|
- });
|
|
|
-
|
|
|
- // Listen for WebSocket events
|
|
|
- useEffect(() => {
|
|
|
- const handleSettingsUpdate = (event: CustomEvent) => {
|
|
|
- const settingsData = event.detail;
|
|
|
- if (settingsData.type === "settings") {
|
|
|
- // Invalidate and refetch settings when settings updates occur
|
|
|
- queryClient.invalidateQueries({ queryKey: ["settings"] });
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- window.addEventListener(
|
|
|
- "settingsUpdate",
|
|
|
- handleSettingsUpdate as EventListener
|
|
|
- );
|
|
|
-
|
|
|
- return () => {
|
|
|
- window.removeEventListener(
|
|
|
- "settingsUpdate",
|
|
|
- handleSettingsUpdate as EventListener
|
|
|
- );
|
|
|
- };
|
|
|
- }, [queryClient]);
|
|
|
|
|
|
const [editKey, setEditKey] = useState<string | null>(null);
|
|
|
const [editValue, setEditValue] = useState<string>("");
|
|
|
@@ -58,27 +30,28 @@ export default function SettingsList() {
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
|
const [pageSize, setPageSize] = useState(25);
|
|
|
|
|
|
- const deleteMutation = useMutation({
|
|
|
- mutationFn: (key: string) => del(`/config/settings/${key}`),
|
|
|
- onSuccess: (_, key) => {
|
|
|
- queryClient.invalidateQueries({ queryKey: ["settings"] });
|
|
|
- toast.success("Setting deleted successfully");
|
|
|
- addNotification({
|
|
|
- type: "success",
|
|
|
- title: "Setting Deleted",
|
|
|
- message: `Setting "${key}" has been deleted successfully.`
|
|
|
- });
|
|
|
- },
|
|
|
- onError: (error, key) => {
|
|
|
- console.error("Failed to delete setting:", error);
|
|
|
- toast.error("Failed to delete setting");
|
|
|
- addNotification({
|
|
|
- type: "error",
|
|
|
- title: "Delete Failed",
|
|
|
- message: `Failed to delete setting "${key}". Please try again.`
|
|
|
- });
|
|
|
+ const handleDeleteConfirm = async () => {
|
|
|
+ if (deleteConfirm.setting) {
|
|
|
+ try {
|
|
|
+ await deleteSetting(deleteConfirm.setting.key);
|
|
|
+ toast.success("Setting deleted successfully");
|
|
|
+ addNotification({
|
|
|
+ type: "success",
|
|
|
+ title: "Setting Deleted",
|
|
|
+ message: `Setting "${deleteConfirm.setting.key}" has been deleted successfully.`
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Failed to delete setting:", error);
|
|
|
+ toast.error("Failed to delete setting");
|
|
|
+ addNotification({
|
|
|
+ type: "error",
|
|
|
+ title: "Delete Failed",
|
|
|
+ message: `Failed to delete setting "${deleteConfirm.setting.key}". Please try again.`
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
- });
|
|
|
+ setDeleteConfirm({ isOpen: false });
|
|
|
+ };
|
|
|
|
|
|
const handleEdit = (key: string, value: any) => {
|
|
|
setEditKey(key);
|
|
|
@@ -98,13 +71,6 @@ export default function SettingsList() {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- const handleDeleteConfirm = () => {
|
|
|
- if (deleteConfirm.setting) {
|
|
|
- deleteMutation.mutate(deleteConfirm.setting.key);
|
|
|
- }
|
|
|
- setDeleteConfirm({ isOpen: false });
|
|
|
- };
|
|
|
-
|
|
|
const handleDeleteCancel = () => {
|
|
|
setDeleteConfirm({ isOpen: false });
|
|
|
};
|
|
|
@@ -125,9 +91,9 @@ export default function SettingsList() {
|
|
|
|
|
|
// Filter and sort data
|
|
|
const filteredAndSortedData = useMemo(() => {
|
|
|
- if (!data) return [];
|
|
|
+ if (!settings) return [];
|
|
|
|
|
|
- const filtered = Object.entries(data).filter(
|
|
|
+ const filtered = Object.entries(settings).filter(
|
|
|
([key, value]: [string, any]) =>
|
|
|
key.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
|
JSON.stringify(value).toLowerCase().includes(searchTerm.toLowerCase())
|
|
|
@@ -148,7 +114,7 @@ export default function SettingsList() {
|
|
|
);
|
|
|
|
|
|
return filtered;
|
|
|
- }, [data, searchTerm, sortField, sortDirection]);
|
|
|
+ }, [settings, searchTerm, sortField, sortDirection]);
|
|
|
|
|
|
// Handle pagination
|
|
|
const paginatedData = useMemo(() => {
|
|
|
@@ -190,9 +156,9 @@ export default function SettingsList() {
|
|
|
There was an error loading the settings data.
|
|
|
</p>
|
|
|
<button
|
|
|
- onClick={() =>
|
|
|
- queryClient.invalidateQueries({ queryKey: ["settings"] })
|
|
|
- }
|
|
|
+ onClick={() => {
|
|
|
+ window.location.reload();
|
|
|
+ }}
|
|
|
className="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
|
|
|
>
|
|
|
Try Again
|
|
|
@@ -276,7 +242,6 @@ export default function SettingsList() {
|
|
|
Edit
|
|
|
</button>
|
|
|
<button
|
|
|
- disabled={deleteMutation.isPending}
|
|
|
className="inline-flex items-center rounded-md bg-red-600 px-3 py-1 text-xs font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 disabled:opacity-50"
|
|
|
onClick={() => handleDeleteClick({ key, value })}
|
|
|
>
|
|
|
@@ -328,7 +293,7 @@ export default function SettingsList() {
|
|
|
type="danger"
|
|
|
onConfirm={handleDeleteConfirm}
|
|
|
onClose={handleDeleteCancel}
|
|
|
- isLoading={deleteMutation.isPending}
|
|
|
+ isLoading={false}
|
|
|
/>
|
|
|
</>
|
|
|
);
|