-
Notifications
You must be signed in to change notification settings - Fork 1
[FEAT] 강사 마이페이지 퍼블리싱 #28
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
Changes from all commits
f94a6b5
d95062d
82fd0b0
e5d6258
9214d64
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,15 @@ | ||
| import { CommissionsHistorySection, MyInfoSection } from "@/widgets/instructor/my"; | ||
|
|
||
| const page = () => { | ||
| return <div>강사 마이페이지</div>; | ||
| return ( | ||
| <div className="mx-auto flex w-212.75 flex-col items-center pt-15"> | ||
| <h1 className="text-title2-sb w-full pb-10 text-left text-black">마이페이지</h1> | ||
| <div className="flex flex-col gap-8"> | ||
| <MyInfoSection /> | ||
| <CommissionsHistorySection /> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default page; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| export type { CommissionHistoryItem } from "@/features/instructor/my/model/my"; | ||
| export { | ||
| CATEGORY_BADGE_MAP, | ||
| commissionHistoryData, | ||
| PLAN_DISPLAY_MAP, | ||
| } from "@/features/instructor/my/model/my"; | ||
| export { default as CommissionsHeader } from "@/features/instructor/my/ui/CommissionsHeader"; | ||
| export { default as CommissionsHistoryRow } from "@/features/instructor/my/ui/CommissionsHistoryRow"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| import { BadgeVariant } from "@/shared/ui/Badge"; | ||
|
|
||
| // [강사] 마이페이지 외주 내역 조회 | ||
| export type CommissionHistoryItem = { | ||
| commissionId: number; | ||
| category: string; | ||
| title: string; | ||
| createdAt: string; | ||
| plan: "BASIC" | "PLUS" | "MAX"; | ||
| totalAmount: number; | ||
| status: "COMPLETED" | "ONGOING"; | ||
| }; | ||
|
|
||
| export const PLAN_DISPLAY_MAP: Record<CommissionHistoryItem["plan"], string> = { | ||
| BASIC: "기본", | ||
| PLUS: "플러스", | ||
| MAX: "맥스", | ||
| }; | ||
|
|
||
| export const CATEGORY_BADGE_MAP: Record<string, BadgeVariant> = { | ||
| FLYER_TEXTBOOK_COVER_INNER: "교재", | ||
| }; | ||
|
|
||
| export const commissionHistoryData: CommissionHistoryItem[] = [ | ||
| { | ||
| commissionId: 1, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "YMB 영어교재 표지디자인 외주", | ||
| createdAt: "2025-05-05", | ||
| plan: "BASIC", | ||
| totalAmount: 400000, | ||
| status: "COMPLETED", | ||
| }, | ||
| { | ||
| commissionId: 2, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "해커스톡 왕초보 영어 기초 문법편 표지디자인 외주", | ||
| createdAt: "2025-04-18", | ||
| plan: "PLUS", | ||
| totalAmount: 480000, | ||
| status: "COMPLETED", | ||
| }, | ||
| { | ||
| commissionId: 3, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "토익 실전 모의고사 Part 5·6 표지디자인 외주", | ||
| createdAt: "2025-03-24", | ||
| plan: "MAX", | ||
| totalAmount: 560000, | ||
| status: "COMPLETED", | ||
| }, | ||
| { | ||
| commissionId: 4, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "수능 영어 독해 빈칸추론 완성 표지디자인 외주", | ||
| createdAt: "2025-03-02", | ||
| plan: "BASIC", | ||
| totalAmount: 400000, | ||
| status: "COMPLETED", | ||
| }, | ||
| { | ||
| commissionId: 5, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "중학 수학 개념서 1학기 과정 표지디자인 외주", | ||
| createdAt: "2025-02-14", | ||
| plan: "PLUS", | ||
| totalAmount: 480000, | ||
| status: "ONGOING", | ||
| }, | ||
| { | ||
| commissionId: 6, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "고등 국어 문학 현대시 집중 표지디자인 외주", | ||
| createdAt: "2025-01-28", | ||
| plan: "MAX", | ||
| totalAmount: 560000, | ||
| status: "ONGOING", | ||
| }, | ||
| { | ||
| commissionId: 7, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "중등 과학 탐구 물질과 에너지 표지디자인 외주", | ||
| createdAt: "2024-12-19", | ||
| plan: "BASIC", | ||
| totalAmount: 400000, | ||
| status: "COMPLETED", | ||
| }, | ||
| { | ||
| commissionId: 8, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "고등 수학 II 미적분 집중 완성 표지디자인 외주", | ||
| createdAt: "2024-11-30", | ||
| plan: "PLUS", | ||
| totalAmount: 480000, | ||
| status: "COMPLETED", | ||
| }, | ||
| { | ||
| commissionId: 9, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "초등 사회 한국사 인물편 표지디자인 외주", | ||
| createdAt: "2024-11-12", | ||
| plan: "BASIC", | ||
| totalAmount: 400000, | ||
| status: "ONGOING", | ||
| }, | ||
| { | ||
| commissionId: 10, | ||
| category: "FLYER_TEXTBOOK_COVER_INNER", | ||
| title: "고등 영어 듣기평가 모의고사 표지디자인 외주", | ||
| createdAt: "2024-10-27", | ||
| plan: "MAX", | ||
| totalAmount: 560000, | ||
| status: "COMPLETED", | ||
| }, | ||
| ]; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| const CommissionsHeader = () => { | ||
| return ( | ||
| <div className="text-gray-70 text-caption1-r border-b-gray-20 flex w-full shrink-0 flex-row justify-between border-b px-3 py-2"> | ||
| <p>외주</p> | ||
| <div className="flex gap-16"> | ||
| <p className="w-25">외주 신청 일자</p> | ||
| <p className="w-14">플랜</p> | ||
| <p className="w-25">금액</p> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default CommissionsHeader; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { | ||
| CATEGORY_BADGE_MAP, | ||
| CommissionHistoryItem, | ||
| PLAN_DISPLAY_MAP, | ||
| } from "@/features/instructor/my/model/my"; | ||
| import { ArrowRightIcon } from "@/shared/assets/icons"; | ||
| import Badge from "@/shared/ui/Badge"; | ||
|
|
||
| const CommissionsHistoryRow = ({ item }: { item: CommissionHistoryItem }) => { | ||
| const { category, title, createdAt, plan, totalAmount } = item; | ||
|
|
||
| return ( | ||
| <div className="hover:bg-gray-5 border-b-gray-20 flex h-19.25 w-full shrink-0 cursor-pointer items-center justify-between border-b bg-white px-3 py-5 transition-colors duration-150"> | ||
| <div className="flex flex-row gap-6"> | ||
| <Badge variant={CATEGORY_BADGE_MAP[category] ?? "교재"} /> | ||
| <div className="text-gray-90 flex flex-row items-center gap-1"> | ||
| <p className="text-heading3-m max-w-70 truncate">{title}</p> | ||
| <ArrowRightIcon className="size-6" /> | ||
| </div> | ||
| </div> | ||
| <div className="flex flex-row items-center gap-16"> | ||
| <p className="text-gray-70 text-heading2-m w-25">{createdAt.replaceAll("-", ".")}</p> | ||
| <p className="text-gray-70 text-heading2-m w-14">{PLAN_DISPLAY_MAP[plan]}</p> | ||
| <p className="text-gray-90 text-heading3-m w-25">{totalAmount.toLocaleString()}원</p> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default CommissionsHistoryRow; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const COMMISSION_HISTORY_ITEMS_PER_PAGE = 3; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| export { default as CommissionsHistorySection } from "@/widgets/instructor/my/ui/CommissionsHistorySection"; | ||
| export { default as MyInfoSection } from "@/widgets/instructor/my/ui/MyInfoSection"; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,18 @@ | ||||||||||||||||||
| // [강사] 마이페이지 본인 정보 + 통계 조회 | ||||||||||||||||||
| export type MyInfo = { | ||||||||||||||||||
| name: string; | ||||||||||||||||||
| profileImageUrl: string; | ||||||||||||||||||
| stats: { | ||||||||||||||||||
| totalCommissionCount: number; | ||||||||||||||||||
| ongoingCommissionCount: number; | ||||||||||||||||||
| }; | ||||||||||||||||||
| }; | ||||||||||||||||||
|
|
||||||||||||||||||
| export const myInfoData: MyInfo = { | ||||||||||||||||||
| name: "고다현", | ||||||||||||||||||
| profileImageUrl: "", | ||||||||||||||||||
| stats: { | ||||||||||||||||||
| totalCommissionCount: 5, | ||||||||||||||||||
| ongoingCommissionCount: 5, | ||||||||||||||||||
| }, | ||||||||||||||||||
|
Comment on lines
+14
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 통계 목데이터가 외주 내역 데이터와 불일치합니다. 현재 목데이터 기준으로 외주 내역은 총 10건/진행중 3건인데, 여기서는 5/5로 노출됩니다. 동일 페이지에서 함께 보여주므로 수치를 맞춰두는 게 안전합니다. 제안 diff stats: {
- totalCommissionCount: 5,
- ongoingCommissionCount: 5,
+ totalCommissionCount: 10,
+ ongoingCommissionCount: 3,
},📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. mockData임 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🐇 ✏️ Learnings added
🧠 Learnings used |
||||||||||||||||||
| }; | ||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| "use client"; | ||
|
|
||
| import { | ||
| commissionHistoryData, | ||
| CommissionsHeader, | ||
| CommissionsHistoryRow, | ||
| } from "@/features/instructor/my"; | ||
| import { NextButton, PrevButton } from "@/shared/assets/icons"; | ||
| import usePagination from "@/shared/lib/hooks/usePagination"; | ||
| import PageIndicator from "@/shared/ui/PageIndicator"; | ||
| import { COMMISSION_HISTORY_ITEMS_PER_PAGE } from "@/widgets/instructor/my/config/my"; | ||
|
|
||
| const CommissionsHistorySection = () => { | ||
| const { current, totalPages, pageItems, handlePrev, handleNext } = usePagination( | ||
| commissionHistoryData, | ||
| COMMISSION_HISTORY_ITEMS_PER_PAGE, | ||
| ); | ||
|
|
||
| return ( | ||
| <div className="rounded-12 flex h-auto w-212.75 flex-col gap-6 bg-white p-6"> | ||
| <h1 className="text-heading1-sb text-black">외주 내역 확인</h1> | ||
| <div className="flex h-66.25 flex-col"> | ||
| <CommissionsHeader /> | ||
| {pageItems.map(item => ( | ||
| <CommissionsHistoryRow key={item.commissionId} item={item} /> | ||
| ))} | ||
| </div> | ||
| <div className="flex flex-row items-center justify-center gap-8"> | ||
| <PrevButton className="size-12 cursor-pointer" onClick={handlePrev} /> | ||
| <PageIndicator total={totalPages} current={current} variant="my" /> | ||
| <NextButton className="size-12 cursor-pointer" onClick={handleNext} /> | ||
|
Comment on lines
+29
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아이콘을 직접 클릭 요소로 쓰지 말고 버튼 시맨틱으로 감싸주세요. Line 29, Line 31은 키보드 포커스/스크린리더 접근성이 보장되지 않아 페이지네이션 조작이 막힐 수 있습니다. 수정 예시- <div className="flex flex-row items-center justify-center gap-8">
- <PrevButton className="size-12 cursor-pointer" onClick={handlePrev} />
- <PageIndicator total={totalPages} current={current} variant="my" />
- <NextButton className="size-12 cursor-pointer" onClick={handleNext} />
- </div>
+ <div className="flex flex-row items-center justify-center gap-8">
+ <button
+ type="button"
+ onClick={handlePrev}
+ aria-label="이전 페이지"
+ disabled={current === 0}
+ className="cursor-pointer disabled:cursor-not-allowed disabled:opacity-40"
+ >
+ <PrevButton className="size-12" />
+ </button>
+ <PageIndicator total={totalPages} current={current} variant="my" />
+ <button
+ type="button"
+ onClick={handleNext}
+ aria-label="다음 페이지"
+ disabled={current >= totalPages - 1}
+ className="cursor-pointer disabled:cursor-not-allowed disabled:opacity-40"
+ >
+ <NextButton className="size-12" />
+ </button>
+ </div>🤖 Prompt for AI Agents |
||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default CommissionsHistorySection; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { ProfileCircleIcon } from "@/shared/assets/icons"; | ||
| import { myInfoData } from "@/widgets/instructor/my/model/my"; | ||
|
|
||
| const MyInfoSection = () => { | ||
| const { name, stats } = myInfoData; | ||
|
|
||
| return ( | ||
| <div className="w-212.75"> | ||
| <div className="flex flex-row items-center gap-4 rounded-t-xl bg-purple-50 px-6 py-5"> | ||
| <ProfileCircleIcon className="size-8 text-white" /> | ||
| <p className="text-heading2-sb text-white">{name}</p> | ||
| </div> | ||
| <div className="rounded-b-xl bg-white px-30 py-6"> | ||
| <div className="flex justify-between"> | ||
| <div className="flex w-fit flex-row gap-14 px-20 whitespace-nowrap"> | ||
| <p className="text-gray-70 text-body2-m">외주 이용 횟수</p> | ||
| <p className="text-gray-80 text-heading3-sb">{stats.totalCommissionCount}회</p> | ||
| </div> | ||
| <div className="border-gray-30 w-1 border-l" /> | ||
| <div className="flex w-fit flex-row gap-14 px-20 whitespace-nowrap"> | ||
| <p className="text-gray-70 text-body2-m">진행 중인 외주 건수</p> | ||
| <p className="text-gray-80 text-heading3-sb">{stats.ongoingCommissionCount}건</p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default MyInfoSection; |
Uh oh!
There was an error while loading. Please reload this page.
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.
클릭 가능한 UI처럼 보이지만 실제 동작이 없습니다.
cursor-pointer와 화살표 아이콘으로 이동 가능한 행처럼 보이는데, 현재는 클릭 동작이 없어 사용자에게 오해를 줍니다. 상세 이동을 아직 연결하지 않았다면 인터랙티브 스타일을 제거하거나, 지금 연결할 수 있다면Link/button으로 semantics까지 맞춰주세요.제안 diff (미구현 상태 유지 시)
🤖 Prompt for AI Agents
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.
추후 연결 예정 - PR 기타 사항 부분에 작성되어있음
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.
@waldls, PR 기타 사항에 명시되어 있군요 — 확인했습니다. 추후 상세 페이지 이동을 연결할 때div대신Link또는button으로 교체하고 키보드 접근성도 함께 맞춰주시면 좋을 것 같습니다.혹시 이 작업을 추적하기 위한 별도 이슈를 생성해 드릴까요?
🧠 Learnings used