doc(Login): add microsoft login template (#6162)

* Add transitional login page and update navigation menu

* refactor: 重构模板名称

* refactor: 精简代码

* doc: 代码格式化

* refactor: 增加移动端适配

* doc: 更新打包内容

---------

Co-Authored-By: Ethan Lee <33386249+h2ls@users.noreply.github.com>
Co-authored-by: Argo Zhang <argo@live.ca>
This commit is contained in:
XEE LEE
2025-06-06 08:52:17 +08:00
committed by GitHub
parent 30110267d2
commit c3330247b3
4 changed files with 269 additions and 12 deletions

View File

@@ -80,6 +80,12 @@ public partial class TutorialsNavMenu
Template = CreateDownloadButtonComponent("template4", _template4),
Text = "Template 4",
Url = "tutorials/template4"
},
new()
{
Template = CreateDownloadButtonComponent("template5", _template5),
Text = "Template 5",
Url = "/tutorials/template5"
}
]
},
@@ -215,6 +221,14 @@ public partial class TutorialsNavMenu
.. _layoutFileList
];
private readonly string[] _template5 =
[
"Tutorials/LoginAndRegister/Template5.razor",
"Tutorials/LoginAndRegister/Template5.razor.css",
"../Layout/TutorialsLayout.razor",
"../Layout/TutorialsLayout.razor.css"
];
private readonly string[] _waterfallFileList =
[
"Tutorials/Waterfall.razor",

View File

@@ -0,0 +1,92 @@
@page "/tutorials/template5"
@layout TutorialsLayout
<HeadContent>
<style>
.main:has(.background-image) {
height: calc(100vh - 56px - 175px);
}
@@media (min-width: 768px) {
.main:has(.background-image) {
height: calc(100vh - 50px);
}
.login-box {
width: 350px;
}
}
</style>
</HeadContent>
<div class="background-image">
<div class="login-container">
<div class="login-box animate-fade-in">
<div class="header-row">
@if (isEmailEntered)
{
<button @onclick="GoBack" aria-label="返回" class="back-button">
<span>
<i class="fa-solid fa-arrow-left"></i>
</span>
</button>
}
<div class="logo-container">
<h1 class="blazor-text">BootstrapBlazor</h1>
</div>
</div>
@if (!isEmailEntered)
{
<h2></h2>
<p class="subtitle">使 BootstrapBlazor </p>
<BootstrapInput type="email" class="input" placeholder="电子邮件或电话号码" @bind-Value="email" />
<div class="error" hidden="@(!showEmailError)"></div>
<Button class="button" Color="Color.Primary" OnClick="OnEmailSubmit"></Button>
<div class="links">
<a href="#"></a>
</div>
<div class="small">
BootstrapBlazor<a href="/"></a>
</div>
}
else
{
<h2></h2>
<p class="email-display">@email</p>
<BootstrapInput type="password" class="input" placeholder="密码" @bind-Value="password" />
<div class="links">
<a href="#"></a>
</div>
<Button class="button" Color="Color.Primary"></Button>
<div class="links">
<a href="#"></a>
</div>
}
</div>
</div>
</div>
@code {
private bool isEmailEntered = false;
private string email = "";
private string password = "";
private bool showEmailError = false;
private void OnEmailSubmit()
{
if (string.IsNullOrWhiteSpace(email))
{
showEmailError = true;
}
else
{
showEmailError = false;
isEmailEntered = true;
}
}
private void GoBack()
{
isEmailEntered = false;
}
}

View File

@@ -0,0 +1,162 @@
.background-image {
background-image: url('https://logincdn.msauth.net/shared/5/js/../images/fluent_web_light_57fee22710b04cebe1d5.svg');
background-repeat: no-repeat;
background-size: cover;
background-position: center;
width: 100%;
height: 100%;
}
.login-container {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
.login-box {
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
width: auto;
font-family: "Segoe UI", sans-serif;
text-align: left;
position: relative;
box-sizing: content-box !important;
}
::deep .input {
width: 100%;
padding: 10px;
margin: 12px 0;
border: 1px solid #ccc;
border-radius: 4px;
}
.header-row {
display: flex;
align-items: center;
justify-content: center;
position: relative;
height: 40px;
margin-bottom: 20px;
}
.back-button {
position: absolute;
left: 0;
background: transparent;
border: none;
padding: 0;
cursor: pointer;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.blazor-text {
font-family: Arial, sans-serif;
font-size: 2rem;
font-weight: bold;
text-align: center;
background: linear-gradient(to right, #8e44ad, #e84393);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.logo-container {
margin: 0 auto;
}
.logo {
height: 28px;
}
::deep .button {
width: 100%;
padding: 10px;
background-color: #0078d4;
color: white;
border: none;
border-radius: 4px;
font-weight: bold;
margin-top: 10px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.button:hover {
background-color: #005a9e;
}
.links {
margin-top: 10px;
font-size: 14px;
}
.links a {
color: #0066cc;
text-decoration: none;
}
.links a:hover {
text-decoration: underline;
}
.small {
font-size: 12px;
color: #666;
margin-top: 10px;
}
.email-display {
font-size: 14px;
color: #333;
margin-bottom: 10px;
}
.error {
color: red;
font-size: 13px;
}
.lang-switch {
position: absolute;
top: 10px;
right: 10px;
}
.animate-fade-in {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
0% {
opacity: 0;
transform: translateY(20px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.animate-fade-out {
animation: fadeOut 0.5s ease-in-out forwards;
}
@keyframes fadeOut {
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(-20px);
}
}

View File

@@ -10,10 +10,8 @@ namespace BootstrapBlazor.Server.Components.Samples;
/// <summary>
/// AvatarUpload sample code
/// </summary>
public partial class UploadAvatars : IDisposable
public partial class UploadAvatars
{
private static readonly long MaxFileLength = 5 * 1024 * 1024;
private CancellationTokenSource? _token;
private readonly List<UploadFile> _previewFileList = [];
private readonly Person _foo = new();
private bool _isUploadButtonAtFirst;
@@ -47,15 +45,6 @@ public partial class UploadAvatars : IDisposable
return ToastService.Error(Localizer["UploadsValidateFormTitle"], Localizer["UploadsValidateFormInValidContent"]);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public void Dispose()
{
_token?.Cancel();
GC.SuppressFinalize(this);
}
private List<AttributeItem> GetAttributes() =>
[
new()