Skip to content

Conversation

@hamo-o
Copy link
Contributor

@hamo-o hamo-o commented Mar 3, 2025

#️⃣ 연관된 이슈>

📝 작업 내용> 이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

  • 겹치는 일정을 모두 노출할 수 있도록 처리합니다.
    image
  • 이미 생성된 일정 카드 위로 드래그 했을 때도 정상적으로 드래그가 이루어지도록 합니다. (이벤트 버블링)
  • 겹치는 일정을 계산하는 로직을 비즈니스 로직과 분리하고 테스트합니다.
  • CI 스크립트를 추가하여, 모든 테스트에 통과해야 PR을 머지할 수 있습니다.

🙏 여기는 꼭 봐주세요! > 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Enhanced calendar event card rendering with improved handling of multi-day and overlapping events.
    • Event cards dynamically adjust size and position based on duration and overlap.
    • Calendar card list disables pointer interactions during time selection.
    • Added continuous integration workflow for frontend codebase.
    • Introduced utilities for generating mock calendar events for testing.
    • Exposed time selection state to improve calendar interactivity.
  • Refactor

    • Reorganized event grouping and rendering logic for clearer, more maintainable calendar views.
    • Updated calendar to reflect current time selection state for improved interactivity.
  • Style

    • Added styles to enable or disable pointer events on calendar card list based on selection state.
  • Tests

    • Added unit tests for calendar card list rendering and event grouping utilities.
    • Introduced browser testing configuration and enhanced test setup.
  • Chores

    • Updated dependencies to include latest testing libraries and added React as dev dependencies.
    • Added path alias for feature modules to simplify imports.
    • Improved TypeScript configurations to support test files and global types.

@hamo-o hamo-o added the 🖥️ FE Frontend label Mar 3, 2025
@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2025

"""

Walkthrough

This update refactors the calendar event card rendering logic in the weekly calendar feature. It introduces a new DefaultCard component, modularizes event grouping and overlap handling, adds a CSS-in-JS recipe for pointer event control, and propagates selection state through the relevant hooks and components.

Changes

File(s) Change Summary
.../ui/CalendarCardList/DefaultCard.tsx Adds new exported DefaultCard React component for rendering individual calendar event cards with positioning logic.
.../ui/CalendarCardList/index.css.ts Introduces cardListStyle CSS-in-JS recipe to toggle pointer events for the card list.
.../ui/CalendarCardList/index.tsx Refactors CalendarCardList to modularize event grouping, overlap handling, and rendering; updates prop signature.
.../ui/MyCalendar/CalendarTable.tsx Passes new isSelecting prop from selection state to CalendarCardList.
.../ui/SchedulePopover/index.tsx Reformats import statements for utility functions; no logic changes.
.../core/src/hooks/useSelectTime.ts Adds isSelecting boolean to TimeInfo and exposes it in useSelectTime hook return value.
.github/workflows/fe-ci.yml Adds new GitHub Actions workflow for frontend continuous integration on PRs targeting dev branch.
.../tests/mocks/events.ts Adds utility function createCards to generate mock personal calendar events for testing.
.../tests/unit/my-calendar/card.tsx Adds unit tests for CalendarCardList component verifying rendering and child count.
.../package.json Removes explicit react and react-dom dependencies from frontend client package.json.
.../setup-file.ts Adds test setup file importing @testing-library/jest-dom for enhanced Jest DOM matchers.
.../tsconfig.app.json Extends TypeScript config to include Playwright types and test directory.
.../vite.config.ts Adds new path alias @features pointing to src/features directory.
.../vitest.config.ts Updates Vitest config to include test file pattern and setup file; extends module aliasing.
.../configs/vitest-config/src/browser.ts Adds new Vitest browser testing config with Playwright Chromium setup.
.../configs/vitest-config/src/index.ts Re-exports browser testing config.
.../configs/vitest-config/src/node.ts Removes include property from node Vitest config to broaden test discovery.
.../configs/vitest-config/src/react.ts Adds React and vanilla-extract plugins to Vitest React config; removes include property.
frontend/package.json Updates devDependencies: bumps testing libs, adds Playwright, adds React as dev deps.
.../date-time/tests/group.test.ts Adds unit tests for groupByOverlap and groupByDate grouping functions.
.../date-time/tests/mocks/index.ts Adds mock data sets for testing date grouping and overlap logic.
.../date-time/tests/sort.test.ts Adds unit tests for sortDates comparator function.
.../date-time/src/constants/regex.ts Updates DATETIME regex to allow optional fractional seconds and trailing 'Z'.
.../date-time/src/date.ts Extends EndolphinDate constructor overloads; adds date part extraction, valueOf, toString, and primitive coercion.
.../date-time/src/group.ts Adds types and functions for grouping date ranges by overlap and by date.
.../date-time/src/index.ts Re-exports group and sort modules along with existing exports.
.../date-time/src/sort.ts Adds sortDates comparator function for sorting date ranges.
.../date-time/src/type.ts Adds new DateRange interface with start and end properties of type EndolphinDate.
.../date-time/src/utils/date.ts Expands isAllday function parameter types to accept `string
.../date-time/tsconfig.json Adds "vitest/globals" types and includes __tests__ directory in compilation scope.
.../date-time/vitest.config.ts Restricts Vitest test discovery to __tests__/*.test.ts files.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CalendarTable
  participant useSelectTime
  participant CalendarCardList
  participant DefaultCard

  User->>CalendarTable: Interacts with calendar (e.g., selects time)
  CalendarTable->>useSelectTime: Gets { isSelecting, ... }
  CalendarTable->>CalendarCardList: Passes cards, isSelecting
  CalendarCardList->>DefaultCard: Renders cards with overlap/grouping info
  DefaultCard-->>CalendarCardList: Renders positioned card or null
Loading

Possibly related PRs

Suggested reviewers

  • dioo1461

Poem

In the garden of dates, where events overlap,
A DefaultCard hops in, closing the gap.
With styles that toggle and logic anew,
Cards line up neatly, in columns of two.
Now, with selection, the calendar’s bright—
Hopping through time, from morning to night! 🗓️🐇
"""

✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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.

@hamo-o hamo-o force-pushed the feature/fe/calendar-overlap branch from 1f25c51 to 5b05f8d Compare June 9, 2025 10:08
@hamo-o hamo-o marked this pull request as ready for review June 9, 2025 10:12
@hamo-o hamo-o requested a review from dioo1461 as a code owner June 9, 2025 10:12
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: 3

🧹 Nitpick comments (3)
frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/DefaultCard.tsx (1)

18-22: Extract constants outside the component to avoid recreation on each render.

These constants are recreated on every render. Move them outside the component for better performance.

+const LEFT_MARGIN = 24;
+const RIGHT_MARGIN = 8;
+const SIDEBAR_WIDTH = 72;
+const TOP_GAP = 16;
+const DAYS = 7;
+
 export const DefaultCard = (
   { card, start, end, idx }: 
   { card: PersonalEventResponse; start: Date; end: Date; idx: number },
 ) => {
-  const LEFT_MARGIN = 24;
-  const RIGHT_MARGIN = 8;
-  const SIDEBAR_WIDTH = 72;
-  const TOP_GAP = 16;
-  const DAYS = 7;
frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.tsx (2)

10-22: Remove redundant Date object creation in sortCards.

The start and end properties are already Date objects according to the CardItem type, so creating new Date objects is unnecessary.

 const sortCards = (e1: CardItem, e2: CardItem) => {
-  const start1 = new Date(e1.start);
-  const end1 = new Date(e1.end);
-  const start2 = new Date(e2.start);
-  const end2 = new Date(e2.end);
+  const { start: start1, end: end1 } = e1;
+  const { start: start2, end: end2 } = e2;

   if (start1 < start2) return -1;
   if (start1 > start2) return 1;
   if (end1 < end2) return -1;
   if (end1 > end2) return 1;

   return 0;
 };

70-71: Use a more descriptive variable name instead of underscore.

The underscore suggests the day key is unused, but it could be useful for debugging or future features. Consider using a descriptive name.

-    {groupByDate(cards).map(([_, dayCards]) =>
+    {groupByDate(cards).map(([dayKey, dayCards]) =>
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 262599f and 5b05f8de6fa66f9c97a764c6401be92cd6e908a2.

📒 Files selected for processing (6)
  • frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/DefaultCard.tsx (1 hunks)
  • frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.css.ts (1 hunks)
  • frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.tsx (1 hunks)
  • frontend/apps/client/src/features/my-calendar/ui/MyCalendar/CalendarTable.tsx (1 hunks)
  • frontend/apps/client/src/features/my-calendar/ui/SchedulePopover/index.tsx (1 hunks)
  • frontend/packages/core/src/hooks/useSelectTime.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
frontend/apps/client/src/features/my-calendar/ui/MyCalendar/CalendarTable.tsx (1)
frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.tsx (1)
  • CalendarCardList (65-84)
frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/DefaultCard.tsx (1)
frontend/apps/client/src/features/my-calendar/model/index.ts (1)
  • PersonalEventResponse (21-21)
🪛 Biome (1.9.4)
frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.tsx

[error] 58-58: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

🔇 Additional comments (5)
frontend/apps/client/src/features/my-calendar/ui/SchedulePopover/index.tsx (1)

1-5: LGTM: Import formatting improvement.

The multi-line import format enhances readability and is a good practice for managing multiple imports.

frontend/packages/core/src/hooks/useSelectTime.ts (2)

90-90: LGTM: Well-designed interface extension.

Adding the isSelecting property to the TimeInfo interface is backward compatible and provides useful state information to consumers.


109-109: LGTM: Correct state exposure.

The isSelecting state is properly exposed from the internal reducer state, enabling downstream components to react to selection status.

frontend/apps/client/src/features/my-calendar/ui/MyCalendar/CalendarTable.tsx (1)

38-38: LGTM: Proper state propagation.

The isSelecting prop is correctly passed from the useSelectTime hook to CalendarCardList, enabling the card list to respond to selection state changes.

frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/DefaultCard.tsx (1)

38-44: ⚠️ Potential issue

Fix double subtraction of overlap margin in width calculation.

The overlap margin (idx * LEFT_MARGIN) is being subtracted twice - once in the width calculation and once in marginLeft. This will make overlapping cards progressively narrower than intended.

Either remove it from the width calculation or from marginLeft:

         width: `calc(
-          (100% - ${SIDEBAR_WIDTH}px) / ${DAYS} - ${RIGHT_MARGIN}px - ${idx * LEFT_MARGIN}px)`,
+          (100% - ${SIDEBAR_WIDTH}px) / ${DAYS} - ${RIGHT_MARGIN}px)`,
         height,
         position: 'absolute',
         left: `calc(((100% - ${SIDEBAR_WIDTH}px) / ${DAYS} * ${sx}) + ${SIDEBAR_WIDTH}px)`,
         marginLeft: idx * LEFT_MARGIN,

Likely an incorrect or invalid review comment.

hamo-o added 23 commits June 12, 2025 15:39
@hamo-o hamo-o force-pushed the feature/fe/calendar-overlap branch from 5b05f8d to 0cd3d83 Compare June 12, 2025 06:39
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: 14

🔭 Outside diff range comments (2)
frontend/packages/date-time/vitest.config.ts (1)

1-1: ⚠️ Potential issue

Missing dependency breaks CI – @endolphin/vitest-config cannot be resolved.

The pipeline failure shows the import at line 1 is unresolved. Add the package (or a workspace alias) to frontend/package.json under devDependencies, or inline the minimal config to remove the external dependency.

-import { createAlias, nodeConfig } from '@endolphin/vitest-config';
+// TODO: remove once @endolphin/vitest-config is published
+import { nodeConfig } from 'vitest/config';
+const createAlias = (dir: string) => ({ '@/': `${dir}/src` });
🧰 Tools
🪛 GitHub Actions: fe-ci

[error] 1-1: Failed to resolve entry for package "@endolphin/vitest-config". The package may have incorrect main/module/exports specified in its package.json. Error triggered by import at line 1: 'import { createAlias, nodeConfig } from '@endolphin/vitest-config';'.

frontend/packages/date-time/src/date.ts (1)

23-31: 🛠️ Refactor suggestion

Typo and inconsistent null handling in #formateToDate

  1. The method name is misspelled (formate).
  2. Returning null forces downstream callers to guard against null, yet many methods directly pass this.#date to util functions without checks, risking TypeError.
-#formateToDate (input: InputDate): Date | null {
+#formatToDate (input: InputDate): Date {
   if (!input) throw new Error('빈 값입니다.');
   ...
 }
🧹 Nitpick comments (8)
frontend/packages/date-time/tsconfig.json (1)

18-18: include should use globs to prevent accidental transpilation

"__tests__" will pull every file in that folder (fixtures, mocks, compiled artifacts, etc.).
Consider narrowing it:

-  "include": ["src", "__tests__"],
+  "include": ["src", "__tests__/**/*.ts", "__tests__/**/*.tsx"],

This keeps build / type-check time down and avoids shipping stray files in the published package.

frontend/configs/vitest-config/src/react.ts (1)

6-11: Missing include pattern may slow down Vitest in monorepo

Removing include makes Vitest crawl the entire workspace, which can explode start-up time.
If you meant to inherit a root pattern, at least restrict to the package:

-  test: {
+  test: {
     globals: true,
     environment: 'jsdom',
     passWithNoTests: true,
+    include: ['src/**/*.{test,spec}.{ts,tsx}'],
   },
.github/workflows/fe-ci.yml (1)

39-43: Masking secret output – use set-output rather than echo to file.

echo "${{ secrets.FE_ENV }}" > .env writes the secret to disk before build steps execute. While GitHub masks secrets in logs, the plaintext file lives for the remainder of the workflow and can be leaked by accidental cat .env or artefact upload. Prefer passing env vars explicitly:

- name: Build Frontend
  run: pnpm build
  env:
    $(grep -o '^[A-Z_]*=' <<<"${{ secrets.FE_ENV }}")

or, if a file is unavoidable, create it in $RUNNER_TEMP and delete it right after use.

frontend/packages/date-time/vitest.config.ts (1)

13-15: Hard-coded include pattern omits nested test folders.

['__tests__/*.test.ts'] ignores any deeper structure (__tests__/utils/foo.test.ts). Safer pattern:

-include: ['__tests__/*.test.ts'],
+include: ['**/__tests__/**/*.test.{ts,tsx}'],
frontend/apps/client/__tests__/unit/my-calendar/card.tsx (1)

27-29: Child count assertion may break with grouping logic
CalendarCardList flattens nested arrays, but further refactors (e.g., wrapping each day in its own <div>) will invalidate childElementCount. A safer assertion is to count rendered cards themselves:

expect(container.querySelectorAll('[data-testid="calendar-card"]').length)
  .toBe(cards.length);
frontend/packages/date-time/src/date.ts (1)

68-70: getDate leaks internal mutable state
Returning the raw Date allows external mutation:

const d = new EndolphinDate('2024-01-01').getDate();
d.setFullYear(1900); // mutates internal state

Return a defensive copy instead.

-getDate () {
-  return this.#date;
+getDate () {
+  return this.#date ? new Date(this.#date) : undefined;
}
frontend/packages/date-time/src/group.ts (2)

73-75: Edge-minute truncation – 23:59 drops the last 59 999 ms

Using 23:59 omits the final minute of the start day.
Prefer end-of-day precision (23:59:59.999) or EndolphinDate(...).endOf('day') helper if available.

- new EndolphinDate(sy, sm, sd, 23, 59)
+ new EndolphinDate(sy, sm, sd, 23, 59, 59, 999)

81-81: Returned daily buckets are unordered – can break deterministic layout

Object.values(result) yields buckets in engine-dependent key order.
Sort by weekday index before returning:

-return Object.values(result);
+return Object.keys(result)
+  .map(Number)
+  .sort((a, b) => a - b)
+  .map((k) => result[k]);

Ensures consistent Monday→Sunday ordering across browsers.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5b05f8de6fa66f9c97a764c6401be92cd6e908a2 and 0cd3d83.

⛔ Files ignored due to path filters (1)
  • frontend/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (31)
  • .github/workflows/fe-ci.yml (1 hunks)
  • frontend/apps/client/__tests__/mocks/events.ts (1 hunks)
  • frontend/apps/client/__tests__/unit/my-calendar/card.tsx (1 hunks)
  • frontend/apps/client/package.json (0 hunks)
  • frontend/apps/client/setup-file.ts (1 hunks)
  • frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/DefaultCard.tsx (1 hunks)
  • frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.css.ts (1 hunks)
  • frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.tsx (1 hunks)
  • frontend/apps/client/src/features/my-calendar/ui/MyCalendar/CalendarTable.tsx (1 hunks)
  • frontend/apps/client/src/features/my-calendar/ui/SchedulePopover/index.tsx (1 hunks)
  • frontend/apps/client/tsconfig.app.json (2 hunks)
  • frontend/apps/client/vite.config.ts (1 hunks)
  • frontend/apps/client/vitest.config.ts (1 hunks)
  • frontend/configs/vitest-config/src/browser.ts (1 hunks)
  • frontend/configs/vitest-config/src/index.ts (1 hunks)
  • frontend/configs/vitest-config/src/node.ts (0 hunks)
  • frontend/configs/vitest-config/src/react.ts (1 hunks)
  • frontend/package.json (3 hunks)
  • frontend/packages/core/src/hooks/useSelectTime.ts (2 hunks)
  • frontend/packages/date-time/__tests__/group.test.ts (1 hunks)
  • frontend/packages/date-time/__tests__/mocks/index.ts (1 hunks)
  • frontend/packages/date-time/__tests__/sort.test.ts (1 hunks)
  • frontend/packages/date-time/src/constants/regex.ts (1 hunks)
  • frontend/packages/date-time/src/date.ts (2 hunks)
  • frontend/packages/date-time/src/group.ts (1 hunks)
  • frontend/packages/date-time/src/index.ts (1 hunks)
  • frontend/packages/date-time/src/sort.ts (1 hunks)
  • frontend/packages/date-time/src/type.ts (1 hunks)
  • frontend/packages/date-time/src/utils/date.ts (1 hunks)
  • frontend/packages/date-time/tsconfig.json (1 hunks)
  • frontend/packages/date-time/vitest.config.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • frontend/apps/client/package.json
  • frontend/configs/vitest-config/src/node.ts
✅ Files skipped from review due to trivial changes (8)
  • frontend/apps/client/vite.config.ts
  • frontend/apps/client/setup-file.ts
  • frontend/apps/client/src/features/my-calendar/ui/SchedulePopover/index.tsx
  • frontend/packages/date-time/src/type.ts
  • frontend/configs/vitest-config/src/index.ts
  • frontend/packages/date-time/src/index.ts
  • frontend/apps/client/tests/mocks/events.ts
  • frontend/packages/date-time/tests/mocks/index.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • frontend/apps/client/src/features/my-calendar/ui/MyCalendar/CalendarTable.tsx
  • frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.css.ts
  • frontend/packages/core/src/hooks/useSelectTime.ts
  • frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.tsx
  • frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/DefaultCard.tsx
🧰 Additional context used
🧬 Code Graph Analysis (6)
frontend/configs/vitest-config/src/react.ts (1)
frontend/configs/tsup-config/src/react.ts (1)
  • reactConfig (4-13)
frontend/apps/client/__tests__/unit/my-calendar/card.tsx (2)
frontend/apps/client/__tests__/mocks/events.ts (1)
  • createCards (3-19)
frontend/apps/client/src/features/my-calendar/ui/CalendarCardList/index.tsx (1)
  • CalendarCardList (24-52)
frontend/packages/date-time/src/sort.ts (1)
frontend/packages/date-time/src/type.ts (1)
  • DateRange (13-16)
frontend/packages/date-time/__tests__/sort.test.ts (3)
frontend/packages/date-time/src/type.ts (1)
  • DateRange (13-16)
frontend/packages/date-time/src/date.ts (1)
  • EndolphinDate (7-90)
frontend/packages/date-time/src/sort.ts (1)
  • sortDates (9-16)
frontend/apps/client/vitest.config.ts (1)
frontend/configs/vitest-config/src/createAlias.ts (1)
  • createAlias (8-14)
frontend/packages/date-time/src/date.ts (1)
frontend/packages/date-time/src/type.ts (1)
  • InputDate (3-3)
🪛 GitHub Actions: fe-ci
frontend/packages/date-time/vitest.config.ts

[error] 1-1: Failed to resolve entry for package "@endolphin/vitest-config". The package may have incorrect main/module/exports specified in its package.json. Error triggered by import at line 1: 'import { createAlias, nodeConfig } from '@endolphin/vitest-config';'.

🪛 Biome (1.9.4)
frontend/packages/date-time/src/group.ts

[error] 43-43: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

🔇 Additional comments (6)
frontend/packages/date-time/tsconfig.json (1)

16-17: Adding only vitest/globals may drop default type defs

When you specify "types": [...], TypeScript stops including the default DOM / Node types that come from @types/*.
If this package still needs e.g. DOM globals (quite common in a date-time lib that runs in browsers) you should append rather than replace:

-    "types": ["vitest/globals"],
+    "types": ["vitest/globals", "node", "dom"],

Otherwise you’ll run into “cannot find name ‘Window’/’NodeJS’” errors in consumer code.

frontend/configs/vitest-config/src/react.ts (1)

1-2: vanillaExtractPlugin before @vitejs/plugin-react is safer

@vanilla-extract relies on CSS outputs generated after JSX transforms. The recommended order is react() first, vanillaExtractPlugin() second (what you have in the browser config).
Swap them here for consistency:

-  plugins: [react(), vanillaExtractPlugin()],
+  plugins: [react(), vanillaExtractPlugin()],

(If intentional, ignore.)

frontend/apps/client/tsconfig.app.json (1)

5-5: Playwright typings path might be wrong.

The published types live under @vitest/browser, not under @vitest/browser/providers/playwright. If the path is incorrect the IDE will silently fall back to any. Double-check and adjust:

-"types": ["vitest/globals", "@vitest/browser/providers/playwright"],
+"types": ["vitest/globals", "@vitest/browser"],
frontend/packages/date-time/src/sort.ts (1)

9-15: Comparator assumes EndolphinDate is a plain Date.

If EndolphinDate is a wrapper (e.g., Day.js, Luxon) the < / > operators yield unreliable results. Convert to epoch milliseconds or use the library’s valueOf()/toMillis().

-if (d1.start < d2.start) return -1;
+if (+d1.start < +d2.start) return -1;

Same for the other comparisons.

frontend/package.json (1)

62-63:

Details

❌ Incorrect review comment

React 19 is still in alpha – adopting it project-wide is risky
"react": "^19.0.0" and "react-dom": "^19.0.0" point to pre-release versions. Unless you have already audited all breaking changes and verified compatibility of every dependency, stick to the latest stable 18.x.

-"react": "^19.0.0",
-"react-dom": "^19.0.0"
+"react": "^18.3.0",
+"react-dom": "^18.3.0"

🌐 Web query:

What is the latest stable version of React, and is React 19.0.0 released as a stable version or marked as an alpha/prerelease?

💡 Result:

As of June 12, 2025, the latest stable version of React is 19.0.0, released on December 5, 2024. (versionlog.com) React 19.0.0 is the official stable release and is not marked as an alpha or prerelease.

Citations:


React 19.0.0 Is a Stable Release
React 19.0.0 and React-DOM 19.0.0 were officially released as stable on December 5, 2024, not as an alpha or prerelease. You can safely upgrade project-wide—there’s no need to revert to 18.x.

No changes required in frontend/package.json.

Likely an incorrect or invalid review comment.

frontend/packages/date-time/src/group.ts (1)

37-38: Date comparison relies on implicit coercion – verify EndolphinDate implements valueOf

lastGroup[lastGroup.length - 1].end <= current.start works only if EndolphinDate overrides valueOf/toMillis.
If it doesn’t, the comparison devolves to object reference checks and grouping fails silently.

Guard against it by comparing epoch values:

lastGroup[lastGroup.length - 1].end.getTime() <= current.start.getTime()

or expose an explicit valueOf() in EndolphinDate.

Copy link
Contributor

@dioo1461 dioo1461 left a comment

Choose a reason for hiding this comment

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

테스트 모두 정상적으로 실행되는 것 확인했습니다! 지금 저도 캘린더 권한추가가 안돼서 브라우저 상에서 확인은 못했네요..ㅜ 고생 많으셨습니다!!

* @returns - 겹치는 날짜 범위를 그룹화하여 반환
*/
export const groupByOverlap = <T extends DateRangeWithId>(dateInfos: T[]): OverlapDate<T>[] => {
const groups = [] as (T & { idx: number })[][];
Copy link
Contributor

Choose a reason for hiding this comment

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

p3;
T & { idx: number }OverlapDate<T> 로 치환할 수 있을 것 같습니다!

Copy link
Contributor Author

@hamo-o hamo-o Jun 13, 2025

Choose a reason for hiding this comment

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

615811f
수정했습니다

@hamo-o
Copy link
Contributor Author

hamo-o commented Jun 13, 2025

테스트 모두 정상적으로 실행되는 것 확인했습니다! 지금 저도 캘린더 권한추가가 안돼서 브라우저 상에서 확인은 못했네요..ㅜ 고생 많으셨습니다!!

구글 캘린더와 연동 토글을 비활성화하면 확인 가능합니다!! 시간되실때 봐주세요 ㅎㅎ 우선 리뷰 반영하겠습니다~

@hamo-o hamo-o merged commit 8732589 into dev Jun 13, 2025
1 of 2 checks passed
@hamo-o hamo-o deleted the feature/fe/calendar-overlap branch June 13, 2025 00:57
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

🧹 Nitpick comments (2)
frontend/packages/date-time/__tests__/utils/index.ts (2)

4-15: Extract a tiny helper to remove duplication & tighten typing

The three comparators all repeat the same “bar-string” date comparison. A dedicated helper improves readability and centralises the conversion logic:

+import type { EndolphinDate } from '@/type';
+
+const isSameBarDate = (a: EndolphinDate, b: EndolphinDate): boolean =>
+  a.formatDateToBarString() === b.formatDateToBarString();
-return as.formatDateToBarString() === bs.formatDateToBarString() 
-    && ae.formatDateToBarString() === be.formatDateToBarString();
+return isSameBarDate(as, bs) && isSameBarDate(ae, be);

Applying the same replacement in the other two comparator bodies removes repeated strings and future-proofs the tests if the date-formatting method ever changes.


17-36: Order-sensitive comparison may mask logical equality

deepCompareGroups assumes both inputs are pre-sorted identically; otherwise equal sets in a different order will be reported as different.
Given the TODO comment already hints at order-agnostic comparison, consider either:

  1. Sorting each inner array by id before comparison, or
  2. Converting to a Map<id, item> for O(n) look-ups.

This will make the helper robust to incidental ordering differences and remove the need for callers to remember to sort beforehand.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7de7e49 and 3035966.

📒 Files selected for processing (6)
  • frontend/apps/client/tsconfig.app.json (1 hunks)
  • frontend/packages/date-time/__tests__/group.test.ts (1 hunks)
  • frontend/packages/date-time/__tests__/mocks/index.ts (1 hunks)
  • frontend/packages/date-time/__tests__/sort.test.ts (1 hunks)
  • frontend/packages/date-time/__tests__/utils/index.ts (1 hunks)
  • frontend/packages/date-time/src/group.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • frontend/packages/date-time/tests/group.test.ts
  • frontend/packages/date-time/tests/sort.test.ts
  • frontend/packages/date-time/tests/mocks/index.ts
  • frontend/packages/date-time/src/group.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
frontend/packages/date-time/__tests__/utils/index.ts (2)
frontend/packages/date-time/src/type.ts (1)
  • DateRange (13-16)
frontend/packages/date-time/src/group.ts (2)
  • ReturnItem (25-27)
  • OverlapDate (8-10)
🪛 Biome (1.9.4)
frontend/apps/client/tsconfig.app.json

[error] 13-13: Expected a property but instead found '}'.

Expected a property here.

(parse)


[error] 18-18: Expected a property but instead found '}'.

Expected a property here.

(parse)

🔇 Additional comments (5)
frontend/apps/client/tsconfig.app.json (3)

5-5: Add Playwright provider types for browser testing
This correctly extends the Vitest globals with Playwright types, enabling proper typings for your new browser-based tests.


11-12: Introduce new path aliases
The added @components/* and @features/* mappings align with your Vite and Vitest setups, streamlining imports for component and feature modules.


19-19: Include test files in type-checking
Adding __tests__ here ensures the compiler picks up your new test suites, matching the expanded coverage introduced in this PR.

frontend/packages/date-time/__tests__/utils/index.ts (2)

1-2: Verify test-runner resolves the @ path alias

The test file relies on @/group and @/type path aliases.
If ts-jest/Vitest isn’t configured with the same pathsmoduleNameMapper/alias mapping as tsconfig.json, the imports will fail when the tests run in CI.

Please double-check jest.config.ts / vitest.config.ts (or the relevant runner) to be sure the alias is recognised outside of the build pipeline.


38-50: OverlapDate comparison ignores extra fields from generic T

OverlapDate<DateRange> currently includes only start, end, idx, but the generic could later widen (e.g. OverlapDate<MyExtendedRange>).
If that happens, the comparator would silently accept mismatches on the additional fields. Either:

  • Keep the current narrow contract but document it explicitly in the jsdoc, or
  • Extend the equality check to ...JSON.stringify(itemA) === JSON.stringify(itemB) when T is known to be serialisable.

This reduces the risk of false positives in future refactors.

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

Labels

🖥️ FE Frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants