Skip to content

Conversation

@Friedrich482
Copy link
Owner

@Friedrich482 Friedrich482 commented Aug 14, 2025

Commits

  • refactor: logger

    • replaced all the raw console.{log, dir, error}, by custom logger functions with prefix to easily identify MoonCode logs in the console
  • chore: extension bump

    • bumped the version of the extension to 0.0.22
    • removed the unnecessary parseInt calls in the DayLanguagesChart and ProjectLanguagesTimeOnPeriod components
  • chore: zod

    • fixed the zod version in the dashboard and vscode extension
    • replaced default zod import in favor of single exports
  • feat: react-day-picker

    • updated react-day-picker to v9
  • chore: migration

    • migrated to react 19 and to tailwindcss v4
  • fix: calendar

    • fixed the calendar with the proper styles
    • added .prettierrc in the ui package to get the tailwind prettier plugin, also installed the plugin in the package
  • fix: ProjectTimeOnPeriod

    • fixed the issue of the chart not properly displaying after the migration to tailwind v4 and react 19
  • chore: checkbox

    • increased the size of the check icon in the checkbox component
    • removed some smaller dependencies from the rollup chunks
  • chore: zod

    • updated zod to v4.0.17
  • chore: web

    • migrated the web app to tailwindcss v4

Summary by CodeRabbit

  • New Features

    • Rebuilt login and registration pages with client-side validation and JWT flow.
    • Project time chart can toggle between area and bar+line views.
  • Improvements

    • Overhauled theming, color tokens and responsive breakpoints for improved visuals and dark mode.
    • UI component refresh for more consistent styling and accessibility.
    • Refined chart and tooltip visuals and color handling.
  • Tooling

    • Tailwind/Vite integrations and SVGR plugin added.
  • VS Code Extension

    • Extension version bumped to 0.0.22.
  • Chores

    • Dependency upgrades (React 19, Tailwind v4, Zod and others); removed legacy npm peer-deps config.

- replaced all the raw `console.{log, dir, error},` by custom logger functions with prefix to easily identify MoonCode logs in the console
- bumped the version of the extension to `0.0.22`
- removed the unnecessary `parseInt` calls in the `DayLanguagesChart` and `ProjectLanguagesTimeOnPeriod` components
- fixed the zod version in the dashboard and vscode extension
- replaced default zod import in favor of single exports
- updated react-day-picker to v9
- migrated to react 19 and to tailwindcss v4
- fixed the calendar with the proper styles
- added `.prettierrc` in the ui package to get the tailwind prettier plugin, also installed the plugin in the package
-  fixed the issue of the chart not properly displaying after the migration to tailwind v4 and react 19
- increased the size of the check icon in the checkbox component
- removed some smaller dependencies from the rollup chunks
- updated zod to v4.0.17
- migrated the web app to tailwindcss v4
@coderabbitai
Copy link

coderabbitai bot commented Aug 14, 2025

Walkthrough

Removed legacy-peer-deps from .npmrc; bumped and realigned dependencies (React 19, zod ^4.0.17, Tailwind/tooling); migrated PostCSS/Tailwind configs and Vite plugins (svgr, @tailwindcss/vite); large UI refactors (many forwardRef → plain components, data-slot, tokenized CSS); moved/added dashboard auth pages; added VSCode extension logger and replaced console usage.

Changes

