File size: 6,235 Bytes
244fdfb
1723ad3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244fdfb
1723ad3
 
 
 
 
 
244fdfb
1723ad3
 
 
 
 
 
 
 
 
244fdfb
1723ad3
 
 
 
 
 
 
244fdfb
1723ad3
 
 
 
 
 
 
 
 
 
 
 
25f925e
 
1723ad3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25f925e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
@model Frontend.Models.RewardsViewModel
@{
    ViewData["Title"] = "Loyalty Rewards";
}

<div class="mb-10">
    <div class="flex flex-col md:flex-row md:items-center justify-between gap-6">
        <div>
            <h1 class="text-3xl font-extrabold tracking-tight text-slate-900 border-b border-slate-100 pb-4 mb-2">Loyalty Rewards</h1>
            <p class="text-slate-500 font-medium">Redeem your hard-earned points for exclusive library benefits.</p>
        </div>
        <div class="flex items-center gap-4 bg-amber-50 border border-amber-100 px-6 py-4 rounded-2xl shadow-sm">
            <div class="p-2 bg-amber-100 rounded-lg text-amber-600">
                <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7"></path></svg>
            </div>
            <div>
                <p class="text-[10px] font-bold text-amber-600 uppercase tracking-widest mb-0.5">Your Balance</p>
                <p class="text-2xl font-black text-slate-900">@(Model.Account?.CurrentBalance.ToString("N0") ?? "0") Points</p>
            </div>
        </div>
    </div>
</div>

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
    @if (!Model.Rewards.Any())
    {
        <div class="col-span-full py-20 text-center bg-slate-50 rounded-3xl border-2 border-dashed border-slate-200">
            <div class="text-slate-400 mb-4">
                <svg class="w-16 h-16 mx-auto opacity-20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"></path></svg>
            </div>
            <p class="text-slate-500 font-medium italic">No active rewards available at the moment. Check back soon!</p>
        </div>
    }

    @foreach (var reward in Model.Rewards)
    {
        <div class="group relative card p-6 hover:shadow-2xl hover:-translate-y-1 transition-all duration-300 border-t-4 border-amber-400">
            <div class="flex justify-between items-start mb-6">
                <div class="p-3 bg-amber-50 rounded-xl text-amber-600 group-hover:bg-amber-400 group-hover:text-white transition-colors">
                    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z"></path></svg>
                </div>
                <div class="text-right">
                    <span class="text-3xl font-black text-slate-900">@reward.PointCost.ToString("N0")</span>
                    <span class="text-[10px] block font-bold text-slate-400 uppercase tracking-tighter">Points Required</span>
                </div>
            </div>

            <h3 class="text-lg font-bold text-slate-900 mb-2 truncate">@reward.Name</h3>
            <p class="text-sm text-slate-500 leading-relaxed mb-6 h-12 overflow-hidden line-clamp-2">@reward.Description</p>

            <div class="flex items-center justify-between pt-6 border-t border-slate-50">
                <div class="flex flex-col">
                    <span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">Stock</span>
                    <span class="text-sm font-bold text-slate-700">@reward.StockQuantity available</span>
                </div>
                <button onclick="redeemReward('@reward.Id', '@reward.Name', @reward.PointCost)" 
                        class="bg-slate-900 text-white px-5 py-2.5 rounded-xl text-xs font-bold hover:bg-slate-800 hover:shadow-lg transition-all active:scale-95">
                    Redeem Reward
                </button>
            </div>

            @if (reward.StockQuantity < 10)
            {
                <div class="absolute top-2 right-2 flex">
                    <span class="animate-pulse bg-rose-500 text-white text-[8px] font-black px-1.5 py-0.5 rounded uppercase">Limited</span>
                </div>
            }
        </div>
    }
</div>

<div class="mt-12 p-8 bg-slate-900 rounded-3xl text-white relative overflow-hidden">
    <div class="relative z-10 flex flex-col md:flex-row items-center justify-between gap-8">
        <div class="text-center md:text-left">
            <h2 class="text-2xl font-bold mb-2">How to earn more points?</h2>
            <p class="text-slate-400 max-w-md">Borrow books, subscribe to memberships, and return books on time to stack up your points and unlock even bigger rewards!</p>
        </div>
        <a asp-controller="Books" asp-action="Index" class="bg-amber-400 text-slate-900 px-8 py-4 rounded-2xl font-black hover:bg-amber-300 transition-all shadow-xl shadow-amber-400/20 whitespace-nowrap">
            Browse Books Now
        </a>
    </div>
    <!-- Decorative background element -->
    <div class="absolute -right-10 -bottom-10 w-64 h-64 bg-amber-400/10 rounded-full blur-3xl"></div>
    <div class="absolute -left-10 -top-10 w-48 h-48 bg-blue-400/5 rounded-full blur-3xl"></div>
</div>

<script>
    async function redeemReward(rewardId, rewardName, cost) {
        if (!confirm(`Are you sure you want to redeem ${rewardName} for ${cost.toLocaleString()} points?`)) {
            return;
        }

        try {
            const response = await fetch('/Borrowings/Redeem', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: new URLSearchParams({ rewardId: rewardId })
            });

            const result = await response.json();
            
            if (result.success) {
                alert(result.message);
                window.location.reload();
            } else {
                alert('Error: ' + result.message);
            }
        } catch (error) {
            console.error('Redemption error:', error);
            alert('An unexpected error occurred. Please try again.');
        }
    }
</script>