Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: #63 수행자 권한 표시를 아이콘으로 변경 & 아이콘 툴팁 설명 추가 #81

Merged
merged 1 commit into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/components/common/RoleIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { TbChess, TbChessKnight, TbChessQueen } from 'react-icons/tb';
import { Role } from '@/types/RoleType';

type RoleIconProps = {
roleName: Role['roleName'];
};

function getRoleIcon(roleName: Role['roleName']) {
switch (roleName) {
case 'HEAD':
case 'ADMIN':
return <TbChessQueen />;
case 'LEADER':
return <TbChessKnight />;
case 'MATE':
case 'ASSIGNEE':
return <TbChess />;
default:
return null;
}
}

export default function RoleIcon({ roleName }: RoleIconProps) {
return (
<div className="group relative cursor-help">
{getRoleIcon(roleName)}
{/* prettier-ignore */}
<h4 className="
invisible absolute bottom-full left-1/2 -translate-x-1/2 select-none rounded-md bg-black/50 px-5
my-2 text-center text-xs text-white transition-opacity duration-700 group-hover:visible
after:content[''] after:absolute after:top-full after:left-1/2 after:border-4 after:-ml-2
after:border-t-black/50 after:border-b-transparent after:border-x-transparent
">
{roleName}
</h4>
</div>
);
}
17 changes: 8 additions & 9 deletions src/components/modal/task/ModalTaskForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IoSearch } from 'react-icons/io5';
import { IoMdCloseCircle } from 'react-icons/io';

import { TASK_VALIDATION_RULES } from '@constants/formValidationRules';
import RoleIcon from '@components/common/RoleIcon';
import ToggleButton from '@components/common/ToggleButton';
import DuplicationCheckInput from '@components/common/DuplicationCheckInput';
import useToast from '@hooks/useToast';
Expand Down Expand Up @@ -70,7 +71,7 @@ export default function ModalTaskForm({ formId, project, taskId, onSubmit }: Mod
}, [fetchData, projectId, keyword]);

useEffect(() => {
if (keyword.trim()) {
if (keyword) {
debounceRef.current = setTimeout(() => searchUsers(), 500);
}
return () => {
Expand All @@ -85,7 +86,7 @@ export default function ModalTaskForm({ formId, project, taskId, onSubmit }: Mod
setHasDeadline((prev) => !prev);
};

const handleKeywordChange = (e: React.ChangeEvent<HTMLInputElement>) => setKeyword(e.target.value);
const handleKeywordChange = (e: React.ChangeEvent<HTMLInputElement>) => setKeyword(e.target.value.trim());

const handleSearchClick = () => searchUsers();

Expand All @@ -100,9 +101,9 @@ export default function ModalTaskForm({ formId, project, taskId, onSubmit }: Mod
const isIncludedUser = workers.find((worker) => worker.userId === user.userId);
if (isIncludedUser) return toastInfo('이미 포함된 수행자입니다');

const newWorkers = [...workers, user];
const workersIdList = newWorkers.map((worker) => worker.userId);
setWorkers(newWorkers);
const updatedWorkers = [...workers, user];
const workersIdList = updatedWorkers.map((worker) => worker.userId);
setWorkers(updatedWorkers);
setValue('userId', workersIdList);
setKeyword('');
clearData();
Expand Down Expand Up @@ -211,7 +212,7 @@ export default function ModalTaskForm({ formId, project, taskId, onSubmit }: Mod
<IoSearch className="size-15 text-emphasis hover:text-black" />
</button>
{keyword && !loading && (
<ul className="invisible absolute left-0 right-0 max-h-110 overflow-auto rounded-md border-2 bg-white group-focus-within:visible">
<ul className="invisible absolute left-0 right-0 z-10 max-h-110 overflow-auto rounded-md border-2 bg-white group-focus-within:visible">
{data && data.length === 0 ? (
<div className="h-20 border px-10 leading-8">&apos;{keyword}&apos; 의 검색 결과가 없습니다.</div>
) : (
Expand All @@ -237,7 +238,7 @@ export default function ModalTaskForm({ formId, project, taskId, onSubmit }: Mod
<section className="flex w-full flex-wrap items-center gap-4">
{workers.map((user) => (
<div key={user.userId} className="flex items-center space-x-4 rounded-md bg-button px-5">
<div>{user.roleName}</div>
<RoleIcon roleName={user.roleName} />
<div>{user.nickname}</div>
<button type="button" aria-label="delete-worker" onClick={() => handleDeleteClick(user)}>
<IoMdCloseCircle className="text-error" />
Expand All @@ -246,12 +247,10 @@ export default function ModalTaskForm({ formId, project, taskId, onSubmit }: Mod
))}
</section>
</div>

<label htmlFor="content" className="mb-20">
<h3 className="text-large">내용</h3>
<textarea name="content" id="content" className="w-full border" rows={5} />
</label>

<label htmlFor="files">
<h3 className="text-large">첨부파일</h3>
<input type="file" id="files" />
Expand Down
2 changes: 1 addition & 1 deletion src/mocks/mockData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ export const PROJECT_USER_DUMMY: ProjectUser[] = [
{
projectId: 1,
userId: 11,
roleId: 6,
roleId: 5,
},
{
projectId: 1,
Expand Down