File size: 4,515 Bytes
01be06d
 
 
 
 
f6d34ff
01be06d
8c88a89
01be06d
f6d34ff
 
01be06d
 
f6d34ff
be17a46
f6d34ff
01be06d
8c88a89
01be06d
8c88a89
01be06d
 
 
f6d34ff
01be06d
 
f6d34ff
01be06d
8c88a89
 
01be06d
 
 
8c88a89
 
01be06d
 
 
8c88a89
 
01be06d
 
 
 
 
 
 
 
 
 
 
 
8c88a89
f6d34ff
8c88a89
01be06d
 
 
 
 
 
 
 
 
 
 
8c88a89
f6d34ff
 
 
 
 
01be06d
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
@page "/reset-password"
@layout Layout.EmptyLayout
@rendermode @(new InteractiveServerRenderMode(prerender: false))
@attribute [Microsoft.AspNetCore.Authorization.AllowAnonymous]
@inject NavigationManager Navigation
@inject IJSRuntime JS

<PageTitle>@AppLocalization.Text("auth.resetPassword", "Reset Password") - Taskify</PageTitle>

<div class="flex min-h-screen items-center justify-center bg-slate-50 px-4 py-10 sm:px-6 lg:px-8">
    <div class="w-full max-w-md space-y-7 rounded-xl border border-slate-200 bg-white p-8 shadow-sm">
        <div>
            <div class="flex justify-center">
                <span class="flex h-12 w-12 items-center justify-center rounded-xl bg-violet-600 text-white shadow-sm">
                    <i data-lucide="clipboard-check" class="h-6 w-6"></i>
                </span>
            </div>
            <h2 class="mt-5 text-center text-2xl font-bold text-slate-900">@AppLocalization.Text("auth.resetPassword", "Reset your password")</h2>
            <p class="mt-2 text-center text-sm text-slate-600">
                @AppLocalization.Text("auth.resetPasswordHelp", "Use the recovery code configured in the API to set a new password.")
            </p>
        </div>

        <form method="post" action="/account/reset-password" class="space-y-5">
            <AntiforgeryToken />

            <div class="space-y-4">
                <div>
                    <label for="usernameOrEmail" class="block text-sm font-medium text-slate-700 mb-1">@AppLocalization.Text("auth.usernameOrEmail", "Username or Email")</label>
                    <input id="usernameOrEmail" name="UsernameOrEmail" required placeholder="@AppLocalization.Text("auth.enterUsernameOrEmail", "Enter username or email")"
                           class="w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-slate-900 focus:border-transparent transition-all" />
                </div>
                <div>
                    <label for="recoveryCode" class="block text-sm font-medium text-slate-700 mb-1">@AppLocalization.Text("auth.recoveryCode", "Recovery Code")</label>
                    <input id="recoveryCode" name="RecoveryCode" required placeholder="@AppLocalization.Text("auth.enterRecoveryCode", "Enter recovery code")"
                           class="w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-slate-900 focus:border-transparent transition-all" />
                </div>
                <div>
                    <label for="newPassword" class="block text-sm font-medium text-slate-700 mb-1">@AppLocalization.Text("auth.newPassword", "New Password")</label>
                    <input id="newPassword" name="NewPassword" type="password" required placeholder="@AppLocalization.Text("validation.passwordMinLengthRule", "Min 8 characters")"
                           class="w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-slate-900 focus:border-transparent transition-all" />
                </div>
            </div>

            @if (ShowError)
            {
                <div class="p-3 rounded-lg bg-red-50 border border-red-100">
                    <p class="text-sm text-red-600 text-center">@ErrorMessage</p>
                </div>
            }

            <div class="flex items-center justify-between">
                <a href="/login" class="text-sm font-medium text-violet-600 hover:underline">@AppLocalization.Text("common.backToDashboard", "Back to sign in")</a>
                <button type="submit" class="group relative flex justify-center rounded-lg bg-violet-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-violet-700">
                    @AppLocalization.Text("auth.resetPassword", "Reset Password")
                </button>
            </div>
        </form>
    </div>
</div>

@code {
    [SupplyParameterFromQuery(Name = "error")]
    private string? Error { get; set; }

    private bool ShowError => !string.IsNullOrWhiteSpace(Error);
    private string ErrorMessage => string.IsNullOrWhiteSpace(Error) ? AppLocalization.Text("auth.unableToResetPassword", "Unable to reset password.") : Error;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await JS.InvokeVoidAsync("initIcons");
    }
}