Skip to content

Commit

Permalink
Merge pull request #128 from YAPP-Github/feature/FE-092
Browse files Browse the repository at this point in the history
Feature/FE-092 : map, 회원가입, 로그인 QA 대응
  • Loading branch information
jieunpark247 authored Jul 30, 2023
2 parents 6e01c86 + 92dd3fa commit 935ed5a
Show file tree
Hide file tree
Showing 18 changed files with 177 additions and 158 deletions.
1 change: 1 addition & 0 deletions src/app/login/components/LoginButton/LoginButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const LoginButton = ({ submitErrorMsg }: LoginButtonProps) => {
active={true}
onClick={onClickPersistentButton}
type="button"
initActive={keep === 'Y'}
/>
<Typography variant="label2" as="p" color="sub">
로그인 유지
Expand Down
23 changes: 15 additions & 8 deletions src/app/login/components/LoginWrapper/LoginWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
'use client';
import { LoginForm, LoginTitle } from '../../components';
import { Content } from '@/components';
import { useIsMobile } from '@/hooks';
import { animate } from '@/styles/theme.css';

import { Media } from '@/components';
const LoginWrapper = () => {
const mobile = useIsMobile();

return (
<div className={animate}>
<Content verticalCenter={mobile ? false : true}>
<LoginTitle />
<LoginForm />
</Content>
<Media breakpoint="m" fallback={<></>}>
<Media.Less>
<Content verticalCenter={false}>
<LoginTitle />
<LoginForm />
</Content>
</Media.Less>
<Media.Greater>
<Content verticalCenter={true}>
<LoginTitle />
<LoginForm />
</Content>
</Media.Greater>
</Media>
</div>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/app/login/contexts/LoginContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface LoginContextValue {
const LoginContext = createContext<LoginContextValue | null>(null);

const LoginContextProvider = ({ children }: { children: ReactNode }) => {
const [keep, setKeep] = useState('N');
const [keep, setKeep] = useState('Y');

const contextValue = useMemo(() => ({ keep, setKeep }), [keep, setKeep]);

Expand Down
4 changes: 2 additions & 2 deletions src/app/signup/components/AgreeButton/AgreeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ const AgreeButton = ({ onClick, error, text, name }: AgreeButtonProps) => {
type="button"
/>
<Typography variant="label2" as="p" color="sub">
(필수){' '}
(필수)
<span className={agreeText} onClick={() => onClickAgreeText()}>
{text}
</span>{' '}
</span>
동의
</Typography>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import clsx from 'classnames';
const ProfileSetupSignUp = () => {
const { userInfo } = useSignupContext();
const router = useRouter();
const [disabled, setDisabled] = useState<boolean>(false);
const [selectedValue, setSelectedValue] = useState<SelectedDropDownValue>({
job: null,
birth: null,
Expand All @@ -26,13 +27,18 @@ const ProfileSetupSignUp = () => {
const successSignup = () => {
router.replace('/welcome');
};
const onError = () => {
setDisabled(false);
};
const { postData, errorMsg } = usePostApi<SignupRequest, SignupResponse>({
apiFunction: postSignup,
onSuccess: successSignup,
onError,
});
const { method } = useCommonForm({ schema: signupSchema, checkMode: 'onSubmit' });

const onSubmit: SubmitHandler<FieldValues> = async (data: FieldValues) => {
setDisabled(true);
postData({
email: `${userInfo?.email}@samsung.com`,
password: userInfo?.password,
Expand Down Expand Up @@ -67,7 +73,7 @@ const ProfileSetupSignUp = () => {
label="직군 소분류"
name="job"
placeholder="ex) uiux디자이너"
required={true}
required={false}
method={method}
className={inputMargin}
/>
Expand All @@ -82,11 +88,11 @@ const ProfileSetupSignUp = () => {
selections={birthType}
/>
</div>
<Button size="large" type="submit" className={button}>
<Button size="large" type="submit" className={button} disabled={disabled}>
저장하기
</Button>
<div className={requiredFields}>{errorMsg}</div>
<BottomButton type="submit" errorMsg={errorMsg}>
<BottomButton type="submit" errorMsg={errorMsg} disabled={disabled}>
저장하기
</BottomButton>
</InputField>
Expand Down
2 changes: 1 addition & 1 deletion src/app/signup/constants/dropdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export const birthType = getBirthList();
export const jobType = [
'개발',
'교육',
'금융재무',
'금융/재무',
'기획/경영',
'데이터',
'디자인',
Expand Down
8 changes: 5 additions & 3 deletions src/app/signup/constants/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ export const passwordSchema = z
password: z
.string()
.min(1, '필수 입력 정보를 입력해 주세요.')
.min(8, '영문과 숫자를 포함하여 8~20자로 입력해 주세요.')
.max(20, '영문과 숫자를 포함하여 8~20자로 입력해 주세요.'),
.refine(
(value) => /^(?=.*[a-zA-Z])(?=.*\d).{8,20}$/.test(value),
'영문과 숫자를 포함하여 8~20자로 입력해 주세요.',
),
passwordCheck: z.string().min(1, '필수 입력 정보를 입력해 주세요.'),
})
.refine((data) => data.password === data.passwordCheck, {
Expand All @@ -21,5 +23,5 @@ export const passwordSchema = z
});
export const signupSchema = z.object({
nickname: z.string().min(2, '2-10자로 입력해 주세요.').max(10, '2-10자로 입력해 주세요.'),
job: z.string().min(1, '10자 이하로 입력해주세요.').max(10, '10자 이하로 입력해주세요.'),
job: z.string().min(0, '10자 이하로 입력해주세요.').max(10, '10자 이하로 입력해주세요.'),
});
1 change: 1 addition & 0 deletions src/app/signup/hooks/useConsent/useConsent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const useConsent = (): [boolean, boolean, () => void, () => void] => {
const [error, setError] = useState(false);

const onClickConsent = useCallback(() => {
setError(false);
setAgree((prev: boolean) => !prev);
}, []);

Expand Down
56 changes: 41 additions & 15 deletions src/components/IconButton/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type IconButtonProps = {
hover?: boolean;
active?: boolean;
error?: boolean;
initActive?: boolean;
} & Image &
ButtonHTMLAttributes<HTMLButtonElement>;

Expand All @@ -30,41 +31,66 @@ const IconButton = ({
active = false,
error = false,
disabled = false,
initActive = false,
width = '36',
height = '36',
onClick,
className,
...rest
}: IconButtonProps) => {
const [isActive, setIsActive] = useState(false);
const [isActive, setIsActive] = useState(initActive);
const [status, setStatus] = useState(ICON_STATUS.DEFAULT);
const [iconSvgId, setIconSvgId] = useState<string>(iconType);

useEffect(() => {
if (!error) return;
setStatus(error ? ICON_STATUS.ERROR : ICON_STATUS.DEFAULT);
switch (true) {
case error:
setStatus(ICON_STATUS.ERROR);
break;
case disabled:
setStatus(ICON_STATUS.DISABLE);
break;
case active:
initActive && setStatus(ICON_STATUS.ACTIVE);
break;
default:
setStatus(ICON_STATUS.DEFAULT);
break;
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [error, disabled]);

useEffect(() => {
setStatus(disabled ? ICON_STATUS.DISABLE : ICON_STATUS.DEFAULT);
}, [disabled]);
const updateClickStatus = () => {
switch (true) {
case error:
setStatus(ICON_STATUS.ACTIVE);
setIsActive(true);
break;
case active:
setStatus(isActive ? ICON_STATUS.DEFAULT : ICON_STATUS.ACTIVE);
setIsActive(!isActive);
break;
default:
setStatus(ICON_STATUS.DEFAULT);
break;
}
};
const isPossibleHover = () => !error && !disabled && status !== ICON_STATUS.ACTIVE && hover;

const handleMouseEnter = () => {
if (error || disabled || status === ICON_STATUS.ACTIVE) return;
hover && setStatus(ICON_STATUS.HOVER);
if (isPossibleHover()) {
setStatus(ICON_STATUS.HOVER);
}
};

const handleMouseLeave = () => {
if (error || disabled || status === ICON_STATUS.ACTIVE) return;
hover && setStatus(ICON_STATUS.DEFAULT);
if (isPossibleHover()) {
setStatus(ICON_STATUS.DEFAULT);
}
};

const handleOnClick = (e: MouseEvent<HTMLButtonElement>): void => {
if (disabled) return;
if (active || error) {
setStatus(isActive ? ICON_STATUS.DEFAULT : ICON_STATUS.ACTIVE);
setIsActive(!isActive);
}
updateClickStatus();
onClick?.(e);
};
useEffect(() => {
Expand Down
3 changes: 3 additions & 0 deletions src/components/Map/Map.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ export const searchList = style({
'&:focus': {
background: 'rgba(28, 26, 66, 0.1)',
},
'&:hover': {
background: 'rgba(28, 26, 66, 0.04)',
},
},
});

Expand Down
6 changes: 5 additions & 1 deletion src/components/Map/MapConfirmButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ type MapConfirmButtonProps = {

const MapConfirmButton = ({ onClick }: MapConfirmButtonProps) => {
const { mapState } = useMapContext();
const disabledButton = () => {
const place = mapState.place as Place;
return Object.keys(place).length === 0;
};
const handleOnClick = () => {
const place = mapState.place as Place;
onClick(place);
};
return (
<div className={buttonWrapper}>
<Button disabled={!mapState.keyword} size="medium" aria-label="확인" onClick={handleOnClick}>
<Button disabled={disabledButton()} size="medium" aria-label="확인" onClick={handleOnClick}>
확인
</Button>
</div>
Expand Down
19 changes: 5 additions & 14 deletions src/components/Map/MapSearchList.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client';
import { searchinfoWrapper, noSearchInfoWrapper } from './Map.css';
import { useCallback, useRef } from 'react';
import { Place } from '@/types/map';
import { useMapPickMarker, useMapListMarkers } from './hooks';
import { useSearchList } from './hooks';
import MapSearchItem from './MapSearchItem';
import IconButton from '../IconButton/IconButton';
import { useDisplayContext, useMapContext } from './contexts/MapContextProvider';
import { useDisplayContext } from './contexts/MapContextProvider';

type MapSearchListProps = {
map: any;
Expand Down Expand Up @@ -36,17 +35,9 @@ const SearchInfo = () => {
);
};
const MapSearchList = ({ map, marker }: MapSearchListProps) => {
const markers = useRef<any[]>([]);
const listRefs = useRef<Record<number, HTMLLIElement | null>>({});
const setListItemRef = useCallback((ref: HTMLLIElement | null, index: number) => {
listRefs.current[index] = ref;
}, []);
const { mapState } = useMapContext();
const { displayState } = useDisplayContext();
const placeList = mapState.markerPlace?.length != 0 ? mapState.markerPlace : mapState.searchedPlaces;
const { handleOnClickList, placeList, setListItemRef } = useSearchList({ map, marker });

const { handleOnClickListWithMarkers } = useMapListMarkers({ map, markers });
const { handleOnClickOnlyList } = useMapPickMarker({ map, marker, markers });
if (!placeList) {
return <SearchInfo />;
}
Expand All @@ -56,12 +47,12 @@ const MapSearchList = ({ map, marker }: MapSearchListProps) => {
return (
<div className={searchinfoWrapper({ display: displayState?.searchList, marker: displayState?.marker })} role="list">
<ul>
{placeList?.map((place: Place, index) => (
{placeList?.map((place: Place, index: number) => (
<MapSearchItem
key={index}
place={place}
index={index}
handleOnClickList={mapState.markerPlace?.length != 0 ? handleOnClickOnlyList : handleOnClickListWithMarkers}
handleOnClickList={handleOnClickList}
setListItemRef={setListItemRef}
aria-label={`장소 ${index + 1}`}
/>
Expand Down
12 changes: 2 additions & 10 deletions src/components/Map/contexts/MapContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ type DisplayAction =
| { type: 'handleClickMarker'; payload: boolean };
type DisplayDispatch = (action: DisplayAction) => void;

type MapAction =
| { type: 'handleClickPlaceList'; payload: MapState }
| { type: 'handleClickPlaceResult'; payload: Place }
| { type: 'handleClickInitPlace' };
type MapAction = { type: 'handleClickPlaceList'; payload: MapState } | { type: 'handleClickInitPlace' };
type MapDispatch = (action: MapAction) => void;

const MapContext = createContext<{ mapState: MapState; mapDispatch: MapDispatch }>({
Expand All @@ -43,12 +40,7 @@ const MapContextProvider = ({ children }: { children: ReactNode }) => {
keyword: action.payload.keyword,
searchedPlaces: action.payload.searchedPlaces,
markerPlace: action.payload.markerPlace,
place: {},
};
case 'handleClickPlaceResult':
return {
...state,
...{ place: action.payload },
place: action.payload.place,
};
case 'handleClickInitPlace':
return {
Expand Down
3 changes: 1 addition & 2 deletions src/components/Map/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export { default as useMap } from './useMap';
export { default as useMapListMarkers } from './useMapListMarkers';
export { default as useSearchList } from './useSearchList';
export { default as useMapSearchForm } from './useMapSearchForm';
export { default as useMapPickMarker } from './useMapPickMarker';
44 changes: 0 additions & 44 deletions src/components/Map/hooks/useMapListMarkers.ts

This file was deleted.

Loading

0 comments on commit 935ed5a

Please sign in to comment.