Autosave: 20260526-085434

This commit is contained in:
Flatlogic Bot 2026-05-26 08:54:27 +00:00
parent cb3a15004c
commit a440f4357f
7 changed files with 196 additions and 48 deletions

View File

@ -23,7 +23,8 @@ if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
$result = store_login_user($_POST);
if (!empty($result['success'])) {
store_flash('success', (string)($result['message'] ?? 'Login berhasil.'));
header('Location: ' . $redirectTo);
$destination = store_resume_pending_cart_add($redirectTo);
header('Location: ' . $destination);
exit;
}
@ -37,7 +38,8 @@ if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
$result = store_register_user($_POST);
if (!empty($result['success'])) {
store_flash('success', (string)($result['message'] ?? 'Akun berhasil dibuat.'));
header('Location: ' . $redirectTo);
$destination = store_resume_pending_cart_add($redirectTo);
header('Location: ' . $destination);
exit;
}
@ -51,10 +53,13 @@ if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
$currentUser = store_current_user();
$summary = store_cart_summary();
$categories = store_categories();
$pendingCartAdd = store_pending_cart_add();
$accountTitle = $currentUser ? 'Akun Saya' : 'Login / Register';
$accountDescription = $currentUser
? 'Ringkasan akun user untuk melanjutkan belanja, checkout, dan melacak pesanan.'
: 'Halaman login dan registrasi user untuk masuk ke sistem menggunakan email dan password.';
: ($pendingCartAdd
? 'Login atau register untuk melanjutkan produk yang dipilih ke keranjang belanja.'
: 'Halaman login dan registrasi user untuk masuk ke sistem menggunakan email dan password.');
store_page_start($accountTitle, $accountDescription, ['noindex' => true]);
?>
@ -62,12 +67,18 @@ store_page_start($accountTitle, $accountDescription, ['noindex' => true]);
<div class="section-heading mb-4">
<span class="eyebrow">Login User</span>
<h1 class="section-title">
<?= $currentUser ? 'Akun user aktif dan siap dipakai.' : 'Tampilan login digunakan oleh pengguna yang telah terdaftar untuk masuk ke dalam sistem.' ?>
<?= $currentUser
? 'Akun user aktif dan siap dipakai.'
: ($pendingCartAdd
? 'Silakan login untuk melanjutkan produk yang sudah dipilih.'
: 'Tampilan login digunakan oleh pengguna yang telah terdaftar untuk masuk ke dalam sistem.') ?>
</h1>
<p class="section-copy mb-0">
<?= $currentUser
? 'Anda sudah login. Gunakan halaman ini untuk kembali ke katalog, membuka keranjang, atau melacak status pesanan.'
: 'Masukkan email dan password pada form login, atau buat akun baru melalui form registrasi agar data pengguna tersimpan lebih rapi.' ?>
: ($pendingCartAdd
? 'Produk yang tadi dipilih akan otomatis dimasukkan ke keranjang setelah login atau registrasi berhasil.'
: 'Masukkan email dan password pada form login, atau buat akun baru melalui form registrasi agar data pengguna tersimpan lebih rapi.') ?>
</p>
</div>
@ -150,6 +161,16 @@ store_page_start($accountTitle, $accountDescription, ['noindex' => true]);
</section>
<?php else: ?>
<section class="surface-panel auth-shell">
<?php if ($pendingCartAdd): ?>
<div class="alert alert-light border shadow-sm mb-4" role="alert">
<strong><?= h($pendingCartAdd['product']['name']) ?></strong> sebanyak <?= h((string)$pendingCartAdd['quantity']) ?> item siap masuk ke keranjang.
Login atau buat akun terlebih dahulu, lalu sistem akan otomatis melanjutkan proses ini.
<div class="small text-muted mt-2">
Anda juga bisa kembali ke <a href="product.php?slug=<?= h((string)$pendingCartAdd['product']['slug']) ?>">halaman detail produk</a>
untuk meninjau harga dan informasinya lagi.
</div>
</div>
<?php endif; ?>
<div class="auth-toggle mb-4">
<a class="toggle-pill<?= $mode === 'login' ? ' is-active' : '' ?>" href="auth.php?mode=login<?= $redirectTo !== 'auth.php' ? '&amp;redirect_to=' . urlencode($redirectTo) : '' ?>">Login</a>
<a class="toggle-pill<?= $mode === 'register' ? ' is-active' : '' ?>" href="auth.php?mode=register<?= $redirectTo !== 'auth.php' ? '&amp;redirect_to=' . urlencode($redirectTo) : '' ?>">Register</a>
@ -164,7 +185,7 @@ store_page_start($accountTitle, $accountDescription, ['noindex' => true]);
<h2 class="h4 mb-1">Masuk dengan email dan password</h2>
</div>
</div>
<p class="text-muted mb-4">Gunakan akun yang sudah terdaftar untuk mengakses alur pemesanan dengan lebih cepat.</p>
<p class="text-muted mb-4"><?= $pendingCartAdd ? 'Masuk untuk melanjutkan produk yang tadi Anda pilih ke keranjang belanja.' : 'Gunakan akun yang sudah terdaftar untuk mengakses alur pemesanan dengan lebih cepat.' ?></p>
<?php if ($loginMessage !== ''): ?>
<div class="alert alert-warning border-0 shadow-sm" role="alert"><?= h($loginMessage) ?></div>
@ -197,7 +218,7 @@ store_page_start($accountTitle, $accountDescription, ['noindex' => true]);
<h2 class="h4 mb-1">Daftarkan akun pengguna</h2>
</div>
</div>
<p class="text-muted mb-4">Setelah registrasi berhasil, akun akan langsung aktif pada sesi browser ini.</p>
<p class="text-muted mb-4"><?= $pendingCartAdd ? 'Setelah registrasi berhasil, sistem akan langsung mengaktifkan akun lalu melanjutkan produk yang sudah dipilih ke keranjang.' : 'Setelah registrasi berhasil, akun akan langsung aktif pada sesi browser ini.' ?></p>
<?php if ($registerMessage !== ''): ?>
<div class="alert alert-warning border-0 shadow-sm" role="alert"><?= h($registerMessage) ?></div>

