diff --git a/src/components/common/modals/edit-homework-modal.tsx b/src/components/common/modals/edit-homework-modal.tsx index 3c95ba147..ce5f85576 100644 --- a/src/components/common/modals/edit-homework-modal.tsx +++ b/src/components/common/modals/edit-homework-modal.tsx @@ -9,10 +9,17 @@ import { Modal } from '@/components/common/ui/modal'; import { useEditHomework } from '@/hooks/queries/group-study-homework-api'; import { useToastStore } from '@/stores/use-toast-store'; +import { formatExternalLink } from '@/utils/format'; +import { isValidUrl } from '@/utils/validation'; const EditHomeworkFormSchema = z.object({ textContent: z.string().min(1, '과제 상세 내용을 입력해주세요.').max(1000), - attachmentLink: z.string().optional(), + attachmentLink: z + .string() + .optional() + .refine((val) => !val || isValidUrl(val), { + message: '올바른 URL 형식을 입력해주세요. (예: https://example.com)', + }), }); type EditHomeworkFormValues = z.infer; @@ -98,7 +105,11 @@ function EditHomeworkForm({ homeworkId, request: { textContent: values.textContent, - optionalSubmission: { link: values.attachmentLink }, + optionalSubmission: { + link: values.attachmentLink + ? formatExternalLink(values.attachmentLink) + : values.attachmentLink, + }, }, }, { @@ -127,7 +138,7 @@ function EditHomeworkForm({ label="과제 상세 내용" direction="vertical" required - maxCharCount={5000} + maxCharCount={1000} showCounterRight={false} > !val || isValidUrl(val), { + message: '올바른 URL 형식을 입력해주세요. (예: https://example.com)', + }), }); type SubmitHomeworkFormValues = z.infer; @@ -98,7 +105,11 @@ function SubmitHomeworkForm({ missionId, request: { textContent: values.textContent, - optionalSubmission: { link: values.attachmentLink }, + optionalSubmission: { + link: values.attachmentLink + ? formatExternalLink(values.attachmentLink) + : values.attachmentLink, + }, }, }, { diff --git a/src/components/contents/homework-detail-content.tsx b/src/components/contents/homework-detail-content.tsx index d00069237..d4b0f3fd3 100644 --- a/src/components/contents/homework-detail-content.tsx +++ b/src/components/contents/homework-detail-content.tsx @@ -17,6 +17,7 @@ import { } from '@/hooks/queries/peer-review-api'; import { useUserStore } from '@/stores/useUserStore'; +import { formatExternalLink } from '@/utils/format'; const ConfirmDeleteModal = dynamic( () => import('@/components/common/modals/confirm-delete-modal'), @@ -132,7 +133,9 @@ export default function HomeworkDetailContent({ 제출한 과제 diff --git a/src/components/hall-of-fame/mvp-team-card.tsx b/src/components/hall-of-fame/mvp-team-card.tsx index ee8863e51..b771fa1c5 100644 --- a/src/components/hall-of-fame/mvp-team-card.tsx +++ b/src/components/hall-of-fame/mvp-team-card.tsx @@ -7,6 +7,7 @@ import { cn } from '@/components/common/ui/(shadcn)/lib/utils'; import UserAvatar from '@/components/common/ui/avatar'; import Tooltip from '@/components/common/ui/tooltip'; import type { MVPTeam } from '@/types/one-to-one-study/hall-of-fame'; +import { formatExternalLink } from '@/utils/format'; interface MVPTeamCardProps { team: MVPTeam; @@ -19,12 +20,12 @@ export default function MVPTeamCard({ team, className }: MVPTeamCardProps) { return (
- +
( - + {i + 1} {link.title} diff --git a/src/components/lists/study-list-table.tsx b/src/components/lists/study-list-table.tsx index a896bc5c1..1dd4b209d 100644 --- a/src/components/lists/study-list-table.tsx +++ b/src/components/lists/study-list-table.tsx @@ -11,6 +11,7 @@ import { type DailyStudy, type GetDailyStudiesResponse, } from '@/types/api/schedule.types'; +import { formatExternalLink } from '@/utils/format'; import LinkIcon from 'public/icons/Link.svg'; const TABLE_HEADERS = [ @@ -61,7 +62,7 @@ function mapDailyStudyToDisplayData( '진행 상태': getStatusBadge(row.progressStatus), '참고 자료': row.link ? ( { diff --git a/src/components/schedule/today-study-card.tsx b/src/components/schedule/today-study-card.tsx index 945e9a086..8ad06700b 100644 --- a/src/components/schedule/today-study-card.tsx +++ b/src/components/schedule/today-study-card.tsx @@ -12,6 +12,7 @@ import { TUTORIAL_DAILY_STUDY_MOCK } from '@/config/tutorial-mock'; import { useAuthReady } from '@/features/auth/model/use-auth'; import { useDailyStudyDetailQuery } from '@/hooks/queries/use-interview-query'; import { DailyStudyDetail } from '@/types/api/interview.types'; +import { formatExternalLink } from '@/utils/format'; const StudyDoneModal = dynamic( () => import('@/components/common/modals/study-done-modal'), @@ -95,7 +96,7 @@ export default function TodayStudyCard({ description={ isInterviewee ? '당신은 지원자입니다.' : '당신은 면접관입니다.' } - className="mb-4" + className="mb-200" titleClassName="font-bold-h5" descriptionClassName="font-designer-14r" /> @@ -158,7 +159,7 @@ const renderFeedback = (

피드백

-
+
) { } function StudyLink({ link }: Pick) { + if (!link) return null; + return (
- 스터디 링크 + 스터디 링크 - +
{initial}
@@ -58,11 +61,12 @@ function RequestListCard({
diff --git a/src/features/study/one-to-one/history/ui/study-history-row.tsx b/src/features/study/one-to-one/history/ui/study-history-row.tsx index bda789a79..5cc2fb42c 100644 --- a/src/features/study/one-to-one/history/ui/study-history-row.tsx +++ b/src/features/study/one-to-one/history/ui/study-history-row.tsx @@ -12,6 +12,7 @@ import { import dynamic from 'next/dynamic'; import UserAvatar from '@/components/common/ui/avatar'; import { StudyHistoryItem } from '@/types/one-to-one-study/study-history'; +import { formatExternalLink } from '@/utils/format'; const UserProfileModal = dynamic( () => import('@/components/common/modals/user-profile-modal'), @@ -51,7 +52,7 @@ export const StudyHistoryRow = ({ item }: { item: StudyHistoryItem }) => { image={partner.profileImage || undefined} alt={partner.name} size={32} - className="h-8 w-8" + className="h-400 w-400" /> {partner.name} @@ -65,7 +66,7 @@ export const StudyHistoryRow = ({ item }: { item: StudyHistoryItem }) => { image={undefined} alt="상대방 정보 없음" size={32} - className="h-8 w-8 opacity-60" + className="h-400 w-400 opacity-60" /> 상대방 정보 없음
@@ -75,12 +76,12 @@ export const StudyHistoryRow = ({ item }: { item: StudyHistoryItem }) => { {/* 역할 */}
{item.role === 'INTERVIEWER' ? ( - + 면접자 ) : ( - + 지원자 @@ -92,12 +93,12 @@ export const StudyHistoryRow = ({ item }: { item: StudyHistoryItem }) => { {item.attendance === 'ATTENDED' ? ( - 역할수행 + 역할수행 ) : ( - 미진행 + 미진행 )}
@@ -107,12 +108,12 @@ export const StudyHistoryRow = ({ item }: { item: StudyHistoryItem }) => { {item.status === 'COMPLETED' ? ( - 완료 + 완료 ) : ( - 진행중 + 진행중 )}
@@ -121,7 +122,7 @@ export const StudyHistoryRow = ({ item }: { item: StudyHistoryItem }) => {
{item.link ? (