diff --git a/apps/blog-platform/lib/source.ts b/apps/blog-platform/lib/source.ts index 14e2b36..2acf2da 100644 --- a/apps/blog-platform/lib/source.ts +++ b/apps/blog-platform/lib/source.ts @@ -1,9 +1,12 @@ import { loader } from "fumadocs-core/source"; +import type { PageData } from "fumadocs-core/source"; import { toFumadocsSource } from "fumadocs-mdx/runtime/server"; -import { blogPosts } from "collections/server"; +import { blogPosts } from "../.source/server"; + +type BlogPostPage = (typeof blogPosts)[number] & PageData; export const blog = loader({ baseUrl: "/", - source: toFumadocsSource(blogPosts, []), + source: toFumadocsSource(blogPosts as BlogPostPage[], []), }); diff --git a/apps/docs-platform/content/docs/contributing/index.mdx b/apps/docs-platform/content/docs/contributing/index.mdx index cde2209..8ded844 100644 --- a/apps/docs-platform/content/docs/contributing/index.mdx +++ b/apps/docs-platform/content/docs/contributing/index.mdx @@ -81,6 +81,7 @@ Your branch name should start with one of the following prefixes based on the wo ### Pre-commit Quality Verification Before committing and pushing your changes, run automated scripts to ensure style guides and formats are preserved: + ```bash # Run typescript compilation and linter npm run lint diff --git a/apps/studio/app/(main)/(dashboard)/settings/components/SyncSection.tsx b/apps/studio/app/(main)/(dashboard)/settings/components/SyncSection.tsx index 0c6ee4a..20aee2d 100644 --- a/apps/studio/app/(main)/(dashboard)/settings/components/SyncSection.tsx +++ b/apps/studio/app/(main)/(dashboard)/settings/components/SyncSection.tsx @@ -17,6 +17,7 @@ import { loadWorkspaceSettingsFromLocalStorage, } from "@/features/documents/services/workspace-settings"; import { setAllResumesSyncEnabled } from "@/features/resume/services/resume-service"; +import { useUserStore } from "@/store/useUserStore"; interface TelemetryState { lastAttemptAt: string | null; @@ -26,6 +27,7 @@ interface TelemetryState { export default function SyncSection() { const [loading, setLoading] = useState(false); const [autoSync, setAutoSync] = useState(false); + const isLoggedIn = useUserStore((state) => state.isLoggedIn); const [telemetry, setTelemetry] = useState({ lastAttemptAt: null, @@ -56,6 +58,11 @@ export default function SyncSection() { }, []); const handleToggle = async (checked: boolean) => { + if (!isLoggedIn) { + setAutoSync(false); + return; + } + setAutoSync(checked); setAutoSyncEnabledInLocalStorage(checked); setAllResumesSyncEnabled(checked); @@ -67,6 +74,8 @@ export default function SyncSection() { } }; + const displayedAutoSync = isLoggedIn && autoSync; + return (
@@ -75,7 +84,11 @@ export default function SyncSection() { Cloud & Data -

Manage background synchronization.

+

+ {isLoggedIn + ? "Manage background synchronization." + : "Sign in to enable background synchronization."} +

@@ -83,7 +96,11 @@ export default function SyncSection() { Auto-Sync - +
diff --git a/apps/studio/tests/contracts/sync-section.contract.test.tsx b/apps/studio/tests/contracts/sync-section.contract.test.tsx new file mode 100644 index 0000000..7ec280a --- /dev/null +++ b/apps/studio/tests/contracts/sync-section.contract.test.tsx @@ -0,0 +1,58 @@ +import { renderToStaticMarkup } from "react-dom/server"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import SyncSection from "@/app/(main)/(dashboard)/settings/components/SyncSection"; + +type MockUserState = { + user: { id: string; email: string; name?: string } | null; + loading: boolean; + isLoggedIn: boolean; +}; + +const mockUserState = vi.hoisted(() => ({ + current: { + user: null, + loading: false, + isLoggedIn: false, + } as MockUserState, +})); + +vi.mock("next/font/google", () => ({ + Geist: () => ({ variable: "--font-geist-sans" }), + Geist_Mono: () => ({ variable: "--font-geist-mono" }), +})); + +vi.mock("@/store/useUserStore", () => ({ + useUserStore: (selector: (state: MockUserState) => unknown) => selector(mockUserState.current), +})); + +describe("sync settings contract", () => { + beforeEach(() => { + mockUserState.current = { + user: null, + loading: false, + isLoggedIn: false, + }; + }); + + it("disables auto sync while the user is logged out", () => { + const html = renderToStaticMarkup(); + + expect(html).toContain("Sign in to enable background synchronization."); + expect(html).toMatch(/]*type="checkbox"[^>]*disabled/); + expect(html).not.toMatch(/]*type="checkbox"[^>]*checked/); + }); + + it("keeps the auto sync control available while the user is logged in", () => { + mockUserState.current = { + user: { id: "user-1", email: "user@example.com", name: "User" }, + loading: false, + isLoggedIn: true, + }; + + const html = renderToStaticMarkup(); + + expect(html).toContain("Manage background synchronization."); + expect(html).not.toMatch(/]*type="checkbox"[^>]*disabled/); + }); +}); diff --git a/packages/ui/README.md b/packages/ui/README.md index 3bc5d03..dde9176 100644 --- a/packages/ui/README.md +++ b/packages/ui/README.md @@ -88,9 +88,7 @@ import "@veriworkly/ui/styles/globals.css"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( - - {children} - + {children} ); } @@ -100,16 +98,18 @@ export default function RootLayout({ children }: { children: React.ReactNode }) ## 🎨 Theme & Styling System -The library utilizes a dual-theme variable design configured for light and dark modes in `src/styles/themes.css`. +The library utilizes a dual-theme variable design configured for light and dark modes in `src/styles/themes.css`. ### Key Custom Theme Variables: -* `--background` / `--color-fd-background`: Main application canvas color. -* `--foreground` / `--color-fd-foreground`: Primary typography and element color. -* `--card` / `--color-fd-card`: Card and modal background color. -* `--border` / `--color-fd-border`: Soft divider and border color. -* `--accent` / `--color-fd-primary`: Main brand color for action elements. + +- `--background` / `--color-fd-background`: Main application canvas color. +- `--foreground` / `--color-fd-foreground`: Primary typography and element color. +- `--card` / `--color-fd-card`: Card and modal background color. +- `--border` / `--color-fd-border`: Soft divider and border color. +- `--accent` / `--color-fd-primary`: Main brand color for action elements. ### CSS Usage Example: + ```css .custom-component { background-color: var(--background);