-
Notifications
You must be signed in to change notification settings - Fork 0
#13 refactor: assets 관리 구조 개선 및 라우팅 최적화 (Prettier 도입) #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…eat/13-student-management
|
Warning
|
| Cohort / File(s) | Summary |
|---|---|
SVG component deletions src/assets/svg/AddIcon.tsx, src/assets/svg/ArrowdownIcon.tsx, src/assets/svg/ArrowleftIcon.tsx, src/assets/svg/ArrowrightIcon.tsx, src/assets/svg/ChatIcon.tsx, src/assets/svg/Chevrondown.tsx, src/assets/svg/DeleteIcon.tsx, src/assets/svg/DragAndDropIcon.tsx, src/assets/svg/EditIcon.tsx, src/assets/svg/EllipsisIcon.tsx, src/assets/svg/File.tsx, src/assets/svg/NotificationIcon.tsx, src/assets/svg/SignoutIcon.tsx, src/assets/svg/SingleEllipsisIcon.tsx, src/assets/svg/UserIcon.tsx |
Deleted 15 React SVG component modules and their default exports. |
Barrel exports removed src/assets/svg/index.ts |
Removed re-exports for the deleted SVG components. |
SVG import migration (usage sites) src/components/.../AssignmentCard.tsx, src/components/.../AssignmentPageLayout.tsx, src/components/.../CourseSelector.tsx, src/components/.../FileUpload.tsx, src/components/.../LabeledDropdown.tsx, src/components/common/Dashboard/CourseCard.tsx, src/components/common/Dashboard/CourseList.tsx, src/pages/common/LandingPage.tsx, src/pages/common/UserIdInputPage.tsx |
Replaced local barrel/named SVG imports with direct public /svg/...?.react default imports (SVGR-style) at usage sites. |
Component API & behavior changes src/components/admin/assignments/AssignmentFormLayout.tsx, src/components/common/CourseOverview/CourseActionsBar.tsx, src/components/common/Button.tsx, src/components/common/CourseOverview/CourseHero.tsx, src/components/common/CourseOverview/EmptyCourse.tsx, src/components/common/CourseOverview/CourseStat.tsx |
Added titleExtra?: React.ReactNode to AssignmentFormLayout; extended CourseActionsBar props (title, section) and added navigation to /admin/student; Button now accepts onClick; small className/prop wiring tweaks. |
Layout typing & navigation src/layout/Layout.tsx, src/components/common/IconButton.tsx |
Introduced UserType and NavButton types; typed getNavigationButtons and NavigationBar props; switched some asset imports to public SVGs. |
Student management & routing src/pages/admin/student/studentManagementPage.tsx, src/App.tsx |
Added StudentManagementPage and wired admin routes (admin/student, admin/assignments/create, admin/courses/create); normalized nested route paths and updated imports. |
Tooling & config package.json, .prettierrc, .husky/commit-msg, commitlint.config.cjs |
Added devDependencies (@commitlint/cli, @commitlint/config-conventional, prettier, prettier-plugin-tailwindcss), added Prettier tailwind config, and added commit-msg Husky hook + commitlint config. |
| Codebase import aliasing many files under src/components/**, src/pages/**, src/utils/** (e.g., @/...) |
Replaced numerous relative imports with project alias imports (@/...) for consistency. |
Styling tokens src/index.css |
Added status CSS variables: --color-status-green, --color-status-yellow, --color-status-red. |
Minor page/component cleanups src/pages/admin/assignments/AssignmentCreatePage.tsx, src/pages/admin/assignments/AssignmentSelectPage.tsx, src/pages/admin/assignments/AssignmentsPage.tsx |
Unused param rename (ex → _), removed linkedAssignments state/handler, adjusted layout prop usage and imports. |
Repository automation config .coderabbit.yaml |
Added CodeRabbit review automation policy (localized rules, path-specific checks, tooling integration). |
Sequence Diagram(s)
(omitted)
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~22 minutes
Possibly related PRs
- #4 feat: 공통 헤더 레이아웃 적용 및 통합 #6 — overlapping changes to layout/header and SVG icon usage.
- #10 feat: 학번 입력 otp 구현 #11 — touches the same SVG icon modules and UserIdInputPage imports.
- #14 feat: 강의 개설 페이지, 문제 등록 및 수정 페이지 구현 #18 — related to AssignmentFormLayout component changes (titleExtra addition origin/continuation).
Suggested labels
🛠️ refactor
Suggested reviewers
- suminb99
Poem
🐇 I hopped through code and moved each icon,
nudged routes, added lint for each commit—so spry—
I gave forms extra room to flaunt,
and left a prettier, tidier sky.
— a tidy rabbit's tiny try.
Pre-merge checks
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (4 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title clearly describes the main refactoring changes: asset structure improvement, routing optimization, and Prettier introduction, matching the primary objectives of the PR. |
| Linked Issues check | ✅ Passed | The PR successfully implements all coding requirements from issue #13: asset structure optimization (deleted unused SVG components, switched to ?react imports), routing improvements (unified casing, added admin routes), Prettier setup, titleExtra prop addition, and Git hooks/CodeRabbit configuration. |
| Out of Scope Changes check | ✅ Passed | All changes are aligned with issue #13 requirements. No out-of-scope modifications detected; changes include asset management refactoring, routing optimization, tooling additions, and component enhancements as specified. |
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/common/Dashboard/CourseList.tsx (1)
35-37: Remove commented code.The commented
onClickAddfunction should either be implemented and connected to the Add button (lines 48-51), or removed entirely.
🤖 Fix all issues with AI Agents
In @package.json:
- Around line 30-31: The Prettier Tailwind plugin is installed (prettier and
prettier-plugin-tailwindcss) but your .prettierrc is missing the
tailwindStylesheet option required for Tailwind CSS v4 support; open .prettierrc
and add the tailwindStylesheet key with the path to your Tailwind entry file
(e.g., "src/index.css" or your actual entry) so prettier-plugin-tailwindcss can
correctly sort classes.
In @src/components/common/CourseOverview/CourseActionsBar.tsx:
- Around line 13-15: handleStudentListClick builds the student list URL by
directly interpolating title and section causing malformed URLs for values with
spaces or special characters; update handleStudentListClick to URL-encode the
query parameters (e.g., use encodeURIComponent on title and section or build the
query via URLSearchParams) before passing to navigate so the resulting
`/admin/student?course=...` value is properly escaped.
In @src/components/common/Dashboard/CourseList.tsx:
- Line 3: The import for AddIcon uses an incorrect /public/ prefix; update the
import in CourseList.tsx to remove the /public part so it imports from
'/svg/addIcon.svg?react' (i.e., change the AddIcon import statement to use the
root-served path), and check any other SVG imports in the file for the same
/public/ prefix and fix them similarly.
In @src/layout/Layout.tsx:
- Line 11: Remove the duplicate local type alias UserType in Layout.tsx and
instead import and reuse the canonical UserType defined in the Dashboard types
module (the types.ts that currently defines UserType). Replace the local
declaration "type UserType = 'admin' | 'student';" with an import like "import {
UserType } from '...types...';" (use the existing Dashboard types module), and
ensure any references in Layout.tsx continue to use UserType without changing
semantics.
In @src/pages/admin/student/studentManagementPage.tsx:
- Line 11: The className on the button element in studentManagementPage.tsx has
a leading space (' text-primary px-3...'); remove the leading whitespace so the
value begins with "text-primary..." to avoid issues with class parsing (locate
the button element that currently sets className to ' text-primary px-3 py-[6px]
rounded-4xl inline-flex h-8 justify-center items-center border border-primary'
and update it).
In @src/pages/common/LandingPage.tsx:
- Line 8: The SVG import paths use the `/public` prefix which breaks Vite
resolution; update imports like the ArrowrightIcon import (ArrowrightIcon in
LandingPage.tsx) to remove `/public` so they reference root-served assets (e.g.,
`/svg/arrowrightIcon.svg?react`) and apply the same change for all other SVG
imports across Layout.tsx, CourseCard.tsx, AssignmentCard.tsx, etc.; ensure the
query parameter `?react` remains and run the app to verify the modules resolve.
🧹 Nitpick comments (6)
src/components/common/IconButton.tsx (1)
1-11: Component looks good; consider adding common button props for flexibility.The IconButton component is clean and simple. However, it lacks common button affordances such as
onClick,disabled, andaria-label, which limits its reusability. If these are intentionally handled at the call site, that's fine, but consider extending the interface for better component flexibility.🔎 Optional enhancement for broader button support
If needed in the future, you can extend the component to accept standard button attributes:
-interface IconButtonProps { - icon: React.ReactElement; -} - -const IconButton = ({icon}: IconButtonProps) => { - return <button className='header-btn'>{icon}</button>; +interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { + icon: React.ReactElement; +} + +const IconButton = ({icon, ...buttonProps}: IconButtonProps) => { + return <button className='header-btn' {...buttonProps}>{icon}</button>; };This allows callers to pass
onClick,aria-label,title,disabled, etc. as needed.src/pages/admin/assignments/AssignmentsPage.tsx (1)
1-1: Consider replacing dummy data with a real API call.The import references a
dummy/responsefile, suggesting this is mock data. If this page is production-ready, consider replacing the hardcoded response with an actual API call or state management solution.src/components/common/CourseOverview/EmptyCourse.tsx (1)
14-14: Consider whether CourseActionsBar should render in an empty course state.Passing empty strings for
titleandsectionsuggests these props may not be meaningful in this context. Consider either:
- Making
titleandsectionoptional inCourseActionsBarand handling the empty/undefined case appropriately in its implementation, or- Conditionally rendering
CourseActionsBaronly when there's actual course data to display.This would better align the component's API with its semantic usage.
src/App.tsx (1)
11-11: Inconsistent filename casing for student management page.The imported file
studentManagementPage.tsxuses camelCase, while other admin page files in this project use PascalCase (e.g.,AssignmentsPage.tsx,CourseCreatePage.tsx,AssignmentSelectPage.tsx). For consistency, consider renaming the file toStudentManagementPage.tsx.src/pages/admin/student/studentManagementPage.tsx (2)
11-31: Initial UI scaffolding detected - consider implementing interactive functionality.The course filter button (lines 11-13), search input (lines 15-20), and action handlers (lines 30-31) are currently non-functional placeholders. Based on the PR objectives mentioning "detailed tasks left as TODOs" for issue #13, this appears to be intentional initial scaffolding.
Consider adding:
onClickhandler for the course filter button (possibly opening a dropdown)- State management and
onChangehandler for the search input- Implementation for
onCancelandonConfirmhandlers- Actual student management content to replace the placeholder
Would you like me to help generate the implementation for any of these interactive features, or would you prefer to track these as separate issues/TODOs?
15-20: Add accessible label for search input.The search input uses only a
placeholderfor labeling, which is insufficient for accessibility. Screen readers may not properly announce the input's purpose.🔎 Suggested accessibility improvements
Option 1: Visible label
+ <label htmlFor='student-search' className='sr-only'> + 학번 검색 + </label> <input + id='student-search' type='text' placeholder='학번을 검색하세요' className='border border-gray-300 rounded-lg px-4 py-2 pr-10 w-64' />Option 2: aria-label
<input type='text' placeholder='학번을 검색하세요' + aria-label='학번 검색' className='border border-gray-300 rounded-lg px-4 py-2 pr-10 w-64' />
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
package-lock.jsonis excluded by!**/package-lock.jsonpublic/svg/profileImage.svgis excluded by!**/*.svgpublic/svg/search.svgis excluded by!**/*.svg
📒 Files selected for processing (40)
package.jsonsrc/App.tsxsrc/assets/svg/AddIcon.tsxsrc/assets/svg/ArrowdownIcon.tsxsrc/assets/svg/ArrowleftIcon.tsxsrc/assets/svg/ArrowrightIcon.tsxsrc/assets/svg/ChatIcon.tsxsrc/assets/svg/Chevrondown.tsxsrc/assets/svg/DeleteIcon.tsxsrc/assets/svg/DragAndDropIcon.tsxsrc/assets/svg/EditIcon.tsxsrc/assets/svg/EllipsisIcon.tsxsrc/assets/svg/File.tsxsrc/assets/svg/NotificationIcon.tsxsrc/assets/svg/SignoutIcon.tsxsrc/assets/svg/SingleEllipsisIcon.tsxsrc/assets/svg/UserIcon.tsxsrc/assets/svg/index.tssrc/components/admin/assignments/AssignmentCard.tsxsrc/components/admin/assignments/AssignmentFormLayout.tsxsrc/components/admin/assignments/AssignmentPageLayout.tsxsrc/components/admin/assignments/CourseSelector.tsxsrc/components/admin/form/FileUpload.tsxsrc/components/admin/form/LabeledDropdown.tsxsrc/components/common/Button.tsxsrc/components/common/CourseOverview/CourseActionsBar.tsxsrc/components/common/CourseOverview/CourseHero.tsxsrc/components/common/CourseOverview/CourseStat.tsxsrc/components/common/CourseOverview/EmptyCourse.tsxsrc/components/common/Dashboard/CourseCard.tsxsrc/components/common/Dashboard/CourseList.tsxsrc/components/common/IconButton.tsxsrc/index.csssrc/layout/Layout.tsxsrc/pages/admin/assignments/AssignmentCreatePage.tsxsrc/pages/admin/assignments/AssignmentSelectPage.tsxsrc/pages/admin/assignments/AssignmentsPage.tsxsrc/pages/admin/student/studentManagementPage.tsxsrc/pages/common/LandingPage.tsxsrc/pages/common/UserIdInputPage.tsx
💤 Files with no reviewable changes (17)
- src/assets/svg/ChatIcon.tsx
- src/assets/svg/EditIcon.tsx
- src/assets/svg/AddIcon.tsx
- src/assets/svg/SingleEllipsisIcon.tsx
- src/assets/svg/File.tsx
- src/pages/admin/assignments/AssignmentSelectPage.tsx
- src/assets/svg/ArrowdownIcon.tsx
- src/assets/svg/DragAndDropIcon.tsx
- src/assets/svg/ArrowleftIcon.tsx
- src/assets/svg/SignoutIcon.tsx
- src/assets/svg/EllipsisIcon.tsx
- src/assets/svg/UserIcon.tsx
- src/assets/svg/NotificationIcon.tsx
- src/assets/svg/DeleteIcon.tsx
- src/assets/svg/index.ts
- src/assets/svg/ArrowrightIcon.tsx
- src/assets/svg/Chevrondown.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/App.tsx:6-11
Timestamp: 2025-07-16T12:33:43.867Z
Learning: JiiminHa prefers hierarchical routing structure with role-based path organization: common routes at root level (/), student-specific routes under /student prefix, and admin-specific routes under /admin prefix, using nested routes with a shared Layout component for consistent UI patterns.
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:14:38.834Z
Learning: In this project, the svgr workflow requires placing original SVG files in the `public/svg` folder first, then running `npm run svgr` command to generate converted TSX files in the `src/assets/svg` folder according to the root configuration.
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:00:01.926Z
Learning: This project uses svgr for automatic SVG to React component conversion. Running `npm run svgr` automatically converts all svgr files to React component format and handles camelCase conversion for SVG attributes (e.g., stroke-width → strokeWidth).
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 2
File: src/components/Header/StudentHeader.tsx:6-18
Timestamp: 2025-07-13T00:25:00.538Z
Learning: User JiiminHa prefers using semantic HTML tags over excessive div usage for better code structure and accessibility in React components.
📚 Learning: 2025-07-13T00:27:31.464Z
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 2
File: src/components/Header/StudentHeader.tsx:10-10
Timestamp: 2025-07-13T00:27:31.464Z
Learning: Using TypeScript interfaces for React component props (like StudentHeaderProps) provides clear structure, improves readability, and makes components more maintainable and extensible for future development.
Applied to files:
src/components/admin/assignments/CourseSelector.tsxsrc/components/admin/assignments/AssignmentCard.tsxsrc/pages/admin/student/studentManagementPage.tsxsrc/components/common/CourseOverview/CourseHero.tsxsrc/components/common/Dashboard/CourseCard.tsxsrc/layout/Layout.tsxsrc/components/common/CourseOverview/CourseActionsBar.tsx
📚 Learning: 2025-07-16T13:14:38.834Z
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:14:38.834Z
Learning: In this project, the svgr workflow requires placing original SVG files in the `public/svg` folder first, then running `npm run svgr` command to generate converted TSX files in the `src/assets/svg` folder according to the root configuration.
Applied to files:
src/components/admin/assignments/AssignmentCard.tsxsrc/components/admin/form/FileUpload.tsx
📚 Learning: 2025-07-16T12:33:43.867Z
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/App.tsx:6-11
Timestamp: 2025-07-16T12:33:43.867Z
Learning: JiiminHa prefers hierarchical routing structure with role-based path organization: common routes at root level (/), student-specific routes under /student prefix, and admin-specific routes under /admin prefix, using nested routes with a shared Layout component for consistent UI patterns.
Applied to files:
src/App.tsx
🧬 Code graph analysis (2)
src/layout/Layout.tsx (1)
src/components/common/Dashboard/types.ts (1)
UserType(30-30)
src/App.tsx (2)
src/pages/common/UserIdInputPage.tsx (1)
UserIdInputPage(7-134)src/pages/admin/student/studentManagementPage.tsx (1)
StudentManagementPage(5-34)
🔇 Additional comments (23)
src/components/common/CourseOverview/CourseStat.tsx (1)
13-13: LGTM! Prettier formatting applied correctly.The Tailwind class reordering is the expected result of running prettier-plugin-tailwindcss (added in this PR). The change is purely cosmetic with no functional impact.
src/index.css (1)
51-53: LGTM! Status color tokens follow project conventions.The new status color custom properties are well-named, use valid hex values, and are correctly placed within the
@themeblock for Tailwind v4. These likely support the student management UI features introduced in this PR.src/pages/admin/assignments/AssignmentsPage.tsx (1)
2-14: LGTM!The import path update correctly reflects the file reorganization, and the component logic is clean and straightforward.
src/components/common/Dashboard/CourseList.tsx (1)
48-51: Verify: Add button has no onClick handler.The Add button is rendered for admin users but has no click handler attached. Is this intentional, or should it connect to the commented
onClickAddfunction?src/components/admin/form/LabeledDropdown.tsx (2)
27-86: Component implementation looks solid — migration approach is cleaner than the previous svgr workflow.The component logic is well-structured with proper state management, event handling, and accessibility considerations. Once the import path is corrected (see previous comment), the migration to direct SVG imports with
?reactsuffix is actually simpler than the old workflow requiringnpm run svgrcode generation.Based on learnings, the previous workflow required placing SVGs in public/svg, running npm run svgr, then importing from src/assets/svg. This new approach is more direct and eliminates the code generation step.
2-2: No changes needed — import path is correct and consistent with the codebase.The
/public/svg/chevrondown.svg?reactpattern is already established throughout the codebase. Multiple files (AssignmentCard.tsx, Layout.tsx, CourseSelector.tsx, FileUpload.tsx, and others) use this exact same import pattern. The vite-plugin-svgr configuration in vite.config.ts supports this approach, processing SVG files from the public directory at build/dev time with the?reactquery parameter.src/pages/admin/assignments/AssignmentCreatePage.tsx (1)
38-38: LGTM! Good practice for unused parameter.Using
_to indicate the unused array element parameter improves code readability and follows common conventions.src/components/admin/assignments/CourseSelector.tsx (1)
2-2: Verify the import path for public folder assets.The import path includes the
/publicprefix, which is typically not needed when importing from Vite's public folder. This should likely be/svg/arrowdownIcon.svg?reactinstead. Please verify this works correctly in your build environment.src/components/admin/assignments/AssignmentPageLayout.tsx (1)
5-5: Verify the import path for public folder assets.The
/publicprefix in the import path may be incorrect for Vite's public folder handling. Standard Vite convention uses/svg/addIcon.svg?reactwithout the/publicprefix.src/components/common/Dashboard/CourseCard.tsx (1)
2-2: Verify the import path for public folder assets.Consistent with the other files in this PR, this import uses the
/publicprefix. In standard Vite setups, public folder assets are accessed from the root (e.g.,/svg/ellipsisIcon.svg?react). Please confirm your Vite configuration supports this path pattern or adjust the imports accordingly.src/components/admin/form/FileUpload.tsx (1)
3-3: LGTM! Consistent with project-wide SVG migration.The import source change from local assets to public SVG path with
?reactloader aligns with the broader migration strategy across the codebase. The component name change toFileIconis also more descriptive.Based on learnings, this pattern uses Vite's svgr loader to import SVGs as React components from the public directory.
Also applies to: 106-106
src/components/admin/assignments/AssignmentCard.tsx (1)
2-5: LGTM! SVG imports consistently migrated.All four icon imports have been successfully migrated to the public SVG path pattern with the
?reactloader, maintaining consistency with the broader refactoring effort across the codebase.src/pages/common/UserIdInputPage.tsx (1)
5-5: LGTM! Icon import migrated correctly.The ArrowleftIcon import follows the established public SVG path pattern, consistent with the project-wide migration strategy.
src/layout/Layout.tsx (3)
4-7: LGTM! Icon imports migrated to public SVG pattern.All four icon imports successfully follow the public SVG path pattern with
?reactloader, consistent with the project-wide migration.
9-9: React import is necessary for type usage.While React 19's JSX transform doesn't require importing React for JSX, the import is needed here because
React.ReactElementis used in theNavButtoninterface type definition (line 14).
13-16: Excellent type safety improvements!The addition of the
NavButtoninterface and comprehensive type annotations forgetNavigationButtons,getWelcomeMessage, andNavigationBarsignificantly improves type safety and code maintainability.Also applies to: 27-65
src/components/common/Button.tsx (1)
5-5: LGTM! onClick handler properly implemented.The
onClickprop is correctly typed as optional, properly destructured, and forwarded to the button element. This enables the Button component to support click handlers for navigation and other interactions.Also applies to: 19-19, 22-22
src/App.tsx (1)
18-40: LGTM on routing structure improvements!The removal of leading slashes from nested routes (e.g.,
useridinstead of/userid) is correct for React Router v6, and the new admin routes for assignment creation, course creation, and student management are well-organized under the/adminprefix, following the hierarchical routing structure.src/components/admin/assignments/AssignmentFormLayout.tsx (1)
5-5: LGTM on titleExtra prop addition!The optional
titleExtraprop is well-designed, allowing flexible composition of the title area. The flex layout implementation (lines 22-25) properly positions the title and extra content with appropriate spacing, and the prop being optional maintains backward compatibility with existing usages.Also applies to: 13-13, 22-25
src/components/common/CourseOverview/CourseHero.tsx (1)
36-40: LGTM on CourseActionsBar props update!The addition of
titleandsectionprops toCourseActionsBaris correctly implemented, passing through the component's own props to provide necessary context to the actions bar. The conditional rendering logic remains appropriate for the admin active course scenario.src/components/common/CourseOverview/CourseActionsBar.tsx (3)
1-1: LGTM!The import statement is correct and follows React Router v6 conventions.
4-8: LGTM!The TypeScript interface is well-structured and provides clear prop types. Based on learnings, using interfaces for React component props improves readability and maintainability.
22-22: LGTM!The onClick handler is correctly wired to the button, assuming the URL encoding issue in
handleStudentListClickis addressed.
| import IconButton from '../components/common/IconButton'; | ||
| import React from 'react'; | ||
|
|
||
| type UserType = 'admin' | 'student'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Eliminate duplicate UserType definition.
The UserType type is already defined in src/components/common/Dashboard/types.ts (line 29). Import and reuse the existing type instead of redefining it to avoid code duplication and potential inconsistencies.
🔎 Proposed fix to import existing UserType
+import type {UserType} from '../components/common/Dashboard/types';
+
-type UserType = 'admin' | 'student';
-
interface NavButton {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| type UserType = 'admin' | 'student'; | |
| import type {UserType} from '../components/common/Dashboard/types'; | |
| interface NavButton { |
🤖 Prompt for AI Agents
In @src/layout/Layout.tsx around line 11, Remove the duplicate local type alias
UserType in Layout.tsx and instead import and reuse the canonical UserType
defined in the Dashboard types module (the types.ts that currently defines
UserType). Replace the local declaration "type UserType = 'admin' | 'student';"
with an import like "import { UserType } from '...types...';" (use the existing
Dashboard types module), and ensure any references in Layout.tsx continue to use
UserType without changing semantics.
|
|
||
| const titleExtra = ( | ||
| <div className='flex justify-between items-center flex-1'> | ||
| <button className=' text-primary px-3 py-[6px] rounded-4xl inline-flex h-8 justify-center items-center border border-primary'> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove leading space in className.
The className prop starts with a space: ' text-primary'. This leading whitespace should be removed as it can cause unexpected behavior or issues with certain CSS frameworks and class name processing.
🔎 Proposed fix
- <button className=' text-primary px-3 py-[6px] rounded-4xl inline-flex h-8 justify-center items-center border border-primary'>
+ <button className='text-primary px-3 py-[6px] rounded-4xl inline-flex h-8 justify-center items-center border border-primary'>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <button className=' text-primary px-3 py-[6px] rounded-4xl inline-flex h-8 justify-center items-center border border-primary'> | |
| <button className='text-primary px-3 py-[6px] rounded-4xl inline-flex h-8 justify-center items-center border border-primary'> |
🤖 Prompt for AI Agents
In @src/pages/admin/student/studentManagementPage.tsx around line 11, The
className on the button element in studentManagementPage.tsx has a leading space
(' text-primary px-3...'); remove the leading whitespace so the value begins
with "text-primary..." to avoid issues with class parsing (locate the button
element that currently sets className to ' text-primary px-3 py-[6px]
rounded-4xl inline-flex h-8 justify-center items-center border border-primary'
and update it).
There was a problem hiding this 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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/pages/admin/assignments/AssignmentSelectPage.tsx (3)
7-7: Add validation for the route parameter.
Number(useParams().id)will produceNaNif theidparameter is undefined, missing, or non-numeric. This will cause the course lookup (line 11) to fail silently, resulting in an emptyfullCoursesarray and a broken UI.🔎 Suggested fix with validation
const AssignmentSelectPage = () => { // url에서 course id 가져오기 - const courseId = Number(useParams().id); + const {id} = useParams(); + const courseId = Number(id); + + if (!id || isNaN(courseId)) { + return <div>잘못된 강의 ID입니다.</div>; + }
10-17: Add error handling for course lookup failure.If the course with the given
courseIdis not found,courseTitlewill beundefined, causing the filter to return an empty array. This results in a blank page with no feedback to the user about why courses aren't displayed.🔎 Suggested fix with error handling
// 강의명 찾기 - const courseTitle = coursesResponse.response.courses.find( + const course = coursesResponse.response.courses.find( (course) => course.id === courseId - )?.title; + ); + + if (!course) { + return <div>해당 강의를 찾을 수 없습니다.</div>; + } // 기본 문제 목록 const fullCourses = coursesResponse.response.courses.filter( - (course) => course.title === courseTitle + (c) => c.title === course.title );
19-25: Missing onLinkAssignments callback breaks selection tracking in selectMode.The
onLinkAssignmentsprop is defined inAssignmentPageLayout's interface (line 12) but is not destructured or forwarded toAssignmentList(line 33). WhenselectMode={true}, users can select assignments, but the selection callback will not be invoked because it's never passed down the component chain. This breaks the selection functionality that depends ononLinkAssignmentsbeing called inAssignmentCard.Pass the
onLinkAssignmentsprop toAssignmentListon line 33:Fix
<AssignmentList courses={courses} selectMode={selectMode} onLinkAssignments={onLinkAssignments} />
🤖 Fix all issues with AI Agents
In @src/components/common/CourseOverview/CourseActionsBar.tsx:
- Around line 13-15: The navigation URL in handleStudentListClick builds an
unencoded query string using title and section which breaks when those values
contain spaces or special characters; update handleStudentListClick to
URL-encode the parameters (e.g., use encodeURIComponent on title and section or
construct the query via URLSearchParams) and then call navigate with the encoded
query so navigate(`/admin/student?course=${encodedCourse}`) receives a valid,
safe URL.
In @src/components/common/CourseOverview/EmptyCourse.tsx:
- Line 14: The current EmptyCourse passes empty title/section to
CourseActionsBar which lets handleStudentListClick build a malformed URL via
navigate(`/admin/student?course=${title} (${section})`); fix by adding
validation inside CourseActionsBar: make title and section optional props, have
handleStudentListClick first check that title and section are non-empty (or
produce a safe fallback) and, if invalid, prevent navigation and disable or hide
the "학생 목록" button; alternatively, change EmptyCourse to not render
CourseActionsBar when title/section are empty so handleStudentListClick is never
invoked.
In @src/components/common/CourseOverview/UnitHeader.tsx:
- Around line 1-2: Duplicate import of UnitLabel in UnitHeader.tsx: remove the
redundant import statement so only a single import of UnitLabel remains (keep
the first import and delete the second) to resolve the redeclaration/compilation
error referencing UnitLabel in UnitHeader.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
src/components/admin/assignments/AssignmentCard.tsxsrc/components/admin/assignments/AssignmentPageLayout.tsxsrc/components/admin/assignments/CourseSelector.tsxsrc/components/admin/form/FileUpload.tsxsrc/components/admin/form/LabeledDropdown.tsxsrc/components/common/BaseHeader.tsxsrc/components/common/CourseOverview/AssignmentItem.tsxsrc/components/common/CourseOverview/AssignmentList.tsxsrc/components/common/CourseOverview/CourseActionsBar.tsxsrc/components/common/CourseOverview/CourseHero.tsxsrc/components/common/CourseOverview/EmptyCourse.tsxsrc/components/common/CourseOverview/SubmissionBadge.tsxsrc/components/common/CourseOverview/UnitHeader.tsxsrc/components/common/CourseOverview/dummy/types.tssrc/components/common/Dashboard/CourseCard.tsxsrc/components/common/Dashboard/CourseList.tsxsrc/components/common/Dashboard/ScheduleList.tsxsrc/components/common/Dashboard/types.tssrc/layout/Layout.tsxsrc/pages/admin/assignments/AssignmentSelectPage.tsxsrc/pages/admin/assignments/AssignmentsPage.tsxsrc/pages/admin/student/studentManagementPage.tsxsrc/pages/common/CourseOverviewPage.tsxsrc/pages/common/Dashboard.tsxsrc/pages/common/LandingPage.tsxsrc/pages/common/UserIdInputPage.tsxsrc/utils/getSemesterLabel.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- src/components/common/Dashboard/CourseList.tsx
- src/components/common/Dashboard/CourseCard.tsx
- src/components/admin/assignments/AssignmentCard.tsx
- src/components/admin/form/FileUpload.tsx
- src/components/admin/form/LabeledDropdown.tsx
- src/components/admin/assignments/AssignmentPageLayout.tsx
- src/pages/admin/assignments/AssignmentsPage.tsx
- src/pages/admin/student/studentManagementPage.tsx
- src/pages/common/UserIdInputPage.tsx
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/App.tsx:6-11
Timestamp: 2025-07-16T12:33:43.867Z
Learning: JiiminHa prefers hierarchical routing structure with role-based path organization: common routes at root level (/), student-specific routes under /student prefix, and admin-specific routes under /admin prefix, using nested routes with a shared Layout component for consistent UI patterns.
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:00:01.926Z
Learning: This project uses svgr for automatic SVG to React component conversion. Running `npm run svgr` automatically converts all svgr files to React component format and handles camelCase conversion for SVG attributes (e.g., stroke-width → strokeWidth).
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:14:38.834Z
Learning: In this project, the svgr workflow requires placing original SVG files in the `public/svg` folder first, then running `npm run svgr` command to generate converted TSX files in the `src/assets/svg` folder according to the root configuration.
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 2
File: src/components/Header/StudentHeader.tsx:6-18
Timestamp: 2025-07-13T00:25:00.538Z
Learning: User JiiminHa prefers using semantic HTML tags over excessive div usage for better code structure and accessibility in React components.
📚 Learning: 2025-07-13T00:27:31.464Z
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 2
File: src/components/Header/StudentHeader.tsx:10-10
Timestamp: 2025-07-13T00:27:31.464Z
Learning: Using TypeScript interfaces for React component props (like StudentHeaderProps) provides clear structure, improves readability, and makes components more maintainable and extensible for future development.
Applied to files:
src/components/common/Dashboard/types.tssrc/layout/Layout.tsxsrc/components/common/CourseOverview/AssignmentItem.tsxsrc/components/common/BaseHeader.tsxsrc/components/common/CourseOverview/AssignmentList.tsxsrc/components/admin/assignments/CourseSelector.tsxsrc/components/common/CourseOverview/CourseActionsBar.tsxsrc/components/common/CourseOverview/UnitHeader.tsx
📚 Learning: 2025-07-16T13:14:38.834Z
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:14:38.834Z
Learning: In this project, the svgr workflow requires placing original SVG files in the `public/svg` folder first, then running `npm run svgr` command to generate converted TSX files in the `src/assets/svg` folder according to the root configuration.
Applied to files:
src/pages/common/LandingPage.tsx
🧬 Code graph analysis (6)
src/components/common/Dashboard/types.ts (1)
src/components/admin/assignments/dummy/types.ts (1)
Course(10-18)
src/layout/Layout.tsx (2)
src/components/common/Dashboard/types.ts (1)
UserType(30-30)src/App.tsx (1)
App(12-45)
src/components/common/CourseOverview/AssignmentItem.tsx (2)
src/components/admin/assignments/dummy/types.ts (2)
Assignment(4-8)Course(10-18)src/components/admin/assignments/AssignmentList.tsx (1)
AssignmentListProps(4-8)
src/components/common/CourseOverview/AssignmentList.tsx (2)
src/components/admin/assignments/dummy/types.ts (2)
Assignment(4-8)Course(10-18)src/components/admin/assignments/AssignmentList.tsx (1)
AssignmentListProps(4-8)
src/pages/common/CourseOverviewPage.tsx (2)
src/components/common/CourseOverview/CourseContent.tsx (1)
unit(11-13)src/components/common/CourseOverview/Unit.tsx (1)
UnitProps(5-7)
src/components/admin/assignments/CourseSelector.tsx (1)
src/assets/svg/ArrowdownIcon.tsx (1)
props(3-16)
🪛 Biome (2.1.2)
src/components/common/CourseOverview/UnitHeader.tsx
[error] 2-2: Shouldn't redeclare 'UnitLabel'. Consider to delete it or rename it.
'UnitLabel' is defined here:
(lint/suspicious/noRedeclare)
🔇 Additional comments (23)
src/components/admin/assignments/CourseSelector.tsx (1)
2-2: Import statement is correct.The SVG filename casing matches exactly—
public/svg/arrowdownIcon.svgexists and is properly referenced in the import. The migration to Vite's?reactsuffix is correctly implemented with no issues.src/pages/admin/assignments/AssignmentSelectPage.tsx (1)
1-3: The @ path alias is properly configured invite.config.tsand both imported modules exist at their specified paths, so the imports are correct.src/components/common/CourseOverview/SubmissionBadge.tsx (1)
1-4: LGTM! Import paths successfully migrated to alias-based paths.The refactor from relative paths to
@/alias paths improves maintainability and aligns with the PR's objectives for path standardization.src/components/common/CourseOverview/UnitHeader.tsx (1)
3-3: LGTM! Asset import successfully migrated to alias path.The lock icon import now uses the
@/alias, consistent with the PR's path standardization objectives.src/pages/common/LandingPage.tsx (2)
30-35: LGTM! Conditional rendering logic is correct.The ternary operator formatting adjustment maintains the same logic while improving readability.
8-9: SVG import pattern is correctly configured.The
/svg/arrowrightIcon.svg?reactimport is valid and properly supported by the project. Thevite-plugin-svgr(v4.3.0) is configured invite.config.tswithicon: trueoptimization, the SVG file exists atpublic/svg/arrowrightIcon.svg, and Vite correctly serves files from the public folder at the/svg/path. No action required.src/components/common/Dashboard/types.ts (1)
1-1: LGTM! Type import successfully migrated to alias path.The refactor to use
@/alias for theSemesterCodetype import improves consistency with the broader codebase restructuring in this PR.src/pages/common/CourseOverviewPage.tsx (1)
1-4: LGTM! All imports successfully migrated to alias-based paths.The consistent use of
@/alias across all CourseOverview component imports improves code maintainability and aligns perfectly with the PR's path standardization objectives.src/components/common/Dashboard/ScheduleList.tsx (1)
2-3: LGTM! Import path refactor aligns with PR objectives.The conversion from relative to alias-based import paths is correct and consistent with the project-wide standardization. The SVG files are properly imported as regular images (without
?reactsuffix) since they're used in<img>elements.src/components/common/CourseOverview/AssignmentItem.tsx (1)
1-1: LGTM! Type import path correctly updated.The conversion to alias-based import path for the
Assignmenttype is correct and aligns with the project-wide refactor.src/components/common/CourseOverview/dummy/types.ts (1)
1-4: LGTM! Type import paths correctly updated.The conversion to alias-based import paths for
AssignmentandSemesterCodetypes is correct and consistent with the project-wide import path standardization.src/pages/common/Dashboard.tsx (1)
1-2: LGTM! Component import paths correctly updated.The conversion to alias-based import paths for
CourseListandScheduleListcomponents is correct and aligns with the project-wide refactor.src/components/common/CourseOverview/EmptyCourse.tsx (1)
1-1: LGTM! Asset import path correctly updated.The conversion to alias-based import path for the overview image is correct and consistent with the project-wide refactor.
src/utils/getSemesterLabel.ts (1)
1-1: LGTM! Import path refactored to use alias.The change from relative to alias-based import path improves consistency across the codebase.
src/components/common/CourseOverview/CourseHero.tsx (2)
2-4: LGTM! Import paths refactored to use aliases.The migration to alias-based imports improves consistency and maintainability.
36-40: CourseActionsBar properly accepts the new props.The component signature has been correctly updated to accept
titleandsectionin addition toisActive. The interface definition (lines 4-8 of CourseActionsBar.tsx) matches the invocation, and the props are used to construct the student list navigation URL.src/components/common/BaseHeader.tsx (1)
1-1: LGTM! Logo import refactored to use alias.The change improves import consistency across the codebase.
src/components/common/CourseOverview/AssignmentList.tsx (1)
1-1: LGTM! Import path refactored to use alias.The change aligns with the project-wide migration to alias-based imports.
src/layout/Layout.tsx (2)
3-9: LGTM! Import paths updated to use aliases and public SVG assets.The migration to:
- Alias-based imports (
@/...) for components- Public SVG imports with
?reactsuffix (Vite's built-in feature)- Explicit React import for TypeScript typing
aligns with the PR's objective to optimize asset management and improve import consistency.
13-16: LGTM! TypeScript typing improvements enhance code quality.The addition of:
NavButtoninterface for navigation items- Type annotations for
getNavigationButtons,getWelcomeMessage, andNavigationBarprovides clear structure, improves type safety, and makes the component more maintainable. Based on learnings, this aligns with the project's preference for explicit TypeScript interfaces.
Also applies to: 27-42, 45-49, 52-58
src/components/common/CourseOverview/CourseActionsBar.tsx (3)
1-2: Good refactoring: absolute path alias and navigation hook.The migration to absolute imports using the
@alias aligns with the PR objectives, and theuseNavigatehook is correctly imported for programmatic navigation.
4-8: Excellent use of TypeScript interface for props.The
CourseActionsBarPropsinterface provides clear structure and type safety for the component. This aligns with project best practices for maintainable component APIs.
22-22: LGTM: onClick handler correctly bound.The event handler is properly attached to the button component.
| const handleStudentListClick = () => { | ||
| navigate(`/admin/student?course=${title} (${section})`); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URL encoding issue remains unaddressed.
The previously flagged issue with unencoded query parameters is still present. Course titles or sections containing spaces, ampersands, or other special characters will create malformed URLs and break navigation.
🔎 Reminder: Use encodeURIComponent to fix
const handleStudentListClick = () => {
- navigate(`/admin/student?course=${title} (${section})`);
+ navigate(`/admin/student?course=${encodeURIComponent(`${title} (${section})`)}`);
};Alternatively, use URLSearchParams for cleaner query string construction:
const handleStudentListClick = () => {
- navigate(`/admin/student?course=${title} (${section})`);
+ const params = new URLSearchParams({ course: `${title} (${section})` });
+ navigate(`/admin/student?${params.toString()}`);
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleStudentListClick = () => { | |
| navigate(`/admin/student?course=${title} (${section})`); | |
| }; | |
| const handleStudentListClick = () => { | |
| navigate(`/admin/student?course=${encodeURIComponent(`${title} (${section})`)}`); | |
| }; |
| const handleStudentListClick = () => { | |
| navigate(`/admin/student?course=${title} (${section})`); | |
| }; | |
| const handleStudentListClick = () => { | |
| const params = new URLSearchParams({ course: `${title} (${section})` }); | |
| navigate(`/admin/student?${params.toString()}`); | |
| }; |
🤖 Prompt for AI Agents
In @src/components/common/CourseOverview/CourseActionsBar.tsx around lines
13-15, The navigation URL in handleStudentListClick builds an unencoded query
string using title and section which breaks when those values contain spaces or
special characters; update handleStudentListClick to URL-encode the parameters
(e.g., use encodeURIComponent on title and section or construct the query via
URLSearchParams) and then call navigate with the encoded query so
navigate(`/admin/student?course=${encodedCourse}`) receives a valid, safe URL.
| 아직 생성된 단원이 없어요 | ||
| </span> | ||
| <CourseActionsBar isActive={false} /> | ||
| <CourseActionsBar isActive={false} title='' section='' /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find and display CourseActionsBar component definition
echo "=== CourseActionsBar Component Definition ==="
fd -t f "CourseActionsBar.tsx" --exec cat {}
echo -e "\n=== CourseActionsBar.tsx exists? ==="
fd -t f "CourseActionsBar"
echo -e "\n=== All CourseActionsBar usages ==="
rg -n -A2 -B1 '<CourseActionsBar' --type ts --type tsxRepository: 2025-snowCode/snowCode-Client
Length of output: 1072
🏁 Script executed:
#!/bin/bash
# Fix the search with proper type syntax
echo "=== All CourseActionsBar usages ==="
rg -n -A2 -B1 '<CourseActionsBar'
echo -e "\n=== EmptyCourse.tsx content ==="
cat src/components/common/CourseOverview/EmptyCourse.tsx
echo -e "\n=== CourseActionsBar button onClick handling ==="
rg -n -A5 "handleStudentListClick" src/components/common/CourseOverview/CourseActionsBar.tsxRepository: 2025-snowCode/snowCode-Client
Length of output: 1831
Fix button handler to prevent malformed navigation with empty props.
The CourseActionsBar component unconditionally attaches the handleStudentListClick onClick handler, which constructs a URL using title and section: navigate(/admin/student?course=${title} (${section})).
When EmptyCourse passes title='' and section='', clicking the "학생 목록" button will navigate to a malformed URL: /admin/student?course= ().
Solutions:
- Add validation in
handleStudentListClickto guard against empty values, or - Make
titleandsectionoptional props and conditionally disable/hide the button when empty, or - Don't render
CourseActionsBarin the empty state.
🤖 Prompt for AI Agents
In @src/components/common/CourseOverview/EmptyCourse.tsx around line 14, The
current EmptyCourse passes empty title/section to CourseActionsBar which lets
handleStudentListClick build a malformed URL via
navigate(`/admin/student?course=${title} (${section})`); fix by adding
validation inside CourseActionsBar: make title and section optional props, have
handleStudentListClick first check that title and section are non-empty (or
produce a safe fallback) and, if invalid, prevent navigation and disable or hide
the "학생 목록" button; alternatively, change EmptyCourse to not render
CourseActionsBar when title/section are empty so handleStudentListClick is never
invoked.
| import UnitLabel from './UnitLabel'; | ||
| import lock from '../../../assets/images/lock.svg'; | ||
| import UnitLabel from './UnitLabel'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove duplicate import statement.
Line 2 redeclares UnitLabel which is already imported on line 1. This will cause a compilation error.
🔎 Proposed fix
import UnitLabel from './UnitLabel';
-import UnitLabel from './UnitLabel';
import lock from '@/assets/images/lock.svg';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import UnitLabel from './UnitLabel'; | |
| import lock from '../../../assets/images/lock.svg'; | |
| import UnitLabel from './UnitLabel'; | |
| import UnitLabel from './UnitLabel'; | |
| import lock from '@/assets/images/lock.svg'; |
🧰 Tools
🪛 Biome (2.1.2)
[error] 2-2: Shouldn't redeclare 'UnitLabel'. Consider to delete it or rename it.
'UnitLabel' is defined here:
(lint/suspicious/noRedeclare)
🤖 Prompt for AI Agents
In @src/components/common/CourseOverview/UnitHeader.tsx around lines 1-2,
Duplicate import of UnitLabel in UnitHeader.tsx: remove the redundant import
statement so only a single import of UnitLabel remains (keep the first import
and delete the second) to resolve the redeclaration/compilation error
referencing UnitLabel in UnitHeader.
There was a problem hiding this 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
🤖 Fix all issues with AI Agents
In @.husky/commit-msg:
- Line 15: The commitlint invocation uses an unquoted parameter $1 which can
break when the commit message file path contains spaces or special characters;
update the command in the .husky/commit-msg hook that calls commitlint (the line
starting with "if npx --no -- commitlint --edit $1; then") to quote the
parameter (use "$1") so the path is passed as a single argument to commitlint.
- Line 4: The commit-msg hook reads the file into commit_msg using an unquoted
$1 which breaks on paths with spaces and lacks validation; change the command to
use the quoted parameter and add checks that the parameter exists and the file
is readable before reading: validate that $1 is set, that [ -r "$1" ] succeeds,
log an error and exit non-zero if not, then assign commit_msg by reading the
quoted path (commit_msg=$(cat "$1")) to safely handle spaces and special
characters.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (3)
.husky/commit-msgcommitlint.config.cjspackage.json
✅ Files skipped from review due to trivial changes (1)
- commitlint.config.cjs
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/App.tsx:6-11
Timestamp: 2025-07-16T12:33:43.867Z
Learning: JiiminHa prefers hierarchical routing structure with role-based path organization: common routes at root level (/), student-specific routes under /student prefix, and admin-specific routes under /admin prefix, using nested routes with a shared Layout component for consistent UI patterns.
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:00:01.926Z
Learning: This project uses svgr for automatic SVG to React component conversion. Running `npm run svgr` automatically converts all svgr files to React component format and handles camelCase conversion for SVG attributes (e.g., stroke-width → strokeWidth).
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:14:38.834Z
Learning: In this project, the svgr workflow requires placing original SVG files in the `public/svg` folder first, then running `npm run svgr` command to generate converted TSX files in the `src/assets/svg` folder according to the root configuration.
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 2
File: src/components/Header/StudentHeader.tsx:6-18
Timestamp: 2025-07-13T00:25:00.538Z
Learning: User JiiminHa prefers using semantic HTML tags over excessive div usage for better code structure and accessibility in React components.
| echo "📝 커밋 메시지를 검증합니다..." | ||
|
|
||
| # 커밋 메시지 읽기 | ||
| commit_msg=$(cat $1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quote the parameter and add validation.
The unquoted $1 parameter can cause failures if the file path contains spaces or special characters. Additionally, there's no check that the parameter was provided or that the file exists.
🔎 Proposed fix
+# 파일 경로 검증
+if [ -z "$1" ] || [ ! -f "$1" ]; then
+ echo "❌ 커밋 메시지 파일을 찾을 수 없습니다."
+ exit 1
+fi
+
# 커밋 메시지 읽기
-commit_msg=$(cat $1)
+commit_msg=$(cat "$1")Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In @.husky/commit-msg around line 4, The commit-msg hook reads the file into
commit_msg using an unquoted $1 which breaks on paths with spaces and lacks
validation; change the command to use the quoted parameter and add checks that
the parameter exists and the file is readable before reading: validate that $1
is set, that [ -r "$1" ] succeeds, log an error and exit non-zero if not, then
assign commit_msg by reading the quoted path (commit_msg=$(cat "$1")) to safely
handle spaces and special characters.
| fi | ||
|
|
||
| # commitlint 실행 | ||
| if npx --no -- commitlint --edit $1; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quote the parameter in commitlint command.
The unquoted $1 parameter can cause commitlint to fail if the file path contains spaces or special characters.
🔎 Proposed fix
# commitlint 실행
-if npx --no -- commitlint --edit $1; then
+if npx --no -- commitlint --edit "$1"; then
echo "✅ 커밋 메시지가 규칙에 맞습니다."
exit 0
else📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if npx --no -- commitlint --edit $1; then | |
| if npx --no -- commitlint --edit "$1"; then | |
| echo "✅ 커밋 메시지가 규칙에 맞습니다." | |
| exit 0 | |
| else |
🤖 Prompt for AI Agents
In @.husky/commit-msg around line 15, The commitlint invocation uses an unquoted
parameter $1 which can break when the commit message file path contains spaces
or special characters; update the command in the .husky/commit-msg hook that
calls commitlint (the line starting with "if npx --no -- commitlint --edit $1;
then") to quote the parameter (use "$1") so the path is passed as a single
argument to commitlint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI Agents
In @.coderabbit.yaml:
- Around line 14-16: Remove the duplicate YAML key by keeping only one
definition of high_level_summary_placeholder; either delete the later occurrence
(the simpler default at line 24) to retain your custom Korean multi-line
placeholder (the block starting with "@coderabbitai summary"), or replace the
first multi-line block with the single-line default — ensure only one
high_level_summary_placeholder entry remains in the file.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.coderabbit.yaml
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:00:01.926Z
Learning: This project uses svgr for automatic SVG to React component conversion. Running `npm run svgr` automatically converts all svgr files to React component format and handles camelCase conversion for SVG attributes (e.g., stroke-width → strokeWidth).
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 2
File: src/components/Header/StudentHeader.tsx:10-10
Timestamp: 2025-07-13T00:27:31.464Z
Learning: Using TypeScript interfaces for React component props (like StudentHeaderProps) provides clear structure, improves readability, and makes components more maintainable and extensible for future development.
Learnt from: suminb99
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/assets/svg/ChatIcon.tsx:14-14
Timestamp: 2025-07-16T13:14:38.834Z
Learning: In this project, the svgr workflow requires placing original SVG files in the `public/svg` folder first, then running `npm run svgr` command to generate converted TSX files in the `src/assets/svg` folder according to the root configuration.
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 6
File: src/App.tsx:6-11
Timestamp: 2025-07-16T12:33:43.867Z
Learning: JiiminHa prefers hierarchical routing structure with role-based path organization: common routes at root level (/), student-specific routes under /student prefix, and admin-specific routes under /admin prefix, using nested routes with a shared Layout component for consistent UI patterns.
Learnt from: JiiminHa
Repo: 2025-snowCode/snowCode-Client PR: 2
File: src/components/Header/StudentHeader.tsx:6-18
Timestamp: 2025-07-13T00:25:00.538Z
Learning: User JiiminHa prefers using semantic HTML tags over excessive div usage for better code structure and accessibility in React components.
🪛 YAMLlint (1.37.1)
.coderabbit.yaml
[error] 24-24: duplication of key "high_level_summary_placeholder" in mapping
(key-duplicates)
🔇 Additional comments (1)
.coderabbit.yaml (1)
10-115: Configuration aligns well with project standards.The path-specific review instructions are comprehensive and well-aligned with the learnings retrieved from prior PRs. Korean-language tone instructions, hierarchical component/hook/TypeScript conventions, and auto-review settings with appropriate base branches and tool integrations are clearly defined.
| high_level_summary_placeholder: | | ||
| @coderabbitai summary | ||
| (졸업작품 평가 기준: 구조 / 타입 안정성 / 접근성 관점 요약) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix duplicate YAML key high_level_summary_placeholder.
The configuration defines high_level_summary_placeholder twice (lines 14-16 and line 24), which is invalid YAML and will cause a parsing error. The schema allows only one definition per key.
Line 24 appears to be a duplicate of the schema default. Remove it to retain your custom Korean-language placeholder (lines 14-16), or replace lines 14-16 with the simpler line 24 value if the customization is unintended.
🔎 Proposed fix: Remove line 24
abort_on_close: true
- high_level_summary_placeholder: '@coderabbitai summary'
collapse_walkthrough: trueAlso applies to: 24-24
🤖 Prompt for AI Agents
In @.coderabbit.yaml around lines 14 - 16, Remove the duplicate YAML key by
keeping only one definition of high_level_summary_placeholder; either delete the
later occurrence (the simpler default at line 24) to retain your custom Korean
multi-line placeholder (the block starting with "@coderabbitai summary"), or
replace the first multi-line block with the single-line default — ensure only
one high_level_summary_placeholder entry remains in the file.
|
|
|
PR 확인했습니다! 수고하셨어요 👍 |
|
@JiiminHa PR 머지 부탁드려요! |
⚙️ Related ISSUE Number
close #13
📄 Work Description
1. 자산 및 아이콘 관리
src/assets/svg폴더 내의 모든 SVG 리액트 컴포넌트 파일과index.ts의 export 문을 삭제하여 불필요하거나 중복된 코드를 제거했습니다.AssignmentCard.tsx등에서 SVG를 가져올 때,public/svg경로에서?react접미사를 사용하여 리액트 컴포넌트처럼 직접 임포트하도록 수정했습니다.2. 라우팅 및 페이지 구조
App.tsx에서 임포트 경로의 대소문자 표기를 통일하고, 라우트 경로(path)에서 선행 슬래시(/)를 제거하여 유지보수성을 높였습니다.3. 개발 도구(Tooling)
prettier와prettier-plugin-tailwindcss를 개발 의존성(dev dependency)으로 추가했습니다. 이를 통해 일관된 코드 스타일을 유지하고, 특히 Tailwind CSS 클래스 정렬을 자동화했습니다.4. 컴포넌트 개선
AssignmentFormLayout컴포넌트에titleExtra속성(prop)을 추가했습니다. 이를 통해 제목 옆에 버튼이나 아이콘 등 추가적인 요소를 유연하게 배치할 수 있습니다.📷 Screenshot
💬 To Reviewers
🔗 Reference
Summary by CodeRabbit
New Features
Improvements
Chores
✏️ Tip: You can customize this high-level summary in your review settings.