@actuate-media/cms-admin 0.25.0 → 0.27.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.
Files changed (101) hide show
  1. package/dist/AdminRoot.d.ts.map +1 -1
  2. package/dist/AdminRoot.js +3 -3
  3. package/dist/AdminRoot.js.map +1 -1
  4. package/dist/__tests__/views/appearance-settings.render.test.d.ts +2 -0
  5. package/dist/__tests__/views/appearance-settings.render.test.d.ts.map +1 -0
  6. package/dist/__tests__/views/appearance-settings.render.test.js +95 -0
  7. package/dist/__tests__/views/appearance-settings.render.test.js.map +1 -0
  8. package/dist/__tests__/views/general-settings.render.test.d.ts +2 -0
  9. package/dist/__tests__/views/general-settings.render.test.d.ts.map +1 -0
  10. package/dist/__tests__/views/general-settings.render.test.js +105 -0
  11. package/dist/__tests__/views/general-settings.render.test.js.map +1 -0
  12. package/dist/actuate-admin.css +1 -1
  13. package/dist/components/ThemeProvider.d.ts +47 -4
  14. package/dist/components/ThemeProvider.d.ts.map +1 -1
  15. package/dist/components/ThemeProvider.js +173 -27
  16. package/dist/components/ThemeProvider.js.map +1 -1
  17. package/dist/components/ui/Badge.d.ts +1 -1
  18. package/dist/components/ui/Button.d.ts +1 -1
  19. package/dist/components/ui/Card.d.ts +2 -2
  20. package/dist/components/ui/Input.d.ts +1 -1
  21. package/dist/components/ui/Select.d.ts +1 -1
  22. package/dist/layout/Sidebar.d.ts.map +1 -1
  23. package/dist/layout/Sidebar.js +47 -8
  24. package/dist/layout/Sidebar.js.map +1 -1
  25. package/dist/views/Settings.d.ts +3 -1
  26. package/dist/views/Settings.d.ts.map +1 -1
  27. package/dist/views/Settings.js +10 -33
  28. package/dist/views/Settings.js.map +1 -1
  29. package/dist/views/settings/AdminThemeCard.d.ts +6 -0
  30. package/dist/views/settings/AdminThemeCard.d.ts.map +1 -0
  31. package/dist/views/settings/AdminThemeCard.js +31 -0
  32. package/dist/views/settings/AdminThemeCard.js.map +1 -0
  33. package/dist/views/settings/AppearanceTab.d.ts +7 -0
  34. package/dist/views/settings/AppearanceTab.d.ts.map +1 -0
  35. package/dist/views/settings/AppearanceTab.js +24 -0
  36. package/dist/views/settings/AppearanceTab.js.map +1 -0
  37. package/dist/views/settings/BrandPreviewCard.d.ts +5 -0
  38. package/dist/views/settings/BrandPreviewCard.d.ts.map +1 -0
  39. package/dist/views/settings/BrandPreviewCard.js +18 -0
  40. package/dist/views/settings/BrandPreviewCard.js.map +1 -0
  41. package/dist/views/settings/BrandingCard.d.ts +6 -0
  42. package/dist/views/settings/BrandingCard.d.ts.map +1 -0
  43. package/dist/views/settings/BrandingCard.js +38 -0
  44. package/dist/views/settings/BrandingCard.js.map +1 -0
  45. package/dist/views/settings/GeneralSettingsTab.d.ts +7 -0
  46. package/dist/views/settings/GeneralSettingsTab.d.ts.map +1 -0
  47. package/dist/views/settings/GeneralSettingsTab.js +19 -0
  48. package/dist/views/settings/GeneralSettingsTab.js.map +1 -0
  49. package/dist/views/settings/LanguageRegionCard.d.ts +10 -0
  50. package/dist/views/settings/LanguageRegionCard.d.ts.map +1 -0
  51. package/dist/views/settings/LanguageRegionCard.js +48 -0
  52. package/dist/views/settings/LanguageRegionCard.js.map +1 -0
  53. package/dist/views/settings/SeoRobotsDefaultsCard.d.ts +12 -0
  54. package/dist/views/settings/SeoRobotsDefaultsCard.d.ts.map +1 -0
  55. package/dist/views/settings/SeoRobotsDefaultsCard.js +45 -0
  56. package/dist/views/settings/SeoRobotsDefaultsCard.js.map +1 -0
  57. package/dist/views/settings/SiteIndexStatusCard.d.ts +12 -0
  58. package/dist/views/settings/SiteIndexStatusCard.d.ts.map +1 -0
  59. package/dist/views/settings/SiteIndexStatusCard.js +51 -0
  60. package/dist/views/settings/SiteIndexStatusCard.js.map +1 -0
  61. package/dist/views/settings/SiteInformationCard.d.ts +11 -0
  62. package/dist/views/settings/SiteInformationCard.d.ts.map +1 -0
  63. package/dist/views/settings/SiteInformationCard.js +21 -0
  64. package/dist/views/settings/SiteInformationCard.js.map +1 -0
  65. package/dist/views/settings/TypographyMotionCard.d.ts +6 -0
  66. package/dist/views/settings/TypographyMotionCard.d.ts.map +1 -0
  67. package/dist/views/settings/TypographyMotionCard.js +8 -0
  68. package/dist/views/settings/TypographyMotionCard.js.map +1 -0
  69. package/dist/views/settings/components.d.ts +38 -0
  70. package/dist/views/settings/components.d.ts.map +1 -0
  71. package/dist/views/settings/components.js +43 -0
  72. package/dist/views/settings/components.js.map +1 -0
  73. package/dist/views/settings/useAppearanceSettings.d.ts +69 -0
  74. package/dist/views/settings/useAppearanceSettings.d.ts.map +1 -0
  75. package/dist/views/settings/useAppearanceSettings.js +344 -0
  76. package/dist/views/settings/useAppearanceSettings.js.map +1 -0
  77. package/dist/views/settings/useGeneralSettings.d.ts +82 -0
  78. package/dist/views/settings/useGeneralSettings.d.ts.map +1 -0
  79. package/dist/views/settings/useGeneralSettings.js +286 -0
  80. package/dist/views/settings/useGeneralSettings.js.map +1 -0
  81. package/package.json +3 -3
  82. package/src/AdminRoot.tsx +5 -3
  83. package/src/__tests__/views/appearance-settings.render.test.tsx +132 -0
  84. package/src/__tests__/views/general-settings.render.test.tsx +135 -0
  85. package/src/components/ThemeProvider.tsx +249 -36
  86. package/src/layout/Sidebar.tsx +81 -13
  87. package/src/styles/theme.css +32 -2
  88. package/src/views/Settings.tsx +19 -155
  89. package/src/views/settings/AdminThemeCard.tsx +145 -0
  90. package/src/views/settings/AppearanceTab.tsx +81 -0
  91. package/src/views/settings/BrandPreviewCard.tsx +125 -0
  92. package/src/views/settings/BrandingCard.tsx +332 -0
  93. package/src/views/settings/GeneralSettingsTab.tsx +126 -0
  94. package/src/views/settings/LanguageRegionCard.tsx +119 -0
  95. package/src/views/settings/SeoRobotsDefaultsCard.tsx +149 -0
  96. package/src/views/settings/SiteIndexStatusCard.tsx +184 -0
  97. package/src/views/settings/SiteInformationCard.tsx +122 -0
  98. package/src/views/settings/TypographyMotionCard.tsx +65 -0
  99. package/src/views/settings/components.tsx +198 -0
  100. package/src/views/settings/useAppearanceSettings.ts +513 -0
  101. package/src/views/settings/useGeneralSettings.ts +379 -0
@@ -0,0 +1,344 @@
1
+ 'use client';
2
+ import { classifyLogoShape, logoShapeWarning, resolveAdminBrand, resolvePublicBrand, validateAccentColor, } from '@actuate-media/cms-core/appearance';
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
+ import { useTheme } from '../../components/ThemeProvider.js';
5
+ import { cmsApi } from '../../lib/api.js';
6
+ export const FIELD_ROLE = {
7
+ publicPrimaryLogoAssetId: 'publicPrimaryLogo',
8
+ publicLogoMarkAssetId: 'publicLogoMark',
9
+ publicDarkLogoAssetId: 'publicDarkLogo',
10
+ adminPrimaryLogoAssetId: 'adminPrimaryLogo',
11
+ adminLogoMarkAssetId: 'adminLogoMark',
12
+ adminDarkLogoAssetId: 'adminDarkLogo',
13
+ faviconSourceAssetId: 'faviconSource',
14
+ };
15
+ const LOGO_MIME = ['image/svg+xml', 'image/png'];
16
+ const FAVICON_MIME = ['image/svg+xml', 'image/png'];
17
+ const MAX_BYTES = 1024 * 1024; // 1 MB
18
+ const DEFAULT_FORM = {
19
+ colorMode: 'system',
20
+ accent: 'purple',
21
+ density: 'default',
22
+ font: 'DM Sans',
23
+ reduceMotion: false,
24
+ };
25
+ const DEFAULT_BRAND_FORM = { mode: 'inheritPublicBrand' };
26
+ function snapshot(a, b) {
27
+ return JSON.stringify({ a, b });
28
+ }
29
+ /** Read an uploaded image's shape client-side (raster via Image, SVG via XML). */
30
+ async function detectShape(file) {
31
+ if (file.type === 'image/svg+xml') {
32
+ try {
33
+ const text = await file.text();
34
+ const viewBox = text.match(/viewBox\s*=\s*["']\s*[\d.]+\s+[\d.]+\s+([\d.]+)\s+([\d.]+)/i);
35
+ if (viewBox)
36
+ return classifyLogoShape(parseFloat(viewBox[1]), parseFloat(viewBox[2]));
37
+ const w = text.match(/\bwidth\s*=\s*["']([\d.]+)/i);
38
+ const h = text.match(/\bheight\s*=\s*["']([\d.]+)/i);
39
+ if (w && h)
40
+ return classifyLogoShape(parseFloat(w[1]), parseFloat(h[1]));
41
+ }
42
+ catch {
43
+ /* fall through */
44
+ }
45
+ return 'unknown';
46
+ }
47
+ return new Promise((resolve) => {
48
+ const url = URL.createObjectURL(file);
49
+ const img = new Image();
50
+ img.onload = () => {
51
+ URL.revokeObjectURL(url);
52
+ resolve(classifyLogoShape(img.naturalWidth, img.naturalHeight));
53
+ };
54
+ img.onerror = () => {
55
+ URL.revokeObjectURL(url);
56
+ resolve('unknown');
57
+ };
58
+ img.src = url;
59
+ });
60
+ }
61
+ function assetToCache(brand, assets, siteTitle) {
62
+ const map = new Map(Object.values(assets).map((a) => [
63
+ a.id,
64
+ { id: a.id, publicUrl: a.url, mimeType: a.mimeType, width: a.width, height: a.height },
65
+ ]));
66
+ const resolved = resolveAdminBrand(brand, map, siteTitle);
67
+ return {
68
+ primaryUrl: resolved.primary?.url ?? null,
69
+ markUrl: resolved.mark?.url ?? null,
70
+ darkUrl: resolved.dark?.url ?? null,
71
+ initials: resolved.initials,
72
+ };
73
+ }
74
+ export function useAppearanceSettings(canEdit, config) {
75
+ const { applyAppearance, setAdminBrand } = useTheme();
76
+ const [loading, setLoading] = useState(true);
77
+ const [loadError, setLoadError] = useState(null);
78
+ const [appearance, setAppearance] = useState(DEFAULT_FORM);
79
+ const [brand, setBrand] = useState(DEFAULT_BRAND_FORM);
80
+ const [assets, setAssets] = useState({});
81
+ const [saveState, setSaveState] = useState('idle');
82
+ const [saveError, setSaveError] = useState(null);
83
+ const [uploadingField, setUploadingField] = useState(null);
84
+ const [showAdvanced, setShowAdvanced] = useState(false);
85
+ const baselineRef = useRef(snapshot(DEFAULT_FORM, DEFAULT_BRAND_FORM));
86
+ const siteTitleRef = useRef(null);
87
+ // Config-managed source detection (admin branding configured in actuate.config.ts).
88
+ const branding = config?.admin?.branding;
89
+ const sources = useMemo(() => {
90
+ const out = {};
91
+ if (branding?.primaryColor) {
92
+ out.accent = {
93
+ source: 'config',
94
+ editable: false,
95
+ reason: 'Primary color is set in actuate.config.ts (admin.branding.primaryColor).',
96
+ };
97
+ }
98
+ if (branding?.darkMode !== undefined) {
99
+ out.colorMode = {
100
+ source: 'config',
101
+ editable: true,
102
+ reason: 'Default dark mode comes from admin.branding.darkMode; you can still override it.',
103
+ };
104
+ }
105
+ return out;
106
+ }, [branding]);
107
+ const pushLive = useCallback((a, b, assetMap) => {
108
+ applyAppearance({
109
+ theme: a.colorMode,
110
+ accent: a.accent,
111
+ density: a.density,
112
+ font: a.font,
113
+ reduceMotion: a.reduceMotion,
114
+ adminBrand: assetToCache(b, assetMap, siteTitleRef.current),
115
+ });
116
+ }, [applyAppearance]);
117
+ const load = useCallback(async () => {
118
+ setLoading(true);
119
+ setLoadError(null);
120
+ const res = await cmsApi('/appearance');
121
+ if (res.error || !res.data) {
122
+ setLoadError(res.error ?? 'Failed to load appearance settings');
123
+ setLoading(false);
124
+ return;
125
+ }
126
+ const d = res.data;
127
+ const nextAppearance = {
128
+ colorMode: d.appearance.adminColorModeDefault,
129
+ accent: d.appearance.adminAccentColor,
130
+ density: d.appearance.sidebarDensity,
131
+ font: d.appearance.contentFont,
132
+ reduceMotion: d.appearance.reduceMotion,
133
+ };
134
+ const nextBrand = { ...d.brand, mode: d.brand?.mode ?? 'inheritPublicBrand' };
135
+ const nextAssets = {};
136
+ for (const a of d.assets ?? []) {
137
+ nextAssets[a.id] = {
138
+ id: a.id,
139
+ url: a.publicUrl,
140
+ mimeType: a.mimeType,
141
+ width: a.width ?? undefined,
142
+ height: a.height ?? undefined,
143
+ shape: classifyLogoShape(a.width ?? undefined, a.height ?? undefined),
144
+ };
145
+ }
146
+ siteTitleRef.current = d.siteTitle ?? null;
147
+ setAppearance(nextAppearance);
148
+ setBrand(nextBrand);
149
+ setAssets(nextAssets);
150
+ if (nextBrand.adminLogoMarkAssetId || nextBrand.publicLogoMarkAssetId)
151
+ setShowAdvanced(true);
152
+ baselineRef.current = snapshot(nextAppearance, nextBrand);
153
+ pushLive(nextAppearance, nextBrand, nextAssets);
154
+ setSaveState('idle');
155
+ setLoading(false);
156
+ }, [pushLive]);
157
+ useEffect(() => {
158
+ void load();
159
+ }, [load]);
160
+ // ── Mutators (live-apply theme controls before save) ──────────────────────
161
+ const update = useCallback((next, b, assetMap) => {
162
+ setAppearance(next);
163
+ setBrand(b);
164
+ setAssets(assetMap);
165
+ setSaveState('idle');
166
+ pushLive(next, b, assetMap);
167
+ }, [pushLive]);
168
+ const setColorMode = useCallback((v) => update({ ...appearance, colorMode: v }, brand, assets), [appearance, brand, assets, update]);
169
+ const setAccent = useCallback((v) => update({ ...appearance, accent: v }, brand, assets), [appearance, brand, assets, update]);
170
+ const setDensity = useCallback((v) => update({ ...appearance, density: v }, brand, assets), [appearance, brand, assets, update]);
171
+ const setFont = useCallback((v) => update({ ...appearance, font: v }, brand, assets), [appearance, brand, assets, update]);
172
+ const setReduceMotion = useCallback((v) => update({ ...appearance, reduceMotion: v }, brand, assets), [appearance, brand, assets, update]);
173
+ const setBrandingMode = useCallback((v) => update(appearance, { ...brand, mode: v }, assets), [appearance, brand, assets, update]);
174
+ const setAltText = useCallback((v) => update(appearance, { ...brand, defaultLogoAltText: v }, assets), [appearance, brand, assets, update]);
175
+ const uploadAsset = useCallback(async (field, file) => {
176
+ const isFavicon = field === 'faviconSourceAssetId';
177
+ const allowed = isFavicon ? FAVICON_MIME : LOGO_MIME;
178
+ if (!allowed.includes(file.type)) {
179
+ setSaveError(`Unsupported file type. Allowed: ${allowed.join(', ')}.`);
180
+ return;
181
+ }
182
+ if (file.size > MAX_BYTES) {
183
+ setSaveError('File exceeds the 1MB limit.');
184
+ return;
185
+ }
186
+ setSaveError(null);
187
+ setUploadingField(field);
188
+ try {
189
+ const shape = await detectShape(file);
190
+ const form = new FormData();
191
+ form.append('file', file);
192
+ // Preserve original format (SVG/PNG/ICO fidelity) — brand assets must
193
+ // not be transcoded to WebP.
194
+ form.append('skipOptimize', 'true');
195
+ const res = await cmsApi('/media/upload', {
196
+ method: 'POST',
197
+ body: form,
198
+ });
199
+ if (res.error || !res.data?.id) {
200
+ setSaveError(res.error ?? 'Upload failed');
201
+ return;
202
+ }
203
+ const id = res.data.id;
204
+ const nextAssets = {
205
+ ...assets,
206
+ [id]: {
207
+ id,
208
+ url: res.data.url ?? '',
209
+ mimeType: res.data.mimeType ?? file.type,
210
+ shape,
211
+ },
212
+ };
213
+ update(appearance, { ...brand, [field]: id }, nextAssets);
214
+ }
215
+ finally {
216
+ setUploadingField(null);
217
+ }
218
+ }, [appearance, brand, assets, update]);
219
+ const removeAsset = useCallback((field) => {
220
+ const next = { ...brand };
221
+ delete next[field];
222
+ update(appearance, next, assets);
223
+ }, [appearance, brand, assets, update]);
224
+ const issues = useMemo(() => {
225
+ const out = [];
226
+ const accentCheck = validateAccentColor(appearance.accent);
227
+ if (!accentCheck.valid) {
228
+ out.push({
229
+ field: 'accent',
230
+ message: accentCheck.reason ?? 'Invalid accent color.',
231
+ severity: 'error',
232
+ });
233
+ }
234
+ // Shape warnings per asset field.
235
+ for (const field of Object.keys(FIELD_ROLE)) {
236
+ const id = brand[field];
237
+ if (!id)
238
+ continue;
239
+ const shape = assets[id]?.shape;
240
+ if (!shape)
241
+ continue;
242
+ const w = logoShapeWarning(FIELD_ROLE[field], shape);
243
+ if (w)
244
+ out.push({ field, message: w, severity: 'warning' });
245
+ }
246
+ // Dark mode default but no dark logo.
247
+ const hasDark = Boolean(brand.publicDarkLogoAssetId || brand.adminDarkLogoAssetId);
248
+ if (appearance.colorMode === 'dark' && !hasDark) {
249
+ out.push({
250
+ field: 'colorMode',
251
+ message: 'Dark mode is the default but no dark-mode logo is set. The primary logo will be used on dark backgrounds.',
252
+ severity: 'warning',
253
+ });
254
+ }
255
+ return out;
256
+ }, [appearance, brand, assets]);
257
+ const preview = useMemo(() => {
258
+ const map = new Map(Object.values(assets).map((a) => [
259
+ a.id,
260
+ { id: a.id, publicUrl: a.url, mimeType: a.mimeType, width: a.width, height: a.height },
261
+ ]));
262
+ const title = siteTitleRef.current;
263
+ const faviconId = brand.faviconSourceAssetId;
264
+ return {
265
+ admin: resolveAdminBrand(brand, map, title),
266
+ public: resolvePublicBrand(brand, map, title),
267
+ faviconUrl: faviconId ? (assets[faviconId]?.url ?? null) : null,
268
+ };
269
+ }, [brand, assets]);
270
+ const dirty = useMemo(() => snapshot(appearance, brand) !== baselineRef.current, [appearance, brand]);
271
+ const save = useCallback(async () => {
272
+ if (!canEdit)
273
+ return;
274
+ if (issues.some((i) => i.severity === 'error'))
275
+ return;
276
+ setSaveState('saving');
277
+ setSaveError(null);
278
+ // Read-modify-write the settings global so we never clobber sibling keys
279
+ // (siteTitle, SEO defaults, AI flags, …) written by other settings tabs.
280
+ const current = await cmsApi('/globals/settings');
281
+ if (current.error) {
282
+ setSaveState('error');
283
+ setSaveError(current.error);
284
+ return;
285
+ }
286
+ const now = new Date().toISOString();
287
+ const brandPayload = { ...brand, updatedAt: now };
288
+ const appearancePayload = {
289
+ adminColorModeDefault: appearance.colorMode,
290
+ adminAccentColor: appearance.accent,
291
+ sidebarDensity: appearance.density,
292
+ contentFont: appearance.font,
293
+ reduceMotion: appearance.reduceMotion,
294
+ updatedAt: now,
295
+ };
296
+ const merged = {
297
+ ...(current.data ?? {}),
298
+ appearance: appearancePayload,
299
+ brand: brandPayload,
300
+ };
301
+ const res = await cmsApi('/globals/settings', { method: 'PUT', body: JSON.stringify(merged) });
302
+ if (res.error) {
303
+ setSaveState('error');
304
+ setSaveError(res.error);
305
+ return;
306
+ }
307
+ baselineRef.current = snapshot(appearance, brand);
308
+ setAdminBrand(assetToCache(brand, assets, siteTitleRef.current));
309
+ setSaveState('success');
310
+ }, [canEdit, issues, appearance, brand, assets, setAdminBrand]);
311
+ const reset = useCallback(() => {
312
+ const base = JSON.parse(baselineRef.current);
313
+ update(base.a, base.b, assets);
314
+ }, [assets, update]);
315
+ return {
316
+ loading,
317
+ loadError,
318
+ appearance,
319
+ brand,
320
+ assets,
321
+ sources,
322
+ issues,
323
+ preview,
324
+ dirty,
325
+ saveState,
326
+ saveError,
327
+ uploadingField,
328
+ showAdvanced,
329
+ setShowAdvanced,
330
+ setColorMode,
331
+ setAccent,
332
+ setDensity,
333
+ setFont,
334
+ setReduceMotion,
335
+ setBrandingMode,
336
+ setAltText,
337
+ uploadAsset,
338
+ removeAsset,
339
+ save,
340
+ reset,
341
+ reload: () => void load(),
342
+ };
343
+ }
344
+ //# sourceMappingURL=useAppearanceSettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAppearanceSettings.js","sourceRoot":"","sources":["../../../src/views/settings/useAppearanceSettings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /** Editable + computed shape of the General tab form. */
2
+ export interface GeneralSettingsForm {
3
+ siteTitle: string;
4
+ tagline: string;
5
+ siteUrl: string;
6
+ language: string;
7
+ timezone: string;
8
+ defaultNoIndex: boolean;
9
+ defaultNoFollow: boolean;
10
+ noIndexNonProduction: boolean;
11
+ }
12
+ export type SettingsSource = 'config' | 'environment' | 'database' | 'plugin' | 'computed';
13
+ export interface SettingsSourceMetadata {
14
+ source: SettingsSource;
15
+ editable: boolean;
16
+ reason?: string;
17
+ }
18
+ export type IndexStatusLevel = 'indexable' | 'protected' | 'blocked' | 'partially_blocked' | 'unknown';
19
+ export interface SiteIndexStatus {
20
+ status: IndexStatusLevel;
21
+ severity: 'success' | 'warning' | 'danger' | 'neutral';
22
+ label: string;
23
+ description: string;
24
+ environment: string;
25
+ checks: Array<{
26
+ key: string;
27
+ label: string;
28
+ value: string;
29
+ status: 'pass' | 'warning' | 'fail' | 'unknown';
30
+ }>;
31
+ actions: Array<{
32
+ label: string;
33
+ href?: string;
34
+ action?: string;
35
+ }>;
36
+ lastAuditAt: string | null;
37
+ }
38
+ export interface ValidationIssue {
39
+ /** Field key the issue relates to. A plain string so the primitive can be
40
+ * reused by other settings tabs (e.g. Appearance) whose fields aren't part
41
+ * of `GeneralSettingsForm`. */
42
+ field: string;
43
+ message: string;
44
+ severity: 'error' | 'warning';
45
+ }
46
+ /** Validate a site URL: absolute http(s), no trailing slash, parseable. */
47
+ export declare function validateSiteUrl(value: string): {
48
+ valid: boolean;
49
+ error?: string;
50
+ };
51
+ /** Best-effort IANA timezone check using the Intl API. */
52
+ export declare function isValidTimeZone(tz: string): boolean;
53
+ /** Best-effort BCP 47 locale check. */
54
+ export declare function isValidLocale(locale: string): boolean;
55
+ type SaveState = 'idle' | 'saving' | 'success' | 'error';
56
+ export interface UseGeneralSettings {
57
+ loading: boolean;
58
+ loadError: string | null;
59
+ form: GeneralSettingsForm;
60
+ setField: <K extends keyof GeneralSettingsForm>(key: K, value: GeneralSettingsForm[K]) => void;
61
+ dirty: boolean;
62
+ issues: ValidationIssue[];
63
+ hasErrors: boolean;
64
+ indexStatus: SiteIndexStatus | null;
65
+ sources: Record<string, SettingsSourceMetadata>;
66
+ isProduction: boolean;
67
+ saveState: SaveState;
68
+ saveError: string | null;
69
+ save: () => Promise<void>;
70
+ reset: () => void;
71
+ refetch: () => void;
72
+ }
73
+ /**
74
+ * Loads the General tab from its three real backends — the `settings` global
75
+ * (site info / locale), the shared `/seo/config` (site URL + robots defaults),
76
+ * and the computed `/seo/index-status` — tracks a dirty diff, and on save
77
+ * writes each field back to its OWNING store (never a duplicate), preserving
78
+ * unrelated keys.
79
+ */
80
+ export declare function useGeneralSettings(canEdit: boolean): UseGeneralSettings;
81
+ export {};
82
+ //# sourceMappingURL=useGeneralSettings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGeneralSettings.d.ts","sourceRoot":"","sources":["../../../src/views/settings/useGeneralSettings.ts"],"names":[],"mappings":"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"}