feat: convert line chart data to table format and enhance filtering options in IndexReport
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import React, { memo, useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useBreadcrumb } from '../../../layout/LayoutBreadcrumb';
|
||||
import { Typography, Select, DatePicker, Button, Row, Col, Card, Statistic } from 'antd';
|
||||
import { Typography, Select, DatePicker, Button, Row, Col, Card } from 'antd';
|
||||
import { ResponsiveLine } from '@nivo/line';
|
||||
import { ResponsivePie } from '@nivo/pie';
|
||||
import { FileTextOutlined, ToolOutlined, CheckCircleOutlined, ClockCircleOutlined } from '@ant-design/icons';
|
||||
import { FileTextOutlined } from '@ant-design/icons';
|
||||
import { decryptData } from '../../../components/Global/Formatter';
|
||||
import dayjs from 'dayjs';
|
||||
import './trending.css';
|
||||
@@ -47,8 +46,20 @@ const IndexTrending = memo(function IndexTrending() {
|
||||
}
|
||||
|
||||
setBreadcrumbItems([
|
||||
{ title: <Text strong style={{ fontSize: '14px' }}>• History</Text> },
|
||||
{ title: <Text strong style={{ fontSize: '14px' }}>Trending</Text> },
|
||||
{
|
||||
title: (
|
||||
<Text strong style={{ fontSize: '14px' }}>
|
||||
• History
|
||||
</Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<Text strong style={{ fontSize: '14px' }}>
|
||||
Trending
|
||||
</Text>
|
||||
),
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
navigate('/signin');
|
||||
@@ -138,16 +149,19 @@ const IndexTrending = memo(function IndexTrending() {
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="trending-container">
|
||||
{/* Filter Section */}
|
||||
<Card className="filter-card">
|
||||
{/* Filter Section */}
|
||||
<Card className="filter-card">
|
||||
<div className="filter-header">
|
||||
<Text strong style={{ fontSize: '14px' }}>☰ Filter Data</Text>
|
||||
<Text strong style={{ fontSize: '14px' }}>
|
||||
☰ Filter Data
|
||||
</Text>
|
||||
</div>
|
||||
<Row gutter={16} style={{ marginTop: '16px' }}>
|
||||
<Col xs={24} sm={12} md={6}>
|
||||
<div className="filter-item">
|
||||
<Text style={{ fontSize: '12px', color: '#666' }}>Plant Sub Section</Text>
|
||||
<Text style={{ fontSize: '12px', color: '#666' }}>
|
||||
Plant Sub Section
|
||||
</Text>
|
||||
<Select
|
||||
value={plantSubSection}
|
||||
onChange={setPlantSubSection}
|
||||
@@ -155,7 +169,7 @@ const IndexTrending = memo(function IndexTrending() {
|
||||
options={[
|
||||
{ value: 'Semua Plant', label: 'Semua Plant' },
|
||||
{ value: 'Plant 1', label: 'Plant 1' },
|
||||
{ value: 'Plant 2', label: 'Plant 2' }
|
||||
{ value: 'Plant 2', label: 'Plant 2' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
@@ -192,7 +206,7 @@ const IndexTrending = memo(function IndexTrending() {
|
||||
options={[
|
||||
{ value: 'Harian', label: 'Harian' },
|
||||
{ value: 'Mingguan', label: 'Mingguan' },
|
||||
{ value: 'Bulanan', label: 'Bulanan' }
|
||||
{ value: 'Bulanan', label: 'Bulanan' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
@@ -221,7 +235,7 @@ const IndexTrending = memo(function IndexTrending() {
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
{/* Statistics Cards */}
|
||||
{/* Charts Section */}
|
||||
{!canViewData ? (
|
||||
<Card style={{ marginTop: '24px', textAlign: 'center', padding: '40px' }}>
|
||||
<Text style={{ fontSize: '16px', color: '#999' }}>
|
||||
@@ -233,205 +247,61 @@ const IndexTrending = memo(function IndexTrending() {
|
||||
) : (
|
||||
<>
|
||||
<Row gutter={16} style={{ marginTop: '24px' }}>
|
||||
<Col xs={24} sm={12} md={6}>
|
||||
<Card className="stat-card stat-card-red">
|
||||
<div className="stat-icon">
|
||||
<FileTextOutlined style={{ fontSize: '24px' }} />
|
||||
{/* Line Chart */}
|
||||
<Col xs={24}>
|
||||
<Card className="chart-card">
|
||||
<div className="chart-header">
|
||||
<Text strong style={{ fontSize: '14px' }}>
|
||||
☰ Trending Error per Plant Sub Section
|
||||
</Text>
|
||||
</div>
|
||||
<Statistic
|
||||
title={<Text style={{ fontSize: '12px', color: '#666' }}>Total Error</Text>}
|
||||
value={245}
|
||||
valueStyle={{ fontSize: '24px', fontWeight: 'bold', color: '#333' }}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={12} md={6}>
|
||||
<Card className="stat-card stat-card-orange">
|
||||
<div className="stat-icon">
|
||||
<ToolOutlined style={{ fontSize: '24px' }} />
|
||||
<div style={{ height: '500px', marginTop: '16px' }}>
|
||||
<ResponsiveLine
|
||||
data={lineChartData}
|
||||
margin={{ top: 20, right: 20, bottom: 50, left: 50 }}
|
||||
xScale={{ type: 'point' }}
|
||||
yScale={{ type: 'linear', min: 0, max: 35 }}
|
||||
curve="natural"
|
||||
axisBottom={{
|
||||
tickSize: 5,
|
||||
tickPadding: 5,
|
||||
tickRotation: 0,
|
||||
}}
|
||||
axisLeft={{
|
||||
tickSize: 5,
|
||||
tickPadding: 5,
|
||||
tickRotation: 0,
|
||||
}}
|
||||
colors={{ datum: 'color' }}
|
||||
pointSize={6}
|
||||
pointColor={{ theme: 'background' }}
|
||||
pointBorderWidth={2}
|
||||
pointBorderColor={{ from: 'serieColor' }}
|
||||
pointLabelYOffset={-12}
|
||||
useMesh={true}
|
||||
legends={[
|
||||
{
|
||||
anchor: 'bottom',
|
||||
direction: 'row',
|
||||
justify: false,
|
||||
translateX: 0,
|
||||
translateY: 50,
|
||||
itemsSpacing: 10,
|
||||
itemDirection: 'left-to-right',
|
||||
itemWidth: 140,
|
||||
itemHeight: 20,
|
||||
itemOpacity: 0.75,
|
||||
symbolSize: 12,
|
||||
symbolShape: 'circle',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<Statistic
|
||||
title={<Text style={{ fontSize: '12px', color: '#666' }}>Sedang Maintenance</Text>}
|
||||
value={12}
|
||||
valueStyle={{ fontSize: '24px', fontWeight: 'bold', color: '#333' }}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={12} md={6}>
|
||||
<Card className="stat-card stat-card-green">
|
||||
<div className="stat-icon">
|
||||
<CheckCircleOutlined style={{ fontSize: '24px' }} />
|
||||
</div>
|
||||
<Statistic
|
||||
title={<Text style={{ fontSize: '12px', color: '#666' }}>Selesai Diperbaiki</Text>}
|
||||
value={233}
|
||||
valueStyle={{ fontSize: '24px', fontWeight: 'bold', color: '#333' }}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={12} md={6}>
|
||||
<Card className="stat-card stat-card-blue">
|
||||
<div className="stat-icon">
|
||||
<ClockCircleOutlined style={{ fontSize: '24px' }} />
|
||||
</div>
|
||||
<Statistic
|
||||
title={<Text style={{ fontSize: '12px', color: '#666' }}>Rata-rata Waktu Perbaikan</Text>}
|
||||
value="2.5 jam"
|
||||
valueStyle={{ fontSize: '24px', fontWeight: 'bold', color: '#333' }}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* Charts Section */}
|
||||
<Row gutter={16} style={{ marginTop: '24px' }}>
|
||||
{/* Line Chart */}
|
||||
<Col xs={24} lg={12}>
|
||||
<Card className="chart-card">
|
||||
<div className="chart-header">
|
||||
<Text strong style={{ fontSize: '14px' }}>☰ Trending Error per Plant Sub Section</Text>
|
||||
</div>
|
||||
<div style={{ height: '300px', marginTop: '16px' }}>
|
||||
<ResponsiveLine
|
||||
data={lineChartData}
|
||||
margin={{ top: 20, right: 20, bottom: 50, left: 50 }}
|
||||
xScale={{ type: 'point' }}
|
||||
yScale={{ type: 'linear', min: 0, max: 35 }}
|
||||
curve="natural"
|
||||
axisBottom={{
|
||||
tickSize: 5,
|
||||
tickPadding: 5,
|
||||
tickRotation: 0
|
||||
}}
|
||||
axisLeft={{
|
||||
tickSize: 5,
|
||||
tickPadding: 5,
|
||||
tickRotation: 0
|
||||
}}
|
||||
colors={{ datum: 'color' }}
|
||||
pointSize={6}
|
||||
pointColor={{ theme: 'background' }}
|
||||
pointBorderWidth={2}
|
||||
pointBorderColor={{ from: 'serieColor' }}
|
||||
pointLabelYOffset={-12}
|
||||
useMesh={true}
|
||||
legends={[
|
||||
{
|
||||
anchor: 'bottom',
|
||||
direction: 'row',
|
||||
justify: false,
|
||||
translateX: 0,
|
||||
translateY: 50,
|
||||
itemsSpacing: 10,
|
||||
itemDirection: 'left-to-right',
|
||||
itemWidth: 140,
|
||||
itemHeight: 20,
|
||||
itemOpacity: 0.75,
|
||||
symbolSize: 12,
|
||||
symbolShape: 'circle'
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
|
||||
{/* Donut Chart */}
|
||||
<Col xs={24} lg={12}>
|
||||
<Card className="chart-card">
|
||||
<div className="chart-header">
|
||||
<Text strong style={{ fontSize: '14px' }}>☰ Distribusi Error per Plant</Text>
|
||||
</div>
|
||||
<div style={{ height: '300px', marginTop: '16px' }}>
|
||||
<ResponsivePie
|
||||
data={donutChartData}
|
||||
margin={{ top: 20, right: 80, bottom: 80, left: 80 }}
|
||||
innerRadius={0.6}
|
||||
padAngle={1}
|
||||
cornerRadius={3}
|
||||
activeOuterRadiusOffset={8}
|
||||
colors={{ datum: 'data.color' }}
|
||||
borderWidth={1}
|
||||
borderColor={{ from: 'color', modifiers: [['darker', 0.2]] }}
|
||||
arcLinkLabelsSkipAngle={10}
|
||||
arcLinkLabelsTextColor="#333333"
|
||||
arcLinkLabelsThickness={2}
|
||||
arcLinkLabelsColor={{ from: 'color' }}
|
||||
arcLabelsSkipAngle={10}
|
||||
arcLabelsTextColor={{ from: 'color', modifiers: [['darker', 2]] }}
|
||||
legends={[
|
||||
{
|
||||
anchor: 'bottom',
|
||||
direction: 'row',
|
||||
justify: false,
|
||||
translateX: 0,
|
||||
translateY: 56,
|
||||
itemsSpacing: 8,
|
||||
itemWidth: 80,
|
||||
itemHeight: 18,
|
||||
itemTextColor: '#999',
|
||||
itemDirection: 'left-to-right',
|
||||
itemOpacity: 1,
|
||||
symbolSize: 12,
|
||||
symbolShape: 'circle'
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* Bar Chart and Bottom Section */}
|
||||
<Row gutter={16} style={{ marginTop: '24px' }}>
|
||||
{/* Bar Chart */}
|
||||
<Col xs={24} lg={12}>
|
||||
<Card className="chart-card">
|
||||
<div className="chart-header">
|
||||
<Text strong style={{ fontSize: '14px' }}>☰ Jenis Error Terbanyak</Text>
|
||||
</div>
|
||||
<div style={{ marginTop: '24px', padding: '0 20px' }}>
|
||||
{barChartData.map((item, index) => (
|
||||
<div key={index} style={{ marginBottom: '20px' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '4px' }}>
|
||||
<Text style={{ fontSize: '12px' }}>{item.label}</Text>
|
||||
<Text strong style={{ fontSize: '12px' }}>{item.value}</Text>
|
||||
</div>
|
||||
<div style={{
|
||||
width: '100%',
|
||||
height: '24px',
|
||||
backgroundColor: '#f0f0f0',
|
||||
borderRadius: '4px',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
<div style={{
|
||||
width: `${(item.value / 70) * 100}%`,
|
||||
height: '100%',
|
||||
backgroundColor: '#FF6B4A',
|
||||
transition: 'width 0.3s ease'
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
|
||||
{/* Perbandingan Error Section */}
|
||||
<Col xs={24} lg={12}>
|
||||
<Card className="chart-card">
|
||||
<div className="chart-header">
|
||||
<Text strong style={{ fontSize: '14px' }}>☰ Perbandingan Error Bulan Ini vs Bulan Lalu</Text>
|
||||
</div>
|
||||
<div style={{ marginTop: '24px', padding: '20px', textAlign: 'center' }}>
|
||||
<Text style={{ color: '#999' }}>Data akan ditampilkan di sini</Text>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user