파일의 입력 및 저장에 성공하였다.
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 |