본문 바로가기

개발 기록/카드 사용 내용 프로그램

지출 내역 입력 및 저장 완료

파일의 입력 및 저장에 성공하였다.

 

json파일로 지출한 내역을 저장한 다음 달력의 날짜가 갱신되면 이를 반영하여 표현하도록 하였다.

 

좌측에는 이름 입력할 수 있는 파트와 저장되어 있는 내용을 저장할 수 있도록 되어있다.

 

import React, { useState, useEffect } from "react";
import "./App.css";

function App() {
  const [currentDate, setCurrentDate] = useState(new Date());
  const [selectedDate, setSelectedDate] = useState(null);
  const [transactions, setTransactions] = useState({});

  // 연/월로 구분된 key를 만드는 함수
  const getYearMonthKey = (date) => {
    return `${date.getFullYear()}-${date.getMonth() + 1}`;
  };

  // localStorage에서 데이터 불러오기
  useEffect(() => {
    const savedTransactions = JSON.parse(localStorage.getItem("transactions"));
    if (savedTransactions) {
      setTransactions(savedTransactions);
    }
  }, []);

  // 데이터를 localStorage에 저장하는 함수
  const saveTransactions = (data) => {
    localStorage.setItem("transactions", JSON.stringify(data));
  };

  // 지출 추가 핸들러
  const handleAddTransaction = (e) => {
    e.preventDefault();
    const itemName = e.target.elements.itemName.value;
    const amount = e.target.elements.amount.value;
    const category = e.target.elements.category.value || "기타";

    const yearMonthKey = getYearMonthKey(currentDate);

    if (itemName && amount) {
      const updatedTransactions = {
        ...transactions,
        [yearMonthKey]: {
          ...transactions[yearMonthKey],
          [selectedDate]: [...(transactions[yearMonthKey]?.[selectedDate] || []), { itemName, amount: parseInt(amount), category }]
        }
      };

      setTransactions(updatedTransactions);
      saveTransactions(updatedTransactions);
      e.target.reset();
    }
  };

  // 달력 생성 함수
  const generateCalendar = () => {
    const yearMonthKey = getYearMonthKey(currentDate);
    const year = currentDate.getFullYear();
    const month = currentDate.getMonth();
    const daysInMonth = new Date(year, month + 1, 0).getDate();
    const firstDayOfMonth = new Date(year, month, 1).getDay();
    const calendarGrid = [];

    // 첫 주 빈 칸 채우기
    for (let i = 0; i < firstDayOfMonth; i++) {
      calendarGrid.push(<div className="calendar-day empty" key={`empty-${i}`}></div>);
    }

    // 날짜별 셀 생성
    for (let day = 1; day <= daysInMonth; day++) {
      const dayTransactions = transactions[yearMonthKey]?.[day] || [];
      const totalSpending = dayTransactions.reduce((sum, tx) => sum + tx.amount, 0);

      calendarGrid.push(
        <div
          key={day}
          className={`calendar-cell ${selectedDate === day ? "selected" : ""}`}
          onClick={() => handleDateClick(day)}
        >
          <div className="day-number">{day}</div>
          <div className="spending-amount">
            {totalSpending ? `${totalSpending} ₩` : "0 ₩"}
          </div>
        </div>
      );
    }

    return calendarGrid;
  };

  // 날짜 클릭 핸들러
  const handleDateClick = (day) => {
    setSelectedDate(day);
  };

  return (
    <div className="app-grid">
      {/* 사이드바 */}
      <aside className="sidebar">
        <h2>지출 내역</h2>
        <div className="transaction-list">
          {selectedDate ? (
            <>
              <h3>
                {currentDate.getFullYear()}년 {currentDate.getMonth() + 1}월 {selectedDate}일
              </h3>
              <div className="transaction">
                {transactions[getYearMonthKey(currentDate)]?.[selectedDate]?.map((tx, idx) => (
                  <div key={idx}>
                    {tx.itemName}: {tx.amount} ₩ ({tx.category})
                  </div>
                )) || "지출 내역 없음"}
              </div>
              {/* 지출 추가 폼 */}
              <form onSubmit={handleAddTransaction}>
                <input type="text" name="itemName" placeholder="품목" required />
                <input type="number" name="amount" placeholder="금액" required />
                <input type="text" name="category" placeholder="유형 (기타)" />
                <button type="submit">추가</button>
              </form>
            </>
          ) : (
            <p>날짜를 선택하세요</p>
          )}
        </div>
      </aside>

      {/* 달력 섹션 */}
      <section className="calendar-section">
        <header className="calendar-header">
          <button onClick={() => setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() - 1))}>
            ◀
          </button>
          {currentDate.getFullYear()}년 {currentDate.getMonth() + 1}월
          <button onClick={() => setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() + 1))}>
            ▶
          </button>
        </header>
        <div className="calendar-grid">{generateCalendar()}</div>
      </section>

      {/* 푸터 */}
      <footer className="footer">편의성 UI 배치 (환경설정, 프로필 관리, 테마 관리)</footer>
    </div>
  );
}

export default App;

 

위가 코드이다.

 

이제 개선하고 싶은 사항은 항목을 사용자가 원하는데로 사전에 추가한 것을 선택하여 사용할 수 있는 것과 일괄적으로 항목과 가격을 입력한 다음 나중에 분류를 수정할 수 있는 기능이다.

 

그 다음으로는 사용량 분석 등에 도전할 것이다.

'개발 기록 > 카드 사용 내용 프로그램' 카테고리의 다른 글

프로젝트 일시 중지  (0) 2024.10.17
API Vercel 호출 실패 및 계획 변경  (0) 2024.10.14
API 사용 방법 탐구  (0) 2024.10.08
기본 틀 제작 및 날짜 설정  (5) 2024.10.07
개발 환경 설정  (0) 2024.10.07