Skip to content

Commit

Permalink
#14 FE : [FEAT] 전력량 통계 페이지 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
bbabbi committed Nov 14, 2024
1 parent e338308 commit e3a5c23
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 172 deletions.
146 changes: 31 additions & 115 deletions client/src/pages/EnergyUsage.css
Original file line number Diff line number Diff line change
@@ -1,145 +1,61 @@
/* 기본 레이아웃 */
.container {
.energy-dashboard-container {
display: flex;
width: 100vw;
height: 100vh;
overflow: hidden;
}

/* 사이드바 */
.sidebar {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 250px;
background-color: #f5f7fa;
transform: translateX(-250px);
transition: transform 0.3s ease;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
}

.sidebar.open {
transform: translateX(0);
}

.toggle-button {
position: absolute;
top: 20px;
right: -40px;
background-color: #4e89ff;
color: white;
border: none;
font-size: 20px;
padding: 10px;
cursor: pointer;
}

.nav-menu {
.energy-dashboard-content {
flex: 1;
padding: 20px;
box-sizing: border-box;
overflow-y: auto;
}

.nav-menu h1 {
font-size: 1.5rem;
font-weight: bold;
color: #1921;
}

.nav-menu ul {
list-style-type: none;
padding: 0;
}

.nav-menu ul li {
padding: 10px 0;
font-size: 1.1rem;
color: #333;
}

.nav-footer {
position: absolute;
bottom: 20px;
font-size: 1rem;
color: #333;
}

/* 콘텐츠 */
.content {
flex-grow: 1;
margin-left: 250px;
padding: 40px;
transition: margin-left 0.3s ease;
}

.sidebar.open + .content {
margin-left: 0;
}

.title {
font-size: 1.5rem;
.dashboard-title {
font-size: 32px;
font-weight: bold;
margin-bottom: 20px;
}

/* 그래프 섹션 */
.graph-section, .data-section {
overflow: hidden;
margin-top: 20px;
background-color: #fff;
border-radius: 8px;
background-color: #f9f9f9;
padding: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
margin-bottom: 30px;
}

.graph-section h3, .data-section h3 {
font-size: 1.2rem;
color: #333;
.graph-section h2, .data-section h2 {
font-size: 21px;
font-weight: bold;
margin-bottom: 15px;
display: flex;
align-items: center;
}

/* 테이블 */
.table-container {
max-height: 200px;
.energy-data-table-wrapper {
max-height: 300px;
overflow-y: auto;
margin-top: 10px;
}

.data-table {
.energy-data-table {
width: 100%;
border-collapse: collapse;
text-align: left;
}

.data-table th, .data-table td {
.energy-data-table th, .energy-data-table td {
border: 1px solid #e0e0e0;
padding: 12px;
border-bottom: 1px solid #e0e0e0;
color: #333;
text-align: center;
font-size: 16px;
}

.data-table th {
.energy-data-table th {
background-color: #f1f3f5;
font-weight: bold;
background-color: #f0f2f5;
}

.data-table tr:hover {
background-color: #f9f9f9;
}

/* 반응형 */
@media (max-width: 1024px) {
.content {
margin-left: 0;
padding: 20px;
}
.sidebar {
width: 200px;
}
}

@media (max-width: 768px) {
.sidebar {
transform: translateX(-200px);
}
.sidebar.open {
transform: translateX(0);
}
.content {
margin-left: 0;
}
.energy-data-table tr:nth-child(even) {
background-color: #f7f9fc;
}
124 changes: 67 additions & 57 deletions client/src/pages/EnergyUsage.tsx
Original file line number Diff line number Diff line change
@@ -1,88 +1,98 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { LineChart, Line, XAxis, YAxis, Tooltip, CartesianGrid, ResponsiveContainer } from 'recharts';
import { Line } from 'react-chartjs-2';
import { FaChartBar, FaFolderOpen } from 'react-icons/fa';
import Sidebar from './Sidebar';
import './EnergyUsage.css';

interface EnergyData {
sensorNumber: string;
dateTime: string;
result: number;
percentage: number;
}

const EnergyUsage: React.FC = () => {
const [data, setData] = useState<EnergyData[]>([]);
const [isNavOpen, setIsNavOpen] = useState(false);
const [percentageData, setPercentageData] = useState<number[]>([]);
const [energyData, setEnergyData] = useState<EnergyData[]>([]);
const [isSidebarOpen, setIsSidebarOpen] = useState(false);

useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get('https://www.dgu1921.p-e.kr/energy-usage');
setData(response.data);
} catch (error) {
console.error("Error fetching energy usage data", error);
}
};
fetchData();
fetch('https://www.dgu1921.p-e.kr/energy-usage')
.then(response => response.json())
.then(data => {
const processedData = data.map((item: any) => ({
sensorNumber: item.sensorNumber,
dateTime: item.dateTime,
percentage: item.percentage * 10,
}));
setEnergyData(processedData);
setPercentageData(processedData.map((item: EnergyData) => item.percentage));
})
.catch(() => {
setPercentageData([20, 30, 50, 70, 90, 60, 80]);
setEnergyData([
{ sensorNumber: '12345', dateTime: '2024-10-15 11:59:00', percentage: 20 },
{ sensorNumber: '12345', dateTime: '2024-10-15 11:59:00', percentage: 30 },
]);
});
}, []);

const toggleNav = () => {
setIsNavOpen(!isNavOpen);
const chartData = {
labels: Array.from({ length: percentageData.length }, (_, i) => `Time ${i + 1}`),
datasets: [{
label: '전력량 (x10)',
data: percentageData,
fill: true,
backgroundColor: 'rgba(72, 128, 255, 0.2)',
borderColor: '#4880FF',
pointBackgroundColor: '#4880FF',
pointBorderColor: '#4880FF',
tension: 0.1
}]
};

const chartOptions = {
scales: {
x: {
grid: {
display: false
}
},
y: {
grid: {
color: "rgba(200, 200, 200, 0.3)"
}
}
}
};

return (
<div className="container">
<div className={`sidebar ${isNavOpen ? 'open' : ''}`}>
<button className="toggle-button" onClick={toggleNav}>
</button>
<nav className="nav-menu">
<h1>1921 for admin</h1>
<ul>
<li>Dashboard</li>
<li>호실별 정보</li>
<li>IoT 기기 정보</li>
<li>전력량 통계</li>
<li>1921이란?</li>
</ul>
<div className="nav-footer">
<p>Settings</p>
<p>Logout</p>
</div>
</nav>
</div>
<div className="content">
<h2 className="title">전력량 통계</h2>
<div className="energy-dashboard-container">
<Sidebar onToggle={setIsSidebarOpen} />
<div className="energy-dashboard-content" style={{ marginLeft: isSidebarOpen ? '280px' : '0' }}>
<h1 className="dashboard-title">전력량 통계</h1>

<div className="graph-section">
<h3>전력량 그래프</h3>
{/* isNavOpen 상태에 따라 width를 조정하여 불필요한 ResizeObserver 이벤트를 방지 */}
<ResponsiveContainer width={isNavOpen ? "90%" : "100%"} height={300}>
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="dateTime" tickFormatter={(tick) => new Date(tick).toLocaleDateString()} />
<YAxis domain={[0, 100]} />
<Tooltip />
<Line type="monotone" dataKey="percentage" stroke="#8884d8" dot />
</LineChart>
</ResponsiveContainer>
<h2><FaChartBar className="section-icon" />전력량 그래프</h2>
<Line data={chartData} options={chartOptions} />
</div>

<div className="data-section">
<h3>전력량 데이터</h3>
<div className="table-container">
<table className="data-table">
<h2><FaFolderOpen className="section-icon" /> 전력량 데이터</h2>
<div className="energy-data-table-wrapper">
<table className="energy-data-table">
<thead>
<tr>
<th>센서 번호</th>
<th>기기번호</th>
<th>시간</th>
<th>전력량 (%)</th>
</tr>
</thead>
<tbody>
{data.map((item, index) => (
{energyData.map((item, index) => (
<tr key={index}>
<td>{item.sensorNumber}</td>
<td>{new Date(item.dateTime).toLocaleString()}</td>
<td>{item.percentage.toFixed(2)}</td>
<td>{item.dateTime}</td>
<td>{item.percentage}</td>
</tr>
))}
</tbody>
Expand All @@ -94,4 +104,4 @@ const EnergyUsage: React.FC = () => {
);
};

export default EnergyUsage;
export default EnergyUsage;

0 comments on commit e3a5c23

Please sign in to comment.