개인프로젝트 API와 연결할 간단한 웹페이지 만들기(3)-일정 작성하기 페이지

2024. 11. 29. 18:38TIL

 

public 하위에 create_todo.html 파일을 생성.

해당 페이지에서 할일 목록을 작성하는 기능을 수행할 수 있도록 할 예정이다.

와이어프레임

<li><a href="create_todo.html">일정 작성하기</a></li>

create_todo.html 작성

1차 수정

 

 

<script>
    document.getElementById('todo-form').addEventListener('submit', function (event) {
        event.preventDefault();

        const when = document.getElementById('when').value;
        const description = document.getElementById('description').value;

        if (!when || !description) {
            alert('WHEN과 DESCRIPTION을 모두 입력해주세요.');
            return;
        }

        let apiUrl = '';
        if (when === 'today') {
            apiUrl = 'http://localhost:8080/todo';
        } else if (when === 'week') {
            apiUrl = 'http://localhost:8080/todo/week';
        } else if (when === 'month' || when === 'year') {
            apiUrl = 'http://localhost:8080/todo/month_year';
        }

        const requestData =
            when === 'month' || when === 'year'
                ? {type: when, description: description} // CreatePlannerMonthYearDto
                : {description: description}; // CreatePlannerDto

        fetch(apiUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(requestData),
        })
            .then((response) => {
                if (response.ok) {
                    return response.json();
                } else {
                    throw new Error('API 요청 실패');
                }
            })
            .then((data) => {
                alert('일정이 성공적으로 생성되었습니다!');
                console.log(data);
                //window.location.reload(); //페이지 새로고침
                document.getElementById('todo-form').reset();
            })
            .catch((error) => {
                console.error('Error:', error);
            });
    });
</script>

 

일정 생성시 서버 측에서 오류가 발생하였다.

 

POST 비즈니스 로직을 수행하는 함수에 @Transactional(readOnly = false) 를 적용하여 해결하였다.

 

제출이 되었는지 확인하기 위해 알람추가 및 새로고침 추가

.then(data => {
    alert('제출이 완료되었습니다!');
    location.reload();
})

 

금주 진행률과 금일 진행률 추가하자.

해당 기능은 api를 설계할때는 고려하지 못했기 때문에 api에 해당 기능을 추가해줘야한다.

일단 html을 먼저 작성해보자.

와이어프레임을 토대로 외관을 최대한 구현해보았다. (chat gpt의 도움을 받음..)

    <section id="progress-section">
        <div class="progress-box">
            <h3>금일<br>진행률:</h3>
            <div class="percentage" id="today-progress">0%</div>
        </div>
        <div class="progress-box">
            <h3>금주<br>진행률:</h3>
            <div class="percentage" id="week-progress">0%</div>
        </div>
    </section>

 

 

api를 작성해보자

today나 week값을 전달받았을때 로직이 수행이 가능하도록 api를 만들것이다. 따로 따로 만들기보다는 하나의 api에서 처리하는것이 더 유지보수 측면에서 좋다고 판단하여 하나의 api에서 제어하도록 만들었다.

fun showProgress(type: String): Long {

    var result: Long = 0

    if (type.uppercase() == "TODAY") {
        result = Math.round(queryDslPlannerRepository.findAllTodayPlanCount() * 100)
    } else {
        result = Math.round(queryDslPlannerWeekRepository.findAllWeekPlanCount() * 100)
    }
    return result

}

로직은 매우 간단하다. today면 today repository에서 쿼리문을 실행하고 그결과를 반환하고 month면 month repository에서 쿼리문을 실행하고 결과를 반환하는 형태로 설게하였다. 나중에 year나 month 혹은 다른형태로 추가할때는 else if문에 추가하는 식으로 할 수 있을것이다.

fun findAllTodayPlanCount(): Double {
    val today = LocalDate.now()

    // 전체 개수
    val totalCount = queryFactory.selectFrom(plannerToday)
        .where(plannerToday.createdAt.eq(today))
        .fetch().size.toLong()

    // check = false인 항목 개수
    val falseCount = queryFactory.selectFrom(plannerToday)
        .where(
            plannerToday.createdAt.eq(today),
            plannerToday.check.isTrue
        )
        .fetch().size.toLong()

    return falseCount.toDouble() / totalCount.toDouble()
}

week도 비슷한 형태이다.

 

 

1차 수정