File size: 14,309 Bytes
6f32ae8
 
 
 
 
d8a7fc4
 
6f32ae8
d3d3b46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6f32ae8
 
d3d3b46
6f32ae8
 
 
 
 
 
d3d3b46
6f32ae8
d3d3b46
4433399
d3d3b46
 
 
 
 
 
 
 
 
6f32ae8
 
 
 
 
d3d3b46
 
 
d8a7fc4
d3d3b46
 
 
6f32ae8
d3d3b46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d8a7fc4
 
d3d3b46
 
 
 
 
 
 
 
 
 
 
 
 
 
6f32ae8
d3d3b46
d8a7fc4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d3d3b46
 
d8a7fc4
 
 
 
 
 
d3d3b46
 
 
d8a7fc4
d3d3b46
 
 
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
@inherits LayoutComponentBase
@using BlazorWebAssembly.Services
@using Microsoft.AspNetCore.Components.Authorization
@inject ThemeService ThemeService
@inject AuthenticationStateProvider AuthStateProvider
@inject IJSRuntime JS
@inject LibraryApiClient ApiClient

<AuthorizeView>
    <Authorized>
        <div class="flex h-screen overflow-hidden bg-body text-main animate-fade font-sans">
            <!-- Sidebar (Dashboard View) -->
            <aside class="hidden lg:flex lg:w-64 lg:flex-col lg:fixed lg:inset-y-0 z-50 border-r border-border bg-card">
                <div class="flex flex-col flex-grow pt-8 pb-4 overflow-y-auto">
                    <div class="flex items-center flex-shrink-0 px-6 gap-3 mb-10">
                        <div class="bg-primary rounded-xl p-2 text-white shadow-lg shadow-primary/20">
                            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m16 6 4 14"/><path d="M12 6v14"/><path d="M8 8v12"/><path d="M4 4v16"/><path d="M4 12V4l4 4"/><path d="m12 6 4 4"/></svg>
                        </div>
                        <span class="text-xl font-black tracking-tighter uppercase">LibraryLuxe</span>
                    </div>
                    <div class="flex-grow px-3">
                        <NavMenu />
                    </div>
                    <div class="px-6 py-6 border-t border-border">
                        <div class="mb-6">
                            <p class="text-[10px] font-black text-muted uppercase tracking-[0.2em] mb-4 text-center">Switch Theme</p>
                            <ThemeSwitcher />
                        </div>
                        <div class="flex items-center gap-3 p-3 bg-body rounded-2xl border border-border">
                            <div class="h-10 w-10 rounded-xl bg-primary flex items-center justify-center text-white font-bold shadow-sm">
                                @(context.User.Identity?.Name?.Length > 0 ? context.User.Identity.Name[..1].ToUpper() : "?")
                            </div>
                            <div class="flex flex-col min-w-0">
                                <span class="text-xs font-bold truncate">@context.User.Identity?.Name</span>
                                <span class="text-[10px] text-muted font-medium uppercase tracking-wider">Member</span>
                            </div>
                        </div>
                    </div>
                </div>
            </aside>

            <div class="lg:pl-64 flex flex-col flex-1 w-0">
                <header class="h-20 bg-card/80 backdrop-blur-md border-b border-border sticky top-0 z-40 flex items-center justify-between px-8">
                    <div class="flex-grow max-w-lg">
                        <div class="relative">
                            <svg class="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-muted" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
                            <input type="text" placeholder="Quick search..." class="w-full bg-body border border-border rounded-xl pl-12 pr-4 py-2.5 text-sm focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all shadow-sm" />
                        </div>
                    </div>
                    <div class="flex items-center gap-6">
                        <button class="relative text-muted hover:text-primary 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="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"></path></svg>
                            <span class="absolute top-0 right-0 w-2 h-2 bg-primary rounded-full border-2 border-card"></span>
                        </button>
                        <a href="/logout" class="text-xs font-black uppercase tracking-widest text-muted hover:text-red-500 transition-colors">Logout</a>
                    </div>
                </header>
                <main class="flex-1 overflow-y-auto p-8 scrollbar-hide">
                    <div class="max-w-7xl mx-auto w-full">
                        @Body
                    </div>
                </main>
            </div>
        </div>
    </Authorized>
    <NotAuthorized>
        <div class="min-h-screen bg-body text-main animate-fade font-sans flex flex-col">
            <!-- Top Navbar (Guest View) -->
            <nav class="h-20 bg-card/80 backdrop-blur-md border-b border-border sticky top-0 z-50 px-8 flex items-center justify-between shadow-sm">
                <div class="flex items-center gap-10">
                    <a href="/" class="flex items-center gap-3 group">
                        <div class="bg-primary rounded-xl p-2 text-white shadow-lg shadow-primary/20 group-hover:scale-110 transition-transform">
                            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m16 6 4 14"/><path d="M12 6v14"/><path d="M8 8v12"/><path d="M4 4v16"/><path d="M4 12V4l4 4"/><path d="m12 6 4 4"/></svg>
                        </div>
                        <span class="text-xl font-black tracking-tighter uppercase">LibraryLuxe</span>
                    </a>
                    <div class="hidden md:flex items-center gap-8">
                        <NavLink href="/" Match="NavLinkMatch.All" class="text-xs font-black uppercase tracking-widest text-muted hover:text-primary transition-colors">Home</NavLink>
                        <NavLink href="/membership" class="text-xs font-black uppercase tracking-widest text-muted hover:text-primary transition-colors">Membership</NavLink>
                        <NavLink href="/features" class="text-xs font-black uppercase tracking-widest text-muted hover:text-primary transition-colors">Features</NavLink>
                        <NavLink href="/about" class="text-xs font-black uppercase tracking-widest text-muted hover:text-primary transition-colors">About Us</NavLink>
                        <NavLink href="/contact" class="text-xs font-black uppercase tracking-widest text-muted hover:text-primary transition-colors">Contact</NavLink>
                    </div>
                </div>
                <div class="flex items-center gap-6">
                    <ThemeSwitcher />
                    <div class="h-6 w-px bg-border hidden sm:block"></div>
                    <div class="flex items-center gap-4">
                        <a href="/login" class="text-xs font-black uppercase tracking-widest text-muted hover:text-primary transition-colors">Sign In</a>
                        <a href="/register" class="bg-primary text-white px-6 py-2.5 rounded-xl text-xs font-black uppercase tracking-widest hover:bg-primary-hover shadow-lg shadow-primary/20 transition-all transform hover:scale-105">Get Started</a>
                    </div>
                </div>
            </nav>
            <main class="flex-grow">
                @Body
            </main>
            <footer class="py-20 border-t border-border bg-card">
                <div class="max-w-7xl mx-auto px-8">
                    <div class="grid grid-cols-1 md:grid-cols-4 gap-12 mb-16">
                        <div class="col-span-1 md:col-span-2">
                            <div class="flex items-center gap-3 mb-6">
                                <div class="bg-primary rounded-xl p-2 text-white">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m16 6 4 14"/><path d="M12 6v14"/><path d="M8 8v12"/><path d="M4 4v16"/><path d="M4 12V4l4 4"/><path d="m12 6 4 4"/></svg>
                                </div>
                                <span class="text-xl font-black tracking-tighter uppercase">LibraryLuxe</span>
                            </div>
                            <p class="text-muted text-sm max-w-sm leading-relaxed mb-8">
                                Redefining the modern library experience with digital-first solutions and community-driven rewards.
                            </p>
                            <div class="flex gap-4">
                                <!-- Social Icons Placeholder -->
                                <div class="w-10 h-10 rounded-xl bg-body border border-border flex items-center justify-center text-muted hover:text-primary transition-colors cursor-pointer">
                                    <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/></svg>
                                </div>
                                <div class="w-10 h-10 rounded-xl bg-body border border-border flex items-center justify-center text-muted hover:text-primary transition-colors cursor-pointer">
                                    <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/></svg>
                                </div>
                            </div>
                        </div>
                        <div>
                            <h4 class="text-xs font-black uppercase tracking-[0.2em] text-main mb-6">Navigation</h4>
                            <ul class="space-y-4">
                                <li><a href="/" class="text-sm text-muted hover:text-primary transition-colors">Home</a></li>
                                <li><a href="/membership" class="text-sm text-muted hover:text-primary transition-colors">Membership</a></li>
                                <li><a href="/features" class="text-sm text-muted hover:text-primary transition-colors">Features</a></li>
                                <li><a href="/faq" class="text-sm text-muted hover:text-primary transition-colors">FAQ</a></li>
                            </ul>
                        </div>
                        <div>
                            <h4 class="text-xs font-black uppercase tracking-[0.2em] text-main mb-6">Legal</h4>
                            <ul class="space-y-4">
                                <li><a href="/privacy" class="text-sm text-muted hover:text-primary transition-colors">Privacy Policy</a></li>
                                <li><a href="/terms" class="text-sm text-muted hover:text-primary transition-colors">Terms of Service</a></li>
                                <li><a href="/contact" class="text-sm text-muted hover:text-primary transition-colors">Contact Support</a></li>
                            </ul>
                        </div>
                    </div>
                    <div class="pt-8 border-t border-border flex flex-col md:row justify-between items-center gap-4">
                        <p class="text-[10px] font-bold text-muted uppercase tracking-[0.2em]">&copy; 2026 LibraryLuxe Ecosystem. Built with passion for readers.</p>
                        <div class="flex items-center gap-2">
                            <div class="w-2 h-2 rounded-full bg-green-500 animate-pulse"></div>
                            <span class="text-[10px] font-black uppercase tracking-widest text-muted">System Operational</span>
                        </div>
                    </div>
                </div>
            </footer>

        </div>
    </NotAuthorized>
</AuthorizeView>

@code {
    protected override async Task OnInitializedAsync()
    {
        await ThemeService.InitializeAsync();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            var authState = await AuthStateProvider.GetAuthenticationStateAsync();
            var user = authState.User;

            if (user.Identity?.IsAuthenticated == true)
            {
                try
                {
                    var token = await JS.InvokeAsync<string>("getFcmToken");
                    if (!string.IsNullOrEmpty(token))
                    {
                        await ApiClient.UpdateFcmTokenAsync(token);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"FCM Token Error: {ex.Message}");
                }
            }
        }
    }
}