Skip to content

Commit

Permalink
Merge pull request #1086 from minjeong9919/part3-김민정-week20
Browse files Browse the repository at this point in the history
[김민정] Week20
  • Loading branch information
devToram authored May 18, 2024
2 parents cfa2421 + 0098a38 commit f73136f
Show file tree
Hide file tree
Showing 45 changed files with 840 additions and 540 deletions.
5 changes: 5 additions & 0 deletions api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ export const postSignIn = async (data: any) => {
return fetchPOSTJson(url, data);
};

export const postSignUp = async(data: {email: string; password: string}) => {
const url = `${BASE_URL}sign-up`;
return fetchPOSTJson(url, data);
}

export const postCheckDuplicationEmail = async (data: any) => {
const url = `${BASE_URL}check-email`;
return fetchPOSTJson(url, data);
Expand Down
182 changes: 33 additions & 149 deletions components/SignInUp/EmailPwdInput.tsx
Original file line number Diff line number Diff line change
@@ -1,168 +1,59 @@
import { useState, useEffect, ChangeEvent, KeyboardEvent } from "react";
import { useState, useEffect } from "react";
import styled from "styled-components";
import Image from "next/image";
import eyeoff from "@/assets/icons/eye-off.png";
import eyeon from "@/assets/icons/eye-on.png";
import { changeInputBorderColor } from "@/utils/commonSigninupFunc";
import {
emailInputValidationcheck,
loginPasswordInputValidationcheck,
signInPasswordInputValidationcheck,
emailDuplicationCheck,
} from "@/utils/validation";
import { ERROR_MESSAGE } from "@/constants/errorMessage";
import INPUT_STATUS from "@/constants/inputStatus";
import eyeoff from "@/public/assets/icons/eye-off.png";
import eyeon from "@/public/assets/icons/eye-on.png";
import INPUT_ERROR_INFO from "@/type/inputErrorInfo";


type EmailPwdInputPropsType = {
title: string;
type: string;
valueType: string;
isEyeIcon?: boolean;
setEmailValue?: React.Dispatch<React.SetStateAction<string>>;
emailValue?: string | "";
setPasswordValue?: React.Dispatch<React.SetStateAction<string | undefined>>;
passwordValue?: string | undefined;
onEnterButtonClick: () => void;
loginStatus?: string;
signInStatus?: string;
setIsEmailValid?: React.Dispatch<React.SetStateAction<boolean>>;
setIsPasswordValid?: React.Dispatch<React.SetStateAction<boolean>>;
setIsPasswordConfirmValid?: React.Dispatch<React.SetStateAction<boolean>>;
eventFunc: {
onFocusOut: () => void;
onChange: () => void;
onKeydown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
}
inputErrorInfo: INPUT_ERROR_INFO;
inputRef: React.RefObject<HTMLInputElement>
};


const EmailPwdInput = ({
title,
type,
valueType,
isEyeIcon,
setEmailValue,
emailValue,
setPasswordValue,
passwordValue,
onEnterButtonClick,
loginStatus,
signInStatus,
setIsEmailValid,
setIsPasswordValid,
setIsPasswordConfirmValid,
eventFunc,
inputErrorInfo,
inputRef
}: EmailPwdInputPropsType) => {
const INPUT_STATUS_VALUE = {
default: "default",
error: "error",
};

const [inputStatus, setInputStatus] = useState("default");
const [inputErrorMessage, setInputErrorMessage] = useState("");

const [isViewPassword, setIsViewPassword] = useState(false);

const onInputChangeHandler = (e: ChangeEvent<HTMLInputElement>) => {
const inputValue = e.target.value;
if (valueType === "email") {
setEmailValue?.(inputValue);
} else if (valueType === "password") {
setPasswordValue?.(inputValue);
}
};

const setInputStatusAndErrorMessage = (status: "valid" | ErrorType) => {
status === "valid"
? setInputStatus(INPUT_STATUS_VALUE.default)
: (setInputStatus(INPUT_STATUS_VALUE.error),
setInputErrorMessage(status.message));
};

const onInputFocusOutHandler = (e: ChangeEvent<HTMLInputElement>) => {
const inputValue = e.target.value;

switch (valueType) {
case "email":
emailInputFocusOutHandler(inputValue);
break;
case "password": {
passwordInputFocusOutHandler(inputValue);
break;
}
case "password2":
passwordConfirmInputFocusOutHandler(inputValue);
break;
default:
null;
}
};

const emailInputFocusOutHandler = async (email: string) => {
const emailInputStatus = emailInputValidationcheck(email);
setInputStatusAndErrorMessage(emailInputStatus);
if (emailInputStatus === "valid") {
setIsEmailValid?.(true);
if (signInStatus) {
const isDuplicateEmail = await emailDuplicationCheck(email);
isDuplicateEmail &&
setInputStatusAndErrorMessage(INPUT_STATUS.inUseEmail);
}
} else {
setIsEmailValid?.(false);
}
};

const passwordInputFocusOutHandler = async (password: string) => {
let passwordInputStatus;
if (loginStatus) {
passwordInputStatus = loginPasswordInputValidationcheck(password);
} else {
passwordInputStatus = signInPasswordInputValidationcheck(password);
}
setInputStatusAndErrorMessage(passwordInputStatus);
passwordInputStatus === "valid"
? setIsPasswordValid?.(true)
: setIsPasswordValid?.(false);
};

const passwordConfirmInputFocusOutHandler = async (password2: string) => {
const passwordInputStatus = signInPasswordInputValidationcheck(
passwordValue,
password2
);
setInputStatusAndErrorMessage(passwordInputStatus);
passwordInputStatus === "valid"
? setIsPasswordConfirmValid?.(true)
: setIsPasswordConfirmValid?.(false);
};

useEffect(() => {
if (loginStatus === "fail") {
valueType === "email"
? (setInputStatus(INPUT_STATUS_VALUE.error),
setInputErrorMessage(ERROR_MESSAGE.email.check))
: (setInputStatus(INPUT_STATUS_VALUE.error),
setInputErrorMessage(ERROR_MESSAGE.password.check));
}
}, [loginStatus]);

const onInputFocusHandler = () => {
setInputStatus("writing");
};

const KeyEventHandler = (e: KeyboardEvent<HTMLInputElement>) => {
const inputElement = e.target as HTMLInputElement;
if (e.key === "Enter") {
onEnterButtonClick();
inputElement.blur();
if(inputErrorInfo !== "valid") {
setInputErrorMessage(inputErrorInfo.message);
} else {
setInputErrorMessage('');
}
};

},[inputErrorInfo])

return (
<InputDiv>
<p>{title}</p>
<EmailPasswordInput
type={isViewPassword ? "text" : type}
status={inputStatus}
onKeyDown={KeyEventHandler}
onChange={onInputChangeHandler}
onBlur={onInputFocusOutHandler}
onFocus={onInputFocusHandler}
inputErrorInfo={inputErrorInfo}
onChange={eventFunc.onChange}
onBlur={eventFunc.onFocusOut}
onKeyDown={eventFunc.onKeydown}
ref={inputRef}
/>
{isEyeIcon && (
{type==="password" && (
<EyeIconDiv
onClick={() => {
setIsViewPassword(!isViewPassword);
Expand All @@ -171,31 +62,24 @@ const EmailPwdInput = ({
<Image src={isViewPassword ? eyeon : eyeoff} alt="eye_off_icon" />
</EyeIconDiv>
)}
{inputStatus === "error" && (
{inputErrorMessage && (
<ErrorMessageDiv>{inputErrorMessage}</ErrorMessageDiv>
)}
</InputDiv>
);
};

type ErrorType =
| {
errorName: string;
type: string;
message: string;
}
| "valid";

const InputDiv = styled.div`
width: 100%;
margin-bottom: 24px;
position: relative;
`;
const EmailPasswordInput = styled.input<{ status: string }>`
const EmailPasswordInput = styled.input<{ inputErrorInfo: INPUT_ERROR_INFO }>`
width: 100%;
padding: 18px 15px;
border: ${({ status }) =>
`1px solid ${changeInputBorderColor(status) ?? "var(--Grey_300)"}`};
border: ${({ inputErrorInfo }) =>
`1px solid ${inputErrorInfo === "valid" ? "var(--Grey_300)" : "red"}`};
border-radius: 8px;
outline: none;
margin-top: 12px;
Expand Down
Empty file added components/SignInUp/Input.tsx
Empty file.
59 changes: 39 additions & 20 deletions components/common/FolderItem.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,56 @@
import styled from "styled-components";
import { useState } from "react";
import { CalcTime } from "@/utils/calculator";
import Star from "@/assets/icons/card_star.svg";
import Kebab from "@/assets/icons/kebab.svg";
import logo from "@/assets/icons/logo.png";
import { calcTime } from "@/utils/calculator";
import Star from "@/public/assets/icons/card_star.svg";
import Kebab from "@/public/assets/icons/kebab.svg";
import logo from "@/public/assets/icons/logo.png";
import { PopOver } from "./modals/PopOver";
import Image from "next/image";
import styles from "@/styles/shared.module.css";
import Link from "next/link";
import { CommonFolderInfoProps } from "@/constants/commonTypes";
import { useModal } from "@/contexts/ModalContext";
import { DeleteModal } from "./modals/DeleteModal";
import { AddToFolder } from "./modals/AddToFolder";

interface FolderItemProps {
item: CommonFolderInfoProps;
$isModalVisible: string;
setIsModalVisible: any;
}

function FolderItem({
item,
$isModalVisible,
setIsModalVisible,
}: FolderItemProps) {
const { imageSource, createdAt, description, url, id } = item;
const { created_at, favorite, image_source } = item;
const [isPopOverVisible, setIsPopOverVisible] = useState(false);
const createdAtTime: string = String(createdAt ?? created_at);

const time = CalcTime(createdAtTime);
const time = calcTime(createdAtTime);
const img_src = image_source || imageSource;

const modal = useModal();

const openDeleteModal = () => {
modal.openModal(<DeleteModal />);
};

const openAddToFolderModal = () => {
modal.openModal(<AddToFolder />)
};

const POPOVER_INFO = [
{
option: "삭제하기",
callback: openDeleteModal
},
{
option: "폴더에 추가",
callback: openAddToFolderModal
}
]

return (
<a href={url} target="_blank" rel="noreferrer">
<Link href={url || './'} target="_blank" rel="noreferrer">
<Folder>
<ImageContainer>
{img_src ? (
Expand All @@ -49,25 +70,21 @@ function FolderItem({
e.preventDefault();
setIsPopOverVisible(!isPopOverVisible);
}}
/>
/>
<PopOver
$isPopOverVisible={isPopOverVisible}
setIsPopOverVisible={setIsPopOverVisible}
$options={["삭제하기", "폴더에 추가"]}
$modalType={["삭제", "폴더에 추가"]}
popOverInfo={POPOVER_INFO}
$top="20px"
$right="0px"
$isModalVisible={$isModalVisible}
setIsModalVisible={setIsModalVisible}
/>
</TimeContainer>
<Description>{description}</Description>

<DateText>2023. 3. 15</DateText>
</TextBox>{" "}
*
</Folder>
</a>
</TextBox>
</Folder>
</Link>
);
}

Expand Down Expand Up @@ -111,12 +128,13 @@ const DefaultImage = styled.div`

const TextBox = styled.div`
width: 100%;
height: 135px;
height: auto;
display: flex;
flex-direction: column;
gap: 10px;
padding: 15px 20px;
border-radius: 0px 0px 15px 15px;
text-decoration-line: none;
`;

const Description = styled.div`
Expand All @@ -129,6 +147,7 @@ const Description = styled.div`
line-height: 24px;
margin: 0px;
color: #000;
text-decoration: none;
display: -webkit-box;
-webkit-box-orient: vertical;
Expand Down
Loading

0 comments on commit f73136f

Please sign in to comment.