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; justify-content: space-around;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
font-size: 14px;
} }
.dateSelector { .dateSelector {

View File

@@ -59,16 +59,20 @@ const DailyCharts = ({ transactionGraph, colors, type }) => {
0 0
); );
const formatDate = (dateString) => { const formatDate = (dateString) => {
const date = new Date(dateString); const date = new Date(dateString); // Parse the date string
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 };
};
// 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 ( return (
<div className={styles.chartItemContainer}> <div className={styles.chartItemContainer}>

View File

@@ -137,10 +137,10 @@ const App = ({ forCafe = true, cafeId="",
fetchData(filter); // Fetch data when filter changes fetchData(filter); // Fetch data when filter changes
}, [filter, selectedCafeId]); }, [filter, selectedCafeId]);
const filteredItems = analytics.itemSales || []; const filteredItems = analytics?.itemSales || analytics?.items || [];
const colors = [ const colors = [
"#E63946", // Bright Red "#af9463", // Bright Red
"#F4A261", // Soft Orange "#F4A261", // Soft Orange
"#FFD166", // Sunshine Yellow "#FFD166", // Sunshine Yellow
"#06D6A0", // Mint Green "#06D6A0", // Mint Green
@@ -161,11 +161,54 @@ const App = ({ forCafe = true, cafeId="",
"#BC4749", // Cranberry Red "#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
percentage: item.percentage, const colorPalette = colors;
color: colors[index] || "#cccccc",
})); // 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) => { const formatIncome = (amount) => {
if (amount >= 1_000_000_000) { if (amount >= 1_000_000_000) {
@@ -222,7 +265,7 @@ const App = ({ forCafe = true, cafeId="",
updatedFullTexts = [ updatedFullTexts = [
["semua", 0], // First entry is "semua" ["semua", 0], // First entry is "semua"
...otherCafes.map(cafe => [cafe.name, cafe.cafeId]), // Map over cafes to get name and cafeId pairs ...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' }}> <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>} {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' }}> <div style={{ marginTop: '10px' }}>
{!forCafe && <MultiSwitch {!forCafe &&
key={resetKey} // Add key to reset the component and force it to re-render
texts={texts} // <MultiSwitch
selectedSwitch={selectedSwitch} // key={resetKey} // Add key to reset the component and force it to re-render
bgColor={'#f4efe6'} // texts={texts}
borderColor={'transparent'} // selectedSwitch={selectedSwitch}
borderWidth={0.1} // bgColor={'#f4efe6'}
onToggleCallback={onItemToggle} // borderColor={'transparent'}
fontColor={"#af9463"} // borderWidth={0.1}
selectedFontColor={"black"} // onToggleCallback={onItemToggle}
selectedSwitchColor={"white"} // fontColor={"#af9463"}
eachSwitchWidth={70} // selectedFontColor={"black"}
height={"25px"} // selectedSwitchColor={"white"}
fontSize={"12px"} // 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> </div>
<div style={{ <div style={{
@@ -427,7 +491,7 @@ const App = ({ forCafe = true, cafeId="",
<CircularDiagram segments={segments} /> <CircularDiagram segments={segments} />
</div> </div>
<div style={{ flex: 1, marginLeft: "20px" }}> <div style={{ flex: 1, marginLeft: "20px" }}>
{filteredItems.map((item, index) => ( {segments.map((item, index) => (
<div <div
key={index} key={index}
style={{ style={{

View File

@@ -286,3 +286,44 @@
font-size: 20px; font-size: 20px;
text-align: center; 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;
}