Cohort / File(s) Summary
Repo config & dependency updates
/.npmrc, apps/api/package.json, apps/dashboard/package.json, apps/web/package.json, apps/vscode-extension/package.json, packages/common/package.json, packages/ui/package.json, packages/ui/.prettierrc
Removed legacy-peer-deps flag; bumped zod across packages, upgraded React/ReactDOM and @types to 19.x in UI/apps; added Tailwind/PostCSS/Vite plugins and prettier-plugin-tailwindcss; pinned date-fns in vscode extension.
Vite / PostCSS / Tailwind changes
apps/dashboard/vite.config.ts, apps/dashboard/postcss.config.mjs, apps/dashboard/tailwind.config.ts (deleted), apps/web/postcss.config.mjs, apps/web/tailwind.config.ts (deleted), apps/dashboard/src/vite-env.d.ts
Added vite-plugin-svgr and @tailwindcss/vite plugins; removed manualChunks; switched PostCSS to inline @tailwindcss/postcss; deleted per-app Tailwind configs; added SVGR types reference.
Shared UI theming & PostCSS
packages/ui/postcss.config.mjs, packages/ui/tailwind.config.ts (deleted), packages/ui/components.json, packages/ui/src/globals.css, apps/dashboard/src/index.css
Replaced tailwind+autoprefixer with @tailwindcss/postcss; removed packages/ui Tailwind config; enabled cssVariables; introduced tokenized CSS variables, breakpoints, and auth-root padding override.
UI public exports
packages/ui/src/index.ts
Removed re-export of DateRange type from react-day-picker.
Large UI component refactor
packages/ui/src/components/ui/* (e.g., button.tsx, button-variants.ts (deleted), card.tsx, chart.tsx, dropdown-menu.tsx, popover.tsx, tooltip.tsx, form.tsx, input.tsx, label.tsx, calendar.tsx, CalendarPopover.tsx, checkbox.tsx, ...)
Converted many components from forwardRef/aliases to plain function components, removed/refactored ref forwarding, added data-slot attributes, inlined buttonVariants, expanded/changed public exports (e.g., CardAction), reorganized chart primitives to use a Recharts namespace.
Dashboard components & charts
apps/dashboard/src/components/** (e.g., CustomChartToolTip.tsx, GeneralStatsChart.tsx, PeriodTimeChart.tsx, dayLanguagesChart/DayLanguagesChart.tsx, project-page/charts/*, constants.ts, layout/Layout.tsx, project-page/Project.tsx)
Mostly presentational class reorders and small visual tweaks; several colors changed from hsl(var(--...))var(--...); tooltip formatter types adjusted (string → number) in charts; ProjectTimeOnPeriodChart added conditional AreaChart/ComposedChart rendering; some prop typings widened (ref
Auth pages relocation & new components
apps/dashboard/src/main.tsx, apps/dashboard/src/components/auth/login-page/LoginForm.tsx (added), apps/dashboard/src/components/auth/register-page/RegisterForm.tsx (added), deletions: apps/dashboard/src/components/login-page/LoginForm.tsx, apps/dashboard/src/components/register-page/RegisterForm.tsx
Moved login/register into auth subfolder; added new LoginForm/RegisterForm implementations using react-hook-form + zod, JWT fetch & callback redirect logic, TRPC cache invalidation and navigation; removed older login/register files.
VSCode extension: logger + logging replacements
apps/vscode-extension/src/utils/logger/logger.ts, apps/vscode-extension/src/extension.ts, apps/vscode-extension/src/utils/commands/initExtensionCommands.ts, apps/vscode-extension/src/utils/dashboard/serveDashboard.ts, apps/vscode-extension/src/utils/periodicSyncData.ts, apps/vscode-extension/src/utils/time/calculateTime.ts
Added a logger module (logInfo, logDir, logError) and replaced console.log/dir/error calls with these helpers across the extension (preserving messages/behavior).
VSCode extension types & metadata
apps/vscode-extension/README.md, apps/vscode-extension/src/types-schemas.ts, apps/vscode-extension/src/utils/auth/parseJwtPayload.ts
Bumped extension version and README badge; switched zod import to named { z }; adjusted parseJwtPayload return type to ZodSafeParseResult.
Misc small UI tweaks
apps/dashboard/src/components/layout/header/Logo.tsx, apps/dashboard/src/components/CustomChartToolTip.tsx, various chart files, apps/dashboard/src/components/project-page/charts/ProjectTimeOnPeriodChart.tsx
Logo now accepts className; minor Tailwind class reorders and rounding changes; icon imports/aliases adjusted; chart color string usages made consistent with token surface.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ProjectTimeOnPeriodChart
  participant Recharts
  participant Tooltip

  User->>ProjectTimeOnPeriodChart: open/view chart
  ProjectTimeOnPeriodChart->>ProjectTimeOnPeriodChart: check isBarChartVisible
  alt isBarChartVisible == true
    ProjectTimeOnPeriodChart->>Recharts: render ComposedChart (Bar + Line)
  else
    ProjectTimeOnPeriodChart->>Recharts: render AreaChart
  end
  Recharts->>Tooltip: request tooltip content/format
  Tooltip-->>User: render tooltip with numeric value and originalDate
Loading
sequenceDiagram
  participant VSCodeExt
  participant Logger
  participant Console

  VSCodeExt->>Logger: logInfo/logError/logDir(...)
  Logger->>Console: console.log / console.error / console.dir (prefixed with [MoonCode])
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

I hopped through CSS and bumped some crates,
Reworked components, untangled the gates.
Logs now wear tags, charts pick bar or wave,
Auth doors moved in — the router's brave.
A rabbit's tiny tweak, shipped in joyful straits 🥕🐇

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch features

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Owner Author

@Friedrich482 Friedrich482 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes reviewed

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 33

🔭 Outside diff range comments (12)
apps/vscode-extension/src/types-schemas.ts (2)

17-22: Replace non-standard z.iso.datetime() with a supported Zod v4 approach.

z.iso.datetime() isn’t part of Zod’s public API. Use z.coerce.date() to accept Date or ISO string and produce a Date, simplifying the union and transform.

Apply:

-export const globalStateInitialDataSchema = z.object({
-  lastServerSync: z.union([
-    z.date(),
-    z.iso.datetime().transform((str) => new Date(str)),
-  ]),
+export const globalStateInitialDataSchema = z.object({
+  lastServerSync: z.coerce.date(),

39-43: Same issue here: prefer z.coerce.date() for updatedAt.

Aligns with Zod v4 and removes reliance on a non-existent z.iso.datetime().

Apply:

-  updatedAt: z.union([
-    z.date(),
-    z.iso.datetime().transform((str) => new Date(str)),
-  ]),
+  updatedAt: z.coerce.date(),
apps/dashboard/src/components/dashboard-page/charts/dayLanguagesChart/DayLanguagesChart.tsx (1)

100-109: Incorrect prop on ; use Bar.minPointSize instead of Cell.min.

Recharts’ Cell doesn’t support “min”. If you want a minimum visible bar size, set it on Bar via minPointSize and remove min from Cell.

Apply this diff:

-            <Bar dataKey="timeSpent" layout="vertical" radius={5}>
+            <Bar dataKey="timeSpent" layout="vertical" radius={5} minPointSize={2}>
               {chartData.map((entry) => (
                 <Cell
                   fill={entry.color}
-                  min={0}
                   key={entry.languageSlug}
                   className="cursor-pointer"
                 />
               ))}
             </Bar>
apps/dashboard/src/components/project-page/charts/ProjectLanguagesTimeOnPeriodChart.tsx (1)

111-134: Remove parseInt and type the formatter value as number for BarChart.

This still parses a value that Recharts already provides as a number. Align with the PieChart and other charts by typing the arg as number and passing it through.

Apply this diff:

-                formatter={(value: string, languageSlug) =>
-                  CustomChartToolTip(
-                    parseInt(value),
-                    getLanguageColor(languageSlug),
-                    languageSlug,
-                  )
-                }
+                formatter={(value: number, languageSlug) =>
+                  CustomChartToolTip(
+                    value,
+                    getLanguageColor(languageSlug),
+                    languageSlug,
+                  )
+                }
apps/dashboard/src/components/dashboard-page/charts/PeriodTimeChart.tsx (1)

67-71: Drop parseInt and type the value as number in the tooltip formatter.

Recharts provides numeric values for numeric dataKeys. Avoid coercion and keep types explicit.

Apply this diff:

-            formatter={(value, name) =>
-              name === "Time"
-                ? CustomChartToolTip(parseInt(value), "var(--color-time)")
-                : null
-            }
+            formatter={(value: number, name) =>
+              name === "Time"
+                ? CustomChartToolTip(value, "var(--color-time)")
+                : null
+            }
packages/ui/package.json (1)

5-13: Remove stale export "./tailwind.config" from packages/ui/package.json

The package exports "./tailwind.config": "./tailwind.config.ts", but there is no tailwind.config.ts file in the repo and no imports of @repo/ui/tailwind.config were found — remove the broken subpath export.

  • packages/ui/package.json — remove the "./tailwind.config" export entry
  "exports": {
    "./globals.css": "./src/globals.css",
    "./postcss.config": "./postcss.config.mjs",
-    "./tailwind.config": "./tailwind.config.ts",
    "./lib/*": "./src/lib/*.ts",
    "./components/*": "./src/components/*.tsx",
    "./index": "./src/index.ts",
    "./utils/*": "./src/utils/*.ts"
  },
apps/vscode-extension/src/utils/auth/parseJwtPayload.ts (1)

3-12: Fix Zod type + JWT base64url parsing in parseJwtPayload.ts

Zod v4 does not export ZodSafeParseResult — use ReturnType (or z.SafeParseReturnType) and validate/decode JWT payload as base64url.

Files to update:

  • apps/vscode-extension/src/utils/auth/parseJwtPayload.ts

Apply this diff:

-import { JWTDto } from "@repo/common/schemas";
-import { JwtPayloadType } from "@/types-schemas";
-import { ZodSafeParseResult } from "zod";
+import { JWTDto } from "@repo/common/schemas";
+import { JwtPayloadType } from "@/types-schemas";
@@
-const parseJwtPayload = (
-  token: string | undefined,
-):
-  | ZodSafeParseResult<JwtPayloadType>
-  | {
-      success: false;
-      error: unknown;
-    } => {
+const parseJwtPayload = (
+  token: string | undefined,
+): | ReturnType<typeof JWTDto.safeParse> | { success: false; error: unknown } => {
   try {
-    if (!token || typeof token !== "string" || !token.includes(".")) {
-      return { success: false, error: new Error("Invalid token format") };
-    }
-    const base64Payload = token.split(".")[1];
-    const decodedPayload = Buffer.from(base64Payload, "base64").toString(
-      "utf8",
-    );
-    const jsonPayload = JSON.parse(decodedPayload);
-
-    return JWTDto.safeParse(jsonPayload);
+    if (!token || typeof token !== "string") {
+      return { success: false, error: new Error("Invalid token format") };
+    }
+    const parts = token.split(".");
+    if (parts.length !== 3) {
+      return { success: false, error: new Error("Invalid token format") };
+    }
+    // JWT payloads use base64url (RFC 7515) — convert to standard base64
+    const base64UrlPayload = parts[1];
+    const base64Payload = base64UrlPayload.replace(/-/g, "+").replace(/_/g, "/");
+    const padded = base64Payload.padEnd(Math.ceil(base64Payload.length / 4) * 4, "=");
+    const decodedPayload = Buffer.from(padded, "base64").toString("utf8");
+    const jsonPayload = JSON.parse(decodedPayload);
+    return JWTDto.safeParse(jsonPayload);
   } catch (error) {
     return { success: false, error };
   }
 };
apps/dashboard/src/components/project-page/charts/CircularPacking.tsx (1)

16-20: Guard against SSR: avoid direct window access in initial state

Accessing window in useState initializers will throw during server-side rendering. Use lazy initializers with typeof window guards and perform the initial measurement inside useEffect.

Files/locations to fix:

  • apps/dashboard/src/components/project-page/charts/CircularPacking.tsx — lines 16-20
  • Also apply the same pattern to any other useState that reads window (e.g. lines 35-41)

Suggested change:

-  const [width, setWidth] = useState(
-    parentDivRef.current?.clientWidth ?? (window.innerWidth * 5) / 6,
-  );
-  const [height, setHeight] = useState((window.innerWidth * 2) / 3);
+  const getDefaultWidth = () =>
+    typeof window === "undefined"
+      ? 0
+      : parentDivRef.current?.clientWidth ?? (window.innerWidth * 5) / 6;
+  const getDefaultHeight = () =>
+    typeof window === "undefined" ? 0 : (window.innerWidth * 2) / 3;
+  const [width, setWidth] = useState(getDefaultWidth);
+  const [height, setHeight] = useState(getDefaultHeight);
@@
-  useEffect(() => {
-    window.addEventListener("resize", handleWindowResize);
-
-    return () => {
-      window.removeEventListener("resize", handleWindowResize);
-    };
-  }, []);
+  useEffect(() => {
+    if (typeof window === "undefined") return;
+    // initial measurement on mount
+    handleWindowResize();
+    window.addEventListener("resize", handleWindowResize);
+    return () => {
+      window.removeEventListener("resize", handleWindowResize);
+    };
+  }, []);
packages/ui/src/components/ui/form.tsx (3)

45-66: Bug: useFormField reads context before asserting presence; fix nullability and guard checks

useFormField accesses fieldContext.name before verifying the provider is present, and FormItemContext is also assumed. This can cause runtime issues when misused. Make both contexts nullable and guard before use.

-const useFormField = () => {
-  const fieldContext = React.useContext(FormFieldContext);
-  const itemContext = React.useContext(FormItemContext);
-  const { getFieldState } = useFormContext();
-  const formState = useFormState({ name: fieldContext.name });
-  const fieldState = getFieldState(fieldContext.name, formState);
-
-  if (!fieldContext) {
-    throw new Error("useFormField should be used within <FormField>");
-  }
-
-  const { id } = itemContext;
+const useFormField = () => {
+  const fieldContext = React.useContext(FormFieldContext);
+  const itemContext = React.useContext(FormItemContext);
+  const { getFieldState } = useFormContext();
+
+  if (!fieldContext?.name) {
+    throw new Error("useFormField should be used within <FormField>");
+  }
+  if (!itemContext?.id) {
+    throw new Error("useFormField should be used within <FormItem>");
+  }
+
+  const formState = useFormState({ name: fieldContext.name });
+  const fieldState = getFieldState(fieldContext.name, formState);
+
+  const { id } = itemContext;
 
   return {
     id,
     name: fieldContext.name,
     formItemId: `${id}-form-item`,
     formDescriptionId: `${id}-form-item-description`,
     formMessageId: `${id}-form-item-message`,
     ...fieldState,
   };
 };

28-31: Make FormFieldContext nullable to force correct guarding

Initialize the context with null instead of a casted empty object to avoid false confidence and ensure proper runtime checks.

-const FormFieldContext = React.createContext<FormFieldContextValue>(
-  {} as FormFieldContextValue,
-);
+const FormFieldContext = React.createContext<FormFieldContextValue | null>(null);

72-74: Make FormItemContext nullable and guard it

Same rationale as FormFieldContext — prevents accidental usage without a provider.

-const FormItemContext = React.createContext<FormItemContextValue>(
-  {} as FormItemContextValue,
-);
+const FormItemContext = React.createContext<FormItemContextValue | null>(null);
apps/dashboard/src/components/dashboard-page/PeriodDropDown.tsx (1)

57-68: Effect misses period in deps; can skip updates when toggling “Custom Range”.

The effect only runs on start/end changes. If a user switches to “Custom Range” after start/end are already set, the effect won’t run, and setCustomRange won’t be called. Include period (and optionally setCustomRange) in deps to avoid stale reads.

Apply this diff:

-  useEffect(() => {
+  useEffect(() => {
     if (period === "Custom Range") {
       if (start && end) {
         const periodResolution = getPeriodResolution(start, end);
         setCustomRange({
           start,
           end,
           periodResolution,
         });
       }
     }
-  }, [start, end]);
+  }, [start, end, period, setCustomRange]);
🧹 Nitpick comments (22)
packages/ui/src/components/ui/tooltip.tsx (1)

8-19: Confirm intent: default delayDuration={0} on Provider

Setting delay to zero makes tooltips show immediately. If this wasn’t intentional, consider restoring a small delay (e.g., 200–400ms) for UX polish.

apps/vscode-extension/package.json (1)

134-134: Pinning date-fns to an exact version: confirm intent.

Locking to 4.1.0 avoids accidental bundle changes for the extension but also prevents patch updates. If reproducibility is the goal, consider keeping it pinned and relying on lockfiles; otherwise, prefer a caret.

If you want to re-allow patch updates:

-    "date-fns": "4.1.0",
+    "date-fns": "^4.1.0",
apps/dashboard/src/components/layout/Layout.tsx (1)

10-10: Confirm CSS token: var(--primary) vs var(--color-primary)

There’s an apparent mix of token schemes across the repo (e.g., var(--color-primary) and var(--primary)). Please confirm which is canonical post-migration and align accordingly to avoid silent theming regressions.

If the canonical token is --color-primary, apply this diff:

-    <ClipLoader size={80} color="var(--primary)" />
+    <ClipLoader size={80} color="var(--color-primary)" />
apps/web/postcss.config.mjs (1)

1-7: PostCSS config diverges from UI package; consider re-export or align options (e.g., base)

The UI package’s PostCSS config passes a base option to @tailwindcss/postcss (see packages/ui/postcss.config.mjs). This local copy omits it, which can cause styling/token resolution to drift between apps and the UI package.

Two options:

  • Re-export UI config to avoid config drift (preferred if no app-specific overrides are needed).
  • Replicate the same options (ensure parity, including base, if required by your setup).

Apply either of the following diffs.

Option A — restore re-export:

-const config = {
-  plugins: {
-    "@tailwindcss/postcss": {},
-  },
-};
-
-export default config;
+export { default } from "@repo/ui/postcss.config";

Option B — replicate UI config (parity):

+import { fileURLToPath } from "node:url";
+import { dirname, join } from "node:path";
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+
 const config = {
   plugins: {
-    "@tailwindcss/postcss": {},
+    "@tailwindcss/postcss": {
+      // keep this in sync with packages/ui/postcss.config.mjs unless the web app
+      // intentionally needs a different base
+      base: join(__dirname, "../../"),
+    },
   },
 };
 
 export default config;
apps/dashboard/src/components/project-page/charts/CircularPacking.tsx (1)

14-15: Ref type should be React.RefObject<HTMLDivElement> (not HTMLDivElement | null)

RefObject<T> already exposes current: T | null. Using RefObject<HTMLDivElement | null> redundantly nests null into the generic, complicating types.

Apply this diff:

-  parentDivRef: React.RefObject<HTMLDivElement | null>;
+  parentDivRef: React.RefObject<HTMLDivElement>;
apps/vscode-extension/src/utils/logger/logger.ts (2)

7-10: Use safer inspect depth and avoid any in logger API

Infinity can be heavy/ambiguous for util.inspect. null means “unlimited” and is the recommended way. Also prefer unknown over any for stronger typing.

-export const logDir = (data: any) => {
+export const logDir = (data: unknown) => {
   console.log(`${LOG_PREFIX} Data:`);
-  console.dir(data, { depth: Infinity });
+  console.dir(data, { depth: null });
 };

3-5: Consider using a VS Code OutputChannel instead of console for better UX and discoverability

Console logs are easy to miss in extensions. OutputChannel provides a dedicated “MoonCode” output pane for users and support diagnostics.

Example approach (alternative to console-based logger):

import * as vscode from "vscode";
// Optionally: import { inspect } from "node:util";

const channel = vscode.window.createOutputChannel("MoonCode");
const LOG_PREFIX = "[MoonCode]";

export const logInfo = (message: string) => {
  channel.appendLine(`${LOG_PREFIX} INFO: ${message}`);
};

export const logDir = (data: unknown) => {
  channel.appendLine(`${LOG_PREFIX} Data:`);
  channel.appendLine(String(data)); // or inspect(data, { depth: null })
};

export const logError = (err: unknown, context?: string) => {
  const base = context ? `${LOG_PREFIX} ERROR: ${context}:` : `${LOG_PREFIX} ERROR:`;
  if (err instanceof Error) {
    channel.appendLine(`${base} ${err.message}`);
    if (err.stack) channel.appendLine(err.stack);
    const cause = (err as any).cause;
    if (cause) channel.appendLine(`${LOG_PREFIX} ERROR: cause -> ${String(cause)}`);
  } else {
    channel.appendLine(`${base} ${String(err)}`);
  }
};

Also applies to: 12-14

apps/vscode-extension/src/utils/dashboard/serveDashboard.ts (1)

31-31: Include protocol and colon in the startup log message

Slight polish that also makes it clickable in many terminals.

-        logInfo(`Dashboard server started on localhost ${availablePort}`);
+        logInfo(`Dashboard server started on http://localhost:${availablePort}`);
apps/vscode-extension/src/utils/periodicSyncData.ts (2)

137-139: Log the actual Error object to preserve stack/cause; avoid manual stringifying of cause

Passing the Error directly (with optional context) yields better diagnostics and avoids “[object Object]” for complex causes. This pairs with the proposed logError signature.

-      logError(
-        `tRPC Error during sync: ${error.message}, Cause: ${error.cause}.`,
-      );
+      logError(error, "tRPC Error during sync");

141-144: Also log unknown errors for diagnostics (while keeping user-facing warning)

This ensures we don’t silently drop useful debugging info in non-TRPC errors.

-      vscode.window.showWarningMessage(
-        `Unknown error during server sync: ${error}.`,
-      );
+      logError(error, "Unknown error during server sync");
+      vscode.window.showWarningMessage(
+        `Unknown error during server sync: ${String(error)}.`,
+      );
apps/vscode-extension/src/utils/time/calculateTime.ts (2)

30-30: Pass the error object to the logger for richer diagnostics

Avoid interpolating the unknown error directly. This leverages the logger to include message/stack/cause and prevents “[object Object]”.

-      logError(`Error in periodic check:${error}`);
+      logError(error, "Error in periodic check");

19-33: Consider throttling repeated error logs in a 1s loop

If a persistent error occurs, this path logs every second. Add a simple throttle/backoff to reduce noise.

I can propose a small helper (e.g., lastLoggedAt and minimum interval) if you want to proceed.

apps/vscode-extension/src/utils/commands/initExtensionCommands.ts (1)

76-76: Nit: keep the “from server” label for clarity.

If the data is indeed the initial snapshot synced from the backend, keeping that context helps during support/debugging.

Apply this minimal tweak:

-      logInfo(`InitialFilesData:\n${formattedData}`);
+      logInfo(`InitialFilesData (server):\n${formattedData}`);
apps/dashboard/vite.config.ts (1)

6-6: Tailwind v4 Vite plugin integration — looks right.

  • @tailwindcss/vite is correctly imported and added to plugins.
  • Remaining Rollup manualChunks keep your large deps split.

Optional: ensure @tailwindcss/vite is marked as a dev dependency in package.json since it’s only used at build time.

Also applies to: 11-11

apps/dashboard/package.json (1)

18-18: Move @tailwindcss/vite to devDependencies.

The Vite Tailwind plugin is a build-time tool and shouldn’t ship with the runtime bundle. Keep it in devDependencies to reduce install footprint.

Proposed change:

   "dependencies": {
     "@fontsource-variable/inter": "^5.1.1",
     "@hookform/resolvers": "^5.0.1",
     "@repo/common": "*",
     "@repo/trpc": "*",
     "@repo/ui": "*",
-    "@tailwindcss/vite": "^4.1.11",
     "@tanstack/react-query": "^5.74.3",
     ...
   },
   "devDependencies": {
+    "@tailwindcss/vite": "^4.1.11",
     "@eslint/js": "^9.17.0",
     ...
     "prettier-plugin-tailwindcss": "^0.6.14",
     "rollup-plugin-visualizer": "^6.0.3",
     "tailwindcss": "^4.1.11",
     ...
   }

Also applies to: 54-54

apps/dashboard/src/index.css (1)

10-19: Consider centralizing breakpoint tokens to avoid drift across apps/packages

I searched the repo for other --breakpoint-* definitions and @theme breakpoint blocks but found no matches, so I cannot confirm a shared source of truth. Prefer a single shared file (e.g., packages/ui/src/globals.css) and keep only app-specific extras locally (like --breakpoint-chart).

Files/actions to verify:

  • apps/dashboard/src/index.css — current breakpoint tokens (lines 10–19)
  • Check packages/ui (e.g., packages/ui/src/globals.css) and other apps/packages for duplicate --breakpoint-* tokens and consolidate if found
  • If no shared file exists, add one and move shared tokens there; leave per-app overrides local
packages/ui/src/components/ui/Icon.tsx (1)

6-23: Optional: consider keeping ref forwarding if consumers attach refs to this button

Less critical than Input, but if toolbars/menus focus this programmatically, dropping ref support might break UX/tests.

Do you want a patch to reintroduce forwardRef while keeping the same API?

apps/web/src/app/globals.css (1)

1-1: Prefer package-level import over deep relative paths

The deep relative path is brittle. If possible, re-export globals.css from the UI package and import it via the package name (or a workspace alias). This improves maintainability and bundler friendliness.

Example:

  • In packages/ui/package.json, add an export: "./globals.css": "./src/globals.css"
  • Then here: @import "@mooncode/ui/globals.css"; (or your actual package name/alias)
packages/ui/src/components/ui/chart.tsx (1)

281-286: Stabilize legend item keys

Using item.value alone can clash. Prefer a composite key or fallback to dataKey.

-          <div
-            key={item.value}
+          <div
+            key={String(item.dataKey ?? item.value)}
apps/dashboard/src/components/project-page/charts/ProjectTimeOnPeriodChart.tsx (3)

55-60: Make the chart type toggle accessible.

Clickable icons without button semantics aren’t keyboard-accessible and lack an accessible name. Wrap in a semantic button (or add role, tabIndex, key handlers, and aria-label).

Apply this diff:

-      <Icon
-        Icon={isBarChartVisible ? AreaChartIcon : BarChartIcon}
-        className="absolute -top-12 right-0 z-0"
-        onClick={handleClick}
-      />
+      <button
+        type="button"
+        aria-label={isBarChartVisible ? "Switch to area chart" : "Switch to bar chart"}
+        className="absolute -top-12 right-0 z-0"
+        onClick={handleClick}
+      >
+        <Icon Icon={isBarChartVisible ? AreaChartIcon : BarChartIcon} />
+      </button>

74-95: Tooltip labelFormatter: guard with a better fallback and avoid brittle payload access.

Accessing payload[0].payload assumes at least one series and a stable ordering. Safer to fall back to _date if originalDate is absent.

Apply this diff:

-              labelFormatter={(
+              labelFormatter={(
                 _date: string,
                 payload: Payload<string, string>[],
               ) => {
                 if (payload.length === 0) return null;

                 const {
                   payload: innerPayload,
                 }: { payload?: (typeof chartData)[number] } = payload[0];

-                if (!innerPayload) return null;
-
-                return <div>{innerPayload.originalDate}</div>;
+                const label = innerPayload?.originalDate ?? _date;
+                return <div>{label}</div>;
               }}
-              formatter={(value, name) =>
-                name === "Time"
-                  ? CustomChartToolTip(parseInt(value), "var(--color-time)")
-                  : null
-              }
+              formatter={(value, name) =>
+                name === "Time"
+                  ? CustomChartToolTip(Number(value), "var(--color-time)")
+                  : null
+              }

66-74: DRY opportunity: extract shared XAxis + tooltip config to a tiny helper.

You already note not extracting ChartTooltip into its own component due to Recharts limitations. Still, you can extract the labelFormatter and formatter functions into constants within the component scope to avoid duplication between branches, improving maintainability.

If desirable, I can propose a concise refactor that keeps everything within this module and avoids the component-extraction pitfall.

Also applies to: 113-121

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 65443b5 and 194c186.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (55)
  • .npmrc (0 hunks)
  • apps/api/package.json (1 hunks)
  • apps/dashboard/package.json (3 hunks)
  • apps/dashboard/postcss.config.mjs (0 hunks)
  • apps/dashboard/src/components/CustomChartToolTip.tsx (1 hunks)
  • apps/dashboard/src/components/dashboard-page/PeriodDropDown.tsx (2 hunks)
  • apps/dashboard/src/components/dashboard-page/charts/GeneralStatsChart.tsx (2 hunks)
  • apps/dashboard/src/components/dashboard-page/charts/PeriodTimeChart.tsx (3 hunks)
  • apps/dashboard/src/components/dashboard-page/charts/dayLanguagesChart/DayLanguagesChart.tsx (1 hunks)
  • apps/dashboard/src/components/layout/Layout.tsx (1 hunks)
  • apps/dashboard/src/components/project-page/Project.tsx (3 hunks)
  • apps/dashboard/src/components/project-page/charts/CircularPacking.tsx (2 hunks)
  • apps/dashboard/src/components/project-page/charts/ProjectLanguagesTimeOnPeriodChart.tsx (2 hunks)
  • apps/dashboard/src/components/project-page/charts/ProjectTimeOnPeriodChart.tsx (2 hunks)
  • apps/dashboard/src/constants.ts (1 hunks)
  • apps/dashboard/src/index.css (1 hunks)
  • apps/dashboard/tailwind.config.ts (0 hunks)
  • apps/dashboard/vite.config.ts (1 hunks)
  • apps/vscode-extension/README.md (1 hunks)
  • apps/vscode-extension/package.json (2 hunks)
  • apps/vscode-extension/src/extension.ts (2 hunks)
  • apps/vscode-extension/src/types-schemas.ts (1 hunks)
  • apps/vscode-extension/src/utils/auth/parseJwtPayload.ts (1 hunks)
  • apps/vscode-extension/src/utils/commands/initExtensionCommands.ts (5 hunks)
  • apps/vscode-extension/src/utils/dashboard/serveDashboard.ts (2 hunks)
  • apps/vscode-extension/src/utils/logger/logger.ts (1 hunks)
  • apps/vscode-extension/src/utils/periodicSyncData.ts (2 hunks)
  • apps/vscode-extension/src/utils/time/calculateTime.ts (2 hunks)
  • apps/web/package.json (1 hunks)
  • apps/web/postcss.config.mjs (1 hunks)
  • apps/web/src/app/globals.css (1 hunks)
  • apps/web/tailwind.config.ts (0 hunks)
  • packages/common/package.json (1 hunks)
  • packages/common/src/types.ts (1 hunks)
  • packages/ui/.prettierrc (1 hunks)
  • packages/ui/components.json (1 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/postcss.config.mjs (1 hunks)
  • packages/ui/src/components/ui/CalendarPopover.tsx (1 hunks)
  • packages/ui/src/components/ui/Icon.tsx (1 hunks)
  • packages/ui/src/components/ui/button-variants.ts (0 hunks)
  • packages/ui/src/components/ui/button.tsx (1 hunks)
  • packages/ui/src/components/ui/calendar.tsx (1 hunks)
  • packages/ui/src/components/ui/card.tsx (1 hunks)
  • packages/ui/src/components/ui/chart.tsx (3 hunks)
  • packages/ui/src/components/ui/checkbox.tsx (2 hunks)
  • packages/ui/src/components/ui/dropdown-menu.tsx (1 hunks)
  • packages/ui/src/components/ui/form.tsx (3 hunks)
  • packages/ui/src/components/ui/input.tsx (1 hunks)
  • packages/ui/src/components/ui/label.tsx (1 hunks)
  • packages/ui/src/components/ui/popover.tsx (1 hunks)
  • packages/ui/src/components/ui/tooltip.tsx (1 hunks)
  • packages/ui/src/globals.css (2 hunks)
  • packages/ui/src/index.ts (0 hunks)
  • packages/ui/tailwind.config.ts (0 hunks)
💤 Files with no reviewable changes (7)
  • packages/ui/src/components/ui/button-variants.ts
  • apps/dashboard/postcss.config.mjs
  • .npmrc
  • apps/dashboard/tailwind.config.ts
  • packages/ui/src/index.ts
  • apps/web/tailwind.config.ts
  • packages/ui/tailwind.config.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-06T20:22:58.925Z
Learnt from: Friedrich482
PR: Friedrich482/mooncode#85
File: apps/api/src/filters/errorFormatter.ts:1-1
Timestamp: 2025-08-06T20:22:58.925Z
Learning: In Zod v4, the $ZodIssue types are officially available at the import path "zod/v4/core/errors.cjs" as part of the new module structure. This is the correct way to import these types in v4, not an internal or fragile import path.

Applied to files:

  • apps/vscode-extension/src/types-schemas.ts
  • packages/common/src/types.ts
📚 Learning: 2025-08-06T23:16:51.944Z
Learnt from: Friedrich482
PR: Friedrich482/mooncode#86
File: apps/api/src/common/dto.ts:13-16
Timestamp: 2025-08-06T23:16:51.944Z
Learning: In Zod v4, using shape spreading syntax (e.g., `z.object({...BaseSchema.shape, newField: z.string()})`) is recommended over the `.extend()` method for optimizing TypeScript compiler performance. This represents a change in best practices from earlier Zod versions.

Applied to files:

  • apps/vscode-extension/src/types-schemas.ts
🧬 Code Graph Analysis (20)
apps/vscode-extension/src/utils/dashboard/serveDashboard.ts (1)
apps/vscode-extension/src/utils/logger/logger.ts (1)
  • logInfo (3-5)
apps/vscode-extension/src/extension.ts (1)
apps/vscode-extension/src/utils/logger/logger.ts (1)
  • logInfo (3-5)
apps/vscode-extension/src/utils/periodicSyncData.ts (1)
apps/vscode-extension/src/utils/logger/logger.ts (1)
  • logError (12-14)
apps/web/postcss.config.mjs (1)
packages/ui/postcss.config.mjs (1)
  • config (3-9)
apps/vscode-extension/src/utils/time/calculateTime.ts (1)
apps/vscode-extension/src/utils/logger/logger.ts (1)
  • logError (12-14)
packages/ui/postcss.config.mjs (1)
apps/web/postcss.config.mjs (1)
  • config (1-5)
packages/ui/src/components/ui/input.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
apps/vscode-extension/src/utils/commands/initExtensionCommands.ts (1)
apps/vscode-extension/src/utils/logger/logger.ts (2)
  • logInfo (3-5)
  • logDir (7-10)
apps/vscode-extension/src/utils/auth/parseJwtPayload.ts (1)
apps/vscode-extension/src/types-schemas.ts (1)
  • JwtPayloadType (49-49)
packages/ui/src/components/ui/Icon.tsx (2)
packages/ui/src/components/ui/button.tsx (1)
  • Button (58-58)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
apps/dashboard/src/components/dashboard-page/PeriodDropDown.tsx (1)
packages/ui/src/components/ui/button.tsx (1)
  • Button (58-58)
packages/ui/src/components/ui/popover.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
packages/ui/src/components/ui/label.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
packages/ui/src/components/ui/card.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
packages/ui/src/components/ui/button.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
packages/ui/src/components/ui/tooltip.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
packages/ui/src/components/ui/form.tsx (2)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
packages/ui/src/components/ui/label.tsx (1)
  • Label (24-24)
packages/ui/src/components/ui/calendar.tsx (2)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
packages/ui/src/components/ui/button.tsx (1)
  • buttonVariants (58-58)
packages/ui/src/components/ui/chart.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
packages/ui/src/components/ui/dropdown-menu.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
🔇 Additional comments (60)
packages/ui/src/components/ui/checkbox.tsx (1)

4-4: LGTM on import placement and usage.

Importing the Radix checkbox primitive directly and keeping it adjacent to React is fine. No issues here.

packages/ui/src/components/ui/dropdown-menu.tsx (4)

154-160: Minor: consistent className blocks (no functional issue)

All good. Keeping label styling consistent with the new slot approach looks solid.


169-173: Separator looks good

The slot and styling are straightforward and consistent with Tailwind v4.


184-187: Shortcut styling LGTM

Good use of ml-auto and tracking-widest for accelerator text.


7-11: API change: wrappers don’t forward refs—verify downstream usage

These wrappers don’t use React.forwardRef, which is a change from common patterns in UI libs. Consumers won’t be able to pass refs to e.g., DropdownMenuTrigger, Content, Item, etc. Radix itself doesn’t require you to forward refs for functionality, but some apps do for focus management, measurements, or effect dependencies.

  • Confirm no downstream code relies on refs to these components.
  • If needed, I can generate a follow-up patch to add forwardRef consistently.

Example pattern for DropdownMenuItem:

const DropdownMenuItem = React.forwardRef<
  React.ElementRef<typeof DropdownMenuPrimitive.Item>,
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
    inset?: boolean;
    variant?: "default" | "destructive";
  }
>(function DropdownMenuItem(
  { className, inset, variant = "default", ...props },
  ref
) {
  return (
    <DropdownMenuPrimitive.Item
      ref={ref}
      data-slot="dropdown-menu-item"
      data-inset={inset}
      data-variant={variant}
      className={cn(/* ... */)}
      {...props}
    />
  );
});

