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

회원가입 취향설정(어떤 여행을 좋아하세요) 구현완료 #47

Closed
wants to merge 19 commits into from
Closed
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
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!doctype html>
<html lang="en">
<html lang="ko">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.jpeg" />
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"react-router-dom": "^6.21.1",
"recoil": "^0.7.7",
"styled-components": "^6.1.3",
"tailwind-scrollbar-hide": "^1.1.7",
"uuid": "^9.0.1"
},
"devDependencies": {
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const App = () => {
<BrowserRouter>
<ThemeProvider theme={theme}>
<GlobalStyle />
<MainRouter />
<MainRouter />
</ThemeProvider>
</BrowserRouter>
</RecoilRoot>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Review/ReviewButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ButtonPrimary } from '@components/common/button/Button';
import { Button } from '@components/common';

export default function ReviewButton() {
return <ButtonPrimary onClick={() => {}}>완료</ButtonPrimary>;
return <Button onClick={() => {}}>완료</Button>;
}
14 changes: 14 additions & 0 deletions src/components/common/back/Back.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useNavigate, useNavigation } from 'react-router-dom';
import { LeftIcon } from '../icons/Icons';

const Back = () => {
const navigate = useNavigate();

return (
<div className="flex h-10 items-center" onClick={() => navigate(-1)}>
<LeftIcon />
</div>
);
};

export default Back;
33 changes: 20 additions & 13 deletions src/components/common/button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
import { ReactNode } from 'react';

interface ButtonProps {
onClick: () => void;
isActive?: boolean;
type?: 'submit' | 'button' | 'reset' | undefined;
onClick?: VoidFunction;
children: ReactNode;
className?: string;
outline?: boolean;
}

export const ButtonWhite: React.FC<ButtonProps> = ({ onClick, children }) => {
const Button = ({
isActive = true,
type = 'submit',
onClick,
children,
outline = false,
}: ButtonProps) => {
return (
<button
type={type}
onClick={onClick}
className="btn-base border-gray3 rounded-lg border border-solid text-sm">
disabled={!isActive}
className={`btn-base headline1 ${
outline
? 'text-main1 border-main1 border-[1.5px] border-solid bg-white'
: 'bg-main1 text-white'
} h-14 p-2 disabled:cursor-not-allowed disabled:bg-gray3`}>
{children}
</button>
);
};

export const ButtonPrimary: React.FC<ButtonProps> = ({ onClick, children }) => {
return (
<button
onClick={onClick}
className="btn-base disabled:bg-gray3 bg-primary text-lg font-bold text-white disabled:cursor-not-allowed">
{children}
</button>
);
};
export default Button;
55 changes: 55 additions & 0 deletions src/components/common/icons/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -711,3 +711,58 @@ export const CameraIcon: React.FC<IconProps> = ({
</svg>
);
};

interface LogoProps {
width?: string;
height?: string;
fill?: string;
}

export const LogoIcon: React.FC<LogoProps> = ({
width = '71',
height = '22',
fill = '#29DDF6',
}) => {
return (
<svg
width={width}
height={height}
viewBox="0 0 71 22"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<g id="WPP">
<path
d="M0.888672 2.28455C1.17545 1.71099 1.62611 1.27057 2.24064 0.963305C2.87566 0.635555 3.62334 0.47168 4.48369 0.47168C5.83566 0.47168 6.91109 0.963306 7.70998 1.94656C8.52936 2.90933 8.93905 4.4559 8.93905 6.58628V17.5557L15.9754 1.08621H19.6012L20.4308 16.6339L20.3386 17.525L27.6516 1.08621H31.8611L22.0286 21.3351H15.4838L14.8693 11.9942L10.8134 21.3351H3.40826L2.48646 6.58628C2.425 5.48012 2.24064 4.56856 1.93338 3.85161C1.6466 3.11417 1.29836 2.59182 0.888672 2.28455Z"
fill={fill}
/>
<path
d="M43.483 0.840398C48.5017 0.840398 51.011 2.6123 51.011 6.15611C51.011 8.10213 50.3862 9.65894 49.1367 10.8266C47.9076 11.9942 46.2177 12.578 44.0668 12.578C43.0631 12.578 42.172 12.2912 41.3936 11.7176C41.0249 11.4718 40.7176 11.185 40.4718 10.8573C41.9671 10.8573 43.104 10.4066 43.8824 9.50531C44.6813 8.58351 45.0808 7.23154 45.0808 5.44939C45.0808 3.66725 44.1999 2.77618 42.4383 2.77618H41.7008C41.5779 2.77618 41.4653 2.78642 41.3628 2.8069L37.8293 21.3351H31.1616L34.941 1.20912C37.1328 1.00427 38.8638 0.89161 40.1338 0.871126C41.4038 0.850641 42.5202 0.840398 43.483 0.840398Z"
fill={fill}
/>
<path
d="M63.3415 0.840398C68.3602 0.840398 70.8696 2.6123 70.8696 6.15611C70.8696 8.10213 70.2448 9.65894 68.9952 10.8266C67.7662 11.9942 66.0762 12.578 63.9253 12.578C62.9216 12.578 62.0305 12.2912 61.2521 11.7176C60.8834 11.4718 60.5761 11.185 60.3303 10.8573C61.8257 10.8573 62.9626 10.4066 63.741 9.50531C64.5399 8.58351 64.9393 7.23154 64.9393 5.44939C64.9393 3.66725 64.0585 2.77618 62.2968 2.77618H61.5594C61.4365 2.77618 61.3238 2.78642 61.2214 2.8069L57.6878 21.3351H51.0201L54.7995 1.20912C56.9914 1.00427 58.7223 0.89161 59.9923 0.871126C61.2624 0.850641 62.3788 0.840398 63.3415 0.840398Z"
fill={fill}
/>
</g>
</svg>
);
};

export const KakaoIcon = () => {
return (
<svg
width="17"
height="16"
viewBox="0 0 17 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
id="Kakao"
fill-rule="evenodd"
clip-rule="evenodd"
d="M8.60938 12.9979C13.0277 12.9979 16.6094 10.2415 16.6094 6.84126C16.6094 3.44101 13.0277 0.68457 8.60938 0.68457C4.1911 0.68457 0.609375 3.44101 0.609375 6.84126C0.609375 9.02531 2.08711 10.9437 4.31509 12.0367L3.76215 15.1916L6.86492 12.8511C7.42645 12.9473 8.01022 12.9979 8.60938 12.9979Z"
fill="#3B1E1E"
/>
</svg>
);
};
6 changes: 6 additions & 0 deletions src/components/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Back from './back/Back';
import Button from './button/Button';
import { Nav } from './nav';
import { Header } from './header';

export { Back, Button, Nav, Header };
5 changes: 5 additions & 0 deletions src/components/user/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import UserInputBox from './useInputBox/UserInputBox';
import UserEmailInputBox from './useInputBox/UserEmailInputBox';
import UserPwInputBox from './useInputBox/UserPwInputBox';

export { UserInputBox, UserEmailInputBox, UserPwInputBox };
66 changes: 66 additions & 0 deletions src/components/user/useInputBox/UserEmailInputBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { CloseIcon } from '@components/common/icons/Icons';
import { useState } from 'react';

const UserEmailInputBox = () => {
const [inputValue, setInputValue] = useState<string>('');

const [isEmailValidated, setIsEmailValidated] = useState(true);
const [isEmailDuplicate, setIsEmailDuplicate] = useState(false);

const onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);

if (e.target.value !== '') {
setIsEmailValidated(
/^[A-Za-z0-9_\.\-]+@[A-Za-z0-9\-]+\.[A-za-z0-9\-]+/.test(inputValue),
);
} else {
setIsEmailDuplicate(false);
}
};

