Skip to content

Commit a157437

Browse files
Add amount label, extend material bars, and include unit tests for ResourceUsage component
1 parent 8eb2f4a commit a157437

3 files changed

Lines changed: 222 additions & 203 deletions

File tree

src/components/CommunityPortal/ResourceUsage/ResourceUsage.jsx

Lines changed: 111 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,33 @@ import {
1313
ResponsiveContainer,
1414
} from 'recharts';
1515
import styles from './ResourceUsage.module.css';
16+
import { useSelector } from 'react-redux';
1617

1718
const allData = {
1819
material: [
19-
{ name: 'Material A', returned: 5, loaned: 3, date: '2024-12-05' },
20-
{ name: 'Material B', returned: 8, loaned: 4, date: '2024-12-06' },
21-
{ name: 'Material C', returned: 12, loaned: 6, date: '2024-12-07' },
22-
{ name: 'Material D', returned: 25, loaned: 8, date: '2024-12-08' },
23-
{ name: 'Material E', returned: 15, loaned: 3, date: '2024-12-09' },
24-
{ name: 'Material F', returned: 4, loaned: 6, date: '2024-12-10' },
25-
{ name: 'Material G', returned: 2, loaned: 1, date: '2024-12-11' },
20+
{ name: 'Material A', returned: 5, loaned: 3 },
21+
{ name: 'Material B', returned: 8, loaned: 4 },
22+
{ name: 'Material C', returned: 12, loaned: 6 },
23+
{ name: 'Material D', returned: 25, loaned: 8 },
24+
{ name: 'Material E', returned: 15, loaned: 3 },
25+
{ name: 'Material F', returned: 4, loaned: 6 },
26+
{ name: 'Material G', returned: 2, loaned: 1 },
2627
],
2728
equipment: [
28-
{ name: 'Laptops', returned: 15, loaned: 5, date: '2024-12-05' },
29-
{ name: 'Projectors', returned: 10, loaned: 3, date: '2024-12-06' },
30-
{ name: 'Chairs', returned: 30, loaned: 10, date: '2024-12-07' },
31-
{ name: 'Tables', returned: 20, loaned: 5, date: '2024-12-08' },
32-
{ name: 'Microphones', returned: 8, loaned: 2, date: '2024-12-09' },
29+
{ name: 'Laptops', returned: 15, loaned: 5 },
30+
{ name: 'Projectors', returned: 10, loaned: 3 },
31+
{ name: 'Chairs', returned: 30, loaned: 10 },
32+
{ name: 'Tables', returned: 20, loaned: 5 },
33+
{ name: 'Microphones', returned: 8, loaned: 2 },
3334
],
3435
venue: [
35-
{ name: 'Venue A', returned: 5, loaned: 3, date: '2024-12-05' },
36-
{ name: 'Venue B', returned: 8, loaned: 4, date: '2024-12-06' },
37-
{ name: 'Venue C', returned: 12, loaned: 6, date: '2024-12-07' },
38-
{ name: 'Venue D', returned: 25, loaned: 8, date: '2024-12-08' },
39-
{ name: 'Venue E', returned: 15, loaned: 3, date: '2024-12-09' },
40-
{ name: 'Venue F', returned: 4, loaned: 6, date: '2024-12-10' },
41-
{ name: 'Venue G', returned: 2, loaned: 1, date: '2024-12-11' },
36+
{ name: 'Venue A', returned: 5, loaned: 3 },
37+
{ name: 'Venue B', returned: 8, loaned: 4 },
38+
{ name: 'Venue C', returned: 12, loaned: 6 },
39+
{ name: 'Venue D', returned: 25, loaned: 8 },
40+
{ name: 'Venue E', returned: 15, loaned: 3 },
41+
{ name: 'Venue F', returned: 4, loaned: 6 },
42+
{ name: 'Venue G', returned: 2, loaned: 1 },
4243
],
4344
};
4445

@@ -69,61 +70,50 @@ const allInsights = {
6970
],
7071
};
7172

