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

UI: #62 모든 프로젝트 관리 페이지 중 팀/프로젝트가 있는 경우 UI 작성 #71

Merged
merged 3 commits into from
Aug 14, 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
27 changes: 27 additions & 0 deletions src/components/modal/project/CreateModalProject.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import ModalPortal from '@components/modal/ModalPortal';
import ModalLayout from '@layouts/ModalLayout';
import ModalProjectForm from '@components/modal/project/ModalProjectForm';
import ModalFormButton from '@components/modal/ModalFormButton';

import type { SubmitHandler } from 'react-hook-form';
import type { Project } from '@/types/ProjectType';

type CreateModalProjectProps = {
onClose: () => void;
};

export default function CreateModalProject({ onClose: handleClose }: CreateModalProjectProps) {
const handleSubmit: SubmitHandler<Project> = async (data) => {
console.log('프로젝트 생성 폼 제출');
console.log(data);
handleClose();
};
return (
<ModalPortal>
<ModalLayout onClose={handleClose}>
<ModalProjectForm formId="createProjectForm" onSubmit={handleSubmit} />
<ModalFormButton formId="createProjectForm" isCreate onClose={handleClose} />
</ModalLayout>
</ModalPortal>
);
}
18 changes: 18 additions & 0 deletions src/components/modal/project/ModalProjectForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useForm } from 'react-hook-form';

import type { SubmitHandler } from 'react-hook-form';
import type { Project } from '@/types/ProjectType';

type ModalProjectFormProps = {
formId: string;
onSubmit: SubmitHandler<Project>;
};

export default function ModalProjectForm({ formId, onSubmit }: ModalProjectFormProps) {
const { handleSubmit } = useForm<Project>();
return (
<form id={formId} className="mb-10 flex grow flex-col justify-center" onSubmit={handleSubmit(onSubmit)}>
project form
</form>
);
}
28 changes: 28 additions & 0 deletions src/components/modal/project/UpdateModalProject.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import ModalPortal from '@components/modal/ModalPortal';
import ModalLayout from '@layouts/ModalLayout';
import ModalProjectForm from '@components/modal/project/ModalProjectForm';
import ModalFormButton from '@components/modal/ModalFormButton';

import type { SubmitHandler } from 'react-hook-form';
import type { Project } from '@/types/ProjectType';

type UpdateModalProjectProps = {
projectId: Project['projectId'];
onClose: () => void;
};

export default function UpdateModalProject({ projectId, onClose: handleClose }: UpdateModalProjectProps) {
const handleSubmit: SubmitHandler<Project> = async (data) => {
console.log('프로젝트 생성 폼 제출');
console.log(data);
handleClose();
};
return (
<ModalPortal>
<ModalLayout onClose={handleClose}>
<ModalProjectForm formId="updateProjectForm" projectId={projectId} onSubmit={handleSubmit} />
<ModalFormButton formId="updateProjectForm" isCreate={false} onClose={handleClose} />
</ModalLayout>
</ModalPortal>
);
}
27 changes: 27 additions & 0 deletions src/components/modal/team/UpdateModalTeam.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import ModalLayout from '@layouts/ModalLayout';
import ModalPortal from '@components/modal/ModalPortal';
import ModaFormButton from '@components/modal/ModalFormButton';
import ModalTeamForm from '@components/modal/team/ModalTeamForm';

import { SubmitHandler } from 'react-hook-form';
import { Team } from '@/types/TeamType';

type UpdateModalTeamProps = {
teamId: Team['teamId'];
onClose: () => void;
};
export default function UpdateModalTeam({ teamId, onClose: handleClose }: UpdateModalTeamProps) {
const handleSubmit: SubmitHandler<Team> = async (data) => {
console.log(teamId, '수정 폼 제출');
console.log(data);
handleClose();
};
return (
<ModalPortal>
<ModalLayout onClose={handleClose}>
<ModalTeamForm formId="updateTeamForm" teamId={teamId} onSubmit={handleSubmit} />
<ModaFormButton formId="updateTeamForm" isCreate={false} onClose={handleClose} />
</ModalLayout>
</ModalPortal>
);
}
54 changes: 41 additions & 13 deletions src/components/sidebar/ListTeam.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { useState } from 'react';
import { Link } from 'react-router-dom';
import { IoIosSettings } from 'react-icons/io';
import UpdateModalTeam from '@/components/modal/team/UpdateModalTeam'; // Import the UpdateModalTeam component
import useModal from '@/hooks/useModal';
import type { Team } from '@/types/TeamType';