Would you like me to apply this pattern across Trigger, Content, Item, CheckboxItem, RadioItem, SubTrigger, Label, Separator, Shortcut, and SubContent?

Also applies to: 21-30, 32-50, 52-58, 60-81, 83-107, 109-118, 120-142, 144-162, 164-175, 177-191, 193-198, 199-221, 223-237, 239-255

packages/ui/src/components/ui/calendar.tsx (6)

1-2: Good: client directive is appropriate here

Using "use client" is necessary for an interactive component in Next.js.


3-8: Good: icon imports align with v9 Chevron orientations

Using lucide-react’s Chevron*Icon variants is appropriate and keeps the bundle minimal.


17-23: Good: switch to inline named const export

This keeps types intact and avoids hoisting surprises.


26-26: Padding increased to p-6 — verify layout parity

The larger padding can affect small viewports and popover positioning. Please sanity-check CalendarPopover and any constrained containers for overflow or clipping.


12-13: Action: confirm bundler/consumer resolution for #lib/utils.ts (or remove the .ts extension)

Finding: every UI component imports "#lib/utils.ts" and none import "#lib/utils" (no extension).

Files referencing "#lib/utils.ts":

  • packages/ui/src/components/ui/checkbox.tsx:7
  • packages/ui/src/components/ui/dropdown-menu.tsx:5
  • packages/ui/src/components/ui/popover.tsx:6
  • packages/ui/src/components/ui/label.tsx:6
  • packages/ui/src/components/ui/tooltip.tsx:6
  • packages/ui/src/components/ui/input.tsx:3
  • packages/ui/src/components/ui/card.tsx:3
  • packages/ui/src/components/ui/calendar.tsx:12
  • packages/ui/src/components/ui/button.tsx:5
  • packages/ui/src/components/ui/Icon.tsx:4
  • packages/ui/src/components/ui/chart.tsx:5
  • packages/ui/src/components/ui/form.tsx:16
  • packages/ui/src/components/ui/skeleton.tsx:1

