ok
This commit is contained in:
@@ -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 segments = filteredItems.map((item, index) => ({
|
||||
percentage: item.percentage,
|
||||
color: colors[index] || "#cccccc",
|
||||
}));
|
||||
const totalSoldAcrossAllCafes = filteredItems.reduce((total, cafe) => {
|
||||
const cafeTotal = (cafe.report?.itemSales || []).reduce((sum, item) => sum + item.sold, 0);
|
||||
return total + cafeTotal;
|
||||
}, 0);
|
||||
|
||||
// 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: 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={{
|
||||
|
||||
@@ -285,4 +285,45 @@
|
||||
font-family: Helvetica, Arial Black, sans;
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user