AI웹 개발자 과정 공부 (팀스파르타)/프로젝트

24.06.14_TIL ( 팀 프로젝트 : AI NOST Django ) _ 16. 배포 후 트러블 슈팅 정리 및 코드 수정

티아(tia) 2024. 6. 14. 14:57
728x90



[ 세번째 프로젝트 ] 

 
 

AI를 이용한 소설 사이트를 만들어 보자.

 
 
 
 
++  팀 스로젝트로 팀과의 협업이 중요하다.
++  장고 공식 문서는 항상 확인하기 

https://docs.djangoproject.com/en/4.2/

 

++ 랭체인 공식 문서

https://www.langchain.com/

 

++ 리액트 공식문서

https://ko.legacy.reactjs.org/  # 한국어
https://ko.react.dev/


 
https://github.com/1489ehdghks/NOST.git

 

GitHub - 1489ehdghks/NOST

Contribute to 1489ehdghks/NOST development by creating an account on GitHub.

github.com

 

배포사이트 https://novel-stella.com/

 

Novel Stella

 

novel-stella.com

 

https://github.com/Juunsik/NOST-backend/tree/F/feat/scrolldown

 

GitHub - Juunsik/NOST-backend: Novel Stella backend

Novel Stella backend. Contribute to Juunsik/NOST-backend development by creating an account on GitHub.

github.com

 

 

 

 

 

 

 

 

 

 

 

1.  회의를 하여 디벨롭 할것과 수정할 것을 정리함

 

  1. 회원가입 포커스되었을 떄, 유효성 검사에 대해 설명 보여주기.-비밀번호 오류 알림창/ 확인받을 수 있는 이메일로 받아야함
  2.  like, 평점 바꾸기.-별점수정 안함(그냥 한번 주고 끝나게)
  3. 로딩이 너무 길어지면 다른 로딩케이터로 시간이 얼마쯤 걸리는지 표시
  4. summary 생성시에 세션 안채우고 다음 세션으로 넘어갈 수 있음 - 뉴 노벨 말고 다른 곳에서  생성하면 먹통 / 처음 프롤로그 주고 나서 세션이 넘어가야하는데 그냥 바로 넘어감 / 시놉시스 next 넘길 때 흰 화면
  5. My Book List 책 타이틀이 길면 제목 잘림
  6. 프로필 업로드한 사진 DB에 저장 안됨
  7. 소설 중간에 생성을 그만두면 이어서 작성이 불가능 - 중간저장이나 다시 만들게
  8. ai 로직이 오래 걸릴 경우 안내 문구가 나오지 않음(ex: 1분 이상 소요될 수 있습니다)
  9. access 토큰 만료시 프론트에서 refresh 토큰이 제대로 보내지는지 확인 필요 - 로그아웃부분이 사용자가 눌러야함 엑세스 토큰이 만료되면 바로 로그아웃이 되어야
  10. 한 계정에 여러 사람이 들어갈 수 없도록 해야함
  11. language default 있으면 좋겠음 - 초기설정은 그냥 이렇게 하고 나중에 자신의 오픈에이아이키로 
  12. 번역프로그램을 영어이면 디폴트로 번역값이 들지 않게 백엔드에서 수정하기
  13. summary 생성시 chapter번호를 몰라서 언제 끝날지 사용자 입장에서 모름
  14. summary 생성시 위치 섞여서 나옴- 백엔드에서 순서 정해주기
  15. 30 chapter 넘어도 생성됨 - 마지막에는 피니쉬나 완료창이 나와야 됨

 

 

회원가입, 로그인 에러알림창 / 특수문자 유효성 검사 / 메인페이지 안내문(스크롤 밑으로 생성이 된다)/ 프롬프트 라벨 적는 칸에 하얀색이 아니라 회색글씨로 어떤식으로 적어주세요 하고 예시 있으면/ API 키와 사이트 번역 사용자들의 API 키를 쓸수 있게 구현(토스페이등)

 

 

 

 

 

 

 

 

 