Example (calendar.tsx):
import { cn } from "#lib/utils.ts";

Recommendation (pick one):

  • Standardize imports to "#lib/utils" (no extension), or
  • Ensure your tsconfig paths and bundler configs (Vite/Next/tsup, etc.) resolve the #lib/utils.ts alias for consumers and published builds.

Please verify consumer/bundle builds (or update imports/config) to avoid cross-bundler resolution issues.


27-61: Confirm classNames keys match react-day-picker v9 API — confirmed

The keys used in packages/ui/src/components/ui/calendar.tsx (lines 27–61) match react-day-picker v9’s supported structure and modifier classNames (months, month, month_caption, caption_label, button_previous, button_next, month_grid, weekdays, weekday, week, day, day_button, selected, today, outside, disabled, hidden, range_start, range_end, range_middle). No changes required.

  • packages/ui/src/components/ui/calendar.tsx — lines 27–61: OK
packages/ui/src/components/ui/tooltip.tsx (1)

31-35: LGTM: Thin wrapper for Trigger

Wrapper looks good and keeps asChild opt-in available for consumers.

packages/ui/src/components/ui/popover.tsx (3)

8-12: LGTM: Root wrapper

Simple wrapper with data-slot is fine and keeps the public surface minimal.


14-18: LGTM: Trigger wrapper

