HDC Inbase Admin Front 프로젝트 저장소 입니다.
Type | Module |
---|---|
Language | |
Framework | |
Style | |
Design System |
- app - Next.js App Router Pattern
- public - 정적 파일 보관 디렉토리
- src
- components - 프로젝트에서 사용하는 컴포넌트를 정의합니다.
- hooks
- screens - 메뉴 기준으로 구성되어 있고, 레이아웃을 제외한 컨텐츠를 정의합니다.
- utils
- network/ssp - SSP 모듈에 접근하기 위한 요청 함수를 정의합니다.
- common.tsx - 공통으로 사용하는 함수를 정의합니다.
- constants.ts - 공통으로 사용하는 상수를 정의합니다.
- types.ts - app 디렉토리에서 사용하는 공통 타입을 정의합니다.
RDS 모듈을 설치하기 위해서는 패키지 참조를 .npmrc
를 통해 설정해야 합니다.
우선 Github PAT(personal Access Token) 발급 가이드를 참고 하여 Token을 발급 받으시길 바랍니다.
그런 다음 프로젝트 루트 디렉토리에 .npmrc
파일을 생성하여 아래 내용을 입력해 주세요.
//npm.pkg.github.com/:_authToken={발급 받은 토큰을 입력해 주세요.}
@r114dev:registry=https://npm.pkg.github.com/
- 모듈 설치
npm install
- 개발 모드 실행
npm run dev
- 프로덕션 모드 실행 (빌드 필수)
npm run build && npm run start
타이틀과 Breadcrumb이 들어가는 HeaderSection은 로그인을 제외한 모든 페이지에 공통으로 사용됩니다.
헤더 영역의 경우 레이아웃을 잡기 위한 스타일 컴포넌트인 HeaderSection
과 함수 컴포넌트 Header
의 합성으로 구성합니다.
Header 컴포넌트는 타이틀을 표시하기 위한 title
과 Breadcrumb 정의를 위한 breadcrumbItems
, 두 props로 구성이 되어 있습니다.
💡
Breadcrumb
의 경우 링크 잘못 입력되어 이탈되지 않도록 반드시 확인해 주세요.
상위 메뉴의 경우 페이지가 없는 경우가 대부분인데, 아래 예시 코드처럼 하위 메뉴 첫 번째로 라우팅 될 수 있게 설정해 주시면 됩니다.
key
값은 아무값이나 넣어도 괜찮지만 breadcrumbItems
내에 고유한 값을 입력해야 합니다.
편의상 문자열 숫자 오름차순 형태로 입력해 주면 되겠습니다.
// Sample Code
const Page = () => {
return (
{/* ... */}
<HeaderSection>
<Header
title="List 1"
breadcrumbItems={[
{
key: "1",
title: "샘플",
link: "/sample/list-1",
},
{
key: "2",
title: "리스트 1",
link: "/sample/list-1",
},
]}
/>
</HeaderSection>
{/* ... */}
)
}
모달은 디자인 시스템 내에 비지니스 로직을 담당하는 컴포넌트 중 하나인 core/Dialog
와 Modal
컴포넌트를 활용하여 구성합니다.
conflict issue를 고려하여 각 작업자들은 screen 폴더내에 사용하는 모달을 각자 생성하여 작업합니다.
Code Spliting Tip
- 해당 모달 고유 이름으로 함수 컴포넌트를 만들어 줍니다. (ex. DetailModal.tsx)
-
Modal
컴포넌트를 활용하여 해당 모달내에 네크워크 로직 상위 컴포넌트와 상호작용하는 로직을 작성합니다. - 상위 컴포넌트에서 모달을 트리거하는 요소에
Dialog
컴포넌트를 활용하여 작업을 마무리 합니다.
구조
// 디자인 시스템에 있는 Dialog를 활용합니다.
rds
core
Dialog
// 프로젝트 내 Modal 컴포넌트를 활용하여 DetailModal을 생성합니다.
// 생성한 DetailModal을 Dialog 컴포넌트와 합성하여 Detail 페이지에 추가합니다.
src
components
Modal
screens
상위메뉴
하위메뉴
Detail.tsx (DetailModal을 띄울 페이지)
DetailModal.tsx (Modal을 활용하여 만들어짐)
DetailModal.tsx 예시 코드
const DetailModal = ({ onSelect, onClose }) => {
return (
<Modal
size="large"
title="모달 타이틀"
primary={{ title: "선택", onClick: onSelect }}
secondary={{
title: "취소",
onClick: onClose,
}}
onClose={onClose}
>
{/* ... */}
</Modal>
);
};
Detail.tsx 예시 코드
import { core } from "@r114dev/rds";
const { Dialog } = core;
const Detail = () => {
const handleSelect = () => {
// ...
};
return (
<Dialog>
{({ handleClose }) => {
return (
<>
<Dialog.Trigger>
<button>상세보기</button>
</Dialog.Trigger>
<Dialog.Body>
<DetailModal onSelect={handleSelect} onClose={handleClose} />
</Dialog.Body>
</>
);
}}
</Dialog>
);
};
등록 / 수정 등 유효성검사가 필요한 화면에서 사용합니다.
디자인 시스템 core에 있는 Form
컴포넌트와 useForm
을 같이 사용하여야 하며, 아래 예시를 참고하여 작성하십시오.
필요에 따라 작업자가 registValidation
에 타입을 추가하여 사용할 수 있습니다.
import { core } from "@r114dev/rds";
import FormItem from "@/src/components/FormItem";
import { registValidation } from "@/src/utils/common";
const { Form, useForm } = core;
const App = () => {
const form = useForm({
initialValues: {
name: "",
age: "",
gender: "M",
},
validation: [
registValidation("name", "이름", "required"),
registValidation("name", "이름", "name"),
registValidation("name", "이름", ["min", 1]),
registValidation("name", "이름", ["max", 5]),
registValidation("age", "나이", "number"),
registValidation("gender", "성별", "required"),
],
});
return (
<Form form={form}>
<FormItem fieldKey="name">
<Input
value={form.values.name}
isError={!!form.errors.name}
onChange={(value) => form.handleValue("name", value)}
/>
</FormItem>
</Form>
);
};
리스트 1 레이아웃은 다음과 같이 세 가지 섹션으로 나누어 집니다.
- HeaderSection
- FilterSection
- TableSection
필터 영역의 경우 레이아웃을 잡기 위한 스타일 컴포넌트인 FilterSection
과 함수 컴포넌트 Filter
의 합성으로 구성합니다.
💡 모든 필터 리패칭은 적용 버튼 클릭시에 동작합니다.
하나의 행에 최대 두 항목의 필터가 들어갈 수 있고 각 항목은 title
과 input
영역으로 나뉩니다.
Filter
컴포넌트의 items
props에 배열 형태로 전달하면 화면이 정책에 맞게 구성 됩니다.
items
의 각 요소에는 inputs
라는 속성이 있습니다.
이를 이용하여, 복합 input 형태를 구현할 수 있습니다.
ratio
는 해당 input이 차지하는 비율을 나타내며 전체 6 중 차지하는 비율을 입력합니다.
💡
inputs
각 항목의 ratio 합이 다음과 같이 6을 넘지 않도록 해야합니다.
// Sample Code
const Page = () => {
const handleFilterSubmit = () => {
// refetch();
};
return (
<FilterSection>
<Filter
items={[
{
title: "검색어",
inputs: [
{
ratio: 2,
node: (
<StyledDropdown
selectedValue=""
options={[
{
value: "",
title: "선택",
},
{
value: "gender",
title: "성별",
},
{
value: "name",
title: "이름",
},
]}
/>
),
},
{
ratio: 4,
node: <StyledInput />,
},
],
},
]}
onSubmit={handleFilterSubmit}
/>
</FilterSection>
);
};
TableSection은 별도의 스타일 컴포넌트 합성없이 InbaseTable을 활용합니다.
RDS Table 기반으로 개발되어 있어 해당 링크의 문서 및 샘플 소스 코드를 참고하십시오.
빈 페이지가 나올 경우 아래 계정으로 로그인 후 다시 시도해 주세요.
developer@r114.com / qwer1234!@