Skip to content

Commit

Permalink
Merge pull request #519 from Accept77/part3-양진수
Browse files Browse the repository at this point in the history
  • Loading branch information
SINHOLEE authored Dec 14, 2023
2 parents f101283 + c736649 commit 01a2435
Show file tree
Hide file tree
Showing 18 changed files with 732 additions and 111 deletions.
43 changes: 42 additions & 1 deletion component/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import axios from "axios";

const apiUrl = "https://bootcamp-api.codeit.kr/api";

export default async function getApi(path: string) {
export async function getApi(path: string) {
try {
const res = await axios.get(`${apiUrl}${path}`);
if (res.status === 200) {
Expand All @@ -12,3 +12,44 @@ export default async function getApi(path: string) {
throw new Error("Unknown error");
}
}

export async function postSignIn(email: string, password: string) {
try {
const res = await axios.post(`${apiUrl}/sign-in`, {
email,
password,
});
if (res.status === 200) {
return res.data;
}
} catch (e) {
throw new Error("Wrong email, password");
}
}

export async function checkEmail(email: string) {
try {
const res = await axios.post(`${apiUrl}/check-email`, {
email,
});
if (res.status === 200) {
return res.data;
}
} catch (e) {
throw new Error("Wrong email");
}
}

export async function postSignUp(email: string, password: string) {
try {
const res = await axios.post(`${apiUrl}/sign-up`, {
email,
password,
});
if (res.status === 200) {
return res.data;
}
} catch (e) {
throw new Error("Wrong email, password");
}
}
17 changes: 16 additions & 1 deletion component/card/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,24 @@ import { useState } from "react";
import Image from "next/image";
import Link from "next/link";
import dateCalculator from "@/utils/dateCalculator";
import { CardProps, CardsProps } from "../../types/type";
import filterItems from "./filterItems";
import { NoLink } from "@/pages/folder";
import { CardItem } from "@/types/type";

interface CardProps {
item: CardItem;
setClose?: React.Dispatch<React.SetStateAction<boolean>>;
setTag?: React.Dispatch<React.SetStateAction<string>>;
close?: boolean;
}

interface CardsProps {
items: CardItem[];
setClose?: React.Dispatch<React.SetStateAction<boolean>>;
setTag?: React.Dispatch<React.SetStateAction<string>>;
close?: boolean;
search?: string;
}

function Card({ item, setClose, setTag, close }: CardProps) {
const [status, setStatus] = useState(true);
Expand Down
2 changes: 1 addition & 1 deletion component/common/header.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";
import logo from "../../public/images/header/logo.png";
import getApi from "../api/api";
import { getApi } from "../api/api";
import styled from "styled-components";
import Image from "next/image";
import Link from "next/link";
Expand Down
205 changes: 176 additions & 29 deletions component/common/input.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import styled from "styled-components";
import eyeOnIcon from "../public/input/signin-eye-on.png";
import eyeOffIcon from "../public/input/signin-eye-off.png";
import eyeOnIcon from "../../public/images/input/signin-eye-on.png";
import eyeOffIcon from "../../public/images/input/signin-eye-off.png";
import Image from "next/image";
import { useState } from "react";

export default function Input({ passwd }: { passwd?: boolean }) {
interface InputPasswordProps {
signUp?: boolean;
passwordValue: string;
setPasswordValue: React.Dispatch<React.SetStateAction<string>>;
passwordError: string;
setPasswordError: React.Dispatch<React.SetStateAction<string>>;
postApi: () => Promise<void>;
}

export function InputPassword({
signUp,
passwordValue,
setPasswordValue,
passwordError,
setPasswordError,
postApi,
}: InputPasswordProps) {
const [eyeIcon, setEyeIcon] = useState(eyeOnIcon);
const [passwdView, setPasswdView] = useState("password");
const [error, setError] = useState(false);
const errorCase = "오류";

function handleIcon() {
if (eyeIcon === eyeOnIcon) {
Expand All @@ -19,42 +33,175 @@ export default function Input({ passwd }: { passwd?: boolean }) {
setPasswdView("password");
}
}
function valueError(event: React.FocusEvent<HTMLInputElement>) {
if (errorCase === event.target.value) {
setError(true);
function valueError() {
const regex = new RegExp("(?=.*[a-zA-Z])(?=.*[0-9])(?=.{8,})");
if (passwordValue === "") {
setPasswordError("비밀번호를 입력해주세요");
} else if (
signUp &&
(passwordValue.length < 8 || !regex.test(passwordValue))
) {
setPasswordError(
"비밀번호는 영문, 숫자 조합 8자 이상 입력해 주세요."
);
} else {
setError(false);
setPasswordError("");
}
}
function enterCheck(event: React.KeyboardEvent<HTMLInputElement>) {
if (event.key === "Enter") {
postApi();
}
}

return (
<>
<StyledInputBox $error={error}>
{passwd ? (
<>
<StyledInput type={passwdView} onBlur={valueError} />
<StyledInputIcon onClick={handleIcon}>
<Image src={eyeIcon} alt="eyeIcon" />
</StyledInputIcon>
</>
) : (
<StyledInput placeholder="내용 입력" onBlur={valueError} />
)}
<div>
<StyledInputBox $error={passwordError}>
<StyledInput
type={passwdView}
placeholder={
signUp
? "영문, 숫자를 조합해 8자 이상 입력해 주세요."
: "비밀번호를 입력해 주세요"
}
onBlur={valueError}
onChange={(event) => setPasswordValue(event.target.value)}
onKeyDown={enterCheck}
/>
<StyledInputIcon onClick={handleIcon}>
<Image src={eyeIcon} alt="eyeIcon" />
</StyledInputIcon>
</StyledInputBox>
<StyledErrorMsg $error={error}>
내용을 다시 작성해주세요
<StyledErrorMsg $error={passwordError}>
{passwordError}
</StyledErrorMsg>
</>
</div>
);
}

interface InputPasswordCheckProps {
passwordCheckValue: string;
setPasswordCheckValue: React.Dispatch<React.SetStateAction<string>>;
passwordCheckError: string;
setPasswordCheckError: React.Dispatch<React.SetStateAction<string>>;
passwordValue: string;
postApi: () => Promise<void>;
}

export function InputPasswordCheck({
passwordCheckValue,
setPasswordCheckValue,
passwordCheckError,
setPasswordCheckError,
passwordValue,
postApi,
}: InputPasswordCheckProps) {
const [eyeIcon, setEyeIcon] = useState(eyeOnIcon);
const [passwdView, setPasswdView] = useState("password");

function handleIcon() {
if (eyeIcon === eyeOnIcon) {
setEyeIcon(eyeOffIcon);
setPasswdView("text");
} else {
setEyeIcon(eyeOnIcon);
setPasswdView("password");
}
}
function valueError() {
if (passwordCheckValue === "") {
setPasswordCheckError("비밀번호를 입력해주세요");
} else if (passwordValue !== passwordCheckValue) {
console.log(passwordValue, passwordCheckValue);
setPasswordCheckError("비밀번호가 일치하지 않아요.");
} else {
setPasswordCheckError("");
}
}
function enterCheck(event: React.KeyboardEvent<HTMLInputElement>) {
if (event.key === "Enter") {
postApi();
}
}

return (
<div>
<StyledInputBox $error={passwordCheckError}>
<StyledInput
type={passwdView}
placeholder="비밀번호와 일치하는 값을 입력해 주세요."
onBlur={valueError}
onChange={(event) =>
setPasswordCheckValue(event.target.value)
}
onKeyDown={enterCheck}
/>
<StyledInputIcon onClick={handleIcon}>
<Image src={eyeIcon} alt="eyeIcon" />
</StyledInputIcon>
</StyledInputBox>
<StyledErrorMsg $error={passwordCheckError}>
{passwordCheckError}
</StyledErrorMsg>
</div>
);
}

interface InputEmailProps {
emailValue: string;
setEmailValue: React.Dispatch<React.SetStateAction<string>>;
emailError: string;
setEmailError: React.Dispatch<React.SetStateAction<string>>;
postApi: () => Promise<void>;
}

export function InputEmail({
emailValue,
setEmailValue,
emailError,
setEmailError,
postApi,
}: InputEmailProps) {
const regex = new RegExp(
"([!#-'*+/-9=?A-Z^-~-]+(.[!#-'*+/-9=?A-Z^-~-]+)*|\"([]!#-[^-~ \t]|(\\[\t -~]))+\")@([!#-'*+/-9=?A-Z^-~-]+(.[!#-'*+/-9=?A-Z^-~-]+)*|[[\t -Z^-~]*])"
);

function valueCheck() {
if (emailValue === "") {
setEmailError("이메일을 입력해주세요.");
} else if (!regex.test(emailValue)) {
setEmailError("올바른 이메일 주소가 아닙니다.");
} else {
setEmailError("");
}
}
function enterCheck(event: React.KeyboardEvent<HTMLInputElement>) {
if (event.key === "Enter") {
postApi();
}
}

return (
<div>
<StyledInputBox $error={emailError}>
<StyledInput
placeholder="이메일을 입력해 주세요."
onBlur={valueCheck}
onChange={(event) => setEmailValue(event.target.value)}
onKeyDown={enterCheck}
/>
</StyledInputBox>
<StyledErrorMsg $error={emailError}>{emailError}</StyledErrorMsg>
</div>
);
}

const StyledInputBox = styled.div<{ $error: boolean }>`
width: 350px;
const StyledInputBox = styled.div<{ $error: string }>`
height: 60px;
padding: 18px 15px;
border-radius: 8px;
border: 1px solid ${({ $error }) =>
$error ? "var(--red);" : "var(--gray20);"}
$error !== "" ? "var(--red);" : "var(--gray20);"}
background: var(--white);
position: relative;
display: flex;
Expand All @@ -77,9 +224,9 @@ const StyledInputIcon = styled.div`
cursor: pointer;
`;

const StyledErrorMsg = styled.div<{ $error: boolean }>`
const StyledErrorMsg = styled.div<{ $error: string }>`
color: var(--red);
font-size: 14px;
margin-top: 6px;
display: ${({ $error }) => ($error ? "" : "none;")};
visibility: ${({ $error }) => ($error !== "" ? "" : "hidden;")};
`;
4 changes: 2 additions & 2 deletions component/common/searchbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export default function SearchBar({
search,
setSearch,
}: {
search: string;
setSearch: React.Dispatch<React.SetStateAction<string>>;
search?: string;
setSearch?: React.Dispatch<React.SetStateAction<string>>;
}) {
return (
<StyledSearchBox>
Expand Down
21 changes: 19 additions & 2 deletions component/folder/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useState } from "react";
import CopyToClipboard from "react-copy-to-clipboard";
import { FacebookMessengerShareButton } from "react-share";
import Image from "next/image";
import Script from "next/script";

function Add() {
const [select, setSelect] = useState("0");
Expand Down Expand Up @@ -94,8 +95,18 @@ function DeleteFolder() {
);
}

declare global {
interface Window {
Kakao: any;
}
}

function Share({ query }: { query: string }) {
const currentUrl = window.location.href + "?" + query;
const kakaoInit = () => {
if (!window.Kakao.isInitialized())
window.Kakao.init(process.env.NEXT_PUBLIC_KAKAO_API);
};

const shareKakao = async () => {
await window.Kakao.Share.sendDefault({
Expand All @@ -121,6 +132,12 @@ function Share({ query }: { query: string }) {

return (
<>
<Script
src="https://t1.kakaocdn.net/kakao_js_sdk/2.5.0/kakao.min.js"
integrity="sha384-kYPsUbBPlktXsY6/oNHSUDZoTX6+YI51f63jCPEIPFP09ttByAdxd2mEjKuhdqn4"
crossOrigin="anonymous"
onLoad={kakaoInit}
/>
<StyledModalTitleBox>
<StyledModalTitle>폴더 공유</StyledModalTitle>
<StyledModalSubTitle>폴더명</StyledModalSubTitle>
Expand Down Expand Up @@ -318,8 +335,8 @@ const StyledModalShare = styled.div`
const StyledModalShareIcon = styled.div<{ $name?: string }>`
padding: 12px;
border-radius: 37.333px;
background: ${({ $name }) => ($name === "kakao" ? "#fee500" : "")};
background: ${({ $name }) => ($name === "facebook" ? "#1877F2" : "")};
background: ${({ $name }) =>
$name === "kakao" ? "#fee500" : $name === "facebook" ? "#1877F2" : ""};
cursor: pointer;
`;

Expand Down
Loading

0 comments on commit 01a2435

Please sign in to comment.