mirror of
https://github.com/p-stream/p-stream.git
synced 2026-03-11 17:55:33 +00:00
add save confirmation to admin page
fixes embed order not propagating to backend
This commit is contained in:
parent
f25e055477
commit
71a3d91b2a
3 changed files with 176 additions and 10 deletions
105
src/hooks/useEmbedOrderState.ts
Normal file
105
src/hooks/useEmbedOrderState.ts
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
import { updateSettings } from "@/backend/accounts/settings";
|
||||
import { useBackendUrl } from "@/hooks/auth/useBackendUrl";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { usePreferencesStore } from "@/stores/preferences";
|
||||
|
||||
export function useEmbedOrderState() {
|
||||
const account = useAuthStore((s) => s.account);
|
||||
const backendUrl = useBackendUrl();
|
||||
|
||||
// Get current values from store
|
||||
const embedOrder = usePreferencesStore((s) => s.embedOrder);
|
||||
const enableEmbedOrder = usePreferencesStore((s) => s.enableEmbedOrder);
|
||||
const disabledEmbeds = usePreferencesStore((s) => s.disabledEmbeds);
|
||||
|
||||
// Local state for tracking changes
|
||||
const [localEmbedOrder, setLocalEmbedOrder] = useState(embedOrder);
|
||||
const [localEnableEmbedOrder, setLocalEnableEmbedOrder] =
|
||||
useState(enableEmbedOrder);
|
||||
const [localDisabledEmbeds, setLocalDisabledEmbeds] =
|
||||
useState(disabledEmbeds);
|
||||
|
||||
// Store setters
|
||||
const setEmbedOrder = usePreferencesStore((s) => s.setEmbedOrder);
|
||||
const setEnableEmbedOrder = usePreferencesStore((s) => s.setEnableEmbedOrder);
|
||||
const setDisabledEmbeds = usePreferencesStore((s) => s.setDisabledEmbeds);
|
||||
|
||||
// Check if any changes have been made
|
||||
const hasChanges = useMemo(() => {
|
||||
return (
|
||||
JSON.stringify(localEmbedOrder) !== JSON.stringify(embedOrder) ||
|
||||
localEnableEmbedOrder !== enableEmbedOrder ||
|
||||
JSON.stringify(localDisabledEmbeds) !== JSON.stringify(disabledEmbeds)
|
||||
);
|
||||
}, [
|
||||
localEmbedOrder,
|
||||
embedOrder,
|
||||
localEnableEmbedOrder,
|
||||
enableEmbedOrder,
|
||||
localDisabledEmbeds,
|
||||
disabledEmbeds,
|
||||
]);
|
||||
|
||||
// Reset local state to match store
|
||||
const reset = useCallback(() => {
|
||||
setLocalEmbedOrder(embedOrder);
|
||||
setLocalEnableEmbedOrder(enableEmbedOrder);
|
||||
setLocalDisabledEmbeds(disabledEmbeds);
|
||||
}, [embedOrder, enableEmbedOrder, disabledEmbeds]);
|
||||
|
||||
// Save changes to backend and update store
|
||||
const saveChanges = useCallback(async () => {
|
||||
if (!account || !backendUrl) return;
|
||||
|
||||
try {
|
||||
await updateSettings(backendUrl, account, {
|
||||
embedOrder: localEmbedOrder,
|
||||
enableEmbedOrder: localEnableEmbedOrder,
|
||||
disabledEmbeds: localDisabledEmbeds,
|
||||
});
|
||||
|
||||
// Update the store with the new values
|
||||
setEmbedOrder(localEmbedOrder);
|
||||
setEnableEmbedOrder(localEnableEmbedOrder);
|
||||
setDisabledEmbeds(localDisabledEmbeds);
|
||||
} catch (error) {
|
||||
console.error("Failed to save embed order settings:", error);
|
||||
throw error;
|
||||
}
|
||||
}, [
|
||||
account,
|
||||
backendUrl,
|
||||
localEmbedOrder,
|
||||
localEnableEmbedOrder,
|
||||
localDisabledEmbeds,
|
||||
setEmbedOrder,
|
||||
setEnableEmbedOrder,
|
||||
setDisabledEmbeds,
|
||||
]);
|
||||
|
||||
// Update local state when store changes
|
||||
useEffect(() => {
|
||||
setLocalEmbedOrder(embedOrder);
|
||||
setLocalEnableEmbedOrder(enableEmbedOrder);
|
||||
setLocalDisabledEmbeds(disabledEmbeds);
|
||||
}, [embedOrder, enableEmbedOrder, disabledEmbeds]);
|
||||
|
||||
return {
|
||||
// Current values
|
||||
embedOrder: localEmbedOrder,
|
||||
enableEmbedOrder: localEnableEmbedOrder,
|
||||
disabledEmbeds: localDisabledEmbeds,
|
||||
|
||||
// Setters
|
||||
setEmbedOrder: setLocalEmbedOrder,
|
||||
setEnableEmbedOrder: setLocalEnableEmbedOrder,
|
||||
setDisabledEmbeds: setLocalDisabledEmbeds,
|
||||
|
||||
// State management
|
||||
hasChanges,
|
||||
reset,
|
||||
saveChanges,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
import { useCallback, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Button } from "@/components/buttons/Button";
|
||||
import { ThinContainer } from "@/components/layout/ThinContainer";
|
||||
import { Heading1, Paragraph } from "@/components/utils/Text";
|
||||
import { Transition } from "@/components/utils/Transition";
|
||||
import { useEmbedOrderState } from "@/hooks/useEmbedOrderState";
|
||||
import { SubPageLayout } from "@/pages/layouts/SubPageLayout";
|
||||
import { ConfigValuesPart } from "@/pages/parts/admin/ConfigValuesPart";
|
||||
import { M3U8TestPart } from "@/pages/parts/admin/M3U8TestPart";
|
||||
|
|
@ -10,6 +16,21 @@ import { BackendTestPart } from "../parts/admin/BackendTestPart";
|
|||
import { EmbedOrderPart } from "../parts/admin/EmbedOrderPart";
|
||||
|
||||
export function AdminPage() {
|
||||
const { t } = useTranslation();
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const embedOrderState = useEmbedOrderState();
|
||||
|
||||
const handleSaveChanges = useCallback(async () => {
|
||||
setIsSaving(true);
|
||||
try {
|
||||
await embedOrderState.saveChanges();
|
||||
} catch (error) {
|
||||
console.error("Failed to save embed order changes:", error);
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
}, [embedOrderState]);
|
||||
|
||||
return (
|
||||
<SubPageLayout>
|
||||
<ThinContainer>
|
||||
|
|
@ -21,8 +42,40 @@ export function AdminPage() {
|
|||
<WorkerTestPart />
|
||||
<TMDBTestPart />
|
||||
<M3U8TestPart />
|
||||
<EmbedOrderPart />
|
||||
<EmbedOrderPart
|
||||
embedOrder={embedOrderState.embedOrder}
|
||||
setEmbedOrder={embedOrderState.setEmbedOrder}
|
||||
enableEmbedOrder={embedOrderState.enableEmbedOrder}
|
||||
setEnableEmbedOrder={embedOrderState.setEnableEmbedOrder}
|
||||
disabledEmbeds={embedOrderState.disabledEmbeds}
|
||||
setDisabledEmbeds={embedOrderState.setDisabledEmbeds}
|
||||
/>
|
||||
</ThinContainer>
|
||||
|
||||
<Transition
|
||||
animation="fade"
|
||||
show={embedOrderState.hasChanges}
|
||||
className="bg-settings-saveBar-background border-t border-settings-card-border/50 py-4 transition-opacity w-full fixed bottom-0 flex justify-between flex-col md:flex-row px-8 items-start md:items-center gap-3 z-[999]"
|
||||
>
|
||||
<p className="text-type-danger">{t("settings.unsaved")}</p>
|
||||
<div className="space-x-3 w-full md:w-auto flex">
|
||||
<Button
|
||||
className="w-full md:w-auto"
|
||||
theme="secondary"
|
||||
onClick={embedOrderState.reset}
|
||||
>
|
||||
{t("settings.reset")}
|
||||
</Button>
|
||||
<Button
|
||||
className="w-full md:w-auto"
|
||||
theme="purple"
|
||||
loading={isSaving}
|
||||
onClick={handleSaveChanges}
|
||||
>
|
||||
{t("settings.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</Transition>
|
||||
</SubPageLayout>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,19 +7,27 @@ import { Button } from "@/components/buttons/Button";
|
|||
import { Toggle } from "@/components/buttons/Toggle";
|
||||
import { SortableListWithToggles } from "@/components/form/SortableListWithToggles";
|
||||
import { Heading2 } from "@/components/utils/Text";
|
||||
import { usePreferencesStore } from "@/stores/preferences";
|
||||
|
||||
export function EmbedOrderPart() {
|
||||
interface EmbedOrderPartProps {
|
||||
embedOrder: string[];
|
||||
setEmbedOrder: (order: string[]) => void;
|
||||
enableEmbedOrder: boolean;
|
||||
setEnableEmbedOrder: (enabled: boolean) => void;
|
||||
disabledEmbeds: string[];
|
||||
setDisabledEmbeds: (disabled: string[]) => void;
|
||||
}
|
||||
|
||||
export function EmbedOrderPart({
|
||||
embedOrder,
|
||||
setEmbedOrder,
|
||||
enableEmbedOrder,
|
||||
setEnableEmbedOrder,
|
||||
disabledEmbeds,
|
||||
setDisabledEmbeds,
|
||||
}: EmbedOrderPartProps) {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const embedOrder = usePreferencesStore((s) => s.embedOrder);
|
||||
const setEmbedOrder = usePreferencesStore((s) => s.setEmbedOrder);
|
||||
const enableEmbedOrder = usePreferencesStore((s) => s.enableEmbedOrder);
|
||||
const setEnableEmbedOrder = usePreferencesStore((s) => s.setEnableEmbedOrder);
|
||||
const disabledEmbeds = usePreferencesStore((s) => s.disabledEmbeds);
|
||||
const setDisabledEmbeds = usePreferencesStore((s) => s.setDisabledEmbeds);
|
||||
|
||||
const allEmbeds = getAllProviders().listEmbeds();
|
||||
|
||||
const embedItems = useMemo(() => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue