Skip to content
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

[Feat] LogPage, HistoryPage 퍼블리싱 및 리스트 컴포넌트 작업 #47

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from

Conversation

nanafromjeju
Copy link
Collaborator

@nanafromjeju nanafromjeju commented Jan 8, 2025

🚀 풀 리퀘스트 제안

closes #36
closes #37

📋 작업 내용

차량 리스트 컴포넌트 구현 및 구조 변경

  • ListHeader, ListItem 컴포넌트 생성
  • VehicleList 페이지 경로 삭제

페이지 퍼블리싱 및 스타일링

  • LogPageHistoryPage 레이아웃 퍼블리싱
  • 공통 컴포넌트 SquareButton 패딩값 수정
  • theme.cssopacity 상수 추가 및 컴포넌트 적용

데이터 처리

  • 각 페이지별 mockData 추가
  • 리스트 렌더링을 위한 map 함수

🔧 변경 사항

  • 💡 비즈니스 로직 (src/, app/ 등)
  • 📦 의존성 (package.json)
  • 📃 문서 (README.md 등)
  • 🔥 삭제된 파일/코드
  • ⚙️ 설정 파일 (.env, .gitignore 등)

📸 스크린샷

2025-01-094 00 59-ezgif com-video-to-gif-converter

📄 기타

  • 페이지네이션 기능은 추후 추가 예정
  • API 연동 시 mockData 부분 실제 데이터로 교체 필요

💻 코드 설명

🌟 ListHeader를 하나의 컴포넌트가 아닌 두개로 분리하고 하드코딩한 이유:

  • 정적 텍스트만 있는 단순한 헤더 컴포넌트로, props나 조건문으로 관리하는 것이 오히려 복잡도를 높일 수 있고, 수정 시 여러 부분을 확인해야 할 수 있어 분리하였습니다. (불필요한 추상화보다는 명확하고 단순한 구조가 더 도움이 될 것 같다는 생각에 분리하여 사용했습니다!)

🌟 ListItem span을 사용한 이유:

  1. 각 데이터 항목들(vehicleNumber, department 등)은 inline 요소로 표시되어야 하는 텍스트 콘텐츠 = span은 기본적으로 inline 요소이므로 텍스트를 표현하는데 적합하다고 판단했습니다.
  1. 데이터의 각 열은 독립적인 리스트 아이템이라기보다는 하나의 행을 구성하는 데이터 셀이므로, ul/li보다는 span이 의미적으로 더 적절하다고 생각했습니다. (l/li는 세로로 나열되는 독립적인 목록 항목을 표현할 때 적합)
  1. div 대신 span을 사용한 이유는, div는 block 레벨 요소이고 불필요한 추가 공간을 만들 수 있는 반면, span은 필요한 만큼만 공간을 차지하면서 grid 레이아웃 내에서 더 자연스럽게 정렬될 수 있기 때문입니다.

🖱️ Commits 참고

리베이스를 잘못해서 커밋이 뒤섞이는 이슈 발생.. 커밋단위는 전에 올렸던거 참고해주세요:)

스크린샷 2025-01-09 오전 11 40 24

📍 2024/01/09 수정내용

기존에 설계했던 그림은 두 개의 컴포넌트를 하나의 컴포넌트로 만들어 사용하고 싶었는데
능력+지식 부족으로 두 개의 컴포넌트를 하나에 구겨 넣지도 못하는(?) 설계가 되어버렸네요🤯
ListItem 컴포넌트를 각각 페이지의 컴포넌트로 분리하고,
VehicleLogModelVehicleHistoryModel를 생성하여 types 폴더로 분리했습니다.

📍 2024/01/10 수정내용

🌟 드디어 ListHeader 컴포넌트를 하나로 통일했습니다:)

🌟 ListItem 컴포넌트는 변경사항X

구조 분해 할당 사용 이유:

  1. 코드가 더 명시적이고 읽기 쉬움 (각 필드가 어떤 데이터인지 바로 알 수 있음)
  2. TypeScript의 타입 체크의 정확도가 높다
  3. 각 필드별로 다른 스타일이나 추가 로직을 적용하기 쉬움

배열로 변환하여 map을 사용하는 방식:

코드는 더 짧아지지만 각 항목이 어떤 데이터인지 파악하기 어렵고
현재와 같이 필드가 명확하고 각각의 의미가 중요한 경우에는 구조 분해 할당 방식이 적절하다고 판단했습니다!

------------------------------------------------------

------------------------------------------------------
------------------------------------------------------

------------------------------------------------------
@nanafromjeju nanafromjeju added ✨ Feat 새로운 기능 추가 작업 🎨 Design 퍼블리싱 및 레이아웃 등 화면을 구현하는 작업 labels Jan 8, 2025
@nanafromjeju nanafromjeju added this to the 화면 UI 구현 milestone Jan 8, 2025
@nanafromjeju nanafromjeju self-assigned this Jan 8, 2025
------------------------------------------------------

------------------------------------------------------
------------------------------------------------------

------------------------------------------------------
------------------------------------------------------

------------------------------------------------------
Comment on lines 6 to 14
<span className={styles.headerTitle}>차량번호</span>
<span className={styles.headerTitle}>부서명</span>
<span className={styles.headerTitle}>이름</span>
<span className={styles.headerTitle}>운행일수</span>
<span className={styles.headerTitle}>평균운행거리</span>
<span className={styles.headerTitle}>평균운행시간</span>
<span className={styles.headerTitle}>총운행거리</span>
<span className={styles.headerTitle}>운행률</span>
<span className={styles.headerIcon}>icon</span>
Copy link
Collaborator

Choose a reason for hiding this comment

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

span 태그의 경우, 인라인 요소이라 구조적 레이아웃에는 div 태그가 더 적절해보입니다.
PR에 작성해주신 내용을 보니, 이 부분은 선택적으로 하셔도 좋을 것 같습니다:)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

span보다는 div가 구조적으로 더 명확한 것 같네요! 수정하겠습니다:)

export const headerIcon = style({
width: '24px',
height: '24px',
visibility: 'hidden',
Copy link
Collaborator

Choose a reason for hiding this comment

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

단순 공간을 위해 콘텐츠를 작성하고 visibility: 'hidden'를 사용하기 보다, <div />와 같이 사용해보는 방법도 있습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

오오 굿굿

Comment on lines 5 to 7
interface HistoryItemProps {
data: VehicleHistoryModel
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

인터페이스명이 현재 컨벤션대로 되어있지 않습니다.
컴포넌트명 + Props이므로, ListItemProps가 적절해보입니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

...정신 차릴게요!

<span className={styles.itemContent}>{averageDrivingTime}분</span>
<span className={styles.itemContent}>{totalDrivingDistance}km</span>
<span className={styles.itemContent}>{drivingRate}%</span>
<div className={styles.icon}>{icon}</div>
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기서 div를 사용하신 것과 같이 위 헤더에서도 일관성있게 맞추는 것이 좋아보입니다:)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

div통일 절대 지켜

Comment on lines 137 to 138
<div className={styles.componentsWrapper}>
<div className={styles.searchInputWrapper}>
Copy link
Collaborator

Choose a reason for hiding this comment

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

div가 중첩이 되어있는데 componentWrapper와 searchInputWrapper를 구분하신 이유가 있으실까요?

Copy link
Collaborator Author

@nanafromjeju nanafromjeju Jan 10, 2025

Choose a reason for hiding this comment

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

LogPage랑 헷갈렸습니다..! 이 부분은 컴포넌트로 따로 만들어 관리하도록 하겠습니다!

Comment on lines 143 to 148
<div className={styles.listWrapper}>
<ListHeader />
{mockHistoryData.map((history) => (
<ListItem key={history.id} data={history} />
))}
</div>
Copy link
Collaborator

Choose a reason for hiding this comment

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

페이지에서 독립된 컴포넌트로 제작해보는 것도 좋아보입니다. 물론 선택입니다:)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

굿.. 지저분하게 느껴진다면 추후 컴포넌트로 제작하도록 하겠습니다!


import * as styles from './styles.css'

interface ListItemProps {
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기처럼 위 History도 컨벤션대로 수정해주세요~

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

넵!

Comment on lines 29 to 38
<div className={styles.componentsWrapper}>
<div className={styles.buttonWrapper}>
<RoundButton color='secondary' onClick={() => {}} size='small'>
등록
</RoundButton>
</div>
<div className={styles.searchInputWrapper}>
<SearchInput icon='/icons/search-icon.svg' />
</div>
</div>
Copy link
Collaborator

Choose a reason for hiding this comment

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

버튼과 인풋의 wrapper를 생성해 각각 레이아웃을 구성하기 보다, 두 개를 하나의 레이아웃으로 묶어 위치를 조정하시는 게 더 편하실 겁니다. 두 개를 묶은 레이아웃을 position: absolute 그리고 그 안에서 displex: flexgap으로 스타일링해보심 좋을 것 같아요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

CSS의 신..ㄷㄷ

@@ -13,7 +13,7 @@ export const shape = styleVariants({
[BADGE_SHAPE.RECTANGLE]: {
paddingLeft: '12px',
paddingRight: '12px',
fontSize: styles.fontSizes.small,
fontSize: styles.fontSizes.medium,
Copy link
Collaborator

Choose a reason for hiding this comment

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

기본 폰트가 16px이므로, 해당 내용은 삭제해도 좋을 것 같습니다:)

Copy link
Collaborator Author

@nanafromjeju nanafromjeju Jan 10, 2025

Choose a reason for hiding this comment

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

네에🐰🎀

Comment on lines 24 to 35
small: {
width: '76px',
height: '48px',
backgroundColor: styles.colors.white,
backgroundColor: styles.colors.primary,
border: `1px solid ${styles.colors.gray[200]}`,
boxShadow: `0px 4px 4px 0px ${styles.colors.shadow[100]}`,
color: styles.colors.white,
},
large: {
color: styles.colors.primary,
height: '60px',
},
},
color: {
primary: {
color: styles.colors.primary,
},
secondary: {
color: styles.colors.black,
padding: '16px 24px',
Copy link
Collaborator

Choose a reason for hiding this comment

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

size로 구분하신 스타일에 color 스타일링이 들어가고 있습니다. 이는 위 color로 구분한 것과 같이 쓸 때 문제가 될 수도 있다고 생각합니다. 만약 각각 디자인 버튼을 구분하고 싶으시면 recipe보다 styleVariant로 작성하시면 조금 더 편하실 수도 있어요:)

Copy link
Collaborator Author

@nanafromjeju nanafromjeju Jan 10, 2025

Choose a reason for hiding this comment

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

아직 vanilla extract가 익숙하지 않아 recipestyleVariant의 차이점을 잘 몰랐는데 덕분에 어떻게 구분하면 좋을지 알게 됐네요! 감사합니다!

------------------------------------------------------

------------------------------------------------------
- 기존에 분리되어 있던 ListHeader 컴포넌트를 하나로 병합
- headerTitles props로 헤더 제목 리스트를 받도록 개선
- 컴포넌트 재사용성 향상 및 코드 중복 제거
------------------------------------------------------

------------------------------------------------------
------------------------------------------------------

------------------------------------------------------
------------------------------------------------------

------------------------------------------------------
------------------------------------------------------

------------------------------------------------------
- props로 전달받던 icon을 컴포넌트 내부로 이동
- 컴포넌트 구조 단순화
------------------------------------------------------

------------------------------------------------------
------------------------------------------------------

------------------------------------------------------
------------------------------------------------------

------------------------------------------------------
Copy link
Collaborator

@red-dev-Mark red-dev-Mark left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎨 Design 퍼블리싱 및 레이아웃 등 화면을 구현하는 작업 ✨ Feat 새로운 기능 추가 작업
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Design] 운행목록 페이지 퍼블리싱 [Feat] ListHeader, ListItem 페이지 컴포넌트
2 participants