initial
This commit is contained in:
103
OnProfNext.Client/Layout/MainLayout.razor
Normal file
103
OnProfNext.Client/Layout/MainLayout.razor
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
@inherits LayoutComponentBase
|
||||||
|
|
||||||
|
<MudThemeProvider Theme="@_theme" IsDarkMode="_isDarkMode" />
|
||||||
|
<MudPopoverProvider />
|
||||||
|
<MudDialogProvider />
|
||||||
|
<MudSnackbarProvider />
|
||||||
|
<MudLayout>
|
||||||
|
<MudAppBar Elevation="1">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())" />
|
||||||
|
<MudText Typo="Typo.h5" Class="ml-3">Application</MudText>
|
||||||
|
<MudSpacer />
|
||||||
|
<MudIconButton Icon="@(DarkLightModeButtonIcon)" Color="Color.Inherit" OnClick="@DarkModeToggle" />
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.MoreVert" Color="Color.Inherit" Edge="Edge.End" />
|
||||||
|
</MudAppBar>
|
||||||
|
<MudDrawer id="nav-drawer" @bind-Open="_drawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2">
|
||||||
|
<NavMenu />
|
||||||
|
</MudDrawer>
|
||||||
|
<MudMainContent Class="pt-16 pa-4">
|
||||||
|
@Body
|
||||||
|
</MudMainContent>
|
||||||
|
</MudLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="blazor-error-ui" data-nosnippet>
|
||||||
|
An unhandled error has occurred.
|
||||||
|
<a href="." class="reload">Reload</a>
|
||||||
|
<span class="dismiss">🗙</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private bool _drawerOpen = true;
|
||||||
|
private bool _isDarkMode = true;
|
||||||
|
private MudTheme? _theme = null;
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
base.OnInitialized();
|
||||||
|
|
||||||
|
_theme = new()
|
||||||
|
{
|
||||||
|
PaletteLight = _lightPalette,
|
||||||
|
PaletteDark = _darkPalette,
|
||||||
|
LayoutProperties = new LayoutProperties()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawerToggle()
|
||||||
|
{
|
||||||
|
_drawerOpen = !_drawerOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DarkModeToggle()
|
||||||
|
{
|
||||||
|
_isDarkMode = !_isDarkMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly PaletteLight _lightPalette = new()
|
||||||
|
{
|
||||||
|
Black = "#110e2d",
|
||||||
|
AppbarText = "#424242",
|
||||||
|
AppbarBackground = "rgba(255,255,255,0.8)",
|
||||||
|
DrawerBackground = "#ffffff",
|
||||||
|
GrayLight = "#e8e8e8",
|
||||||
|
GrayLighter = "#f9f9f9",
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly PaletteDark _darkPalette = new()
|
||||||
|
{
|
||||||
|
Primary = "#7e6fff",
|
||||||
|
Surface = "#1e1e2d",
|
||||||
|
Background = "#1a1a27",
|
||||||
|
BackgroundGray = "#151521",
|
||||||
|
AppbarText = "#92929f",
|
||||||
|
AppbarBackground = "rgba(26,26,39,0.8)",
|
||||||
|
DrawerBackground = "#1a1a27",
|
||||||
|
ActionDefault = "#74718e",
|
||||||
|
ActionDisabled = "#9999994d",
|
||||||
|
ActionDisabledBackground = "#605f6d4d",
|
||||||
|
TextPrimary = "#b2b0bf",
|
||||||
|
TextSecondary = "#92929f",
|
||||||
|
TextDisabled = "#ffffff33",
|
||||||
|
DrawerIcon = "#92929f",
|
||||||
|
DrawerText = "#92929f",
|
||||||
|
GrayLight = "#2a2833",
|
||||||
|
GrayLighter = "#1e1e2d",
|
||||||
|
Info = "#4a86ff",
|
||||||
|
Success = "#3dcb6c",
|
||||||
|
Warning = "#ffb545",
|
||||||
|
Error = "#ff3f5f",
|
||||||
|
LinesDefault = "#33323e",
|
||||||
|
TableLines = "#33323e",
|
||||||
|
Divider = "#292838",
|
||||||
|
OverlayLight = "#1e1e2d80",
|
||||||
|
};
|
||||||
|
|
||||||
|
public string DarkLightModeButtonIcon => _isDarkMode switch
|
||||||
|
{
|
||||||
|
true => Icons.Material.Rounded.AutoMode,
|
||||||
|
false => Icons.Material.Outlined.DarkMode,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
10
OnProfNext.Client/Layout/NavMenu.razor
Normal file
10
OnProfNext.Client/Layout/NavMenu.razor
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
<MudNavMenu>
|
||||||
|
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Home</MudNavLink>
|
||||||
|
<MudNavLink Href="counter" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Add">Counter</MudNavLink>
|
||||||
|
|
||||||
|
<MudNavLink Href="weather" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.List">Weather</MudNavLink>
|
||||||
|
|
||||||
|
</MudNavMenu>
|
||||||
|
|
||||||
|
|
||||||
48
OnProfNext.Client/Layout/ReconnectModal.razor
Normal file
48
OnProfNext.Client/Layout/ReconnectModal.razor
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<script type="module" src="@Assets["Layout/ReconnectModal.razor.js"]"></script>
|
||||||
|
|
||||||
|
<dialog id="components-reconnect-modal" data-nosnippet>
|
||||||
|
<div class="components-reconnect-backdrop">
|
||||||
|
<section class="components-reconnect-surface" aria-live="assertive" aria-atomic="true">
|
||||||
|
<header class="components-reconnect-header">
|
||||||
|
<span class="components-reconnect-status-dot" aria-hidden="true"></span>
|
||||||
|
<h2>Connection Interrupted</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<p class="components-reconnect-supporting">
|
||||||
|
Your current session is still open. We'll keep trying to restore it.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="components-rejoin-loader components-reconnect-first-attempt-visible components-reconnect-repeated-attempt-visible" aria-hidden="true">
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="components-reconnect-first-attempt-visible components-reconnect-message">
|
||||||
|
Rejoining the server...
|
||||||
|
</p>
|
||||||
|
<p class="components-reconnect-repeated-attempt-visible components-reconnect-message">
|
||||||
|
Rejoin failed. Trying again in <span id="components-seconds-to-next-attempt"></span>s.
|
||||||
|
</p>
|
||||||
|
<p class="components-reconnect-failed-visible components-reconnect-message components-reconnect-danger">
|
||||||
|
Failed to rejoin. Retry now or reload the page.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="components-pause-visible components-reconnect-message">
|
||||||
|
The session has been paused by the server.
|
||||||
|
</p>
|
||||||
|
<p class="components-resume-failed-visible components-reconnect-message components-reconnect-danger">
|
||||||
|
Failed to resume the session. Retry now or reload the page.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="components-reconnect-actions">
|
||||||
|
<button id="components-reconnect-button" class="components-reconnect-failed-visible" type="button">
|
||||||
|
Retry
|
||||||
|
</button>
|
||||||
|
<button id="components-resume-button" class="components-pause-visible components-resume-failed-visible" type="button">
|
||||||
|
Resume
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
220
OnProfNext.Client/Layout/ReconnectModal.razor.css
Normal file
220
OnProfNext.Client/Layout/ReconnectModal.razor.css
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
#components-reconnect-modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1400;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#components-reconnect-modal::backdrop {
|
||||||
|
background: rgba(10, 16, 28, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#components-reconnect-modal.components-reconnect-show,
|
||||||
|
#components-reconnect-modal[open],
|
||||||
|
#components-reconnect-modal.components-reconnect-failed,
|
||||||
|
#components-reconnect-modal.components-reconnect-repeated-attempt,
|
||||||
|
#components-reconnect-modal.components-reconnect-paused,
|
||||||
|
#components-reconnect-modal.components-reconnect-resume-failed,
|
||||||
|
#components-reconnect-modal.components-pause,
|
||||||
|
#components-reconnect-modal.components-resume-failed {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 24px;
|
||||||
|
background: radial-gradient(90% 60% at 80% 0%, color-mix(in srgb, var(--mud-palette-primary, #594AE2) 12%, transparent), transparent 60%), radial-gradient(80% 55% at 0% 100%, color-mix(in srgb, var(--mud-palette-info, #2196f3) 16%, transparent), transparent 62%), rgba(8, 12, 20, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-surface {
|
||||||
|
width: min(480px, 100%);
|
||||||
|
border-radius: var(--mud-default-borderradius, 12px);
|
||||||
|
border: 1px solid color-mix(in srgb, var(--mud-palette-lines-default, #e0e0e0) 70%, transparent);
|
||||||
|
background: var(--mud-palette-surface, #fff);
|
||||||
|
box-shadow: var(--mud-elevation-24, 0 16px 30px rgba(0, 0, 0, 0.28));
|
||||||
|
color: var(--mud-palette-text-primary, #1f2937);
|
||||||
|
padding: 20px 20px 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-header h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-status-dot {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--mud-palette-warning, #f59e0b);
|
||||||
|
box-shadow: 0 0 0 6px color-mix(in srgb, var(--mud-palette-warning, #f59e0b) 25%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-supporting,
|
||||||
|
.components-reconnect-message {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.45;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-supporting {
|
||||||
|
color: var(--mud-palette-text-secondary, #52607a);
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-message {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-danger {
|
||||||
|
color: var(--mud-palette-error, #b00020);
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-actions {
|
||||||
|
margin-top: 14px;
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-first-attempt-visible,
|
||||||
|
.components-reconnect-repeated-attempt-visible,
|
||||||
|
.components-reconnect-failed-visible,
|
||||||
|
.components-pause-visible,
|
||||||
|
.components-resume-failed-visible {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open].components-reconnect-show .components-reconnect-first-attempt-visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open].components-reconnect-show .components-rejoin-loader {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open].components-reconnect-failed .components-reconnect-failed-visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open].components-reconnect-failed #components-reconnect-button {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open].components-reconnect-repeated-attempt .components-reconnect-repeated-attempt-visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open].components-reconnect-repeated-attempt .components-rejoin-loader {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open].components-reconnect-paused .components-pause-visible,
|
||||||
|
dialog[open].components-pause .components-pause-visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open].components-reconnect-paused #components-resume-button,
|
||||||
|
dialog[open].components-pause #components-resume-button,
|
||||||
|
dialog[open].components-reconnect-resume-failed #components-resume-button,
|
||||||
|
dialog[open].components-resume-failed #components-resume-button {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open].components-reconnect-resume-failed .components-resume-failed-visible,
|
||||||
|
dialog[open].components-resume-failed .components-resume-failed-visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-rejoin-loader {
|
||||||
|
display: none;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-rejoin-loader div {
|
||||||
|
width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: var(--mud-palette-primary, #594AE2);
|
||||||
|
animation: reconnect-pulse 1.2s infinite ease-in-out both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-rejoin-loader div:nth-child(1) {
|
||||||
|
animation-delay: -0.24s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-rejoin-loader div:nth-child(2) {
|
||||||
|
animation-delay: -0.12s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes reconnect-pulse {
|
||||||
|
0%, 80%, 100% {
|
||||||
|
transform: scale(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
40% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#components-reconnect-button,
|
||||||
|
#components-resume-button {
|
||||||
|
display: none;
|
||||||
|
min-width: 92px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: var(--mud-palette-primary, #594AE2);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.2;
|
||||||
|
transition: filter 140ms ease, transform 140ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#components-reconnect-button:hover,
|
||||||
|
#components-resume-button:hover {
|
||||||
|
filter: brightness(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
#components-reconnect-button:active,
|
||||||
|
#components-resume-button:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.components-reconnect-backdrop {
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-reconnect-surface {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
69
OnProfNext.Client/Layout/ReconnectModal.razor.js
Normal file
69
OnProfNext.Client/Layout/ReconnectModal.razor.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// Set up event handlers
|
||||||
|
const reconnectModal = document.getElementById("components-reconnect-modal");
|
||||||
|
reconnectModal.addEventListener("components-reconnect-state-changed", handleReconnectStateChanged);
|
||||||
|
|
||||||
|
const retryButton = document.getElementById("components-reconnect-button");
|
||||||
|
retryButton.addEventListener("click", retry);
|
||||||
|
|
||||||
|
const resumeButton = document.getElementById("components-resume-button");
|
||||||
|
resumeButton.addEventListener("click", resume);
|
||||||
|
|
||||||
|
function handleReconnectStateChanged(event) {
|
||||||
|
if (event.detail.state === "show") {
|
||||||
|
reconnectModal.showModal();
|
||||||
|
} else if (event.detail.state === "hide") {
|
||||||
|
reconnectModal.close();
|
||||||
|
} else if (event.detail.state === "failed") {
|
||||||
|
document.addEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
|
||||||
|
} else if (event.detail.state === "rejected") {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function retry() {
|
||||||
|
document.removeEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Reconnect will asynchronously return:
|
||||||
|
// - true to mean success
|
||||||
|
// - false to mean we reached the server, but it rejected the connection (e.g., unknown circuit ID)
|
||||||
|
// - exception to mean we didn't reach the server (this can be sync or async)
|
||||||
|
const successful = await Blazor.reconnect();
|
||||||
|
if (!successful) {
|
||||||
|
// We have been able to reach the server, but the circuit is no longer available.
|
||||||
|
// We'll reload the page so the user can continue using the app as quickly as possible.
|
||||||
|
const resumeSuccessful = await Blazor.resumeCircuit();
|
||||||
|
if (!resumeSuccessful) {
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
reconnectModal.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// We got an exception, server is currently unavailable
|
||||||
|
document.addEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resume() {
|
||||||
|
try {
|
||||||
|
const successful = await Blazor.resumeCircuit();
|
||||||
|
if (!successful) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
if (reconnectModal.classList.contains("components-reconnect-paused")) {
|
||||||
|
reconnectModal.classList.replace("components-reconnect-paused", "components-reconnect-resume-failed");
|
||||||
|
} else if (reconnectModal.classList.contains("components-pause")) {
|
||||||
|
reconnectModal.classList.replace("components-pause", "components-resume-failed");
|
||||||
|
} else {
|
||||||
|
reconnectModal.classList.add("components-reconnect-resume-failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function retryWhenDocumentBecomesVisible() {
|
||||||
|
if (document.visibilityState === "visible") {
|
||||||
|
await retry();
|
||||||
|
}
|
||||||
|
}
|
||||||
17
OnProfNext.Client/OnProfNext.Client.csproj
Normal file
17
OnProfNext.Client/OnProfNext.Client.csproj
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
|
||||||
|
<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
|
||||||
|
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.*" />
|
||||||
|
<PackageReference Include="MudBlazor" Version="9.*" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
19
OnProfNext.Client/Pages/Counter.razor
Normal file
19
OnProfNext.Client/Pages/Counter.razor
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
@page "/counter"
|
||||||
|
|
||||||
|
|
||||||
|
<PageTitle>Counter</PageTitle>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h3" GutterBottom="true">Counter</MudText>
|
||||||
|
|
||||||
|
<MudText Class="mb-4">Current count: @currentCount</MudText>
|
||||||
|
|
||||||
|
<MudButton Color="Color.Primary" Variant="Variant.Filled" @onclick="IncrementCount">Click me</MudButton>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private int currentCount = 0;
|
||||||
|
|
||||||
|
private void IncrementCount()
|
||||||
|
{
|
||||||
|
currentCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
59
OnProfNext.Client/Pages/Home.razor
Normal file
59
OnProfNext.Client/Pages/Home.razor
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
@page "/"
|
||||||
|
|
||||||
|
<PageTitle>Home</PageTitle>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h3" GutterBottom="true">Hello, world!</MudText>
|
||||||
|
<MudText Class="mb-8">Welcome to your new app, powered by MudBlazor and the .NET 10 Template!</MudText>
|
||||||
|
|
||||||
|
<MudAlert Severity="Severity.Normal" ContentAlignment="HorizontalAlignment.Start">
|
||||||
|
You can find documentation and examples on our website here:
|
||||||
|
<MudLink Href="https://mudblazor.com" Target="_blank" Typo="Typo.body2" Color="Color.Primary">
|
||||||
|
<b>www.mudblazor.com</b>
|
||||||
|
</MudLink>
|
||||||
|
</MudAlert>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<MudText Typo="Typo.h5" GutterBottom="true">Interactivity in this Template</MudText>
|
||||||
|
<br />
|
||||||
|
<MudText Typo="Typo.body2">
|
||||||
|
When you opt for the "Global" Interactivity Location, <br />
|
||||||
|
the render modes are defined in App.razor and consequently apply to all child components.<br />
|
||||||
|
In this case, providers are globally set in the MainLayout.<br />
|
||||||
|
<br />
|
||||||
|
On the other hand, if you choose the "Per page/component" Interactivity Location,<br />
|
||||||
|
it is necessary to include the <br />
|
||||||
|
<br />
|
||||||
|
<MudPopoverProvider /> <br />
|
||||||
|
<MudDialogProvider /> <br />
|
||||||
|
<MudSnackbarProvider /> <br />
|
||||||
|
<br />
|
||||||
|
components on every interactive page.<br />
|
||||||
|
<br />
|
||||||
|
If a render mode is not specified for a page, it defaults to Server-Side Rendering (SSR),<br />
|
||||||
|
similar to this page. While MudBlazor allows pages to be rendered in SSR,<br />
|
||||||
|
please note that interactive features, such as buttons and dropdown menus, will not be functional.
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<MudText Typo="Typo.h5" GutterBottom="true">What's New in Blazor with the Release of .NET 10</MudText>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h6" GutterBottom="true">Prerendering</MudText>
|
||||||
|
<MudText Typo="Typo.body2" GutterBottom="true">
|
||||||
|
If you're exploring the features of .NET 10 Blazor,<br /> you might be pleasantly surprised to learn that each page is prerendered on the server,<br /> regardless of the selected render mode.<br /><br />
|
||||||
|
This means that you'll need to inject all necessary services on the server,<br /> even when opting for the wasm (WebAssembly) render mode.<br /><br />
|
||||||
|
This prerendering functionality is crucial to ensuring that WebAssembly mode feels fast and responsive,<br /> especially when it comes to initial page load times.<br /><br />
|
||||||
|
For more information on how to detect prerendering and leverage the RenderContext, you can refer to the following link:
|
||||||
|
<MudLink Href="https://github.com/dotnet/aspnetcore/issues/51468#issuecomment-1783568121" Target="_blank" Typo="Typo.body2" Color="Color.Primary">
|
||||||
|
More details
|
||||||
|
</MudLink>
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<MudText Typo="Typo.h6" GutterBottom="true">InteractiveAuto</MudText>
|
||||||
|
<MudText Typo="Typo.body2">
|
||||||
|
A discussion on how to achieve this can be found here:
|
||||||
|
<MudLink Href="https://github.com/dotnet/aspnetcore/issues/51468#issue-1950424116" Target="_blank" Typo="Typo.body2" Color="Color.Primary">
|
||||||
|
More details
|
||||||
|
</MudLink>
|
||||||
|
</MudText>
|
||||||
9
OnProfNext.Client/Pages/NotFound.razor
Normal file
9
OnProfNext.Client/Pages/NotFound.razor
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
@page "/not-found"
|
||||||
|
@layout Layout.MainLayout
|
||||||
|
|
||||||
|
<PageTitle>Not Found</PageTitle>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h3" GutterBottom="true">404 - Page Not Found</MudText>
|
||||||
|
<MudText Class="mb-8">Sorry, the content you are looking for does not exist.</MudText>
|
||||||
|
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Primary" Href="/">Go to Home</MudButton>
|
||||||
63
OnProfNext.Client/Pages/Weather.razor
Normal file
63
OnProfNext.Client/Pages/Weather.razor
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
@page "/weather"
|
||||||
|
|
||||||
|
|
||||||
|
<PageTitle>Weather</PageTitle>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h3" GutterBottom="true">Weather forecast</MudText>
|
||||||
|
<MudText Typo="Typo.body1" Class="mb-8">This component demonstrates fetching data from the server.</MudText>
|
||||||
|
|
||||||
|
@if (Forecasts == null)
|
||||||
|
{
|
||||||
|
<MudProgressCircular Color="Color.Default" Indeterminate="true" />
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudTable Items="Forecasts" Hover="true" SortLabel="Sort By" Elevation="0" AllowUnsorted="false">
|
||||||
|
<HeaderContent>
|
||||||
|
<MudTh><MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<WeatherForecast, object>(x=>x.Date)">Date</MudTableSortLabel></MudTh>
|
||||||
|
<MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.TemperatureC)">Temp. (C)</MudTableSortLabel></MudTh>
|
||||||
|
<MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.TemperatureF)">Temp. (F)</MudTableSortLabel></MudTh>
|
||||||
|
<MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.Summary!)">Summary</MudTableSortLabel></MudTh>
|
||||||
|
</HeaderContent>
|
||||||
|
<RowTemplate>
|
||||||
|
<MudTd DataLabel="Date">@context.Date</MudTd>
|
||||||
|
<MudTd DataLabel="Temp. (C)">@context.TemperatureC</MudTd>
|
||||||
|
<MudTd DataLabel="Temp. (F)">@context.TemperatureF</MudTd>
|
||||||
|
<MudTd DataLabel="Summary">@context.Summary</MudTd>
|
||||||
|
</RowTemplate>
|
||||||
|
<PagerContent>
|
||||||
|
<MudTablePager PageSizeOptions="new int[]{50, 100}" />
|
||||||
|
</PagerContent>
|
||||||
|
</MudTable>
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[PersistentState(AllowUpdates = true)]
|
||||||
|
public WeatherForecast[]? Forecasts { get; set; }
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
if (Forecasts is null)
|
||||||
|
{
|
||||||
|
// Simulate asynchronous loading to demonstrate a loading indicator
|
||||||
|
await Task.Delay(500);
|
||||||
|
|
||||||
|
var startDate = DateOnly.FromDateTime(DateTime.Now);
|
||||||
|
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
|
||||||
|
Forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||||
|
{
|
||||||
|
Date = startDate.AddDays(index),
|
||||||
|
TemperatureC = Random.Shared.Next(-20, 55),
|
||||||
|
Summary = summaries[Random.Shared.Next(summaries.Length)]
|
||||||
|
}).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WeatherForecast
|
||||||
|
{
|
||||||
|
public DateOnly Date { get; set; }
|
||||||
|
public int TemperatureC { get; set; }
|
||||||
|
public string? Summary { get; set; }
|
||||||
|
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||||
|
}
|
||||||
|
}
|
||||||
8
OnProfNext.Client/Program.cs
Normal file
8
OnProfNext.Client/Program.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
|
using MudBlazor.Services;
|
||||||
|
|
||||||
|
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||||
|
|
||||||
|
builder.Services.AddMudServices();
|
||||||
|
|
||||||
|
await builder.Build().RunAsync();
|
||||||
6
OnProfNext.Client/Routes.razor
Normal file
6
OnProfNext.Client/Routes.razor
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<Router AppAssembly="typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
|
||||||
|
<Found Context="routeData">
|
||||||
|
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
|
||||||
|
<FocusOnNavigate RouteData="routeData" Selector="h1" />
|
||||||
|
</Found>
|
||||||
|
</Router>
|
||||||
11
OnProfNext.Client/_Imports.razor
Normal file
11
OnProfNext.Client/_Imports.razor
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
@using System.Net.Http
|
||||||
|
@using System.Net.Http.Json
|
||||||
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
|
@using Microsoft.AspNetCore.Components.Routing
|
||||||
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
|
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||||
|
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||||
|
@using Microsoft.JSInterop
|
||||||
|
@using MudBlazor
|
||||||
|
@using MudBlazor.Services
|
||||||
|
@using OnProfNext.Client.Layout
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/Microsoft.CSharp.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/Microsoft.CSharp.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/Microsoft.JSInterop.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/Microsoft.JSInterop.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/Microsoft.VisualBasic.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/Microsoft.VisualBasic.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/Microsoft.Win32.Registry.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/Microsoft.Win32.Registry.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/MudBlazor.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/MudBlazor.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/OnProfNext.Client.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/OnProfNext.Client.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/OnProfNext.Client.pdb
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/OnProfNext.Client.pdb
Normal file
Binary file not shown.
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net10.0",
|
||||||
|
"includedFrameworks": [
|
||||||
|
{
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "10.0.5"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"wasmHostProperties": {
|
||||||
|
"perHostConfig": [
|
||||||
|
{
|
||||||
|
"name": "browser",
|
||||||
|
"host": "browser"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"configProperties": {
|
||||||
|
"Microsoft.AspNetCore.Components.Routing.RegexConstraintSupport": false,
|
||||||
|
"Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true,
|
||||||
|
"System.ComponentModel.DefaultValueAttribute.IsSupported": false,
|
||||||
|
"System.ComponentModel.Design.IDesignerHost.IsSupported": false,
|
||||||
|
"System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization": false,
|
||||||
|
"System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported": false,
|
||||||
|
"System.Data.DataSet.XmlSerializationIsSupported": false,
|
||||||
|
"System.Diagnostics.Metrics.Meter.IsSupported": false,
|
||||||
|
"System.Diagnostics.Tracing.EventSource.IsSupported": false,
|
||||||
|
"System.GC.Server": true,
|
||||||
|
"System.Globalization.Invariant": false,
|
||||||
|
"System.TimeZoneInfo.Invariant": false,
|
||||||
|
"System.Linq.Enumerable.IsSizeOptimized": true,
|
||||||
|
"System.Net.Http.EnableActivityPropagation": false,
|
||||||
|
"System.Net.Http.WasmEnableStreamingResponse": true,
|
||||||
|
"System.Net.SocketsHttpHandler.Http3Support": false,
|
||||||
|
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
|
||||||
|
"System.Resources.ResourceManager.AllowCustomResourceTypes": false,
|
||||||
|
"System.Resources.UseSystemResourceKeys": true,
|
||||||
|
"System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported": true,
|
||||||
|
"System.Runtime.InteropServices.BuiltInComInterop.IsSupported": false,
|
||||||
|
"System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting": false,
|
||||||
|
"System.Runtime.InteropServices.EnableCppCLIHostActivation": false,
|
||||||
|
"System.Runtime.InteropServices.Marshalling.EnableGeneratedComInterfaceComImportInterop": false,
|
||||||
|
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
|
||||||
|
"System.StartupHookProvider.IsSupported": false,
|
||||||
|
"System.Text.Encoding.EnableUnsafeUTF7Encoding": false,
|
||||||
|
"System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault": true,
|
||||||
|
"System.Threading.Thread.EnableAutoreleasePool": false,
|
||||||
|
"Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
OnProfNext.Client/bin/Debug/net10.0/System.AppContext.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.AppContext.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Buffers.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Buffers.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Collections.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Collections.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.ComponentModel.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.ComponentModel.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Configuration.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Configuration.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Console.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Console.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Core.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Core.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Data.Common.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Data.Common.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Data.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Data.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Diagnostics.Debug.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Diagnostics.Debug.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Diagnostics.Tools.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Diagnostics.Tools.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Drawing.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Drawing.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Dynamic.Runtime.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Dynamic.Runtime.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Formats.Asn1.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Formats.Asn1.dll
Normal file
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Formats.Tar.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Formats.Tar.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Globalization.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.Globalization.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.IO.Compression.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.IO.Compression.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OnProfNext.Client/bin/Debug/net10.0/System.IO.FileSystem.dll
Normal file
BIN
OnProfNext.Client/bin/Debug/net10.0/System.IO.FileSystem.dll
Normal file
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user