2. like가 작동을 안하고 이미 선택한 것부터 시작해서 수정함

widgets / books / booklike.jsx 에서

const [isLiked, setIsLiked] = useState(false);

 

이렇게만 넣어주면 일단 다시 새로고침을 하거나 했을 때 작 디비에서 받아들여서 작동을 하기는 하는데 배포환경에서는 작동이 되는지 확인이 필요하다.

 

 

 

 

 

 

3. 제목부분 카드 넘어서 보이거나 잘려서 보이는 부분 수정

제목부분 수정  pages/ mybooks/ mybooklist.scss 부분 수정

.card-header {
    position: absolute;
    bottom: 1rem;
    width: 170px;


카드 제목부분 width만 170으로 수정해주시면 해결된다.

 

 

 

 

 

 

 

 

 

 

 

 

4. 게시글에서 밑으로 내려야 게시글 생성 가능합니다 문구넣기

 

참고 사이트 : http://rwdb.kr/css_scroll_icon/

 

CSS 구현 스크롤 유도 표기 - RWDB

RWDB Responsive Web Design dB Web awards, 우수 하이브리드웹·반응형웹 모음 사이트

rwdb.kr

 

이 사이트에서 가시성이 좋기 위해서 7번을 선택하여 메인페이지에 스크롤을 추가한다.

 

 

src/ pages/ main/ component/ booklist.jsx 에 스크롤 유도분 추가

const BookList = () => {
    const { themes, currentSeason } = useThemeStore(); // 테마 설정 사용
    const currentTheme = themes[currentSeason]; // 현재 시즌 테마 색상
  
  ...

    return (
        <div className="book-list section" style={{ backgroundColor: currentTheme.mainpageBackgroundColor, color: currentTheme.textColor }}>
    
    ...
    
            <div className="bookpagination">
                
                ...
                
       
            </div>
            <div className="scroll-down-indicator">
                <p style={{ color: currentTheme.sidebarBg }}>Please scroll down to create a novel</p>
                <a href="#top">
                    <span></span>
                    <span></span>
                    <span></span>
                </a>
            </div>
        </div>
    );
};

export default BookList;

 


.scroll-down-indicator {
    position: relative;
    text-align: center;

    p {
        margin-bottom: 5px;
        margin-top: 5px;
        color: inherit;
        font-size: 20px;
    }

    a {
        display: inline-block;
        position: relative;
        padding-top: 80px;
    }

    a span {
        position: absolute;
        top: 0;
        left: 50%;
        width: 24px;
        height: 24px;
        margin-left: -12px;
        border-left: 1px solid #000000;
        border-bottom: 1px solid #000000;
        transform: rotate(-45deg);
        animation: sdb 2s infinite;
        opacity: 0;
        box-sizing: border-box;
    }

    a span:nth-of-type(1) {
        animation-delay: 0s;
    }

    a span:nth-of-type(2) {
        top: 16px;
        animation-delay: .15s;
    }

    a span:nth-of-type(3) {
        top: 32px;
        animation-delay: .3s;
    }

    @keyframes sdb {
        0% {
            opacity: 0;
        }
        50% {
            opacity: 1;
        }
        100% {
            opacity: 0;
        }
    }
}

 

 

css 부분은 깜빡깜빡 하도록 설정해서 넣어주었다.

위치 조정이나 padding 부분은 console 창에서 정의된 class 명과 magin 부분인지 padding 부분인지 top과 bottom 부분을 확인하면서 조정해주었다.

이게 class 명이 같으면 전역으로 먹어서 class 명을 다 일일히 다르게 주어야 하는것도 신경 써야 했다.

list 부분을 조정하니 likebooklist 부분도 같이 조정이 되어서 class 명을 다르게 주었더니 잘 작동하는 모습이다.

 

 

 

++ 여기서 화면이 너무 위아래로 길어져서 자꾸 깨지는 현상이 발생..

회의를 거쳐서 문구를 모달창으로 띄우기로 함. 스크롤 다운 애니메이션은 그냥 두기로 함.

 

 

 

참고 사이트 : https://velog.io/@jsi06138/React-Toast-%EB%A7%8C%EB%93%A4%EA%B8%B0

 

[React] Toast 만들기

Portal과 Context API를 이용해 Toast 만들기

velog.io

 

 

창을 토스트라는 모달창 같은 것으로 띄우기로 상의하고 코드를 수정한다.

이렇게 정 가운데에 3초정도 띄우고 사라짐. 

 

...

const BookList = () => {
   ...
    
    const [showToast, setShowToast] = useState(false); // 토스트 표시 상태 추가

    const { isLoading, setIsLoading, error, setError } = useGlobalStore();

    useEffect(() => {
        fetchNovels();
        setShowToast(true); // 컴포넌트가 마운트될 때 토스트 표시
        const timer = setTimeout(() => {
            setShowToast(false); // 2초 후에 토스트 숨기기
        }, 2000);

        return () => clearTimeout(timer); // 컴포넌트 언마운트 시 타이머 정리
    }, []);

    ...

    return (
       
       ...
       
            </div>
            {showToast && (
                <div className="toast" style={{ backgroundColor: currentTheme.sidebarBg, color: currentTheme.textColor }}>
                    <p>Please scroll down to create a novel</p>
                </div>
            )}
            <div className="scroll-down-indicator">
                <a href="#top">
                    <span></span>
                    <span></span>
                    <span></span>
                </a>
            </div>
        </div>
    );
};

export default BookList;

 

.toast {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    padding: 0px 20px;
    border-radius: 5px;
    z-index: 1000;
    animation: fadeInOut 3s ease-in-out;
}

@keyframes fadeInOut {
    0%, 100% { opacity: 0; }
    20%, 80% { opacity: 1; }
}

 

 

 

 

 

 

 

 

 

 

 

 

5. 회원가입 유효성 검사에 대해 설명 보여주기 - 비밀번호 오류 알림창 

 

 

 

import { ToastContainer, toast } from 'react-toastify';


const LoginModal = ({ onClose }) => {

    ...


const handleSignupSubmit = async (event) => {
    event.preventDefault();
    setSignupErrors({});

    console.log('Signup Inputs:', signupInputs);

    if (signupInputs.password1 !== signupInputs.password2) {
        setSignupErrors({ password2: ['Passwords do not match'] });
        toast.error('Passwords do not match');
        return;
    }

    try {
        const response = await signup(signupInputs.email, signupInputs.password1, signupInputs.password2, signupInputs.nickname);

        console.log('Signup Response:', response);

        if (response.errors) {
            const errors = {};
            // 각 에러 메시지를 toast로 표시
            if (response.errors.email) {
                errors.email = response.errors.email;
                response.errors.email.forEach((msg) => toast.error(msg));
            }
            if (response.errors.password1) {
                errors.password1 = response.errors.password1;
                response.errors.password1.forEach((msg) => toast.error(msg));
            }
            if (response.errors.password2) {
                errors.password2 = response.errors.password2;
                response.errors.password2.forEach((msg) => toast.error(msg));
            }
            setSignupErrors(errors);
        }
        else {
            setSignupSuccess(true);
            setLoginFormActive(true);
        }
    } catch (error) {
        console.error('Signup API error:', error);
        toast.error('An unexpected error occurred. Please try again.');
    }

    console.log('Global Error:', globalError);
    if (globalError === null) {
        toast.error('This is a duplicate nickname. Please fix.');
    } // 닉네임은 에러를 받아들이지 못해 따로 글로벌에러 null 값일 때 보여주는 것으로 함
};

...

export default LoginModal;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

배포 환경에서 토큰값이 다 노출되어서 조정이 필요함...ㅠㅠ

 

 

반응형