File size: 7,495 Bytes
6f32ae8
 
 
 
 
d8a7fc4
6f32ae8
 
 
 
 
 
 
 
 
 
d3d3b46
6f32ae8
d3d3b46
6f32ae8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d3d3b46
6f32ae8
d3d3b46
6f32ae8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d8a7fc4
 
6f32ae8
 
 
 
 
 
d8a7fc4
6f32ae8
 
 
d8a7fc4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6f32ae8
 
 
 
 
d8a7fc4
6f32ae8
 
 
d8a7fc4
6f32ae8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d8a7fc4
6f32ae8
d8a7fc4
 
 
 
 
 
 
 
 
 
 
 
 
6f32ae8
 
 
 
 
 
 
 
 
 
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
@page "/borrowings"
@using LibraryManagement.Shared.Models
@using BlazorWebAssembly.Services
@inject LibraryApiClient ApiClient
@inject NavigationManager Navigation
@inject IJSRuntime JS

<div class="max-w-6xl mx-auto py-12 px-6">
    <!-- Header -->
    <div class="flex justify-between items-end mb-16">
        <div>
            <h1 class="text-5xl font-black tracking-tight text-main mb-4">My Loans</h1>
            <p class="text-lg text-muted max-w-xl">
                Keep track of your reading journey and manage your active borrowings.
            </p>
        </div>
        <a href="/books" class="hidden md:block bg-body text-main border border-border px-8 py-3 rounded-xl font-bold hover:bg-card transition-all text-center">
            Browse More
        </a>
    </div>

    @if (_isLoading)
    {
        <div class="space-y-6">
            @for (int i = 0; i < 3; i++)
            {
                <div class="animate-pulse bg-card rounded-2xl border border-border h-32 w-full"></div>
            }
        </div>
    }
    else if (!_borrowings.Any())
    {
        <div class="text-center py-24 bg-card rounded-[2.5rem] border border-dashed border-border shadow-sm">
            <h3 class="text-2xl font-bold text-main mb-3">No active loans</h3>
            <p class="text-muted mb-8">You haven't borrowed any books yet. Explore our collection to get started.</p>
            <a href="/books" class="bg-primary text-white px-10 py-4 rounded-xl font-black hover:bg-primary-hover transition-all shadow-lg shadow-primary/20 inline-block text-center">
                Go to Catalog
            </a>
        </div>
    }
    else
    {
        <div class="space-y-6">
            @foreach (var loan in _borrowings)
            {
                <div class="bg-card rounded-2xl border border-border p-6 flex flex-col md:flex-row items-center gap-8 hover:border-primary/50 transition-all group">
                    <!-- Book Cover / Placeholder -->
                    <div class="w-20 h-28 bg-body rounded-lg overflow-hidden flex-shrink-0 border border-border flex items-center justify-center">
                        <svg class="w-8 h-8 text-muted opacity-20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18 18.246 18.477 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path></svg>
                    </div>

                    <!-- Details -->
                    <div class="flex-grow text-center md:text-left">
                        <h3 class="text-xl font-bold text-main mb-1 group-hover:text-primary transition-colors">@loan.BookTitle</h3>
                        <p class="text-sm text-muted font-medium mb-4 md:mb-0">ID: @loan.BookId</p>
                    </div>

                    <!-- Dates & Fines -->
                    <div class="grid grid-cols-2 md:grid-cols-3 gap-8 px-8 border-x border-border hidden lg:grid flex-grow">
                        <div>
                            <p class="text-[10px] font-black text-muted uppercase tracking-[0.2em] mb-1">Borrowed</p>
                            <p class="text-sm font-bold text-main">@loan.BorrowDate.ToString("MMM dd, yyyy")</p>
                        </div>
                        <div>
                            <p class="text-[10px] font-black text-muted uppercase tracking-[0.2em] mb-1">Due Date</p>
                            <p class="text-sm font-bold @(loan.DueDate < DateTime.UtcNow && loan.Status == "Borrowed" ? "text-red-500" : "text-main")">
                                @loan.DueDate.ToString("MMM dd, yyyy")
                            </p>
                        </div>
                        <div class="hidden md:block">
                            @if (loan.ReturnDate.HasValue)
                            {
                                <p class="text-[10px] font-black text-muted uppercase tracking-[0.2em] mb-1">Returned</p>
                                <p class="text-sm font-bold text-green-500">@loan.ReturnDate.Value.ToString("MMM dd, yyyy")</p>
                            }
                            else if (loan.FineAmount > 0)
                            {
                                <p class="text-[10px] font-black text-muted uppercase tracking-[0.2em] mb-1">Fine</p>
                                <p class="text-sm font-bold @(loan.IsFinePaid ? "text-muted line-through" : "text-red-500")">
                                    MMK @loan.FineAmount.ToString("N0")
                                </p>
                                @if (loan.IsFinePaid)
                                {
                                    <span class="text-[10px] text-green-500 font-black uppercase">Paid</span>
                                }
                            }
                            else
                            {
                                <p class="text-[10px] font-black text-muted uppercase tracking-[0.2em] mb-1">Fine</p>
                                <p class="text-sm font-bold text-muted">No Fines</p>
                            }
                        </div>
                    </div>

                    <!-- Status & Action -->
                    <div class="flex flex-col md:items-end gap-3 min-w-[150px]">
                        <span class='px-4 py-1.5 rounded-full text-[10px] font-black uppercase tracking-widest text-center @GetStatusColor(loan.Status)'>
                            @(loan.Status == "PendingReturn" ? "Pending" : loan.Status)
                        </span>
                        @if (loan.Status == "Borrowed")
                        {
                            <button @onclick="() => ReturnRequestAsync(loan)" class="text-xs font-bold text-primary hover:underline">
                                Request Return
                            </button>
                        }
                    </div>
                </div>
            }
        </div>
    }
</div>

@code {
    private bool _isLoading = true;
    private List<BorrowingDto> _borrowings = new();

    protected override async Task OnInitializedAsync()
    {
        await LoadData();
    }

    private async Task LoadData()
    {
        _isLoading = true;
        try
        {
            _borrowings = (await ApiClient.GetMyBorrowingsAsync()).ToList();
        }
        catch { }
        finally { _isLoading = false; }
    }

    private async Task ReturnRequestAsync(BorrowingDto loan)
    {
        bool confirmed = await JS.InvokeAsync<bool>("confirm", $"Request return for \"{loan.BookTitle}\"? It will be marked as pending until approved by a librarian.");
        if (!confirmed) return;

        var success = await ApiClient.RequestReturnAsync(loan.Id);
        if (success) 
        {
            await JS.InvokeVoidAsync("alert", "Return request submitted successfully!");
            await LoadData();
        }
        else
        {
            await JS.InvokeVoidAsync("alert", "Failed to submit return request.");
        }
    }

    private string GetStatusColor(string status) => status switch
    {
        "Borrowed" => "bg-blue-500/10 text-blue-500",
        "Returned" => "bg-green-500/10 text-green-500",
        "PendingReturn" => "bg-orange-500/10 text-orange-500",
        _ => "bg-body text-muted"
    };
}