Skip to content

Commit

Permalink
Merge pull request #110 from 42Where/feature/tooltips
Browse files Browse the repository at this point in the history
[#104] 툴팁 추가 및 타입, UX 개선 (Feature/tooltips)
  • Loading branch information
daejlee authored Sep 10, 2024
2 parents 7a6a4e6 + edbb42f commit 073bd2c
Show file tree
Hide file tree
Showing 27 changed files with 2,073 additions and 1,276 deletions.
2,824 changes: 1,736 additions & 1,088 deletions package-lock.json

Large diffs are not rendered by default.

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-select": "^2.0.0",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.5",
"@radix-ui/react-tooltip": "^1.1.2",
"axios": "^1.6.7",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/api/authApi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import User from '@/types/User';
import { User } from '@/types/User';
import { axios, tokenAxios } from '@/lib/Axios';

const authApi = {
Expand Down
2 changes: 1 addition & 1 deletion src/api/groupApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { axios } from '@/lib/Axios';
import Group from '@/types/Group';
import User from '@/types/User';
import { User } from '@/types/User';

const groupApi = {
/**
Expand Down
8 changes: 6 additions & 2 deletions src/api/memberApi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import User from '@/types/User';
import { User, SearchedUser } from '@/types/User';
import { axios } from '@/lib/Axios';

const memberApi = {
Expand All @@ -18,7 +18,11 @@ const memberApi = {
deleteAccount: async (): Promise<void> => {
await axios.delete('/v3/member');
},
searchMember: async ({ keyWord }: { keyWord: string }): Promise<User[]> => {
searchMember: async ({
keyWord,
}: {
keyWord: string;
}): Promise<SearchedUser[]> => {
const response = await axios.get('/v3/search', {
params: { keyWord },
});
Expand Down
40 changes: 40 additions & 0 deletions src/components/Buttons/GroupSettingBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Group from '@/types/Group';
import Image from 'next/image';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';
import { DropdownMenuTrigger } from '@/components/ui/dropdown-menu';

export default function GroupSettingBtn({
curGroup,
groups,
}: {
curGroup: Group;
groups: Group[];
}) {
return !groups.find((group) => group.groupId === curGroup.groupId)
?.isInEdit ? (
<DropdownMenuTrigger className='absolute size-10 rounded-lg flex justify-center items-center right-[50px] md:right-[64px] top-[8px] md:top-[16px] hover:bg-gray-200'>
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<Image
src='/Icons/pencil.svg'
alt='pencil'
width={24}
height={24}
/>
</TooltipTrigger>
<TooltipContent>
<p className='font-gsansMd text-[#4A6282] text-l lg:text-xl'>
그룹 설정
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</DropdownMenuTrigger>
) : null;
}
64 changes: 40 additions & 24 deletions src/components/Buttons/LocationBtn.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,57 @@
import { Button } from '../ui/button';
import React from 'react';
import User from '@/types/User';
import { User, SearchedUser } from '@/types/User';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';

export default function LocationBtn({
user,
searchedUser,
isMyProfile,
}: {
user: User;
searchedUser?: any;
user: SearchedUser | User;
isMyProfile?: boolean;
}) {
const [location, setLocation] = React.useState<string>('');
React.useEffect(() => {
if (searchedUser) {
if (searchedUser.location) {
setLocation(searchedUser.location);
} else if (searchedUser.inOrOut || searchedUser.inCluster) {
setLocation('개포');
} else {
setLocation('퇴근');
}
} else if (user.location) {
if ('location' in user && user.location) {
setLocation(user.location);
} else if (user.inCluster || user.inOrOut) {
} else if (
('inCluster' in user && user.inCluster) ||
('inOrOut' in user && user.inOrOut)
) {
setLocation('개포');
} else {
setLocation('퇴근');
}
}, [user, searchedUser]);
}, [user]);
return (
<Button
className={`rounded-full ${
location !== '퇴근'
? 'bg-[#132743]'
: 'bg-white hover:bg-white text-[#132743] border-2 border-[#132743]'
} h-6 md:h-8 px-2 md:px-3 md:text-xl font-gsansMd`}
>
{location}
</Button>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
className={`rounded-full
${!isMyProfile && 'cursor-default'}
${
location !== '퇴근'
? 'bg-[#132743]'
: 'bg-white hover:bg-white text-[#132743] border-2 border-[#132743]'
} h-6 md:h-8 px-2 md:px-3 md:text-xl font-gsansMd`}
>
{location}
</Button>
</TooltipTrigger>
{isMyProfile && (
<TooltipContent>
<p className='font-gsansMd text-[#4A6282] text-l lg:text-xl'>
내 위치 변경
</p>
</TooltipContent>
)}
</Tooltip>
</TooltipProvider>
);
}
44 changes: 44 additions & 0 deletions src/components/Buttons/LogoutBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Cookies from 'js-cookie';
import { useRouter } from 'next/router';
import Image from 'next/image';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';

export default function LogoutBtn() {
const router = useRouter();
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div
className='size-10 lg:size-14 rounded-lg flex justify-center items-center hover:bg-gray-200'
role='button'
tabIndex={0}
onClick={() => {
Cookies.remove('accessToken');
Cookies.remove('refreshToken');
router.push('/login');
}}
>
<Image
src='/Icons/signOut.svg'
alt='search'
width={40}
height={40}
className='rounded-lg hover:bg-gray-200 lg:size-[40px] size-[30px]'
/>
</div>
</TooltipTrigger>
<TooltipContent>
<p className='font-gsansMd text-[#4A6282] text-l lg:text-xl'>
로그아웃
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
30 changes: 30 additions & 0 deletions src/components/Buttons/MySettingBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Image from 'next/image';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';

export default function MySettingBtn() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Image
src='/Icons/setting.svg'
alt='setting'
width={60}
height={60}
className='rounded-lg hover:bg-gray-200 lg:size-[60px] size-[50px] cursor-pointer'
/>
</TooltipTrigger>
<TooltipContent>
<p className='font-gsansMd text-[#4A6282] text-l lg:text-xl'>
내 정보 설정
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
36 changes: 36 additions & 0 deletions src/components/Buttons/SearchBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Image from 'next/image';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';

export default function SearchBtn() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div
className='size-10 lg:size-14 rounded-lg flex justify-center items-center hover:bg-gray-200'
role='button'
tabIndex={0}
>
<Image
src='/Icons/search.svg'
alt='search'
width={40}
height={40}
className='rounded-lg hover:bg-gray-200 lg:size-[40px] size-[30px]'
/>
</div>
</TooltipTrigger>
<TooltipContent>
<p className='font-gsansMd text-[#4A6282] text-l lg:text-xl'>
유저 검색
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
13 changes: 3 additions & 10 deletions src/components/Cards/MyProfileCard.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useEffect } from 'react';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import User from '@/types/User';
import { User } from '@/types/User';
import { useCheckedStore } from '@/lib/stores';
import NewGroupModal from '../Modals/NewGroupModal';
import MySettingModal from '../Modals/MySettingModal';
import CustomLocationModal from '../Modals/CustomLocationModal';
import ProfilePic from '@/components/ProfilePic';

export default function MyProfileCard({ user }: { user: User }) {
useEffect(() => {
Expand All @@ -20,14 +20,7 @@ export default function MyProfileCard({ user }: { user: User }) {
return (
<div className='flex flex-row justify-between items-center pb-12 lg:px-8 pt-0 relative'>
<div className='flex flex-row items-center gap-4 lg:gap-6'>
<Avatar
className={`size-24 lg:size-28 border-[${
user.location ? '#FFB5B5' : '#7F848D'
}] border-4`}
>
<AvatarImage src={user.image} />
<AvatarFallback />
</Avatar>
<ProfilePic user={user} type='myCard' />
<div className='flex flex-col items-start gap-2'>
<CustomLocationModal />
<h3 className='text-xl lg:text-3xl font-gsansLg text-[#132743]'>
Expand Down
26 changes: 6 additions & 20 deletions src/components/Cards/ProfileCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import User from '@/types/User';
import ProfilePic from '@/components/ProfilePic';
import { User } from '@/types/User';
import { useCheckedUsersStore } from '@/lib/stores';
import { Checkbox } from '../ui/checkbox';
import UserSettingModal from '../Modals/UserSettingModal';
Expand All @@ -21,9 +21,9 @@ export default function ProfileCard({
const { checkedUsers, setCheckedUsers } = useCheckedUsersStore();
return (
<div
className='flex flex-row justify-between p-4 md:p-6 rounded-2xl border-2 hover:border-[#FFB5B5] items-center'
role='button'
tabIndex={0}
className={`flex flex-row justify-between p-4 md:p-6 rounded-2xl border-2 hover:border-[#FFB5B5] items-center ${
isEdit && 'cursor-pointer'
}`}
onClick={() => {
if (isEdit) {
const temp = checkedUsers;
Expand All @@ -38,21 +38,7 @@ export default function ProfileCard({
}}
>
<div className='flex flex-row items-center gap-4 md:gap-6'>
<Avatar
className={`size-20 md:size-28 ${
user.inOrOut || user.location || user.inCluster
? 'border-[#FFB5B5]'
: ''
} border-4 hover:border-[#bfb5ff]`}
onClick={() => {
if (!isEdit) {
window.open(`https://profile.intra.42.fr/users/${user.intraId}`);
}
}}
>
<AvatarImage src={user.image} />
<AvatarFallback />
</Avatar>
<ProfilePic user={user} type='userCard' />
<div className='flex flex-col items-start gap-1 md:gap-2'>
<LocationBtn user={user} />
<h3 className='text-xl md:text-3xl font-gsansLg text-[#132743]'>
Expand Down
19 changes: 5 additions & 14 deletions src/components/Cards/SearchedCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import Image from 'next/image';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import User from '@/types/User';
import { SearchedUser } from '@/types/User';
import groupApi from '@/api/groupApi';
import {
useUserStore,
Expand All @@ -10,13 +9,14 @@ import {
} from '@/lib/stores';
import LocationBtn from '../Buttons/LocationBtn';
import { useToast } from '@/components/ui/use-toast';
import ProfilePic from '@/components/ProfilePic';

export default function SearchedCard({
member,
onClick,
isAddingUser,
}: {
member: User;
member: SearchedUser;
onClick?: () => void;
isAddingUser?: boolean;
}) {
Expand All @@ -43,18 +43,9 @@ export default function SearchedCard({
onClick={() => onClick && onClick()}
>
<div className='flex flex-row items-center gap-4 md:gap-4'>
<Avatar
className={`size-16 md:size-20 ${
member.location || member.inCluster || member.inOrOut
? 'border-[#FFB5B5]'
: ''
} border-4`}
>
<AvatarImage src={member.image} />
<AvatarFallback />
</Avatar>
<ProfilePic user={member} type='searchedCard' />
<div className='flex flex-col items-start gap-1'>
<LocationBtn user={member} searchedUser={member} />
<LocationBtn user={member} />
<h3 className='text-xl md:text-2xl font-gsansLg text-[#132743]'>
{member.intraName}
</h3>
Expand Down
Loading

0 comments on commit 073bd2c

Please sign in to comment.