ok
This commit is contained in:
42
src/App.js
42
src/App.js
@@ -38,7 +38,7 @@ function HomePage({
|
||||
|
||||
if (tab === 'products') scrollToProduct();
|
||||
if (tab === 'academy') scrollToCourse();
|
||||
}, [productSectionRef, courseSectionRef]);
|
||||
}, [productSectionRef.current, courseSectionRef.current]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -194,31 +194,42 @@ function App() {
|
||||
if (!productModalRequest || !subscriptions) return;
|
||||
|
||||
const { productId, authorizedUri, unauthorizedUri } = productModalRequest;
|
||||
console.log(subscriptions)
|
||||
|
||||
const hasAccess = subscriptions && subscriptions.some(
|
||||
sub => sub.product_id === productId || sub.product_parent_id === productId
|
||||
);
|
||||
console.log(hasAccess)
|
||||
console.log("hasAccess:", hasAccess);
|
||||
|
||||
if (hasAccess) {
|
||||
if (authorizedUri) {
|
||||
let finalUri = decodeURIComponent(authorizedUri);
|
||||
const token = document.cookie.match(/(^| )token=([^;]+)/)?.[2];
|
||||
|
||||
if (finalUri.includes('token=null') || finalUri.includes('token=')) {
|
||||
// --- ambil product_name distinct berdasarkan productId/parent ---
|
||||
const relatedSubs = subscriptions.filter(
|
||||
sub => sub.product_id === productId || sub.product_parent_id === productId
|
||||
);
|
||||
const distinctNames = [...new Set(relatedSubs.map(sub => sub.product_name))];
|
||||
|
||||
if (distinctNames.length > 1) {
|
||||
// lebih dari 1 → pakai dashboard=true
|
||||
const url = new URL(finalUri);
|
||||
url.searchParams.set('token', token || '');
|
||||
url.searchParams.set("token", token || "");
|
||||
finalUri = url.toString();
|
||||
} else if (distinctNames.length === 1) {
|
||||
// hanya 1 → tambahkan productName=<nama> sebelum query lain
|
||||
const url = new URL(finalUri);
|
||||
url.searchParams.set("token", token || "");
|
||||
url.searchParams.set("productName", distinctNames[0]);
|
||||
finalUri = url.toString();
|
||||
}
|
||||
|
||||
window.location.href = finalUri;
|
||||
}
|
||||
else {// Assuming you already imported processProducts from './processProducts'
|
||||
|
||||
} else {
|
||||
// fallback ambil detail produk via fetch
|
||||
fetch('https://bot.kediritechnopark.com/webhook/store-production/products', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
itemsId: [productId],
|
||||
withChildren: true,
|
||||
@@ -227,9 +238,7 @@ function App() {
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
// Process the raw data to group children under their parent
|
||||
const processed = processProducts(data);
|
||||
// Set the first product (which should be the parent with children nested)
|
||||
setSelectedProduct(processed[0]);
|
||||
setShowedModal('product');
|
||||
}
|
||||
@@ -240,12 +249,9 @@ function App() {
|
||||
if (unauthorizedUri) {
|
||||
window.location.href = decodeURIComponent(unauthorizedUri);
|
||||
} else {
|
||||
|
||||
fetch('https://bot.kediritechnopark.com/webhook/store-production/products', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
itemsId: [productId],
|
||||
withChildren: true,
|
||||
@@ -254,9 +260,7 @@ function App() {
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
// Process the raw data to group children under their parent
|
||||
const processed = processProducts(data);
|
||||
// Set the first product (which should be the parent with children nested)
|
||||
setSelectedProduct(processed[0]);
|
||||
setShowedModal('product');
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Container, Row, Col, Card, Button, Tabs, Tab, Form } from "react-bootstrap";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import processProducts from '../../helper/processProducts';
|
||||
|
||||
const Dashboard = ({
|
||||
subscriptions,
|
||||
@@ -28,7 +27,6 @@ const Dashboard = ({
|
||||
}
|
||||
});
|
||||
|
||||
// 🔹 Handle input settings
|
||||
const handleSettingsChange = (field, value, nested = false) => {
|
||||
if (nested) {
|
||||
setSettings((prev) => ({
|
||||
@@ -40,7 +38,6 @@ const Dashboard = ({
|
||||
}
|
||||
};
|
||||
|
||||
// 🔹 Save profile
|
||||
const saveSettings = () => {
|
||||
fetch("https://bot.kediritechnopark.com/webhook-test/user-production/data", {
|
||||
method: "PUT",
|
||||
@@ -52,7 +49,6 @@ const Dashboard = ({
|
||||
.catch((err) => alert("Error updating settings: " + err));
|
||||
};
|
||||
|
||||
// 🔹 Group subscriptions
|
||||
const groupSubscriptionsByProductName = (subs) => {
|
||||
const result = {};
|
||||
subs.forEach((sub) => {
|
||||
@@ -82,7 +78,6 @@ const Dashboard = ({
|
||||
return result;
|
||||
};
|
||||
|
||||
// 🔹 Fetch produk berdasarkan subscription
|
||||
useEffect(() => {
|
||||
if (!subscriptions) return;
|
||||
|
||||
@@ -96,54 +91,46 @@ const Dashboard = ({
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
console.log(data)
|
||||
|
||||
const dataMap = {};
|
||||
data.forEach((item) => {
|
||||
dataMap[item.id] = { ...item, children: [] };
|
||||
});
|
||||
|
||||
// Masukkan anak-anak ke parent-nya
|
||||
data.forEach((item) => {
|
||||
if (item.sub_product_of && dataMap[item.sub_product_of]) {
|
||||
dataMap[item.sub_product_of].children.push(dataMap[item.id]);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(dataMap)
|
||||
const enrichedData = Object.values(groupedSubs)
|
||||
.filter((group) => data.some((p) => p.id === group.product_id))
|
||||
.map((group) => {
|
||||
const productData = data.find((p) => p.id === group.product_id);
|
||||
let image = productData?.image || "";
|
||||
let description = productData?.description || "";
|
||||
let site_url = productData?.site_url || "";
|
||||
if (!image && productData?.sub_product_of) {
|
||||
console.log(productData)
|
||||
let realProductName = productData?.name || "";
|
||||
if (!description && productData?.sub_product_of) {
|
||||
const parent = data.find((p) => p.id === productData.sub_product_of);
|
||||
image = parent?.image || "";
|
||||
description = parent?.description || "";
|
||||
site_url = parent?.site_url || "";
|
||||
realProductName = parent.name;
|
||||
}
|
||||
|
||||
return {
|
||||
executeCheckout: group.product_name,
|
||||
id: group.product_id,
|
||||
name: group.product_name,
|
||||
realProductName,
|
||||
type: productData?.type || "product",
|
||||
image,
|
||||
description,
|
||||
site_url,
|
||||
price: productData?.price || 0,
|
||||
currency: productData?.currency || "IDR",
|
||||
duration: productData?.duration || {},
|
||||
sub_product_of: productData?.sub_product_of || null,
|
||||
is_visible: productData?.is_visible ?? true,
|
||||
unit_type: productData?.unit_type || group.unit_type,
|
||||
quantity: group.quantity,
|
||||
end_date: group.end_date,
|
||||
children: dataMap[productData?.sub_product_of]?.children || []
|
||||
};
|
||||
});
|
||||
console.log(enrichedData)
|
||||
|
||||
setProducts(enrichedData);
|
||||
})
|
||||
.catch((err) => console.error("Fetch error:", err));
|
||||
@@ -151,18 +138,13 @@ const Dashboard = ({
|
||||
|
||||
return (
|
||||
<Container fluid className="mt-4">
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onSelect={(k) => setActiveTab(k)}
|
||||
className="mb-3"
|
||||
>
|
||||
{/* Produk Saya */}
|
||||
<Tabs activeKey={activeTab} onSelect={(k) => setActiveTab(k)} className="mb-3">
|
||||
<Tab eventKey="products" title="Produk Saya">
|
||||
<Row>
|
||||
{products.map((product) => (
|
||||
<Col md={4} key={product.id} className="mb-4">
|
||||
{products.map((product, i) => (
|
||||
<Col md={4} key={i} className="mb-4">
|
||||
<Card
|
||||
className={`h-100 shadow-sm ${hoveredCard === product.name ? "border-primary" : ""}`}
|
||||
className={`h-100 shadow-sm p-2 ${hoveredCard === product.name ? "border-primary" : ""}`}
|
||||
onMouseEnter={() => setHoveredCard(product.name)}
|
||||
onMouseLeave={() => setHoveredCard(null)}
|
||||
onClick={() => {
|
||||
@@ -170,27 +152,25 @@ const Dashboard = ({
|
||||
setShowedModal("product");
|
||||
}}
|
||||
>
|
||||
{product.image && (
|
||||
<Card.Img variant="top" src={product.image} />
|
||||
)}
|
||||
<Card.Body>
|
||||
<Card.Title>{product.name.split("%%%")[0]}</Card.Title>
|
||||
<Card.Text>{product.description}</Card.Text>
|
||||
<Card.Title>
|
||||
📦 {product.name.split("%%%")[0] + ' - ' + product.realProductName}
|
||||
</Card.Title>
|
||||
<Card.Text style={{ fontSize: "0.9rem", color: "#555" }}>
|
||||
{product.description}
|
||||
</Card.Text>
|
||||
</Card.Body>
|
||||
<Card.Footer>
|
||||
<Card.Footer className="d-flex justify-content-between align-items-center">
|
||||
<small className="text-muted">
|
||||
{product.unit_type === "duration"
|
||||
? `Valid until: ${product.end_date
|
||||
? new Date(product.end_date).toLocaleDateString()
|
||||
: "N/A"
|
||||
}`
|
||||
: `SISA TOKEN ${product.quantity || 0}`}
|
||||
? `Valid until: ${product.end_date ? new Date(product.end_date).toLocaleDateString() : "N/A"}`
|
||||
: `SISA TOKEN: ${product.quantity || 0}`}
|
||||
</small>
|
||||
<Button
|
||||
variant="primary"
|
||||
variant="outline-primary"
|
||||
size="sm"
|
||||
className="float-end"
|
||||
onClick={() => {
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setSelectedProduct(product);
|
||||
setShowedModal("product");
|
||||
setWillDo("checkout");
|
||||
@@ -203,21 +183,19 @@ const Dashboard = ({
|
||||
</Col>
|
||||
))}
|
||||
|
||||
{/* Tambah produk baru */}
|
||||
<Col md={4} className="mb-4">
|
||||
<Card
|
||||
className={`h-100 shadow-sm text-center align-items-center justify-content-center`}
|
||||
className="h-100 shadow-sm d-flex justify-content-center align-items-center text-center"
|
||||
onClick={() => navigate("/?tab=products")}
|
||||
>
|
||||
<Card.Body>
|
||||
<h5>+ Tambah produk baru</h5>
|
||||
<h5 style={{ color: "#007bff" }}>➕ Tambah Produk Baru</h5>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</Tab>
|
||||
|
||||
{/* Profil Pengguna */}
|
||||
<Tab eventKey="settings" title="Profil Pengguna">
|
||||
<Form>
|
||||
<Row>
|
||||
@@ -232,7 +210,6 @@ const Dashboard = ({
|
||||
/>
|
||||
</Form.Group>
|
||||
</Col>
|
||||
|
||||
<Col md={6}>
|
||||
<Form.Group className="mb-3">
|
||||
<Form.Label>Email</Form.Label>
|
||||
@@ -333,7 +310,6 @@ const Dashboard = ({
|
||||
</Form>
|
||||
</Tab>
|
||||
|
||||
{/* Orders */}
|
||||
<Tab eventKey="orders" title="Pembelian">
|
||||
<h4>My Orders</h4>
|
||||
<p>Orders list will be displayed here.</p>
|
||||
|
||||
Reference in New Issue
Block a user