-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This reverts commit cfb6743.
- Loading branch information
IceCandle
committed
Jan 17, 2025
1 parent
cfb6743
commit eaf49b8
Showing
10 changed files
with
81 additions
and
593 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,139 +1,57 @@ | ||
import { Link as LinkIcon } from 'lucide-react'; | ||
import { useEffect, useState } from 'react'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import { Settings } from 'lucide-react'; | ||
|
||
import FollowButton from './FollowButton'; | ||
|
||
interface ProfileInfoProps { | ||
userId: number; | ||
type ProfileInfoProps = { | ||
username: string; | ||
posts: number; | ||
followers: number; | ||
following: number; | ||
fullName: string; | ||
bio: string; | ||
website: string | null; | ||
profileImage: string; | ||
} | ||
}; | ||
|
||
const ProfileInfo = ({ | ||
userId, | ||
username, | ||
posts, | ||
followers, | ||
following, | ||
fullName, | ||
bio, | ||
website, | ||
profileImage, | ||
}: ProfileInfoProps) => { | ||
const [isCurrentUser, setIsCurrentUser] = useState(false); | ||
const [currentFollowers, setCurrentFollowers] = useState(followers); | ||
const navigate = useNavigate(); | ||
|
||
useEffect(() => { | ||
const checkCurrentUser = async () => { | ||
try { | ||
const token = localStorage.getItem('access_token'); | ||
if (token === null) { | ||
void navigate('/'); | ||
return; | ||
} | ||
|
||
const response = await fetch('http://3.34.185.81:8000/api/user/profile', { | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
}, | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error('Failed to fetch user profile'); | ||
} | ||
|
||
interface UserProfile { | ||
user_id: number; | ||
} | ||
|
||
const data: UserProfile = await response.json() as UserProfile; | ||
setIsCurrentUser(data.user_id === userId); | ||
} catch (error) { | ||
console.error('Error checking current user:', error); | ||
} | ||
}; | ||
|
||
void checkCurrentUser(); | ||
}, [userId, navigate]); | ||
|
||
const handleFollowChange = (isFollowing: boolean) => { | ||
setCurrentFollowers((prev) => (isFollowing ? prev + 1 : prev - 1)); | ||
}; | ||
|
||
const handleEditProfile = () => { | ||
void navigate(`/settings`); | ||
}; | ||
|
||
return ( | ||
<div className="mb-8"> | ||
<div className="flex flex-col md:flex-row items-center md:items-start"> | ||
<div className="w-20 h-20 md:w-36 md:h-36 rounded-full overflow-hidden mb-4 md:mb-0 md:mr-8 flex-shrink-0"> | ||
<img | ||
src={profileImage.length > 0 ? profileImage : '/placeholder.svg'} | ||
alt={username} | ||
className="w-full h-full object-cover" | ||
/> | ||
</div> | ||
|
||
<div className="flex-1 text-center md:text-left"> | ||
<div className="flex flex-col md:flex-row md:items-center md:space-x-4 mb-4"> | ||
<h2 className="text-xl mb-4 md:mb-0">{username}</h2> | ||
<div className="flex justify-center md:justify-start space-x-2"> | ||
{isCurrentUser ? ( | ||
<button | ||
onClick={handleEditProfile} | ||
className="bg-gray-100 px-4 py-1.5 rounded font-medium text-sm" | ||
> | ||
Edit Profile | ||
</button> | ||
) : ( | ||
<FollowButton userId={userId} onFollowChange={handleFollowChange} /> | ||
)} | ||
</div> | ||
<div className="flex items-center mb-4"> | ||
<img | ||
src="/placeholder.svg" | ||
alt={username} | ||
className="w-20 h-20 rounded-full mr-4" | ||
/> | ||
<div className="flex-1"> | ||
<div className="flex items-center mb-2"> | ||
<h1 className="text-xl font-semibold mr-4">{username}</h1> | ||
<button className="bg-blue-500 text-white px-4 py-1 rounded-md text-sm font-semibold mr-2"> | ||
Follow | ||
</button> | ||
<Settings className="w-6 h-6" /> | ||
</div> | ||
|
||
<div className="flex justify-center md:justify-start space-x-8 mb-4"> | ||
<div> | ||
<span className="font-semibold">{posts}</span> | ||
<span className="ml-1 text-gray-700">posts</span> | ||
</div> | ||
<div> | ||
<span className="font-semibold">{currentFollowers}</span> | ||
<span className="ml-1 text-gray-700">followers</span> | ||
</div> | ||
<div> | ||
<span className="font-semibold">{following}</span> | ||
<span className="ml-1 text-gray-700">following</span> | ||
</div> | ||
</div> | ||
|
||
<div className="space-y-2"> | ||
<h1 className="font-semibold">{fullName}</h1> | ||
{bio.length > 0 && <p className="whitespace-pre-line">{bio}</p>} | ||
{website !== null && website.length > 0 && ( | ||
<a | ||
href={website} | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
className="text-blue-900 font-medium flex items-center justify-center md:justify-start" | ||
> | ||
<LinkIcon className="w-4 h-4 mr-1" /> | ||
{website} | ||
</a> | ||
)} | ||
<div className="flex space-x-4 text-sm"> | ||
<span> | ||
<strong>{posts}</strong> posts | ||
</span> | ||
<span> | ||
<strong>{followers}</strong> followers | ||
</span> | ||
<span> | ||
<strong>{following}</strong> following | ||
</span> | ||
</div> | ||
</div> | ||
</div> | ||
<div className="md:hidden"> | ||
<h2 className="font-semibold">{fullName}</h2> | ||
<p>{bio}</p> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ProfileInfo; | ||
export default ProfileInfo; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,35 @@ | ||
import { Grid } from 'lucide-react'; | ||
import { Bookmark, Grid } from 'lucide-react'; | ||
import { useState } from 'react'; | ||
|
||
import type { APIPost } from '../../types/post'; | ||
import PostGrid from '../shared/PostGrid'; | ||
import PostModal from '../shared/PostModal'; | ||
|
||
interface ProfileTabsProps { | ||
postIds: number[]; | ||
} | ||
|
||
const ProfileTabs = ({ postIds }: ProfileTabsProps) => { | ||
const [selectedPost, setSelectedPost] = useState<APIPost | null>(null); | ||
const ProfileTabs = () => { | ||
const [activeTab, setActiveTab] = useState('posts'); | ||
|
||
return ( | ||
<div> | ||
<div className="border-t"> | ||
<div className="flex justify-center"> | ||
<button className="flex items-center py-4 space-x-1 text-sm font-semibold border-t border-black"> | ||
<Grid className="w-4 h-4" /> | ||
<span>POSTS</span> | ||
</button> | ||
</div> | ||
<div className="flex justify-around border-t"> | ||
<button | ||
className={`flex-1 py-2 ${activeTab === 'posts' ? 'border-t-2 border-black' : ''}`} | ||
onClick={() => { | ||
setActiveTab('posts'); | ||
}} | ||
> | ||
<Grid className="w-6 h-6 mx-auto" /> | ||
</button> | ||
<button | ||
className={`flex-1 py-2 ${activeTab === 'saved' ? 'border-t-2 border-black' : ''}`} | ||
onClick={() => { | ||
setActiveTab('saved'); | ||
}} | ||
> | ||
<Bookmark className="w-6 h-6 mx-auto" /> | ||
</button> | ||
</div> | ||
|
||
<PostGrid | ||
postIds={postIds} | ||
onPostClick={(post: APIPost) => { setSelectedPost(post); }} | ||
/> | ||
|
||
{selectedPost !== null && ( | ||
<PostModal post={selectedPost} onClose={() => { setSelectedPost(null); }} /> | ||
)} | ||
{activeTab === 'posts' && <PostGrid />} | ||
{activeTab === 'saved' && <div className="text-center py-8">저장됨</div>} | ||
</div> | ||
); | ||
}; | ||
|
||
export default ProfileTabs; | ||
export default ProfileTabs; |
Oops, something went wrong.