Straightforward wrapper; asChild remains available to consumers via props.


42-46: LGTM: Anchor wrapper

Consistent slot naming and minimal wrapper — good.

apps/web/package.json (1)

29-29: Tailwind v4 upgrade: looks good.

This aligns with the repo-wide migration to Tailwind v4. Assuming the PostCSS plugin has been wired via @tailwindcss/postcss in this app (as done elsewhere), this is good to go.

packages/common/src/types.ts (2)

2-2: Switch to named import from zod is correct.

This matches Zod v4’s recommended import style and keeps types consistent.


2-2: Confirm repo-wide removal of default zod imports — fix required

rg found one remaining default import; convert it to the named import to avoid mixed import styles and potential type duplication.

  • packages/common/src/schemas.ts:1 — replace:
    • Old: import z from "zod";
    • New: import { z } from "zod";
⛔ Skipped due to learnings
Learnt from: Friedrich482
PR: Friedrich482/mooncode#85
File: apps/api/src/filters/errorFormatter.ts:1-1
Timestamp: 2025-08-06T20:22:58.925Z
Learning: In Zod v4, the $ZodIssue types are officially available at the import path "zod/v4/core/errors.cjs" as part of the new module structure. This is the correct way to import these types in v4, not an internal or fragile import path.
Learnt from: Friedrich482
PR: Friedrich482/mooncode#86
File: apps/api/src/common/dto.ts:13-16
Timestamp: 2025-08-06T23:16:51.944Z
Learning: In Zod v4, using shape spreading syntax (e.g., `z.object({...BaseSchema.shape, newField: z.string()})`) is recommended over the `.extend()` method for optimizing TypeScript compiler performance. This represents a change in best practices from earlier Zod versions.
apps/vscode-extension/package.json (2)

5-5: Extension version bump to 0.0.22 approved.

Changelog alignment looks consistent with the rest of the PR.


138-138: No action needed — extension already uses named z import

Scanned apps/vscode-extension for default imports, namespace imports, and require() usages of zod. Only named imports were found:

  • apps/vscode-extension/src/types-schemas.ts — line 2: import { z } from "zod";
  • apps/vscode-extension/src/utils/auth/storeJWTToken.ts — line 2: import { z } from "zod";

No import z from "zod", import * as ... from "zod", or require("zod") usages detected.

apps/vscode-extension/src/types-schemas.ts (2)

2-2: Named import from zod is correct.

Matches Zod v4 usage across the repo.


17-22: Replace non-standard z.iso usages — fix required

z.iso is not a standard Zod API and there is no module augmentation in the repo — the current z.iso.datetime() calls will throw at runtime. Replace them with the existing IsoDateSchema from @repo/common/schemas.

Locations to fix:

  • apps/vscode-extension/src/types-schemas.ts — fields: lastServerSync, updatedAt

Suggested changes (concise diff):

- import { IsoDateStringSchema, JWTDto } from "@repo/common/schemas";
+ import { IsoDateStringSchema, IsoDateSchema, JWTDto } from "@repo/common/schemas";

- lastServerSync: z.union([
-   z.date(),
-   z.iso.datetime().transform((str) => new Date(str)),
- ]),
+ lastServerSync: z.union([z.date(), IsoDateSchema]),

... 

- updatedAt: z.union([
-   z.date(),
-   z.iso.datetime().transform((str) => new Date(str)),
- ]),
+ updatedAt: z.union([z.date(), IsoDateSchema]),

[fiz_required]

packages/common/package.json (1)

41-41: Zod bumped to ^4.0.17: approved.

Matches the import changes and keeps versions consistent across packages.

apps/api/package.json (1)

42-42: Zod upgrade to ^4.0.17 — declared versions are consistent

All package.json files that reference zod declare "^4.0.17":

  • apps/api/package.json — dependencies: ^4.0.17
  • apps/dashboard/package.json — dependencies: ^4.0.17
  • apps/vscode-extension/package.json — dependencies: ^4.0.17
  • packages/common/package.json — dependencies: ^4.0.17
packages/ui/components.json (2)

7-7: Empty Tailwind config path may break shadcn/ui tooling

Setting "tailwind.config" to an empty string could cause the shadcn/ui CLI to not find a Tailwind config, depending on the CLI version. With Tailwind v4’s config-optional approach this might be intentional, but please confirm the CLI supports it to avoid generation errors.

If not supported, point "config" to the root Tailwind config (if any) or adjust to the CLI’s recommended v4 setup.


10-10: Enabling cssVariables is aligned with your v4 token strategy

This aligns with the broader move to CSS tokens and is consistent with your globals/tokens work.

apps/dashboard/src/components/CustomChartToolTip.tsx (1)

31-31: Class reordering is a no-op; looks good

Reordering Tailwind classes doesn’t change output. No issues here.

apps/dashboard/src/components/dashboard-page/charts/dayLanguagesChart/DayLanguagesChart.tsx (1)

85-94: Good fix: tooltip now receives a numeric value (no parseInt).

Aligns with Recharts’ numeric payloads and removes unnecessary coercion. Keep this pattern consistent across all charts.

apps/dashboard/src/components/project-page/charts/ProjectLanguagesTimeOnPeriodChart.tsx (1)

58-74: LGTM: PieChart tooltip now treats value as number.

Directly passing numeric value to CustomChartToolTip removes unnecessary parsing and potential NaN pitfalls.

apps/dashboard/src/constants.ts (1)

74-75: Confirmed — --primary resolves to a concrete color (oklch(...))

packages/ui/src/globals.css defines --primary as oklch(...) (lines 16–17 and 69–70) and exposes --color-primary: var(--primary) (lines 120–121). apps/dashboard currently uses var(--primary) (apps/dashboard/src/constants.ts:74 and apps/dashboard/src/components/layout/Layout.tsx:10).

  • No breakage expected from switching from hsl(var(--primary)) → var(--primary) because --primary is already a full color value (oklch(...)).
  • Optional: use var(--color-primary) if you prefer the public alias.

Snippet (apps/dashboard/src/constants.ts:74-75):

    color: "var(--primary)",
  },
apps/dashboard/src/components/dashboard-page/charts/PeriodTimeChart.tsx (2)

38-38: No-op class reordering.

Class reordering is fine; no behavioral impact.


83-84: LGTM: stroke now uses direct CSS var.

Using var(--destructive) aligns with the token strategy elsewhere in the PR.

