💄 Restyled web pages
This commit is contained in:
		| @@ -6,53 +6,44 @@ | ||||
|  | ||||
| @if (Model.Account != null) | ||||
| { | ||||
|     <div class="h-full bg-gray-100 dark:bg-gray-900 py-8 px-4"> | ||||
|     <div class="p-4 sm:p-8 bg-base-200"> | ||||
|         <div class="max-w-6xl mx-auto"> | ||||
|             <!-- Header --> | ||||
|             <div class="mb-8"> | ||||
|                 <h1 class="text-3xl font-bold text-gray-900 dark:text-white">Profile Settings</h1> | ||||
|                 <p class="text-gray-600 dark:text-gray-400 mt-2">Manage your account information and preferences</p> | ||||
|                 <h1 class="text-3xl font-bold">Profile Settings</h1> | ||||
|                 <p class="text-base-content/70 mt-2">Manage your account information and preferences</p> | ||||
|             </div> | ||||
|  | ||||
|             <!-- Two Column Layout --> | ||||
|             <div class="flex flex-col md:flex-row gap-8"> | ||||
|                 <!-- Left Pane - Profile Card --> | ||||
|                 <div class="w-full md:w-1/3 lg:w-1/4"> | ||||
|                     <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 sticky top-8"> | ||||
|                         <div class="flex flex-col items-center text-center"> | ||||
|                     <div class="card bg-base-100 shadow-xl sticky top-8"> | ||||
|                         <div class="card-body items-center text-center"> | ||||
|                             <!-- Avatar --> | ||||
|                             <div | ||||
|                                 class="w-32 h-32 rounded-full bg-gray-200 dark:bg-gray-700 flex items-center justify-center mb-4 overflow-hidden"> | ||||
|                                 <span class="text-4xl text-gray-500 dark:text-gray-400"> | ||||
|                                     @Model.Account.Name?.Substring(0, 1).ToUpper() | ||||
|                                 </span> | ||||
|                             <div class="avatar avatar-placeholder mb-4"> | ||||
|                                 <div class="bg-neutral text-neutral-content rounded-full w-32"> | ||||
|                                     <span class="text-4xl">@Model.Account.Name?[..1].ToUpper()</span> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|  | ||||
|                             <!-- Basic Info --> | ||||
|                             <h2 class="text-xl font-semibold text-gray-900 dark:text-white"> | ||||
|                                 @Model.Account.Nick | ||||
|                             </h2> | ||||
|                             <p class="text-gray-600 dark:text-gray-400">@Model.Account.Name</p> | ||||
|                             <h2 class="card-title">@Model.Account.Nick</h2> | ||||
|                             <p class="font-mono text-sm">@@@Model.Account.Name</p> | ||||
|  | ||||
|                             <!-- Stats --> | ||||
|                             <div | ||||
|                                 class="mt-4 flex justify-around w-full border-t border-gray-200 dark:border-gray-700 pt-4"> | ||||
|                                 <div class="text-center"> | ||||
|                                     <div | ||||
|                                         class="text-lg font-semibold text-gray-900 dark:text-white">@Model.Account.Profile.Level</div> | ||||
|                                     <div class="text-sm text-gray-500 dark:text-gray-400">Level</div> | ||||
|                             <div class="stats stats-vertical shadow mt-4"> | ||||
|                                 <div class="stat"> | ||||
|                                     <div class="stat-title">Level</div> | ||||
|                                     <div class="stat-value">@Model.Account.Profile.Level</div> | ||||
|                                 </div> | ||||
|                                 <div class="text-center"> | ||||
|                                     <div | ||||
|                                         class="text-lg font-semibold text-gray-900 dark:text-white">@Model.Account.Profile.Experience</div> | ||||
|                                     <div class="text-sm text-gray-500 dark:text-gray-400">XP</div> | ||||
|                                 <div class="stat"> | ||||
|                                     <div class="stat-title">XP</div> | ||||
|                                     <div class="stat-value">@Model.Account.Profile.Experience</div> | ||||
|                                 </div> | ||||
|                                 <div class="text-center"> | ||||
|                                     <div | ||||
|                                         class="text-lg font-semibold text-gray-900 dark:text-white"> | ||||
|                                         @Model.Account.CreatedAt.ToDateTimeUtc().ToString("yyyy/MM/dd") | ||||
|                                     </div> | ||||
|                                     <div class="text-sm text-gray-500 dark:text-gray-400">Member since</div> | ||||
|                                 <div class="stat"> | ||||
|                                     <div class="stat-title">Member since</div> | ||||
|                                     <div class="stat-value">@Model.Account.CreatedAt.ToDateTimeUtc().ToString("yyyy/MM")</div> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </div> | ||||
| @@ -61,181 +52,107 @@ | ||||
|  | ||||
|                 <!-- Right Pane - Tabbed Content --> | ||||
|                 <div class="flex-1"> | ||||
|                     <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden"> | ||||
|                         <!-- Tabs --> | ||||
|                         <div class="border-b border-gray-200 dark:border-gray-700"> | ||||
|                             <nav class="flex -mb-px"> | ||||
|                                 <button type="button" | ||||
|                                         class="tab-button active py-4 px-6 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-200" | ||||
|                                         data-tab="profile"> | ||||
|                                     Profile | ||||
|                                 </button> | ||||
|                                 <button type="button" | ||||
|                                         class="tab-button py-4 px-6 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-200" | ||||
|                                         data-tab="security"> | ||||
|                                     Security | ||||
|                                 </button> | ||||
|                                 <button type="button" | ||||
|                                         class="tab-button py-4 px-6 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-200" | ||||
|                                         data-tab="sessions"> | ||||
|                                     Sessions | ||||
|                                 </button> | ||||
|                             </nav> | ||||
|                     <div role="tablist" class="tabs tabs-lift w-full"> | ||||
|                         <input type="radio" name="profile-tabs" role="tab" class="tab" aria-label="Profile" checked /> | ||||
|                         <div role="tabpanel" class="tab-content bg-base-100 border-base-300 p-6"> | ||||
|                             <h2 class="text-xl font-semibold mb-6">Profile Information</h2> | ||||
|  | ||||
|                             <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | ||||
|                                 <div> | ||||
|                                     <h3 class="text-lg font-medium mb-4">Basic Information</h3> | ||||
|                                     <dl class="space-y-4"> | ||||
|                                         <div> | ||||
|                                             <dt class="text-sm font-medium text-base-content/70">Full Name</dt> | ||||
|                                             <dd class="mt-1 text-sm">@($"{Model.Account.Profile.FirstName} {Model.Account.Profile.MiddleName} {Model.Account.Profile.LastName}".Trim())</dd> | ||||
|                                         </div> | ||||
|                                         <div> | ||||
|                                             <dt class="text-sm font-medium text-base-content/70">Username</dt> | ||||
|                                             <dd class="mt-1 text-sm">@Model.Account.Name</dd> | ||||
|                                         </div> | ||||
|                                         <div> | ||||
|                                             <dt class="text-sm font-medium text-base-content/70">Nickname</dt> | ||||
|                                             <dd class="mt-1 text-sm">@Model.Account.Nick</dd> | ||||
|                                         </div> | ||||
|                                         <div> | ||||
|                                             <dt class="text-sm font-medium text-base-content/70">Gender</dt> | ||||
|                                             <dd class="mt-1 text-sm">@Model.Account.Profile.Gender</dd> | ||||
|                                         </div> | ||||
|                                     </dl> | ||||
|                                 </div> | ||||
|  | ||||
|                                 <div> | ||||
|                                     <h3 class="text-lg font-medium mb-4">Additional Details</h3> | ||||
|                                     <dl class="space-y-4"> | ||||
|                                         <div> | ||||
|                                             <dt class="text-sm font-medium text-base-content/70">Location</dt> | ||||
|                                             <dd class="mt-1 text-sm">@Model.Account.Profile.Location</dd> | ||||
|                                         </div> | ||||
|                                         <div> | ||||
|                                             <dt class="text-sm font-medium text-base-content/70">Birthday</dt> | ||||
|                                             <dd class="mt-1 text-sm">@Model.Account.Profile.Birthday?.ToString("MMMM d, yyyy", System.Globalization.CultureInfo.InvariantCulture)</dd> | ||||
|                                         </div> | ||||
|                                         <div> | ||||
|                                             <dt class="text-sm font-medium text-base-content/70">Bio</dt> | ||||
|                                             <dd class="mt-1 text-sm">@(string.IsNullOrEmpty(Model.Account.Profile.Bio) ? "No bio provided" : Model.Account.Profile.Bio)</dd> | ||||
|                                         </div> | ||||
|                                     </dl> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </div> | ||||
|  | ||||
|                         <!-- Tab Content --> | ||||
|                         <div class="p-6"> | ||||
|                             <!-- Profile Tab --> | ||||
|                             <div id="profile-tab" class="tab-content"> | ||||
|                                 <h2 class="text-xl font-semibold text-gray-900 dark:text-white mb-6">Profile | ||||
|                                     Information</h2> | ||||
|                         <input type="radio" name="profile-tabs" role="tab" class="tab" aria-label="Security" /> | ||||
|                         <div role="tabpanel" class="tab-content bg-base-100 border-base-300 p-6"> | ||||
|                             <h2 class="text-xl font-semibold mb-2">Security Settings</h2> | ||||
|  | ||||
|                                 <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | ||||
|                                     <div> | ||||
|                                         <h3 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Basic | ||||
|                                             Information</h3> | ||||
|                                         <dl class="space-y-4"> | ||||
|                                             <div> | ||||
|                                                 <dt class="text-sm font-medium text-gray-500 dark:text-gray-400">Full | ||||
|                                                     Name | ||||
|                                                 </dt> | ||||
|                                                 <dd class="mt-1 text-sm text-gray-900 dark:text-white"> | ||||
|                                                     @($"{Model.Account.Profile.FirstName} {Model.Account.Profile.MiddleName} {Model.Account.Profile.LastName}".Trim()) | ||||
|                                                 </dd> | ||||
|                             <div class="space-y-6"> | ||||
|                                 <div class="card bg-base-300 shadow-xl"> | ||||
|                                     <div class="card-body"> | ||||
|                                         <h3 class="card-title">Access Token</h3> | ||||
|                                         <p>Use this token to authenticate with the API</p> | ||||
|                                         <div class="form-control"> | ||||
|                                             <div class="join"> | ||||
|                                                 <input type="password" id="accessToken" value="@Model.AccessToken" readonly class="input input-bordered join-item flex-grow" /> | ||||
|                                                 <button onclick="copyAccessToken()" class="btn join-item">Copy</button> | ||||
|                                             </div> | ||||
|                                             <div> | ||||
|                                                 <dt class="text-sm font-medium text-gray-500 dark:text-gray-400"> | ||||
|                                                     Username | ||||
|                                                 </dt> | ||||
|                                                 <dd class="mt-1 text-sm text-gray-900 dark:text-white">@Model.Account.Name</dd> | ||||
|                                             </div> | ||||
|                                             <div> | ||||
|                                                 <dt class="text-sm font-medium text-gray-500 dark:text-gray-400"> | ||||
|                                                     Nickname | ||||
|                                                 </dt> | ||||
|                                                 <dd class="mt-1 text-sm text-gray-900 dark:text-white">@Model.Account.Nick</dd> | ||||
|                                             </div> | ||||
|                                             <div> | ||||
|                                                 <dt class="text-sm font-medium text-gray-500 dark:text-gray-400"> | ||||
|                                                     Gender | ||||
|                                                 </dt> | ||||
|                                                 <dd class="mt-1 text-sm text-gray-900 dark:text-white">@Model.Account.Profile.Gender</dd> | ||||
|                                             </div> | ||||
|                                         </dl> | ||||
|                                     </div> | ||||
|  | ||||
|                                     <div> | ||||
|                                         <h3 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Additional | ||||
|                                             Details</h3> | ||||
|                                         <dl class="space-y-4"> | ||||
|                                             <div> | ||||
|                                                 <dt class="text-sm font-medium text-gray-500 dark:text-gray-400"> | ||||
|                                                     Location | ||||
|                                                 </dt> | ||||
|                                                 <dd class="mt-1 text-sm text-gray-900 dark:text-white">@Model.Account.Profile.Location</dd> | ||||
|                                             </div> | ||||
|                                             <div> | ||||
|                                                 <dt class="text-sm font-medium text-gray-500 dark:text-gray-400"> | ||||
|                                                     Birthday | ||||
|                                                 </dt> | ||||
|                                                 <dd class="mt-1 text-sm text-gray-900 dark:text-white"> | ||||
|                                                     @Model.Account.Profile.Birthday?.ToString("MMMM d, yyyy", System.Globalization.CultureInfo.InvariantCulture) | ||||
|                                                 </dd> | ||||
|                                             </div> | ||||
|                                             <div> | ||||
|                                                 <dt class="text-sm font-medium text-gray-500 dark:text-gray-400">Bio | ||||
|                                                 </dt> | ||||
|                                                 <dd class="mt-1 text-sm text-gray-900 dark:text-white"> | ||||
|                                                     @(string.IsNullOrEmpty(Model.Account.Profile.Bio) ? "No bio provided" : Model.Account.Profile.Bio) | ||||
|                                                 </dd> | ||||
|                                             </div> | ||||
|                                         </dl> | ||||
|                                     </div> | ||||
|                                 </div> | ||||
|  | ||||
|                                 <div class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700"> | ||||
|                                     <button type="button" | ||||
|                                             class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> | ||||
|                                         Edit Profile | ||||
|                                     </button> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|  | ||||
|                             <!-- Security Tab --> | ||||
|                             <div id="security-tab" class="tab-content hidden"> | ||||
|                                 <h2 class="text-xl font-semibold text-gray-900 dark:text-white mb-6">Security | ||||
|                                     Settings</h2> | ||||
|  | ||||
|                                 <div class="space-y-6"> | ||||
|                                     <div class="bg-white dark:bg-gray-800 shadow overflow-hidden sm:rounded-lg"> | ||||
|                                         <div class="px-4 py-5 sm:px-6"> | ||||
|                                             <h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-white"> | ||||
|                                                 Access Token</h3> | ||||
|                                             <p class="mt-1 max-w-2xl text-sm text-gray-500 dark:text-gray-400">Use this | ||||
|                                                 token to authenticate with the API</p> | ||||
|                                         </div> | ||||
|                                         <div class="border-t border-gray-200 dark:border-gray-700 px-4 py-5 sm:px-6"> | ||||
|                                             <div class="flex items-center"> | ||||
|                                                 <input type="password" id="accessToken" value="@Model.AccessToken" | ||||
|                                                        readonly | ||||
|                                                        class="form-input flex-grow rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-500 focus:ring-opacity-50 dark:bg-gray-700 dark:border-gray-600 dark:text-white py-2 px-4"/> | ||||
|                                                 <button onclick="copyAccessToken()" | ||||
|                                                         class="ml-4 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"> | ||||
|                                                     Copy | ||||
|                                                 </button> | ||||
|                                             </div> | ||||
|                                             <p class="mt-2 text-sm text-gray-500 dark:text-gray-400"> | ||||
|                                                 Keep this token secure and do not share it with anyone. | ||||
|                                             </p> | ||||
|                                         </div> | ||||
|                                         <p class="text-sm text-base-content/70 mt-2">Keep this token secure and do not share it with anyone.</p> | ||||
|                                     </div> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </div> | ||||
|  | ||||
|                             <!-- Sessions Tab --> | ||||
|                             <div id="sessions-tab" class="tab-content hidden"> | ||||
|                                 <h2 class="text-xl font-semibold text-gray-900 dark:text-white mb-6">Active | ||||
|                                     Sessions</h2> | ||||
|                                 <p class="text-gray-600 dark:text-gray-400 mb-6">This is a list of devices that have | ||||
|                                     logged into your account. Revoke any sessions that you do not recognize.</p> | ||||
|                         <input type="radio" name="profile-tabs" role="tab" class="tab" aria-label="Sessions" /> | ||||
|                         <div role="tabpanel" class="tab-content bg-base-100 border-base-300 p-6"> | ||||
|                             <h2 class="text-xl font-semibold">Active Sessions</h2> | ||||
|                             <p class="text-base-content/70 mb-3">This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize.</p> | ||||
|  | ||||
|                                 <div class="bg-white dark:bg-gray-800 shadow overflow-hidden sm:rounded-lg"> | ||||
|                                     <ul class="divide-y divide-gray-200 dark:divide-gray-700"> | ||||
|                                         <li class="px-4 py-4 sm:px-6"> | ||||
|                                             <div class="flex items-center justify-between"> | ||||
|                                                 <div class="flex items-center"> | ||||
|                                                     <div | ||||
|                                                         class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 dark:bg-blue-900 flex items-center justify-center"> | ||||
|                                                         <svg class="h-6 w-6 text-blue-600 dark:text-blue-400" | ||||
|                                                              fill="currentColor" viewBox="0 0 20 20"> | ||||
|                                                             <path fill-rule="evenodd" | ||||
|                                                                   d="M4 4a2 2 0 012-2h8a2 2 0 012 2v12a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 0v12h8V4H6z" | ||||
|                                                                   clip-rule="evenodd"/> | ||||
|                                                         </svg> | ||||
|                                                     </div> | ||||
|                                                     <div class="ml-4"> | ||||
|                                                         <div class="text-sm font-medium text-gray-900 dark:text-white"> | ||||
|                                                             Current Session | ||||
|                             <div class="card bg-base-300 shadow-xl"> | ||||
|                                 <div class="card-body"> | ||||
|                                     <div class="overflow-x-auto"> | ||||
|                                         <table class="table"> | ||||
|                                             <tbody> | ||||
|                                             <tr> | ||||
|                                                 <td> | ||||
|                                                     <div class="flex items-center gap-3"> | ||||
|                                                         <div class="avatar"> | ||||
|                                                             <div class="mask mask-squircle w-12 h-12"> | ||||
|                                                                 <svg class="h-full w-full text-blue-600 dark:text-blue-400" fill="currentColor" viewBox="0 0 20 20"> | ||||
|                                                                     <path fill-rule="evenodd" d="M4 4a2 2 0 012-2h8a2 2 0 012 2v12a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 0v12h8V4H6z" clip-rule="evenodd" /> | ||||
|                                                                 </svg> | ||||
|                                                             </div> | ||||
|                                                         </div> | ||||
|                                                         <div class="text-sm text-gray-500 dark:text-gray-400"> | ||||
|                                                             @($"{Request.Headers["User-Agent"]} • {DateTime.Now:MMMM d, yyyy 'at' h:mm tt}") | ||||
|                                                         <div> | ||||
|                                                             <div class="font-bold">Current Session</div> | ||||
|                                                             <div class="text-sm opacity-50">@($"{Request.Headers["User-Agent"]} • {DateTime.Now:MMMM d, yyyy 'at' h:mm tt}")</div> | ||||
|                                                         </div> | ||||
|                                                     </div> | ||||
|                                                 </div> | ||||
|                                                 <div class="ml-4 flex-shrink-0"> | ||||
|                                                     <span | ||||
|                                                         class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"> | ||||
|                                                         Active now | ||||
|                                                     </span> | ||||
|                                                 </div> | ||||
|                                             </div> | ||||
|                                         </li> | ||||
|                                     </ul> | ||||
|                                     <div class="bg-gray-50 dark:bg-gray-800 px-4 py-4 sm:px-6 text-right"> | ||||
|                                         <button type="button" | ||||
|                                                 class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"> | ||||
|                                             Sign out all other sessions | ||||
|                                         </button> | ||||
|                                                 </td> | ||||
|                                             </tr> | ||||
|                                             </tbody> | ||||
|                                         </table> | ||||
|                                     </div> | ||||
|                                     <div class="card-actions justify-end mt-4"> | ||||
|                                         <button type="button" class="btn btn-error">Sign out all other sessions</button> | ||||
|                                     </div> | ||||
|                                 </div> | ||||
|                             </div> | ||||
| @@ -245,10 +162,7 @@ | ||||
|                     <!-- Logout Button --> | ||||
|                     <div class="mt-6 flex justify-end"> | ||||
|                         <form method="post" asp-page-handler="Logout"> | ||||
|                             <button type="submit" | ||||
|                                     class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"> | ||||
|                                 Sign out | ||||
|                             </button> | ||||
|                             <button type="submit" class="btn btn-error">Sign out</button> | ||||
|                         </form> | ||||
|                     </div> | ||||
|                 </div> | ||||
| @@ -258,54 +172,22 @@ | ||||
| } | ||||
| else | ||||
| { | ||||
|     <div class="min-h-screen flex items-center justify-center bg-gray-100 dark:bg-gray-900"> | ||||
|         <div class="max-w-md w-full p-8 bg-white dark:bg-gray-800 rounded-lg shadow-md text-center"> | ||||
|             <div class="text-red-500 text-5xl mb-4"> | ||||
|                 <i class="fas fa-exclamation-circle"></i> | ||||
|     <div class="hero min-h-screen bg-base-200"> | ||||
|         <div class="hero-content text-center"> | ||||
|             <div class="max-w-md"> | ||||
|                 <div class="text-error text-5xl mb-4"> | ||||
|                     <i class="fas fa-exclamation-circle"></i> | ||||
|                 </div> | ||||
|                 <h1 class="text-5xl font-bold">Profile Not Found</h1> | ||||
|                 <p class="py-6">User profile not found. Please log in to continue.</p> | ||||
|                 <a href="/auth/login" class="btn btn-primary">Go to Login</a> | ||||
|             </div> | ||||
|             <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">Profile Not Found</h2> | ||||
|             <p class="text-gray-600 dark:text-gray-400 mb-6">User profile not found. Please log in to continue.</p> | ||||
|             <a href="/auth/login" | ||||
|                class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> | ||||
|                 Go to Login | ||||
|             </a> | ||||
|         </div> | ||||
|     </div> | ||||
| } | ||||
|  | ||||
| @section Scripts { | ||||
|     <script> | ||||
|         // Tab functionality | ||||
|         document.addEventListener('DOMContentLoaded', function () { | ||||
|             // Get all tab buttons and content | ||||
|             const tabButtons = document.querySelectorAll('.tab-button'); | ||||
|             const tabContents = document.querySelectorAll('.tab-content'); | ||||
|  | ||||
|             // Add click event listeners to tab buttons | ||||
|             tabButtons.forEach(button => { | ||||
|                 button.addEventListener('click', function () { | ||||
|                     const tabId = this.getAttribute('data-tab'); | ||||
|  | ||||
|                     // Update active tab button | ||||
|                     tabButtons.forEach(btn => btn.classList.remove('border-blue-500', 'text-blue-600', 'dark:text-blue-400')); | ||||
|                     this.classList.add('border-blue-500', 'text-blue-600', 'dark:text-blue-400'); | ||||
|  | ||||
|                     // Show corresponding tab content | ||||
|                     tabContents.forEach(content => { | ||||
|                         content.classList.add('hidden'); | ||||
|                         if (content.id === `${tabId}-tab`) { | ||||
|                             content.classList.remove('hidden'); | ||||
|                         } | ||||
|                     }); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             // Show first tab by default | ||||
|             if (tabButtons.length > 0) { | ||||
|                 tabButtons[0].click(); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         // Copy access token to clipboard | ||||
|         function copyAccessToken() { | ||||
|             const copyText = document.getElementById("accessToken"); | ||||
| @@ -340,4 +222,4 @@ else | ||||
|             } | ||||
|         } | ||||
|     </script> | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -4,10 +4,10 @@ | ||||
|     ViewData["Title"] = "Authorize Application"; | ||||
| } | ||||
|  | ||||
| <div class="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 transition-colors duration-200 py-12 px-4 sm:px-6 lg:px-8"> | ||||
|     <div class="max-w-md w-full space-y-8 bg-white dark:bg-gray-800 p-8 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 transition-colors duration-200"> | ||||
|         <div class="text-center"> | ||||
|             <h2 class="mt-6 text-3xl font-extrabold text-gray-900 dark:text-white"> | ||||
| <div class="min-h-screen flex items-center justify-center bg-base-200 py-12 px-4 sm:px-6 lg:px-8"> | ||||
|     <div class="card w-full max-w-md bg-base-100 shadow-xl"> | ||||
|         <div class="card-body"> | ||||
|             <h2 class="card-title justify-center text-2xl font-bold"> | ||||
|                 Authorize Application | ||||
|             </h2> | ||||
|             @if (!string.IsNullOrEmpty(Model.AppName)) | ||||
| @@ -16,21 +16,17 @@ | ||||
|                     <div class="flex items-center justify-center"> | ||||
|                         @if (!string.IsNullOrEmpty(Model.AppLogo)) | ||||
|                         { | ||||
|                             <div class="relative h-16 w-16 flex-shrink-0"> | ||||
|                                 <img class="h-16 w-16 rounded-lg object-cover border border-gray-200 dark:border-gray-700"  | ||||
|                                      src="@Model.AppLogo"  | ||||
|                                      alt="@Model.AppName logo"  | ||||
|                                      onerror="this.onerror=null; this.src='data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzczz0idy02IGgtNiB0ZXh0LWdyYXktNDAwIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xOS42MDMgMy4wMDRjMS4xNTMgMCAyLjI2LjE4IDMuMzI5LjUxM2EuNzUuNzUgMCAwMS0uMzI4IDEuNDQ1IDE2LjkzIDE2LjkzIDAgMDAtNi4wMS0xuMTAzLjc1Ljc1IDAgMDEtLjY2OC0uNzQ4VjMuNzVBLjc1Ljc1IDAgMDExNi41IDNoMy4xMDN6TTMxLjUgMjEuMDA4Yy0uU0UuNzUgNzUuNzUgMCAwMTEuOTQ4LjA1MWMuMDgxLjkxOC4wNTIgMS44MzgtLjA4NiAyLjczNGEuNzUuNzUgMCAwMS0xLjQ5LS4xNTkgMjEuMzg2IDIxLjM4NiAwIDAwLjA2LTIuNTc1Ljc1Ljc1IDAgMDExLjU3OC0uMDQzem0tMy4wMi0xOC4wMmMuMDYgMS4wOTIuMDQgMi4xODctLjA1NiAzLjI3MmEuNzUuNzUgMCAwMS0xLjQ5Mi0uMTY0Yy4wOTItLjg3NC4xMDctMS43NTYuMDUxLTIuNjA3YS43NS43NSAwIDAxMS40OTctLjEwMXpNNS42MzcgNS42MzJjLS4zMzQuMS0uNjc2LjE4NS0xLjAyNi4yNTdhLjc1Ljc1IDAgMDEuMTQ5LTEuNDljLjQyNS0uMDg1Ljg1Mi0uMTg5IDEuMjY4LS4zMDRhLjc1Ljc1IDAgMDEuMzYgMS40Mzd6TTMuMzMgMTkuNjUzYy0uMTY1LS4zNS0uMzA4LS43MDctNDIuNjUzLjc1Ljc1IDAgMS4zODgtLjU0MiAxLjQ5LTEuMjg1LjA0Ni0uMzI2LjEwNi0uNjUyLjE4LS45NzZhLjc1Ljc1IDAgMTExLjQ2LS41M2MuMTA2LjQzNy4xODkuODgxLjI0NSAxLjM0OGEuNzUuNzUgMCAwMS0xLjQ5LjIzM3pNTEuMzUzIDIuNzY3YS43NS43NSAwIDAxLjc1LS4wMTdsLjAwMS4wMDFoLjAwMWwuMDAyLjAwMWwuMDA3LjAwM2wuMDI0LjAxM2MuMDIuMDEuMDQ1LjAyNS4wNzkuMDQ2LjA2Ny4wNDIuMTYxLjEwMi4yNzUuMTc4LjIzMi4xNTEuNTUuMzgzLjg1Ni42NjdsLjAyNy4wMjRjLjYxNi41NTggMS4yMTIgMS4xNzYgMS43MzMgMS44NDNhLjc1Ljc1IDAgMDEtMS4yNC44N2MtLjQ3LS42NzEtMS4wMzEtMS4yOTItMS42LFsxLjYxNi0xLjYxNmEzLjc1IDMuNzUgMCAwMC01LjMwNS01LjMwNGwtMS4wNi0xuMDZBNy4yNDMgNy4yNDMgMCAwMTUxLjM1MyAyLjc2N3pNNDQuMzc5IDkuNjRsLTEuNTYgMS41NmE2Ljk5IDYuOTkgMCAwMTIuMjMgNC4zMzcgNi45OSA2Ljk5IDAgMDEtMi4yMyA1LjE3NmwtMS41Ni0xLjU2QTguNDkgOC40OSAwIDAwNDUuNSAxNS41YzAtMi4yOTYtLjg3NC00LjQzLTIuMTIxLTYuMDF6bS0zLjUzLTMuNTNsLTEuMDYxLTEuMDZhNy4yNDMgNy4yNDMgMCAwMTkuMTkyIDkuE2x0LTEuMDYgMS4wNjFhNS43NDkgNS43NDkgMCAwMC04LjEzLTguMTN6TTM0LjUgMTUuNWE4Ljk5IDguOTkgMCAwMC0yLjYzMSA2LjM2OS43NS43NSAwIDExLTEuNDk0LS43MzlDNzIuMzkgMjAuMDYgMzMuNSAxNy41NzUgMzMuNSAxNS41YzAtMi4zNzYgMS4wOTktNC40MzggMi44MTEtNS44MTJsLS4zOTYtLjM5NmEuNzUuNzUgMCAwMTEuMDYtMS4wNkwzNy41IDkuNDRWMmgtL4wMDJhLjc1Ljc1IDAgMDEtLjc0OC0uNzVWMS41YS43NS43NSAwIDAxLjc1LS43NWg2YS43NS43NSAwIDAxLjc1Ljc1di4yNWEwIC43NS0uNzUuNzVoLS4wMDF2Ny40NGwzLjUzNy0zLjUzN2EuNzUuNzUgMCAwMTEuMDYgMS4wNmwtLjM5Ni4zOTZDMzUuNDAxIDExLjA2MiAzNC41IDEzLjEyNCAzNC41IDE1LjV6TTM5IDIuMjV2Ni4wMy0uMDAyYTEuNSAxLjUgMCAwMS0uNDQ0IDEuMDZsLTEuMDYxIDEuMDZBOC40OSA4LjQ5IDAgMDAzOSAxNS41YzAgMi4yOTYtLjg3NCA0LjQzLTIuMTIxIDYuMDFsMS41NiAxLjU2QTYuOTkgNi45OSAwIDAwNDIgMTUuNWE2Ljk5IDYuOTkgMCAwMC0yLjIzLTUuMTc2bC0xLjU2LTEuNTZhMS41IDEuNSAwIDAxLS40NC0xLjA2VjIuMjVoLTF6TTI0IDkuNzVhLjc1Ljc1IDAgMDEtLjc1Ljc1di0uNWMwLS40MTQuMzM2LS43NS43NS0uNzVoLjVjLjQxNCAwIC43NS4zMzYuNzUuNzV2LjVhLjc1Ljc1IDAgMDEtLjc1Ljc1aC0uNXpNMTkuNSAxM2EuNzUuNzUgMCAwMS0uNzUtLjc1di0uNWMwLS40MTQuMzM2LS43NS43NS0uNzVoLjVjLjQxNCAwIC43NS4zMzYuNzUuNzV2LjVhLjc1Ljc1IDAgMDEtLjc1Ljc1aC0uNXpNMTUgMTYuMjVhLjc1Ljc1IDAgMDEuNzUtLjc1aC41Yy40MTQgMCAuNzUuMzM2Ljc1Ljc1di41YS43NS43NSAwIDAxLS43NS43NWgtLjVhLjc1Ljc1IDAgMDEtLjc1LS43NXYtLjV6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=';"> | ||||
|                                 <div class="absolute inset-0 flex items-center justify-center bg-gray-100 dark:bg-gray-700 rounded-lg border border-gray-200 dark:border-gray-600"> | ||||
|                                     <span class="text-xs font-medium text-gray-500 dark:text-gray-300">@Model.AppName?[0]</span> | ||||
|                             <div class="avatar"> | ||||
|                                 <div class="w-16 rounded"> | ||||
|                                     <img src="@Model.AppLogo" alt="@Model.AppName logo" /> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         } | ||||
|                         <div class="ml-4 text-left"> | ||||
|                             <h3 class="text-lg font-medium text-gray-900 dark:text-white">@Model.AppName</h3> | ||||
|                             <h3 class="text-lg font-medium">@Model.AppName</h3> | ||||
|                             @if (!string.IsNullOrEmpty(Model.AppUri)) | ||||
|                             { | ||||
|                                 <a href="@Model.AppUri" class="text-sm text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300 transition-colors duration-200" target="_blank" rel="noopener noreferrer"> | ||||
|                                 <a href="@Model.AppUri" class="text-sm link link-primary" target="_blank" rel="noopener noreferrer"> | ||||
|                                     @Model.AppUri | ||||
|                                 </a> | ||||
|                             } | ||||
| @@ -38,77 +34,69 @@ | ||||
|                     </div> | ||||
|                 </div> | ||||
|             } | ||||
|             <p class="mt-6 text-sm text-gray-600 dark:text-gray-300"> | ||||
|             <p class="mt-6 text-sm text-center"> | ||||
|                 wants to access your account with the following permissions: | ||||
|             </p> | ||||
|         </div> | ||||
|  | ||||
|         <div class="mt-6"> | ||||
|             <ul class="border border-gray-200 dark:border-gray-700 rounded-lg divide-y divide-gray-200 dark:divide-gray-700 overflow-hidden"> | ||||
|                 @if (Model.Scope != null) | ||||
|                 { | ||||
|                     var scopeDescriptions = new Dictionary<string, (string Name, string Description)> | ||||
|             <div class="mt-6"> | ||||
|                 <ul class="menu bg-base-200 rounded-box"> | ||||
|                     @if (Model.Scope != null) | ||||
|                     { | ||||
|                         ["openid"] = ("OpenID", "Read your basic profile information"), | ||||
|                         ["profile"] = ("Profile", "View your basic profile information"), | ||||
|                         ["email"] = ("Email", "View your email address"), | ||||
|                         ["offline_access"] = ("Offline Access", "Access your data while you're not using the application") | ||||
|                     }; | ||||
|                         var scopeDescriptions = new Dictionary<string, (string Name, string Description)> | ||||
|                         { | ||||
|                             ["openid"] = ("OpenID", "Read your basic profile information"), | ||||
|                             ["profile"] = ("Profile", "View your basic profile information"), | ||||
|                             ["email"] = ("Email", "View your email address"), | ||||
|                             ["offline_access"] = ("Offline Access", "Access your data while you're not using the application") | ||||
|                         }; | ||||
|  | ||||
|                     foreach (var scope in Model.Scope.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s))) | ||||
|                     { | ||||
|                         var scopeInfo = scopeDescriptions.GetValueOrDefault(scope, (scope, scope.Replace('_', ' '))); | ||||
|                         <li class="px-4 py-3 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-150"> | ||||
|                             <div class="flex items-start"> | ||||
|                                 <div class="flex-shrink-0 pt-0.5"> | ||||
|                                     <svg class="h-5 w-5 text-green-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> | ||||
|                         foreach (var scope in Model.Scope.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s))) | ||||
|                         { | ||||
|                             var scopeInfo = scopeDescriptions.GetValueOrDefault(scope, (scope, scope.Replace('_', ' '))); | ||||
|                             <li> | ||||
|                                 <a> | ||||
|                                     <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-success" viewBox="0 0 20 20" fill="currentColor"> | ||||
|                                         <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" /> | ||||
|                                     </svg> | ||||
|                                 </div> | ||||
|                                 <div class="ml-3"> | ||||
|                                     <p class="text-sm font-medium text-gray-900 dark:text-white">@scopeInfo.Item1</p> | ||||
|                                     <p class="text-xs text-gray-500 dark:text-gray-400">@scopeInfo.Item2</p> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </li> | ||||
|                                     <div> | ||||
|                                         <p class="font-medium">@scopeInfo.Item1</p> | ||||
|                                         <p class="text-xs text-base-content/70">@scopeInfo.Item2</p> | ||||
|                                     </div> | ||||
|                                 </a> | ||||
|                             </li> | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             </ul> | ||||
|              | ||||
|             <div class="mt-4 text-xs text-gray-500 dark:text-gray-400"> | ||||
|                 <p>By authorizing, you allow this application to access your information on your behalf.</p> | ||||
|                 </ul> | ||||
|                  | ||||
|                 <div class="mt-4 text-xs text-base-content/70"> | ||||
|                     <p>By authorizing, you allow this application to access your information on your behalf.</p> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <form method="post" class="mt-8 space-y-4"> | ||||
|             <input type="hidden" asp-for="ClientIdString" /> | ||||
|             <input type="hidden" asp-for="ResponseType" name="response_type" /> | ||||
|             <input type="hidden" asp-for="RedirectUri" name="redirect_uri" /> | ||||
|             <input type="hidden" asp-for="Scope" name="scope" /> | ||||
|             <input type="hidden" asp-for="State" name="state" /> | ||||
|             <input type="hidden" asp-for="Nonce" name="nonce" /> | ||||
|             <input type="hidden" asp-for="ReturnUrl" name="returnUrl" /> | ||||
|             <input type="hidden" name="code_challenge" value="@HttpContext.Request.Query["code_challenge"]" /> | ||||
|             <input type="hidden" name="code_challenge_method" value="@HttpContext.Request.Query["code_challenge_method"]" /> | ||||
|             <input type="hidden" name="response_mode" value="@HttpContext.Request.Query["response_mode"]" /> | ||||
|              | ||||
|             <div class="flex flex-col space-y-3"> | ||||
|                 <button type="submit" name="allow" value="true"  | ||||
|                         class="w-full flex justify-center py-2.5 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-offset-gray-800 transition-colors duration-200"> | ||||
|                     Allow | ||||
|                 </button> | ||||
|                 <button type="submit" name="allow" value="false"  | ||||
|                         class="w-full flex justify-center py-2.5 px-4 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-offset-gray-800 transition-colors duration-200"> | ||||
|                     Deny | ||||
|                 </button> | ||||
|             </div> | ||||
|              | ||||
|             <div class="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700"> | ||||
|                 <p class="text-xs text-center text-gray-500 dark:text-gray-400"> | ||||
|                     You can change these permissions later in your account settings. | ||||
|                 </p> | ||||
|             </div> | ||||
|         </form> | ||||
|             <form method="post" class="mt-8 space-y-4"> | ||||
|                 <input type="hidden" asp-for="ClientIdString" /> | ||||
|                 <input type="hidden" asp-for="ResponseType" name="response_type" /> | ||||
|                 <input type="hidden" asp-for="RedirectUri" name="redirect_uri" /> | ||||
|                 <input type="hidden" asp-for="Scope" name="scope" /> | ||||
|                 <input type="hidden" asp-for="State" name="state" /> | ||||
|                 <input type="hidden" asp-for="Nonce" name="nonce" /> | ||||
|                 <input type="hidden" asp-for="ReturnUrl" name="returnUrl" /> | ||||
|                 <input type="hidden" name="code_challenge" value="@HttpContext.Request.Query["code_challenge"]" /> | ||||
|                 <input type="hidden" name="code_challenge_method" value="@HttpContext.Request.Query["code_challenge_method"]" /> | ||||
|                 <input type="hidden" name="response_mode" value="@HttpContext.Request.Query["response_mode"]" /> | ||||
|                  | ||||
|                 <div class="card-actions justify-center"> | ||||
|                     <button type="submit" name="allow" value="true" class="btn btn-primary">Allow</button> | ||||
|                     <button type="submit" name="allow" value="false" class="btn btn-ghost">Deny</button> | ||||
|                 </div> | ||||
|                  | ||||
|                 <div class="mt-4 pt-4 border-t border-base-300"> | ||||
|                     <p class="text-xs text-center text-base-content/70"> | ||||
|                         You can change these permissions later in your account settings. | ||||
|                     </p> | ||||
|                 </div> | ||||
|             </form> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| @@ -124,4 +112,4 @@ | ||||
|             _ => scope | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -5,10 +5,12 @@ | ||||
|     Layout = "_Layout"; | ||||
| } | ||||
|  | ||||
| <div class="h-full flex items-center justify-center"> | ||||
|     <div class="max-w-lg w-full mx-auto p-6 text-center"> | ||||
|         <h1 class="text-2xl font-bold text-gray-900 dark:text-white">Authentication Successful</h1> | ||||
|         <p class="mb-6 text-gray-900 dark:text-white">You can now close this window and return to the application.</p> | ||||
| <div class="hero min-h-full bg-base-200"> | ||||
|     <div class="hero-content text-center"> | ||||
|         <div class="max-w-md"> | ||||
|             <h1 class="text-5xl font-bold">Authentication Successful</h1> | ||||
|             <p class="py-6">You can now close this window and return to the application.</p> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| @@ -44,4 +46,4 @@ | ||||
|             } | ||||
|         })(); | ||||
|     </script> | ||||
| } | ||||
| } | ||||
| @@ -6,8 +6,11 @@ | ||||
|     Response.Redirect($"/web/auth/challenge/{Model.Id}/select-factor"); | ||||
| } | ||||
|  | ||||
| <div class="h-full flex items-center justify-center bg-gray-100 dark:bg-gray-900"> | ||||
|     <div class="bg-white dark:bg-gray-800 p-8 rounded-lg shadow-md w-full max-w-md text-center"> | ||||
|         <p>Redirecting to authentication page...</p> | ||||
| <div class="hero min-h-full bg-base-200"> | ||||
|     <div class="hero-content text-center"> | ||||
|         <div class="max-w-md"> | ||||
|             <span class="loading loading-spinner loading-lg"></span> | ||||
|             <p class="py-6">Redirecting to authentication page...</p> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| </div> | ||||
|   | ||||
| @@ -5,32 +5,32 @@ | ||||
|     var returnUrl = Model.ReturnUrl ?? ""; | ||||
| } | ||||
|  | ||||
| <div class="h-full flex items-center justify-center bg-gray-100 dark:bg-gray-900"> | ||||
|     <div class="bg-white dark:bg-gray-800 p-8 rounded-lg shadow-md w-full max-w-md"> | ||||
|         <h1 class="text-2xl font-bold text-center text-gray-900 dark:text-white mb-6">Login</h1> | ||||
|  | ||||
|         <form method="post"> | ||||
|             <input type="hidden" asp-for="ReturnUrl" value="@returnUrl" /> | ||||
|             <div class="mb-4"> | ||||
|                 <label asp-for="Username" | ||||
|                        class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"></label> | ||||
|                 <input asp-for="Username" | ||||
|                        class="form-input mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-500 focus:ring-opacity-50 dark:bg-gray-700 dark:border-gray-600 dark:text-white px-4 py-2"/> | ||||
|                 <span asp-validation-for="Username" class="text-red-500 text-sm mt-1"></span> | ||||
| <div class="hero min-h-full bg-base-200"> | ||||
|     <div class="hero-content w-full max-w-md"> | ||||
|         <div class="card w-full bg-base-100 shadow-xl"> | ||||
|             <div class="card-body px-8 py-7"> | ||||
|                 <h1 class="card-title justify-center text-2xl font-bold">Welcome back!</h1> | ||||
|                 <p class="text-center">Login to your Solar Network account to continue.</p> | ||||
|                 <form method="post" class="mt-4"> | ||||
|                     <input type="hidden" asp-for="ReturnUrl" value="@returnUrl"/> | ||||
|                     <div class="form-control"> | ||||
|                         <label class="label" asp-for="Username"> | ||||
|                             <span class="label-text">Username</span> | ||||
|                         </label> | ||||
|                         <input asp-for="Username" class="input input-bordered w-full"/> | ||||
|                         <span asp-validation-for="Username" class="text-error text-sm mt-1"></span> | ||||
|                     </div> | ||||
|                     <div class="form-control mt-6"> | ||||
|                         <button type="submit" class="btn btn-primary w-full">Next</button> | ||||
|                     </div> | ||||
|                     <div class="text-sm text-center mt-4"> | ||||
|                         <span class="text-base-content/70">Have no account?</span> <br/> | ||||
|                         <a href="https://solian.app/#/auth/create-account" class="link link-primary"> | ||||
|                             Create a new account → | ||||
|                         </a> | ||||
|                     </div> | ||||
|                 </form> | ||||
|             </div> | ||||
|             <button type="submit" | ||||
|                     class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"> | ||||
|                 Next | ||||
|             </button> | ||||
|         </form> | ||||
|  | ||||
|         <div class="mt-8 flex flex-col text-sm text-center"> | ||||
|             <span class="text-gray-900 dark:text-white opacity-80">Have no account?</span> | ||||
|  | ||||
|             <a href="https://solian.app/#/auth/create-account" | ||||
|                class="text-blue-600 hover:text-blue-500 dark:text-blue-400 dark:hover:text-blue-300"> | ||||
|                 Create a new account → | ||||
|             </a> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
|   | ||||
| @@ -5,54 +5,92 @@ | ||||
|     ViewData["Title"] = "Select Authentication Method"; | ||||
| } | ||||
|  | ||||
| <div class="h-full flex items-center justify-center bg-gray-100 dark:bg-gray-900"> | ||||
|     <div class="bg-white dark:bg-gray-800 p-8 rounded-lg shadow-md w-full max-w-md"> | ||||
|         <h1 class="text-2xl font-bold text-center text-gray-900 dark:text-white mb-6">Select Authentication Method</h1> | ||||
| <div class="hero min-h-full bg-base-200"> | ||||
|     <div class="hero-content w-full max-w-md"> | ||||
|         <div class="card w-full bg-base-100 shadow-xl"> | ||||
|             <div class="card-body"> | ||||
|                 <h1 class="card-title justify-center text-2xl font-bold">Select Authentication Method</h1> | ||||
|  | ||||
|         @if (Model.AuthChallenge == null) | ||||
|         { | ||||
|             <p class="text-red-500 text-center">Challenge not found or expired.</p> | ||||
|         } | ||||
|         else if (Model.AuthChallenge.StepRemain == 0) | ||||
|         { | ||||
|             <p class="text-green-600 dark:text-green-400 text-center">Challenge completed. Redirecting...</p> | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             <p class="text-gray-700 dark:text-gray-300 mb-4">Please select an authentication method:</p> | ||||
|  | ||||
|             <div class="space-y-4"> | ||||
|                 @foreach (var factor in Model.AuthFactors) | ||||
|                 @if (Model.AuthChallenge == null) | ||||
|                 { | ||||
|                     <div class="mb-4"> | ||||
|                         <form method="post" asp-page-handler="SelectFactor" class="w-full" id="factor-@factor.Id"> | ||||
|                             <input type="hidden" name="SelectedFactorId" value="@factor.Id"/> | ||||
|                              | ||||
|                             @if (factor.Type == AccountAuthFactorType.EmailCode) | ||||
|                             { | ||||
|                                 <div class="mb-3"> | ||||
|                                     <label for="hint-@factor.Id" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"> | ||||
|                                         Email to send code to | ||||
|                                     </label> | ||||
|                                     <input type="email"  | ||||
|                                            id="hint-@factor.Id"  | ||||
|                                            name="hint"  | ||||
|                                            class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white" | ||||
|                                            placeholder="Enter your email" | ||||
|                                            required> | ||||
|                                 </div> | ||||
|                             } | ||||
|                              | ||||
|                             <button type="submit" | ||||
|                                     class="w-full text-left p-4 bg-gray-50 dark:bg-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 rounded-lg transition-colors"> | ||||
|                                 <div class="font-medium text-gray-900 dark:text-white">@GetFactorDisplayName(factor.Type)</div> | ||||
|                                 <div class="text-sm text-gray-500 dark:text-gray-400">@GetFactorDescription(factor.Type)</div> | ||||
|                             </button> | ||||
|                         </form> | ||||
|                     <div class="alert alert-error"> | ||||
|                         <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" | ||||
|                              viewBox="0 0 24 24"> | ||||
|                             <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | ||||
|                                   d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"/> | ||||
|                         </svg> | ||||
|                         <span>Challenge not found or expired.</span> | ||||
|                     </div> | ||||
|                 } | ||||
|                 else if (Model.AuthChallenge.StepRemain == 0) | ||||
|                 { | ||||
|                     <div class="alert alert-success"> | ||||
|                         <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" | ||||
|                              viewBox="0 0 24 24"> | ||||
|                             <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | ||||
|                                   d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/> | ||||
|                         </svg> | ||||
|                         <span>Challenge completed. Redirecting...</span> | ||||
|                     </div> | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     <p class="text-center">Please select an authentication method:</p> | ||||
|  | ||||
|                     <div class="space-y-4"> | ||||
|                         @foreach (var factor in Model.AuthFactors) | ||||
|                         { | ||||
|                             <form method="post" asp-page-handler="SelectFactor" class="w-full" id="factor-@factor.Id"> | ||||
|                                 <input type="hidden" name="SelectedFactorId" value="@factor.Id"/> | ||||
|  | ||||
|                                 @if (factor.Type == AccountAuthFactorType.EmailCode) | ||||
|                                 { | ||||
|                                     <div class="card w-full bg-base-200 card-sm shadow-sm rounded-md"> | ||||
|                                         <div class="py-4 px-5 align-items-center"> | ||||
|                                             <div> | ||||
|                                                 <h2 class="card-title">@GetFactorDisplayName(factor.Type)</h2> | ||||
|                                                 <p>@GetFactorDescription(factor.Type)</p> | ||||
|                                             </div> | ||||
|                                             <div class="join w-full mt-2"> | ||||
|                                                 <div class="flex-1"> | ||||
|                                                     <label class="input join-item input-sm"> | ||||
|                                                         <input id="hint-@factor.Id" type="email" | ||||
|                                                                placeholder="mail@site.com" required/> | ||||
|                                                     </label> | ||||
|                                                 </div> | ||||
|                                                 <button class="btn btn-primary join-item btn-sm"> | ||||
|                                                     <span class="material-symbols-outlined"> | ||||
|                                                         arrow_right_alt | ||||
|                                                     </span> | ||||
|                                                 </button> | ||||
|                                             </div> | ||||
|                                         </div> | ||||
|                                     </div> | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
|                                     <div class="card w-full bg-base-200 card-sm shadow-sm rounded-md"> | ||||
|                                         <div class="flex py-4 px-5 align-items-center"> | ||||
|                                             <div class="flex-1"> | ||||
|                                                 <h2 class="card-title">@GetFactorDisplayName(factor.Type)</h2> | ||||
|                                                 <p>@GetFactorDescription(factor.Type)</p> | ||||
|                                             </div> | ||||
|                                             <div class="justify-end card-actions"> | ||||
|                                                 <button type="submit" class="btn btn-primary btn-sm"> | ||||
|                                                     <span class="material-symbols-outlined"> | ||||
|                                                         arrow_right_alt | ||||
|                                                     </span> | ||||
|                                                 </button> | ||||
|                                             </div> | ||||
|                                         </div> | ||||
|                                     </div> | ||||
|                                 } | ||||
|                             </form> | ||||
|                         } | ||||
|                     </div> | ||||
|                 } | ||||
|             </div> | ||||
|         } | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| @@ -78,4 +116,4 @@ | ||||
|         _ => string.Empty | ||||
|     }; | ||||
|  | ||||
| } | ||||
| } | ||||
| @@ -5,73 +5,82 @@ | ||||
|     ViewData["Title"] = "Verify Your Identity"; | ||||
| } | ||||
|  | ||||
| <div class="h-full flex items-center justify-center bg-gray-100 dark:bg-gray-900"> | ||||
|     <div class="bg-white dark:bg-gray-800 px-8 pt-8 pb-4 rounded-lg shadow-md w-full max-w-md"> | ||||
|         <h1 class="text-2xl font-bold text-center text-gray-900 dark:text-white mb-2">Verify Your Identity</h1> | ||||
|         <p class="text-center text-gray-600 dark:text-gray-300 mb-6"> | ||||
|             @switch (Model.FactorType) | ||||
|             { | ||||
|                 case AccountAuthFactorType.EmailCode: | ||||
|                     <span>We've sent a verification code to your email.</span> | ||||
|                     break; | ||||
|                 case AccountAuthFactorType.InAppCode: | ||||
|                     <span>Enter the code from your authenticator app.</span> | ||||
|                     break; | ||||
|                 case AccountAuthFactorType.TimedCode: | ||||
|                     <span>Enter your time-based verification code.</span> | ||||
|                     break; | ||||
|                 case AccountAuthFactorType.PinCode: | ||||
|                     <span>Enter your PIN code.</span> | ||||
|                     break; | ||||
|                 case AccountAuthFactorType.Password: | ||||
|                     <span>Enter your password.</span> | ||||
|                     break; | ||||
|                 default: | ||||
|                     <span>Please verify your identity.</span> | ||||
|                     break; | ||||
|             } | ||||
|         </p> | ||||
| <div class="hero min-h-full bg-base-200"> | ||||
|     <div class="hero-content w-full max-w-md"> | ||||
|         <div class="card w-full bg-base-100 shadow-xl"> | ||||
|             <div class="card-body px-8 py-7"> | ||||
|                 <h1 class="card-title justify-center text-2xl font-bold">Verify Your Identity</h1> | ||||
|                 <p class="text-center"> | ||||
|                     @switch (Model.FactorType) | ||||
|                     { | ||||
|                         case AccountAuthFactorType.EmailCode: | ||||
|                             <span>We've sent a verification code to your email.</span> | ||||
|                             break; | ||||
|                         case AccountAuthFactorType.InAppCode: | ||||
|                             <span>Enter the code from your authenticator app.</span> | ||||
|                             break; | ||||
|                         case AccountAuthFactorType.TimedCode: | ||||
|                             <span>Enter your time-based verification code.</span> | ||||
|                             break; | ||||
|                         case AccountAuthFactorType.PinCode: | ||||
|                             <span>Enter your PIN code.</span> | ||||
|                             break; | ||||
|                         case AccountAuthFactorType.Password: | ||||
|                             <span>Enter your password.</span> | ||||
|                             break; | ||||
|                         default: | ||||
|                             <span>Please verify your identity.</span> | ||||
|                             break; | ||||
|                     } | ||||
|                 </p> | ||||
|  | ||||
|         @if (Model.AuthChallenge == null) | ||||
|         { | ||||
|             <p class="text-red-500 text-center">Challenge not found or expired.</p> | ||||
|         } | ||||
|         else if (Model.AuthChallenge.StepRemain == 0) | ||||
|         { | ||||
|             <p class="text-green-600 dark:text-green-400 text-center">Verification successful. Redirecting...</p> | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             <form method="post" class="space-y-4"> | ||||
|                 <div asp-validation-summary="ModelOnly" class="text-red-500 text-sm"></div> | ||||
|                  | ||||
|                 <div class="mb-4"> | ||||
|                     <label asp-for="Code" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"> | ||||
|                         @(Model.FactorType == AccountAuthFactorType.Password ? "Use your password" : "Verification Code") | ||||
|                     </label> | ||||
|                     <input asp-for="Code" | ||||
|                            class="form-input mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-500 focus:ring-opacity-50 dark:bg-gray-700 dark:border-gray-600 dark:text-white px-4 py-2" | ||||
|                            autocomplete="one-time-code" | ||||
|                            type="password" | ||||
|                            autofocus /> | ||||
|                     <span asp-validation-for="Code" class="text-red-500 text-sm mt-1"></span> | ||||
|                 </div> | ||||
|                 @if (Model.AuthChallenge == null) | ||||
|                 { | ||||
|                     <div class="alert alert-error"> | ||||
|                         <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg> | ||||
|                         <span>Challenge not found or expired.</span> | ||||
|                     </div> | ||||
|                 } | ||||
|                 else if (Model.AuthChallenge.StepRemain == 0) | ||||
|                 { | ||||
|                     <div class="alert alert-success"> | ||||
|                         <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg> | ||||
|                         <span>Verification successful. Redirecting...</span> | ||||
|                     </div> | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     <form method="post" class="space-y-4"> | ||||
|                         <div asp-validation-summary="ModelOnly" class="text-error text-sm"></div> | ||||
|                          | ||||
|                         <div class="form-control"> | ||||
|                             <label asp-for="Code" class="label"> | ||||
|                                 <span class="label-text">@(Model.FactorType == AccountAuthFactorType.Password ? "Use your password" : "Verification Code")</span> | ||||
|                             </label> | ||||
|                             <input asp-for="Code" | ||||
|                                    class="input input-bordered w-full" | ||||
|                                    autocomplete="one-time-code" | ||||
|                                    type="password" | ||||
|                                    autofocus /> | ||||
|                             <span asp-validation-for="Code" class="text-error text-sm mt-1"></span> | ||||
|                         </div> | ||||
|  | ||||
|                 <button type="submit" | ||||
|                         class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"> | ||||
|                     Verify | ||||
|                 </button> | ||||
|                         <div class="form-control mt-6"> | ||||
|                             <button type="submit" class="btn btn-primary w-full">Verify</button> | ||||
|                         </div> | ||||
|  | ||||
|                 <div class="text-center mt-4"> | ||||
|                     <a asp-page="SelectFactor" asp-route-id="@Model.Id" class="text-sm text-blue-600 hover:text-blue-500 dark:text-blue-400 dark:hover:text-blue-300"> | ||||
|                         ← Back to authentication methods | ||||
|                     </a> | ||||
|                 </div> | ||||
|             </form> | ||||
|         } | ||||
|                         <div class="text-center mt-4"> | ||||
|                             <a asp-page="SelectFactor" asp-route-id="@Model.Id" class="link link-primary text-sm"> | ||||
|                                 ← Back to authentication methods | ||||
|                             </a> | ||||
|                         </div> | ||||
|                     </form> | ||||
|                 } | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| @section Scripts { | ||||
|     @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | ||||
| } | ||||
| } | ||||
| @@ -38,73 +38,73 @@ | ||||
|     </script> | ||||
| } | ||||
|  | ||||
| <div class="h-full flex items-center justify-center"> | ||||
|     <div class="max-w-lg w-full mx-auto p-6"> | ||||
|         <div class="text-center"> | ||||
|             <h1 class="text-2xl font-bold text-gray-900 dark:text-white">Security Check</h1> | ||||
|             <p class="mb-6 text-gray-900 dark:text-white">Please complete the contest below to confirm you're not a robot</p> | ||||
| <div class="hero min-h-full bg-base-200"> | ||||
|     <div class="hero-content text-center"> | ||||
|         <div class="max-w-md"> | ||||
|             <div class="card bg-base-100 shadow-xl"> | ||||
|                 <div class="card-body"> | ||||
|                     <h1 class="card-title">Security Check</h1> | ||||
|                     <p>Please complete the contest below to confirm you're not a robot</p> | ||||
|  | ||||
|             <div class="flex justify-center mb-8"> | ||||
|                 @switch (provider) | ||||
|                 { | ||||
|                     case "cloudflare": | ||||
|                         <div class="cf-turnstile" | ||||
|                              data-sitekey="@apiKey" | ||||
|                              data-callback="onSuccess"> | ||||
|                     <div class="flex justify-center my-8"> | ||||
|                         @switch (provider) | ||||
|                         { | ||||
|                             case "cloudflare": | ||||
|                                 <div class="cf-turnstile" | ||||
|                                      data-sitekey="@apiKey" | ||||
|                                      data-callback="onSuccess"> | ||||
|                                 </div> | ||||
|                                 break; | ||||
|                             case "recaptcha": | ||||
|                                 <div class="g-recaptcha" | ||||
|                                      data-sitekey="@apiKey" | ||||
|                                      data-callback="onSuccess"> | ||||
|                                 </div> | ||||
|                                 break; | ||||
|                             case "hcaptcha": | ||||
|                                 <div class="h-captcha" | ||||
|                                      data-sitekey="@apiKey" | ||||
|                                      data-callback="onSuccess"> | ||||
|                                 </div> | ||||
|                                 break; | ||||
|                             default: | ||||
|                                 <div class="alert alert-warning"> | ||||
|                                     <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg> | ||||
|                                     <span>Captcha provider not configured correctly.</span> | ||||
|                                 </div> | ||||
|                                 break; | ||||
|                         } | ||||
|                     </div> | ||||
|                      | ||||
|                     <div class="text-center text-sm"> | ||||
|                         <div class="font-semibold mb-1">Solar Network Anti-Robot</div> | ||||
|                         <div class="text-base-content/70"> | ||||
|                             Powered by | ||||
|                             @switch (provider) | ||||
|                             { | ||||
|                                 case "cloudflare": | ||||
|                                     <a href="https://www.cloudflare.com/turnstile/" class="link link-hover"> | ||||
|                                         Cloudflare Turnstile | ||||
|                                     </a> | ||||
|                                     break; | ||||
|                                 case "recaptcha": | ||||
|                                     <a href="https://www.google.com/recaptcha/" class="link link-hover"> | ||||
|                                         Google reCaptcha | ||||
|                                     </a> | ||||
|                                     break; | ||||
|                                 default: | ||||
|                                     <span>Nothing</span> | ||||
|                                     break; | ||||
|                             } | ||||
|                             <br/> | ||||
|                             Hosted by | ||||
|                             <a href="https://github.com/Solsynth/DysonNetwork" class="link link-hover"> | ||||
|                                 DysonNetwork.Sphere | ||||
|                             </a> | ||||
|                         </div> | ||||
|                         break; | ||||
|                     case "recaptcha": | ||||
|                         <div class="g-recaptcha" | ||||
|                              data-sitekey="@apiKey" | ||||
|                              data-callback="onSuccess"> | ||||
|                         </div> | ||||
|                         break; | ||||
|                     case "hcaptcha": | ||||
|                         <div class="h-captcha" | ||||
|                              data-sitekey="@apiKey" | ||||
|                              data-callback="onSuccess"> | ||||
|                         </div> | ||||
|                         break; | ||||
|                     default: | ||||
|                         <div class="p-4 bg-yellow-100 dark:bg-yellow-900 rounded-lg"> | ||||
|                             <p class="text-yellow-800 dark:text-yellow-200"> | ||||
|                                 Captcha provider not configured correctly. | ||||
|                             </p> | ||||
|                         </div> | ||||
|                         break; | ||||
|                 } | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="mt-8 text-center text-sm"> | ||||
|             <div class="font-semibold text-gray-700 dark:text-gray-300 mb-1">Solar Network Anti-Robot</div> | ||||
|             <div class="text-gray-600 dark:text-gray-400"> | ||||
|                 Powered by | ||||
|                 @switch (provider) | ||||
|                 { | ||||
|                     case "cloudflare": | ||||
|                         <a href="https://www.cloudflare.com/turnstile/" | ||||
|                            class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors"> | ||||
|                             Cloudflare Turnstile | ||||
|                         </a> | ||||
|                         break; | ||||
|                     case "recaptcha": | ||||
|                         <a href="https://www.google.com/recaptcha/" | ||||
|                            class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors"> | ||||
|                             Google reCaptcha | ||||
|                         </a> | ||||
|                         break; | ||||
|                     default: | ||||
|                         <span>Nothing</span> | ||||
|                         break; | ||||
|                 } | ||||
|                 <br/> | ||||
|                 Hosted by | ||||
|                 <a href="https://github.com/Solsynth/DysonNetwork" | ||||
|                    class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors"> | ||||
|                     DysonNetwork.Sphere | ||||
|                 </a> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| </div> | ||||
|   | ||||
| @@ -4,26 +4,20 @@ | ||||
|     ViewData["Title"] = "The Solar Network"; | ||||
| } | ||||
|  | ||||
| <div class="container-default h-full text-center flex flex-col justify-center items-center"> | ||||
|     <div class="mx-auto max-w-2xl"> | ||||
|         <h1 class="text-4xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-6xl"> | ||||
|             Solar Network | ||||
|         </h1> | ||||
|         <p class="mt-6 text-lg leading-8 text-gray-600 dark:text-gray-300"> | ||||
|             This Solar Network instance is up and running. | ||||
|         </p> | ||||
|         <div class="mt-10 flex items-center justify-center gap-x-6"> | ||||
|             <a href="https://sn.solsynth.dev" target="_blank" class="btn-primary"> | ||||
|                 Get started | ||||
|             </a> | ||||
|         </div> | ||||
|         <div class="flex items-center justify-center gap-x-6 mt-6"> | ||||
|             <a href="/swagger" target="_blank" class="btn-text"> | ||||
|                 <span aria-hidden="true">λ </span> API Docs | ||||
|             </a> | ||||
|             <a href="https://kb.solsynth.dev" target="_blank" class="btn-text"> | ||||
|                 Learn more <span aria-hidden="true">→</span> | ||||
|             </a> | ||||
|         </div> | ||||
| <div class="hero min-h-full bg-base-200"> | ||||
|   <div class="hero-content text-center"> | ||||
|     <div class="max-w-md"> | ||||
|       <h1 class="text-5xl font-bold">Solar Network</h1> | ||||
|       <p class="py-6">This Solar Network instance is up and running.</p> | ||||
|       <a href="https://sn.solsynth.dev" target="_blank" class="btn btn-primary">Get started</a> | ||||
|       <div class="flex items-center justify-center gap-x-6 mt-6"> | ||||
|           <a href="/swagger" target="_blank" class="btn btn-ghost"> | ||||
|               <span aria-hidden="true">λ </span> API Docs | ||||
|           </a> | ||||
|           <a href="https://kb.solsynth.dev" target="_blank" class="btn btn-ghost"> | ||||
|               Learn more <span aria-hidden="true">→</span> | ||||
|           </a> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|   | ||||
| @@ -6,6 +6,5 @@ public class IndexModel : PageModel | ||||
| { | ||||
|     public void OnGet() | ||||
|     { | ||||
|         // Add any page initialization logic here | ||||
|     } | ||||
| }  | ||||
| @@ -5,34 +5,44 @@ | ||||
|     <meta charset="utf-8"/> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | ||||
|     <title>@ViewData["Title"]</title> | ||||
|     <link rel="preconnect" href="https://fonts.googleapis.com"> | ||||
|     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||||
|     <link | ||||
|         href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:wght@100..900&family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap" | ||||
|         rel="stylesheet"> | ||||
|     <link rel="stylesheet" href="~/css/styles.css" asp-append-version="true"/> | ||||
|     <link | ||||
|         href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" | ||||
|         rel="stylesheet" | ||||
|     /> | ||||
| </head> | ||||
| <body class="h-[calc(100dvh-118px)] mt-[64px] bg-white dark:bg-gray-900"> | ||||
| <header class="bg-white dark:bg-gray-800 shadow-sm fixed left-0 right-0 top-0 z-50"> | ||||
|     <nav class="container-default"> | ||||
|         <div class="flex justify-between h-16 items-center"> | ||||
|             <div class="flex"> | ||||
|                 <a href="/" class="text-xl font-bold text-gray-900 dark:text-white">Solar Network</a> | ||||
|             </div> | ||||
|             <div class="flex items-center ml-auto"> | ||||
|                 @if (Context.Request.Cookies.TryGetValue(AuthConstants.CookieTokenName, out _)) | ||||
|                 { | ||||
|                     <a href="/web/account/profile" class="text-gray-900 dark:text-white hover:text-gray-700 dark:hover:text-gray-300 px-3 py-2 rounded-md text-sm font-medium">Profile</a> | ||||
|                     <form method="post" asp-page="/Account/Profile" asp-page-handler="Logout" class="inline"> | ||||
|                         <button type="submit" class="text-gray-900 dark:text-white hover:text-gray-700 dark:hover:text-gray-300 px-3 py-2 rounded-md text-sm font-medium">Logout</button> | ||||
| <body class="h-full bg-base-200"> | ||||
| <header class="navbar bg-base-100/35 backdrop-blur-md shadow-xl fixed left-0 right-0 top-0 z-50 px-5"> | ||||
|     <div class="flex-1"> | ||||
|         <a class="btn btn-ghost text-xl">Solar Network</a> | ||||
|     </div> | ||||
|     <div class="flex-none"> | ||||
|         <ul class="menu menu-horizontal px-1"> | ||||
|             @if (Context.Request.Cookies.TryGetValue(AuthConstants.CookieTokenName, out _)) | ||||
|             { | ||||
|                 <li><a href="/web/account/profile">Profile</a></li> | ||||
|                 <li> | ||||
|                     <form method="post" asp-page="/Account/Profile" asp-page-handler="Logout"> | ||||
|                         <button type="submit">Logout</button> | ||||
|                     </form> | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     <a href="/web/auth/login" class="text-gray-900 dark:text-white hover:text-gray-700 dark:hover:text-gray-300 px-3 py-2 rounded-md text-sm font-medium">Login</a> | ||||
|                 } | ||||
|             </div> | ||||
|         </div> | ||||
|     </nav> | ||||
|                 </li> | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 <li> | ||||
|                     <a href="/web/auth/login"><span class="material-symbols-outlined">login</span></a> | ||||
|                 </li> | ||||
|             } | ||||
|         </ul> | ||||
|     </div> | ||||
| </header> | ||||
|  | ||||
| @* The header 64px *@ | ||||
| <main class="h-full"> | ||||
| <main class="h-full pt-16"> | ||||
|     @RenderBody() | ||||
| </main> | ||||
|  | ||||
|   | ||||
| @@ -6,96 +6,86 @@ | ||||
|     ViewData["Title"] = "Magic Spell"; | ||||
| } | ||||
|  | ||||
| <div class="h-full flex items-center justify-center"> | ||||
|     <div class="max-w-lg w-full mx-auto p-6"> | ||||
|         <div class="text-center"> | ||||
|             <h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-4">Magic Spell</h1> | ||||
| <div class="hero min-h-full bg-base-200"> | ||||
|     <div class="hero-content text-center"> | ||||
|         <div class="max-w-md"> | ||||
|             <h1 class="text-5xl font-bold mb-4">Magic Spell</h1> | ||||
|  | ||||
|             @if (Model.IsSuccess) | ||||
|             { | ||||
|                 <div class="p-4 bg-green-100 dark:bg-green-900 rounded-lg mb-6"> | ||||
|                     <p class="text-green-800 dark:text-green-200">The spell was applied successfully!</p> | ||||
|                     <p class="text-green-800 dark:text-green-200 opacity-80">Now you can close this page.</p> | ||||
|                 <div class="alert alert-success"> | ||||
|                     <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg> | ||||
|                     <span>The spell was applied successfully!</span> | ||||
|                     <p>Now you can close this page.</p> | ||||
|                 </div> | ||||
|             } | ||||
|             else if (Model.CurrentSpell == null) | ||||
|             { | ||||
|                 <div class="p-4 bg-yellow-100 dark:bg-yellow-900 rounded-lg"> | ||||
|                     <p class="text-yellow-800 dark:text-yellow-200">The spell was expired or does not exist.</p> | ||||
|                 <div class="alert alert-warning"> | ||||
|                     <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg> | ||||
|                     <span>The spell was expired or does not exist.</span> | ||||
|                 </div> | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 <div | ||||
|                     class="px-4 py-12 bg-white dark:bg-gray-800 text-gray-900 dark:text-white shadow-lg rounded-lg mb-6"> | ||||
|                     <div class="mb-2"> | ||||
|                         <p> | ||||
|                             <span class="font-medium">The spell is for </span> | ||||
|                             <span | ||||
|                                 class="font-bold">@System.Text.RegularExpressions.Regex.Replace(Model.CurrentSpell!.Type.ToString(), "([a-z])([A-Z])", "$1 $2")</span> | ||||
|                         </p> | ||||
|                         <p><span class="font-medium">for @@</span>@Model.CurrentSpell.Account?.Name</p> | ||||
|                     </div> | ||||
|                     <div class="text-sm opacity-80"> | ||||
|                         @if (Model.CurrentSpell.ExpiresAt.HasValue) | ||||
|                         { | ||||
|                             <p>Available until @Model.CurrentSpell.ExpiresAt.Value.ToDateTimeUtc().ToString("g")</p> | ||||
|                         } | ||||
|                         @if (Model.CurrentSpell.AffectedAt.HasValue) | ||||
|                         { | ||||
|                             <p>Available after @Model.CurrentSpell.AffectedAt.Value.ToDateTimeUtc().ToString("g")</p> | ||||
|                         } | ||||
|                     </div> | ||||
|                     <p class="text-sm opacity-80">Would you like to apply this spell?</p> | ||||
|                 </div> | ||||
|  | ||||
|                 <form method="post" class="mt-4"> | ||||
|                     <input type="hidden" asp-for="CurrentSpell!.Id"/> | ||||
|  | ||||
|                     @if (Model.CurrentSpell?.Type == MagicSpellType.AuthPasswordReset) | ||||
|                     { | ||||
|                         <div class="mb-4"> | ||||
|                             <label | ||||
|                                 asp-for="NewPassword" | ||||
|                                 class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" | ||||
|                             > | ||||
|                                 New Password | ||||
|                             </label> | ||||
|                             <input type="password" | ||||
|                                    asp-for="NewPassword" | ||||
|                                    required | ||||
|                                    minlength="8" | ||||
|                                    style="padding: 0.5rem 1rem" | ||||
|                                    placeholder="Your new password" | ||||
|                                    class="w-full border-2 border-gray-300 dark:border-gray-600 rounded-lg  | ||||
|                                           focus:ring-2 focus:ring-blue-400 | ||||
|                                           dark:text-white bg-gray-100 dark:bg-gray-800"/> | ||||
|                 <div class="card bg-base-100 shadow-xl"> | ||||
|                     <div class="card-body"> | ||||
|                         <h2 class="card-title"> | ||||
|                             @System.Text.RegularExpressions.Regex.Replace(Model.CurrentSpell!.Type.ToString(), "([a-z])([A-Z])", "$1 $2") | ||||
|                         </h2> | ||||
|                         <p>for @@ @Model.CurrentSpell.Account?.Name</p> | ||||
|                         <div class="text-sm opacity-80"> | ||||
|                             @if (Model.CurrentSpell.ExpiresAt.HasValue) | ||||
|                             { | ||||
|                                 <p>Available until @Model.CurrentSpell.ExpiresAt.Value.ToDateTimeUtc().ToString("g")</p> | ||||
|                             } | ||||
|                             @if (Model.CurrentSpell.AffectedAt.HasValue) | ||||
|                             { | ||||
|                                 <p>Available after @Model.CurrentSpell.AffectedAt.Value.ToDateTimeUtc().ToString("g")</p> | ||||
|                             } | ||||
|                         </div> | ||||
|                     } | ||||
|                         <p class="text-sm opacity-80">Would you like to apply this spell?</p> | ||||
|                          | ||||
|                         <form method="post" class="mt-4"> | ||||
|                             <input type="hidden" asp-for="CurrentSpell!.Id"/> | ||||
|  | ||||
|                     <button type="submit" | ||||
|                             class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors | ||||
|                                    transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-blue-400"> | ||||
|                         Apply | ||||
|                     </button> | ||||
|                 </form> | ||||
|                             @if (Model.CurrentSpell?.Type == MagicSpellType.AuthPasswordReset) | ||||
|                             { | ||||
|                                 <div class="form-control w-full max-w-xs"> | ||||
|                                     <label class="label" asp-for="NewPassword"> | ||||
|                                         <span class="label-text">New Password</span> | ||||
|                                     </label> | ||||
|                                     <input type="password" | ||||
|                                            asp-for="NewPassword" | ||||
|                                            required | ||||
|                                            minlength="8" | ||||
|                                            placeholder="Your new password" | ||||
|                                            class="input input-bordered w-full max-w-xs"/> | ||||
|                                 </div> | ||||
|                             } | ||||
|  | ||||
|                             <div class="card-actions justify-end mt-4"> | ||||
|                                 <button type="submit" class="btn btn-primary">Apply</button> | ||||
|                             </div> | ||||
|                         </form> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             } | ||||
|         </div> | ||||
|  | ||||
|         <div class="mt-8 text-center text-sm"> | ||||
|             <div class="font-semibold text-gray-700 dark:text-gray-300 mb-1">Solar Network</div> | ||||
|             <div class="text-gray-600 dark:text-gray-400"> | ||||
|                 <a href="https://solsynth.dev" class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors"> | ||||
|                     Solsynth LLC | ||||
|                 </a> | ||||
|                 © @DateTime.Now.Year | ||||
|                 <br/> | ||||
|                 Powered by | ||||
|                 <a href="https://github.com/Solsynth/DysonNetwork" | ||||
|                    class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors"> | ||||
|                     DysonNetwork.Sphere | ||||
|                 </a> | ||||
|              | ||||
|             <div class="mt-8 text-center text-sm"> | ||||
|                 <div class="font-semibold mb-1">Solar Network</div> | ||||
|                 <div class="text-base-content/70"> | ||||
|                     <a href="https://solsynth.dev" class="link link-hover"> | ||||
|                         Solsynth LLC | ||||
|                     </a> | ||||
|                     © @DateTime.Now.Year | ||||
|                     <br/> | ||||
|                     Powered by | ||||
|                     <a href="https://github.com/Solsynth/DysonNetwork" class="link link-hover"> | ||||
|                         DysonNetwork.Sphere | ||||
|                     </a> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| </div> | ||||
|   | ||||
| @@ -6,7 +6,8 @@ | ||||
|     "css:build": "npx @tailwindcss/cli -i ./wwwroot/css/site.css -o ./wwwroot/css/styles.css" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@tailwindcss/cli": "^4.1.7", | ||||
|     "@tailwindcss/postcss": "^4.1.7", | ||||
|     "@tailwindcss/cli": "^4.1.7" | ||||
|     "daisyui": "^5.0.46" | ||||
|   } | ||||
| } | ||||
| @@ -1,10 +1,88 @@ | ||||
| @import "tailwindcss"; | ||||
|  | ||||
| @plugin "daisyui"; | ||||
|  | ||||
| @layer theme, base, components, utilities; | ||||
|  | ||||
| @import "tailwindcss/theme.css" layer(theme); | ||||
| @import "tailwindcss/preflight.css" layer(base); | ||||
| @import "tailwindcss/utilities.css" layer(utilities); | ||||
|  | ||||
| @theme { | ||||
|     --font-sans: "Nunito", sans-serif; | ||||
|     --font-mono: "Noto Sans Mono", monospace; | ||||
| } | ||||
|  | ||||
| @plugin "daisyui/theme" { | ||||
|     name: "light"; | ||||
|     default: true; | ||||
|     prefersdark: false; | ||||
|     color-scheme: "light"; | ||||
|     --color-base-100: oklch(100% 0 0); | ||||
|     --color-base-200: oklch(98% 0 0); | ||||
|     --color-base-300: oklch(95% 0 0); | ||||
|     --color-base-content: oklch(21% 0.006 285.885); | ||||
|     --color-primary: oklch(62% 0.0873 281deg); | ||||
|     --color-primary-content: oklch(93% 0.034 272.788); | ||||
|     --color-secondary: oklch(62% 0.214 259.815); | ||||
|     --color-secondary-content: oklch(94% 0.028 342.258); | ||||
|     --color-accent: oklch(77% 0.152 181.912); | ||||
|     --color-accent-content: oklch(38% 0.063 188.416); | ||||
|     --color-neutral: oklch(14% 0.005 285.823); | ||||
|     --color-neutral-content: oklch(92% 0.004 286.32); | ||||
|     --color-info: oklch(82% 0.111 230.318); | ||||
|     --color-info-content: oklch(29% 0.066 243.157); | ||||
|     --color-success: oklch(79% 0.209 151.711); | ||||
|     --color-success-content: oklch(37% 0.077 168.94); | ||||
|     --color-warning: oklch(82% 0.189 84.429); | ||||
|     --color-warning-content: oklch(41% 0.112 45.904); | ||||
|     --color-error: oklch(71% 0.194 13.428); | ||||
|     --color-error-content: oklch(27% 0.105 12.094); | ||||
|     --radius-selector: 0.5rem; | ||||
|     --radius-field: 0.5rem; | ||||
|     --radius-box: 1rem; | ||||
|     --size-selector: 0.28125rem; | ||||
|     --size-field: 0.28125rem; | ||||
|     --border: 1px; | ||||
|     --depth: 1; | ||||
|     --noise: 1; | ||||
| } | ||||
|  | ||||
| @plugin "daisyui/theme" { | ||||
|     name: "dark"; | ||||
|     default: false; | ||||
|     prefersdark: true; | ||||
|     color-scheme: "dark"; | ||||
|     --color-base-100: oklch(0% 0 0); | ||||
|     --color-base-200: oklch(20% 0.016 285.938); | ||||
|     --color-base-300: oklch(25% 0.013 285.805); | ||||
|     --color-base-content: oklch(97.807% 0.029 256.847); | ||||
|     --color-primary: oklch(50% 0.0873 281deg); | ||||
|     --color-primary-content: oklch(96% 0.018 272.314); | ||||
|     --color-secondary: oklch(62% 0.214 259.815); | ||||
|     --color-secondary-content: oklch(94% 0.028 342.258); | ||||
|     --color-accent: oklch(77% 0.152 181.912); | ||||
|     --color-accent-content: oklch(38% 0.063 188.416); | ||||
|     --color-neutral: oklch(21% 0.006 285.885); | ||||
|     --color-neutral-content: oklch(92% 0.004 286.32); | ||||
|     --color-info: oklch(82% 0.111 230.318); | ||||
|     --color-info-content: oklch(29% 0.066 243.157); | ||||
|     --color-success: oklch(79% 0.209 151.711); | ||||
|     --color-success-content: oklch(37% 0.077 168.94); | ||||
|     --color-warning: oklch(82% 0.189 84.429); | ||||
|     --color-warning-content: oklch(41% 0.112 45.904); | ||||
|     --color-error: oklch(64% 0.246 16.439); | ||||
|     --color-error-content: oklch(27% 0.105 12.094); | ||||
|     --radius-selector: 0.5rem; | ||||
|     --radius-field: 0.5rem; | ||||
|     --radius-box: 1rem; | ||||
|     --size-selector: 0.28125rem; | ||||
|     --size-field: 0.28125rem; | ||||
|     --border: 1px; | ||||
|     --depth: 1; | ||||
|     --noise: 1; | ||||
| } | ||||
|  | ||||
| @layer base { | ||||
|     html, body { | ||||
|         padding: 0; | ||||
| @@ -12,6 +90,10 @@ | ||||
|         box-sizing: border-box; | ||||
|     } | ||||
|  | ||||
|     .material-symbols-outlined { | ||||
|         font-variation-settings: 'FILL' 1, 'wght' 700, 'GRAD' 0, 'opsz' 48; | ||||
|     } | ||||
|  | ||||
|     /* For Firefox. */ | ||||
|     * { | ||||
|         scrollbar-width: none; | ||||
| @@ -23,14 +105,6 @@ | ||||
|     } | ||||
| } | ||||
|  | ||||
| .btn-primary { | ||||
|     @apply px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors dark:bg-blue-600 dark:hover:bg-blue-700; | ||||
| } | ||||
|  | ||||
| .btn-text { | ||||
|     @apply text-sm font-semibold leading-6 text-gray-900 dark:text-gray-100 hover:text-gray-700 dark:hover:text-gray-300; | ||||
| } | ||||
|  | ||||
| .container-default { | ||||
|     @apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8; | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -70,6 +70,7 @@ | ||||
| 	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APutObjectArgs_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F6efe388c7585d5dd5587416a55298550b030c2a107edf45f988791297c3ffa_003FPutObjectArgs_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> | ||||
| 	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueryable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F42d8f09d6a294d00a6f49efc989927492fe00_003F4e_003F26d1ee34_003FQueryable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> | ||||
| 	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueryable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcbafb95b4df34952928f87356db00c8f2fe00_003F9b_003F8ba036bb_003FQueryable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> | ||||
| 	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARazorPage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F81d2924a2bbd4b0c864a1d23cbf5f0893d200_003F5f_003Fc110be1c_003FRazorPage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> | ||||
| 	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AResizeOptions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fef3339e864a448e2b1ec6fa7bbf4c6661fee00_003F48_003F0209e410_003FResizeOptions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> | ||||
| 	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AResourceManagerStringLocalizerFactory_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb62f365d06c44ad695ff75960cdf97a2a800_003Fe4_003Ff6ba93b7_003FResourceManagerStringLocalizerFactory_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> | ||||
| 	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARSA_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fee4f989f6b8042b59b2654fdc188e287243600_003F8b_003F44e5f855_003FRSA_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user