diff --git a/app/(my)/my-page/page.tsx b/app/(my)/my-page/page.tsx index d5b23f10..13ec9bfa 100644 --- a/app/(my)/my-page/page.tsx +++ b/app/(my)/my-page/page.tsx @@ -15,7 +15,11 @@ export default async function MyPage() { return (
- +
); diff --git a/next.config.ts b/next.config.ts index 108ea078..e40cb1e2 100644 --- a/next.config.ts +++ b/next.config.ts @@ -12,18 +12,18 @@ const nextConfig: NextConfig = { }, { protocol: 'https', - hostname: 'test-api.zeroone.it.kr', - pathname: '/profile-image/**', + hostname: 'lh3.googleusercontent.com', + pathname: '/**', // 구글 이미지 전체 허용 }, { protocol: 'https', - hostname: 'api.zeroone.it.kr', - pathname: '/profile-image/**', + hostname: 'test-api.zeroone.it.kr', + pathname: '/**', }, { protocol: 'https', - hostname: 'lh3.googleusercontent.com', - pathname: '/**', // 구글 이미지 전체 허용 + hostname: 'www.zeroone.it.kr', + pathname: '/**', }, ], }, diff --git a/package.json b/package.json index 4334a658..83f1931e 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@radix-ui/react-avatar": "^1.1.9", "@radix-ui/react-dialog": "^1.1.10", "@radix-ui/react-dropdown-menu": "^2.1.15", + "@radix-ui/react-progress": "^1.1.7", "@radix-ui/react-slot": "^1.2.2", "@radix-ui/react-switch": "^1.2.4", "@radix-ui/react-toggle": "^1.1.9", diff --git a/public/images/help_outline.png b/public/images/help_outline.png new file mode 100644 index 00000000..20462273 Binary files /dev/null and b/public/images/help_outline.png differ diff --git a/src/entities/user/api/types.ts b/src/entities/user/api/types.ts index fbd0d905..cb5663ea 100644 --- a/src/entities/user/api/types.ts +++ b/src/entities/user/api/types.ts @@ -65,19 +65,26 @@ export interface MemberProfile { simpleIntroduction: string; mbti: string; interests: Interest[]; - hobbies: Hobby[]; + hobbies?: Hobby[]; birthDate: string; githubLink: SocialLink | undefined; blogOrSnsLink: SocialLink | undefined; tel: string; } +export interface SincerityTemp { + temperature: number; + levelId: number; + levelName: string; +} + export interface GetUserProfileResponse { memberId: number; autoMatching: boolean; studyApplied: boolean; memberInfo: MemberInfo; memberProfile: MemberProfile; + sincerityTemp: SincerityTemp; } export interface PatchAutoMatchingParams { diff --git a/src/entities/user/ui/my-profile-card.tsx b/src/entities/user/ui/my-profile-card.tsx index 8e2bf597..13dfe550 100644 --- a/src/entities/user/ui/my-profile-card.tsx +++ b/src/entities/user/ui/my-profile-card.tsx @@ -5,12 +5,15 @@ import React, { useState } from 'react'; import { usePatchAutoMatchingMutation } from '@/entities/user/model/use-user-profile-query'; import { useReviewReminder } from '@/features/study/lib/use-reminder-review'; import StudyReviewModal from '@/features/study/ui/study-review-modal'; +import { getSincerityPresetByLevelId } from '@/shared/config/sincerity-temp-presets'; +import { cn } from '@/shared/shadcn/lib/utils'; import UserAvatar from '@/shared/ui/avatar'; import { ToggleSwitch } from '@/shared/ui/toggle'; import AccessTimeIcon from 'public/icons/access_time.svg'; import AssignmentIcon from 'public/icons/assignment.svg'; import CodeIcon from 'public/icons/code.svg'; import SettingIcon from 'public/icons/setting.svg'; +import { SincerityTemp } from '../api/types'; interface MyProfileCardProps { memberId: number; @@ -21,6 +24,7 @@ interface MyProfileCardProps { time?: string; techStacks?: string; studyApplied?: boolean; + sincerityTemp: SincerityTemp; } export default function MyProfileCard({ @@ -32,10 +36,12 @@ export default function MyProfileCard({ time, techStacks, studyApplied, + sincerityTemp, }: MyProfileCardProps) { const { showReviewReminder, setShowReviewReminder } = useReviewReminder(); const [enabled, setEnabled] = useState(matching); + const temperPreset = getSincerityPresetByLevelId(sincerityTemp.levelId); const { mutate: patchAutoMatching, isPending } = usePatchAutoMatchingMutation(); @@ -72,9 +78,20 @@ export default function MyProfileCard({ -
-
- {name?.trim() || '비회원'}님 +
+
+
+ {name?.trim() || '비회원'}님 +
+
+ {sincerityTemp.temperature.toFixed(1)} ℃ +
diff --git a/src/entities/user/ui/user-profile-modal.tsx b/src/entities/user/ui/user-profile-modal.tsx index f49fe6ba..7bbc47d7 100644 --- a/src/entities/user/ui/user-profile-modal.tsx +++ b/src/entities/user/ui/user-profile-modal.tsx @@ -9,6 +9,7 @@ import GithubIcon from '@/features/my-page/ui/icon/github-logo.svg'; import GlobeIcon from '@/features/my-page/ui/icon/globe-simple.svg'; import PhoneIcon from '@/features/my-page/ui/icon/phone.svg'; import { useUserPositiveKeywordsQuery } from '@/features/study/model/use-review-query'; +import { getSincerityPresetByLevelId } from '@/shared/config/sincerity-temp-presets'; import UserAvatar from '@/shared/ui/avatar'; import Badge from '@/shared/ui/badge'; import { Modal } from '@/shared/ui/modal'; @@ -30,6 +31,9 @@ export default function UserProfileModal({ if (isLoading || isError || !profile || !positiveKeywordsData) return null; const positiveKeywords = positiveKeywordsData?.keywords || []; + const temperPreset = getSincerityPresetByLevelId( + profile.sincerityTemp.levelId, + ); return ( @@ -68,33 +72,55 @@ export default function UserProfileModal({ ))}
-
- {profile.memberProfile.memberName} +
+
+ {profile.memberProfile.memberName} +
+ +
{profile.memberProfile.simpleIntroduction}
-
-
-
- + +
+
+ + {profile.memberProfile.birthDate ?? ''} -
-
- - {profile.memberProfile.tel ?? ''} -
+
-
-
- +
+ + {profile.memberProfile.githubLink?.url ?? ''} -
-
- + +
+
+ + + {profile.memberProfile.tel ?? ''} + +
+ +
+ + {profile.memberProfile.blogOrSnsLink?.url ?? ''} -
+
diff --git a/src/features/my-page/ui/profile.tsx b/src/features/my-page/ui/profile.tsx index aa685de4..8b5eedc1 100644 --- a/src/features/my-page/ui/profile.tsx +++ b/src/features/my-page/ui/profile.tsx @@ -1,18 +1,29 @@ -import { MemberProfile } from '@/entities/user/api/types'; +import Image from 'next/image'; +import { MemberProfile, SincerityTemp } from '@/entities/user/api/types'; import CakeIcon from '@/features/my-page/ui/icon/cake.svg'; import GithubIcon from '@/features/my-page/ui/icon/github-logo.svg'; import GlobeIcon from '@/features/my-page/ui/icon/globe-simple.svg'; import PhoneIcon from '@/features/my-page/ui/icon/phone.svg'; import ProfileEditModal from '@/features/my-page/ui/profile-edit-modal'; +import { getSincerityPresetByLevelId } from '@/shared/config/sincerity-temp-presets'; +import { cn } from '@/shared/shadcn/lib/utils'; import UserAvatar from '@/shared/ui/avatar'; import Badge from '@/shared/ui/badge'; +import Progress from '@/shared/ui/progress'; interface ProfileProps { memberId: number; memberProfile: MemberProfile; + sincerityTemp: SincerityTemp; } -export default function Profile({ memberId, memberProfile }: ProfileProps) { +export default function Profile({ + memberId, + memberProfile, + sincerityTemp, +}: ProfileProps) { + const temperPreset = getSincerityPresetByLevelId(sincerityTemp.levelId); + return (
-
-
-
- +
+
+ + {memberProfile.birthDate ?? '생일을 입력해주세요!'} -
-
- + +
+
+ + + {memberProfile.githubLink?.url ?? '깃허브 링크를 입력해주세요!'} + +
+
+ + {memberProfile.tel ?? '번호를 입력해주세요!'} -
+
+
+ + + {memberProfile.blogOrSnsLink?.url ?? + '블로그 링크를 입력해주세요!'} + +
+
-
-
- - {memberProfile.githubLink?.url || '깃허브 링크를 입력해주세요!'} +
+
+
+ 성실 온도 + 성실온도 설명
-
- - {memberProfile.blogOrSnsLink?.url || - '블로그 링크를 입력해주세요!'} +
+ +
{sincerityTemp.temperature.toFixed(1)} ℃
+
diff --git a/src/shared/config/sincerity-temp-presets.tsx b/src/shared/config/sincerity-temp-presets.tsx new file mode 100644 index 00000000..e78c10d2 --- /dev/null +++ b/src/shared/config/sincerity-temp-presets.tsx @@ -0,0 +1,65 @@ +import TempType1 from '@/shared/icons/temp_1.svg'; +import TempType2 from '@/shared/icons/temp_2.svg'; +import TempType3 from '@/shared/icons/temp_3.svg'; +import TempType4 from '@/shared/icons/temp_4.svg'; + +export type SincerityType = 'type1' | 'type2' | 'type3' | 'type4'; + +export interface SincerityPreset { + indicatorClass: string; + textClass: string; + bgClass: string; + Icon: React.ComponentType>; + label?: string; +} + +export const SINCERITY_TEMP_PRESETS: Record = { + type1: { + // todo: Figma에 헥스코드로만 존재. 디자인 시스템 X. 현재 코드에서는 헥스값 인식을 하지 못하기 때문에 임의 컬러로 설정 + // 현재 기획 여쭤본 상태, 컬러값에 따라 global에 추가후 변경 가능성 O. + // indicatorClass: '#F5C400', + // textClass: '#FFD21F', + indicatorClass: 'bg-yellow-300', + textClass: 'text-yellow-400', + bgClass: 'bg-yellow-50', + Icon: TempType1, + label: '노란불씨', + }, + type2: { + indicatorClass: 'bg-orange-400', + textClass: 'text-orange-400', + bgClass: 'bg-orange-50', + Icon: TempType2, + label: '주황불꽃', + }, + type3: { + indicatorClass: 'bg-rose-500', + textClass: 'text-rose-500', + bgClass: 'bg-rose-50', + Icon: TempType3, + label: '불꽃', + }, + type4: { + indicatorClass: 'bg-indigo-500', + textClass: 'text-indigo-500', + bgClass: 'bg-indigo-50', + Icon: TempType4, + label: '푸른불꽃', + }, +} as const; + +const LEVEL_ID_TO_TYPE: Record = { + 5: 'type1', // 1단계 + 6: 'type2', // 2단계 + 7: 'type3', // 3단계 + 8: 'type4', // 4단계 +}; + +// 매핑 안되는 값이 들어왔을 경우 FALLBACK +const FALLBACK_TYPE: SincerityType = 'type1'; + +export function getSincerityPresetByLevelId(levelId: number): SincerityPreset { + const type = LEVEL_ID_TO_TYPE[levelId] ?? FALLBACK_TYPE; + + return SINCERITY_TEMP_PRESETS[type]; +} diff --git a/src/shared/icons/temp_1.svg b/src/shared/icons/temp_1.svg new file mode 100644 index 00000000..edbc9675 --- /dev/null +++ b/src/shared/icons/temp_1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/shared/icons/temp_2.svg b/src/shared/icons/temp_2.svg new file mode 100644 index 00000000..3bb87659 --- /dev/null +++ b/src/shared/icons/temp_2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/shared/icons/temp_3.svg b/src/shared/icons/temp_3.svg new file mode 100644 index 00000000..8ca85a33 --- /dev/null +++ b/src/shared/icons/temp_3.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/shared/icons/temp_4.svg b/src/shared/icons/temp_4.svg new file mode 100644 index 00000000..60119ca5 --- /dev/null +++ b/src/shared/icons/temp_4.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/shared/ui/progress/index.tsx b/src/shared/ui/progress/index.tsx new file mode 100644 index 00000000..fb9ca504 --- /dev/null +++ b/src/shared/ui/progress/index.tsx @@ -0,0 +1,29 @@ +'use client'; + +import * as RadixProgress from '@radix-ui/react-progress'; +import * as React from 'react'; + +interface ProgressProps { + value: number; + indicatorColor?: string; +} + +const Progress: React.FC = ({ + value, + indicatorColor = 'bg-white', +}) => { + return ( + + + + ); +}; + +export default Progress; diff --git a/src/widgets/home/sidebar.tsx b/src/widgets/home/sidebar.tsx index f588e6cb..88c8a5dd 100644 --- a/src/widgets/home/sidebar.tsx +++ b/src/widgets/home/sidebar.tsx @@ -30,6 +30,7 @@ export default async function Sidebar() { ?.map((t) => t.techStackName) .join(', ')} studyApplied={userProfile?.studyApplied ?? false} + sincerityTemp={userProfile.sincerityTemp} /> {userProfile.studyApplied ? ( diff --git a/yarn.lock b/yarn.lock index 15d0327d..2f43b386 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2926,6 +2926,26 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-progress@npm:^1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-progress@npm:1.1.7" + dependencies: + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/bed5349682a75db02d362c07ac99fefddbbdc0152c4d5035719498223b9d490ebd834e2d9f64d498424048eb3da7eb7e55ba696e202cd0a048d6e319390e69d3 + languageName: node + linkType: hard + "@radix-ui/react-roving-focus@npm:1.1.10": version: 1.1.10 resolution: "@radix-ui/react-roving-focus@npm:1.1.10" @@ -10605,6 +10625,7 @@ __metadata: "@radix-ui/react-avatar": "npm:^1.1.9" "@radix-ui/react-dialog": "npm:^1.1.10" "@radix-ui/react-dropdown-menu": "npm:^2.1.15" + "@radix-ui/react-progress": "npm:^1.1.7" "@radix-ui/react-slot": "npm:^1.2.2" "@radix-ui/react-switch": "npm:^1.2.4" "@radix-ui/react-toggle": "npm:^1.1.9"