mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-07 13:24:21 +00:00
c6f15cd53f
Settings and Xray config endpoints now live at /panel/api/setting/* and /panel/api/xray/*, registered under the existing /panel/api group so they inherit the same Bearer-or-session auth (checkAPIAuth) as the rest of the API. An API token is a full-admin credential, so this just makes the surface consistent. The SPA page routes /panel/settings and /panel/xray are unchanged. BREAKING CHANGE: the old /panel/setting/* and /panel/xray/* paths are removed. External callers must switch to the /panel/api/ prefix. Frontend call sites, API docs, the dev proxy, and the route-documentation test are updated to match.
58 lines
1.4 KiB
TypeScript
58 lines
1.4 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { HttpUtil } from '@/utils';
|
|
import { parseMsg } from '@/utils/zodValidate';
|
|
import { DefaultsPayloadSchema } from '@/schemas/defaults';
|
|
|
|
type Calendar = 'gregorian' | 'jalalian';
|
|
|
|
let cachedValue: Calendar = 'gregorian';
|
|
let fetched = false;
|
|
let pending: Promise<void> | null = null;
|
|
const listeners = new Set<(value: Calendar) => void>();
|
|
|
|
function notify(value: Calendar) {
|
|
listeners.forEach((fn) => fn(value));
|
|
}
|
|
|
|
async function loadOnce(): Promise<void> {
|
|
if (fetched) return;
|
|
if (pending) {
|
|
await pending;
|
|
return;
|
|
}
|
|
pending = (async () => {
|
|
try {
|
|
const msg = await HttpUtil.post('/panel/api/setting/defaultSettings');
|
|
if (msg?.success) {
|
|
const validated = parseMsg(msg, DefaultsPayloadSchema, 'setting/defaultSettings');
|
|
cachedValue = validated.obj?.datepicker || 'gregorian';
|
|
notify(cachedValue);
|
|
}
|
|
} finally {
|
|
fetched = true;
|
|
pending = null;
|
|
}
|
|
})();
|
|
await pending;
|
|
}
|
|
|
|
export function setDatepicker(value: Calendar) {
|
|
fetched = true;
|
|
cachedValue = value || 'gregorian';
|
|
notify(cachedValue);
|
|
}
|
|
|
|
export function useDatepicker() {
|
|
const [datepicker, setLocal] = useState<Calendar>(cachedValue);
|
|
|
|
useEffect(() => {
|
|
listeners.add(setLocal);
|
|
loadOnce();
|
|
return () => {
|
|
listeners.delete(setLocal);
|
|
};
|
|
}, []);
|
|
|
|
return { datepicker };
|
|
}
|