Skip to content

Commit

Permalink
In-app navigation accessibility (#30)
Browse files Browse the repository at this point in the history
Preparing for final show

---------

Co-authored-by: IceCandle <[email protected]>
  • Loading branch information
IceCandle and IceCandle authored Feb 2, 2025
1 parent 95a4777 commit a0040a1
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/components/layout/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,4 @@ const SideBar = ({ onSearchClick }: SideBarProps) => {
);
};

export default SideBar;
export default SideBar;
26 changes: 0 additions & 26 deletions src/components/profile/Highlights.tsx

This file was deleted.

11 changes: 6 additions & 5 deletions src/components/profile/ProfileInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Link } from 'react-router-dom';
import { followUser, unfollowUser } from '../../api/follow';
import { myProfile } from '../../api/profile';
import { LoginContext } from '../../App';
import ProfileStoryView from './ProfileStoryView';

type ProfileInfoProps = {
userId: number;
Expand Down Expand Up @@ -69,12 +70,12 @@ const ProfileInfo = ({
return (
<div className="mb-8">
<div className="flex items-center mb-4">
<img
src={`https://waffle-instaclone.kro.kr/${profileImage}`}
alt={username}
className="w-20 h-20 rounded-full mr-4"
<ProfileStoryView
userId={userId}
username={username}
profileImage={profileImage}
/>
<div className="flex-1">
<div className="flex-1 ml-4">
<div className="flex items-center mb-2">
<h1 className="text-xl font-semibold mr-4">{username}</h1>
{username === context?.myProfile?.username ? (
Expand Down
78 changes: 78 additions & 0 deletions src/components/profile/ProfileStoryView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import type { Story } from '../../types/story';

interface ProfileStoryViewProps {
userId: number;
username: string;
profileImage: string;
}

const ProfileStoryView = ({
userId,
username,
profileImage,
}: ProfileStoryViewProps) => {
const [stories, setStories] = useState<Story[]>([]);
const [loading, setLoading] = useState(true);
const navigate = useNavigate();

useEffect(() => {
const fetchStories = async () => {
try {
const response = await fetch(
`https://waffle-instaclone.kro.kr/api/story/list/${userId}`,
{
headers: {
Authorization: `Bearer ${localStorage.getItem('access_token') ?? ''}`,
},
},
);
if (!response.ok) throw new Error('Failed to fetch stories');
const data = (await response.json()) as Story[];
setStories(data);
} catch (error) {
console.error('Error fetching stories:', error);
} finally {
setLoading(false);
}
};

void fetchStories();
}, [userId]);

const handleClick = () => {
const firstStory = stories[0];
if (stories.length > 0 && firstStory != null) {
void navigate(`/stories/${username}/${firstStory.story_id}`);
}
};

return (
<button onClick={handleClick} className="relative w-20 h-20 rounded-full">
<div
className={`w-full h-full rounded-full p-0.5 ${
stories.length > 0
? 'bg-gradient-to-tr from-yellow-400 to-pink-600'
: 'bg-gray-200'
}`}
>
<div className="w-full h-full rounded-full bg-white p-0.5">
<img
src={`https://waffle-instaclone.kro.kr/${profileImage}`}
alt={username}
className="w-full h-full rounded-full object-cover"
/>
</div>
</div>
{loading && (
<div className="absolute inset-0 flex items-center justify-center bg-black bg-opacity-20 rounded-full">
<div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
</div>
)}
</button>
);
};

export default ProfileStoryView;
5 changes: 3 additions & 2 deletions src/components/shared/PostGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ interface PostGridProps {
}

const PostGrid = ({ posts }: PostGridProps) => {
const sortedPosts = [...posts].sort((a, b) =>
new Date(b.creation_date).getTime() - new Date(a.creation_date).getTime()
const sortedPosts = [...posts].sort(
(a, b) =>
new Date(b.creation_date).getTime() - new Date(a.creation_date).getTime(),
);

return (
Expand Down
27 changes: 20 additions & 7 deletions src/components/story/StoryViewer/StoryUserInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { useNavigate } from 'react-router-dom';

interface StoryUserInfoProps {
username: string;
profileImage?: string;
creationDate: string;
}

const formatTimeAgo = (dateString: string): string => {
const date = new Date(dateString + 'Z');
const now = new Date();
Expand All @@ -17,17 +25,17 @@ const formatTimeAgo = (dateString: string): string => {
}
};

interface StoryUserInfoProps {
username: string;
profileImage?: string;
creationDate: string;
}

const StoryUserInfo = ({
username,
profileImage,
creationDate,
}: StoryUserInfoProps) => {
const navigate = useNavigate();
const handleUsernameClick = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
void navigate(`/${username}`);
};
return (
<div className="absolute top-2 left-0 right-0 z-20">
<div className="flex items-center space-x-3 px-4 py-2">
Expand All @@ -43,7 +51,12 @@ const StoryUserInfo = ({
/>
</div>
<div className="flex items-center space-x-2">
<span className="text-white font-semibold text-sm">{username}</span>
<button
onClick={handleUsernameClick}
className="text-white font-semibold text-sm hover:underline focus:outline-none"
>
{username}
</button>
<span className="text-gray-300 text-xs">
{formatTimeAgo(creationDate)}
</span>
Expand Down
3 changes: 1 addition & 2 deletions src/pages/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import MobileBar from '../components/layout/MobileBar';
import MobileHeader from '../components/layout/MobileHeader';
import SideBar from '../components/layout/SideBar';
import SearchModal from '../components/modals/SearchModal';
import Highlights from '../components/profile/Highlights';
// import Highlights from '../components/profile/Highlights';
import ProfileInfo from '../components/profile/ProfileInfo';
import ProfileTabs from '../components/profile/ProfileTabs';
import { useSearch } from '../hooks/useSearch';
Expand Down Expand Up @@ -77,7 +77,6 @@ const ProfilePage = () => {
fullName={userProfile.full_name}
bio={userProfile.introduce}
/>
<Highlights />
<ProfileTabs postIds={userProfile.post_ids} />
</div>
</div>
Expand Down

0 comments on commit a0040a1

Please sign in to comment.