diff options
Diffstat (limited to 'src/Data')
29 files changed, 664 insertions, 0 deletions
diff --git a/src/Data/Database/Base.cs b/src/Data/Database/Base.cs new file mode 100644 index 0000000..4084ec8 --- /dev/null +++ b/src/Data/Database/Base.cs @@ -0,0 +1,15 @@ +using System; + +namespace VSH.Data.Database; + +public class Base +{ + public Guid Id { get; set; } + public DateTime Created { get; set; } + public DateTime? Updated { get; set; } + + public void SetBaseValues() { + Id = Guid.NewGuid(); + Created = DateTime.UtcNow; + } +}
\ No newline at end of file diff --git a/src/Data/Database/Category.cs b/src/Data/Database/Category.cs new file mode 100644 index 0000000..6e0d324 --- /dev/null +++ b/src/Data/Database/Category.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using IOL.Helpers; +using VSH.Data.Enums; +using VSH.Utilities; + +namespace VSH.Data.Database; + +public class Category : Base +{ + public Category(string name = default) { + if (name.IsNullOrWhiteSpace()) + return; + Name = name; + Slug = name.Slugified(); + } + + public string Name { get; set; } + public string Slug { get; set; } + public CategoryVisibility VisibilityState { get; set; } + public ICollection<Product> Products { get; set; } + public bool Disabled => VisibilityState == CategoryVisibility.DISABLED; + public bool Deleted => VisibilityState == CategoryVisibility.DELETED; + + public void Update(Category update = default) { + Name = update?.Name ?? Name; + VisibilityState = update?.VisibilityState ?? VisibilityState; + Updated = DateTime.UtcNow; + } +}
\ No newline at end of file diff --git a/src/Data/Database/Document.cs b/src/Data/Database/Document.cs new file mode 100644 index 0000000..2ae40d6 --- /dev/null +++ b/src/Data/Database/Document.cs @@ -0,0 +1,9 @@ +using VSH.Data.Enums; + +namespace VSH.Data.Database; + +public class Document : Base +{ + public DocumentType Type { get; set; } + public string Content { get; set; } +}
\ No newline at end of file diff --git a/src/Data/Database/Order.cs b/src/Data/Database/Order.cs new file mode 100644 index 0000000..02869b2 --- /dev/null +++ b/src/Data/Database/Order.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using IOL.Helpers; +using IOL.VippsEcommerce.Models.Api; +using VSH.Data.Enums; +using VSH.Utilities; + +namespace VSH.Data.Database; + +public class Order : Base +{ + public string Comment { get; set; } + public string OrderReference { get; set; } + public OrderStatus Status { get; set; } + public OrderPaymentType PaymentType { get; set; } + public string VippsTransactionId { get; set; } + public ETransactionStatus VippsTransactionStatus { get; set; } + public EStatusEnum VippsStatus { get; set; } + public ContactInformation ContactInfo { get; set; } + public List<OrderProduct> Products { get; set; } + + public class ContactInformation + { + public string Name { get; set; } + public string PhoneNumber { get; set; } + public string EmailAddress { get; set; } + } + + public decimal Total(bool includeTax = true) { + if (!Products.Any()) + return default; + var total = Products.Sum(product => product.PriceAtTimeOfOrder * product.NumberOfItems); + if (includeTax) + return total; + var taxCut = total * 25 / 100; + return total - taxCut; + } + + public decimal Tax(bool includeTax = true) { + if (!Products.Any()) + return default; + var total = Products.Sum(product => product.PriceAtTimeOfOrder * product.NumberOfItems); + var taxCut = total * 25 / 100; + return taxCut; + } + + public string GetAdminMailContent(string hostname) => @$" +Referanse: {OrderReference} +Lenke: {hostname}/kontoret/bestillinger?order={OrderReference} +Betalingsmetode: {EnumName.ForPaymentType(PaymentType)} +Status: {EnumName.ForOrderStatus(Status)} +Navn: {ContactInfo.Name} +E-postadresse: {ContactInfo.EmailAddress} +Telefon: {ContactInfo.PhoneNumber} +{(Comment.HasValue() ? "Kommentar:" + Comment : "")} +"; + + public string GetCustomerMailContent(string hostname) => @$" +Hei {ContactInfo.Name}, tusen takk for din bestilling! +Gå til {hostname}/status/{OrderReference} for å få full oversikt over bestillinga. + +Hvis du har spørsmål angående din ordre er det bare å svare på denne mailen så svarer vi så raskt vi kan. + +Med venleg hilsen + +Øystein og Bodil +Vinjesvingen Handel AS +915 61 900 +"; +} + +public class OrderProduct +{ + public Guid Id { get; set; } + + public int NumberOfItems { get; set; } + + public decimal PriceAtTimeOfOrder { get; set; } + + public decimal Total(bool includeTax = true) { + if (NumberOfItems == default || PriceAtTimeOfOrder == default) + return default; + var total = PriceAtTimeOfOrder * NumberOfItems; + if (includeTax) + return total; + var taxCut = total * 25 / 100; + return total - taxCut; + } + + public decimal Tax(bool includeTax = true) { + if (NumberOfItems == default || PriceAtTimeOfOrder == default) + return default; + var total = PriceAtTimeOfOrder * NumberOfItems; + var taxCut = total * 25 / 100; + return taxCut; + } +}
\ No newline at end of file diff --git a/src/Data/Database/Product.cs b/src/Data/Database/Product.cs new file mode 100644 index 0000000..d8a3d8b --- /dev/null +++ b/src/Data/Database/Product.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using VSH.Data.Enums; +using VSH.Data.Miscellaneous; +using VSH.Data.Static; +using VSH.Utilities; + +namespace VSH.Data.Database; + +public class Product : Base +{ + public string Name { get; set; } + public string Description { get; set; } + public decimal Price { get; set; } + public PriceSuffix PriceSuffix { get; set; } + public ProductVisibility VisibilityState { get; set; } + public Category Category { get; set; } + public List<ProductImage> Images { get; set; } + public int Count { get; set; } + public string Slug { get; set; } + public bool ShowOnFrontpage { get; set; } + + public string ReadablePriceSuffix => EnumName.ForPriceSuffix(PriceSuffix); + + public AppPath GetPrimaryImage() { + var productImage = Images.OrderBy(c => c.Order).FirstOrDefault(); + return productImage != default ? productImage.GetPath() : AppPaths.DefaultProductImage; + } + + public string WebPath() => $"/produktar/{Category?.Slug}/{Slug}"; + + public bool IsVisible => VisibilityState == ProductVisibility.DEFAULT; + public bool IsAvailable => Count == -1 || Count >= 1; +} + +public class ProductImage +{ + public ProductImage(string fileName = default, int order = default) { + FileName = fileName; + Order = order; + } + + public int Order { get; } + public string FileName { get; } + + public AppPath GetPath() { + if (FileName == default) return AppPaths.DefaultProductImage; + return new AppPath { + WebPath = Path.Combine(AppPaths.ProductImages.WebPath, FileName), + HostPath = Path.Combine(AppPaths.ProductImages.HostPath, FileName), + }; + } +}
\ No newline at end of file diff --git a/src/Data/Database/User.cs b/src/Data/Database/User.cs new file mode 100644 index 0000000..f8b083d --- /dev/null +++ b/src/Data/Database/User.cs @@ -0,0 +1,18 @@ +using IOL.Helpers; + +namespace VSH.Data.Database; + +public class User : Base +{ + public User(string username) => Username = username; + public string Username { get; set; } + public string Password { get; set; } + + public void HashAndSetPassword(string password) { + Password = PasswordHelper.HashPassword(password); + } + + public bool VerifyPassword(string password) { + return PasswordHelper.Verify(password, Password); + } +}
\ No newline at end of file diff --git a/src/Data/Dtos/AdminViewOrderDto.cs b/src/Data/Dtos/AdminViewOrderDto.cs new file mode 100644 index 0000000..846b503 --- /dev/null +++ b/src/Data/Dtos/AdminViewOrderDto.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using VSH.Data.Database; +using VSH.Data.Enums; + +namespace VSH.Data.Dtos; + +public class AdminViewOrderDto +{ + public Guid Id { get; set; } + public Order.ContactInformation ContactInformation { get; set; } + public List<OrderDetailProduct> Products { get; set; } + public string OrderReference { get; set; } + public DateTime OrderDate { get; set; } + public OrderPaymentType PaymentType { get; set; } + public OrderStatus Status { get; set; } + public string VippsStatus { get; set; } + public string VippsId { get; set; } + public string VippsTransactionStatus { get; set; } + public string Comment { get; set; } + + public class OrderDetailProduct + { + public Guid Id { get; set; } + public string Name { get; set; } + public int Count { get; set; } + public decimal PayedPrice { get; set; } + } +}
\ No newline at end of file diff --git a/src/Data/Enums/AnalyticType.cs b/src/Data/Enums/AnalyticType.cs new file mode 100644 index 0000000..0ec8b6b --- /dev/null +++ b/src/Data/Enums/AnalyticType.cs @@ -0,0 +1,7 @@ +namespace VSH.Data.Enums; + +public enum AnalyticType +{ + PAGE_LOAD, + ERROR +}
\ No newline at end of file diff --git a/src/Data/Enums/CategoryVisibility.cs b/src/Data/Enums/CategoryVisibility.cs new file mode 100644 index 0000000..b69ee56 --- /dev/null +++ b/src/Data/Enums/CategoryVisibility.cs @@ -0,0 +1,8 @@ +namespace VSH.Data.Enums; + +public enum CategoryVisibility +{ + DEFAULT = 0, + DISABLED = 1, + DELETED = 2 +}
\ No newline at end of file diff --git a/src/Data/Enums/CookieType.cs b/src/Data/Enums/CookieType.cs new file mode 100644 index 0000000..74f1742 --- /dev/null +++ b/src/Data/Enums/CookieType.cs @@ -0,0 +1,8 @@ +namespace VSH.Data.Enums; + +public enum CookieType +{ + XSRF = 0, + SESSION = 1, + CULTURE = 2 +}
\ No newline at end of file diff --git a/src/Data/Enums/DocumentType.cs b/src/Data/Enums/DocumentType.cs new file mode 100644 index 0000000..084e80e --- /dev/null +++ b/src/Data/Enums/DocumentType.cs @@ -0,0 +1,10 @@ +namespace VSH.Data.Enums; + +public enum DocumentType +{ + PRIVACY_POLICY = 0, + SALES_TERMS = 1, + ABOUT_PAGE = 2, + CONTACT_PAGE = 3, + DEALERS_PAGE = 4, +}
\ No newline at end of file diff --git a/src/Data/Enums/OrderAdminStatus.cs b/src/Data/Enums/OrderAdminStatus.cs new file mode 100644 index 0000000..b3235ea --- /dev/null +++ b/src/Data/Enums/OrderAdminStatus.cs @@ -0,0 +1,9 @@ +namespace VSH.Data.Enums; + +public enum OrderAdminStatus +{ + VIPPS_CAPTURED = 0, + INVOICE_SENT = 1, + PAYED = 2, + IN_PROGESS = 3, +}
\ No newline at end of file diff --git a/src/Data/Enums/OrderPaymentType.cs b/src/Data/Enums/OrderPaymentType.cs new file mode 100644 index 0000000..73df3b9 --- /dev/null +++ b/src/Data/Enums/OrderPaymentType.cs @@ -0,0 +1,7 @@ +namespace VSH.Data.Enums; + +public enum OrderPaymentType +{ + VIPPS = 0, + INVOICE_BY_EMAIL = 1 +}
\ No newline at end of file diff --git a/src/Data/Enums/OrderStatus.cs b/src/Data/Enums/OrderStatus.cs new file mode 100644 index 0000000..9baee22 --- /dev/null +++ b/src/Data/Enums/OrderStatus.cs @@ -0,0 +1,11 @@ +namespace VSH.Data.Enums; + +public enum OrderStatus +{ + IN_PROGRESS = 0, + CANCELLED = 1, + FAILED = 2, + COMPLETED = 3, + AWAITING_INVOICE = 4, + AWAITING_VIPPS = 5, +}
\ No newline at end of file diff --git a/src/Data/Enums/PriceSuffix.cs b/src/Data/Enums/PriceSuffix.cs new file mode 100644 index 0000000..c421cd2 --- /dev/null +++ b/src/Data/Enums/PriceSuffix.cs @@ -0,0 +1,7 @@ +namespace VSH.Data.Enums; + +public enum PriceSuffix +{ + PER = 0, + KILOS = 1 +}
\ No newline at end of file diff --git a/src/Data/Enums/ProductVisibility.cs b/src/Data/Enums/ProductVisibility.cs new file mode 100644 index 0000000..41ecc4d --- /dev/null +++ b/src/Data/Enums/ProductVisibility.cs @@ -0,0 +1,8 @@ +namespace VSH.Data.Enums; + +public enum ProductVisibility +{ + DEFAULT = 0, + DISABLED = 1, + DELETED = 2 +}
\ No newline at end of file diff --git a/src/Data/MainDbContext.cs b/src/Data/MainDbContext.cs new file mode 100644 index 0000000..c95a4d0 --- /dev/null +++ b/src/Data/MainDbContext.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore; +using VSH.Data.Database; + +namespace VSH.Data; + +public class MainDbContext : DbContext +{ + public MainDbContext(DbContextOptions<MainDbContext> options) : base(options) { } + + public DbSet<User> Users { get; set; } + public DbSet<Category> Categories { get; set; } + public DbSet<Product> Products { get; set; } + public DbSet<Order> Orders { get; set; } + public DbSet<Document> Documents { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) { + modelBuilder.Entity<User>(e => { + e.ToTable("Users"); + }); + modelBuilder.Entity<Category>(e => { + e.ToTable("Categories"); + }); + modelBuilder.Entity<Order>(e => { + e.Property(c => c.Products).HasColumnType("jsonb"); + e.Property(c => c.ContactInfo).HasColumnType("jsonb"); + e.ToTable("Orders"); + }); + + modelBuilder.Entity<Product>(e => { + e.Property(c => c.Images).HasColumnType("jsonb"); + e.ToTable("Products"); + }); + + modelBuilder.Entity<Document>(e => { + e.ToTable("Documents"); + }); + + base.OnModelCreating(modelBuilder); + } +}
\ No newline at end of file diff --git a/src/Data/Miscellaneous/AppCookie.cs b/src/Data/Miscellaneous/AppCookie.cs new file mode 100644 index 0000000..f355bb6 --- /dev/null +++ b/src/Data/Miscellaneous/AppCookie.cs @@ -0,0 +1,8 @@ +namespace VSH.Data.Miscellaneous; + +public sealed record AppCookie +{ + public string Name { get; init; } + public string Description { get; init; } + public bool Required { get; init; } +}
\ No newline at end of file diff --git a/src/Data/Miscellaneous/AppPath.cs b/src/Data/Miscellaneous/AppPath.cs new file mode 100644 index 0000000..4e17a88 --- /dev/null +++ b/src/Data/Miscellaneous/AppPath.cs @@ -0,0 +1,7 @@ +namespace VSH.Data.Miscellaneous; + +public sealed record AppPath +{ + public string HostPath { get; init; } + public string WebPath { get; init; } +}
\ No newline at end of file diff --git a/src/Data/Miscellaneous/AppSettings.cs b/src/Data/Miscellaneous/AppSettings.cs new file mode 100644 index 0000000..048c67c --- /dev/null +++ b/src/Data/Miscellaneous/AppSettings.cs @@ -0,0 +1,118 @@ +using System.Text.Json.Serialization; + +namespace VSH.Data.Miscellaneous; + +public class AppSettings +{ + [JsonPropertyName("General")] + public GeneralConfiguration General { get; set; } + + [JsonPropertyName("Serilog")] + public SerilogConfiguration Serilog { get; set; } + + public class GeneralConfiguration + { + public const string Name = "General"; + + [JsonPropertyName("StoreName")] + public string StoreName { get; set; } + + [JsonPropertyName("LegalName")] + public string LegalName { get; set; } + + [JsonPropertyName("ShortStoreName")] + public string ShortStoreName { get; set; } + + [JsonPropertyName("DefaultCulture")] + public string DefaultCulture { get; set; } + + [JsonPropertyName("GoogleMapsUrl")] + public string GoogleMapsUrl { get; set; } + + [JsonPropertyName("DefaultDescription")] + public string DefaultDescription { get; set; } + } + + public class SerilogConfiguration + { + public const string Name = "Serilog"; + + [JsonPropertyName("Using")] + public string[] Using { get; set; } + + [JsonPropertyName("MinimumLevel")] + public MinimumLevel MinimumLevel { get; set; } + + [JsonPropertyName("WriteTo")] + public WriteTo[] WriteTo { get; set; } + + [JsonPropertyName("Enrich")] + public string[] Enrich { get; set; } + + [JsonPropertyName("Destructure")] + public Destructure[] Destructure { get; set; } + + [JsonPropertyName("Properties")] + public Properties Properties { get; set; } + } + + public class Destructure + { + [JsonPropertyName("Name")] + public string Name { get; set; } + + [JsonPropertyName("Args")] + public Args Args { get; set; } + } + + public class Args + { + [JsonPropertyName("maximumDestructuringDepth")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public long? MaximumDestructuringDepth { get; set; } + + [JsonPropertyName("maximumStringLength")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public long? MaximumStringLength { get; set; } + + [JsonPropertyName("maximumCollectionCount")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public long? MaximumCollectionCount { get; set; } + } + + public class MinimumLevel + { + [JsonPropertyName("Default")] + public string Default { get; set; } + + [JsonPropertyName("Override")] + public Override Override { get; set; } + } + + public class Override + { + [JsonPropertyName("Microsoft")] + public string Microsoft { get; set; } + + [JsonPropertyName("System")] + public string System { get; set; } + + [JsonPropertyName("Microsoft.AspNetCore")] + public string MicrosoftAspNetCore { get; set; } + + [JsonPropertyName("Microsoft.Hosting")] + public string MicrosoftHosting { get; set; } + } + + public class Properties + { + [JsonPropertyName("Application")] + public string Application { get; set; } + } + + public class WriteTo + { + [JsonPropertyName("Name")] + public string Name { get; set; } + } +}
\ No newline at end of file diff --git a/src/Data/Miscellaneous/OpenGraphData.cs b/src/Data/Miscellaneous/OpenGraphData.cs new file mode 100644 index 0000000..5bf33fe --- /dev/null +++ b/src/Data/Miscellaneous/OpenGraphData.cs @@ -0,0 +1,12 @@ +namespace VSH.Data.Miscellaneous; + +public class OpenGraphData +{ + public string Type { get; set; } + public string Locale { get; set; } + public string Url { get; set; } + public string Title { get; set; } + public string Description { get; set; } + public string SiteName { get; set; } + public string Image { get; set; } +}
\ No newline at end of file diff --git a/src/Data/Payloads/CreateProductDto.cs b/src/Data/Payloads/CreateProductDto.cs new file mode 100644 index 0000000..eada16e --- /dev/null +++ b/src/Data/Payloads/CreateProductDto.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using VSH.Data.Enums; + +namespace VSH.Data.Payloads; + +public class CreateProductDto +{ + public string Name { get; set; } + public string Description { get; set; } + public double Price { get; set; } + public PriceSuffix PriceSuffix { get; set; } + public Guid CategoryId { get; set; } + public List<TProductImage> Images { get; set; } + public int Count { get; set; } + + public class TProductImage + { + public string FileName { get; set; } + public int Order { get; set; } + } +}
\ No newline at end of file diff --git a/src/Data/Payloads/LoginPayload.cs b/src/Data/Payloads/LoginPayload.cs new file mode 100644 index 0000000..8e4f461 --- /dev/null +++ b/src/Data/Payloads/LoginPayload.cs @@ -0,0 +1,8 @@ +namespace VSH.Data.Payloads; + +public record LoginPayload +{ + public string Username { get; set; } + public string Password { get; set; } + public bool Persist { get; set; } +}
\ No newline at end of file diff --git a/src/Data/Payloads/UpdatePasswordPayload.cs b/src/Data/Payloads/UpdatePasswordPayload.cs new file mode 100644 index 0000000..4105eb4 --- /dev/null +++ b/src/Data/Payloads/UpdatePasswordPayload.cs @@ -0,0 +1,6 @@ +namespace VSH.Data.Payloads; + +public class UpdatePasswordPayload +{ + public string NewPassword { get; set; } +}
\ No newline at end of file diff --git a/src/Data/Payloads/ValidateOrderPayload.cs b/src/Data/Payloads/ValidateOrderPayload.cs new file mode 100644 index 0000000..d3aee82 --- /dev/null +++ b/src/Data/Payloads/ValidateOrderPayload.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace VSH.Data.Payloads; + +public record ValidateOrderPayload +{ + public List<ProductValidationDto> Products { get; set; } + + public class ProductValidationDto + { + public Guid Id { get; set; } + public int Count { get; set; } + } +}
\ No newline at end of file diff --git a/src/Data/Results/AppValidationResult.cs b/src/Data/Results/AppValidationResult.cs new file mode 100644 index 0000000..0b1c967 --- /dev/null +++ b/src/Data/Results/AppValidationResult.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace VSH.Data.Results; + +public class AppValidationResult +{ + public AppValidationResult() { + Errors = new List<ValidationError>(); + } + + public bool IsValid => !Errors.Any(); + public List<ValidationError> Errors { get; set; } + + + public class ValidationError + { + public ValidationError(Guid id = default) { + Id = id != default ? id : null; + Errors = new List<string>(); + } + + public Guid? Id { get; set; } + public List<string> Errors { get; set; } + } +}
\ No newline at end of file diff --git a/src/Data/Results/ErrorResult.cs b/src/Data/Results/ErrorResult.cs new file mode 100644 index 0000000..60d1b1d --- /dev/null +++ b/src/Data/Results/ErrorResult.cs @@ -0,0 +1,12 @@ +namespace VSH.Data.Results; + +public class ErrorResult +{ + public ErrorResult(string title = default, string message = default) { + Title = title; + Message = message; + } + + public string Title { get; set; } + public string Message { get; set; } +}
\ No newline at end of file diff --git a/src/Data/Static/AppCookies.cs b/src/Data/Static/AppCookies.cs new file mode 100644 index 0000000..711d59e --- /dev/null +++ b/src/Data/Static/AppCookies.cs @@ -0,0 +1,21 @@ +using VSH.Data.Miscellaneous; + +namespace VSH.Data.Static; + +public static class AppCookies +{ + public static AppCookie Xsrf => new() { + Name = "vsh_xsrf", + Required = true + }; + + public static AppCookie Session => new() { + Name = "vsh_session", + Required = true + }; + + public static AppCookie Culture => new() { + Name = "vsh_culture", + Required = false + }; +}
\ No newline at end of file diff --git a/src/Data/Static/AppPaths.cs b/src/Data/Static/AppPaths.cs new file mode 100644 index 0000000..4073a75 --- /dev/null +++ b/src/Data/Static/AppPaths.cs @@ -0,0 +1,40 @@ +using System.IO; +using VSH.Data.Miscellaneous; + +namespace VSH.Data.Static; + +public static class AppPaths +{ + public static AppPath WwwRoot => new() { + HostPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"), + WebPath = "/" + }; + + public static AppPath Assets => new() { + HostPath = Path.Combine(WwwRoot.HostPath, "assets"), + WebPath = "/assets" + }; + + public static AppPath ProductImages => new() { + HostPath = Path.Combine(Assets.HostPath, "images", "products"), + WebPath = Path.Combine(Assets.WebPath, "images", "products") + }; + + public static AppPath DocumentImages => new() { + HostPath = Path.Combine(Assets.HostPath, "images", "documents"), + WebPath = Path.Combine(Assets.WebPath, "images", "documents") + }; + + public static AppPath DataProtectionKeys => new() { + HostPath = Path.Combine(AppData.HostPath, "DPKeys"), + }; + + public static AppPath AppData => new() { + HostPath = Path.Combine(Directory.GetCurrentDirectory(), "AppData"), + }; + + public static AppPath DefaultProductImage => new() { + HostPath = Path.Combine(Assets.HostPath, "profile", "innrammet.svg"), + WebPath = Path.Combine(Assets.WebPath, "profile", "innrammet.svg") + }; +}
\ No newline at end of file |
