Updated the UI of the application
This commit is contained in:
14
WebUI/Components/Shared/CenteredCard.razor
Normal file
14
WebUI/Components/Shared/CenteredCard.razor
Normal file
@@ -0,0 +1,14 @@
|
||||
<div class="container-fluid d-flex justify-content-center align-items-center" style="height: 95vh;">
|
||||
<div class="card shadow-lg border-0" style="max-width: 500px; width: 100%;">
|
||||
<div class="card-body p-4">
|
||||
<h2 class="card-title text-center mb-4 fw-semibold">@Title</h2>
|
||||
@ChildContent
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter] public string Title { get; set; } = string.Empty;
|
||||
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
|
||||
}
|
||||
28
WebUI/Components/Shared/ModernCheckbox.razor
Normal file
28
WebUI/Components/Shared/ModernCheckbox.razor
Normal file
@@ -0,0 +1,28 @@
|
||||
<div class="form-check d-flex align-items-center gap-2">
|
||||
<input
|
||||
class="form-check-input custom-checkbox"
|
||||
type="checkbox"
|
||||
id="@CheckboxId"
|
||||
@bind="Checked" />
|
||||
|
||||
<label class="form-check-label text-secondary" for="@CheckboxId">
|
||||
@Label
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public string Label { get; set; } = string.Empty;
|
||||
[Parameter] public bool Checked { get; set; }
|
||||
[Parameter] public EventCallback<bool> CheckedChanged { get; set; }
|
||||
|
||||
private string CheckboxId { get; } = $"checkbox_{Guid.NewGuid().ToString("N")}";
|
||||
|
||||
private async Task OnChange(ChangeEventArgs e)
|
||||
{
|
||||
if (e.Value is bool value)
|
||||
{
|
||||
Checked = value;
|
||||
await CheckedChanged.InvokeAsync(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
WebUI/Components/Shared/ModernFileUploader.razor
Normal file
78
WebUI/Components/Shared/ModernFileUploader.razor
Normal file
@@ -0,0 +1,78 @@
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<link rel="stylesheet" href="Components/Shared/ModernFileUploader/modernFileUploader.css" />
|
||||
|
||||
<div class="upload-box p-8 border-2 border-dashed rounded-xl text-center transition relative"
|
||||
id="dropzone"
|
||||
style="cursor: pointer;"
|
||||
@onclick="TriggerFileInputClick">
|
||||
@if (string.IsNullOrEmpty(SelectedFileName))
|
||||
{
|
||||
<p class="text-gray-600 mb-2">Click to upload a file</p>
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(SelectedFileName))
|
||||
{
|
||||
<p class="text-green-600 text-sm">Selected: @SelectedFileName</p>
|
||||
}
|
||||
</div>
|
||||
|
||||
<InputFile id="hiddenFileInput" accepts=".pdf" OnChange="HandleFileChange" class="hidden" hidden="true" />
|
||||
|
||||
@if (!string.IsNullOrEmpty(UploadMessage))
|
||||
{
|
||||
<p class="mt-2 text-sm text-red-600">@UploadMessage</p>
|
||||
}
|
||||
|
||||
<script src="Components/Shared/ModernFileUploader/modernFileUploader.js"></script>
|
||||
|
||||
@code {
|
||||
private string? SelectedFileName;
|
||||
private string? UploadMessage;
|
||||
|
||||
[Parameter] public List<string> AllowedFileTypes { get; set; } = new List<string>();
|
||||
[Parameter] public long MaxFileSize { get; set; } = 10 * 1024 * 1024;
|
||||
[Parameter] public EventCallback<IBrowserFile> OnFileUploaded { get; set; }
|
||||
|
||||
private DotNetObjectReference<ModernFileUploader>? dotNetRef;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
dotNetRef = DotNetObjectReference.Create(this);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task TriggerFileInputClick()
|
||||
{
|
||||
await JS.InvokeVoidAsync("triggerInputClick", "hiddenFileInput");
|
||||
}
|
||||
|
||||
private async Task HandleFileChange(InputFileChangeEventArgs e)
|
||||
{
|
||||
var file = e.File;
|
||||
UploadMessage = null;
|
||||
|
||||
if (AllowedFileTypes.Count > 0 && !AllowedFileTypes.Any(type => file.Name.EndsWith(type, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
UploadMessage = $"Invalid file type. Allowed types: {string.Join(", ", AllowedFileTypes)}.";
|
||||
SelectedFileName = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.Size > MaxFileSize)
|
||||
{
|
||||
UploadMessage = $"File too large. Max allowed size is {MaxFileSize / (1024 * 1024)} MB.";
|
||||
SelectedFileName = null;
|
||||
return;
|
||||
}
|
||||
|
||||
SelectedFileName = file.Name;
|
||||
await OnFileUploaded.InvokeAsync(file);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
dotNetRef?.Dispose();
|
||||
}
|
||||
}
|
||||
7
WebUI/Components/Shared/ModernLabel.razor
Normal file
7
WebUI/Components/Shared/ModernLabel.razor
Normal file
@@ -0,0 +1,7 @@
|
||||
<label class="form-label fw-semibold text-secondary" style="font-size: 1rem;">
|
||||
@Text
|
||||
</label>
|
||||
|
||||
@code {
|
||||
[Parameter] public string Text { get; set; } = string.Empty;
|
||||
}
|
||||
24
WebUI/Components/Shared/RoundedTextBox.razor
Normal file
24
WebUI/Components/Shared/RoundedTextBox.razor
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="form-group">
|
||||
<input
|
||||
class="form-control rounded-pill shadow-sm px-4 py-2 border-0"
|
||||
placeholder="@Placeholder"
|
||||
@bind="Value"
|
||||
@oninput="OnInput" />
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public string Placeholder { get; set; } = string.Empty;
|
||||
|
||||
[Parameter] public string Value { get; set; } = string.Empty;
|
||||
|
||||
[Parameter] public EventCallback<string> ValueChanged { get; set; }
|
||||
|
||||
private async Task OnInput(ChangeEventArgs e)
|
||||
{
|
||||
if (e.Value is string newValue)
|
||||
{
|
||||
Value = newValue;
|
||||
await ValueChanged.InvokeAsync(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user