[TIL/React] 2023/08/30

원민관·2023년 8월 30일
0

[TIL]

목록 보기
105/159
post-thumbnail

EventPage 반응형 구현 🟠

import React, { useState } from "react";
import styled from "styled-components";
import { events } from "../data/EventList";

const CardContainer = styled.div`
  display: flex;
  overflow-x: scroll;
  width: 100%;
  height: 100vh;
  cursor: grab;
  column-gap: 100px;
  background-color: #424242;
  @media (max-width: 900px) {
    flex-wrap: wrap;
  }
`;

const Card = styled.div`
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
  transition: transform 0.3s ease;

  &:hover {
    transform: scale(1.1);
    cursor: pointer;
  }
`;

const CardContentWrapper = styled.div`
  @media (max-width: 900px) {
    width: 100vw;
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
`;

const EventCardImg = styled.img`
  width: 350px;
  height: 350px;
`;

const EventPage = () => {
  const [isMousePressed, setIsMousePressed] = useState(false);
  const [containerScrollLeft, setContainerScrollLeft] = useState(0);
  const [startMouseX, setStartMouseX] = useState(0);

  const handleMousePress = (e) => {
    setIsMousePressed(true);
    setStartMouseX(e.pageX - e.currentTarget.offsetLeft);
    setContainerScrollLeft(e.currentTarget.scrollLeft);
    console.log(e.currentTarget.scrollLeft);
  };

  const handleMouseMove = (e) => {
    if (!isMousePressed) return;
    const currentMouseX = e.pageX - e.currentTarget.offsetLeft;
    e.currentTarget.scrollLeft =
      containerScrollLeft - (currentMouseX - startMouseX);
  };

  const handleMouseRelease = () => setIsMousePressed(false);

  return (
    <CardContainer
      onMouseDown={handleMousePress}
      onMouseMove={handleMouseMove}
      onMouseUp={handleMouseRelease}
      onMouseLeave={handleMouseRelease}
    >
      {events?.map((event) => (
        <Card key={event.id}>
          <CardContentWrapper>
            <EventCardImg src={event.image} alt={event.title} />
            <h3
              style={{
                color: "rgb(255, 255, 255)",
                fontWeight: "bolder",
                textAlign: "center",
              }}
            >
              {event.title}
            </h3>
            <p
              style={{
                color: "rgb(155, 155, 155)",
                fontWeight: "bolder",
                textAlign: "center",
              }}
            >
              {event.subtitle}
            </p>
          </CardContentWrapper>
        </Card>
      ))}
    </CardContainer>
  );
};

export default EventPage;

SignUpPage layout 재구성 🟠

import React from "react";
import styled from "@emotion/styled";

import ComponentWrapper from "../components/common/ComponentWrapper";

const SignUpTitle = styled.p`
  text-align: center;
  font-size: 40px;
  font-weight: bolder;
`;

const FormLabel = styled.p`
  font-size: 16px;
  margin-bottom: 8px;
`;

const FormInput = styled.input`
  padding: 20px;
  margin-bottom: 16px;
  border: 1px solid #ccc;
  border-radius: 8px;
  font-size: 16px;
  width: 100%;
  box-sizing: border-box;
`;

const SubmitButton = styled.button`
  background-color: black;
  color: #fff;
  padding: 20px;
  border: none;
  border-radius: 8px;
  font-size: 18px;
  font-weight: bolder;
  box-sizing: border-box;
  cursor: pointer;
  width: 100%;
  &:hover {
    background-color: #fff;
    color: black;
    border: 2px solid black;
  }
  &:disabled {
    background-color: red;
  }
`;

const LogInPromptTextWrapper = styled.div`
  display: flex;
  column-gap: 8px;
`;

const TermsWrapper = styled.div`
  margin-top: 10px;
  text-align: center;
`;

const TermsLink = styled.a`
  color: blue;
  text-decoration: underline;
  cursor: pointer;
`;

const SignUpPage = () => {
  return (
    <ComponentWrapper
      style={{
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        minHeight: "100vh",
      }}
    >
      <form>
        <SignUpTitle>회원가입</SignUpTitle>
        <div>
          <h2>이메일로 회원가입</h2>

          <FormLabel>Email</FormLabel>
          <FormInput
            name="email"
            type="email"
            placeholder="이메일 주소를 입력하세요"
          />

          <FormLabel>Password</FormLabel>
          <FormInput
            name="password"
            type="password"
            placeholder="비밀번호를 입력하세요"
          />

          <SubmitButton>회원가입</SubmitButton>

          <LogInPromptTextWrapper>
            <p style={{ fontWeight: "bolder" }}>이미 회원이신가요?</p>
            <p
              style={{
                color: "red",
                fontWeight: "bolder",
                cursor: "pointer",
              }}
            >
              로그인하기
            </p>
          </LogInPromptTextWrapper>
          <TermsWrapper>
            회원가입을 진행함으로써
            <br />
            <TermsLink target="_blank">이용약관</TermsLink>에 동의하신 것으로
            간주합니다.
          </TermsWrapper>
        </div>
      </form>
    </ComponentWrapper>
  );
};

export default SignUpPage;

validation logic 수정 🟠

// LogIn Validation
const isValidLogIn = (email, password) => {
  if (email === "" || password === "") {
    return false;
  } else {
    return true;
  }
};

// LogIn - Email - Validation
const isValidEmail = (email) => {
  const EmailValidationTypes = {
    AT_SYMBOL: "at_symbol",
    UPPERCASE_LETTERS: "uppercase_letters",
  };
  switch (EmailValidationTypes) {
    case EmailValidationTypes.AT_SYMBOL:
      if (!/@/.test(email)) {
        return false;
      }
      break;
    case EmailValidationTypes.UPPERCASE_LETTERS:
      if (/[A-Z]/.test(email)) {
        return false;
      }
      break;
    default:
      return true;
  }
};

// LogIn - Password - Validation
const isValidPassword = (password) => {
  const PasswordValidationTypes = {
    PASSWORD_LENGTH: "password_length",
    UPPERCASE_LOWERCASE_LETTERS: "uppercase_lowercase_letters",
    NUMBER_SPECIALCHARACTER: "number_specialcharacter",
  };
  switch (PasswordValidationTypes) {
    case PasswordValidationTypes.PASSWORD_LENGTH:
      if (password.length < 7) {
        return false;
      }
      break;
    case PasswordValidationTypes.UPPERCASE_LOWERCASE_LETTERS:
      if (!/[a-z]/.test(password) || !/[A-Z]/.test(password)) {
        return false;
      }
      break;
    case PasswordValidationTypes.NUMBER_SPECIALCHARACTER:
      if (
        !/[0-9]/.test(password) ||
        !/[!@#$%^&*()_+\-={};':"|,.<>/?]/.test(password)
      ) {
        return false;
      }
      break;
    default:
      return true;
  }
};

export { isValidLogIn, isValidEmail, isValidPassword };

타입 지정 및 switch 문 적용, case 별로 error에 대한 처리를 어떻게 할 것인지는 고민중.

profile
Write a little every day, without hope, without despair ✍️

0개의 댓글