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

[Design] 추가될 데이터 input들 변경하기 #101

Merged
merged 4 commits into from
Oct 10, 2021
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
121 changes: 94 additions & 27 deletions src/pages/CreateDesign/Detail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,55 @@
import {
FormControlLabel,
Grid,
Input,
InputAdornment,
InputProps,
ListSubheader,
MenuItem,
Radio,
RadioGroup,
SelectProps,
Typography,
} from '@material-ui/core';
import { RequiredSelect, RequiredInput, FormLabel } from 'dumbs';
import React from 'react';
import { useRecoilState } from 'recoil';
import styled from 'styled-components';
import { flexVerticalAlign } from 'styles/constants';
import { theme } from 'themes';
import { palette } from 'themes/palette';
import { renderDesign, renderPattern } from 'utils/renderText';

import DesignSizeImage from '../components/DesignSizeImage';
import { currentDesignInputAtom } from '../recoils';
import { DESIGN, DESIGN_TYPE, PATTERN, PATTERN_TYPE } from '../types';
import {
DESIGN,
DESIGN_TYPE,
LevelKind,
LEVEL_TYPE,
PATTERN,
PATTERN_TYPE,
} from '../types';

const FullWithInput = styled(Input)`
width: 100%;
`;

const NumberInput = styled(Input)`
width: 100%;
const Row = styled(Grid)`
padding: ${theme.spacing(1.5)};
`;

const LevelLabel = styled.div`
${flexVerticalAlign}

input {
text-align: right;
span {
margin-right: ${theme.spacing(1.5)};
}
`;

const Row = styled(Grid)`
padding: ${theme.spacing(1.5)};
h6 {
font-weight: 400;
color: ${palette.text.secondary};
}
`;

const Detail = (): React.ReactElement => {
Expand All @@ -50,9 +68,11 @@ const Detail = (): React.ReactElement => {
needle,
yarn,
extra,
price,
designType,
patternType,
description,
techniques,
targetLevel,
} = currentDesignInput;

const { SWEATER } = DESIGN;
Expand Down Expand Up @@ -148,25 +168,42 @@ const Detail = (): React.ReactElement => {
extra: currentTarget.value,
});
};
const onChangePrice: InputProps['onChange'] = ({ currentTarget }) => {
const onChangeDesignType: SelectProps['onChange'] = ({ currentTarget }) => {
if (currentTarget == null) return;
setCurrentDesignInputAtom({
...currentDesignInput,
price: getNumberToChange(currentTarget),
designType: currentTarget.value as DESIGN_TYPE,
});
};
const onChangeDesignType: SelectProps['onChange'] = ({ currentTarget }) => {
const onChangePatternType: SelectProps['onChange'] = ({ currentTarget }) => {
if (currentTarget == null) return;
setCurrentDesignInputAtom({
...currentDesignInput,
designType: currentTarget.value as DESIGN_TYPE,
patternType: currentTarget.value as PATTERN_TYPE,
});
};
const onChangePatternType: SelectProps['onChange'] = ({ currentTarget }) => {

const onChangeDescription: InputProps['onChange'] = ({ currentTarget }) => {
if (currentTarget == null) return;
setCurrentDesignInputAtom({
...currentDesignInput,
patternType: currentTarget.value as PATTERN_TYPE,
description: currentTarget.value,
});
};

const onChangeTechniques: InputProps['onChange'] = ({ currentTarget }) => {
if (currentTarget == null) return;
setCurrentDesignInputAtom({
...currentDesignInput,
techniques: currentTarget.value,
});
};

const onChangeLevelType: SelectProps['onChange'] = ({ currentTarget }) => {
if (currentTarget == null) return;
setCurrentDesignInputAtom({
...currentDesignInput,
targetLevel: currentTarget.value as LEVEL_TYPE,
});
};

Expand Down Expand Up @@ -215,6 +252,48 @@ const Detail = (): React.ReactElement => {
</RequiredSelect>
</Grid>
</Row>
<Row item xs={12}>
<FormLabel variant="h5">도안 한 줄 소개</FormLabel>
<FullWithInput
id="description"
aria-describedby="description"
placeholder="예) 어디서나 잘 어울리는 기본 니트 도안"
value={description}
onChange={onChangeDescription}
/>
</Row>
<Row item xs={12}>
<FormLabel variant="h5">뜨개 기법</FormLabel>
<FullWithInput
id="techniques"
aria-describedby="techniques"
placeholder="예) 겉뜨기, 안뜨기, 원통뜨기"
value={techniques}
onChange={onChangeTechniques}
/>
</Row>
<Row item xs={12}>
<FormLabel variant="h5">난이도</FormLabel>
<RadioGroup value={targetLevel} onChange={onChangeLevelType}>
{LevelKind.map(
({ value, label, description: levelDescription }) => (
<FormControlLabel
key={value}
value={value}
control={<Radio color="primary" />}
label={
<LevelLabel>
<span>{label}</span>
<Typography variant="subtitle2">
{levelDescription}
</Typography>
</LevelLabel>
}
/>
),
)}
</RadioGroup>
</Row>
<Row container>
<FormLabel variant="h5">게이지</FormLabel>
<FormLabel>10 x 10(cm) 편물의 코와 단을 공유해주세요.</FormLabel>
Expand Down Expand Up @@ -359,18 +438,6 @@ const Detail = (): React.ReactElement => {
onChange={onChangeExtra}
/>
</Row>
<Row item xs={12}>
<FormLabel variant="h5">판매 가격</FormLabel>
<NumberInput
id="price"
type="number"
aria-describedby="price"
endAdornment={<InputAdornment position="end">원</InputAdornment>}
value={price}
onChange={onChangePrice}
inputProps={{ min: 0 }}
/>
</Row>
</Grid>
</form>
</>
Expand Down
14 changes: 0 additions & 14 deletions src/pages/CreateDesign/Review/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import styled from 'styled-components';
import DesignSizeImage from '../components/DesignSizeImage';
import { currentDesignInputAtom, editorStateAtom } from '../recoils';
import { PATTERN, PATTERN_TYPE } from '../types';
import { formatNumber } from '../utils';

const Title = styled(Typography)`
font-weight: 600;
Expand Down Expand Up @@ -42,7 +41,6 @@ const Review = (): React.ReactElement => {
needle,
yarn,
extra,
price,
designType,
patternType,
} = currentDesignInput;
Expand All @@ -64,14 +62,6 @@ const Review = (): React.ReactElement => {
}
};

