Skip to content

Commit

Permalink
Merge pull request #40 from boostcampwm-2022/feat/PaceInput
Browse files Browse the repository at this point in the history
PaceInput ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑ
  • Loading branch information
gchoi96 authored Nov 21, 2022
2 parents ba040a7 + e6707ee commit 2a17915
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 41 deletions.
2 changes: 1 addition & 1 deletion client/src/components/Input/Input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ComponentStory, ComponentMeta } from "@storybook/react";
import Input from "./Input";

export default {
title: "Example/Input",
title: "Input/Input",
component: Input,
} as ComponentMeta<typeof Input>;

Expand Down
34 changes: 34 additions & 0 deletions client/src/components/Input/Input.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import styled from "styled-components";
import { COLOR } from "styles/color";

export const InputWrapper = styled.div<{ width: string }>`
display: flex;
padding: 16px;
border-bottom: ${`1px solid ${COLOR.BABY_BLUE}`};
width: ${({ width }) => width};
input {
color: ${COLOR.BLACK};
border: none;
:focus {
outline: none;
}
::placeholder {
color: ${COLOR.BABY_BLUE};
}
/* Chrome, Safari, Edge, Opera */
::-webkit-outer-spin-button,
::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
[type="number"] {
-moz-appearance: textfield;
}
}
p {
color: ${COLOR.BABY_BLUE};
text-align: right;
width: 20%;
}
`;
35 changes: 1 addition & 34 deletions client/src/components/Input/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ChangeEventHandler, ReactNode } from "react";
import styled from "styled-components";
import { COLOR } from "styles/color";
import { InputWrapper } from "./Input.style";

