Initial commit

This commit is contained in:
2022-03-28 18:44:08 -04:00
commit e43d9a90e7
267 changed files with 17049 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.28.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.0.0-preview.2.22153.2" />
</ItemGroup>
<ItemGroup>
<Folder Include="Inputs\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\Services\Services.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="Inputs\" />
</ItemGroup>
</Project>
+10
View File
@@ -0,0 +1,10 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
@@ -0,0 +1,4 @@
.entityDialogBackground {
}
+27
View File
@@ -0,0 +1,27 @@
<div class="code">
@ChildContent
</div>
<style>
.code {
font-family: monospace;
border: 2px solid white;
color: white;
padding: 8px;
background-color: black;
white-space: pre;
overflow-x: scroll;
}
.code::-webkit-scrollbar {
height: 0;
background: transparent;
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
+72
View File
@@ -0,0 +1,72 @@
@if (IsOnDev) {
<div class="devOnlyContainer">
<div class="devOnlyTitleContainer">
<div class="devOnlyTitle">
DevOnly UI
</div>
</div>
<div class="devOnlyContentContainer">
<div class="devOnlyContent">
@ChildContent
</div>
</div>
</div>
<style>
.devOnlyContainer {
display: flex;
flex-direction: column;
}
.devOnlyTitle {
background-color: rgba(20,20,20,0.75);
padding: 10px;
color: orange;
font-weight: bolder;
font-size: 1.5rem;
}
.devOnlyContent {
background-color: rgba(20,20,20,0.75);
width: 100%;
padding: 10px;
}
.devOnlyTitleContainer {
background: repeating-linear-gradient( 45deg, blue, blue 50px, orange 51px, orange 100px);
margin-right: auto;
padding: 10px;
border-left: 6px dashed orange;
border-right: 6px dashed orange;
border-top: 6px dashed orange;
text-shadow: 4px 4px 1px blue;
}
.devOnlyContentContainer {
border: 6px dashed orange;
background: repeating-linear-gradient( 45deg, blue, blue 50px, orange 51px, orange 100px);
box-shadow: 5px 5px 5px blue;
padding: 20px;
}
</style>
}
@code {
[Inject]
NavigationManager NavigationManager { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
bool IsOnDev;
protected override void OnInitialized() {
IsOnDev = NavigationManager.BaseUri.Contains("https://localhost");
}
}
@@ -0,0 +1,78 @@
<div class="entityDisplaySection">
<div class="entityDisplayHeader">
<div class="entityDisplayTitle">
@Title
</div>
<div class="entityDisplayBorder">
</div>
</div>
@ChildContent
</div>
<style>
.entityDisplaySection {
position: relative;
padding: 8px;
display: flex;
gap: 12px;
flex-direction: column;
margin-top: 14px;
margin-top: 20px;
padding: 12px;
background-color: var(--info);
border-top-right-radius: 12px;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
.entityDisplayHeader {
bottom: 100%;
position: absolute;
white-space: pre;
width: 100%;
line-height: 0px;
right: 0px;
top: -4px;
display: flex;
}
.entityDisplayTitle {
font-weight: 800;
font-size: 1.4rem;
padding-right: 8px;
text-shadow: 3px 0 0 var(--info), -3px 0 0 var(--info), 0 3px 0 var(--info), 0 -3px 0 var(--info), 2px 2px var(--info), -2px -2px 0 var(--info), 2px -2px 0 var(--info), -2px 2px 0 var(--info);
}
@@media only screen and (max-width: 1025px) {
.entityDisplayHeader {
position: inherit;
width: 100%;
margin: 0px;
}
.entityDisplaySection {
position: inherit;
width: 100%;
margin: 0px;
max-width: none;
border-top-right-radius: 0px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
}
.entityDisplayTitle {
position: inherit;
margin: 0px;
}
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public string Title { get; set; }
}
@@ -0,0 +1,66 @@
<div class="tooltipWrapper">
<div class="tooltipContent">
@((MarkupString)InfoText)
</div>
@ChildContent
</div>
<style>
.tooltipWrapper {
position: relative;
display: inline-block;
width: 100%;
}
.tooltipContent {
visibility: hidden;
position: absolute;
width: 520px;
max-width: 93vw;
bottom: 100%;
margin-top: 60px;
margin-left: -60px;
margin-bottom: 36px;
background-color: #363636;
color: #fff;
border-radius: 6px;
padding-left: 20px;
padding-right: 20px;
padding-bottom: 20px;
padding-top: 20px;
border: 2px solid black;
white-space: break-spaces;
z-index: 2147483647;
}
.tooltipWrapper:hover .tooltipContent {
visibility: visible;
}
@@media only screen and (max-width: 1025px) {
.tooltipContent {
margin: auto;
margin-bottom: 20px;
position: absolute;
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public string InfoText { get; set; }
[Parameter]
public int? Margin { get; set; }
}
+116
View File
@@ -0,0 +1,116 @@
<div class="makingOfContainer">
<div class="makingInfo">
<div class="makingTitle">@Title</div>
<div class="makingDescription">@Description</div>
</div>
<div class="makingofGrid">
<div class="makingofItem">
<details open>
<summary>Example</summary>
<div class="shownCode">
@Example
</div>
</details>
</div>
<div class="makingofItem">
<details open>
<summary>Usage</summary>
<div class="shownCode">
@Usage
</div>
</details>
</div>
<div class="makingofItem">
<details open>
<summary>Code</summary>
<div class="shownCode">
@Code
</div>
</details>
</div>
</div>
</div>
<style>
.makingInfo {
margin-top: 6px;
margin-bottom: 12px;
}
.makingTitle {
font-weight: bolder;
font-size: 1.4rem;
}
.makingOfContainer {
display: flex;
flex-direction: column;
gap: 6px;
}
.makingofGrid {
display: flex;
flex-wrap: wrap;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
}
.makingofItem {
width: 100%;
}
.makingOfContainer details {
border: 2px dashed black;
border-radius: 4px;
}
.makingOfContainer summary {
font-weight: bold;
padding: 12px;
background-color: rgba(0,0,0, 0.1);
}
.shownCode {
visibility: hidden;
padding: 12px;
background-color: rgba(0,0,0, 0.1);
}
.makingOfContainer details[open] .shownCode {
visibility: visible;
}
.makingOfContainer details[open] summary {
border-bottom: 2px dashed black;
}
@@media only screen and (max-width: 1025px) {
.makingofGrid {
display: flex;
flex-direction: column;
}
}
</style>
@code {
[Parameter]
public RenderFragment Title { get; set; }
[Parameter]
public RenderFragment Description { get; set; }
[Parameter]
public RenderFragment Example { get; set; }
[Parameter]
public RenderFragment Usage { get; set; }
[Parameter]
public RenderFragment Code { get; set; }
}
@@ -0,0 +1,32 @@
<details class="makingOfSection">
<summary>
@Title
</summary>
@ChildContent
</details>
<style>
.makingOfSection {
width: 100%;
background-color: rgba(0,0,0, 0.1);
padding: 25px;
border-radius: 8px;
border: 2px black dashed;
}
.makingOfSection > summary {
font-size: 3.4em;
}
</style>
@code {
[Parameter]
public string Title { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
}
+29
View File
@@ -0,0 +1,29 @@
<div class="paper">
@ChildContent
</div>
<style>
.paper {
padding-top: 24px;
padding-left: 24px;
padding-right: 24px;
padding-bottom: 24px;
margin: auto;
overflow-y: auto;
overflow-x: hidden;
border: 4px solid var(--paper-border);
background-color: var(--paper);
box-shadow: 0px 6px var(--paper-border);
width: 100%;
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public string Title { get; set; }
}
+61
View File
@@ -0,0 +1,61 @@
<div class="alertContainer @Type.ToString().ToLower()">
@if (Title != null) {
<div class="alertTitle">
@Title
</div>
}
@if (Message != null) {
<div>
@Message
</div>
}
</div>
<style>
.alertContainer {
border: 4px solid;
border-radius: 4px;
padding: 16px;
display: flex;
flex-direction: column;
justify-items: stretch;
width: 100%;
}
.alertContainer.@SeverityType.Warning.ToString().ToLower() {
border-color: #2a2000;
background-color: #ffbf0029;
}
.alertContainer.@SeverityType.Error.ToString().ToLower() {
border-color: #290102;
background-color: #4C2C33;
}
.alertContainer.@SeverityType.Information.ToString().ToLower() {
border-color: #030129;
background-color: #2c3a4c;
}
.alertContainer.@SeverityType.Success.ToString().ToLower() {
border-color: #042901;
background-color: #2E4C2C;
}
.alertTitle {
font-weight: 800;
}
</style>
@code {
[Parameter]
public RenderFragment? Title { get; set; }
[Parameter]
public RenderFragment? Message { get; set; }
[Parameter]
public SeverityType Type { get; set; } = SeverityType.Warning;
}
@@ -0,0 +1,46 @@
<div class="loadingContainer">
<div style="flex-grow: 1"></div>
<div class="loadingText">
Loading...
</div>
<div style="flex-grow: 3"></div>
</div>
<style>
@@keyframes loadingKeyframes {
0% {
font-size: 1.0rem
}
50% {
font-size: 1.4rem
}
100% {
font-size: 1.0rem
}
}
.loadingContainer {
width: 100%;
height: 100%;
display: flex;
flex-grow: 1;
justify-content: center;
background-color: black;
border-radius: 4px;
flex-direction: column;
}
.loadingText {
margin-left: auto;
margin-right: auto;
animation-name: loadingKeyframes;
animation-duration: 6s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
</style>
@code {
}
+8
View File
@@ -0,0 +1,8 @@
namespace Components.Feedback;
public enum SeverityType {
Warning,
Information,
Error,
Success
}
@@ -0,0 +1,73 @@
<div class="formContainer">
<div class="formTextContainer">
<div class="formLabel">
@Label:
</div>
<input readonly="@ReadOnly"
class="formCheckboxInput"
type="checkbox"
id="@labelId"
checked="@Value
"@onchange="OnChange"/>
</div>
@if (Info != "") {
<div class="formInfo">
@Info
</div>
}
</div>
<style>
.formContainer {
display: flex;
flex-direction: column;
gap: 6px;
width: 100%;
}
.formTextContainer {
display: flex;
flex-direction: row;
gap: 8px;
align-items: center;
}
.formLabel {
font-weight: 800;
}
.formInfo {
font-size: 0.8rem;
font-style: italic;
}
.formCheckboxInput {
background-color: var(--primary);
color: var(--primary);
border: 2px solid var(--primary-border);
}
</style>
@code {
[Parameter]
public string Label { get; set; } = "";
[Parameter]
public string Info { get; set; } = "";
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public bool ReadOnly { get; set; }
[Parameter]
public bool Value { get; set; }
private string labelId = "";
protected override void OnInitialized() {
labelId = Label.ToLower().Replace(" ", "_");
}
}
@@ -0,0 +1,55 @@
<div class="displayContainer">
@if (Label != "") {
<div class="formLabel">
@Label
</div>
}
<div class="displayContent">
@Display
</div>
@if (Info != "") {
<div class="formInfo">
@Info
</div>
}
</div>
<style>
.displayContainer {
display: flex;
width: 100%;
flex-direction: column;
gap: 6px;
}
.displayContent {
background-color: var(--accent);
width: 100%;
border: 1px solid var(--primary-border);
border-radius: 1px;
padding: 8px;
min-height: 42px;
}
</style>
@code {
//TODO Clean up
[Parameter]
public string Label { get; set; }
[Parameter]
public string Info { get; set; }
[Parameter]
public RenderFragment? Display { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public bool? ReadOnly { get; set; }
[Parameter]
public string? Value { get; set; }
}
@@ -0,0 +1,29 @@
@using System.Web
<div class="escapeCodeContainer">
<textarea style="background-color: #2C2E33; width: 100%; border:3px solid #A8ADB9; border-radius:1px; padding: 8px;"
rows="8"
@onchange="OnChange" />
<textarea style="background-color: #2C2E33; width: 100%; border:3px solid #A8ADB9; border-radius:1px; padding: 8px;"
rows="8"
@bind="Output" />
</div>
<style>
.escapeCodeContainer {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
</style>
@code {
string Output = "";
public void OnChange(ChangeEventArgs changeEventArgs) {
var encoded = HttpUtility.HtmlEncode(changeEventArgs.Value.ToString());
Output = encoded.Replace("@", "@@");
Output = Output.Replace("\n", "<br />");
}
}
+154
View File
@@ -0,0 +1,154 @@
@using Services
@using Services.Immortal
@using Model.Immortal.MemoryTester
@implements IDisposable
@inject IMemoryTesterService MemoryTesterService
<div class="formGuessContainer">
@if (MemoryQuestion.Name != "") {
<div class="formLabel">
@MemoryQuestion.Name
</div>
}
<div>
<input readonly="@MemoryQuestion.IsRevealed"
class="formTextInput @(MemoryQuestion.IsRevealed ? "revealed" : IsSubmitted == false ? "guess" : int.Parse(guess) == MemoryQuestion.Answer ? "correct" : "wrong")"
placeholder="guess..."
type="number"
value="@guess"
id="@labelId"
@onchange="OnGuessChanged"/>
</div>
</div>
<style>
.formGuessContainer {
display: flex;
flex-direction: column;
gap: 6px;
width: 100%;
}
.formLabel {
font-weight: 800;
}
.formInfo {
font-size: 0.8rem;
font-style: italic;
}
.formTextInput {
background-color: #2C2E33;
border: 3px solid #A8ADB9;
border-radius: 1px;
padding: 8px;
display: block;
width: 100%;
}
.guess {
background-color: var(--primary);
border: 4px solid var(--primary-border);
border-radius: 1px;
}
::placeholder {
color: white;
opacity: 1;
}
.formTextInput.correct {
border: 3px solid green;
border-radius: 2px;
}
.formTextInput.wrong {
border: 3px solid red;
border-radius: 2px;
font-weight: bold;
}
</style>
@code {
[Parameter]
public string Label { get; set; } = "";
[Parameter]
public string Info { get; set; } = "";
[Parameter]
public EventCallback<AnswerEventArgs> OnChange { get; set; }
[Parameter]
public MemoryQuestionModel MemoryQuestion { get; set; }
[Parameter]
public bool IsSubmitted { get; set; }
private string guess { get; set; } = "";
private string labelId = "";
protected override void OnInitialized() {
labelId = Label.ToLower().Replace(" ", "_") + MemoryQuestion.Id;
MemoryTesterService.Subscribe(OnMemoryEvent);
if (MemoryQuestion.IsRevealed) {
guess = MemoryQuestion.Answer.ToString();
}
OnRefresh();
}
void IDisposable.Dispose() {
MemoryTesterService.Unsubscribe(OnMemoryEvent);
}
void OnMemoryEvent(MemoryTesterEvent memoryTesterEvent) {
if (memoryTesterEvent == MemoryTesterEvent.OnVerify) {
OnVerify();
}
if (memoryTesterEvent == MemoryTesterEvent.OnRefresh) {
OnRefresh();
}
}
protected override void OnAfterRender(bool firstRender) {
if (MemoryQuestion.IsRevealed) {
guess = MemoryQuestion.Answer.ToString();
}
}
void OnVerify() {
IsSubmitted = true;
}
void OnRefresh() {
guess = "";
if (MemoryQuestion.IsRevealed) {
guess = MemoryQuestion.Answer.ToString();
}
IsSubmitted = false;
}
void OnGuessChanged(ChangeEventArgs changeEventArgs) {
guess = changeEventArgs.Value.ToString();
OnChange.InvokeAsync(new AnswerEventArgs {
Name = MemoryQuestion.Name,
IsCorrect = int.Parse(guess) == MemoryQuestion.Answer,
Guess = int.Parse(guess)
});
}
}
+12
View File
@@ -0,0 +1,12 @@
<div style="font-size:0.8rem; font-style:italic;">
<i>
@ChildContent
</i>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
+10
View File
@@ -0,0 +1,10 @@
<div style="font-weight:800">
@ChildContent:
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
+10
View File
@@ -0,0 +1,10 @@
<div style="display: flex; gap: 16px; width: 100%; flex-direction: column;">
@ChildContent
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
+59
View File
@@ -0,0 +1,59 @@
<div class="formNumberContainer">
@if (FormLabelComponent != null) {
<FormLabelComponent>@FormLabelComponent</FormLabelComponent>
}
<div>
<input readonly="@ReadOnly"
class="numberInput"
type="number"
min="@Min"
max="@Max"
value="@Value"
@onchange="OnChange"/>
</div>
@if (FormInfoComponent != null) {
<FormInfoComponent>@FormInfoComponent</FormInfoComponent>
}
</div>
<style>
.formNumberContainer {
display: flex;
width: 100%;
flex-direction: column;
gap: 6px;
}
.numberInput {
width: 100%;
background-color: var(--primary);
border: 4px solid var(--primary-border);
border-radius: 1px;
padding: 8px;
}
</style>
@code {
[Parameter]
public RenderFragment? FormLabelComponent { get; set; }
[Parameter]
public RenderFragment? FormInfoComponent { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public bool? ReadOnly { get; set; }
[Parameter]
public int? Value { get; set; }
[Parameter]
public int? Min { get; set; }
[Parameter]
public int? Max { get; set; }
}
+30
View File
@@ -0,0 +1,30 @@
<div style="display: flex; width: 100%; flex-direction: column; gap:6px;">
@if (FormLabelComponent != null) {
<FormLabelComponent>@FormLabelComponent</FormLabelComponent>
}
<select style="background-color: #2C2E33; width: 100%; border:3px solid #A8ADB9; border-radius:1px; padding: 8px;"
@onchange="OnChange">
@ChildContent
</select>
@if (FormInfoComponent != null) {
<FormInfoComponent>@FormInfoComponent</FormInfoComponent>
}
</div>
@code {
[Parameter]
public RenderFragment? FormLabelComponent { get; set; }
[Parameter]
public RenderFragment? FormInfoComponent { get; set; }
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
}
@@ -0,0 +1,90 @@
<div class="form-text-container">
@if (Label != "") {
<div class="form-label">
@Label
</div>
}
<div>
<textarea readonly="@ReadOnly"
class="textAreaInput"
type="text"
rows="@Rows"
value="@Value"
@onchange="OnChange" />
</div>
@if (Info != "") {
<div class="form-info">
@Info
</div>
}
</div>
<style>
.form-text-container {
display: flex;
flex-direction: column;
gap: 6px;
width: 100%;
}
.textAreaInput {
width: 100%;
border-radius: 1px;
padding: 8px;
background-color: var(--primary);
border: 4px solid var(--primary-border);
}
.form-text-container .form-label {
font-weight: 800;
}
.form-text-container .form-info {
font-size: 0.8rem;
font-style: italic;
}
.form-text-container .form-text-input {
background-color: #2C2E33;
border: 3px solid #A8ADB9;
border-radius: 1px;
padding: 8px;
}
</style>
@code {
[Parameter]
public RenderFragment? FormLabelComponent { get; set; }
[Parameter]
public RenderFragment? FormInfoComponent { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public bool? ReadOnly { get; set; }
[Parameter]
public string? Value { get; set; }
[Parameter]
public int Rows { get; set; } = 4;
[Parameter]
public string Label { get; set; } = "";
[Parameter]
public string Info { get; set; } = "";
[Parameter]
public string Placeholder { get; set; } = "";
private string labelId = "";
protected override void OnInitialized() {
labelId = Label.ToLower().Replace(" ", "_");
}
}
+75
View File
@@ -0,0 +1,75 @@
<div class="formContainer">
@if (Label != "") {
<div class="formLabel">
@Label
</div>
}
<div>
<input readonly="@ReadOnly"
class="formTextInput"
placeholder="@Placeholder"
type="text"
value="@Value"
id="@labelId"
@onchange="OnChange"/>
</div>
@if (Info != "") {
<div class="formInfo">
@Info
</div>
}
</div>
<style>
.formContainer {
display: flex;
flex-direction: column;
gap: 6px;
width: 100%;
}
.formLabel {
font-weight: 800;
}
.formInfo {
font-size: 0.8rem;
font-style: italic;
}
.formTextInput {
border-radius: 1px;
padding: 8px;
display: block;
width: 100%;
background-color: var(--primary);
border: 4px solid var(--primary-border);
}
</style>
@code {
[Parameter]
public string Label { get; set; } = "";
[Parameter]
public string Info { get; set; } = "";
[Parameter]
public string Placeholder { get; set; } = "";
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public bool ReadOnly { get; set; }
[Parameter]
public string Value { get; set; } = "";
private string labelId = "";
protected override void OnInitialized() {
labelId = Label.ToLower().Replace(" ", "_");
}
}
+44
View File
@@ -0,0 +1,44 @@
<div class="infoContainer">
@if (InfoQuestionComponent != null) {
<div class="infoTitle">@InfoQuestionComponent</div>
}
@if (InfoAnswerComponent != null) {
<div>@InfoAnswerComponent</div>
}
</div>
<style>
.infoContainer {
display: flex;
flex-direction: column;
border-radius: 8px;
padding-top: 16px;
padding-left: 16px;
padding-right: 16px;
padding-bottom: 16px;
margin: auto;
width: 100%;
gap: 8px;
}
.infoTitle {
font-weight: 800;
font-size: 1.3rem;
}
@@media only screen and (max-width: 1025px) {
.infoContainer {
padding: 2px;
}
}
</style>
@code {
[Parameter]
public RenderFragment? InfoQuestionComponent { get; set; }
[Parameter]
public RenderFragment? InfoAnswerComponent { get; set; }
}
+52
View File
@@ -0,0 +1,52 @@
<button class="buttonContainer @ButtonType.ToString().ToLower()" @onclick="ButtonClicked">@ChildContent</button>
<style>
.buttonContainer {
padding: 16px;
border: 1px solid;
border-radius: 8px;
font-weight: 800;
font-size: 1.2rem;
}
.@(ButtonType.Primary.ToString().ToLower()) {
border-color: var(--primary);
background-color: var(--primary);
}
.@ButtonType.Secondary.ToString().ToLower() {
border-color: var(--secondary);
background-color: var(--secondary);
}
.@ButtonType.Primary.ToString().ToLower():hover {
background-color: var(--primary-hover);
border-color: var(--primary-border-hover);
color: white;
}
.@ButtonType.Secondary.ToString().ToLower():hover {
background-color: var(--secondary-hover);
border-color: var(--secondary-border-hover);
color: white;
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public EventCallback<EventArgs> OnClick { get; set; }
[Parameter]
public ButtonType ButtonType { get; set; }
private void ButtonClicked(EventArgs eventArgs) {
OnClick.InvokeAsync(eventArgs);
}
}
+6
View File
@@ -0,0 +1,6 @@
namespace Components.Inputs;
public enum ButtonType {
Primary, // Positive Actions
Secondary // Destruction Action
}
@@ -0,0 +1,13 @@
<div class="divider">
</div>
<style>
.divider {
width: 100%;
border-bottom: 2px solid black;
margin-top: 6px;
margin-bottom: 6px;
height: 12px;
background-color: #545454;
}
</style>
@@ -0,0 +1,18 @@
<div class="columnContainer">
@ChildContent
</div>
<style>
.columnContainer {
display: flex;
flex-direction: column;
flex: 1;
}
</style>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
@@ -0,0 +1,40 @@
<div class="lrg_container">
@ChildContent
</div>
<style>
.lrg_container {
display: flex;
gap: 16px;
flex-direction: column;
width: 75%;
min-width: 1000px;
margin-left: auto;
margin-right: auto;
padding-top: 10px;
padding-bottom: 30px;
}
@@media only screen and (max-width: 1025px) {
.lrg_container {
width: 100%;
min-width: 350px;
}
}
@@media only screen and (min-width: 1024px) {
.lrg_container {
margin-top: 50px;
}
}
</style>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
@@ -0,0 +1,39 @@
<div class="med_container">
@ChildContent
</div>
<style>
.med_container {
display: flex;
gap: 16px;
flex-direction: column;
width: 50%;
min-width: 1000px;
margin-left: auto;
margin-right: auto;
padding-top: 10px;
padding-bottom: 30px;
}
@@media only screen and (max-width: 1025px) {
.med_container {
width: 99%;
min-width: 350px;
}
}
@@media only screen and (min-width: 1024px) {
.med_container {
margin-top: 50px;
}
}
</style>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
@@ -0,0 +1,35 @@
<div class="med_container">
@ChildContent
</div>
<style>
.med_container {
display: flex;
gap: 16px;
flex-direction: column;
width: 50%;
margin-left: auto;
margin-right: auto;
padding-top: 10px;
padding-left: 20px;
padding-right: 20px;
padding-bottom: 30px;
border: 2px solid black;
}
@@media only screen and (max-width: 1025px) {
.med_container {
width: 85%;
}
}
</style>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
@@ -0,0 +1,27 @@
<div class="rowContainer">
@ChildContent
</div>
<style>
.rowContainer {
display: flex;
flex-direction: row;
gap: 30px;
width: 100%;
flex-wrap: wrap;
}
@@media only screen and (max-width: 1025px) {
.rowContainer {
gap: 3px;
flex-direction: column;
}
}
</style>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
@@ -0,0 +1,30 @@
<div class="content">
@ChildContent
</div>
<style>
.content {
display: flex;
flex-direction: column;
flex-wrap: wrap;
gap: 20px;
padding: 20px;
border: 2px solid black;
min-height: 50vh;
padding-bottom: 124px
}
@@media only screen and (max-width: 1025px) {
.content {
padding: 10px;
border: 0px solid black;
}
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
@@ -0,0 +1,27 @@
<div class="title">
@ChildContent
</div>
<style>
.title {
padding-top: 35px;
padding-bottom: 5px;
font-size: 1.5rem;
font-weight: bolder;
}
@@media only screen and (max-width: 1025px) {
.title {
padding: 10px;
border: 0px solid black;
}
}
</style>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
@@ -0,0 +1,22 @@
@if (Markdown == null) {
<div>Loading...</div>
}
else {
@((MarkupString)Markdown)
}
@code {
[Inject]
protected HttpClient Http { get; set; }
[Parameter]
public string MarkdownFileName { get; set; }
public string Markdown { get; set; }
protected override async Task OnInitializedAsync() {
Markdown = Markdig.Markdown.ToHtml(await Http.GetStringAsync($"markdown/{MarkdownFileName}.md"));
}
}
@@ -0,0 +1,120 @@
@inherits LayoutComponentBase
@inject INavigationService NavigationService
@using Services
@using Model.Website
@using Model.Website.Enums
@using Microsoft.EntityFrameworkCore
@implements IDisposable
<div onmouseleave="@HoverOut" class="desktopNavContainer">
<div class="menuHeader" @onmouseover="() => NavigationService.ChangeNavigationState(NavigationStateType.Hovering_Menu)">
<NavLink href="/" class="websiteTitle">
IGP Fan Reference
</NavLink>
@foreach (var webSection in WebSections) {
<div>@webSection.Name</div>
}
</div>
@{
var hoveredStyle = NavigationStateType.Hovering_Menu.Equals(NavigationService.GetNavigationState()) ?
"navMenuContainerShow" : "";
}
<div class="navMenuContainer @hoveredStyle">
@foreach (var section in WebSections) {
var pages = (from page in WebPages
where page.WebSectionModelId == section.Id
select page).ToList();
<NavSectionComponent Section=section Children=pages/>
}
</div>
</div>
<style>
.desktopNavContainer {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 40px;
background-color: rgba(255,255,255,0.1);
z-index: 1001;
}
.menuHeader {
border-bottom: 4px solid black;
position: fixed;
width: 100%;
padding: 12px;
display: flex;
justify-content: center;
gap: 32px;
height: 50px;
background-color: var(--accent);
}
.websiteTitle {
font-weight: bold;
color: white;
}
.navMenuContainer {
display: none;
position: fixed;
top: 50px;
flex-direction: row;
gap: 20px;
width: 100%;
align-items: flex-start;
justify-content: center;
flex-wrap: wrap;
border-bottom: 4px solid black;
padding-top: 20px;
padding-bottom: 20px;
background-color: rgba(22, 22, 24, 0.95);
}
.navMenuContainerShow {
display: flex;
}
@@media only screen and (max-width: 1025px) {
.desktopNavContainer {
display: none;
}
}
@@media only screen and (max-width: 480px) {
.desktopNavContainer {
display: none;
}
}
</style>
@code {
[Parameter]
public DbSet<WebSectionModel> WebSections { get; set; }
[Parameter]
public DbSet<WebPageModel> WebPages { get; set; }
protected override void OnInitialized() {
NavigationService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose() {
NavigationService.Unsubscribe(StateHasChanged);
}
void HoverOut(MouseEventArgs mouseEventArgs) {
Console.WriteLine(NavigationStateType.Default);
NavigationService.ChangeNavigationState(NavigationStateType.Default);
}
}
@@ -0,0 +1,170 @@
@using Model.Website
@using Microsoft.EntityFrameworkCore
<div class="mobileFooter">
<div class="mobileNavSectionsContainer">
@foreach (var _section in WebSections) {
<div class="mobileNavSectionButton" @onclick="() => OnSectionClicked(_section)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavSectionButtonText">
@_section.Name
</div>
</div>
}
</div>
<div class="fullPageButton @(selectedSection != null)" @onclick="OnPageClicked" @onclick:stopPropagation="false" @onclick:preventDefault="false">
</div>
@if (selectedSection != null) {
var pages = (from page in WebPages
where page.WebSectionModelId == selectedSection.Id
select page).ToList();
<div class="mobileNavPagesContainer">
@foreach (var _page in pages) {
if (_page.IsPrivate.Equals("True")) {
continue;
}
<div class="mobileNavPageButton" @onclick="() => OnPageLinkClicked(_page)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavPageButtonText">
@_page.Name
</div>
</div>
}
</div>
}
</div>
<style>
fullPageButton {
position: fixed;
width: 100vw;
height: 100vh;
bottom: 0;
display: none;
background-color: rgba(0,0,0,0.6);
}
.fullPageButton.True {
display: block;
}
.mobileFooter {
position: fixed;
background-color: rgba(0,0,0,1);
width: 100vw;
bottom: 0;
display: none;
}
.mobileNavPagesContainer {
position: fixed;
display: flex;
flex-direction: column;
bottom: 0;
width: 100vw;
background-color: black;
padding-bottom: 6px;
padding-top: 6px;
padding-left: 4px;
padding-right: 4px;
gap: 2px;
}
.mobileNavSectionsContainer {
display: grid;
grid-auto-columns: 1fr;
grid-auto-flow: column;
width: 100%;
padding-bottom: 6px;
padding-top: 6px;
padding-left: 4px;
padding-right: 4px;
gap: 2px;
}
.mobileNavSectionButton {
border: 1px solid var(--primary);
width: 100%;
height: 64px;
display: flex;
background-color: var(--primary);
cursor: pointer;
}
.mobileNavPageButton {
border: 1px solid var(--primary);
width: 100%;
height: 64px;
display: flex;
background-color: var(--primary);
cursor: pointer;
}
.mobileNavPageButton:hover {
background-color: var(--primary-hover);
border-color: var(--primary-border-hover);
}
.mobileNavSectionButton:hover {
background-color: var(--primary-hover);
border-color: var(--primary-border-hover);
}
.mobileNavSectionButtonText {
font-size: 0.75rem;
text-align: center;
margin: auto;
font-weight: bolder;
}
.mobileNavPageButtonText {
font-size: 1.1rem;
text-align: center;
margin: auto;
font-weight: bolder;
}
@@media only screen and (max-width: 480px) {
.mobileFooter {
display: block;
}
}
</style>
@code {
[Parameter]
public DbSet<WebSectionModel> WebSections { get; set; }
[Parameter]
public DbSet<WebPageModel> WebPages { get; set; }
[Inject]
public NavigationManager NavigationManager { get; set; }
public WebSectionModel selectedSection;
public WebPageModel selectedPage;
void OnSectionClicked(WebSectionModel webSection) {
selectedSection = webSection;
}
void OnPageLinkClicked(WebPageModel webPage) {
selectedPage = webPage;
selectedSection = null;
NavigationManager.NavigateTo(webPage.Href);
}
void OnPageClicked(EventArgs eventArgs) {
selectedPage = null;
selectedSection = null;
}
}
@@ -0,0 +1,84 @@
@using Services
@using Model.Website
@using Model.Website.Enums
@inject INavigationService NavigationService;
@inject NavigationManager NavigationManager;
@if (IsOnPage) {
<NavLink href="@Page.Href" class="navContainer navLink navSelected">
<div class="navName">
@Page.Name
</div>
</NavLink>
}
else {
<NavLink @onclick="() => NavigationService.ChangeNavigationState(NavigationStateType.Default)" href="@Page.Href" class="navContainer navLink">
<div class="navName">
@Page.Name
</div>
</NavLink>
}
<style>
.navContainer {
cursor: pointer;
border: 2px solid black;
border: none;
height: 60px;
width: 100%;
display: block;
display: flex;
border: none;
}
.navName {
margin: auto;
color: white;
font-size: 1.3rem;
font-weight: 600;
text-align: center;
}
.navLink {
background-color: var(--primary);
border: 1px solid var(--primary);
}
.navLink:hover {
color: #8EC3FF;
background-color: var(--primary-hover);
border-color: var(--primary-border-hover);
}
.navSelected {
background-color: var(--primary-hover);
}
</style>
@code {
[Parameter]
public WebPageModel Page { get; set; }
bool IsOnPage = false;
protected override async Task OnParametersSetAsync() {
var uri = NavigationManager.Uri.Remove(0, NavigationManager.BaseUri.Count()).ToLower();
IsOnPage = Page.Href.ToLower().Equals(uri);
}
void OnNavigationChanged() {
StateHasChanged();
}
void OnBack() {
NavigationService.Back();
}
}
@@ -0,0 +1,58 @@
@using Model.Website
<div class="sectionContainer">
<div class="sectionHeader">
<div class="sectionTitle">
@Section.Name
</div>
</div>
@foreach (var childPage in Children) {
if (childPage.IsPrivate.Equals("True")) {
continue;
}
<NavLinkComponent Page=childPage></NavLinkComponent>
}
</div>
<style>
.sectionContainer {
display: flex;
flex-direction: column;
gap: 4px;
justify-content: flex-start;
position: relative;
margin-top: 12px;
padding: 18px;
width: 300px;
margin-left: 4px;
}
.sectionHeader {
bottom: 100%;
position: absolute;
top: 0px;
left: -8px;
padding-right: 12px;
padding-left: 4px;
width: 100%;
display: flex;
line-height: 0px;
}
.sectionTitle {
font-weight: bold;
padding-right: 8px;
margin-top: -2px;
white-space: pre;
}
</style>
@code {
[Parameter]
public WebSectionModel? Section { get; set; }
[Parameter]
public List<WebPageModel>? Children { get; set; }
}
@@ -0,0 +1,163 @@
@using Model.Website
@using Microsoft.EntityFrameworkCore
@inherits LayoutComponentBase
<div class="tablet">
<div class="tabletHeader" @onclick="OnNavClicked" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="tabletTitle">
IGP Fan Reference
</div>
<div class="tabletButton">
<div class="tabletMenuTitle">
Menu
</div>
</div>
</div>
<div class="fullPageButton @NavOpen" @onclick="OnNavClicked" @onclick:stopPropagation="false" @onclick:preventDefault="false">
</div>
<div class="tabletNav @NavOpen">
@foreach (var _section in WebSections) {
var pages = (from page in WebPages
where page.WebSectionModelId == _section.Id
select page).ToList();
<div>
<div>
@_section.Name
</div>
<div class="tabletNavItems">
@foreach (var _page in pages) {
if (_page.IsPrivate.Equals("True")) {
continue;
}
<NavLink href="@_page.Href" class="tabletNavItem" @onclick="OnPageClicked">
@_page.Name
</NavLink>
}
</div>
</div>
}
</div>
</div>
<style>
.fullPageButton {
position: fixed;
width: 100vw;
height: 100vh;
bottom: 0;
display: none;
background-color: rgba(0,0,0,0.6);
}
.fullPageButton.True {
display: block;
}
.tablet {
display: none;
}
.tabletNav {
position: fixed;
background-color: rgba(30,30,30,0.98);
display: none;
height: 100vh;
padding: 32px;
overflow-y: auto;
overflow-x: hidden;
top: 0px;
gap: 22px;
flex-direction: column;
}
.tabletNavItem {
padding: 8px;
}
.tabletNavItems {
display: flex;
flex-direction: column;
}
.tabletNav.True {
display: flex;
}
.tabletHeader {
height: 60px;
width: 100vw;
position: fixed;
top: 0;
display: flex;
background-color: var(--accent);
border-bottom: 4px solid rgba(0,0,0,0.95);
justify-content: space-between;
}
.tabletMenuTitle {
margin: auto;
font-weight: 700;
}
.tabletTitle {
margin: auto;
font-weight: 700;
font-size: 1.4rem;
}
.tabletButton {
border: 2px solid black;
background-color: rgba(0,0,0,0.3);
width: 80px;
height: 100%;
display: flex;
cursor: pointer;
}
.tabletButton:hover {
background-color: rgba(0,0,0,0.7);
}
@@media only screen and (max-width: 1025px) {
.tablet {
display: block;
}
}
@@media only screen and (max-width: 480px) {
.tablet {
display: none;
}
}
</style>
@code {
[Parameter]
public DbSet<WebSectionModel> WebSections { get; set; }
[Parameter]
public DbSet<WebPageModel> WebPages { get; set; }
bool NavOpen = true;
void OnNavClicked(EventArgs eventArgs) {
NavOpen = !NavOpen;
}
void OnPageClicked(EventArgs eventArgs) {
NavOpen = false;
}
}
@@ -0,0 +1,24 @@
@using Model.Website.Enums
@using Model.Website
@if (isDisplayable) {
@ChildContent
}
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public WebDeploymentType DeploymentType { get; set; }
[Inject]
public NavigationManager MyNavigationManager { get; set; }
bool isDisplayable;
protected override void OnInitialized() {
isDisplayable = DeploymentType == WebDeploymentModel.DeploymentType;
}
}
+26
View File
@@ -0,0 +1,26 @@
@using Model.Website
@if (isDisplayable) {
@ChildContent
}
else {
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
}
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
[Inject]
public NavigationManager MyNavigationManager { get; set; }
bool isDisplayable;
protected override void OnInitialized() {
var page = MyNavigationManager.Uri.Remove(0, MyNavigationManager.BaseUri.Length);
isDisplayable = WebDeploymentModel.Get().Contains(page);
}
}
+4
View File
@@ -0,0 +1,4 @@
@inherits LayoutComponentBase
@Body
@@ -0,0 +1,19 @@
<div style="display:inline; width: 12px;">
<div style="height: 0px; display:flex; flex-direction:column; align-items:center;">
<div style="height: 0px;">
</div>
<div style="height: 0px;position: relative; top: -6px; left:0px; white-space:pre">@Dividee</div>
<div style="height: 0px; position: relative; top: 6px; left:0px; white-space:pre">@Divider</div>
</div>
</div>
@code {
[Parameter]
public RenderFragment Dividee { get; set; }
[Parameter]
public RenderFragment Divider { get; set; }
}
@@ -0,0 +1,24 @@
<div style="display:flex; flex-direction:column; align-items:center;padding-right: 12px;padding-left: 4px; font-family:monospace">
<div style="height: 0px;display:flex; flex-direction:row; ">
<div style="font-size: 18px; height: 0px;">
&#8721;
</div>
<div style="position:relative; left: 2px; top: 1px;">@IndexSymbol</div>
</div>
<div style="height: 0px;position: relative; top: -18px; left:0px; font-size: 80%; display:flex;">@LoopEnd</div>
<div style="height: 0px; position: relative; top: 22px; left:0px; font-size: 80%; display:flex;">@LoopStart</div>
</div>
@code {
[Parameter]
public RenderFragment LoopEnd { get; set; }
[Parameter]
public RenderFragment LoopStart { get; set; }
[Parameter]
public RenderFragment IndexSymbol { get; set; }
}
@@ -0,0 +1,28 @@
<span class="spoiler">
<u>@ChildContent</u>
</span>
<style>
.spoiler {
color: black;
background-color: black;
}
u {
text-decoration-color: inherit;
text-decoration-thickness:1px;
}
.spoiler:hover {
color: inherit;
background-color: inherit;
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
+7
View File
@@ -0,0 +1,7 @@
namespace Components.Utils;
public static class Interval {
public static string ToTime(int interval) {
return TimeSpan.FromSeconds(interval).ToString(@"mm\:ss");
}
}
+10
View File
@@ -0,0 +1,10 @@
@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 Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using System.Text
@using System.Text.Json
@using YamlDotNet.Serialization