zeromin41 / travel_rocommend_project

콘텐츠 기반 필터링을 활용한 여행지 추천 웹앱
0 stars 2 forks source link

회원가입react와 백연동 #9

Open greenblueredgreen opened 2 months ago

greenblueredgreen commented 2 months ago
import React, { useState } from 'react';
import { Container, Row, Col, Card, Form, Button, Alert } from 'react-bootstrap';
import { useNavigate } from 'react-router-dom';
import axios from 'axios';

const Signup = () => {
  const navigate = useNavigate();
  const [formData, setFormData] = useState({
    // name: '',
    // gender: '',
    // birthdate: '',
    email: '',
    password: '',
    confirmPassword: ''
  });
  const [errors, setErrors] = useState({});

  const validateForm = () => {
    const newErrors = {};
    // if (formData.name.trim().length < 2) newErrors.name = '이름은 2글자 이상이어야 합니다.';
    // if (!formData.gender) newErrors.gender = '성별을 선택해주세요.';
    // if (!formData.birthdate) newErrors.birthdate = '생년월일을 입력해주세요.';
    if (!/^\S+@\S+\.\S+$/.test(formData.email)) newErrors.email = '유효한 이메일 주소를 입력해주세요.';
    if (formData.password.length < 8) newErrors.password = '비밀번호는 8자 이상이어야 합니다.';
    if (formData.password !== formData.confirmPassword) newErrors.confirmPassword = '비밀번호가 일치하지 않습니다.';

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

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
    // 실시간 오류 메시지 제거
    if (errors[name]) {
      setErrors(prev => ({ ...prev, [name]: '' }));
    }
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (validateForm()) {
      try {
        const response = await axios.post(`http://localhost:8080/user/sign-up?email=${formData.email}&password=${formData.password}`);
        console.log('회원가입 성공:', response.data);
        navigate('/login', { state: { message: '회원가입이 완료되었습니다. 로그인해주세요.' } });
      } catch (error) {
        console.error('회원가입 실패:', error);
        setErrors({ submit: '회원가입에 실패했습니다. 다시 시도해주세요.' });
      }
    }
  };

  return (
    <Container className="py-5">
      <Row className="justify-content-center">
        <Col md={8}>
          <Card className="shadow">
            <Card.Body>
              <h2 className="text-center mb-4">회원가입</h2>
              {errors.submit && <Alert variant="danger">{errors.submit}</Alert>}
              <Form onSubmit={handleSubmit}>
                {/* <Form.Group className="mb-3">
                  <Form.Label>이름</Form.Label>
                  <Form.Control
                    type="text"
                    name="name"
                    value={formData.name}
                    onChange={handleChange}
                    isInvalid={!!errors.name}
                  />
                  <Form.Control.Feedback type="invalid">{errors.name}</Form.Control.Feedback>
                </Form.Group>
                <Form.Group className="mb-3">
                  <Form.Label>성별</Form.Label>
                  <Form.Select
                    name="gender"
                    value={formData.gender}
                    onChange={handleChange}
                    isInvalid={!!errors.gender}
                  >
                    <option value="">선택하세요</option>
                    <option value="male">남성</option>
                    <option value="female">여성</option>
                    <option value="other">기타</option>
                  </Form.Select>
                  <Form.Control.Feedback type="invalid">{errors.gender}</Form.Control.Feedback>
                </Form.Group>
                <Form.Group className="mb-3">
                  <Form.Label>생년월일</Form.Label>
                  <Form.Control
                    type="date"
                    name="birthdate"
                    value={formData.birthdate}
                    onChange={handleChange}
                    isInvalid={!!errors.birthdate}
                  />
                  <Form.Control.Feedback type="invalid">{errors.birthdate}</Form.Control.Feedback>
                </Form.Group> */}
                <Form.Group className="mb-3">
                  <Form.Label>이메일 (아이디)</Form.Label>
                  <Form.Control
                    type="email"
                    name="email"
                    value={formData.email}
                    onChange={handleChange}
                    isInvalid={!!errors.email}
                  />
                  <Form.Control.Feedback type="invalid">{errors.email}</Form.Control.Feedback>
                </Form.Group>
                <Form.Group className="mb-3">
                  <Form.Label>비밀번호</Form.Label>
                  <Form.Control
                    type="password"
                    name="password"
                    value={formData.password}
                    onChange={handleChange}
                    isInvalid={!!errors.password}
                  />
                  <Form.Control.Feedback type="invalid">{errors.password}</Form.Control.Feedback>
                </Form.Group>
                <Form.Group className="mb-3">
                  <Form.Label>비밀번호 확인</Form.Label>
                  <Form.Control
                    type="password"
                    name="confirmPassword"
                    value={formData.confirmPassword}
                    onChange={handleChange}
                    isInvalid={!!errors.confirmPassword}
                  />
                  <Form.Control.Feedback type="invalid">{errors.confirmPassword}</Form.Control.Feedback>
                </Form.Group>
                <Button variant="primary" type="submit" className="w-100">회원가입</Button>
              </Form>
            </Card.Body>
          </Card>
        </Col>
      </Row>
    </Container>
  );
};

export default Signup;
greenblueredgreen commented 2 months ago

일단 db user 테이블을 loginId와 password만 설정해놓아서 성별, 생년월일 등은 잠시 주석처리진행.

greenblueredgreen commented 2 months ago

경로설정을 절대경로로 설정해준다.

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (validateForm()) {
      try {
        const response = await axios.post(`http://localhost:8080/user/sign-up?email=${formData.email}&password=${formData.password}`);
        console.log('회원가입 성공:', response.data);
        navigate('/login', { state: { message: '회원가입이 완료되었습니다. 로그인해주세요.' } });
      } catch (error) {
        console.error('회원가입 실패:', error);
        setErrors({ submit: '회원가입에 실패했습니다. 다시 시도해주세요.' });
      }
    }
  };
greenblueredgreen commented 2 months ago

이번에도 400에러가 발생했다. 그것은 백엔드 파라미터 변수명 에러였다. react에서 email로 파라미터가 넘어가는데 스프링의 requestParam은 longinId로 설정해놓았기 때문에 발생한 에러였다. 그리고 500에러도 발생했는데 파라미터는 스프링으로 정상적으로 넘어갔지만, db의 loginId 컬럼의 데이터 타입이 varchar(10)으로 설정해놓았기 때문에 발생한 에러였다. loginId는 email이라 길이가 길어서 varchar(512)로 변경하였다.

greenblueredgreen commented 2 months ago

로그인 잘 되므로 고칠 것 없다. 파라미터값도 잘 넘겼다.