const renderPrice = (patternPrice: number): string => {
if (patternPrice === 0) {
return '무료 나눔';
} else {
return `${formatNumber(patternPrice)}원`;
}
};

return (
<>
<Grid container>
Expand Down Expand Up @@ -136,10 +126,6 @@ const Review = (): React.ReactElement => {
<Label variant="h4">추가 재료</Label>
<Contents>{extra}</Contents>
</Row>
<Row item xs={12}>
<Label variant="h4">판매 가격</Label>
<Contents>{renderPrice(price)}</Contents>
</Row>
<Row item xs={12}>
<Label variant="h4">도안</Label>
<Contents>
Expand Down
2 changes: 0 additions & 2 deletions src/pages/CreateDesign/components/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ const Footer = (): React.ReactElement => {
needle,
yarn,
extra,
price,
designType,
patternType,
} = useRecoilValue(currentDesignInputAtom);
Expand Down Expand Up @@ -76,7 +75,6 @@ const Footer = (): React.ReactElement => {
needle,
yarn,
extra,
price,
pattern: `${JSON.stringify(
convertToRaw(editorState.getCurrentContent()),
)}`,
Expand Down
6 changes: 4 additions & 2 deletions src/pages/CreateDesign/recoils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EditorState } from 'draft-js';
import { atom } from 'recoil';

import { DESIGN, DesignInput, PAGE, PAGE_TYPE, PATTERN } from './types';
import { DESIGN, DesignInput, LEVEL, PAGE, PAGE_TYPE, PATTERN } from './types';

export const currentStepAtom = atom<PAGE_TYPE>({
key: 'currentStep',
Expand All @@ -14,6 +14,9 @@ export const currentDesignInputAtom = atom<DesignInput>({
name: '',
designType: DESIGN.SWEATER,
patternType: PATTERN.TEXT,
description: '',
techniques: '',
targetLevel: LEVEL.NORMAL,
stitches: 0,
rows: 0,
totalLength: 0,
Expand All @@ -24,7 +27,6 @@ export const currentDesignInputAtom = atom<DesignInput>({
needle: '',
yarn: '',
extra: undefined,
price: 0,
pattern: '',
},
});
Expand Down
49 changes: 40 additions & 9 deletions src/pages/CreateDesign/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { SnakeToCamelCase } from 'utils/types';

export const PAGE = {
DETAIL: 0,
PATTERN: 1,
Expand All @@ -20,20 +22,49 @@ export const PATTERN = {

export type PATTERN_TYPE = typeof PATTERN[keyof typeof PATTERN];

export type DesignInput = {
export const LEVEL = {
EASY: 'EASY',
NORMAL: 'NORMAL',
HARD: 'HARD',
} as const;
export type LEVEL_TYPE = typeof LEVEL[keyof typeof LEVEL];

export const LevelKind = [
{
value: LEVEL.EASY,
label: '쉬움',
description: '이제 막 뜨개질을 시작한 사람!',
},
{
value: LEVEL.NORMAL,
label: '보통',
description: '겉뜨기, 안뜨기, 코잡기는 쉽게 가능한 사람!',
},
{
value: LEVEL.HARD,
label: '어려움',
description: '니트, 양말, 모자 하나 정도는 떠본 사람!',
},
];

export type PostDesignInput = {
name: string;
designType: DESIGN_TYPE;
patternType: PATTERN_TYPE;
design_type: DESIGN_TYPE;
pattern_type: PATTERN_TYPE;
description: string;
techniques: string;
target_level: LEVEL_TYPE;
stitches: number;
rows: number;
totalLength: number;
sleeveLength: number;
shoulderWidth: number;
bottomWidth: number;
armholeDepth: number;
total_length: number;
sleeve_length: number;
shoulder_width: number;
bottom_width: number;
armhole_depth: number;
needle: string;
yarn: string;
extra?: string;
price: number;
pattern: string;
};

export type DesignInput = SnakeToCamelCase<PostDesignInput>;
15 changes: 15 additions & 0 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
type BasicSnakeToCamelCase<
zoripong marked this conversation as resolved.
Show resolved Hide resolved
S extends string
> = S extends `${infer FirstLetter}_${infer SecondLetter}`
? `${Lowercase<FirstLetter>}${Capitalize<
BasicSnakeToCamelCase<SecondLetter>
>}`
: Lowercase<S>;

export type SnakeToCamelCase<T> = T extends Record<string, unknown>
? {
[K in keyof T as BasicSnakeToCamelCase<K & string>]: SnakeToCamelCase<
T[K]
>;
}
: T;