Skip to content

Commit

Permalink
[#113] ✨ 특정 유저 프로필 조회 기능 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
Heesun committed Aug 13, 2024
1 parent 948497e commit cb9a182
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 94 deletions.
63 changes: 63 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-menubar": "^1.1.1",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-progress": "^1.1.0",
"@radix-ui/react-radio-group": "^1.2.0",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-separator": "^1.1.0",
Expand Down
26 changes: 26 additions & 0 deletions src/components/ui/progress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as React from "react"
import * as ProgressPrimitive from "@radix-ui/react-progress"

import { cn } from "@/lib/utils"

const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={cn(
"relative h-4 w-full overflow-hidden rounded-full bg-secondary",
className
)}
{...props}
>
<ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
))
Progress.displayName = ProgressPrimitive.Root.displayName

export { Progress }
9 changes: 4 additions & 5 deletions src/pages/ClubPage/ClubPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Footer from '@/components/Footer';
import Header from '@/components/Header';
import NotificationModal from '@/components/ui/notificationModal';
import ProfileModal from '@/components/ui/profileModal';
import { useUserStore } from '@/store/userStore';
import { ClubData } from '@/types/Clubs';
import { Result } from '@/types/Meetings';
import React, { useEffect, useRef, useState } from 'react';
Expand All @@ -17,9 +18,7 @@ const ClubPage: React.FC = () => {
const [selectedMenu, setSelectedMenu] = useState<string>('home');
const [isProfileModalOpen, setIsProfileModalOpen] = useState(false);
const [isNotificationModalOpen, setIsNotificationModalOpen] = useState(false);
const [isLoggedIn, setIsLoggedIn] = useState(
!!localStorage.getItem('accessToken'),
);
const { isLoggedIn, clearUser } = useUserStore();
const [hasNotifications, setHasNotifications] = useState(false);
const { id } = useParams<{ id: string }>();
const location = useLocation();
Expand Down Expand Up @@ -70,7 +69,7 @@ const ClubPage: React.FC = () => {
};

const handleLogout = () => {
setIsLoggedIn(false);
clearUser();
setIsProfileModalOpen(false);
localStorage.removeItem('accessToken');
};
Expand Down Expand Up @@ -154,7 +153,7 @@ const ClubPage: React.FC = () => {
toggleProfileModal={toggleProfileModal}
toggleNotificationModal={toggleNotificationModal}
isLoggedIn={isLoggedIn}
handleLoginLogout={() => setIsLoggedIn(!isLoggedIn)}
handleLoginLogout={() => handleLogout}
profileRef={profileRef}
hasNotifications={hasNotifications}
/>
Expand Down
111 changes: 110 additions & 1 deletion src/pages/ClubPage/member/UserProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,114 @@
import { Api, ProfileResponse } from '@/api/Apis';
import { Progress } from '@/components/ui/progress';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import { useEffect, useState } from 'react';
import { useLocation, useParams } from 'react-router-dom';

const apiInstance = new Api();

const UserProfile = () => {
return <p>user profile</p>;
const { clubUserId } = useParams<{ clubUserId: string }>();
const [userProfile, setUserProfile] = useState<ProfileResponse | null>(null);
const [loading, setLoading] = useState(true);
const location = useLocation();
const mannerTemp = location.state?.mannerTemp || 36; // mannerTemp 값을 가져옴, 없으면 기본값 36
useEffect(() => {
const fetchUserProfile = async () => {
try {
if (clubUserId) {
const response = await apiInstance.api.getUserProfile(
Number(clubUserId),
);
console.log(response);

if (response.results && response.results.length > 0) {
const profileData = response.results[0];

setUserProfile({ ...profileData, mannerRating: mannerTemp });
} else {
setUserProfile(null);
}
}
} catch (err) {
setLoading(true);
console.error('Failed to fetch user profile:', err);
}
setLoading(false);
};

fetchUserProfile();
}, [clubUserId, mannerTemp]);

if (loading) {
return <p>Loading...</p>;
}

if (!userProfile) {
return <p>No profile data available</p>;
}

return (
<div className="flex flex-col p-6 w-[820px] border-2 border-gray-200 bg-white rounded-lg">
<div className="container flex flex-col shadow-md border border-gray-200 rounded-lg p-10 items-center justify-center bg-white relative">
<div
className={`w-40 h-40 rounded-full mb-3 flex bg-red-200 items-center justify-center}`}
>
<img
src={userProfile.profileImage}
alt="Profile"
className="w-full h-full rounded-full object-cover"
/>
</div>

<section>
<div>
<p className="text-xs mt-2">
매너지수: {userProfile.mannerRating}°C
</p>
<Progress value={userProfile.mannerRating} className="mt-2 mb-10" />
</div>
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[200px] "></TableHead>
<TableHead className="text-right"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell className="font-neoBold">닉네임</TableCell>
<TableCell className="font-neoBold text-right text-primary ">
{userProfile.nickname}
</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-neoBold">참여중인 모임</TableCell>
<TableCell className="font-neoBold text-right text-primary">
{userProfile.attendedMeetings &&
userProfile.attendedMeetings.length > 0 ? (
<ul>
{userProfile.attendedMeetings.map((meeting, index) => (
<li key={index}>{meeting.meetingName}</li>
))}
</ul>
) : (
'참여중인 모임이 없습니다'
)}
</TableCell>
</TableRow>
</TableBody>
</Table>
</section>
</div>
</div>
);
};

export default UserProfile;
5 changes: 3 additions & 2 deletions src/pages/MyPage/MyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import Header from '@/components/Header';
import { Button } from '@/components/ui/button';
import NotificationModal from '@/components/ui/notificationModal';
import ProfileModal from '@/components/ui/profileModal';
import { Progress } from '@/components/ui/progress';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { useUserStore } from '@/store/userStore';
import React, { useEffect, useRef, useState } from 'react';
import MyModong from './MyModong';
import UpdateUser from './UpdateUser';

const MyPage: React.FC = () => {
const { isLoggedIn, nickname, clearUser } = useUserStore();
const [isProfileModalOpen, setIsProfileModalOpen] = useState(false);
Expand Down Expand Up @@ -126,8 +126,9 @@ const MyPage: React.FC = () => {
<p className="font-neoLight text-xs">회원 이미지는 원형으로 출력</p>
<p className="font-medium text-xs mt-4">
나의 매너 온도:
{mannerRating !== null ? ` ${mannerRating}` : '정보 없음'}
{mannerRating !== null ? ` ${mannerRating}°C` : '정보 없음'}
</p>
<Progress value={mannerRating} className="mt-2 mb-10 w-[50%]" />
<div className="shadow-md border w-full border-gray-200 rounded-lg m-12 p-24 max-w-full md:w-[800px]">
<Tabs defaultValue="account" className="w-full">
<div className="w-full flex items-center justify-center mb-10">
Expand Down
52 changes: 0 additions & 52 deletions src/pages/chat/chatMockData.ts

This file was deleted.

34 changes: 0 additions & 34 deletions src/pages/chat/socket.ts

This file was deleted.

Loading

0 comments on commit cb9a182

Please sign in to comment.