하이어+플러스! 직원용 구축 방법은 다음과 같습니다(UI - 모달).
79354 단어 tutorialprogrammingreactwebdev
프로젝트 모달 구성 요소
인사이드
components > modal > project-modal.component.tsx
ProjectPopupModalProps
, 이 구성 요소에 전달되는 소품 유형을 정의합니다. defaultFormFields
편집할 모달의 필드. defaultFormFields
의 기본 상태로 projectFields
를 사용했습니다.import React, { ChangeEvent, useState } from 'react';
import { setProjects } from '../../app/features/profile/profileSlice';
import { useAppDispatch, useAppSelector } from '../../app/hooks';
interface ProjectPopupModalProps {
isProjOpen: boolean;
closeProjModal: () => void;
}
const defaultFormFields = {
date: '',
title: '',
summary: '',
github: '',
projectUrl: '',
};
기능
onHandleChange
, onTextareaChange
- 양식 필드의 상태 변경을 처리합니다.resetFormFields
- 제출 후 양식 필드를 재설정합니다.addProject
- profile.projects
내에서 profileSlice
상태에 대한 프로젝트를 설정하고 양식을 재설정한 다음 나중에 모달을 닫습니다.const ProjectPopupModal: React.FC<ProjectPopupModalProps> = ({
isProjOpen,
closeProjModal,
}) => {
const dispatch = useAppDispatch();
const { profile } = useAppSelector((state) => state.profile);
const [projectFields, setProjectFields] = useState(defaultFormFields);
const onHandleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setProjectFields({ ...projectFields, [name]: value });
};
const onTextareaChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
const { value } = e.target;
setProjectFields({ ...projectFields, summary: value });
};
const resetFormFields = () => {
setProjectFields(defaultFormFields);
};
const addProject = (e: ChangeEvent<HTMLFormElement>) => {
e.preventDefault();
dispatch(
setProjects([
{
date: projectFields.date,
title: projectFields.title,
summary: projectFields.summary,
github: projectFields.github,
projectUrl: projectFields.projectUrl,
},
...profile.projects,
])
);
resetFormFields();
setProjectFields(projectFields);
closeProjModal();
};
return ( {/* removed for simplicity */} );
};
export default ProjectPopupModal;
UI
isProjOpen
가 true로 설정된 경우 팝업 모달을 렌더링하고 모든 필드를 편집합니다.const ProjectPopupModal: React.FC<ProjectPopupModalProps> = ({
isProjOpen,
closeProjModal,
}) => {
{/* removed for simplicity */}
return (
<div
className="py-12 bg-gray-700 transition duration-150 ease-in-out z-10 absolute right-0 bottom-0 left-0 h-screen"
id="modal"
style={{ display: `${isProjOpen ? 'block' : 'none'}`, top: '850px' }}
>
<div role="alert" className="container mx-auto w-11/12 md:w-2/3 max-w-lg">
<div className="relative py-8 px-5 md:px-10 bg-white shadow-md rounded border border-gray-400">
<div className="w-full flex justify-center text-gray-600 mb-3">
<svg
xmlns="http://www.w3.org/2000/svg"
className="icon icon-tabler icon-tabler-wallet"
width="52"
height="52"
viewBox="0 0 24 24"
strokeWidth="1"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" />
<path d="M17 8v-3a1 1 0 0 0 -1 -1h-10a2 2 0 0 0 0 4h12a1 1 0 0 1 1 1v3m0 4v3a1 1 0 0 1 -1 1h-12a2 2 0 0 1 -2 -2v-12" />
<path d="M20 12v4h-4a2 2 0 0 1 0 -4h4" />
</svg>
</div>
<h1 className="text-gray-800 font-lg font-bold tracking-normal leading-tight mb-4 text-center text-lg">
Add Project
</h1>
<form onSubmit={addProject}>
<label
htmlFor="name"
className="text-gray-800 text-sm font-bold leading-tight tracking-normal"
>
Project Name
</label>
<input
type="text"
required
name="title"
onChange={onHandleChange}
value={projectFields.title}
id="name"
className="mb-5 mt-2 text-gray-600 focus:outline-none focus:border focus:border-indigo-700 font-normal w-full h-10 flex items-center pl-3 text-sm border-gray-300 rounded border"
placeholder="Full stack react"
/>
{/* Project Date */}
<label
htmlFor="date"
className="text-gray-800 text-sm font-bold leading-tight tracking-normal"
>
Date
</label>
<div className="relative mb-5 mt-2">
<div className="absolute right-0 text-gray-600 flex items-center pr-3 h-full cursor-pointer">
<svg
xmlns="http://www.w3.org/2000/svg"
className="icon icon-tabler icon-tabler-calendar-event"
width="20"
height="20"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" />
<rect x="4" y="5" width="16" height="16" rx="2" />
<line x1="16" y1="3" x2="16" y2="7" />
<line x1="8" y1="3" x2="8" y2="7" />
<line x1="4" y1="11" x2="20" y2="11" />
<rect x="8" y="15" width="2" height="2" />
</svg>
</div>
<input
name="date"
onChange={onHandleChange}
value={projectFields.date}
id="date"
className="text-gray-600 focus:outline-none focus:border focus:border-indigo-700 font-normal w-full h-10 flex items-center pl-3 text-sm border-gray-300 rounded border"
placeholder="MM/YY"
/>
</div>
{/* project github */}
<label
htmlFor="github"
className="text-gray-800 text-sm font-bold leading-tight tracking-normal"
>
Project Github
</label>
<input
type="text"
name="github"
onChange={onHandleChange}
value={projectFields.github}
id="github"
className="mb-5 mt-2 text-gray-600 focus:outline-none focus:border focus:border-indigo-700 font-normal w-full h-10 flex items-center pl-3 text-sm border-gray-300 rounded border"
placeholder="[email protected]"
required
/>
<label
htmlFor="projectUrl"
className="text-gray-800 text-sm font-bold leading-tight tracking-normal"
>
Project URL
</label>
<input
name="projectUrl"
onChange={onHandleChange}
value={projectFields.projectUrl}
id="projectUrl"
className="mb-5 mt-2 text-gray-600 focus:outline-none focus:border focus:border-indigo-700 font-normal w-full h-10 flex items-center pl-3 text-sm border-gray-300 rounded border"
placeholder="www.coolwebapp.com"
required
/>
<label
htmlFor="description"
className="text-gray-800 text-sm font-bold leading-tight tracking-normal"
>
Project Summary
</label>
<textarea
name="summary"
onChange={onTextareaChange}
value={projectFields.summary}
maxLength={300}
id="description"
className="mb-5 mt-2 text-gray-600 focus:outline-none focus:border focus:border-indigo-700 font-normal w-full flex items-center px-3 py-3 text-sm border-gray-300 rounded border"
placeholder="Authentication, testing, etc."
required
/>
<div className="flex items-center justify-start w-full">
<button
type="submit"
className="focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-700 transition duration-150 ease-in-out hover:bg-indigo-600 bg-indigo-700 rounded text-white px-8 py-2 text-sm"
>
Submit
</button>
<button
type="button"
onClick={closeProjModal}
aria-label="close modal"
className="focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-400 ml-3 bg-gray-100 transition duration-150 text-gray-600 ease-in-out hover:border-gray-400 hover:bg-gray-300 border rounded px-8 py-2 text-sm"
>
Cancel
</button>
</div>
</form>
<button
className="cursor-pointer absolute top-0 right-0 mt-4 mr-5 text-gray-400 hover:text-gray-600 transition duration-150 ease-in-out rounded focus:ring-2 focus:outline-none focus:ring-gray-600"
aria-label="close modal"
onClick={closeProjModal}
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="icon icon-tabler icon-tabler-x"
width="20"
height="20"
viewBox="0 0 24 24"
strokeWidth="2.5"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" />
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</button>
</div>
</div>
</div>
);
};
export default ProjectPopupModal;
스크린샷
모달 구성 요소 경험
인사이드
components > modal > experience-modal.component.tsx
ExperiencePopupModalProps
, 이 구성 요소에 전달되는 소품 유형을 정의합니다. defaultFormFields
편집할 모달의 필드. defaultFormFields
의 기본 상태로 experienceFields
를 사용했습니다.import { ChangeEvent, useState } from 'react';
import { setExperiences } from '../../app/features/profile/profileSlice';
import { useAppDispatch, useAppSelector } from '../../app/hooks';
interface ExperiencePopupModalProps {
isOpen: boolean;
closeModal: () => void;
}
const defaultFormFields = {
date: '',
position: '',
positionSummary: '',
};
기능
onHandleChange
, onTextareaChange
- 양식 필드의 상태 변경을 처리합니다.resetFormFields
- 제출 후 양식 필드를 재설정합니다.addExperience
- profile.experience
내에서 profileSlice
상태에 대한 경험을 설정하고 양식을 재설정한 다음 나중에 모달을 닫습니다.const ExperiencePopupModal: React.FC<ExperiencePopupModalProps> = ({
isOpen,
closeModal,
}) => {
const dispatch = useAppDispatch();
const { profile } = useAppSelector((state) => state.profile);
const [experienceFields, setExperienceFields] = useState(defaultFormFields);
const onHandleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setExperienceFields({ ...experienceFields, [name]: value });
};
const onTextareaChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
const { value } = e.target;
setExperienceFields({ ...experienceFields, positionSummary: value });
};
const resetFormFields = () => {
setExperienceFields(defaultFormFields);
};
const addExperience = (e: ChangeEvent<HTMLFormElement>) => {
e.preventDefault();
dispatch(
setExperiences([
{
position: experienceFields.position,
positionSummary: experienceFields.positionSummary,
date: experienceFields.date,
},
...profile.experience,
])
);
resetFormFields();
closeModal();
};
return ( {/* removed for simplicity */} );
};
export default ExperiencePopupModal;
UI
팝업 모달과 편집할 모든 필드를 렌더링합니다.
const ExperiencePopupModal: React.FC<ExperiencePopupModalProps> = ({
isOpen,
closeModal,
}) => {
{/* removed for simplicity */}
return (
<div
className="py-12 bg-gray-700 transition duration-150 ease-in-out z-10 absolute right-0 bottom-0 left-0 h-screen"
id="modal"
style={{ display: `${isOpen ? 'block' : 'none'}`, top: '880px' }}
>
<div role="alert" className="container mx-auto w-11/12 md:w-2/3 max-w-lg">
<div className="relative py-8 px-5 md:px-10 bg-white shadow-md rounded border border-gray-400">
<div className="w-full flex justify-center text-gray-600 mb-3">
<svg
xmlns="http://www.w3.org/2000/svg"
className="icon icon-tabler icon-tabler-wallet"
width="52"
height="52"
viewBox="0 0 24 24"
strokeWidth="1"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" />
<path d="M17 8v-3a1 1 0 0 0 -1 -1h-10a2 2 0 0 0 0 4h12a1 1 0 0 1 1 1v3m0 4v3a1 1 0 0 1 -1 1h-12a2 2 0 0 1 -2 -2v-12" />
<path d="M20 12v4h-4a2 2 0 0 1 0 -4h4" />
</svg>
</div>
<h1 className="text-gray-800 font-lg font-bold tracking-normal leading-tight mb-4 text-center text-lg">
Add Job Experience
</h1>
<form onSubmit={addExperience}>
<label
htmlFor="title"
className="text-gray-800 text-sm font-bold leading-tight tracking-normal"
>
Position Title
</label>
<input
required
name="position"
onChange={onHandleChange}
value={experienceFields.position}
id="title"
className="mb-5 mt-2 text-gray-600 focus:outline-none focus:border focus:border-indigo-700 font-normal w-full h-10 flex items-center pl-3 text-sm border-gray-300 rounded border"
placeholder="Front-End Developer"
/>
<label
htmlFor="description"
className="text-gray-800 text-sm font-bold leading-tight tracking-normal"
>
Position Summary
</label>
<textarea
required
name="description"
onChange={onTextareaChange}
value={experienceFields.positionSummary}
maxLength={1000}
id="description"
className="mb-5 mt-2 text-gray-600 focus:outline-none focus:border focus:border-indigo-700 font-normal w-full flex items-center px-3 py-3 text-sm border-gray-300 rounded border"
placeholder="Job details..."
/>
<label
htmlFor="date"
className="text-gray-800 text-sm font-bold leading-tight tracking-normal"
>
Date
</label>
<div className="relative mb-5 mt-2">
<div className="absolute right-0 text-gray-600 flex items-center pr-3 h-full cursor-pointer">
<svg
xmlns="http://www.w3.org/2000/svg"
className="icon icon-tabler icon-tabler-calendar-event"
width="20"
height="20"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" />
<rect x="4" y="5" width="16" height="16" rx="2" />
<line x1="16" y1="3" x2="16" y2="7" />
<line x1="8" y1="3" x2="8" y2="7" />
<line x1="4" y1="11" x2="20" y2="11" />
<rect x="8" y="15" width="2" height="2" />
</svg>
</div>
<input
required
name="date"
onChange={onHandleChange}
value={experienceFields.date}
id="date"
className="text-gray-600 focus:outline-none focus:border focus:border-indigo-700 font-normal w-full h-10 flex items-center pl-3 text-sm border-gray-300 rounded border"
placeholder="MM/YY"
/>
</div>
<div className="flex items-center justify-start w-full">
<button
type="submit"
className="focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-700 transition duration-150 ease-in-out hover:bg-indigo-600 bg-indigo-700 rounded text-white px-8 py-2 text-sm"
>
Submit
</button>
<button
aria-label="close modal"
type="button"
onClick={closeModal}
className="focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-400 ml-3 bg-gray-100 transition duration-150 text-gray-600 ease-in-out hover:border-gray-400 hover:bg-gray-300 border rounded px-8 py-2 text-sm"
>
Cancel
</button>
</div>
</form>
<button
className="cursor-pointer absolute top-0 right-0 mt-4 mr-5 text-gray-400 hover:text-gray-600 transition duration-150 ease-in-out rounded focus:ring-2 focus:outline-none focus:ring-gray-600"
aria-label="close modal"
onClick={closeModal}
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="icon icon-tabler icon-tabler-x"
width="20"
height="20"
viewBox="0 0 24 24"
strokeWidth="2.5"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" />
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</button>
</div>
</div>
</div>
);
};
export default ExperiencePopupModal;
스크린샷
프로젝트의 UI/모달 부분은 여기까지입니다. 계속 지켜봐 주세요!
Reference
이 문제에 관하여(하이어+플러스! 직원용 구축 방법은 다음과 같습니다(UI - 모달).), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ajeasmith/hireplus-for-employees-heres-how-i-built-it-ui-modals-3l92텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)