apps/dashboard/src/components/dashboard-page/charts/GeneralStatsChart.tsx (4)

60-60: Container class reordering is fine.

No functional change; layout remains consistent.


66-66: Typography class reorder is harmless.

No change in semantics; leaving as-is is fine.


86-86: Typography class reorder is fine.

No behavior change.


98-99: Typography class reorder is fine.

No impact to rendering.

packages/ui/.prettierrc (1)

1-3: LGTM; aligns with Tailwind v4 formatting workflow

Configuration is correct. With the move of prettier-plugin-tailwindcss to devDependencies in package.json (see related comment), this will be cleanly scoped to development.

apps/dashboard/src/components/project-page/charts/CircularPacking.tsx (1)

85-86: LGTM: tokenized color usage (var(--muted-foreground))

Switching from hsl(var(--...)) to direct var(--...) matches the new token strategy in Tailwind v4/theming and aligns with other changes in this PR.

Also applies to: 92-93

apps/vscode-extension/src/extension.ts (1)

52-52: LGTM: centralized logger used for deactivation

Adopts the new logger consistently. No concerns.

apps/vscode-extension/src/utils/commands/initExtensionCommands.ts (2)

2-2: Good move: centralize logging via the new logger.

Importing and using logInfo/logDir improves consistency and makes logs identifiable. Path looks correct relative to this file.


34-34: Consistent log formatting for debug commands — LGTM.

Replacing console.log with logInfo keeps the output uniform and prefixed. Message content remains clear.

Also applies to: 52-52, 63-63

packages/ui/src/components/ui/CalendarPopover.tsx (1)

3-3: Approve: type-only import for DateRange is correct — no remaining consumers found

rg output shows only one occurrence importing the type directly from react-day-picker and no imports from @repo/ui.

  • packages/ui/src/components/ui/CalendarPopover.tsx — line 3
import { type DateRange } from "react-day-picker";
apps/dashboard/package.json (1)

27-29: React 19 / types / Tailwind upgrades — quick verification

  • I inspected apps/dashboard:

    • apps/dashboard/package.json: react/react-dom = 19.1.1, @types/react = 19.1.9, @types/react-dom = 19.1.7, react-error-boundary ^5, zustand ^5, react-router ^7.
    • apps/dashboard/vite.config.ts imports @vitejs/plugin-react-swc and the plugin is listed in devDependencies.
    • apps/dashboard/src/main.tsx uses createRoot(...).render(...) (modern root API).
    • Repo scan found no ReactDOM.render / ReactDOM.hydrate / UNSAFE_* / legacy lifecycle usages.
  • Recommendation: I could not run installs/builds in the sandbox — please run a local smoke install + build + dev to catch peer-dependency warnings or subtle type mismatches. From the repo root, e.g.:
    npm install && npm --workspace=apps/dashboard run build && npm --workspace=apps/dashboard run dev

packages/ui/src/components/ui/label.tsx (2)

15-17: Label uses peer-disabled variants; ensure inputs are peers with the peer class

The label relies on peer-disabled:… which won’t activate unless the associated input has the peer class. Confirm that your Input component sets className to include peer by default.

If not already present, update Input to include peer (see suggestion in input.tsx review).


6-6: #lib alias is resolved via package.json imports — verified

The repo uses the package-import map rather than a tsconfig.paths entry; TypeScript's NodeNext resolution is enabled so the imports resolve.

  • Evidence:
    • packages/ui/package.json — "imports": { "#": "./src/" }
    • packages/ui/src/lib/utils.ts — target file exists
    • packages/ui/src/components/ui/label.tsx (and other UI components) import using: import { cn } from "#lib/utils.ts";
    • packages/typescript-config/base.json — "moduleResolution": "NodeNext" (packages/ui/tsconfig.json extends the react-library.json which inherits this)
  • Action: no change required for correctness. If you need compatibility with older tooling/IDEs that don't honor package.json "imports", add a matching "paths" mapping (e.g. "#": ["src/"]) to packages/ui/tsconfig.json.
packages/ui/src/components/ui/card.tsx (2)

18-29: @container usage in class string — verify Tailwind v4 syntax compatibility

The token @container/card-header in a className string is unconventional but may be intended as a container-name utility in Tailwind v4. Validate that this compiles as expected in your current Tailwind config and Vite plugin, and that it produces the desired container behavior at runtime.

If needed, I can help translate this into explicit container-name CSS or Tailwind’s container utilities for clarity.


84-92: Addition of CardAction slot looks good

The new slot provides a clear, semantic hook for action placement and aligns with the data-slot styling pattern across the UI.

packages/ui/src/components/ui/button.tsx (1)

7-35: Inline variants via cva look good

Consolidating buttonVariants locally with cva is clear and keeps the API surface in one place. Defaults and variant/size options read well.

packages/ui/src/globals.css (1)

188-191: Scrollbar thumb token alignment looks good

Switching to background: var(--border) aligns with your new token system and avoids HSL mismatch. Nice consistency cleanup.

packages/ui/src/components/ui/chart.tsx (1)

165-239: Tooltip content logic reads well; good accessibility touches

Good handling of ARIA attributes via FormControl elsewhere, and the tooltip label logic (labelFormatter/hideLabel/indicator) looks robust. The variable-color indicator via CSS variables is clean and Tailwind v4-friendly.

apps/dashboard/src/components/dashboard-page/PeriodDropDown.tsx (2)

13-13: Directly importing DateRange from react-day-picker v9 looks good.

This aligns with the migration away from re-exporting DateRange from the UI package and avoids type drift.


75-78: Confirm Button ref-forwarding (not found) — ChartTooltip formatters OK

Brief: The provided search output shows no evidence that Button forwards refs in packages/ui/src/components/ui/button.tsx; ChartTooltipContent in packages/ui/src/components/ui/chart.tsx does use labelFormatter/formatter (confirmed).

Please verify / act:

  • packages/ui/src/components/ui/button.tsx — no forwardRef / exported Button found in the search output. Confirm Button forwards refs (React.forwardRef) or locate the actual Button implementation.
  • apps/dashboard/src/components/dashboard-page/PeriodDropDown.tsx — currently uses as child of DropdownMenuTrigger asChild; if Button doesn't forward refs, replace with a native or make Button forward refs.
  • packages/ui/src/components/ui/chart.tsx — labelFormatter and formatter usage confirmed (labelFormatter around lines ~140–145; formatter usage around ~185–186).

Suggested fixes (pick one):

  • Wrap/implement Button with React.forwardRef and forward to the underlying element, or
  • Change DropdownMenuTrigger child to a primitive in PeriodDropDown.
apps/dashboard/src/components/project-page/Project.tsx (4)

31-34: Class re-order is benign.

No behavioral change; error fallback remains clear and accessible.


61-64: LGTM on layout wrapper re-ordering.

Purely presentational; no functional impact.


66-74: LGTM on text classes reorder.

No semantic changes; layout remains consistent.


98-99: LGTM on ErrorFallBack class reorder.

No effect on behavior; keeps style token usage consistent.

apps/dashboard/src/components/project-page/charts/ProjectTimeOnPeriodChart.tsx (4)

1-5: Imports and icon aliasing look correct.

Brings in AreaChart to support the new toggle; lucide aliases read cleanly.


96-111: Confirm tooltip intent: only Bar is named "Time" — should the Line be included in the tooltip?

I couldn't find other ChartTooltip formatters or named series elsewhere in the repo, so I can't verify intent automatically.

  • File to check: apps/dashboard/src/components/project-page/charts/ProjectTimeOnPeriodChart.tsx (around lines 96–111)
  • Current: Bar has name="Time"; Line has no name.
  • If you want both series shown with the same tooltip formatting, add name to the Line (or give a distinct name and handle it in your tooltip formatter). If the Line is just an overlay, no change needed.

Suggested minimal change:

<Line
  dataKey="timeSpentLine"
  name="Time"            <-- add this if you want it in the tooltip
  stroke="var(--destructive)"
  ...
/>

Please confirm desired tooltip behavior.


66-111: Confirmed — backend emits timeSpentBar / timeSpentLine / timeSpentArea and originalDate for getProjectPerDayOfPeriod.

The front-end keys used in ProjectTimeOnPeriodChart are already produced by the server mappers, so no client change is required.

Files verified:

  • apps/api/src/files-stats/utils/getProjectPerDayOfPeriodGroupByMonths.ts — returns timeSpentLine, timeSpentBar, timeSpentArea and originalDate (lines ~39–42).
  • apps/api/src/files-stats/utils/getProjectPerDayOfPeriodGroupByWeeks.ts — returns timeSpentLine, timeSpentBar, timeSpentArea and originalDate (lines ~78–81).
  • apps/api/src/files-stats/files-stats-dashboard.service.ts — getProjectPerDayOfPeriod maps dailyProjectsForPeriod -> timeSpentLine/timeSpentBar/timeSpentArea and originalDate (lines ~95–102, ~196–199).
  • apps/dashboard/src/components/project-page/charts/ProjectTimeOnPeriodChart.tsx — uses dataKey="timeSpentBar"/"timeSpentLine" (and area variant uses "timeSpentArea") and reads innerPayload.originalDate in the tooltip (lines referenced in PR).

Optional note: if other endpoints emit only a single numeric field (timeSpent) and you want less duplication, consider standardizing on one key and adapting client-side usage accordingly.


143-153: Area props OK — no change required

Confirmed: apps/dashboard/package.json lists "recharts": "^2.15.1" and Recharts v2.x supports both dot and activeDot on . The Area usage in apps/dashboard/src/components/project-page/charts/ProjectTimeOnPeriodChart.tsx (lines 143–153) — including dot={{ r: 4 }} — is valid.

  • Checked package: apps/dashboard/package.json -> "recharts": "^2.15.1"
  • Checked chart file: apps/dashboard/src/components/project-page/charts/ProjectTimeOnPeriodChart.tsx (lines 143–153)

