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
6 changes: 3 additions & 3 deletions src/app/(landing)/class/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ export default function ClassDetailPage({
const viewerStatusLabel = getCourseViewerStatusLabel(courseDetail);
const ctaLabel = (() => {
if (createCourseFreeEnrollment.isPending) return '등록 중...';
if (canFreeEnrollFromDetail) return '무료 코스 시작하기';
if (isCoursePaidEnrolled(courseDetail)) return '학습하러 가기';
if (isCourseFreeEnrolled(courseDetail)) return '학습 계속하기';
if (canFreeEnrollFromDetail) return '무료 코스 시작하기';
if (hasFullAccessFromDetail) return '관리자 권한으로 보기';
return '무료 코스 시작하기';
return undefined;
})();
const { data: myGiftEmail } = useGetMyGiftEmail({
enabled: isAuthenticated && !!courseDetail?.isPaidEnrolled,
Expand Down Expand Up @@ -144,8 +144,8 @@ export default function ClassDetailPage({
showToast('무료 코스 등록이 완료되었어요.');
} catch {
showToast('무료 코스 등록 중 오류가 발생했어요.', 'error');
return;
}
return;
}
router.push(learningHomeHref);
}
Expand Down
36 changes: 19 additions & 17 deletions src/components/pages/class/class-detail-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const LoginModal = dynamic(
interface ClassDetailSidebarProps {
courseDetail: CourseDetailResponse | undefined;
isAuthenticated: boolean;
ctaLabel: string;
ctaLabel: string | undefined;
viewerStatusLabel: string | undefined;
isEnrolling: boolean;
onShare: () => void;
Expand Down Expand Up @@ -135,27 +135,29 @@ export function ClassDetailSidebar({
>
공유하기
</button>
{isAuthenticated ? (
<button
type="button"
onClick={onStartCourse}
disabled={isEnrolling}
className="flex h-550 w-full items-center justify-center rounded-100 bg-background-brand-default font-designer-14b text-text-inverse"
>
{ctaLabel}
</button>
) : (
<LoginModal
openTrigger={
{isAuthenticated
? ctaLabel && (
<button
type="button"
onClick={onStartCourse}
disabled={isEnrolling}
className="flex h-550 w-full items-center justify-center rounded-100 bg-background-brand-default font-designer-14b text-text-inverse"
>
무료 코스 시작하기
{ctaLabel}
</button>
}
/>
)}
)
: courseDetail?.canFreeEnroll === true && (
<LoginModal
openTrigger={
<button
type="button"
className="flex h-550 w-full items-center justify-center rounded-100 bg-background-brand-default font-designer-14b text-text-inverse"
>
무료 코스 시작하기
</button>
}
/>
)}
</div>

{isAuthenticated && courseDetail?.isPaidEnrolled && (
Expand Down
13 changes: 12 additions & 1 deletion src/components/pages/class/course-viewer-status.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ describe('course viewer status helpers', () => {
);
});

it('shows free enrollment CTA solely from canFreeEnroll', () => {
const course = {
...baseCourse,
viewerStatus: 'ADMIN',
hasFullAccess: true,
canFreeEnroll: true,
isFreeEnrolled: true,
} satisfies CourseDetailResponse;

expect(canShowCourseFreeEnrollCta(course)).toBe(true);
});

it('ADMIN free enrollment keeps ADMIN status and becomes a real free learner', () => {
const course = {
...baseCourse,
Expand All @@ -58,7 +70,6 @@ describe('course viewer status helpers', () => {
} satisfies CourseDetailResponse;

expect(isCourseFreeEnrolled(course)).toBe(true);
expect(canShowCourseFreeEnrollCta(course)).toBe(false);
expect(getCourseViewerStatusLabel(course)).toBe('무료수강중');
});

Expand Down
20 changes: 4 additions & 16 deletions src/components/pages/class/course-viewer-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,21 @@ export function isAdminViewer(course?: CourseDetailResponse): boolean {
}

export function isCourseFreeEnrolled(course?: CourseDetailResponse): boolean {
return (
course?.isFreeEnrolled === true || course?.viewerStatus === 'FREE_ENROLLED'
);
return course?.isFreeEnrolled === true;
}

export function isCoursePaidEnrolled(course?: CourseDetailResponse): boolean {
return course?.isPaidEnrolled === true || course?.viewerStatus === 'PAID';
return course?.isPaidEnrolled === true;
}

export function hasCourseFullAccess(course?: CourseDetailResponse): boolean {
return (
course?.hasFullAccess === true ||
isAdminViewer(course) ||
isCoursePaidEnrolled(course)
);
return course?.hasFullAccess === true;
}

export function canShowCourseFreeEnrollCta(
course?: CourseDetailResponse,
): boolean {
if (course?.canFreeEnroll !== true) return false;
if (isCourseFreeEnrolled(course) || isCoursePaidEnrolled(course)) {
return false;
}
return (
course.viewerStatus === 'LOGIN_ONLY' || course.viewerStatus === 'ADMIN'
);
return course?.canFreeEnroll === true;
}

export function getCourseViewerStatusLabel(
Expand Down
Loading