type ListTeamProps = {
Expand All @@ -7,19 +11,43 @@ type ListTeamProps = {
};

export default function ListTeam({ data, targetId }: ListTeamProps) {
const { showModal: showUpdateModal, openModal: openUpdateModal, closeModal: closeUpdateModal } = useModal();
const [selectedTeamId, setSelectedTeamId] = useState<Team['teamId'] | null>(null);

const handleOpenUpdateModal = (teamId: Team['teamId']) => {
setSelectedTeamId(teamId);
openUpdateModal();
};

return (
<ul className="grow overflow-auto">
{data.map((team) => (
<li
key={team.teamId}
className={`relative cursor-pointer border-b bg-white hover:brightness-90 ${targetId === team.teamId.toString() ? 'selected' : ''}`}
>
<Link to={`/teams/${team.teamId}`} className="flex h-30 flex-col justify-center px-10">
<small className="font-bold text-category">Team</small>
<span>{team.name}</span>
</Link>
</li>
))}
</ul>
<>
<ul className="grow overflow-auto">
{data.map((team) => (
<li
key={team.teamId}
className={`relative cursor-pointer border-b bg-white hover:brightness-90 ${targetId === team.teamId.toString() ? 'selected' : ''}`}
>
<div className="flex justify-between">
<Link to={`/teams/${team.teamId}`} className="flex h-30 flex-grow flex-col justify-center px-10">
<small className="font-bold text-category">Team</small>
<span>{team.name}</span>
</Link>
<button
className="mr-6 flex items-center text-main hover:brightness-50"
type="button"
onClick={(e) => {
e.preventDefault();
handleOpenUpdateModal(team.teamId); // Open the update modal with the selected team ID
}}
>
<IoIosSettings size={20} />
setting
</button>
</div>
</li>
))}
</ul>
{showUpdateModal && selectedTeamId && <UpdateModalTeam teamId={selectedTeamId} onClose={closeUpdateModal} />}
</>
);
}
5 changes: 2 additions & 3 deletions src/layouts/page/TeamLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ export default function TeamLayout() {
<>
<section className="flex h-full p-15">
<ListSidebar title="팀 목록" showButton text="팀 생성" onClick={openTeamModal}>
{/* ToDo: 사이드바 팀정보 추가 예정 */}
<div />
<ListTeam data={TEAM_DUMMY} targetId={teamId} />
</ListSidebar>
<section className="flex w-2/3 flex-col border border-list bg-contents-box">
<section className="flex h-full w-2/3 flex-col border border-list bg-contents-box">
{teamData.length === 0 ? (
<div className="flex h-full items-center justify-center text-center">
소속된 팀이 없습니다! <br />
Expand Down
100 changes: 99 additions & 1 deletion src/pages/team/TeamPage.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,101 @@
import { IoIosSettings } from 'react-icons/io';
import { FaRegTrashAlt } from 'react-icons/fa';
import { useParams, Link } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { PROJECT_DUMMY, TEAM_DUMMY } from '@/mocks/mockData';
import CreateModalProject from '@/components/modal/project/CreateModalProject';
import useModal from '@/hooks/useModal';
import UpdateModalProject from '@/components/modal/project/UpdateModalProject';
import type { Project } from '@/types/ProjectType';

export default function TeamPage() {
return <div>TeamPage</div>;
const { showModal: showProjectModal, openModal: openProjectModal, closeModal: closeProjectModal } = useModal();
const { showModal: showUpdateModal, openModal: openUpdateModal, closeModal: closeUpdateModal } = useModal();
const { teamId } = useParams();
const [teamProjects, setTeamProjects] = useState<Project[]>([]);
const [teamName, setTeamName] = useState<string>('');
const [selectedProjectId, setSelectedProjectId] = useState<Project['projectId'] | null>(null);

// ToDo: react-query로 대체
useEffect(() => {
const projects = PROJECT_DUMMY.filter((project) => project.teamId.toString() === teamId);
setTeamProjects(projects);

const team = TEAM_DUMMY.find((team) => team.teamId.toString() === teamId);
if (team) {
setTeamName(team.name);
}
}, [teamId]);
Seok93 marked this conversation as resolved.
Show resolved Hide resolved

const handleOpenUpdateModal = (projectId: Project['projectId']) => {
setSelectedProjectId(projectId);
openUpdateModal();
};

return (
<div className="flex h-full flex-col">
<div className="flex justify-between border-b">
<div className="flex h-30 items-center justify-center space-x-4 px-10">
<small className="text-xs font-bold text-main">Team</small>
<span> {teamName}</span>
</div>
<button type="button" onClick={openProjectModal} className="hover:brightness-70 mr-10 text-main">
+ 프로젝트 생성
</button>
</div>
<div className="flex-1 overflow-y-auto">
{/* ToDo: 컴포넌트 분리필요 */}
{teamProjects.length > 0 ? (
<ul>
{teamProjects.map((project) => (
<li key={project.projectId} className="border-b border-opacity-95">
<Link to={`/teams/${teamId}/projects/${project.projectId}`} className="flex h-40 items-center">
<div className="flex h-30 basis-3/12 flex-col justify-center px-10">
<small className="font-bold text-category">Project</small>
<span>{project.name}</span>
</div>
<div className="flex h-30 basis-8/12 flex-col justify-center px-10">
<small className="font-bold text-category">desc</small>
<span>{project.content}</span>
</div>
<div className="mr-6 flex basis-1/12 space-x-10">
<button
className="flex items-center text-main hover:brightness-50"
aria-label="Settings"
type="button"
onClick={(e) => {
e.preventDefault();
handleOpenUpdateModal(project.projectId);
}}
>
<IoIosSettings size={20} className="mr-2" />
setting
</button>
{/* ToDo: 프로젝트 삭제 기능 */}
<button
className="hover:brightness-200"
type="button"
aria-label="Delete"
onClick={(e) => e.preventDefault()}
>
<FaRegTrashAlt size={20} />
</button>
</div>
</Link>
</li>
))}
</ul>
) : (
<div className="flex h-full items-center justify-center text-center">
진행중인 프로젝트가 없습니다! <br />
새로운 프로젝트를 생성해보세요 😄
</div>
)}
</div>
{showProjectModal && <CreateModalProject onClose={closeProjectModal} />}
{showUpdateModal && selectedProjectId && (
<UpdateModalProject projectId={selectedProjectId} onClose={closeUpdateModal} />
)}
</div>
);
}