- added an animated night sky with full moon (moonCode logo) svg to the auth pages (login && register)
- installed the `vite-plugin-svgr` to render svgs directly in the DOM
- grouped the login and register page components under an auth route group
@Friedrich482 Friedrich482 changed the title refactor: logger, chore: extension bump, chore: extension bump, feat: react-day-picker, chore: migration, fix: calendar, fix: ProjectTimeOnPeriod , chore: checkbox, chore: zod and chore: web refactor: logger, chore: extension bump, chore: extension bump, feat: react-day-picker, chore: migration, fix: calendar, fix: ProjectTimeOnPeriod , chore: checkbox, chore: zod,chore: web and feat:auth Aug 16, 2025
@Friedrich482 Friedrich482 changed the title refactor: logger, chore: extension bump, chore: extension bump, feat: react-day-picker, chore: migration, fix: calendar, fix: ProjectTimeOnPeriod , chore: checkbox, chore: zod,chore: web and feat:auth refactor: logger, chore: extension bump, chore: extension bump, feat: react-day-picker, chore: migration, fix: calendar, fix: ProjectTimeOnPeriod , chore: checkbox, chore: zod,chore: web and feat: auth Aug 16, 2025
- inferred the badge version from the vscode marketplace instead of manual bumps
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (15)
apps/dashboard/src/components/layout/header/Logo.tsx (2)

4-8: Consider explicit width/height to eliminate potential CLS.

Since size-8 maps to 2rem, adding width/height attributes (32px) will reserve space and avoid layout shift without changing visuals.

   <img
     src="/moon.svg"
-    className={cn("size-8", className)}
+    className={cn("size-8", className)}
+    width={32}
+    height={32}
     alt="MoonCode Logo"
   />

3-9: Optionally expose standard props for broader reuse.

If you foresee needing to override alt, add titles, aria labels, etc., consider typing against ImgHTMLAttributes and forwarding the rest of the props. Keeps src fixed while increasing reusability.

-import { cn } from "@repo/ui/lib/utils";
+import { cn } from "@repo/ui/lib/utils";
+import type { ImgHTMLAttributes } from "react";
 
-const Logo = ({ className }: { className?: string }) => (
+type Props = Omit<ImgHTMLAttributes<HTMLImageElement>, "src">;
+const Logo = ({ className, alt = "MoonCode Logo", ...props }: Props) => (
   <img
     src="/moon.svg"
-    className={cn("size-8", className)}
-    alt="MoonCode Logo"
+    className={cn("size-8", className)}
+    alt={alt}
+    {...props}
   />
 );
apps/dashboard/package.json (1)

54-54: Remove unused PostCSS & Autoprefixer from apps/dashboard

I verified that in apps/dashboard:

  • No postcss.config.* file exists.
  • Vite is wired up with @tailwindcss/vite in apps/dashboard/vite.config.ts.
  • package.json still lists both "postcss": "^8.5.1" and "autoprefixer": "^10.4.20" under devDependencies.

Since the Tailwind v4 Vite plugin handles all PostCSS transforms out of the box, you can drop these two entries to clean up your toolchain.

Suggested diff:

--- a/apps/dashboard/package.json
+++ b/apps/dashboard/package.json
@@ -45,8 +45,6 @@
     "tailwindcss": "^4.1.11",
     "typescript": "^5.2.2",
-    "postcss": "^8.5.1",
     "vite": "^4.4.9",
-    "autoprefixer": "^10.4.20",
   },

After removal, run a quick local build to confirm nothing breaks. [optional_refactors_recommended]

apps/dashboard/src/components/auth/register-page/RegisterForm.tsx (6)

57-59: Guard missing VITE_REGISTER_URL early

If the env var is unset, fetchJWTToken will likely fail with a less actionable error. Fail fast with a clear message.

       const REGISTER_URL = import.meta.env.VITE_REGISTER_URL;
+      if (!REGISTER_URL) {
+        throw new Error("Missing VITE_REGISTER_URL");
+      }

70-76: Avoid post-redirect work by returning early

After setting window.location.href, the app navigates away. Add a return to prevent unnecessary query invalidation and navigate("/dashboard"). This is handled in the previous diff by returning inside the redirect branch.


78-78: Use the new prefixed logger instead of console.error

This PR refactors raw console usage. Replace console.error(error) with the new logger for consistency and discoverability.

Please confirm the intended logger import path (e.g., a shared logger in @repo/common or a local util), and I can provide a concrete patch.


115-120: Improve email field semantics and autofill

Set proper type and autocomplete to help validation and browser autofill.

-                    <Input
+                    <Input
+                      type="email"
+                      autoComplete="email"
                       placeholder="example@email.com"
                       {...field}
                       className="border-border h-10"
                     />

151-157: Improve password field autofill for registration

For sign-up, prefer autoComplete="new-password".

-                        <Input
+                        <Input
                           placeholder="**********"
                           {...field}
                           type={isPasswordVisible ? "text" : "password"}
+                          autoComplete="new-password"
                           className="border-border h-10 flex-nowrap"
                         />

29-36: Deduplicate root-class toggling via a small hook

Both auth forms add/remove #root.auth-root. Consider extracting a useAuthRootClass() hook to centralize this behavior.

I can generate a tiny shared hook under @/hooks/useAuthRootClass and wire it in both forms if you want.

apps/dashboard/src/components/auth/login-page/LoginForm.tsx (6)

58-60: Guard missing VITE_LOGIN_URL early

Fail fast when the login endpoint env var is absent.

       const LOGIN_URL = import.meta.env.VITE_LOGIN_URL;
+      if (!LOGIN_URL) {
+        throw new Error("Missing VITE_LOGIN_URL");
+      }

115-119: Improve email field semantics and autofill

Add type="email" and autoComplete="email".

-                    <Input
+                    <Input
+                      type="email"
+                      autoComplete="email"
                       placeholder="example@email.com"
                       {...field}
                       className="border-border h-10"
                     />

133-137: Improve password field autofill for login

Use autoComplete="current-password".

-                      <Input
+                      <Input
                         placeholder="**********"
                         {...field}
                         type={isPasswordVisible ? "text" : "password"}
+                        autoComplete="current-password"
                         className="border-border h-10 flex-nowrap"
                       />

146-147: Fix typography: remove extra space before question mark

Minor copy nit.

-              Not registered yet ?{" "}
+              Not registered yet?{" "}

16-16: Use the same alias-based import for Logo as in RegisterForm

For consistency and resilience to file moves, prefer the @ alias here too.

-import Logo from "../../layout/header/Logo";
+import Logo from "@/components/layout/header/Logo";

29-36: Deduplicate root-class toggling via a small hook

Same suggestion as RegisterForm: extract a useAuthRootClass() hook for adding/removing auth-root.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 194c186 and a8be08e.

