diff --git a/.gitignore b/.gitignore index 59c3b68..67de48d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ Frontend/node_modules Frontend/dist +Server/.vs +Server/bin +Server/obj +Server/Bibblan.csproj.user diff --git a/Frontend/package.json b/Frontend/package.json index a89d28c..ed14851 100644 --- a/Frontend/package.json +++ b/Frontend/package.json @@ -8,10 +8,11 @@ "build": "vite build" }, "devDependencies": { - "vite": "^7.1.4", - "vite-plugin-solid": "^2.11.8", + "@types/node": "^24.3.1", "terser": "^5.44.0", - "typescript": "^5.9.2" + "typescript": "^5.9.2", + "vite": "^7.1.4", + "vite-plugin-solid": "^2.11.8" }, "dependencies": { "solid-js": "^1.9.9" diff --git a/Frontend/src/App.tsx b/Frontend/src/App.tsx index c79f0d6..9c2e213 100644 --- a/Frontend/src/App.tsx +++ b/Frontend/src/App.tsx @@ -1,6 +1,20 @@ import type { Component } from "solid-js"; +import { createSignal, For, onMount } from "solid-js"; + +interface Weather { + date: string; + temperatureC: number; + temperatureF: number; + summary: string; +} const App: Component = () => { + const [weather, setWeather] = createSignal([]); + onMount(() => { + fetch("/api/weatherforecast") + .then((r) => r.json()) + .then(setWeather); + }); return (
@@ -15,6 +29,15 @@ const App: Component = () => { Learn Solid
+ + + {(item) => ( +
  • + {item.date} - {item.temperatureC}°C / {item.temperatureF}°F -{" "} + {item.summary} +
  • + )} +
    ); }; diff --git a/Frontend/tsconfig.json b/Frontend/tsconfig.json index 6197ad0..4596714 100644 --- a/Frontend/tsconfig.json +++ b/Frontend/tsconfig.json @@ -3,12 +3,12 @@ "strict": true, "target": "ESNext", "module": "ESNext", - "moduleResolution": "node", + "moduleResolution": "bundler", "allowSyntheticDefaultImports": true, "esModuleInterop": true, "jsx": "preserve", "jsxImportSource": "solid-js", - "types": ["vite/client"], + "types": ["vite/client", "node"], "noEmit": true, "isolatedModules": true } diff --git a/Frontend/vite.config.ts b/Frontend/vite.config.ts index 4fbf103..c94a4bc 100644 --- a/Frontend/vite.config.ts +++ b/Frontend/vite.config.ts @@ -1,8 +1,9 @@ import { defineConfig } from "vite"; import solidPlugin from "vite-plugin-solid"; import { env } from "process"; -//test -const target = env.BACKEND_URL ?? "https://localhost:5001"; + +const target = env.BACKEND_URL ?? "http://localhost:5084/"; //"https://localhost:7192/"; +console.log("vite backend:", target); export default defineConfig({ plugins: [solidPlugin()], diff --git a/Frontend/yarn.lock b/Frontend/yarn.lock index 08c1100..bcea427 100644 --- a/Frontend/yarn.lock +++ b/Frontend/yarn.lock @@ -475,6 +475,13 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== +"@types/node@^24.3.1": + version "24.3.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.3.1.tgz#b0a3fb2afed0ef98e8d7f06d46ef6349047709f3" + integrity sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g== + dependencies: + undici-types "~7.10.0" + acorn@^8.15.0: version "8.15.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" @@ -787,6 +794,11 @@ typescript@^5.9.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== +undici-types@~7.10.0: + version "7.10.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.10.0.tgz#4ac2e058ce56b462b056e629cc6a02393d3ff350" + integrity sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag== + update-browserslist-db@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" diff --git a/Server/Bibblan.csproj b/Server/Bibblan.csproj new file mode 100644 index 0000000..3defcaf --- /dev/null +++ b/Server/Bibblan.csproj @@ -0,0 +1,19 @@ + + + + net9.0 + enable + enable + ../Frontend + npm run dev + http://localhost:3000 + + + + + + 9.*-* + + + + diff --git a/Server/Bibblan.http b/Server/Bibblan.http new file mode 100644 index 0000000..3f4b363 --- /dev/null +++ b/Server/Bibblan.http @@ -0,0 +1,6 @@ +@Bibblan_HostAddress = http://localhost:5084 + +GET {{Bibblan_HostAddress}}/api/weatherforecast/ +Accept: application/json + +### diff --git a/Server/Bibblan.sln b/Server/Bibblan.sln new file mode 100644 index 0000000..f918ffd --- /dev/null +++ b/Server/Bibblan.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35728.132 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bibblan", "Bibblan.csproj", "{760702AA-30CE-4B49-BF4F-D8A9E01D5B6C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {760702AA-30CE-4B49-BF4F-D8A9E01D5B6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {760702AA-30CE-4B49-BF4F-D8A9E01D5B6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {760702AA-30CE-4B49-BF4F-D8A9E01D5B6C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {760702AA-30CE-4B49-BF4F-D8A9E01D5B6C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Server/CHANGELOG.md b/Server/CHANGELOG.md new file mode 100644 index 0000000..139854d --- /dev/null +++ b/Server/CHANGELOG.md @@ -0,0 +1,8 @@ +This file explains how Visual Studio created the project. + +The following steps were used to generate this project: +- Create new ASP\.NET Core Web API project. +- Update `launchSettings.json` to register the SPA proxy as a startup assembly. +- Update project file to add a reference to the frontend project and set SPA properties. +- Add project to the startup projects list. +- Write this file. diff --git a/Server/Controllers/WeatherForecastController.cs b/Server/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..21229c8 --- /dev/null +++ b/Server/Controllers/WeatherForecastController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Bibblan.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} diff --git a/Server/Program.cs b/Server/Program.cs new file mode 100644 index 0000000..1b52868 --- /dev/null +++ b/Server/Program.cs @@ -0,0 +1,28 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi +builder.Services.AddOpenApi(); + +var app = builder.Build(); + +app.UseDefaultFiles(); +app.MapStaticAssets(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.MapOpenApi(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +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..1ad8965 --- /dev/null +++ b/Server/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5084", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy" + } + } + } +} + diff --git a/Server/WeatherForecast.cs b/Server/WeatherForecast.cs new file mode 100644 index 0000000..ca7f606 --- /dev/null +++ b/Server/WeatherForecast.cs @@ -0,0 +1,13 @@ +namespace Bibblan +{ + public class WeatherForecast + { + public DateOnly Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } + } +} 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": "*" +}