View File

@ -5,6 +5,7 @@ require_once __DIR__ . '/store.php';
$summary = store_cart_summary();
$lines = $summary['lines'];
$currentUser = store_current_user();
store_page_start('Keranjang', 'Tinjau item, ubah quantity, dan lanjutkan checkout.', ['noindex' => true]);
?>
@ -15,6 +16,13 @@ store_page_start('Keranjang', 'Tinjau item, ubah quantity, dan lanjutkan checkou
<p class="section-copy mb-0">Update quantity, cek ongkir, lalu lanjut ke checkout untuk menyimpan pesanan ke sistem.</p>
</div>
<?php if ($lines && !$currentUser): ?>
<div class="alert alert-light border shadow-sm mb-4" role="alert">
Keranjang berisi item, tetapi checkout hanya bisa dilakukan setelah login.
Silakan <a href="auth.php?mode=login&amp;redirect_to=cart.php">login / register</a> untuk melanjutkan pesanan.
</div>
<?php endif; ?>
<?php if (!$lines): ?>
<div class="empty-state-card text-center mx-auto">
<span class="eyebrow">Keranjang kosong</span>
@ -99,9 +107,16 @@ store_page_start('Keranjang', 'Tinjau item, ubah quantity, dan lanjutkan checkou
</div>
<p class="note-copy mt-3 mb-4">Gratis ongkir otomatis untuk subtotal mulai Rp 250.000.</p>
<div class="d-grid gap-2">
<a class="btn btn-dark btn-lg" href="checkout.php">Lanjut ke checkout</a>
<?php if ($currentUser): ?>
<a class="btn btn-dark btn-lg" href="checkout.php">Lanjut ke checkout</a>
<?php else: ?>
<a class="btn btn-dark btn-lg" href="auth.php?mode=login&amp;redirect_to=cart.php">Login untuk lanjut checkout</a>
<?php endif; ?>
<a class="btn btn-outline-secondary" href="order_status.php">Sudah punya kode pesanan?</a>
</div>
<?php if (!$currentUser): ?>
<p class="note-copy mt-3 mb-0">Setelah login berhasil, Anda bisa kembali ke keranjang dan meneruskan checkout.</p>
<?php endif; ?>
</aside>
</div>
</div>

View File

@ -15,6 +15,18 @@ switch ($action) {
case 'add':
$slug = (string)($_POST['slug'] ?? '');
$quantity = (int)($_POST['quantity'] ?? 1);
if (!store_is_logged_in()) {
if (store_queue_cart_add_after_login($slug, $quantity, $redirectTo)) {
store_flash('warning', 'Silakan login terlebih dahulu untuk menambahkan produk ke keranjang.');
header('Location: auth.php?mode=login&redirect_to=' . rawurlencode($redirectTo));
exit;
}
store_flash('danger', 'Produk tidak ditemukan.');
break;
}
if (store_add_to_cart($slug, $quantity)) {
$product = store_product($slug);
store_flash('success', ($product['name'] ?? 'Produk') . ' ditambahkan ke keranjang.');

View File

@ -10,9 +10,15 @@ if (!$summary['lines']) {
exit;
}
$currentUser = store_current_user();
if (!$currentUser) {
store_flash('warning', 'Silakan login terlebih dahulu untuk melanjutkan checkout.');
header('Location: auth.php?mode=login&redirect_to=checkout.php');
exit;
}
$formData = store_checkout_defaults();
$errors = [];
$currentUser = store_current_user();
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
$result = store_create_order($_POST);
@ -35,12 +41,6 @@ store_page_start('Checkout', 'Lengkapi data pelanggan, alamat, dan metode pembay
<p class="section-copy mb-0">Status awal pesanan adalah <strong>Menunggu Pembayaran</strong>. Instruksi pembayaran akan tampil setelah order berhasil dibuat.</p>
</div>
<?php if (!$currentUser): ?>
<div class="alert alert-light border shadow-sm mb-4" role="alert">
Belum login? <a href="auth.php?redirect_to=checkout.php">Masuk atau daftar akun</a> agar nama dan email terisi otomatis saat checkout.
</div>
<?php endif; ?>
<?php if (isset($errors['cart'])): ?>
<div class="alert alert-warning border-0 shadow-sm mb-4" role="alert">
<?= h($errors['cart']) ?>

View File

@ -13,6 +13,7 @@ $products = store_filtered_products($selectedCategory);
$summary = store_cart_summary();
$cartLines = array_slice($summary['lines'], 0, 3);
$currentUser = store_current_user();
$requiresLoginToCart = $currentUser === null;
$paymentMethods = store_payment_methods();
store_page_start(
@ -23,15 +24,15 @@ store_page_start(
<section class="hero-panel mb-4 mb-lg-5">
<div class="row g-4 align-items-center">
<div class="col-lg-7">
<span class="eyebrow">Home</span>
<h1 class="display-title">Pesan kue lebih jelas dengan menu user yang lengkap.</h1>
<span class="eyebrow">Home Publik</span>
<h1 class="display-title">Halaman home dapat diakses oleh semua pengguna.</h1>
<p class="lead-copy">
Tampilan user bakery kini dibuat lebih mudah dipahami: ada menu <strong>Home</strong>,
<strong>Daftar Kue</strong>, <strong>Info Pembayaran</strong>, <strong>Kontak Kami</strong>,
serta <strong>Login / Register</strong> agar alur pemesanan terasa lebih terstruktur.
Dari halaman ini, pengunjung bisa melihat katalog bakery, memilih produk, lalu membuka
<strong>halaman detail</strong> yang berisi informasi produk, harga, dan tombol keranjang.
Saat tombol keranjang dipilih, sistem akan memeriksa apakah pengguna sudah login atau belum.
</p>
<div class="d-flex flex-wrap gap-2 mt-4">
<a class="btn btn-dark btn-lg" href="#catalog">Daftar kue</a>
<a class="btn btn-dark btn-lg" href="#catalog">Pilih produk</a>
<a class="btn btn-outline-secondary btn-lg" href="auth.php"><?= $currentUser ? 'Akun saya' : 'Login / Register' ?></a>
<a class="btn btn-outline-secondary btn-lg" href="#payment-info">Info pembayaran</a>
</div>
@ -39,32 +40,33 @@ store_page_start(
<div class="col-sm-4">
<div class="metric-card">
<div class="metric-value"><?= h((string)count(store_products())) ?></div>
<div class="metric-label">produk bakery tampil di daftar kue</div>
<div class="metric-label">produk tampil di home publik</div>
</div>
</div>
<div class="col-sm-4">
<div class="metric-card">
<div class="metric-value"><?= h((string)count($paymentMethods)) ?></div>
<div class="metric-label">metode pembayaran siap dipilih</div>
<div class="metric-label">metode bayar diinformasikan</div>
</div>
</div>
<div class="col-sm-4">
<div class="metric-card">
<div class="metric-value"><?= h((string)store_cart_count()) ?></div>
<div class="metric-label">item tersimpan di keranjang</div>
<div class="metric-label">item aktif di keranjang</div>
</div>
</div>
</div>
</div>
<div class="col-lg-5">
<aside class="summary-card h-100">
<div class="card-kicker">Alur pengguna</div>
<h2 class="summary-title">Dari login sampai cek status pesanan.</h2>
<div class="card-kicker">Alur user</div>
<h2 class="summary-title">Home detail produk login keranjang.</h2>
<ul class="list-clean compact-list mb-4">
<li><span class="list-index">1</span><span>Pengguna login dengan email dan password atau membuat akun baru.</span></li>
<li><span class="list-index">2</span><span>Pengguna membuka daftar kue dan memilih produk bakery yang diinginkan.</span></li>
<li><span class="list-index">3</span><span>Checkout menyimpan pesanan, alamat, dan metode pembayaran ke sistem.</span></li>
<li><span class="list-index">4</span><span>Kode pesanan dipakai lagi untuk melacak status dan konfirmasi pembayaran.</span></li>
<li><span class="list-index">1</span><span>Halaman home dapat dibuka oleh semua pengunjung.</span></li>
<li><span class="list-index">2</span><span>Saat produk dipilih, sistem menampilkan detail produk, harga, dan tombol keranjang.</span></li>
<li><span class="list-index">3</span><span>Saat tombol keranjang ditekan, sistem memeriksa apakah user sudah login.</span></li>
<li><span class="list-index">4</span><span>Jika belum login, user diarahkan ke halaman login / register.</span></li>
<li><span class="list-index">5</span><span>Jika sudah login, produk langsung ditambahkan ke keranjang belanja.</span></li>
</ul>
<div class="receipt-card">
@ -83,9 +85,9 @@ store_page_start(
<span>Total sementara</span>
<strong><?= h(store_money((float)$summary['grand_total'])) ?></strong>
</div>
<a class="btn btn-dark w-100 mt-3" href="cart.php">Lanjutkan checkout</a>
<a class="btn btn-dark w-100 mt-3" href="cart.php">Buka keranjang</a>
<?php else: ?>
<p class="text-muted mb-3">Keranjang masih kosong. Mulai dari daftar kue untuk mencoba alur pemesanan user.</p>
<p class="text-muted mb-3">Keranjang masih kosong. Mulai dengan memilih produk pada katalog di bawah.</p>
<a class="btn btn-outline-secondary w-100" href="#catalog">Buka daftar kue</a>
<?php endif; ?>
</div>
@ -98,20 +100,20 @@ store_page_start(
<div class="row g-3">
<div class="col-lg-4">
<div class="feature-card h-100">
<div class="feature-card__title">Login user lebih jelas</div>
<p class="feature-card__copy">Halaman login/register kini menjadi pintu masuk yang jelas bagi pengguna yang sudah atau belum memiliki akun.</p>
<div class="feature-card__title">Home dapat diakses umum</div>
<p class="feature-card__copy">Semua pengunjung dapat membuka homepage, melihat katalog, dan memilih produk tanpa harus login terlebih dahulu.</p>
</div>
</div>
<div class="col-lg-4">
<div class="feature-card h-100">
<div class="feature-card__title">Daftar kue lebih mudah dicari</div>
<p class="feature-card__copy">Produk dibagi per kategori agar pengguna lebih cepat menemukan cake, bread, atau pastry yang dibutuhkan.</p>
<div class="feature-card__title">Memilih produk membuka detail</div>
<p class="feature-card__copy">Setiap produk mengarahkan pengguna ke halaman detail yang menampilkan informasi produk, harga, dan tombol keranjang.</p>
</div>
</div>
<div class="col-lg-4">
<div class="feature-card h-100">
<div class="feature-card__title">Pembayaran & status tetap terhubung</div>
<p class="feature-card__copy">Setelah checkout, pelanggan tetap bisa melihat metode bayar dan memeriksa progress pesanan dari halaman status.</p>
<div class="feature-card__title">Keranjang selalu cek login</div>
<p class="feature-card__copy">Saat tombol keranjang dipilih, sistem akan mengecek sesi login. Jika belum login, pengguna diarahkan ke halaman autentikasi terlebih dahulu.</p>
</div>
</div>
</div>
@ -122,7 +124,7 @@ store_page_start(
<div>
<span class="eyebrow">Daftar Kue</span>
<h2 class="section-title">Pilihan cake, bread, dan pastry untuk pengguna.</h2>
<p class="section-copy mb-0">Gunakan filter kategori untuk melihat produk yang paling relevan sebelum ditambahkan ke keranjang belanja.</p>
<p class="section-copy mb-0">Klik salah satu produk untuk membuka halaman detail, melihat harga, lalu lanjut ke tombol keranjang sesuai alur pengguna.</p>
</div>
<div class="d-flex flex-wrap gap-2 filter-pills" data-filter-bar>
<?php foreach ($categories as $key => $category): ?>
@ -158,14 +160,12 @@ store_page_start(
<?php endforeach; ?>
</div>
<div class="d-flex flex-column gap-2 mt-auto">
<a class="btn btn-outline-secondary w-100" href="product.php?slug=<?= h($product['slug']) ?>">Lihat detail</a>
<form action="cart_action.php" method="post" class="d-grid" data-auto-disable>
<input type="hidden" name="action" value="add">
<input type="hidden" name="slug" value="<?= h($product['slug']) ?>">
<input type="hidden" name="quantity" value="1">
<input type="hidden" name="redirect_to" value="<?= h($_SERVER['REQUEST_URI'] ?? 'index.php') ?>">
<button class="btn btn-dark" type="submit">Tambah ke keranjang</button>
</form>
<a class="btn btn-dark w-100" href="product.php?slug=<?= h($product['slug']) ?>">Lihat detail &amp; harga</a>
<span class="text-muted small">
<?= $requiresLoginToCart
? 'Tombol keranjang tersedia di halaman detail. Jika belum login, sistem akan mengarahkan Anda ke halaman login terlebih dahulu.'
: 'Anda sudah login. Buka halaman detail untuk menambahkan produk ini langsung ke keranjang.' ?>
</span>
</div>
</div>
</article>

View File

@ -25,6 +25,7 @@ if (!$product) {
}
$relatedProducts = store_related_products($product['slug'], $product['category']);
$currentUser = store_current_user();
store_page_start($product['name'], $product['short_description']);
?>
@ -81,6 +82,11 @@ store_page_start($product['name'], $product['short_description']);
</div>
</div>
<div class="info-box mb-4">
<div class="card-kicker">Alur user</div>
<p class="mb-0">Halaman detail ini dapat diakses semua pengunjung. Saat tombol keranjang dipilih, sistem akan mengecek login terlebih dahulu sebelum produk dimasukkan ke keranjang.</p>
</div>
<form action="cart_action.php" method="post" class="purchase-box" data-auto-disable>
<input type="hidden" name="action" value="add">
<input type="hidden" name="slug" value="<?= h($product['slug']) ?>">
@ -95,6 +101,11 @@ store_page_start($product['name'], $product['short_description']);
<button class="btn btn-dark btn-lg flex-sm-fill" type="submit">Tambah ke keranjang</button>
<a class="btn btn-outline-secondary btn-lg flex-sm-fill" href="cart.php">Lihat keranjang</a>
</div>
<?php if (!$currentUser): ?>
<p class="text-muted small mt-3 mb-0">Login wajib sebelum produk masuk ke keranjang. Setelah login berhasil, item ini akan langsung ditambahkan dan Anda kembali ke halaman detail produk.</p>
<?php else: ?>
<p class="text-muted small mt-3 mb-0">Anda sudah login, jadi produk ini bisa langsung dimasukkan ke keranjang belanja.</p>
<?php endif; ?>
</form>
<div class="info-box mt-4">

View File

@ -16,6 +16,7 @@ const STORE_CART_KEY = 'sekut_cart';
const STORE_FLASH_KEY = 'sekut_flash';
const STORE_LAST_ORDER_KEY = 'sekut_last_order';
const STORE_USER_KEY = 'sekut_user';
const STORE_PENDING_CART_ADD_KEY = 'sekut_pending_cart_add';
function app_env(string $key, string $fallback = ''): string
{
@ -91,12 +92,71 @@ function store_set_user_session(array $user): void
function store_logout_user(): void
{
unset($_SESSION[STORE_USER_KEY]);
unset($_SESSION[STORE_USER_KEY], $_SESSION[STORE_PENDING_CART_ADD_KEY]);
if (session_status() === PHP_SESSION_ACTIVE) {
session_regenerate_id(true);
}
}
function store_queue_cart_add_after_login(string $slug, int $quantity = 1, string $redirectTo = 'index.php'): bool
{
$product = store_product($slug);
if (!$product) {
return false;
}
$_SESSION[STORE_PENDING_CART_ADD_KEY] = [
'slug' => (string)$product['slug'],
'quantity' => max(1, min(20, $quantity)),
'redirect_to' => store_safe_redirect($redirectTo, 'index.php'),
];
return true;
}
function store_pending_cart_add(): ?array
{
$pending = $_SESSION[STORE_PENDING_CART_ADD_KEY] ?? null;
if (!is_array($pending)) {
return null;
}
$slug = (string)($pending['slug'] ?? '');
if ($slug === '') {
unset($_SESSION[STORE_PENDING_CART_ADD_KEY]);
return null;
}
$product = store_product($slug);
if (!$product) {
unset($_SESSION[STORE_PENDING_CART_ADD_KEY]);
return null;
}
return [
'slug' => (string)$product['slug'],
'quantity' => max(1, min(20, (int)($pending['quantity'] ?? 1))),
'redirect_to' => store_safe_redirect((string)($pending['redirect_to'] ?? 'index.php'), 'index.php'),
'product' => $product,
];
}
function store_consume_pending_cart_add(): ?array
{
$pending = store_pending_cart_add();
unset($_SESSION[STORE_PENDING_CART_ADD_KEY]);
if (!$pending) {
return null;
}
return [
'slug' => (string)$pending['slug'],
'quantity' => (int)$pending['quantity'],
'redirect_to' => (string)$pending['redirect_to'],
];
}
function store_auth_password_error(string $password): string
{
if (store_strlen($password) < 8) {
@ -437,6 +497,35 @@ function store_add_to_cart(string $slug, int $quantity = 1): bool
return true;
}
function store_resume_pending_cart_add(string $fallback = 'index.php'): string
{
$pending = store_consume_pending_cart_add();
if (!$pending) {
return store_safe_redirect($fallback, 'index.php');
}
$redirectTo = store_safe_redirect((string)($pending['redirect_to'] ?? $fallback), $fallback);
$product = store_product((string)$pending['slug']);
if (!$product) {
store_flash('danger', 'Produk yang dipilih sudah tidak tersedia.');
return $redirectTo;
}
$quantity = (int)($pending['quantity'] ?? 1);
if (store_add_to_cart((string)$pending['slug'], $quantity)) {
$message = ($product['name'] ?? 'Produk') . ' ditambahkan ke keranjang.';
if ($quantity > 1) {
$message = ($product['name'] ?? 'Produk') . ' ditambahkan ke keranjang sebanyak ' . $quantity . ' item.';
}
store_flash('success', $message);
} else {
store_flash('danger', 'Produk tidak ditemukan.');
}
return $redirectTo;
}
function store_update_cart(array $quantities): void
{
$products = store_products();