⛔ Files ignored due to path filters (2)
  • apps/dashboard/public/animated-night.svg is excluded by !**/*.svg
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • apps/dashboard/package.json (3 hunks)
  • apps/dashboard/src/components/auth/login-page/LoginForm.tsx (1 hunks)
  • apps/dashboard/src/components/auth/register-page/RegisterForm.tsx (1 hunks)
  • apps/dashboard/src/components/layout/header/Logo.tsx (1 hunks)
  • apps/dashboard/src/components/login-page/LoginForm.tsx (0 hunks)
  • apps/dashboard/src/components/register-page/RegisterForm.tsx (0 hunks)
  • apps/dashboard/src/index.css (1 hunks)
  • apps/dashboard/src/main.tsx (1 hunks)
  • apps/dashboard/src/vite-env.d.ts (1 hunks)
  • apps/dashboard/vite.config.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • apps/dashboard/src/components/login-page/LoginForm.tsx
  • apps/dashboard/src/components/register-page/RegisterForm.tsx
✅ Files skipped from review due to trivial changes (1)
  • apps/dashboard/src/vite-env.d.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/dashboard/vite.config.ts
  • apps/dashboard/src/index.css
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/dashboard/src/components/auth/login-page/LoginForm.tsx (3)
packages/common/src/types.ts (1)
  • SignInUserDtoType (10-10)
packages/common/src/schemas.ts (1)
  • SignInUserDto (9-13)
packages/common/src/constants.ts (2)
  • INCORRECT_PASSWORD_MESSAGE (4-4)
  • USER_NOT_FOUND_MESSAGE (3-3)
apps/dashboard/src/components/layout/header/Logo.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
🔇 Additional comments (9)
apps/dashboard/src/components/layout/header/Logo.tsx (2)

3-9: Nice prop-ification and className merging with cn.

Allowing an optional className and merging via cn with Tailwind’s twMerge improves flexibility while keeping sane defaults. This is aligned with your broader UI refactors.


5-5: Asset path validated – no custom base path detected

  • The asset moon.svg is located at apps/dashboard/public/moon.svg.
  • No base setting was found in any vite.config.*, nor basePath in next.config.*.
  • With default config (serving at the domain root), src="/moon.svg" will resolve correctly.

If you later deploy under a sub-directory, remember to update the base/basePath option or switch to an asset import (e.g. using import.meta.env.BASE_URL) to ensure the path remains accurate.

apps/dashboard/package.json (4)

41-42: React 19 type definitions aligned.

@types/react and @types/react-dom are correctly bumped to 19.x, matching react/react-dom. LGTM.


52-52: Prettier Tailwind plugin bump: looks good.

Matches Tailwind v4 adoption. Ensure .prettierrc includes the plugin where needed.


58-59: Plugins properly configured in vite.config.ts
Verified that both vite-plugin-commonjs and vite-plugin-svgr are:

  • Imported in apps/dashboard/vite.config.ts (lines 2 and 6)
  • Included in the plugins array (tailwindcss(), react(), commonjs(), svgr(), visualizer())

No further changes needed.


34-34: Replace default Zod import in packages/common/src/schemas.ts

A default import of Zod was detected, which is incompatible with Zod v4’s named-only export model. Please update it as follows:

• packages/common/src/schemas.ts:1

- import z from "zod";
+ import { z } from "zod";

No other default or mixed imports of Zod were found.

⛔ Skipped due to learnings
Learnt from: Friedrich482
PR: Friedrich482/mooncode#85
File: apps/api/src/filters/errorFormatter.ts:1-1
Timestamp: 2025-08-06T20:22:58.925Z
Learning: In Zod v4, the $ZodIssue types are officially available at the import path "zod/v4/core/errors.cjs" as part of the new module structure. This is the correct way to import these types in v4, not an internal or fragile import path.
Learnt from: Friedrich482
PR: Friedrich482/mooncode#86
File: apps/api/src/common/dto.ts:13-16
Timestamp: 2025-08-06T23:16:51.944Z
Learning: In Zod v4, using shape spreading syntax (e.g., `z.object({...BaseSchema.shape, newField: z.string()})`) is recommended over the `.extend()` method for optimizing TypeScript compiler performance. This represents a change in best practices from earlier Zod versions.
apps/dashboard/src/main.tsx (3)

6-6: LGTM: Auth form import path relocation

Importing LoginForm from the new auth/ path looks correct and matches the file move.


11-11: LGTM: Register form import path relocation

Importing RegisterForm from the new auth/ path looks correct and matches the file move.


1-1: Imports from “react-router” are correct for v7
The dashboard app only depends on react-router@^7.5.1 (no react-router-dom) and, as of v7, the package now includes DOM APIs (RouterProvider, createBrowserRouter, hooks, etc.). No changes needed here.

- moved the `animated-night.svg` in the assets folder for the dashboard
- updated the paths in the login and register forms
- bumped react and react-dom to `v19.1.1` in the web app
- removed useless path base in the `postcss.config.mjs` in the `@repo/ui` package
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (3)
apps/web/package.json (1)

17-18: Good alignment: apps/web upgraded to React 19

React and ReactDOM now match the rest of the repo and Next 15.4.1 requirements. This addresses the earlier concern about apps/web being on React 18.

apps/dashboard/src/components/auth/login-page/LoginForm.tsx (2)

148-152: Encode the callback in the Sign Up link

The raw callbackUrl can contain characters that break the URL. Encode it.

-                to={`/register${callbackUrl ? `?callback=${callbackUrl}` : ""}`}
+                to={`/register${callbackUrl ? `?callback=${encodeURIComponent(callbackUrl)}` : ""}`}

66-69: Stop leaking JWT via query string; build redirect safely and return after redirect

Appending &token=... breaks for URLs without a query and exposes the JWT (and email) to servers/logs and referers. Use the URL API, put the token in the hash (fragment) instead of the query, and return immediately after redirect.

-      if (callbackUrl) {
-        window.location.href = `${callbackUrl}&token=${token}&email=${encodeURIComponent(values.email)}`;
-      }
+      if (callbackUrl) {
+        try {
+          const url = new URL(callbackUrl, window.location.origin);
+          // Keep email only if needed by the destination; otherwise omit or also move to the hash.
+          url.searchParams.set("email", values.email);
+          // Avoid server/referrer exposure by keeping the JWT in the fragment.
+          url.hash = `token=${encodeURIComponent(token)}`;
+          window.location.href = url.toString();
+          return;
+        } catch {
+          form.setError("root", { message: "Invalid callback URL" });
+          return;
+        }
+      }
🧹 Nitpick comments (5)
apps/dashboard/src/components/auth/login-page/LoginForm.tsx (5)

53-54: Gate the callback URL with an allowlist to prevent open redirects/exfiltration

Before honoring a user-supplied callback, validate its origin against a known allowlist (or constrain to same-origin). This avoids redirecting tokens/PII to attacker-controlled domains.

If helpful, I can add an ALLOWED_CALLBACK_ORIGINS constant and wire the check into the redirect code.


58-63: Guard against missing LOGIN_URL to avoid runtime failures

Fail fast with a user-facing error if VITE_LOGIN_URL is not configured.

-      const LOGIN_URL = import.meta.env.VITE_LOGIN_URL;
+      const LOGIN_URL = import.meta.env.VITE_LOGIN_URL;
+      if (!LOGIN_URL) {
+        form.setError("root", { message: "Login URL is not configured" });
+        return;
+      }

114-118: Add autocomplete for better UX and accessibility on email

Let the browser assist users with the email field.

-                    <Input
-                      placeholder="example@email.com"
-                      {...field}
-                      className="border-border h-10"
-                    />
+                    <Input
+                      placeholder="example@email.com"
+                      autoComplete="email"
+                      {...field}
+                      className="border-border h-10"
+                    />

133-137: Add autocomplete on password field

Small UX win and consistent with best practices.

-                      <Input
-                        placeholder="**********"
-                        {...field}
-                        type={isPasswordVisible ? "text" : "password"}
-                        className="border-border h-10 flex-nowrap"
-                      />
+                      <Input
+                        placeholder="**********"
+                        autoComplete="current-password"
+                        {...field}
+                        type={isPasswordVisible ? "text" : "password"}
+                        className="border-border h-10 flex-nowrap"
+                      />

146-147: Minor copy fix: remove extra space before the question mark

Polish the UI text.

-            <p>
-              Not registered yet ?{" "}
+            <p>
+              Not registered yet?{" "}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a8be08e and 43668c7.

⛔ Files ignored due to path filters (2)
  • apps/dashboard/src/assets/animated-night.svg is excluded by !**/*.svg
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • apps/dashboard/src/components/auth/login-page/LoginForm.tsx (1 hunks)
  • apps/dashboard/src/components/auth/register-page/RegisterForm.tsx (1 hunks)
  • apps/vscode-extension/README.md (1 hunks)
  • apps/web/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/vscode-extension/README.md
  • apps/dashboard/src/components/auth/register-page/RegisterForm.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/dashboard/src/components/auth/login-page/LoginForm.tsx (3)
packages/common/src/types.ts (1)
  • SignInUserDtoType (10-10)
packages/common/src/schemas.ts (1)
  • SignInUserDto (9-13)
packages/common/src/constants.ts (2)
  • INCORRECT_PASSWORD_MESSAGE (4-4)
  • USER_NOT_FOUND_MESSAGE (3-3)

- updated the versions of react and react-dom in the web app
- moved `@tailwindcss/vite` in the devDependencies in the dashboard
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
apps/web/package.json (2)

23-24: Remove @types/react and @types/react-dom — React 19 ships its own types

With React 19, the types are bundled and these @types are unnecessary and can cause TS conflicts. Safe to remove both.

Apply this diff to drop them:

   "devDependencies": {
     "@eslint/eslintrc": "^3",
     "@types/node": "^20",
-    "@types/react": "19.1.9",
-    "@types/react-dom": "19.1.7",
     "autoprefixer": "^10.4.21",
     "eslint": "^9.21.0",
     "eslint-config-next": "15.4.1",
     "postcss": "^8.4.31",
     "tailwindcss": "^4.1.11",
     "typescript": "^5"
   }

29-29: Add @tailwindcss/postcss to devDependencies (or remove Tailwind here)

Your PostCSS config for this app uses the Tailwind v4 PostCSS plugin. Ensure @tailwindcss/postcss is listed in devDependencies, or remove Tailwind from this app if it only imports CSS from @repo/ui.

Run this to verify plugin usage and decide the action:

#!/bin/bash
set -euo pipefail

echo "== PostCSS config presence"
if [[ -f apps/web/postcss.config.mjs ]]; then
  sed -n '1,120p' apps/web/postcss.config.mjs
else
  echo "apps/web/postcss.config.mjs not found"
fi

echo
echo "== Check for @tailwindcss/postcss reference"
rg -nP '@tailwindcss/postcss' apps/web/postcss.config.mjs || true

echo
echo "== Check Tailwind directives in apps/web sources"
rg -nP '@tailwind\s' apps/web || true

echo
echo "== Is @tailwindcss/postcss listed in devDependencies?"
jq -r '.devDependencies["@tailwindcss/postcss"] // "NOT_FOUND"' apps/web/package.json

Decision:

  • If the plugin is referenced, add @tailwindcss/postcss to devDependencies (version aligned with your root/workspace).
  • If no Tailwind directives are present and CSS is sourced from @repo/ui, consider removing "tailwindcss" from devDependencies and dropping the plugin from postcss.config.mjs for this app.
apps/dashboard/package.json (1)

26-27: Prefer caret ranges for React 19 and re-verify monorepo alignment

Exact pins can impede receiving patch updates. Unless you intentionally pin, prefer caret ranges. Also, confirm all packages in the monorepo use React 19 to avoid multiple React trees.

Apply this diff:

-    "react": "19.1.1",
-    "react-dom": "19.1.1",
+    "react": "^19.1.1",
+    "react-dom": "^19.1.1",

Run this script to surface any stragglers still on React 18:

#!/bin/bash
set -euo pipefail

echo "== React versions across all package.json =="
fd -t f package.json | while read -r file; do
  react=$(jq -r '.dependencies.react // .peerDependencies.react // empty' "$file")
  reactdom=$(jq -r '.dependencies["react-dom"] // .peerDependencies["react-dom"] // empty' "$file")
  if [[ -n "${react}" || -n "${reactdom}" ]]; then
    echo "File: $file"
    echo "  react:     ${react:-"(none)"}"
    echo "  react-dom: ${reactdom:-"(none)"}"
    echo
  fi
done | sed -n '1p;/\^?18\./,/^$/p' || true
🧹 Nitpick comments (1)
apps/dashboard/package.json (1)

41-42: Use caret ranges for @types to ease patch updates

Unless you have a reason to pin exactly, caret ranges reduce churn while staying within the same major.

Apply this diff:

-    "@types/react": "19.1.9",
-    "@types/react-dom": "19.1.7",
+    "@types/react": "^19.1.9",
+    "@types/react-dom": "^19.1.7",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1cb0d10 and c86966e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • apps/dashboard/package.json (2 hunks)
  • apps/web/package.json (1 hunks)
🔇 Additional comments (5)
apps/web/package.json (1)

17-18: React 19 bump looks good and matches Next 15.x expectations

Pinning react and react-dom to 19.1.1 is consistent with the migration and should align with Next 15.4.1.

apps/dashboard/package.json (4)

33-33: Zod upgrade aligns with repo-wide move to v4.0.17 — LGTM


37-37: Good: @tailwindcss/vite correctly scoped to devDependencies


52-54: Tailwind v4 + prettier-plugin-tailwindcss bump looks consistent with the migration


58-59: Build-time Vite plugins (commonjs, svgr) correctly live in devDependencies

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants