feat: implement CSRF token helper and update fetch headers; adjust layout styles for responsiveness

This commit is contained in:
catlog22
2026-03-02 23:27:42 +08:00
parent 1bf9006d65
commit d7169029ee
3 changed files with 78 additions and 27 deletions

View File

@@ -63,6 +63,12 @@ import type { ExportedSettings } from '@/lib/api';
import { RemoteNotificationSection } from '@/components/settings/RemoteNotificationSection'; import { RemoteNotificationSection } from '@/components/settings/RemoteNotificationSection';
import { A2UIPreferencesSection } from '@/components/settings/A2UIPreferencesSection'; import { A2UIPreferencesSection } from '@/components/settings/A2UIPreferencesSection';
// ========== CSRF Token Helper ==========
function getCsrfToken(): string | null {
const match = document.cookie.match(/XSRF-TOKEN=([^;]+)/);
return match ? decodeURIComponent(match[1]) : null;
}
// ========== File Path Input with Native File Picker ========== // ========== File Path Input with Native File Picker ==========
interface FilePathInputProps { interface FilePathInputProps {
@@ -1282,10 +1288,17 @@ export function SettingsPage() {
body.effort = config.effort || null; body.effort = config.effort || null;
} }
const csrfToken = getCsrfToken();
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
if (csrfToken) {
headers['X-CSRF-Token'] = csrfToken;
}
const res = await fetch(`/api/cli/config/${toolId}`, { const res = await fetch(`/api/cli/config/${toolId}`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers,
body: JSON.stringify(body), body: JSON.stringify(body),
credentials: 'same-origin',
}); });
if (!res.ok) { if (!res.ok) {

View File

@@ -33,14 +33,14 @@
--vp-custom-block-danger-border: #fecaca; --vp-custom-block-danger-border: #fecaca;
--vp-custom-block-danger-text: #b91c1c; --vp-custom-block-danger-text: #b91c1c;
/* Layout Width - Wider content area */ /* Layout Width - Wider content area (using rem for zoom responsiveness) */
--vp-layout-max-width: 1600px; --vp-layout-max-width: 100rem; /* 1600px / 16 */
--vp-content-width: 920px; --vp-content-width: 57.5rem; /* 920px / 16 */
--vp-sidebar-width: 280px; --vp-sidebar-width: 17.5rem; /* 280px / 16 */
--vp-toc-width: 200px; --vp-toc-width: 12.5rem; /* 200px / 16 */
/* Prose width for optimal readability */ /* Prose width for optimal readability */
--vp-prose-width: 820px; --vp-prose-width: 51.25rem; /* 820px / 16 */
} }
.dark { .dark {
@@ -575,6 +575,39 @@ div[class*='language-'] .vp-copy:hover {
padding: var(--vp-spacing-2) var(--vp-spacing-4); padding: var(--vp-spacing-2) var(--vp-spacing-4);
} }
/* Sidebar numbering and indentation */
/* Initialize counter on the sidebar container */
.VPSidebar .VPSidebarGroup,
.VPSidebar nav {
counter-reset: sidebar-item;
}
/* Increment counter for level-1 items only */
.VPSidebar .VPSidebarItem.level-1 {
counter-increment: sidebar-item;
}
/* Add numbers to sidebar items */
.VPSidebar .VPSidebarItem.level-1 .link::before {
content: counter(sidebar-item) ". ";
color: var(--vp-c-text-3);
font-weight: 500;
margin-right: 8px;
}
/* Indentation for different levels */
.VPSidebar .VPSidebarItem.level-1 {
padding-left: 16px;
}
.VPSidebar .VPSidebarItem.level-2 {
padding-left: 32px;
}
.VPSidebar .VPSidebarItem.level-3 {
padding-left: 48px;
}
/* ============================================ /* ============================================
* Navigation Polish * Navigation Polish
* ============================================ */ * ============================================ */
@@ -662,15 +695,20 @@ div[class*='language-'] .vp-copy:hover {
background: var(--vp-c-bg-soft); background: var(--vp-c-bg-soft);
} }
.VPDocOutline .outline-link.is-active { /* Match VitePress actual DOM structure: <li><a class="outline-link active">...</a></li> */
color: var(--vp-c-primary); /* Override VitePress scoped styles with higher specificity */
font-weight: 500; .VPDocAside .VPDocAsideOutline .outline-link.active {
background: var(--vp-c-bg-soft); color: var(--vp-c-brand) !important;
font-weight: 600 !important;
background: var(--vp-c-bg-soft) !important;
padding: 4px 8px !important;
border-radius: 4px !important;
transition: all 0.25s !important;
} }
.VPDocOutline .outline-marker { .VPDocOutline .outline-marker {
width: 2px; width: 3px;
background: var(--vp-c-primary); background: var(--vp-c-brand);
border-radius: var(--vp-radius-full); border-radius: var(--vp-radius-full);
} }

View File

@@ -658,11 +658,11 @@
* ============================================ */ * ============================================ */
@media (min-width: 1024px) { @media (min-width: 1024px) {
:root { :root {
--vp-layout-max-width: 1440px; --vp-layout-max-width: 90rem; /* 1440px / 16 */
--vp-content-width: 860px; --vp-content-width: 53.75rem; /* 860px / 16 */
--vp-sidebar-width: 280px; --vp-sidebar-width: 17.5rem; /* 280px / 16 */
--vp-prose-width: 720px; --vp-prose-width: 45rem; /* 720px / 16 */
--vp-toc-width: 220px; --vp-toc-width: 13.75rem; /* 220px / 16 */
} }
.VPContent { .VPContent {
@@ -691,14 +691,14 @@
/* Ensure content has proper margin-left to clear the sidebar */ /* Ensure content has proper margin-left to clear the sidebar */
.VPContent.has-sidebar { .VPContent.has-sidebar {
margin-left: var(--vp-sidebar-width, 280px) !important; margin-left: var(--vp-sidebar-width) !important;
margin-right: calc(var(--vp-toc-width, 220px) + 48px) !important; margin-right: calc(var(--vp-toc-width) + 3rem) !important; /* 48px = 3rem */
padding: var(--vp-spacing-8) var(--vp-spacing-12) !important; padding: var(--vp-spacing-8) var(--vp-spacing-12) !important;
} }
/* Adjust doc container - remove auto margin to prevent offset */ /* Adjust doc container - allow content to scale with zoom */
.VPDoc.has-aside .content-container { .VPDoc.has-aside .content-container {
max-width: 100%; width: 100%;
padding: 0 var(--vp-spacing-10); padding: 0 var(--vp-spacing-10);
} }
@@ -781,14 +781,14 @@
* ============================================ */ * ============================================ */
@media (min-width: 1440px) { @media (min-width: 1440px) {
:root { :root {
--vp-content-width: 920px; --vp-content-width: 57.5rem; /* 920px / 16 */
--vp-sidebar-width: 300px; --vp-sidebar-width: 18.75rem; /* 300px / 16 */
--vp-prose-width: 760px; --vp-prose-width: 47.5rem; /* 760px / 16 */
--vp-toc-width: 260px; --vp-toc-width: 16.25rem; /* 260px / 16 */
} }
.VPDoc.has-aside .content-container { .VPDoc.has-aside .content-container {
max-width: 100%; width: 100%;
padding: 0 var(--vp-spacing-12); padding: 0 var(--vp-spacing-12);
margin-left: 0; margin-left: 0;
margin-right: 0; margin-right: 0;