diff --git a/Biskilog Accounting.sln b/Biskilog Accounting.sln new file mode 100644 index 0000000..06dd1e5 --- /dev/null +++ b/Biskilog Accounting.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33530.505 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Biskilog Accounting.Server", "Server\Biskilog Accounting.Server.csproj", "{003D3EA8-7344-4667-AE14-E749071197A0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Biskilog Accounting.Client", "Client\Biskilog Accounting.Client.csproj", "{D0EA7A4F-F071-45AE-8A3E-0B17BA7CD8A7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Biskilog Accounting.Shared", "Shared\Biskilog Accounting.Shared.csproj", "{48490CB4-D5CE-46FE-9A7A-FBC91980D262}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {003D3EA8-7344-4667-AE14-E749071197A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {003D3EA8-7344-4667-AE14-E749071197A0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {003D3EA8-7344-4667-AE14-E749071197A0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {003D3EA8-7344-4667-AE14-E749071197A0}.Release|Any CPU.Build.0 = Release|Any CPU + {D0EA7A4F-F071-45AE-8A3E-0B17BA7CD8A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0EA7A4F-F071-45AE-8A3E-0B17BA7CD8A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0EA7A4F-F071-45AE-8A3E-0B17BA7CD8A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0EA7A4F-F071-45AE-8A3E-0B17BA7CD8A7}.Release|Any CPU.Build.0 = Release|Any CPU + {48490CB4-D5CE-46FE-9A7A-FBC91980D262}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {48490CB4-D5CE-46FE-9A7A-FBC91980D262}.Debug|Any CPU.Build.0 = Debug|Any CPU + {48490CB4-D5CE-46FE-9A7A-FBC91980D262}.Release|Any CPU.ActiveCfg = Release|Any CPU + {48490CB4-D5CE-46FE-9A7A-FBC91980D262}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {96064220-88F8-4A9A-93BE-18714368EC27} + EndGlobalSection +EndGlobal diff --git a/Client/App.razor b/Client/App.razor new file mode 100644 index 0000000..6fd3ed1 --- /dev/null +++ b/Client/App.razor @@ -0,0 +1,12 @@ + + + + + + + Not found + +

Sorry, there's nothing at this address.

+
+
+
diff --git a/Client/Biskilog Accounting.Client.csproj b/Client/Biskilog Accounting.Client.csproj new file mode 100644 index 0000000..4f36df1 --- /dev/null +++ b/Client/Biskilog Accounting.Client.csproj @@ -0,0 +1,25 @@ + + + + net7.0 + enable + enable + service-worker-assets.js + $(AssemblyName.Replace(' ', '_')) + + + + + + + + + + + + + + + + + diff --git a/Client/Layouts/AuthLayout.razor b/Client/Layouts/AuthLayout.razor new file mode 100644 index 0000000..0acbf02 --- /dev/null +++ b/Client/Layouts/AuthLayout.razor @@ -0,0 +1,6 @@ +@namespace Biskilog_Accounting +@inherits LayoutComponentBase + +
+ @Body +
\ No newline at end of file diff --git a/Client/Layouts/AuthLayout.razor.css b/Client/Layouts/AuthLayout.razor.css new file mode 100644 index 0000000..8a1e565 --- /dev/null +++ b/Client/Layouts/AuthLayout.razor.css @@ -0,0 +1,22 @@ +.gradient-custom-2 { + /* fallback for old browsers */ + background: #fccb90; + /* Chrome 10-25, Safari 5.1-6 */ + /* Chrome 10-25, Safari 5.1-6 */ + background: -webkit-linear-gradient(to right, rgb(20 158 132 / 76%), rgb(10 10 56/100%)); + /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + background: linear-gradient(to right, rgb(20 158 132 / 76%), rgb(10 10 56/100%)); +} + +@media (min-width: 768px) { + .gradient-form { + height: 100vh !important; + } +} + +@media (min-width: 769px) { + .gradient-custom-2 { + border-top-right-radius: .3rem; + border-bottom-right-radius: .3rem; + } +} \ No newline at end of file diff --git a/Client/MainLayout.razor b/Client/MainLayout.razor new file mode 100644 index 0000000..de2be6c --- /dev/null +++ b/Client/MainLayout.razor @@ -0,0 +1,5 @@ +@inherits LayoutComponentBase + +
+ @Body +
diff --git a/Client/Pages/Auth/Login.razor b/Client/Pages/Auth/Login.razor new file mode 100644 index 0000000..9c7ec4a --- /dev/null +++ b/Client/Pages/Auth/Login.razor @@ -0,0 +1,132 @@ +@layout AuthLayout +@page "/" + +
+
+
+
+
+
+
+
+ +
+ logo +

Biskilog Accounting

+
+ +
+

Please login to your account

+ +
+ + +
+ +
+ + +
+ +
+ + Forgot password? +
+ +
+ + +
+ +
+ +
+
+
+
+

We are more than just a company

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud + exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +

+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/Client/Pages/Index.razor b/Client/Pages/Index.razor new file mode 100644 index 0000000..8af1ce6 --- /dev/null +++ b/Client/Pages/Index.razor @@ -0,0 +1,3 @@ +@page "/welcome" + +

Hello, world!

diff --git a/Client/Program.cs b/Client/Program.cs new file mode 100644 index 0000000..fef3761 --- /dev/null +++ b/Client/Program.cs @@ -0,0 +1,14 @@ +using Biskilog_Accounting.Client; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; + +var builder = WebAssemblyHostBuilder.CreateDefault(args); +builder.RootComponents.Add("#app"); +builder.RootComponents.Add("head::after"); + +builder.Services.AddHttpClient("Biskilog_Accounting.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)); + +// Supply HttpClient instances that include access tokens when making requests to the server project +builder.Services.AddScoped(sp => sp.GetRequiredService().CreateClient("Biskilog_Accounting.ServerAPI")); + +await builder.Build().RunAsync(); diff --git a/Client/Properties/launchSettings.json b/Client/Properties/launchSettings.json new file mode 100644 index 0000000..62cae75 --- /dev/null +++ b/Client/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "iisSettings": { + "iisExpress": { + "applicationUrl": "http://localhost:24369", + "sslPort": 44366 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "http://localhost:5136", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "https://localhost:7247;http://localhost:5136", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Client/_Imports.razor b/Client/_Imports.razor new file mode 100644 index 0000000..b7485da --- /dev/null +++ b/Client/_Imports.razor @@ -0,0 +1,7 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.WebAssembly.Http +@using Microsoft.JSInterop +@using Biskilog_Accounting.Client diff --git a/Client/wwwroot/css/app.css b/Client/wwwroot/css/app.css new file mode 100644 index 0000000..ffcb043 --- /dev/null +++ b/Client/wwwroot/css/app.css @@ -0,0 +1,32 @@ +h1:focus { + outline: none; +} + +#blazor-error-ui { + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; +} + + #blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; + } + +.blazor-error-boundary { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; + padding: 1rem 1rem 1rem 3.7rem; + color: white; +} + + .blazor-error-boundary::after { + content: "An error has occurred." + } diff --git a/Client/wwwroot/icon-512.png b/Client/wwwroot/icon-512.png new file mode 100644 index 0000000..9371f7a Binary files /dev/null and b/Client/wwwroot/icon-512.png differ diff --git a/Client/wwwroot/index.html b/Client/wwwroot/index.html new file mode 100644 index 0000000..fe19158 --- /dev/null +++ b/Client/wwwroot/index.html @@ -0,0 +1,37 @@ + + + + + + Biskilog Accounting + + + + + + + + + + + + + + +
+ +
+ +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + + diff --git a/Client/wwwroot/manifest.json b/Client/wwwroot/manifest.json new file mode 100644 index 0000000..66f20ae --- /dev/null +++ b/Client/wwwroot/manifest.json @@ -0,0 +1,16 @@ +{ + "name": "Biskilog Accounting", + "short_name": "Biskilog", + "start_url": "./", + "display": "standalone", + "background_color": "#ffffff", + "theme_color": "#03173d", + "prefer_related_applications": false, + "icons": [ + { + "src": "icon-512.png", + "type": "image/png", + "sizes": "512x512" + } + ] +} diff --git a/Client/wwwroot/service-worker.js b/Client/wwwroot/service-worker.js new file mode 100644 index 0000000..fe614da --- /dev/null +++ b/Client/wwwroot/service-worker.js @@ -0,0 +1,4 @@ +// In development, always fetch from the network and do not enable offline support. +// This is because caching would make development more difficult (changes would not +// be reflected on the first load after each change). +self.addEventListener('fetch', () => { }); diff --git a/Client/wwwroot/service-worker.published.js b/Client/wwwroot/service-worker.published.js new file mode 100644 index 0000000..6b234d1 --- /dev/null +++ b/Client/wwwroot/service-worker.published.js @@ -0,0 +1,47 @@ +// Caution! Be sure you understand the caveats before publishing an application with +// offline support. See https://aka.ms/blazor-offline-considerations + +self.importScripts('./service-worker-assets.js'); +self.addEventListener('install', event => event.waitUntil(onInstall(event))); +self.addEventListener('activate', event => event.waitUntil(onActivate(event))); +self.addEventListener('fetch', event => event.respondWith(onFetch(event))); + +const cacheNamePrefix = 'offline-cache-'; +const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; +const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ]; +const offlineAssetsExclude = [ /^service-worker\.js$/ ]; + +async function onInstall(event) { + console.info('Service worker: Install'); + + // Fetch and cache all matching items from the assets manifest + const assetsRequests = self.assetsManifest.assets + .filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url))) + .filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url))) + .map(asset => new Request(asset.url, { integrity: asset.hash, cache: 'no-cache' })); + await caches.open(cacheName).then(cache => cache.addAll(assetsRequests)); +} + +async function onActivate(event) { + console.info('Service worker: Activate'); + + // Delete unused caches + const cacheKeys = await caches.keys(); + await Promise.all(cacheKeys + .filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName) + .map(key => caches.delete(key))); +} + +async function onFetch(event) { + let cachedResponse = null; + if (event.request.method === 'GET') { + // For all navigation requests, try to serve index.html from cache + const shouldServeIndexHtml = event.request.mode === 'navigate'; + + const request = shouldServeIndexHtml ? 'index.html' : event.request; + const cache = await caches.open(cacheName); + cachedResponse = await cache.match(request); + } + + return cachedResponse || fetch(event.request); +} diff --git a/Server/Biskilog Accounting.Server.csproj b/Server/Biskilog Accounting.Server.csproj new file mode 100644 index 0000000..4e7bb4c --- /dev/null +++ b/Server/Biskilog Accounting.Server.csproj @@ -0,0 +1,20 @@ + + + + net7.0 + enable + enable + Biskilog Accounting.Server + $(AssemblyName.Replace(' ', '_')) + + + + + + + + + + + + diff --git a/Server/Program.cs b/Server/Program.cs new file mode 100644 index 0000000..3af2c77 --- /dev/null +++ b/Server/Program.cs @@ -0,0 +1,31 @@ +using Microsoft.AspNetCore.ResponseCompression; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllersWithViews(); +builder.Services.AddRazorPages(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseWebAssemblyDebugging(); +} +else +{ + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseHttpsRedirection(); +app.UseBlazorFrameworkFiles(); +app.UseStaticFiles(); + +app.UseRouting(); + +app.MapRazorPages(); +app.MapControllers(); +app.MapFallbackToFile("index.html"); + +app.Run(); diff --git a/Server/Properties/launchSettings.json b/Server/Properties/launchSettings.json new file mode 100644 index 0000000..5e250c1 --- /dev/null +++ b/Server/Properties/launchSettings.json @@ -0,0 +1,44 @@ +{ + "profiles": { + "http": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "http://localhost:5136" + }, + "https": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "https://localhost:7247;http://localhost:5136" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}" + } + }, + "iisExpress": { + "applicationUrl": "http://localhost:24369", + "sslPort": 44366 + }, + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:54487/", + "sslPort": 44383 + } + } +} \ No newline at end of file diff --git a/Server/appsettings.Development.json b/Server/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/Server/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Server/appsettings.json b/Server/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/Server/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Shared/Biskilog Accounting.Shared.csproj b/Shared/Biskilog Accounting.Shared.csproj new file mode 100644 index 0000000..3c56617 --- /dev/null +++ b/Shared/Biskilog Accounting.Shared.csproj @@ -0,0 +1,12 @@ + + + + net7.0 + enable + enable + + + + + + diff --git a/Shared/SharedClass.cs b/Shared/SharedClass.cs new file mode 100644 index 0000000..bb016a8 --- /dev/null +++ b/Shared/SharedClass.cs @@ -0,0 +1 @@ +/* Shared classes can be referenced by both the Client and Server */