72-
function CustomTooltip({ active, payload }) {
73-
if (active && payload && payload.length) {
74-
return (
75-
<div className={styles.customTooltip}>
76-
<p className="mb-1">{`${payload[0].payload.name}`}</p>
77-
<p className="mb-1" style={{ color: '#22c55e' }}>{`Returned: ${payload[0].value}`}</p>
78-
<p className="mb-0" style={{ color: '#fca5a5' }}>{`Loaned: ${payload[1].value}`}</p>
79-
</div>
80-
);
81-
}
82-
return null;
73+
function CustomTooltip({ active, payload, darkMode }) {
74+
if (!active || !payload || !payload.length) return null;
75+
76+
const bg = darkMode ? '#1C2541' : '#ffffff';
77+
const txt = darkMode ? '#ffffff' : '#000000';
78+
79+
return (
80+
<div className={styles.customTooltip} style={{ background: bg, color: txt }}>
81+
<p>{payload[0].payload.name}</p>
82+
<p style={{ color: '#22c55e' }}>Returned: {payload[0].value}</p>
83+
<p style={{ color: '#fca5a5' }}>Loaned: {payload[1].value}</p>
84+
</div>
85+
);
8386
}
8487

8588
export default function ResourceUsage() {
8689
const [resourceType, setResourceType] = useState('Material');
8790
const [timePeriod, setTimePeriod] = useState('This Week');
8891
const [insightsTimePeriod, setInsightsTimePeriod] = useState('Last Week');
89-
const [data, setData] = useState(allData.venue);
92+
const [data, setData] = useState(allData.material);
9093
const [insights, setInsights] = useState(allInsights['Last Week']);
9194

92-
const filterDataByDate = (datas, period) => {
93-
// Create different datasets for different time periods to demonstrate filtering
94-
const baseData = [...datas];
95-
96-
switch (period) {
97-
case 'This Week':
98-
// Show first 3 items for this week
99-
return baseData.slice(0, 3);
100-
case 'Last Week':
101-
// Show middle 3 items for last week
102-
return baseData.slice(2, 5);
103-
case 'This Month':
104-
// Show all items for this month
105-
return baseData;
106-
default:
107-
return baseData;
108-
}
109-
};
95+
const darkMode = useSelector(state => state.theme.darkMode);
11096

11197
useEffect(() => {
112-
const resourceTypeKey = resourceType.toLowerCase();
113-
const filteredData = filterDataByDate(allData[resourceTypeKey], timePeriod);
114-
setData(filteredData);
115-
}, [resourceType, timePeriod, allData]);
98+
setData(allData[resourceType.toLowerCase()]);
99+
}, [resourceType]);
116100

117101
useEffect(() => {
118-
setInsights(allInsights[insightsTimePeriod] || allInsights['Last Week']);
102+
setInsights(allInsights[insightsTimePeriod]);
119103
}, [insightsTimePeriod]);
120104

