This commit is contained in:
zadit
2025-01-27 07:14:48 +07:00
parent f1591b1a2a
commit 54a45e35c2
4 changed files with 147 additions and 37 deletions

View File

@@ -22,6 +22,7 @@
justify-content: space-around;
position: relative;
overflow: hidden;
font-size: 14px;
}
.dateSelector {

View File

@@ -60,15 +60,19 @@ const DailyCharts = ({ transactionGraph, colors, type }) => {
);
const formatDate = (dateString) => {
const date = new Date(dateString);
const monthNames = [
"Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agu", "Sep", "Okt", "Nov", "Des"
];
const month = monthNames[date.getUTCMonth()]; // Use getUTCMonth() for UTC month
const day = date.getUTCDate(); // Use getUTCDate() for UTC day
return { month, day };
};
const date = new Date(dateString); // Parse the date string
// Create an array of month names (use the same names you had earlier)
const monthNames = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
// Get the month and day
const month = monthNames[date.getMonth()]; // Month is 0-indexed (January = 0)
const day = date.getDate(); // Get the day of the month
return { month, day }; // Return the result
};
return (
<div className={styles.chartItemContainer}>

View File

@@ -137,10 +137,10 @@ const App = ({ forCafe = true, cafeId="",
fetchData(filter); // Fetch data when filter changes
}, [filter, selectedCafeId]);
const filteredItems = analytics.itemSales || [];
const filteredItems = analytics?.itemSales || analytics?.items || [];
const colors = [
"#E63946", // Bright Red
"#af9463", // Bright Red
"#F4A261", // Soft Orange
"#FFD166", // Sunshine Yellow
"#06D6A0", // Mint Green
@@ -161,11 +161,54 @@ const App = ({ forCafe = true, cafeId="",
"#BC4749", // Cranberry Red
];
const totalSoldAcrossAllCafes = filteredItems.reduce((total, cafe) => {
const cafeTotal = (cafe.report?.itemSales || []).reduce((sum, item) => sum + item.sold, 0);
return total + cafeTotal;
}, 0);
const segments = filteredItems.map((item, index) => ({
// Define a color palette or generate colors dynamically
const colorPalette = colors;
// Ensure that each segment gets a unique color
let colorIndex = 0;
let segments = (selectedCafeId === 0 || selectedCafeId === -1) ? filteredItems.flatMap((cafe) => {
const cafeItems = cafe.report?.itemSales || [];
console.log(cafeItems); // Log all items for the cafe
return cafeItems.map((item, index) => {
const percentage = totalSoldAcrossAllCafes > 0
? ((item.sold / totalSoldAcrossAllCafes) * 100).toFixed(2)
: 0;
console.log(`${item.itemName}: ${(percentage)}%`); // Log item name and percentage
// Assign a unique color from the color palette
const color = colorPalette[colorIndex % colorPalette.length]; // Use modulo to cycle through colors
colorIndex++; // Increment to ensure a new color for the next item
return {
itemName: item.itemName,
sold: item.sold,
percentage: percentage,
color: color,
};
});
}) : filteredItems.map((item, index) => {
const color = colorPalette[colorIndex % colorPalette.length]; // Use modulo to cycle through colors
colorIndex++; // Increment to ensure a new color for the next item
return {
itemName: item.itemName,
percentage: item.percentage,
color: colors[index] || "#cccccc",
}));
color: color,
};
});
segments.sort((a, b) => b.sold - a.sold);
console.log(segments)
const formatIncome = (amount) => {
if (amount >= 1_000_000_000) {
@@ -222,7 +265,7 @@ const App = ({ forCafe = true, cafeId="",
updatedFullTexts = [
["semua", 0], // First entry is "semua"
...otherCafes.map(cafe => [cafe.name, cafe.cafeId]), // Map over cafes to get name and cafeId pairs
["+", -1] // Add the "+" entry
["tambah kedai +", -1] // Add the "+" entry
];
}
@@ -310,23 +353,44 @@ const App = ({ forCafe = true, cafeId="",
>
<div style={{ display: 'flex', alignItems: 'center', padding: forCafe? '0px 20px' : '0px 15px', justifyContent: forCafe? 'flex-start':'space-between' }}>
{forCafe && <div style={{marginTop: '49px', marginRight: '10px'}} onClick={handleClose}><svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 512 512"><path d="M48,256c0,114.87,93.13,208,208,208s208-93.13,208-208S370.87,48,256,48,48,141.13,48,256Zm212.65-91.36a16,16,0,0,1,.09,22.63L208.42,240H342a16,16,0,0,1,0,32H208.42l52.32,52.73A16,16,0,1,1,238,347.27l-79.39-80a16,16,0,0,1,0-22.54l79.39-80A16,16,0,0,1,260.65,164.64Z"/></svg></div>}
<h2 className={styles["Transactions-title"]} style={{ marginTop: forCafe? '57px': 'revert', marginLeft: '0px' }}>Laporan</h2>
<div style={{ marginTop: '10px' }}>
{!forCafe && <MultiSwitch
key={resetKey} // Add key to reset the component and force it to re-render
texts={texts}
selectedSwitch={selectedSwitch}
bgColor={'#f4efe6'}
borderColor={'transparent'}
borderWidth={0.1}
onToggleCallback={onItemToggle}
fontColor={"#af9463"}
selectedFontColor={"black"}
selectedSwitchColor={"white"}
eachSwitchWidth={70}
height={"25px"}
fontSize={"12px"}
/>}
{!forCafe &&
// <MultiSwitch
// key={resetKey} // Add key to reset the component and force it to re-render
// texts={texts}
// selectedSwitch={selectedSwitch}
// bgColor={'#f4efe6'}
// borderColor={'transparent'}
// borderWidth={0.1}
// onToggleCallback={onItemToggle}
// fontColor={"#af9463"}
// selectedFontColor={"black"}
// selectedSwitchColor={"white"}
// eachSwitchWidth={70}
// height={"25px"}
// fontSize={"12px"}
// />
<div className={styles.dateSelectorWrapper} style={{fontSize: '14px'}}>
{texts.map((item, indexx) => {
return (
<div
key={indexx}
className={`${styles.dateSelector} ${styles.dateSelectorActive}`} style={{position: 'relative', width: 'calc(32vw - 30px)'}}
onClick={()=>onItemToggle(indexx)}
>
<div style={{position: 'absolute', bottom: 0, left: '10%', right: '10%', borderBottom: selectedSwitch == indexx ? `1px solid green` : 'none'}}></div>
<div
style={{ color: 'black' }}>
{item}
</div>
</div>
);
})}
</div>
}
</div>
</div>
<div style={{
@@ -427,7 +491,7 @@ const App = ({ forCafe = true, cafeId="",
<CircularDiagram segments={segments} />
</div>
<div style={{ flex: 1, marginLeft: "20px" }}>
{filteredItems.map((item, index) => (
{segments.map((item, index) => (
<div
key={index}
style={{

View File

@@ -286,3 +286,44 @@
font-size: 20px;
text-align: center;
}
.dateSelectorWrapper {
display: flex;
justify-content: space-around;
position: relative;
overflow: hidden;
width: calc(100vw - 30px);
}
.dateSelector {
flex-grow: 1;
text-align: center;
padding: 10px;
transition: all 0.3s ease-in-out;
font-weight: 600;
width: calc(30vw - 30px);
}
.dateSelector:first-child {
flex-grow: 1;
text-align: center;
padding: 10px;
/* border-radius: 10px 0 0 0; */
transition: all 0.3s ease-in-out;
font-weight: 600;
}
.dateSelector:last-child {
flex-grow: 1;
text-align: center;
padding: 10px;
/* border-radius: 0 10px 0 0; */
transition: all 0.3s ease-in-out;
font-weight: 600;
}
.dateSelectorActive {
color: black;
z-index: 2;
}