Skip to content

Commit

Permalink
feat: 로그인회원가입 유효성
Browse files Browse the repository at this point in the history
  • Loading branch information
27Lia committed Jun 4, 2024
1 parent d819219 commit 1eb7ef6
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 76 deletions.
30 changes: 29 additions & 1 deletion src/page/LoginPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { useDispatch } from "react-redux";
import { login } from "../redux";
import StyledButton from "../component/Button";
import { auth } from "../firebase";
// import { doc, getDoc } from "firebase/firestore";

const LoginContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -35,11 +34,34 @@ const LoginForm = styled.form`
function LoginPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [errors, setErrors] = useState({});
const navigate = useNavigate();
const dispatch = useDispatch();

const validateForm = () => {
const newErrors = {};
if (!email) {
newErrors.email = "이메일을 입력하세요.";
} else if (!/\S+@\S+\.\S+/.test(email)) {
newErrors.email = "유효한 이메일 주소를 입력하세요.";
}

if (!password) {
newErrors.password = "비밀번호를 입력하세요.";
} else if (password.length < 8) {
newErrors.password = "비밀번호는 최소 8자 이상이어야 합니다.";
}

setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};

const handleLogin = async (e) => {
e.preventDefault();
if (!validateForm()) {
return;
}

try {
const userCredential = await signInWithEmailAndPassword(
auth,
Expand All @@ -65,12 +87,18 @@ function LoginPage() {
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
{errors.email && (
<p style={{ color: "red", fontSize: "12px" }}>{errors.email}</p>
)}
<StyledInput
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
{errors.password && (
<p style={{ color: "red", fontSize: "12px" }}>{errors.password}</p>
)}
<StyledButton>로그인</StyledButton>
</LoginContainer>
</LoginForm>
Expand Down
94 changes: 47 additions & 47 deletions src/page/PostDetailPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,6 @@ import styled from "styled-components";
import StyledButton from "../component/Button";
import InnerContainer from "./InnerContainer";

const PostDetailContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
gap: 20px;
border-radius: 10px;
border: 1px solid #ddd;
height: 70vh;
width: 100%;
min-width: 350px;
margin-top: 150px;
`;

const StyledInput = styled.textarea`
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 5px;
border: 1px solid #dee2e6;
width: 100%;
font-size: 18px;
height: 40vh;
`;

const TitleInput = styled(StyledInput)`
height: 10vh;
`;

const PostTitle = styled.h1`
font-size: 28px;
margin-bottom: 20px;
color: #343a40;
max-height: 5vh;
overflow-y: auto;
max-width: 80%;
`;

const PostContent = styled.p`
max-width: 80%;
max-height: 40vh;
overflow: auto;
font-size: 20px;
color: #495057;
line-height: 1.5;
`;

// 이전의 StyledButton 디자인과 충돌이 있을 수 있으므로 여기에 새로운 스타일 추가
const PostButton = styled(StyledButton)`
margin: 0 10px;
Expand Down Expand Up @@ -172,3 +125,50 @@ function PostDetailPage() {
}

export default PostDetailPage;

const PostDetailContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
gap: 20px;
border-radius: 10px;
border: 1px solid #ddd;
height: 70vh;
width: 100%;
min-width: 350px;
margin-top: 150px;
`;

const StyledInput = styled.textarea`
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 5px;
border: 1px solid #dee2e6;
width: 100%;
font-size: 18px;
height: 40vh;
`;

const TitleInput = styled(StyledInput)`
height: 10vh;
`;

const PostTitle = styled.h1`
font-size: 28px;
margin-bottom: 20px;
color: #343a40;
max-height: 5vh;
overflow-y: auto;
max-width: 80%;
`;

const PostContent = styled.p`
max-width: 80%;
max-height: 40vh;
overflow: auto;
font-size: 20px;
color: #495057;
line-height: 1.5;
`;
21 changes: 12 additions & 9 deletions src/page/ProductListPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Nav from "../component/Nav";
import { useSelector, useDispatch } from "react-redux";
import { db, auth } from "../firebase";
import { doc, getDoc } from "firebase/firestore";
import { fetchProducts } from "../redux"; // 상품목록들
import { fetchProducts, resetPage, resetProducts } from "../redux"; // 상품목록들
import { useInView } from "react-intersection-observer";

function ProductListPage() {
Expand All @@ -21,17 +21,19 @@ function ProductListPage() {
triggerOnce: false,
});

// 컴포넌트가 처음 마운트될 때 제품 목록을 불러오기
useEffect(() => {
dispatch(fetchProducts());
}, [dispatch]);

// 페이지의 특정 지점에 도달하면 추가 제품 불러오기
useEffect(() => {
if (inView) {
dispatch(fetchProducts());
}
}, [inView, dispatch]);
}, [inView, filterOption, dispatch]);

// 필터 옵션이 변경될 때 초기 제품 로드
useEffect(() => {
dispatch(resetPage());
dispatch(resetProducts());
dispatch(fetchProducts());
}, [filterOption, dispatch]);

// 제품 필터링 함수
const filterProducts = async (products, filterOption) => {
Expand Down Expand Up @@ -75,8 +77,8 @@ function ProductListPage() {
{filteredProducts.map((product, index) => (
<ProductCard key={index} product={product} />
))}
<div className="blank" ref={ref} />
</main>
<div className="blank" ref={ref} />
</StyleProductList>
</InnerContainer>
);
Expand Down Expand Up @@ -110,6 +112,7 @@ const StyleProductList = styled.div`
cursor: pointer;
}
.blank {
height: 100px;
/* height: 100px; */
border: 2px solid;
}
`;
35 changes: 34 additions & 1 deletion src/page/SignUpPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,34 @@ function SignUpPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const navigate = useNavigate();
const [errors, setErrors] = useState({});

const validateForm = () => {
const newErrors = {};
if (!email) {
newErrors.email = "이메일을 입력하세요.";
} else if (!/\S+@\S+\.\S+/.test(email)) {
newErrors.email = "유효한 이메일 주소를 입력하세요.";
}

if (!password) {
newErrors.password = "비밀번호를 입력하세요.";
} else if (password.length < 8) {
newErrors.password = "비밀번호는 최소 8자 이상이어야 합니다.";
} else if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
newErrors.password = "비밀번호에는 특수 문자가 포함되어야 합니다.";
}

setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};

const handleSignUp = async (e) => {
e.preventDefault();
if (!validateForm()) {
return;
}

const handleSignUp = async () => {
try {
await createUserWithEmailAndPassword(auth, email, password);
navigate("/login");
Expand All @@ -51,12 +77,19 @@ function SignUpPage() {
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
{errors.email && (
<p style={{ color: "red", fontSize: "12px" }}>{errors.email}</p>
)}
<StyledInput
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
{errors.password && (
<p style={{ color: "red", fontSize: "12px" }}>{errors.password}</p>
)}

<StyledButton>회원가입</StyledButton>
</SignUpContainer>
</SignUpForm>
Expand Down
32 changes: 14 additions & 18 deletions src/redux.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const LOGIN = "LOGIN";
export const LOGOUT = "LOGOUT";
export const INCREMENT_PAGE = "INCREMENT_PAGE";
export const RESET_PAGE = "RESET_PAGE";
export const RESET_PRODUCTS = "RESET_PRODUCTS";

// 페이지 번호를 초기화하는 액션 생성 함수
export const resetPage = () => ({
Expand All @@ -26,6 +27,7 @@ export const incrementPage = () => ({

export const login = () => ({ type: LOGIN });
export const logout = () => ({ type: LOGOUT });
export const resetProducts = () => ({ type: RESET_PRODUCTS });

const initialState = {
isLoggedIn: false, // 로그인 상태
Expand All @@ -45,27 +47,21 @@ export const userReducer = (state = initialState, action) => {
return { ...state, currentPage: state.currentPage + 1 };
case RESET_PAGE:
return { ...state, currentPage: 0 };
case RESET_PRODUCTS:
return { ...state, products: [] };
default:
return state;
}
};

export const fetchProducts = () => {
return (dispatch, getState) => {
const { currentPage, products } = getState();
if (products.length < data.length) {
const productsPerPage = 4;
const startIndex = currentPage * productsPerPage;
if (startIndex < data.length) {
const newProducts = data.slice(
startIndex,
startIndex + productsPerPage
);
dispatch(loadProducts(newProducts));
if (startIndex + productsPerPage < data.length) {
dispatch(incrementPage());
}
}
}
};
export const fetchProducts = () => (dispatch, getState) => {
const { currentPage } = getState();
const productsPerPage = 10;
const startIndex = currentPage * productsPerPage;

if (startIndex >= data.length) return;

const newProducts = data.slice(startIndex, startIndex + productsPerPage);
dispatch(loadProducts(newProducts));
dispatch(incrementPage());
};

0 comments on commit 1eb7ef6

Please sign in to comment.