This commit is contained in:
Vassshhh
2025-08-05 15:11:59 +07:00
parent 690bb837f6
commit 7e83b442cc
9 changed files with 1144 additions and 392 deletions

View File

@@ -17,6 +17,7 @@ import Footer from './components/Footer';
import ProductDetailPage from './components/ProductDetailPage';
import Dashboard from './components/Dashboard';
import ProductsPage from './components/pages/ProductsPage';
@@ -43,7 +44,7 @@ function HomePage({
setSelectedProduct={setSelectedProduct}
setShowedModal={setShowedModal}
/>
<AcademySection
<AcademySection
courseSectionRef={courseSectionRef}
hoveredCard={hoveredCard}
setHoveredCard={setHoveredCard}
@@ -56,19 +57,19 @@ function HomePage({
);
}
function parseJwt(token) {
try {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(
atob(base64)
.split('')
.map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
.join('')
);
return JSON.parse(jsonPayload);
} catch (e) {
return null;
}
try {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(
atob(base64)
.split('')
.map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
.join('')
);
return JSON.parse(jsonPayload);
} catch (e) {
return null;
}
}
function App() {
@@ -76,48 +77,51 @@ function App() {
// State yang diperlukan untuk HomePage
const [hoveredCard, setHoveredCard] = useState(null);
const [subscriptions, setSubscriptions] = useState(null);
const [selectedProduct, setSelectedProduct] = useState({});
const [showedModal, setShowedModal] = useState(null); // 'product' | 'login' | null
const [postLoginAction, setPostLoginAction] = useState(null);
const [username, setUsername] = useState(null);
const productSectionRef = useRef(null);
const courseSectionRef = useRef(null);
useEffect(() => {
// Ambil token dari cookies
const match = document.cookie.match(new RegExp('(^| )token=([^;]+)'));
if (match) {
const token = match[2];
useEffect(() => {
// Ambil token dari cookies
const match = document.cookie.match(new RegExp('(^| )token=([^;]+)'));
if (match) {
const token = match[2];
fetch('https://bot.kediritechnopark.com/webhook/user-dev/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
fetch('https://bot.kediritechnopark.com/webhook/user-dev/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
},
})
.then(res => res.json())
.then(data => {
},
})
.then(res => res.json())
.then(data => {
if (data && data[0] && data[0].token) {
// Update token with data[0].token
document.cookie = `token=${data[0].token}; path=/`;
const payload = parseJwt(token);
if (data && data.token) {
// Update token with data[0].token
document.cookie = `token=${data.token}; path=/`;
console.log(data)
setSubscriptions(data.subscriptions)
const payload = parseJwt(data.token);
if (payload && payload.username) {
setUsername(payload.username);
setUsername(payload.username);
}
} else {
console.warn('Token tidak ditemukan dalam data.');
}
})
.catch(err => console.error('Fetch error:', err));
} else {
console.warn('Token tidak ditemukan dalam data.');
}
})
.catch(err => console.error('Fetch error:', err));
}
}, []);
}
}, []);
const scrollToProduct = () => {
productSectionRef.current?.scrollIntoView({ behavior: "smooth" });
};
@@ -132,6 +136,17 @@ function App() {
return () => clearTimeout(timer);
}, []);
const handleLogout = () => {
// Hapus cookie token dengan mengatur tanggal kadaluarsa ke masa lalu
document.cookie = 'token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC';
// Jika kamu menggunakan state seperti `setUsername`, bersihkan di sini juga
setUsername(null); // jika applicable
// Redirect ke homepage atau reload halaman
window.location.reload();
};
if (loading) {
return (
<div id="js-preloader" className="js-preloader">
@@ -150,7 +165,7 @@ function App() {
return (
<Router>
<div className="App">
<Header username={username} scrollToProduct={scrollToProduct} scrollToCourse={scrollToCourse} setShowedModal={setShowedModal} />
<Header username={username} scrollToProduct={scrollToProduct} scrollToCourse={scrollToCourse} setShowedModal={setShowedModal} handleLogout={handleLogout} />
<Routes>
<Route
path="/"
@@ -170,41 +185,48 @@ function App() {
<Route
path="/products"
element={
<ProductsPage/>
<ProductsPage subscriptions={subscriptions}/>
}
/>
<Route
path="/dashboard"
element={
<Dashboard />
}
/>
</Routes>
<Footer />
{/* Unified Modal */}
{showedModal && (
<div
className={styles.modal}
onClick={() => {
setShowedModal(null);
setSelectedProduct({});
}}
>
<div
className={styles.modalBody}
onClick={(e) => e.stopPropagation()}
>
{showedModal === 'product' && (
<ProductDetailPage
setPostLoginAction={setPostLoginAction}
setShowedModal={setShowedModal}
product={selectedProduct}
onClose={() => {
setShowedModal(null);
setSelectedProduct({});
}}
/>
)}
{showedModal === 'login' && (
<Login postLoginAction={postLoginAction} setPostLoginAction={setPostLoginAction} onClose={() => setShowedModal(null)} />
)}
</div>
</div>
)}
{/* Unified Modal */}
{showedModal && (
<div
className={styles.modal}
onClick={() => {
setShowedModal(null);
setSelectedProduct({});
}}
>
<div
className={styles.modalBody}
onClick={(e) => e.stopPropagation()}
>
{showedModal === 'product' && (
<ProductDetailPage
subscriptions={subscriptions}
setPostLoginAction={setPostLoginAction}
setShowedModal={setShowedModal}
product={selectedProduct}
onClose={() => {
setShowedModal(null);
setSelectedProduct({});
}}
/>
)}
{showedModal === 'login' && (
<Login postLoginAction={postLoginAction} setPostLoginAction={setPostLoginAction} onClose={() => setShowedModal(null)} />
)}
</div>
</div>
)}
</div>
</Router>
);