const onInputBlur = () => {
if (isEmailValidated) {
console.log('이메일 중복 확인 요청');
// setIsEmailDuplicate(true);
}
};

return (
<div className="mb-14 flex flex-col gap-2">
<div className="flex flex-col gap-[0.4375rem]">
<label htmlFor="이메일" className="body3 text-main2">
이메일
</label>
<div className="focus-within:border-main1 flex h-10 items-center border-b-[1.25px] border-solid border-gray3">
<input
id="이메일"
className="w-full text-sm font-normal outline-none placeholder:text-gray3"
type="email"
placeholder="이메일 입력"
required
value={inputValue}
onChange={onInputChange}
onBlur={onInputBlur}
/>
{inputValue && (
<button
type="button"
onClick={() => {
setInputValue('');
}}>
<CloseIcon size={20} color="white" fill="#888888" />
</button>
)}
</div>
</div>
<span className="body6 text-red">
{!isEmailValidated
? '이메일 형식이 올바르지 않습니다.'
: isEmailDuplicate && '사용 중인 이메일입니다.'}
</span>
</div>
);
};

export default UserEmailInputBox;
72 changes: 72 additions & 0 deletions src/components/user/useInputBox/UserInputBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { useState } from 'react';
import { CloseIcon } from '@components/common/icons/Icons';

interface Props {
label: string;
type?: string;
placeholder: string;
// children: React.ReactNode;
validifyCheckList?: string[];
// onInputBlur: VoidFunction;
marginB?: string;
}

const UserInputBox = ({
label,
type = 'password',
placeholder,
// validifyCheckList,
marginB = 'mb-6',
}: Props) => {
const [inputValue, setInputValue] = useState('');

const onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};

return (
<div className={`${marginB} flex flex-col gap-2`}>
<div className="flex flex-col gap-2">
<label htmlFor={label} className="body3 text-main2">
{label}
</label>
<div className="focus-within:border-main1 flex h-10 items-center border-b-[1.25px] border-solid border-gray3">
<input
id={label}
className="w-full text-sm font-normal outline-none placeholder:text-gray3"
type={type}
placeholder={placeholder}
required
value={inputValue}
onChange={onInputChange}
/>
{inputValue && (
<button
type="button"
onClick={() => {
setInputValue('');
}}>
<CloseIcon size={20} color="white" fill="#888888" />
</button>
)}
</div>
</div>

{/* {type === 'email' && <EmailValidifyCheck inputValue={inputValue} />}

{validifyCheckList && (
<div className="flex h-6 items-center gap-2">
{validifyCheckList.map((validifyCheckItem) => (
<ValidifyCheck
key={validifyCheckItem}
checkId={validifyCheckItem}
inputValue={inputValue}
/>
))}
</div>
)} */}
</div>
);
};

export default UserInputBox;
Loading