Skip to content

Commit

Permalink
refactor(room-details): 컴포넌트 분리 (#23)
Browse files Browse the repository at this point in the history
* refactor(room-details): indicator 리팩토링

* refactor: 컴포넌트 분리
  • Loading branch information
Mincheol Kim authored Nov 29, 2020
1 parent 0e6a2ca commit 3843d59
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 193 deletions.
139 changes: 2 additions & 137 deletions src/features/checklist/components/ChecklistView.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
/**
* Expansion 기능을 제공해야 한다
* Header: Title, TriangleIcon
* Contents:
* SingleChoice: title, status, checks
* MultipleChoice: title, status, checks
*
* 프레임워크를 만드는 것이 아니기 때문에 공용 이름보다는 용도가 적힌 것이 좋다.
*/
import React, { CSSProperties, ReactElement, useState } from "react";
import React, { ReactElement } from "react";

import { CheckQuestion } from "../models";
import { groupBy } from "../utils";
import { ic_open } from "~/assets";
import { color } from "~/colors";

import CheckBox from "./CheckBox";
import QuestionPanel from "./QuestionPanel";

type Props = {
questions: Array<CheckQuestion>;
Expand All @@ -32,126 +20,3 @@ export default function ChecklistView({ questions }: Props): ReactElement {
</div>
);
}

const 확장뷰_style = (): CSSProperties => ({
display: "flex",
justifyContent: "space-between",
alignItems: "center",
height: 39,
fontSize: 16,
fontWeight: "bold",
fontStretch: "normal",
fontStyle: "normal",
lineHeight: 1.34,
letterSpacing: "normal",
color: color.grayscale29,
cursor: "pointer",
marginTop: 28,
});
const 밑줄_style = (): CSSProperties => ({
height: 1,
backgroundColor: color.primaryDullPurple,
marginTop: 2,
});
const 밑줄_style2 = (): CSSProperties => ({
width: 264,
height: 1,
backgroundColor: color.grayscalef9,
});
const 아이콘_style = (expand: boolean): CSSProperties => ({
transition: "all ease 0.5s",
transform: `rotate(${expand ? 180 : 360}deg)`,
});
const 콘텐츠_style = (expand: boolean): CSSProperties => ({
display: `${expand ? "block" : "none"}`,
});
const 행_style = (): CSSProperties => ({
display: "flex",
alignItems: "flex-start",
height: "auto",
padding: "9px 0 9px 0",
});
const 행_질문_style = (type: string): CSSProperties => ({
width: `${type === "MultipleChoice" ? "84px" : "auto"}`,
fontSize: 12,
alignSelf: "center",
flexGrow: 1,
});
type ItemProps = {
label: string;
questions: Array<CheckQuestion>;
};
export function QuestionPanel({ label, questions }: ItemProps): ReactElement {
const [expand, setExpand] = useState(false);
return (
<>
<QuestionPanelHeader label={label} expand={expand} click={setExpand} />
<div style={밑줄_style()} />
<div style={콘텐츠_style(expand)}>
{questions.map((question) => (
<div key={question.uid}>
<div style={행_style()}>
<span style={행_질문_style(question.type_)}>
{question.title}
</span>
{question.type_ === "MultipleChoice" ? (
<div
style={{
display: "grid",
alignSelf: "flex-end",
width: 174,
gridTemplateColumns: "0.5fr 2fr 0.5fr 2fr",
gap: "3px",
}}
>
{question?.checks?.map((check) => (
<CheckBox
key={check.uid}
uid={check.uid}
label={check.contents}
/>
))}
</div>
) : (
<div
style={{
display: "flex",
justifyContent: "flex-end",
flexGrow: 2,
}}
>
<CheckBox uid={question.uid} />
</div>
)}
</div>
<div style={밑줄_style2()} />
</div>
))}
</div>
</>
);
}

type HeaderProps = {
label: string;
expand: boolean;
click: CallableFunction;
};
function QuestionPanelHeader({
label,
expand,
click,
}: HeaderProps): ReactElement {
return (
<div style={확장뷰_style()} onClick={() => click(!expand)}>
<span>{label}</span>
<img
src={ic_open}
alt=""
width="24"
height="24"
style={아이콘_style(expand)}
/>
</div>
);
}
27 changes: 27 additions & 0 deletions src/features/checklist/components/MultipleChoiceView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { CSSProperties, ReactElement } from "react";

import { CheckItem } from "../models";

import CheckBox from "./CheckBox";

type MultipleChoiceViewProps = {
checks: Array<CheckItem>;
};
const 행_style = (): CSSProperties => ({
display: "grid",
alignSelf: "flex-end",
width: 174,
gridTemplateColumns: "0.5fr 2fr 0.5fr 2fr",
gap: "3px",
});
export default function MultipleChoiceView({
checks,
}: MultipleChoiceViewProps): ReactElement {
return (
<div style={행_style()}>
{checks?.map((check) => (
<CheckBox key={check.uid} uid={check.uid} label={check.contents} />
))}
</div>
);
}
43 changes: 43 additions & 0 deletions src/features/checklist/components/QuestionItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { CSSProperties, ReactElement } from "react";

import { CheckQuestion } from "../models";
import { color } from "~/colors";
import SingleChoiceView from "./SingleChoiceView";
import MultipleChoiceView from "./MultipleChoiceView";

type Props = {
question: CheckQuestion;
};
const 행_style = (): CSSProperties => ({
display: "flex",
alignItems: "flex-start",
height: "auto",
padding: "9px 0 9px 0",
});
const 행_질문_style = (type: string): CSSProperties => ({
width: `${type === "MultipleChoice" ? "84px" : "auto"}`,
fontSize: 12,
alignSelf: "center",
flexGrow: 1,
});

const 밑줄_style = (): CSSProperties => ({
width: 264,
height: 1,
backgroundColor: color.grayscalef9,
});
export default function QuestionItem({ question }: Props): ReactElement {
return (
<div>
<div style={행_style()}>
<span style={행_질문_style(question.type_)}>{question.title}</span>
{question.type_ === "MultipleChoice" ? (
<MultipleChoiceView checks={question.checks} />
) : (
<SingleChoiceView check={question.checks[0]} />
)}
</div>
<div style={밑줄_style()} />
</div>
);
}
87 changes: 87 additions & 0 deletions src/features/checklist/components/QuestionPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Expansion 기능을 제공
* Header: Title, TriangleIcon
* Contents:
* SingleChoice: title, status, checks
* MultipleChoice: title, status, checks
*/
import React, { CSSProperties, ReactElement, useState } from "react";

import { CheckQuestion } from "../models";
import { ic_open } from "~/assets";
import { color } from "~/colors";
import QuestionItem from "./QuestionItem";

const 확장뷰_style = (): CSSProperties => ({
display: "flex",
justifyContent: "space-between",
alignItems: "center",
height: 39,
fontSize: 16,
fontWeight: "bold",
fontStretch: "normal",
fontStyle: "normal",
lineHeight: 1.34,
letterSpacing: "normal",
color: color.grayscale29,
cursor: "pointer",
marginTop: 28,
});
const 밑줄_style = (): CSSProperties => ({
height: 1,
backgroundColor: color.primaryDullPurple,
marginTop: 2,
});
const 콘텐츠_style = (expand: boolean): CSSProperties => ({
display: `${expand ? "block" : "none"}`,
});
type ItemProps = {
label: string;
questions: Array<CheckQuestion>;
};
export default function QuestionPanel({
label,
questions,
}: ItemProps): ReactElement {
const [expand, setExpand] = useState(false);
return (
<>
<QuestionPanelHeader label={label} expand={expand} click={setExpand} />
<div style={밑줄_style()} />
<div style={콘텐츠_style(expand)}>
{questions.map((question) => (
<QuestionItem key={question.uid} question={question} />
))}
</div>
</>
);
}

type HeaderProps = {
label: string;
expand: boolean;
click: CallableFunction;
};
const 아이콘_style = (expand: boolean): CSSProperties => ({
transition: "all ease 0.5s",
transform: `rotate(${expand ? 180 : 360}deg)`,
});

function QuestionPanelHeader({
label,
expand,
click,
}: HeaderProps): ReactElement {
return (
<div style={확장뷰_style()} onClick={() => click(!expand)}>
<span>{label}</span>
<img
src={ic_open}
alt=""
width="24"
height="24"
style={아이콘_style(expand)}
/>
</div>
);
}
21 changes: 21 additions & 0 deletions src/features/checklist/components/SingleChoiceView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { CSSProperties, ReactElement } from "react";

import { CheckItem } from "../models";

import CheckBox from "./CheckBox";

type Props = {
check: CheckItem;
};
const 행_style = (): CSSProperties => ({
display: "flex",
justifyContent: "flex-end",
flexGrow: 2,
});
export default function SingleChoiceView({ check }: Props): ReactElement {
return (
<div style={행_style()}>
<CheckBox uid={check.uid} />
</div>
);
}
13 changes: 12 additions & 1 deletion src/features/checklist/components/index.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
import ChecklistView from "./ChecklistView";
export { ChecklistView };
import QuestionItem from "./QuestionItem";
import SingleChoiceView from "./SingleChoiceView";
import MultipleChoiceView from "./MultipleChoiceView";
import QuestionPanel from "./QuestionPanel";

export {
ChecklistView,
QuestionItem,
MultipleChoiceView,
SingleChoiceView,
QuestionPanel,
};
29 changes: 8 additions & 21 deletions src/features/rooms/components/RoomCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useHistory } from "react-router-dom";
import { Room, SELLING_TYPE_MATCHER } from "../models";
import { img_no_thumbnail } from "~/assets";
import { color } from "~/colors";
import RoomCardIndicator from "./RoomCardIndicator";
type Props = {
room: Room;
is_selected: boolean;
Expand All @@ -22,7 +23,6 @@ const 카드_style = ({ margin }: ThumbnailProps): CSSProperties => ({
cursor: "pointer",
margin: margin,
});

const 카드_썸네일_style = ({
width,
height,
Expand Down Expand Up @@ -115,26 +115,13 @@ function RoomCard({
SELLING_TYPE_MATCHER[room.selling_type]
} ${room.deposit}/${room.monthly_rent}`}</span>
</div>
{is_selected ? (
<div
style={{
backgroundColor: color.primaryYellow,
width: width,
height: 5,
borderRadius: 2.5,
marginTop: 3,
}}
/>
) : (
<div
style={{
width: width,
height: 5,
borderRadius: 2.5,
marginTop: 3,
}}
/>
)}
<RoomCardIndicator
visible={is_selected}
width={width}
height={5}
borderRadius={2.5}
marginTop={3}
/>
</div>
);
}
Expand Down
Loading

0 comments on commit 3843d59

Please sign in to comment.