mirror of
https://github.com/myronblair/tomsjavajive-app
synced 2026-06-30 17:50:56 -05:00
453 lines
15 KiB
PHP
453 lines
15 KiB
PHP
<?php
|
|
/**
|
|
* Tom's Java Jive - Customer Loyalty Rewards Page
|
|
*/
|
|
|
|
$pageTitle = "My Rewards - Tom's Java Jive";
|
|
require_once __DIR__ . '/../includes/functions.php';
|
|
require_once __DIR__ . '/../includes/auth.php';
|
|
require_once __DIR__ . '/../includes/loyalty.php';
|
|
|
|
CustomerAuth::require();
|
|
$customer = CustomerAuth::getFullUser();
|
|
$currentPage = 'rewards';
|
|
|
|
// Get loyalty status
|
|
$loyaltyStatus = loyalty()->getCustomerTier($customer['customer_id']);
|
|
$tiers = loyalty()->getTiers();
|
|
$conversion = loyalty()->getConversionInfo();
|
|
$history = loyalty()->getHistory($customer['customer_id'], 20);
|
|
|
|
// Handle redemption
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['redeem_points'])) {
|
|
$points = intval($_POST['points'] ?? 0);
|
|
|
|
if ($points >= 100) {
|
|
$result = loyalty()->redeemPoints($customer['customer_id'], $points);
|
|
|
|
if ($result['success']) {
|
|
setFlash('success', "Successfully redeemed {$points} points for " . formatCurrency($result['credit_value']) . " wallet credit!");
|
|
} else {
|
|
setFlash('error', $result['error']);
|
|
}
|
|
} else {
|
|
setFlash('error', 'Minimum 100 points required for redemption');
|
|
}
|
|
|
|
redirect('/account/rewards.php');
|
|
}
|
|
|
|
require_once __DIR__ . '/../includes/header.php';
|
|
require_once __DIR__ . '/includes/sidebar.php';
|
|
?>
|
|
|
|
<style>
|
|
.tier-card {
|
|
background: linear-gradient(135deg, <?= $loyaltyStatus['info']['color'] ?>22, <?= $loyaltyStatus['info']['color'] ?>44);
|
|
border: 2px solid <?= $loyaltyStatus['info']['color'] ?>;
|
|
border-radius: var(--radius-lg);
|
|
padding: 2rem;
|
|
margin-bottom: 2rem;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.tier-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: -50%;
|
|
right: -20%;
|
|
width: 300px;
|
|
height: 300px;
|
|
background: <?= $loyaltyStatus['info']['color'] ?>;
|
|
opacity: 0.1;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.tier-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
background: <?= $loyaltyStatus['info']['color'] ?>;
|
|
color: <?= in_array($loyaltyStatus['tier'], ['silver', 'platinum']) ? '#333' : 'white' ?>;
|
|
padding: 0.5rem 1rem;
|
|
border-radius: 20px;
|
|
font-weight: 600;
|
|
font-size: 0.875rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.points-display {
|
|
display: flex;
|
|
gap: 3rem;
|
|
margin: 1.5rem 0;
|
|
}
|
|
|
|
.points-item {
|
|
text-align: center;
|
|
}
|
|
|
|
.points-value {
|
|
font-size: 2.5rem;
|
|
font-weight: 700;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
.points-label {
|
|
color: var(--color-text-muted);
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.progress-to-next {
|
|
background: var(--color-surface);
|
|
border-radius: var(--radius-lg);
|
|
padding: 1.5rem;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.progress-bar-wrapper {
|
|
background: var(--color-border);
|
|
border-radius: 10px;
|
|
height: 12px;
|
|
overflow: hidden;
|
|
margin: 0.75rem 0;
|
|
}
|
|
|
|
.progress-bar-fill {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, <?= $loyaltyStatus['info']['color'] ?>, <?= $loyaltyStatus['next_tier_info']['color'] ?? $loyaltyStatus['info']['color'] ?>);
|
|
border-radius: 10px;
|
|
transition: width 0.5s ease;
|
|
}
|
|
|
|
.tier-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 1rem;
|
|
margin: 2rem 0;
|
|
}
|
|
|
|
.tier-item {
|
|
background: var(--color-surface);
|
|
border-radius: var(--radius-lg);
|
|
padding: 1.25rem;
|
|
text-align: center;
|
|
border: 2px solid transparent;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.tier-item.current {
|
|
border-color: var(--color-primary);
|
|
box-shadow: 0 4px 12px rgba(255, 94, 26, 0.2);
|
|
}
|
|
|
|
.tier-item-icon {
|
|
width: 50px;
|
|
height: 50px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin: 0 auto 0.75rem;
|
|
font-size: 1.25rem;
|
|
}
|
|
|
|
.tier-item h4 {
|
|
margin: 0 0 0.25rem;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.tier-item .points {
|
|
font-size: 0.75rem;
|
|
color: var(--color-text-muted);
|
|
}
|
|
|
|
.redeem-card {
|
|
background: var(--color-surface);
|
|
border-radius: var(--radius-lg);
|
|
padding: 1.5rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.redeem-options {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 1rem;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.redeem-option {
|
|
background: var(--color-background);
|
|
border: 2px solid var(--color-border);
|
|
border-radius: var(--radius-md);
|
|
padding: 1rem;
|
|
text-align: center;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.redeem-option:hover {
|
|
border-color: var(--color-primary);
|
|
}
|
|
|
|
.redeem-option.selected {
|
|
border-color: var(--color-primary);
|
|
background: rgba(255, 94, 26, 0.05);
|
|
}
|
|
|
|
.redeem-option .points {
|
|
font-size: 1.5rem;
|
|
font-weight: 700;
|
|
color: var(--color-primary);
|
|
}
|
|
|
|
.redeem-option .value {
|
|
color: var(--color-success);
|
|
font-weight: 600;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.points-display {
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
.tier-grid {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
|
|
.redeem-options {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<div class="account-header">
|
|
<h1>My Rewards</h1>
|
|
<p class="text-muted">Earn points and unlock exclusive benefits</p>
|
|
</div>
|
|
|
|
<?php if (hasFlash('success')): ?>
|
|
<div class="alert alert-success mb-2">
|
|
<i class="fas fa-check-circle"></i> <?= getFlash('success') ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if (hasFlash('error')): ?>
|
|
<div class="alert alert-error mb-2">
|
|
<i class="fas fa-exclamation-circle"></i> <?= getFlash('error') ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Current Tier Card -->
|
|
<div class="tier-card">
|
|
<div class="tier-badge">
|
|
<i class="fas <?= $loyaltyStatus['info']['icon'] ?>"></i>
|
|
<?= $loyaltyStatus['info']['name'] ?>
|
|
</div>
|
|
|
|
<div class="points-display">
|
|
<div class="points-item">
|
|
<div class="points-value"><?= number_format($loyaltyStatus['points']) ?></div>
|
|
<div class="points-label">Available Points</div>
|
|
</div>
|
|
<div class="points-item">
|
|
<div class="points-value"><?= formatCurrency($loyaltyStatus['points'] * $conversion['points_value']) ?></div>
|
|
<div class="points-label">Points Value</div>
|
|
</div>
|
|
<div class="points-item">
|
|
<div class="points-value"><?= $loyaltyStatus['info']['multiplier'] ?>x</div>
|
|
<div class="points-label">Earning Rate</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($loyaltyStatus['next_tier']): ?>
|
|
<div class="progress-to-next">
|
|
<div style="display: flex; justify-content: space-between; align-items: center;">
|
|
<span>Progress to <?= $loyaltyStatus['next_tier_info']['name'] ?></span>
|
|
<span style="font-weight: 600;"><?= number_format($loyaltyStatus['points_to_next']) ?> points to go</span>
|
|
</div>
|
|
<div class="progress-bar-wrapper">
|
|
<div class="progress-bar-fill" style="width: <?= $loyaltyStatus['progress_percent'] ?>%;"></div>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="progress-to-next" style="text-align: center;">
|
|
<i class="fas fa-crown" style="font-size: 2rem; color: <?= $loyaltyStatus['info']['color'] ?>; margin-bottom: 0.5rem;"></i>
|
|
<p style="margin: 0; font-weight: 600;">You've reached the highest tier!</p>
|
|
<p class="text-muted" style="margin: 0.25rem 0 0;">Enjoy all the exclusive benefits of <?= $loyaltyStatus['info']['name'] ?></p>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- All Tiers -->
|
|
<div class="section-card">
|
|
<div class="section-card-header">
|
|
<h3><i class="fas fa-layer-group"></i> Loyalty Tiers</h3>
|
|
</div>
|
|
<div class="section-card-body">
|
|
<div class="tier-grid">
|
|
<?php foreach ($tiers as $key => $tier): ?>
|
|
<div class="tier-item <?= $key === $loyaltyStatus['tier'] ? 'current' : '' ?>">
|
|
<div class="tier-item-icon" style="background: <?= $tier['color'] ?>22; color: <?= $tier['color'] ?>;">
|
|
<i class="fas <?= $tier['icon'] ?>"></i>
|
|
</div>
|
|
<h4><?= $tier['name'] ?></h4>
|
|
<div class="points"><?= number_format($tier['min_points']) ?>+ pts</div>
|
|
<div style="margin-top: 0.5rem; font-weight: 600;"><?= $tier['multiplier'] ?>x points</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<details style="margin-top: 1rem;">
|
|
<summary style="cursor: pointer; font-weight: 600; color: var(--color-primary);">View All Benefits</summary>
|
|
<div style="margin-top: 1rem;">
|
|
<?php foreach ($tiers as $key => $tier): ?>
|
|
<div style="margin-bottom: 1rem; padding: 1rem; background: var(--color-background); border-radius: var(--radius-md);">
|
|
<h4 style="margin: 0 0 0.5rem; display: flex; align-items: center; gap: 0.5rem;">
|
|
<i class="fas <?= $tier['icon'] ?>" style="color: <?= $tier['color'] ?>;"></i>
|
|
<?= $tier['name'] ?>
|
|
</h4>
|
|
<ul style="margin: 0; padding-left: 1.5rem; color: var(--color-text-muted);">
|
|
<?php foreach ($tier['benefits'] as $benefit): ?>
|
|
<li><?= htmlspecialchars($benefit) ?></li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Redeem Points -->
|
|
<div class="redeem-card">
|
|
<h3 style="margin: 0 0 0.5rem;"><i class="fas fa-gift"></i> Redeem Points</h3>
|
|
<p class="text-muted" style="margin: 0 0 1rem;">Convert your points to wallet credit. <?= $conversion['points_for_one_dollar'] ?> points = $1</p>
|
|
|
|
<?php if ($loyaltyStatus['points'] >= 100): ?>
|
|
<form method="POST">
|
|
<div class="redeem-options">
|
|
<?php
|
|
$redeemOptions = [100, 500, 1000];
|
|
foreach ($redeemOptions as $pts):
|
|
if ($pts <= $loyaltyStatus['points']):
|
|
?>
|
|
<label class="redeem-option">
|
|
<input type="radio" name="points" value="<?= $pts ?>" style="display: none;">
|
|
<div class="points"><?= number_format($pts) ?></div>
|
|
<div>points</div>
|
|
<div class="value" style="margin-top: 0.5rem;"><?= formatCurrency($pts * $conversion['points_value']) ?> credit</div>
|
|
</label>
|
|
<?php
|
|
endif;
|
|
endforeach;
|
|
?>
|
|
</div>
|
|
|
|
<div style="margin-top: 1rem; display: flex; gap: 1rem; align-items: center;">
|
|
<div class="form-group" style="margin: 0; flex: 1;">
|
|
<input type="number" name="custom_points" class="form-input" placeholder="Or enter custom amount" min="100" max="<?= $loyaltyStatus['points'] ?>" step="50">
|
|
</div>
|
|
<button type="submit" name="redeem_points" class="btn btn-primary">
|
|
<i class="fas fa-exchange-alt"></i> Redeem
|
|
</button>
|
|
</div>
|
|
</form>
|
|
<?php else: ?>
|
|
<p class="text-muted" style="text-align: center; padding: 2rem;">
|
|
You need at least 100 points to redeem. Keep shopping to earn more!
|
|
</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- Points History -->
|
|
<div class="section-card">
|
|
<div class="section-card-header">
|
|
<h3><i class="fas fa-history"></i> Points History</h3>
|
|
</div>
|
|
<div class="section-card-body" style="padding: 0;">
|
|
<?php if (empty($history)): ?>
|
|
<p class="text-muted text-center" style="padding: 2rem;">No points activity yet</p>
|
|
<?php else: ?>
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Activity</th>
|
|
<th style="text-align: right;">Points</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($history as $tx): ?>
|
|
<tr>
|
|
<td><?= formatDate($tx['created_at']) ?></td>
|
|
<td>
|
|
<?php
|
|
$icon = match($tx['type']) {
|
|
'earn' => 'fa-plus-circle',
|
|
'redeem' => 'fa-gift',
|
|
'tier_upgrade' => 'fa-arrow-up',
|
|
'birthday_bonus' => 'fa-birthday-cake',
|
|
'referral_bonus', 'referral_welcome' => 'fa-user-plus',
|
|
default => 'fa-circle'
|
|
};
|
|
?>
|
|
<i class="fas <?= $icon ?>" style="color: <?= $tx['points'] > 0 ? 'var(--color-success)' : 'var(--color-primary)' ?>;"></i>
|
|
<?= htmlspecialchars($tx['description'] ?? ucfirst(str_replace('_', ' ', $tx['type']))) ?>
|
|
</td>
|
|
<td style="text-align: right; font-weight: 600; color: <?= $tx['points'] > 0 ? 'var(--color-success)' : 'var(--color-text)' ?>;">
|
|
<?= $tx['points'] > 0 ? '+' : '' ?><?= number_format($tx['points']) ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Handle redeem option selection
|
|
document.querySelectorAll('.redeem-option').forEach(opt => {
|
|
opt.addEventListener('click', function() {
|
|
document.querySelectorAll('.redeem-option').forEach(o => o.classList.remove('selected'));
|
|
this.classList.add('selected');
|
|
this.querySelector('input[type="radio"]').checked = true;
|
|
document.querySelector('input[name="custom_points"]').value = '';
|
|
});
|
|
});
|
|
|
|
// Custom points input clears radio selection
|
|
document.querySelector('input[name="custom_points"]')?.addEventListener('input', function() {
|
|
if (this.value) {
|
|
document.querySelectorAll('.redeem-option').forEach(o => {
|
|
o.classList.remove('selected');
|
|
o.querySelector('input[type="radio"]').checked = false;
|
|
});
|
|
}
|
|
});
|
|
|
|
// Form submission - use custom or selected
|
|
document.querySelector('form')?.addEventListener('submit', function(e) {
|
|
const customPoints = document.querySelector('input[name="custom_points"]').value;
|
|
const selectedRadio = document.querySelector('input[name="points"]:checked');
|
|
|
|
if (!customPoints && !selectedRadio) {
|
|
e.preventDefault();
|
|
alert('Please select or enter the number of points to redeem');
|
|
return;
|
|
}
|
|
|
|
if (customPoints) {
|
|
// Create hidden input with custom points as 'points'
|
|
const hidden = document.createElement('input');
|
|
hidden.type = 'hidden';
|
|
hidden.name = 'points';
|
|
hidden.value = customPoints;
|
|
this.appendChild(hidden);
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|