using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; namespace ApplianceRepair.Components.Pages { public static class RequestNumberGenerator { private static readonly char[] _chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789".ToCharArray(); public static string Generate(int length = 6) { var result = new char[length]; // Use Random.Shared in .NET 6+ for thread safety for (int i = 0; i < length; i++) { result[i] = _chars[Random.Shared.Next(_chars.Length)]; } return new string(result); } } public partial class Book(RepairRequestReader repairRequestReader, RepairRequestMediaReader repairRequestMediaReader) : ComponentBase { public RepairRequestModel Model = new(); public List SelectedFiles = new(); public bool Complete = false; private void HandleFiles(InputFileChangeEventArgs e) => SelectedFiles.AddRange(e.GetMultipleFiles()); private async Task HandleSubmit() { Model.RequestNumber = RequestNumberGenerator.Generate(); Model.CreatedAt = DateTime.Now; Model.UpdatedAt = DateTime.Now; await repairRequestReader.AddRecord(Model); var imageUploadPath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "uploads"); if (!Directory.Exists(imageUploadPath)) Directory.CreateDirectory(imageUploadPath); foreach (var file in SelectedFiles) { try { var trustedFileName = Path.GetRandomFileName() + Path.GetExtension(file.Name); var path = Path.Combine(imageUploadPath, trustedFileName); using var stream = file.OpenReadStream(maxAllowedSize: 1024 * 1024 * 10); using var fileStream = new FileStream(path, FileMode.Create); await stream.CopyToAsync(fileStream); var mediaRecord = new RepairRequestMediaRecord() { CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, RequestNumber = Model.RequestNumber, MediaPath = path, }; await repairRequestMediaReader.AddRecord(mediaRecord); } catch (Exception ex) { // probably need to show this to the user somehow, something prettier tho Console.WriteLine($"File: {file.Name} Error: {ex.Message}"); } } Complete = true; } } }