File size: 9,735 Bytes
6f32ae8
b0a0ed0
 
 
 
 
 
 
36144b0
 
 
 
b0a0ed0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36144b0
b0a0ed0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36144b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b0a0ed0
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
159
160
161
162
163
164
165
166
167
168
169
170
@model Frontend.Models.PagedResult<LibraryManagement.Shared.Models.UserDto>
@{
    ViewData["Title"] = "Members Directory";
}

<div class="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-8">
    <div>
        <h1 class="text-3xl font-bold tracking-tight text-slate-900">Members Directory</h1>
        <p class="mt-2 text-slate-500">
            Manage library members and administrator accounts.
            <span class="ml-2 text-xs text-slate-400">(@Model.TotalCount total)</span>
        </p>
    </div>
    <div class="flex items-center gap-3">
        <a asp-action="Create" class="btn-primary">
            <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg>
            Add New Member
        </a>
    </div>
</div>

<div class="card overflow-hidden">
    <div class="overflow-x-auto">
        <table class="min-w-full divide-y divide-slate-200">
            <thead class="bg-slate-50">
                <tr>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-semibold text-slate-500 uppercase tracking-wider">Member</th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-semibold text-slate-500 uppercase tracking-wider">Contact</th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-semibold text-slate-500 uppercase tracking-wider">Role</th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-semibold text-slate-500 uppercase tracking-wider">Status</th>
                    <th scope="col" class="relative px-6 py-3"><span class="sr-only">Actions</span></th>
                </tr>
            </thead>
            <tbody class="bg-white divide-y divide-slate-200">
                @foreach (var user in Model.Items)
                {
                    <tr class="hover:bg-slate-50 transition-colors">
                        <td class="px-6 py-4 whitespace-nowrap">
                            <div class="flex items-center">
                                <div class="h-10 w-10 flex-shrink-0 rounded-full bg-slate-900 flex items-center justify-center text-white font-bold text-sm">
                                    @(user.FullName?.Substring(0, 2).ToUpper() ?? "U")
                                </div>
                                <div class="ml-4">
                                    <div class="text-sm font-medium text-slate-900">
                                        <a asp-action="Details" asp-route-id="@user.Id" class="hover:underline">@user.FullName</a>
                                    </div>
                                    @if (!string.IsNullOrEmpty(user.StudentId))
                                    {
                                        <div class="text-xs text-slate-500 text-slate-500">ID: @user.StudentId</div>
                                    }
                                </div>
                            </div>
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap">
                            <div class="text-sm text-slate-900">@user.Email</div>
                            <div class="text-xs text-slate-500">@(string.IsNullOrEmpty(user.PhoneNumber) ? "No phone" : user.PhoneNumber)</div>
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap">
                            <span class="inline-flex rounded-full px-2 text-xs font-semibold leading-5 @(user.Role == "Admin" ? "bg-amber-100 text-amber-800" : "bg-blue-100 text-blue-800")">
                                @user.Role
                            </span>
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap">
                            @if (user.BanStatus == true)
                            {
                                <span class="inline-flex rounded-full bg-rose-100 px-2 text-xs font-semibold leading-5 text-rose-800">
                                    Suspended
                                </span>
                            }
                            else if (user.IsActive)
                            {
                                <span class="inline-flex rounded-full bg-emerald-100 px-2 text-xs font-semibold leading-5 text-emerald-800">
                                    Active
                                </span>
                            }
                            else
                            {
                                <span class="inline-flex rounded-full bg-slate-100 px-2 text-xs font-semibold leading-5 text-slate-800">
                                    Inactive
                                </span>
                            }
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
                            <div class="flex items-center justify-end gap-3">
                                <a asp-action="Details" asp-route-id="@user.Id" class="text-slate-600 hover:text-slate-900 transition-colors">Details</a>
                                <a asp-action="Edit" asp-route-id="@user.Id" class="text-indigo-600 hover:text-indigo-900 transition-colors">Edit</a>
                            </div>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>

    @* Pagination *@
    @if (Model.TotalPages > 1)
    {
        <div class="px-6 py-4 border-t border-slate-200 flex items-center justify-between bg-white">
            <p class="text-sm text-slate-500">
                Showing <span class="font-medium text-slate-700">@((Model.CurrentPage - 1) * Model.PageSize + 1)</span>

                <span class="font-medium text-slate-700">@(Math.Min(Model.CurrentPage * Model.PageSize, Model.TotalCount))</span>
                of <span class="font-medium text-slate-700">@Model.TotalCount</span> members
            </p>
            <nav class="flex items-center gap-1" aria-label="Pagination">
                @* Previous *@
                @if (Model.HasPreviousPage)
                {
                    <a asp-action="Index" asp-route-page="@(Model.CurrentPage - 1)"
                       class="inline-flex items-center px-3 py-1.5 rounded-md border border-slate-200 text-sm font-medium text-slate-600 hover:bg-slate-50 hover:text-slate-900 transition-colors">
                        <svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
                        </svg>
                        Prev
                    </a>
                }
                else
                {
                    <span class="inline-flex items-center px-3 py-1.5 rounded-md border border-slate-100 text-sm font-medium text-slate-300 cursor-not-allowed select-none">
                        <svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
                        </svg>
                        Prev
                    </span>
                }

                @* Page numbers *@
                @for (int p = 1; p <= Model.TotalPages; p++)
                {
                    if (p == Model.CurrentPage)
                    {
                        <span class="inline-flex items-center justify-center w-8 h-8 rounded-md bg-slate-900 text-white text-sm font-semibold">@p</span>
                    }
                    else if (p == 1 || p == Model.TotalPages || (p >= Model.CurrentPage - 2 && p <= Model.CurrentPage + 2))
                    {
                        <a asp-action="Index" asp-route-page="@p"
                           class="inline-flex items-center justify-center w-8 h-8 rounded-md border border-slate-200 text-sm font-medium text-slate-600 hover:bg-slate-50 hover:text-slate-900 transition-colors">@p</a>
                    }
                    else if (p == Model.CurrentPage - 3 || p == Model.CurrentPage + 3)
                    {
                        <span class="inline-flex items-center justify-center w-8 h-8 text-sm text-slate-400"></span>
                    }
                }

                @* Next *@
                @if (Model.HasNextPage)
                {
                    <a asp-action="Index" asp-route-page="@(Model.CurrentPage + 1)"
                       class="inline-flex items-center px-3 py-1.5 rounded-md border border-slate-200 text-sm font-medium text-slate-600 hover:bg-slate-50 hover:text-slate-900 transition-colors">
                        Next
                        <svg class="w-4 h-4 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
                        </svg>
                    </a>
                }
                else
                {
                    <span class="inline-flex items-center px-3 py-1.5 rounded-md border border-slate-100 text-sm font-medium text-slate-300 cursor-not-allowed select-none">
                        Next
                        <svg class="w-4 h-4 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
                        </svg>
                    </span>
                }
            </nav>
        </div>
    }
</div>