Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 38 additions & 23 deletions src/features/study/ui/today-study-card.tsx
Copy link
Contributor

Choose a reason for hiding this comment

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

추가적으로 제안드리고 싶은 부분은
공통 구조는 한 번만 작성하고, 바뀌는 값만 조건 분기하는 쪽으로 가는 건 어떠신가요?

<InfoBox
  label={isInterviewee ? '면접관' : '면접자'}
  value={
    <div className="border-border-default bg-background-default flex items-center gap-100 rounded-full border px-100 py-50">
      <UserProfileModal
        memberId={
          isInterviewee
            ? todayStudyData.interviewerId
            : todayStudyData.intervieweeId
        }
...

이런 식으로 바뀌는 값만 조건 분기해서 작성하면 이후 div 클래스나 스타일이 바뀌는 경우 한 곳만 고쳐도 되어 조금 더 유지보수에 좋아질 것 같아 제안드립니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

좋습니다. 테스트 해보면서 작업할 수 있는 상황이 아니다보니 보수적으로 진행했는데, 이 방식이 더 맞다고 생각합니다. 수아님까지 확인하시고 나면 이 부분까지 반영해볼게요

Copy link
Contributor

Choose a reason for hiding this comment

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

저도 민주님이 제안해주신 방법 좋습니다!

Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
'use client';

import { useEffect, useState } from 'react';
import UserProfileModal from '@/features/my-page/ui/user-profile-modal';
import { getStatusBadge } from '@/features/study/ui/status-badge-map';
import { getCookie } from '@/shared/tanstack-query/cookie';
// TODO: FSD 의 import 바운더리를 넘어서 import 해야하는데,
// 해당 UI를 shared 등으로 빼던지 수정 필요
Comment on lines +7 to +8
Copy link
Contributor

Choose a reason for hiding this comment

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

혹시 이 주석에 대해 다시 한 번 설명해주실 수 있을까요?!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

FSD 구조에서 서로다른 features 에서는 import 하는 것이 맞지 않는 것 같은데, 현재 feature/study 에서 feature/my-page 에서 컴포넌트를 불러오고 있어서요. 이 부분 문제가 되는 것 같아서 추후에 작업해야하지 않을까 해서 적어뒀습니다.

제가 잘못 알고 있다면 정정해주셔도 괜찮아요!

Copy link
Contributor

Choose a reason for hiding this comment

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

연환님 말씀이 맞습니다! 그래서 예전에는 @x 세그먼트를 만들어서 거기서 cross import를 했었는데, 현재 fsd 공식문서에서 안보이네요 👀

import UserAvatar from '@/shared/ui/avatar';
import StudyDoneModal from './study-done-modal';
import StudyReadyModal from './study-ready-modal';
Expand All @@ -22,6 +25,18 @@ export default function TodayStudyCard({ studyDate }: { studyDate: string }) {

const isInterviewee = memberId === todayStudyData.intervieweeId;

const matchedUserId = isInterviewee
? todayStudyData.interviewerId
: todayStudyData.intervieweeId;

const matchedUserImage = isInterviewee
? todayStudyData.interviewerImage
: todayStudyData.intervieweeImage;

const matchedUsername = isInterviewee
? todayStudyData.interviewerName
: todayStudyData.intervieweeName;

return (
<section className="flex w-full flex-col gap-150">
<div className="mb-4 flex items-start justify-between">
Expand All @@ -35,26 +50,26 @@ export default function TodayStudyCard({ studyDate }: { studyDate: string }) {
</div>

<div className="mb-4 grid grid-cols-2 gap-100">
<InfoBox
label="스터디 조"
value={`${todayStudyData.studySpaceId} 조`}
/>
<InfoBox
label="면접자"
value={
<div className="border-border-default bg-background-default flex items-center gap-100 rounded-full border px-100 py-50">
<UserAvatar image={todayStudyData.interviewerImage} />
<span className="font-designer-14m">
{todayStudyData.interviewerName}
</span>
</div>
}
/>
<InfoBox label="오늘의 면접 주제" value={todayStudyData.subject} />
<InfoBox
label="진행 현황"
value={getStatusBadge(todayStudyData.progressStatus)}
/>
<InfoBox label="스터디 조">
{`${todayStudyData.studySpaceId} 조`}
</InfoBox>
<InfoBox label={isInterviewee ? '면접관' : '면접자'}>
<UserProfileModal
memberId={matchedUserId}
trigger={
<div className="border-border-default bg-background-default flex items-center gap-100 rounded-full border px-100 py-50">
<UserAvatar image={matchedUserImage} />
<span id="testuuiie" className="font-designer-14m">
{matchedUsername}
</span>
</div>
}
/>
</InfoBox>
<InfoBox label="오늘의 면접 주제">{todayStudyData.subject}</InfoBox>
<InfoBox label="진행 현황">
{getStatusBadge(todayStudyData.progressStatus ?? 'PENDING')}
</InfoBox>
</div>

<div className="rounded-100 bg-background-alternative flex flex-col gap-150 px-300 py-150">
Expand All @@ -66,15 +81,15 @@ export default function TodayStudyCard({ studyDate }: { studyDate: string }) {

function InfoBox({
label,
value,
children,
}: {
label: string;
value: React.ReactNode;
children: React.ReactNode;
}) {
return (
<div className="rounded-100 bg-background-alternative flex min-h-[64px] flex-row items-center justify-between gap-150 px-300 py-150">
<span className="font-designer-14r text-text-subtle">{label}</span>
<span className="font-designer-16m text-text-default">{value}</span>
<span className="font-designer-16m text-text-default">{children}</span>
</div>
);
}
Expand Down
8 changes: 5 additions & 3 deletions src/shared/ui/avatar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ interface UserAvatarProps {

export default function UserAvatar({
image,
alt = 'user image',
alt = 'user profile',
size = 32,
}: UserAvatarProps) {
ref,
...props
}: React.RefAttributes<HTMLSpanElement> & UserAvatarProps) {
return (
<Avatar style={{ width: size, height: size }}>
<Avatar {...props} ref={ref} style={{ width: size, height: size }}>
{image ? (
<AvatarImage src={image} alt={alt} />
) : (
Expand Down
4 changes: 4 additions & 0 deletions src/shared/ui/modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
DialogOverlay,
DialogPortal,
DialogTitle,
DialogDescription,
} from '@/shared/shadcn/ui/dialog';

function ModalRoot({
Expand Down Expand Up @@ -71,9 +72,11 @@ function ModalOverlay({
function ModalContent({
className,
children,
description = '',
...props
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
size?: 'small' | 'medium' | 'large';
description?: string;
}) {
const { size = 'small', ...rest } = props;

Expand Down Expand Up @@ -104,6 +107,7 @@ function ModalContent({
{...rest}
>
<div className="flex max-h-[90vh] flex-col">{children}</div>
<DialogDescription className="sr-only">{description}</DialogDescription>
</DialogPrimitive.Content>
);
}
Expand Down
Loading