Skip to content
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
14 changes: 12 additions & 2 deletions src/components/columns/ColumnItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,18 @@ export default function ColumnItem({ column }: ColumnItemProps) {
<DashboardButton variant='addTodo' onClick={() => addRef.current?.open()} />
<div className='flex flex-col gap-4'>
<AnimatePresence>
{cards.map((card) => (
<motion.div key={card.id} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} transition={{ duration: 1.5 }}>
{cards.map((card, index) => (
<motion.div
key={card.id}
layout
initial={{ opacity: 0, y: 0 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{
opacity: { duration: 1 },
y: { delay: index * 0.5 },
}}
>
<TodoCard card={card} />
</motion.div>
))}
Expand Down
10 changes: 4 additions & 6 deletions src/components/dashboard/DetailTodo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { forwardRef, useState } from 'react';
import { Modal, ModalContent, ModalFooter, ModalHandle, ModalHeader } from '../ui/Modal/Modal';
import { motion } from 'motion/react';
import useAlert from '@/hooks/useAlert';
import { useRouter } from 'next/navigation';
import { Card } from '@/apis/cards/types';
import { deleteCard } from '@/apis/cards';
import CommentSection from './CommentSection';
import useConfirm from '@/hooks/useConfirm';
import Image from 'next/image';
Expand All @@ -18,6 +16,7 @@ import RoundChip from '../ui/Chip/RoundChip';
import { getErrorMessage } from '@/utils/errorMessage';
import { formatDate } from '@/utils/formatDate';
import { useColumnsQuery } from '@/apis/columns/queries';
import { useRemoveCard } from '@/apis/cards/queries';

interface DetailTodoProps {
card: Card;
Expand All @@ -29,8 +28,8 @@ const NO_IMAGE_BASE_URL = 'https://sprint-fe-project.s3.ap-northeast-2.amazonaws
const DetailTodo = forwardRef<ModalHandle, DetailTodoProps>(({ card, onEdit }, ref) => {
const alert = useAlert();
const confirm = useConfirm();
const router = useRouter();
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const { mutateAsync: remove } = useRemoveCard();

const formattedDueDate = formatDate(card.dueDate);

Expand All @@ -48,12 +47,11 @@ const DetailTodo = forwardRef<ModalHandle, DetailTodoProps>(({ card, onEdit }, r

if (!userConfirmed) return; // 취소 버튼을 누르면 진행 중단
try {
await deleteCard(card.id);
await remove(card.id);
alert('카드가 삭제되었습니다.');
if (ref && 'current' in ref && ref.current) {
ref.current.close();
ref?.current?.close();
}
router.push('/dashboard');
} catch (err) {
const message = getErrorMessage(err);
alert(message);
Expand Down
13 changes: 7 additions & 6 deletions src/components/ui/Field/AssignInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Image from 'next/image';
import XIcon from '@/assets/icons/x.svg';
import Avatar from '../Avatar/Avatar';
import { Member } from '@/apis/members/types';
import { Assignee } from '@/types/common';

const PAGE_SIZE = 5;

Expand All @@ -21,14 +22,15 @@ type AssignInputProps = BaseField &
Omit<InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> & {
value: number;
onChange: (assignId: number) => void;
defaultAssignee?: Assignee;
};

export function AssignInput({ onChange, label, required, error, className }: AssignInputProps) {
export function AssignInput({ onChange, label, required, error, className, defaultAssignee }: AssignInputProps) {
const params = useParams();
const dashboardId = Number(params.id);
const [page, setPage] = useState(1);
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const [selectedMember, setSelectedMember] = useState<Member>();
const [selectedAssignee, setSelectedAssignee] = useState<Assignee | null>(defaultAssignee ?? null);
const { data } = useMembersQuery({ dashboardId, page, size: PAGE_SIZE });
const id = useId();
const dropdownRef = useRef<HTMLDivElement>(null);
Expand All @@ -39,7 +41,7 @@ export function AssignInput({ onChange, label, required, error, className }: Ass

const handleSelectItem = (member: Member) => {
onChange(member.userId);
setSelectedMember(member);
setSelectedAssignee({ id: member.userId, nickname: member.nickname, profileImageUrl: member.profileImageUrl });
setIsDropdownOpen(false);
};

Expand All @@ -65,11 +67,11 @@ export function AssignInput({ onChange, label, required, error, className }: Ass
)}
<div ref={dropdownRef} className={cn(baseFieldClassName, 'relative flex h-auto min-h-[50px] items-center gap-2 px-4 py-2', error && baseErrorClassName, className)}>
<div onClick={handleInputClick} className='flex w-full items-center gap-2'>
{selectedMember?.userId && <Avatar email={selectedMember.email} profileImageUrl={selectedMember.profileImageUrl} className='h-8 w-8' />}
{selectedAssignee?.id && <Avatar profileImageUrl={selectedAssignee.profileImageUrl} nickname={selectedAssignee.nickname} className='h-8 w-8' />}
<input
type='text'
id={id}
value={selectedMember?.nickname || ''}
value={selectedAssignee?.nickname || ''}
readOnly
placeholder='담당자를 지정해 주세요'
className={cn('flex flex-1 text-black focus-visible:outline-none', className)}
Expand All @@ -87,7 +89,6 @@ export function AssignInput({ onChange, label, required, error, className }: Ass
>
<li className='mb-2 flex h-10 items-center justify-between px-2'>
<div className='flex items-center gap-4'>
<span>담당자 목록</span>
<PaginationWithCounter totalCount={data?.totalCount || 0} page={page} setPage={setPage} pageSize={PAGE_SIZE} />
</div>

Expand Down
6 changes: 6 additions & 0 deletions src/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ export type BaseCursor = {
};

export type NavigationMethod = 'infiniteScroll' | 'pagination';

export interface Assignee {
id: number;
nickname: string;
profileImageUrl: string | null;
}