This commit is contained in:
zadit
2025-02-03 07:17:53 +07:00
parent 02e101025e
commit fa5bab4d5f
8 changed files with 199 additions and 30 deletions

View File

@@ -114,7 +114,7 @@ const LinktreePage = ({ setModal }) => {
/>
<input
type="password"
placeholder="Re-type Password"
placeholder="Ketik ulang password"
value={retypePassword}
onChange={(e) => setRetypePassword(e.target.value)}
maxLength="30"

View File

@@ -4,6 +4,9 @@ import styles from './Join.module.css'; // Import the module.css file
import { checkCoupon, logCouponForUser } from '../helpers/couponHelpers'; // Import the new helper
import Coupon from '../components/Coupon';
import {
getLocalStorage,
} from "../helpers/localStorageHelpers";
const LinktreePage = ({ data, setModal }) => {
const queryParams = new URLSearchParams(window.location.search);
@@ -21,9 +24,24 @@ const LinktreePage = ({ data, setModal }) => {
console.log(code)
if (modal == 'claim-coupon') {
if (!getLocalStorage('auth')) {
// Preserve the couponCode query param while navigating to the claim-coupon modal
const newUrl = `?modal=join${code ? `&couponCode=${code}` : ''}`;
window.location.href = newUrl; // This will update the URL and reload the page
}
setIsOnlyClaimCoupon(true)
setIsUsingCoupon(true); // Automatically switch to the coupon input state
}
else {
if (getLocalStorage('auth')) {
// Preserve the couponCode query param while navigating to the claim-coupon modal
const newUrl = `?modal=claim-coupon${code ? `&couponCode=${code}` : ''}`;
window.location.href = newUrl; // This will update the URL and reload the page
}
}
if (code) {
setCouponCode(code);
setIsUsingCoupon(true); // Automatically switch to the coupon input state
@@ -104,9 +122,9 @@ const LinktreePage = ({ data, setModal }) => {
</div>
) : (
<div className={styles.dashboardContainer}>
<div className={styles.mainHeading}>{isOnlyClaimCoupon ? 'Aktifkan Voucher' : 'Daftar Menggunakan Voucher'}</div>
<div className={styles.mainHeading}>{isOnlyClaimCoupon ? 'Aktifkan Voucher' : 'Daftar Dengan Voucher'}</div>
<div className={styles.subHeading}>
Voucher dapat digunakan untuk pembuatan akun penyewa maupun untuk memperpanjang masa berlangganan.
Voucher dapat digunakan untuk pembuatan akun bisnis maupun untuk memperpanjang masa berlangganan.
</div>
{couponStatus === 0 ? (
<form className={styles.linktreeForm} onSubmit={(e) => e.preventDefault()}>
@@ -152,7 +170,7 @@ const LinktreePage = ({ data, setModal }) => {
}
}}
>
<span>{isOnlyClaimCoupon ? 'Aktifkan untuk akun ini' : 'Buat akun dengan voucher ini'}</span>
<span>{isOnlyClaimCoupon ? 'Aktifkan untuk akun ini' : 'Buat akun bisnis dengan voucher ini'}</span>
</button>
</div>
@@ -161,6 +179,16 @@ const LinktreePage = ({ data, setModal }) => {
)}
<div className={styles.footer}>
<div className={styles.footerLinks}>
{!getLocalStorage('auth') &&
<a
href="https://linktr.ee/discover/trending"
target="_blank"
rel="noreferrer"
className={styles.footerLink}
>
Sudah punya akun bisnis?
</a>
}
<a
href="https://linktr.ee/discover/trending"
target="_blank"

View File

@@ -123,6 +123,8 @@
.claimButton span {
font-weight: 600;
font-size: 13px;
line-height: 21px;
}
/* Footer */

View File

@@ -114,6 +114,8 @@ const App = ({ forCafe = true, cafeId = -1,
const [analytics, setAnalytics] = useState({});
const [loading, setLoading] = useState(true);
const [filter, setFilter] = useState("yesterday");
const [circularFilter, setCircularFilter] = useState("item");
const [graphFilter, setGraphFilter] = useState("income");
const [itemName, setItemName] = useState('');
@@ -143,7 +145,7 @@ const App = ({ forCafe = true, cafeId = -1,
fetchData(filter); // Fetch data when filter changes
}, [filter, selectedCafeId]);
const filteredItems = analytics?.itemSales || analytics?.items || [];
const filteredItems = (selectedCafeId != 0 && selectedCafeId != -1) ? (circularFilter == 'item' ? analytics?.itemSales || [] : analytics.materialSpend || []) : analytics?.items || [];
const colors = [
"#af9463", // Bright Red
@@ -172,6 +174,11 @@ const App = ({ forCafe = true, cafeId = -1,
return total + cafeTotal;
}, 0);
const totalSpendAcrossAllCafes = filteredItems.reduce((total, cafe) => {
const cafeTotal = (cafe.report?.materialSpend || []).reduce((sum, item) => sum + item.spend, 0);
return total + cafeTotal;
}, 0);
// Define a color palette or generate colors dynamically
const colorPalette = colors;
@@ -214,6 +221,42 @@ const App = ({ forCafe = true, cafeId = -1,
segments.sort((a, b) => b.sold - a.sold);
let materialSegments = (selectedCafeId == 0 || selectedCafeId == -1) ? filteredItems.flatMap((cafe) => {
const cafeItems = cafe.report?.materialSpend || [];
console.log(cafeItems); // Log all items for the cafe
return cafeItems.map((item, index) => {
const percentage = totalSpendAcrossAllCafes > 0
? ((item.spend / totalSpendAcrossAllCafes) * 100).toFixed(2)
: 0;
console.log(`${item.materialName}: ${(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.materialName,
sold: item.spend,
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.materialName,
percentage: item.percentage,
color: color,
};
});
materialSegments.sort((a, b) => b.spend - a.spend);
console.log(selectedCafeId)
console.log(segments)
@@ -474,23 +517,46 @@ const App = ({ forCafe = true, cafeId = -1,
`Data dihitung dengan membandingkan
${comparisonText} hari terakhir dengan ${comparisonText} hari sebelumnya, dengan penghitungan dimulai dari data kemarin.`
:
(filter == 'monthly') ? `Data dihitung dengan membandingkan antara awal hingga akhir bulan ini dan bulan lalu, dengan penghitungan dimulai dari data kemarin` : `Data dihitung dengan membandingkan antara awal hingga akhir tahun ini dan tahun lalu, dengan penghitungan dimulai dari data kemarin`}
(filter == 'monthly') ? `Data dihitung dengan membandingkan antara awal hingga akhir bulan ini dan bulan lalu, dengan penghitungan berakhir pada data kemarin.` : `Data dihitung dengan membandingkan antara awal hingga akhir tahun ini dan tahun lalu, dengan penghitungan berakhir pada data kemarin.`}
</h6>
</div>
</div>
<div className={styles.filterSelectorWrapper}>
<div className={`${styles.filterSelector} ${circularFilter == 'item' ? '':styles.filterSelectorInactive}
}`}
onClick={() =>
setCircularFilter('item')
}
style={{ color: 'black', position: 'relative' }}
>
<div>Item laku</div>
</div>
<div
className={`${styles.filterSelector} ${circularFilter == 'material' ? '':styles.filterSelectorInactive}
}`}
onClick={() =>
setCircularFilter('material')
}
>
<div>Bahan baku</div>
</div>
</div>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "20px",
paddingTop: 0
}}
>
<div style={{ flex: 1 }}>
<CircularDiagram segments={segments} />
<CircularDiagram segments={circularFilter == 'item' ? segments : materialSegments} />
</div>
<div style={{ flex: 1, marginLeft: "20px" }}>
{segments.map((item, index) => (
{(circularFilter === 'item' ? segments : materialSegments).map((item, index) => (
<div
key={index}
style={{
@@ -513,10 +579,42 @@ const App = ({ forCafe = true, cafeId = -1,
))}
</div>
</div>
<div className={styles.filterSelectorWrapper}>
<div className={`${styles.filterSelector} ${graphFilter == 'income' ? '':styles.filterSelectorInactive}
}`}
onClick={() =>
setGraphFilter('income')
}
style={{ color: 'black', position: 'relative' }}
>
<div>Pemasukan</div>
</div>
<div
className={`${styles.filterSelector} ${graphFilter == 'outcome' ? '':styles.filterSelectorInactive}
}`}
onClick={() =>
setGraphFilter('outcome')
}
>
<div>Pengeluaran</div>
</div>
<div
className={`${styles.filterSelector} ${graphFilter == 'transactions' ? '':styles.filterSelectorInactive}
}`}
onClick={() =>
setGraphFilter('transactions')
}
>
<div>Transaksi</div>
</div>
</div>
{filter == 'yesterday' || filter == 'weekly' ?
<DailyCharts transactionGraph={analytics?.transactionGraph || analytics?.combinedTransactionGraph} type={filter} colors={colors} />
:
<PeriodCharts type={filter} aggregatedCurrentReports={analytics?.aggregatedCurrentReports} aggregatedPreviousReports={analytics?.aggregatedPreviousReports} colors={colors} />
<PeriodCharts type={filter} graphFilter={graphFilter} aggregatedCurrentReports={analytics?.aggregatedCurrentReports} aggregatedPreviousReports={analytics?.aggregatedPreviousReports} colors={colors} />
}
</div>
}

View File

@@ -293,7 +293,7 @@
justify-content: space-around;
position: relative;
overflow: hidden;
width: calc(100vw - 30px);
width: calc(100vw - 50px);
}
.dateSelector {
@@ -342,4 +342,33 @@
margin-bottom: 10px;
width: 100%;
height: 52px;
}
.filterSelectorWrapper {
display: flex;
justify-content: space-around;
position: relative;
overflow: hidden;
width: calc(100vw - 60px);
margin: 10px 30px 10px 30px;
}
.filterSelector {
flex-grow: 1;
padding: 6px;
width: calc(30vw - 30px);
background-color: #00000045;
border-radius: 20px;
font-size: 14px;
margin: 3px;
}
.filterSelectorInactive {
flex-grow: 1;
padding: 6px;
width: calc(30vw - 30px);
border-radius: 20px;
font-size: 14px;
margin: 3px;
background-color: white;
border: 1px solid black;
}