interface InputProps {
placeholder?: string;
Expand All @@ -10,38 +9,6 @@ interface InputProps {
onChange?: ChangeEventHandler<HTMLInputElement>;
}

const InputWrapper = styled.div<{ width: string }>`
display: flex;
padding: 16px;
border-bottom: ${`1px solid ${COLOR.BABY_BLUE}`};
width: ${({ width }) => width};
input {
color: ${COLOR.BLACK};
border: none;
:focus {
outline: none;
}
::placeholder {
color: ${COLOR.BABY_BLUE};
}
/* Chrome, Safari, Edge, Opera */
::-webkit-outer-spin-button,
::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
[type="number"] {
-moz-appearance: textfield;
}
}
p {
color: ${COLOR.BABY_BLUE};
text-align: right;
width: 20%;
}
`;

const Input = ({ width, type = "text", placeholder, subText, onChange }: InputProps) => {
return (
<InputWrapper width={width ?? "100%"}>
Expand Down
11 changes: 11 additions & 0 deletions client/src/components/Input/PaceInput/PaceInput.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";
import { ComponentStory, ComponentMeta } from "@storybook/react";

import PaceInput from "./PaceInput";

export default {
title: "Input/PaceInput",
component: PaceInput,
} as ComponentMeta<typeof PaceInput>;

export const Template: ComponentStory<typeof PaceInput> = (args) => <PaceInput {...args} />;
51 changes: 51 additions & 0 deletions client/src/components/Input/PaceInput/PaceInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { ERROR } from "#constants/errorMessage";
import { ChangeEventHandler, FormEventHandler, useCallback } from "react";
import { InputWrapper } from "../Input.style";

interface PaceInputProps {
width?: string;
onChangeMinute: ChangeEventHandler<HTMLInputElement>;
onChangeSecond: ChangeEventHandler<HTMLInputElement>;
}

const PaceInput = ({ width, onChangeMinute, onChangeSecond }: PaceInputProps) => {
const onInput: FormEventHandler<HTMLInputElement> = useCallback((e) => {
const value = e.currentTarget.value;
if (value.length > 1 && value[0] === "0") {
e.currentTarget.value = value.slice(1);
}
if (Number(value) > 60) {
alert(ERROR.INVALID_MINUTE_VALUE);
e.currentTarget.value = "60";
}
if (Number(value) < 0) {
alert(ERROR.INVALID_MINUTE_VALUE);
e.currentTarget.value = "0";
}
}, []);
return (
<InputWrapper width={width ?? "100%"}>
<input
onInput={onInput}
onChange={onChangeMinute}
min="1"
max="60"
type="number"
style={{ width: "40%" }}
/>
<p style={{ marginRight: "1rem" }}>๋ถ„</p>
<input
onInput={onInput}
onChange={onChangeSecond}
min="1"
max="60"
type="number"
style={{ width: "40%" }}
/>
<p style={{ marginRight: "1rem" }}>์ดˆ</p>
<p>/km</p>
</InputWrapper>
);
};

export default PaceInput;
3 changes: 3 additions & 0 deletions client/src/constants/errorMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum ERROR {
INVALID_MINUTE_VALUE = "1 ์ด์ƒ 60 ์ดํ•˜์˜ ์ˆซ์ž๋งŒ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.",
}
File renamed without changes.
15 changes: 15 additions & 0 deletions client/src/hooks/usePaceInput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ChangeEventHandler, useCallback, useState } from "react";

const usePaceInput = () => {
const [pace, setPace] = useState({ minute: 0, second: 0 });
const onChangeMinute: ChangeEventHandler<HTMLInputElement> = useCallback((e) => {
setPace((prev) => ({ ...prev, minute: Number(e.target.value) }));
}, []);

const onChangeSecond: ChangeEventHandler<HTMLInputElement> = useCallback((e) => {
setPace((prev) => ({ ...prev, second: Number(e.target.value) }));
}, []);
return { pace, onChangeMinute, onChangeSecond };
};

export default usePaceInput;
2 changes: 1 addition & 1 deletion client/src/pages/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Input from "#components/Input/Input";
import Button from "#components/Button/Button";
import useInput from "#hooks/useInput";
import axios from "axios";
import { PLACEHOLDER } from "#constants/constants";
import { PLACEHOLDER } from "#constants/placeholder";
import { idValidator, passwordValidator } from "#utils/valitationUtils";
import { InputWrapper, OptionsWrapper } from "./SignUp.styles";
import { LogoWrapper } from "./Login.styles";
Expand Down
11 changes: 6 additions & 5 deletions client/src/pages/SignUp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import axios from "axios";
import useInput from "#hooks/useInput";
import { confirmPasswordValidator, idValidator, passwordValidator, zipCodeValidator } from "#utils/valitationUtils";
import { InputWrapper, LogoWrapper, OptionsWrapper } from "./SignUp.styles";
import { PLACEHOLDER } from "#constants/constants";
import { PLACEHOLDER } from "#constants/placeholder";
import usePaceInput from "#hooks/usePaceInput";
import PaceInput from "#components/Input/PaceInput/PaceInput";

const SignUp = () => {
const [userId, onChangeUserId, userIdError] = useInput(idValidator);
Expand All @@ -16,8 +18,7 @@ const SignUp = () => {
confirmPasswordValidator(String(password)),
);
const [zipCode, onChangeZipCode, zipCodeError] = useInput(zipCodeValidator);
const [pace, onChangePace] = useInput(() => "", true);

const { pace, onChangeMinute, onChangeSecond } = usePaceInput();
const navigate = useNavigate();

const checkFormValidation = () => confirmPassword && password && userId && zipCode;
Expand All @@ -28,7 +29,7 @@ const SignUp = () => {
.post("http://localhost:4000/user", {
userId,
password,
pace,
pace: pace.minute * 60 + pace.second,
zipCode,
})
.then((res) => res.status === 201 && navigate("/", { replace: true }))
Expand All @@ -50,7 +51,7 @@ const SignUp = () => {
onChange={onChangeConfirmPassword}
></Input>
<span>{confirmPasswordError}</span>
<Input placeholder={PLACEHOLDER.PACE} type="number" onChange={onChangePace}></Input>
<PaceInput onChangeMinute={onChangeMinute} onChangeSecond={onChangeSecond}></PaceInput>
<Input placeholder={PLACEHOLDER.ZIP_CODE} type="number" onChange={onChangeZipCode}></Input>
<span>{zipCodeError}</span>
<Button width="fill" onClick={onSubmitSignUp}>
Expand Down

0 comments on commit 2a17915

Please sign in to comment.