121105
return (
122-
<div className={styles.resourceUsageContainer}>
123-
{/* Left Section - Chart */}
124-
<div className={styles.chartSection}>
106+
<div
107+
data-testid="resource-usage-container"
108+
className={`${styles.resourceUsageContainer} ${
109+
darkMode ? 'dark-mode bg-oxford-blue text-light' : ''
110+
}`}
111+
>
112+
{/* LEFT SECTION */}
113+
<div className={`${styles.chartSection} ${darkMode ? 'bg-space-cadet' : ''}`}>
125114
<div className={styles.headerSection}>
126115
<h1>Resources usage</h1>
116+
127117
<div className={styles.filters}>
128118
<Dropdown>
129119
<Dropdown.Toggle className={styles.customDropdown}>{resourceType}</Dropdown.Toggle>
@@ -135,6 +125,7 @@ export default function ResourceUsage() {
135125
<Dropdown.Item onClick={() => setResourceType('Venue')}>Venue</Dropdown.Item>
136126
</Dropdown.Menu>
137127
</Dropdown>
128+
138129
<Dropdown>
139130
<Dropdown.Toggle className={styles.customDropdown}>{timePeriod}</Dropdown.Toggle>
140131
<Dropdown.Menu>
@@ -148,61 +139,65 @@ export default function ResourceUsage() {
148139
</div>
149140
</div>
150141

142+
{/* CHART */}
151143
<div className={styles.chartContainer}>
152-
{data && data.length > 0 ? (
153-
<ResponsiveContainer width="100%" height="100%">
154-
<BarChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 80 }}>
155-
<CartesianGrid strokeDasharray="3 3" stroke="#eee" vertical={false} />
156-
<XAxis
157-
dataKey="name"
158-
axisLine={false}
159-
tickLine={false}
160-
tick={{ fill: '#666', fontSize: 12 }}
161-
/>
162-
<YAxis axisLine={false} tickLine={false} tick={{ fill: '#666', fontSize: 12 }} />
163-
<Tooltip content={<CustomTooltip />} />
164-
<Legend
165-
align="right"
166-
verticalAlign="top"
167-
iconType="circle"
168-
iconSize={8}
169-
wrapperStyle={{ paddingBottom: '20px' }}
170-
/>
171-
<Bar
172-
dataKey="returned"
173-
stackId="a"
174-
fill="#22c55e"
175-
name="Returned"
176-
radius={[4, 4, 0, 0]}
177-
/>
178-
<Bar
179-
dataKey="loaned"
180-
stackId="a"
181-
fill="#fca5a5"
182-
name="Loaned"
183-
radius={[4, 4, 0, 0]}
184-
/>
185-
</BarChart>
186-
</ResponsiveContainer>
187-
) : (
188-
<div
189-
style={{
190-
display: 'flex',
191-
justifyContent: 'center',
192-
alignItems: 'center',
193-
height: '100%',
194-
}}
195-
>
196-
<p>No data available for the selected time period and resource type.</p>
197-
</div>
198-
)}
144+
<div className={styles.yAxisLabel} style={{ color: darkMode ? '#ffffff' : '#666' }}>
145+
Amount
146+
</div>
147+
148+
<ResponsiveContainer width="100%" height="100%">
149+
<BarChart data={data} margin={{ top: 20, right: 30, left: 30, bottom: 80 }}>
150+
<CartesianGrid
151+
strokeDasharray="3 3"
152+
stroke={darkMode ? '#3A506B' : '#eee'}
153+
vertical={false}
154+
/>
155+
156+
<XAxis
157+
dataKey="name"
158+
axisLine={false}
159+
tickLine={false}
160+
tick={{
161+
fill: darkMode ? '#ffffff' : '#666',
162+
fontWeight: 700,
163+
fontSize: 12,
164+
}}
165+
/>
166+
167+
<YAxis
168+
axisLine={false}
169+
tickLine={false}
170+
tick={{
171+
fill: darkMode ? '#ffffff' : '#666',
172+
fontWeight: 700,
173+
fontSize: 12,
174+
}}
175+
/>
176+
177+
<Tooltip content={<CustomTooltip darkMode={darkMode} />} />
178+
179+
<Legend
180+
align="right"
181+
verticalAlign="top"
182+
iconType="circle"
183+
iconSize={8}
184+
wrapperStyle={{
185+
color: darkMode ? '#ffffff' : '#666',
186+
}}
187+
/>
188+
189+
<Bar dataKey="returned" stackId="a" fill="#22c55e" radius={[4, 4, 0, 0]} />
190+
<Bar dataKey="loaned" stackId="a" fill="#fca5a5" radius={[4, 4, 0, 0]} />
191+
</BarChart>
192+
</ResponsiveContainer>
199193
</div>
200194
</div>
201195

202-
{/* Right Section - Insights */}
203-
<div className={styles.insightsSection}>
196+
{/* RIGHT SECTION */}
197+
<div className={`${styles.insightsSection} ${darkMode ? 'bg-space-cadet text-light' : ''}`}>
204198
<div className={styles.insightsHeader}>
205199
<h2>Insights</h2>
200+
206201
<Dropdown>
207202
<Dropdown.Toggle className={styles.customDropdown}>
208203
{insightsTimePeriod}
@@ -220,11 +215,18 @@ export default function ResourceUsage() {
220215
</Dropdown.Menu>
221216
</Dropdown>
222217
</div>
218+
223219
<div className={styles.insightsGrid}>
224-
{insights.map((insight, index) => (
225-
<div key={index} className={styles.insightCard}>
220+
{insights.map((insight, idx) => (
221+
<div
222+
key={idx}
223+
className={`${styles.insightCard} ${darkMode ? 'bg-yinmn-blue text-light' : ''}`}
224+
>
226225
<div className={styles.insightTitle}>{insight.title}</div>
227-
<div className={styles.insightBadge} style={{ backgroundColor: insight.color }}>
226+
<div
227+
className={`${styles.insightBadge} ${darkMode ? 'text-dark' : ''}`}
228+
style={{ backgroundColor: insight.color }}
229+
>
228230
{insight.value}
229231
</div>
230232
</div>

0 commit comments

Comments
 (0)