ソースを参照

This Code is for Issues 1-1

1.2
Daniel Covington 3日前
コミット
f73d372f37
53個のファイルの変更1137行の追加97行の削除
  1. +16
    -0
      .gitignore
  2. +27
    -0
      Campaign_Tracker.Server.Tests/Campaign_Tracker.Server.Tests.csproj
  3. +34
    -0
      Campaign_Tracker.Server.Tests/HealthEndpointTests.cs
  4. +7
    -0
      Campaign_Tracker.Server/Campaign_Tracker.Server.http
  5. +26
    -0
      Campaign_Tracker.Server/Controllers/WeatherForecastController.cs
  6. +26
    -0
      Campaign_Tracker.Server/Program.cs
  7. +23
    -0
      Campaign_Tracker.Server/Properties/launchSettings.json
  8. +13
    -0
      Campaign_Tracker.Server/WeatherForecast.cs
  9. +8
    -0
      Campaign_Tracker.Server/appsettings.Development.json
  10. +9
    -0
      Campaign_Tracker.Server/appsettings.json
  11. +2
    -1
      Initial Description.txt
  12. +41
    -0
      README.md
  13. +67
    -25
      _bmad-output/implementation-artifacts/1-1-project-initialization-solution-scaffold.md
  14. +5
    -3
      _bmad-output/implementation-artifacts/1-10-municipality-account-profile.md
  15. +5
    -3
      _bmad-output/implementation-artifacts/1-11-municipality-operational-addresses.md
  16. +5
    -3
      _bmad-output/implementation-artifacts/1-12-municipality-service-contacts.md
  17. +6
    -4
      _bmad-output/implementation-artifacts/1-13-municipality-prior-cycle-service-defaults-view.md
  18. +7
    -5
      _bmad-output/implementation-artifacts/1-2-workspace-shell-ant-design-foundation.md
  19. +5
    -3
      _bmad-output/implementation-artifacts/1-3-keycloak-realm-configuration-oidc-integration.md
  20. +6
    -4
      _bmad-output/implementation-artifacts/1-4-keycloak-role-mapping-application-authorization.md
  21. +8
    -6
      _bmad-output/implementation-artifacts/1-5-shared-audit-logging-infrastructure.md
  22. +7
    -5
      _bmad-output/implementation-artifacts/1-6-legacy-anti-corruption-data-access-layer.md
  23. +5
    -3
      _bmad-output/implementation-artifacts/1-7-legacy-schema-compatibility-validation-gate.md
  24. +5
    -3
      _bmad-output/implementation-artifacts/1-8-legacy-identifier-linking-for-extension-records.md
  25. +8
    -6
      _bmad-output/implementation-artifacts/1-9-seed-system-reference-values-rule-defaults.md
  26. +8
    -5
      _bmad-output/implementation-artifacts/sprint-status.yaml
  27. +7
    -5
      _bmad-output/planning-artifacts/architecture.md
  28. +6
    -4
      _bmad-output/planning-artifacts/epics.md
  29. +3
    -2
      _bmad-output/planning-artifacts/implementation-readiness-report-2026-05-05.md
  30. +2
    -1
      _bmad-output/planning-artifacts/prd.md
  31. +2
    -1
      _bmad-output/planning-artifacts/ux-color-themes.html
  32. +3
    -2
      _bmad-output/planning-artifacts/ux-design-directions.html
  33. +2
    -1
      _bmad-output/planning-artifacts/ux-design-specification.md
  34. +3
    -2
      _bmad-output/planning-artifacts/validation-report-2026-04-03.md
  35. +24
    -0
      campaign-tracker-client/.gitignore
  36. +73
    -0
      campaign-tracker-client/README.md
  37. +22
    -0
      campaign-tracker-client/eslint.config.js
  38. +14
    -0
      campaign-tracker-client/index.html
  39. +31
    -0
      campaign-tracker-client/package.json
  40. +1
    -0
      campaign-tracker-client/public/favicon.svg
  41. +24
    -0
      campaign-tracker-client/public/icons.svg
  42. +184
    -0
      campaign-tracker-client/src/App.css
  43. +122
    -0
      campaign-tracker-client/src/App.tsx
  44. バイナリ
      campaign-tracker-client/src/assets/hero.png
  45. +1
    -0
      campaign-tracker-client/src/assets/react.svg
  46. +1
    -0
      campaign-tracker-client/src/assets/vite.svg
  47. +111
    -0
      campaign-tracker-client/src/index.css
  48. +10
    -0
      campaign-tracker-client/src/main.tsx
  49. +25
    -0
      campaign-tracker-client/tsconfig.app.json
  50. +7
    -0
      campaign-tracker-client/tsconfig.json
  51. +24
    -0
      campaign-tracker-client/tsconfig.node.json
  52. +7
    -0
      campaign-tracker-client/vite.config.ts
  53. +49
    -0
      campaign-tracker.sln

+ 16
- 0
.gitignore ファイルの表示

@@ -1,5 +1,21 @@
_bmad/
.agents/
.claude/
.idea/
gitea_token
package-lock.json
node_modules/
bin/
obj/
.env
.env.*
dist/
coverage/
*.log
*.user
*.suo
*.swp
*.DS_Store
Thumbs.db
Campaign_Tracker.Server/Campaign_Tracker.Server.csproj


+ 27
- 0
Campaign_Tracker.Server.Tests/Campaign_Tracker.Server.Tests.csproj ファイルの表示

@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Campaign_Tracker.Server\Campaign_Tracker.Server.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

</Project>


+ 34
- 0
Campaign_Tracker.Server.Tests/HealthEndpointTests.cs ファイルの表示

@@ -0,0 +1,34 @@
using System.Net;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Mvc.Testing;

namespace Campaign_Tracker.Server.Tests;

public class HealthEndpointTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;

public HealthEndpointTests(WebApplicationFactory<Program> factory)
{
_factory = factory;
}

[Fact]
public async Task GetHealth_ReturnsOkWithExpectedPayload()
{
using var client = _factory.CreateClient();

var response = await client.GetAsync("/health");
var payload = await response.Content.ReadFromJsonAsync<HealthResponse>();

Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(payload);
Assert.Equal("ok", payload.Status);
}

private sealed class HealthResponse
{
public string Status { get; init; } = string.Empty;
}
}


+ 7
- 0
Campaign_Tracker.Server/Campaign_Tracker.Server.http ファイルの表示

@@ -0,0 +1,7 @@
@Campaign_Tracker.Server_HostAddress = http://localhost:5254

GET {{Campaign_Tracker.Server_HostAddress}}/weatherforecast/
Accept: application/json

###


+ 26
- 0
Campaign_Tracker.Server/Controllers/WeatherForecastController.cs ファイルの表示

@@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Mvc;

namespace Campaign_Tracker.Server.Controllers;

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries =
[
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
];

[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> 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();
}
}


+ 26
- 0
Campaign_Tracker.Server/Program.cs ファイルの表示

@@ -0,0 +1,26 @@
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();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();
app.MapGet("/health", () => Results.Ok(new { status = "ok" }));

app.Run();

public partial class Program;

+ 23
- 0
Campaign_Tracker.Server/Properties/launchSettings.json ファイルの表示

@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5254",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7244;http://localhost:5254",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

+ 13
- 0
Campaign_Tracker.Server/WeatherForecast.cs ファイルの表示

@@ -0,0 +1,13 @@
namespace Campaign_Tracker.Server;

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; }
}


+ 8
- 0
Campaign_Tracker.Server/appsettings.Development.json ファイルの表示

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

+ 9
- 0
Campaign_Tracker.Server/appsettings.json ファイルの表示

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

+ 2
- 1
Initial Description.txt ファイルの表示

@@ -2,7 +2,7 @@ looking at the Client Database Plan.xlsx and Access_Schema.txt in the Initial Do



Continue the `$bmad-create-architecture` workflow from where we left off in `C:\Users\danielc.NTP\Desktop\Brians Client Route Reports App`.
Continue the `$bmad-create-architecture` workflow from where we left off in `C:\Users\danielc.NTP\Desktop\Campaign_Tracker App`.

Current status:
- `Step 3` is already approved and saved in `_bmad-output/planning-artifacts/architecture.md` (with `stepsCompleted: [1,2,3]`).
@@ -22,3 +22,4 @@ Please:
2) Update frontmatter `stepsCompleted` to include `4`.
3) Load Step 5 and continue with normal A/P/C workflow.
4) Show me the Step 5 draft and menu.


+ 41
- 0
README.md ファイルの表示

@@ -0,0 +1,41 @@
# Campaign_Tracker App

## Prerequisites

- .NET SDK 10.0+
- Node.js 20.19+ (or 22.12+)

## Run Commands

### Server

```powershell
dotnet restore .\campaign-tracker.sln
dotnet build .\campaign-tracker.sln
dotnet run --project .\Campaign_Tracker.Server\Campaign_Tracker.Server.csproj
```

Health check:

```powershell
Invoke-WebRequest http://localhost:5000/health
```

### Client

```powershell
cd .\campaign-tracker-client
npm install
npm run dev
```

### Tests

```powershell
dotnet test .\campaign-tracker.sln
cd .\campaign-tracker-client
npm run lint
npm run build
```



+ 67
- 25
_bmad-output/implementation-artifacts/1-1-project-initialization-solution-scaffold.md ファイルの表示

@@ -1,6 +1,6 @@
# Story 1.1: Project Initialization & Solution Scaffold

Status: ready-for-dev
Status: review

## Story

@@ -10,31 +10,31 @@ so that the team has a working, runnable baseline with the correct project struc

## Acceptance Criteria

1. Given the initialization commands are run (`dotnet new sln`, `dotnet new webapi`, `npm create vite@latest --template react-ts`) when the solution builds, then both `BriansClientRouteReports.Server` and `brians-client-route-reports-client` compile without errors.
1. Given the initialization commands are run (`dotnet new sln`, `dotnet new webapi`, `npm create vite@latest --template react-ts`) when the solution builds, then both `Campaign_Tracker.Server` and `campaign-tracker-client` compile without errors.
2. Given the solution is running locally, when the Vite dev server starts, then the React app loads at the configured local URL with no console errors.
3. Given the server is running, when `GET /health` is called, then it returns `200 OK` with a status payload.
4. Given the solution structure is created, when reviewed against the architecture decision, then the `.sln` file, server project folder, and client project folder exist at expected paths and `.gitignore` excludes `node_modules`, `bin`, `obj`, and `.env` files.

## Tasks / Subtasks

- [ ] Create baseline solution and projects (AC: 1, 4)
- [ ] Run `dotnet new sln -n brians-client-route-reports` at repo root.
- [ ] Run `dotnet new webapi -n BriansClientRouteReports.Server -f net10.0 --use-controllers`.
- [ ] Add server project to solution: `dotnet sln add .\\BriansClientRouteReports.Server\\BriansClientRouteReports.Server.csproj`.
- [ ] Run `npm create vite@latest brians-client-route-reports-client -- --template react-ts`.
- [ ] Add operational baseline hardening files (AC: 4)
- [ ] Add/update root `.gitignore` with `.env`, `node_modules/`, `bin/`, `obj/`, and common build artifacts.
- [ ] Ensure folders are exactly:
- `./BriansClientRouteReports.Server/`
- `./brians-client-route-reports-client/`
- `./brians-client-route-reports.sln`
- [ ] Implement health endpoint (AC: 3)
- [ ] Ensure server exposes `GET /health` returning JSON payload and HTTP 200.
- [ ] Add lightweight server integration check for `/health` response shape and status.
- [ ] Verify local run and build paths (AC: 1, 2, 3)
- [ ] Validate `dotnet build` succeeds for server and solution.
- [ ] Validate client install and dev start (`npm install`, `npm run dev`) succeeds with no runtime console errors on first render.
- [ ] Capture exact run commands in README or implementation notes for handoff.
- [x] Create baseline solution and projects (AC: 1, 4)
- [x] Run `dotnet new sln -n campaign-tracker` at repo root.
- [x] Run `dotnet new webapi -n Campaign_Tracker.Server -f net10.0 --use-controllers`.
- [x] Add server project to solution: `dotnet sln add .\\Campaign_Tracker.Server\\Campaign_Tracker.Server.csproj`.
- [x] Run `npm create vite@latest campaign-tracker-client -- --template react-ts`.
- [x] Add operational baseline hardening files (AC: 4)
- [x] Add/update root `.gitignore` with `.env`, `node_modules/`, `bin/`, `obj/`, and common build artifacts.
- [x] Ensure folders are exactly:
- `./Campaign_Tracker.Server/`
- `./campaign-tracker-client/`
- `./campaign-tracker.sln`
- [x] Implement health endpoint (AC: 3)
- [x] Ensure server exposes `GET /health` returning JSON payload and HTTP 200.
- [x] Add lightweight server integration check for `/health` response shape and status.
- [x] Verify local run and build paths (AC: 1, 2, 3)
- [x] Validate `dotnet build` succeeds for server and solution.
- [x] Validate client install and dev start (`npm install`, `npm run dev`) succeeds with no runtime console errors on first render.
- [x] Capture exact run commands in README or implementation notes for handoff.

## Dev Notes

@@ -58,9 +58,9 @@ so that the team has a working, runnable baseline with the correct project struc
### File Structure Requirements

- Required outputs:
- `brians-client-route-reports.sln`
- `BriansClientRouteReports.Server/BriansClientRouteReports.Server.csproj`
- `brians-client-route-reports-client/package.json`
- `campaign-tracker.sln`
- `Campaign_Tracker.Server/Campaign_Tracker.Server.csproj`
- `campaign-tracker-client/package.json`
- Keep server and client sibling directories at repo root.

### Testing Requirements
@@ -94,12 +94,54 @@ GPT-5 Codex

- Sprint source file: `_bmad-output/implementation-artifacts/sprint-status.yaml`
- Requirement source files: `epics.md`, `architecture.md`, `ux-design-specification.md`
- Build/test commands: `dotnet build`, `dotnet test`, `npm install`, `npm run lint`, `npm run build`
- Runtime smoke checks: `GET /health` integration test and Vite startup probe on `http://127.0.0.1:5173`

### Completion Notes List

- Comprehensive context generated for Story 1.1 with explicit guardrails, commands, and scope boundaries.
- Story is intentionally constrained to scaffold readiness and health-check baseline.
- Created root solution scaffold (`campaign-tracker.sln`), ASP.NET Core `net10.0` API, and Vite React TypeScript client.
- Updated root `.gitignore` with required exclusions (`.env`, `node_modules/`, `bin/`, `obj/`) plus standard build artifacts.
- Implemented `GET /health` in server startup pipeline returning `{ "status": "ok" }` with HTTP 200.
- Added lightweight server integration test coverage for `/health` status code and payload shape.
- Verified solution and server builds, server tests, client lint/build, and client dev-server startup.
- Captured exact local run/test commands in root `README.md`.

### File List

- `.gitignore`
- `README.md`
- `campaign-tracker.sln`
- `Campaign_Tracker.Server/Campaign_Tracker.Server.csproj`
- `Campaign_Tracker.Server/Program.cs`
- `Campaign_Tracker.Server/WeatherForecast.cs`
- `Campaign_Tracker.Server/Controllers/WeatherForecastController.cs`
- `Campaign_Tracker.Server/appsettings.json`
- `Campaign_Tracker.Server/appsettings.Development.json`
- `Campaign_Tracker.Server/Properties/launchSettings.json`
- `Campaign_Tracker.Server/Campaign_Tracker.Server.http`
- `Campaign_Tracker.Server.Tests/Campaign_Tracker.Server.Tests.csproj`
- `Campaign_Tracker.Server.Tests/HealthEndpointTests.cs`
- `campaign-tracker-client/package.json`
- `campaign-tracker-client/README.md`
- `campaign-tracker-client/index.html`
- `campaign-tracker-client/eslint.config.js`
- `campaign-tracker-client/vite.config.ts`
- `campaign-tracker-client/tsconfig.json`
- `campaign-tracker-client/tsconfig.app.json`
- `campaign-tracker-client/tsconfig.node.json`
- `campaign-tracker-client/public/favicon.svg`
- `campaign-tracker-client/public/icons.svg`
- `campaign-tracker-client/src/main.tsx`
- `campaign-tracker-client/src/App.tsx`
- `campaign-tracker-client/src/App.css`
- `campaign-tracker-client/src/index.css`
- `campaign-tracker-client/src/assets/react.svg`
- `campaign-tracker-client/src/assets/vite.svg`
- `campaign-tracker-client/src/assets/hero.png`
- `_bmad-output/implementation-artifacts/1-1-project-initialization-solution-scaffold.md`

### Change Log

- 2026-05-05: Completed Story 1.1 scaffold implementation, health endpoint, integration test coverage, and local run/build verification.



+ 5
- 3
_bmad-output/implementation-artifacts/1-10-municipality-account-profile.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.10: Municipality Account Profile
# Story 1.10: Municipality Account Profile

Status: ready-for-dev

@@ -38,8 +38,8 @@ so that permanent municipality data is managed in the extension layer without mo

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -65,3 +65,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-10-municipality-account-profile.md`



+ 5
- 3
_bmad-output/implementation-artifacts/1-11-municipality-operational-addresses.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.11: Municipality Operational Addresses
# Story 1.11: Municipality Operational Addresses

Status: ready-for-dev

@@ -38,8 +38,8 @@ so that election services reference current address information without dependin

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -65,3 +65,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-11-municipality-operational-addresses.md`



+ 5
- 3
_bmad-output/implementation-artifacts/1-12-municipality-service-contacts.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.12: Municipality Service Contacts
# Story 1.12: Municipality Service Contacts

Status: ready-for-dev

@@ -38,8 +38,8 @@ so that the right people can be reached during election operations without consu

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -65,3 +65,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-12-municipality-service-contacts.md`



+ 6
- 4
_bmad-output/implementation-artifacts/1-13-municipality-prior-cycle-service-defaults-view.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.13: Municipality Prior-Cycle Service Defaults View
# Story 1.13: Municipality Prior-Cycle Service Defaults View

Status: ready-for-dev

@@ -12,7 +12,7 @@ so that I can reference proven configurations when setting up new election-cycle

1. **Given** a municipality has at least one completed election-cycle job **When** a client services user views the prior-cycle defaults panel **Then** the most recent cycle's service configurations are displayed as read-only reference data
2. **Given** a municipality has multiple prior cycles **When** the defaults panel is viewed **Then** the most recent cycle is shown by default with a cycle selector control to navigate older cycles
3. **Given** no prior cycles exist for a municipality **When** defaults are requested **Then** the system displays a clear "No prior cycle defaults available" state with guidance to create the first cycle **And** all data in this view is read-only — the apply-to-new-job action is out of scope for this story and delivered in Epic 2 (Story 2.4)
3. **Given** no prior cycles exist for a municipality **When** defaults are requested **Then** the system displays a clear "No prior cycle defaults available" state with guidance to create the first cycle **And** all data in this view is read-only the apply-to-new-job action is out of scope for this story and delivered in Epic 2 (Story 2.4)

## Tasks / Subtasks

@@ -35,8 +35,8 @@ so that I can reference proven configurations when setting up new election-cycle

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -62,3 +62,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-13-municipality-prior-cycle-service-defaults-view.md`



+ 7
- 5
_bmad-output/implementation-artifacts/1-2-workspace-shell-ant-design-foundation.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.2: Workspace Shell & Ant Design Foundation
# Story 1.2: Workspace Shell & Ant Design Foundation

Status: ready-for-dev

@@ -13,9 +13,9 @@ so that I have a predictable, accessible, and keyboard-navigable operational env
1. **Given** the app loads after authentication **When** an authenticated user enters the application **Then** the tri-pane layout renders with a left navigation pane, center content area, and collapsible right panel
2. **Given** the Ant Design token configuration is applied **When** the UI renders **Then** colorPrimary is #1F4E79, teal secondary is #0F766E, semantic status colors (success/warning/error/info/overdue) match the UX spec, and compact density profile is active (UX-DR1)
3. **Given** a user interacts with any focusable element **When** tabbing through the interface **Then** visible 2px focus indicators are present on all interactive elements with logical tab order (UX-DR9)
4. **Given** the viewport is 1280–1599px **When** the layout renders **Then** the right panel is collapsible and the tri-pane adapts to compact mode (UX-DR15)
4. **Given** the viewport is 12801599px **When** the layout renders **Then** the right panel is collapsible and the tri-pane adapts to compact mode (UX-DR15)
5. **Given** the viewport is below 1280px **When** the layout renders **Then** a reduced read mode with a support notice is displayed and full editing is not available
6. **Given** any status indicator renders **When** viewed **Then** status is conveyed with both color and a text label or icon — never color alone (UX-DR12)
6. **Given** any status indicator renders **When** viewed **Then** status is conveyed with both color and a text label or icon never color alone (UX-DR12)

## Tasks / Subtasks

@@ -40,8 +40,8 @@ so that I have a predictable, accessible, and keyboard-navigable operational env

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -67,3 +67,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-2-workspace-shell-ant-design-foundation.md`



+ 5
- 3
_bmad-output/implementation-artifacts/1-3-keycloak-realm-configuration-oidc-integration.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.3: Keycloak Realm Configuration & OIDC Integration
# Story 1.3: Keycloak Realm Configuration & OIDC Integration

Status: ready-for-dev

@@ -39,8 +39,8 @@ so that I can securely access the application with my organizational credentials

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -66,3 +66,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-3-keycloak-realm-configuration-oidc-integration.md`



+ 6
- 4
_bmad-output/implementation-artifacts/1-4-keycloak-role-mapping-application-authorization.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.4: Keycloak Role Mapping & Application Authorization
# Story 1.4: Keycloak Role Mapping & Application Authorization

Status: ready-for-dev

@@ -13,7 +13,7 @@ so that each user sees only the capabilities appropriate to their operational ro
1. **Given** a Keycloak user has the ClientServices role **When** they authenticate and navigate **Then** they can access municipality profile and election-cycle creation routes and cannot access admin-only or production-only routes
2. **Given** a Keycloak user has the Admin role **When** they authenticate **Then** they can access all application routes including admin-sensitive functions
3. **Given** a user without a recognized application role authenticates **When** they access any protected route **Then** they receive 403 Forbidden and the unauthorized access attempt is logged with actor identity
4. **Given** a privileged operation is performed **When** it completes **Then** the authorization check result, actor, and resource are captured by the audit logging service within 5 seconds (NFR6, NFR7) **And** roles ClientServices, Production, Transportation, Support, and Admin are managed entirely in Keycloak Admin Console — FR27 is satisfied without a custom role management UI
4. **Given** a privileged operation is performed **When** it completes **Then** the authorization check result, actor, and resource are captured by the audit logging service within 5 seconds (NFR6, NFR7) **And** roles ClientServices, Production, Transportation, Support, and Admin are managed entirely in Keycloak Admin Console FR27 is satisfied without a custom role management UI

## Tasks / Subtasks

@@ -38,8 +38,8 @@ so that each user sees only the capabilities appropriate to their operational ro

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -65,3 +65,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-4-keycloak-role-mapping-application-authorization.md`



+ 8
- 6
_bmad-output/implementation-artifacts/1-5-shared-audit-logging-infrastructure.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.5: Shared Audit Logging Infrastructure
# Story 1.5: Shared Audit Logging Infrastructure

Status: ready-for-dev

@@ -12,9 +12,9 @@ so that audit history is uniformly available across all application features fro

1. **Given** any security-relevant action occurs (auth event, permission check, privileged update) **When** the action completes **Then** the event is written to the audit log within 5 seconds including actor identity, timestamp (UTC), action type, resource identifier, and outcome (NFR7)
2. **Given** audit records are persisted **When** the retention policy is evaluated **Then** records are retained for at least 365 days and are not purgeable by standard application operations (NFR7)
3. **Given** any application feature calls the audit logging service **When** the call is made **Then** it succeeds using the shared service contract — the calling feature does not implement its own audit persistence
4. **Given** an audit record is written **When** retrieved for review **Then** it is append-only — no update or delete operations are available on audit records
5. **Given** the audit service is unavailable **When** an auditable action occurs **Then** the action is blocked or queued — auditable operations must not silently proceed without capture
3. **Given** any application feature calls the audit logging service **When** the call is made **Then** it succeeds using the shared service contract the calling feature does not implement its own audit persistence
4. **Given** an audit record is written **When** retrieved for review **Then** it is append-only no update or delete operations are available on audit records
5. **Given** the audit service is unavailable **When** an auditable action occurs **Then** the action is blocked or queued auditable operations must not silently proceed without capture

## Tasks / Subtasks

@@ -39,8 +39,8 @@ so that audit history is uniformly available across all application features fro

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -66,3 +66,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-5-shared-audit-logging-infrastructure.md`



+ 7
- 5
_bmad-output/implementation-artifacts/1-6-legacy-anti-corruption-data-access-layer.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.6: Legacy Anti-Corruption Data Access Layer
# Story 1.6: Legacy Anti-Corruption Data Access Layer

Status: ready-for-dev

@@ -11,9 +11,9 @@ so that legacy data is available to all features without any risk of schema muta
## Acceptance Criteria

1. **Given** a feature requests municipality or jurisdiction data **When** the anti-corruption layer is called **Then** it returns data joined by ID, JCode/JurisCode, or KitID without modifying any legacy table structure or content (NFR12)
2. **Given** the anti-corruption layer executes any query **When** the operation is inspected **Then** only SELECT operations are permitted — INSERT, UPDATE, and DELETE on legacy entities are blocked at the layer boundary
2. **Given** the anti-corruption layer executes any query **When** the operation is inspected **Then** only SELECT operations are permitted INSERT, UPDATE, and DELETE on legacy entities are blocked at the layer boundary
3. **Given** legacy data is returned through the layer **When** mapped to the application domain **Then** it is converted to strongly-typed domain model objects before being returned to any calling feature
4. **Given** any application code outside the layer attempts to query legacy tables directly **When** reviewed in code **Then** no such direct access exists — the anti-corruption layer is the sole access point for legacy data
4. **Given** any application code outside the layer attempts to query legacy tables directly **When** reviewed in code **Then** no such direct access exists the anti-corruption layer is the sole access point for legacy data

## Tasks / Subtasks

@@ -38,8 +38,8 @@ so that legacy data is available to all features without any risk of schema muta

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -65,3 +65,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-6-legacy-anti-corruption-data-access-layer.md`



+ 5
- 3
_bmad-output/implementation-artifacts/1-7-legacy-schema-compatibility-validation-gate.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.7: Legacy Schema Compatibility Validation Gate
# Story 1.7: Legacy Schema Compatibility Validation Gate

Status: ready-for-dev

@@ -39,8 +39,8 @@ so that every release can be gated on legacy integrity before deployment.

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -66,3 +66,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-7-legacy-schema-compatibility-validation-gate.md`



+ 5
- 3
_bmad-output/implementation-artifacts/1-8-legacy-identifier-linking-for-extension-records.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.8: Legacy Identifier Linking for Extension Records
# Story 1.8: Legacy Identifier Linking for Extension Records

Status: ready-for-dev

@@ -38,8 +38,8 @@ so that all new capabilities join deterministically to legacy Access records in

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -65,3 +65,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-8-legacy-identifier-linking-for-extension-records.md`



+ 8
- 6
_bmad-output/implementation-artifacts/1-9-seed-system-reference-values-rule-defaults.md ファイルの表示

@@ -1,4 +1,4 @@
# Story 1.9: Seed System Reference Values & Rule Defaults
# Story 1.9: Seed System Reference Values & Rule Defaults

Status: ready-for-dev

@@ -6,15 +6,15 @@ Status: ready-for-dev

As a a developer,
I want the system seeded with default reference values, required-field rules, and escalation rule defaults,
so that Epics 2–5 are immediately functional without requiring administrator configuration before use.
so that Epics 25 are immediately functional without requiring administrator configuration before use.

## Acceptance Criteria

1. **Given** the application initializes for the first time **When** the seed operation runs **Then** operational status sets, service template defaults, and extension-layer reference values are populated in the database
2. **Given** the seed runs **When** required-field rules are evaluated **Then** default readiness fields for election-cycle jobs are defined and evaluable by Epic 2's readiness status feature (FR29)
3. **Given** the seed runs **When** escalation rule defaults are checked **Then** at least one default rule exists covering overdue milestone alert scenarios (FR30)
4. **Given** the seed operation is run multiple times **When** it completes **Then** no duplicate records are created — the operation is fully idempotent
5. **Given** Epic 6 admin UIs update reference values or rules **When** the changes are saved **Then** they persist independently of the seed — rerunning the seed does not overwrite admin-managed values
4. **Given** the seed operation is run multiple times **When** it completes **Then** no duplicate records are created the operation is fully idempotent
5. **Given** Epic 6 admin UIs update reference values or rules **When** the changes are saved **Then** they persist independently of the seed rerunning the seed does not overwrite admin-managed values

## Tasks / Subtasks

@@ -39,8 +39,8 @@ so that Epics 2–5 are immediately functional without requiring administra

### Project Structure Notes

- Backend: `BriansClientRouteReports.Server/`
- Frontend: `brians-client-route-reports-client/`
- Backend: `Campaign_Tracker.Server/`
- Frontend: `campaign-tracker-client/`
- Story artifacts: `_bmad-output/implementation-artifacts/`

### References
@@ -66,3 +66,5 @@ GPT-5 Codex
### File List

- `_bmad-output/implementation-artifacts/1-9-seed-system-reference-values-rule-defaults.md`



+ 8
- 5
_bmad-output/implementation-artifacts/sprint-status.yaml ファイルの表示

@@ -1,6 +1,6 @@
# generated: 2026-05-05T12:00:44-04:00
# generated: 2026-05-05T12:00:44-04:00
# last_updated: 2026-05-05T12:09:17-04:00
# project: Brians Client Route Reports App
# project: Campaign_Tracker App
# project_key: NOKEY
# tracking_system: file-system
# story_location: _bmad-output/implementation-artifacts
@@ -35,15 +35,15 @@
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)

generated: '2026-05-05T12:00:44-04:00'
last_updated: '2026-05-05T12:09:17-04:00'
project: 'Brians Client Route Reports App'
last_updated: '2026-05-05T12:41:10-04:00'
project: 'Campaign_Tracker App'
project_key: 'NOKEY'
tracking_system: 'file-system'
story_location: '_bmad-output/implementation-artifacts'

development_status:
epic-1: in-progress
1-1-project-initialization-solution-scaffold: ready-for-dev
1-1-project-initialization-solution-scaffold: review
1-2-workspace-shell-ant-design-foundation: ready-for-dev
1-3-keycloak-realm-configuration-oidc-integration: ready-for-dev
1-4-keycloak-role-mapping-application-authorization: ready-for-dev
@@ -100,3 +100,6 @@ development_status:







+ 7
- 5
_bmad-output/planning-artifacts/architecture.md ファイルの表示

@@ -12,7 +12,7 @@ inputDocuments:
- Initial Documents/Client Database Plan.xlsx
- _bmad-output/planning-artifacts/client-database-plan-extract.txt
workflowType: 'architecture'
project_name: 'Brians Client Route Reports App'
project_name: 'Campaign_Tracker App'
user_name: 'Daniel'
date: '2026-04-03'
---
@@ -141,10 +141,10 @@ This aligns directly with the requested architecture (`.NET 10 ASP` + `TypeScrip
**Initialization Command:**

```bash
dotnet new sln -n brians-client-route-reports
dotnet new webapi -n BriansClientRouteReports.Server -f net10.0 --use-controllers
dotnet sln add .\BriansClientRouteReports.Server\BriansClientRouteReports.Server.csproj
npm create vite@latest brians-client-route-reports-client -- --template react-ts
dotnet new sln -n campaign-tracker
dotnet new webapi -n Campaign_Tracker.Server -f net10.0 --use-controllers
dotnet sln add .\Campaign_Tracker.Server\Campaign_Tracker.Server.csproj
npm create vite@latest campaign-tracker-client -- --template react-ts
```

**Architectural Decisions Provided by Starter:**
@@ -202,3 +202,5 @@ Imported contact and proofing-related fields are role-protected and auditable.
- Least-privilege visibility by role
- All sensitive field changes captured in audit stream
- No bypass around SafeCommitRail-equivalent validation for publish-sensitive updates



+ 6
- 4
_bmad-output/planning-artifacts/epics.md ファイルの表示

@@ -9,11 +9,11 @@ inputDocuments:
- _bmad-output/planning-artifacts/ux-design-specification.md
---

# Brians Client Route Reports App - Epic Breakdown
# Campaign_Tracker App - Epic Breakdown

## Overview

This document provides the complete epic and story breakdown for Brians Client Route Reports App, decomposing the requirements from the PRD, UX Design, and Architecture into implementable stories.
This document provides the complete epic and story breakdown for Campaign_Tracker App, decomposing the requirements from the PRD, UX Design, and Architecture into implementable stories.

## Requirements Inventory

@@ -76,7 +76,7 @@ NFR17: Recovery procedures ensure no committed extension-record updates are lost

### Additional Requirements

- **Starter Template (Epic 1, Story 1)**: ASP.NET Core 10 Web API + Vite React TypeScript. Initialization commands: `dotnet new sln -n brians-client-route-reports`, `dotnet new webapi -n BriansClientRouteReports.Server -f net10.0 --use-controllers`, `dotnet sln add`, `npm create vite@latest brians-client-route-reports-client -- --template react-ts`.
- **Starter Template (Epic 1, Story 1)**: ASP.NET Core 10 Web API + Vite React TypeScript. Initialization commands: `dotnet new sln -n campaign-tracker`, `dotnet new webapi -n Campaign_Tracker.Server -f net10.0 --use-controllers`, `dotnet sln add`, `npm create vite@latest campaign-tracker-client -- --template react-ts`.
- Anti-corruption data access layer required between modern services and immutable legacy Access structures.
- Separate operational write path (extension tables) from report read path (join/materialized/query layer) to reduce coupling.
- Join-key integrity (ID, JCode/JurisCode, KitID) is a platform concern requiring scheduled validation jobs and release-gate checks.
@@ -211,7 +211,7 @@ So that the team has a working, runnable baseline with the correct project struc

**Given** the initialization commands are run (`dotnet new sln`, `dotnet new webapi`, `npm create vite@latest --template react-ts`)
**When** the solution builds
**Then** both BriansClientRouteReports.Server and brians-client-route-reports-client compile without errors
**Then** both Campaign_Tracker.Server and campaign-tracker-client compile without errors

**Given** the solution is running locally
**When** the Vite dev server starts
@@ -1444,3 +1444,5 @@ So that data mismatches are triaged with clear ownership before they impact oper
**Given** unresolved high-severity mismatches remain
**When** operational export is attempted for affected scope
**Then** the system displays a blocking warning with a direct link to the reconciliation queue



+ 3
- 2
_bmad-output/planning-artifacts/implementation-readiness-report-2026-05-05.md ファイルの表示

@@ -7,7 +7,7 @@ stepsCompleted:
- step-05-epic-quality-review
- step-06-final-assessment
assessmentDate: "2026-05-05"
project: "Brians Client Route Reports App"
project: "Campaign_Tracker App"
documentsSelected:
prd: "_bmad-output/planning-artifacts/prd.md"
architecture: "_bmad-output/planning-artifacts/architecture.md"
@@ -18,7 +18,7 @@ documentsSelected:
# Implementation Readiness Assessment Report

**Date:** 2026-05-05
**Project:** Brians Client Route Reports App
**Project:** Campaign_Tracker App

## Step 1 - Document Discovery

@@ -288,3 +288,4 @@ This assessment identified no remaining critical or major issues after approved

Assessor: Codex (AI pair agent)
Assessment Date: 2026-05-05


+ 2
- 1
_bmad-output/planning-artifacts/prd.md ファイルの表示

@@ -35,7 +35,7 @@ classification:
projectContext: brownfield
---

# Product Requirements Document - Brians Client Route Reports App
# Product Requirements Document - Campaign_Tracker App

**Author:** Daniel
**Date:** 2026-04-03
@@ -395,3 +395,4 @@ Mitigation: strict MVP scope, milestone-based releases, and deferment of advance
- NFR15: Planned system availability target is 99.5% monthly during operational hours.
- NFR16: Every key milestone/status update is stored with audit history sufficient for operational reconstruction.
- NFR17: Recovery procedures ensure no committed extension-record updates are lost for the previous 24 hours of operations.


+ 2
- 1
_bmad-output/planning-artifacts/ux-color-themes.html ファイルの表示

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>UX Color Themes - Brians Client Route Reports App</title>
<title>UX Color Themes - Campaign_Tracker App</title>
<style>
body {
margin: 0;
@@ -96,3 +96,4 @@
</div>
</body>
</html>


+ 3
- 2
_bmad-output/planning-artifacts/ux-design-directions.html ファイルの表示

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>UX Design Directions - Brians Client Route Reports App</title>
<title>UX Design Directions - Campaign_Tracker App</title>
<style>
:root {
--bg: #f7f9fc;
@@ -255,7 +255,7 @@
</head>
<body>
<header class="topbar">
<h1>Design Direction Showcase • Brians Client Route Reports App</h1>
<h1>Design Direction Showcase • Campaign_Tracker App</h1>
<div class="legend">
<span class="pill">PC-first</span>
<span class="pill">Ant Design Foundation</span>
@@ -449,3 +449,4 @@
</main>
</body>
</html>


+ 2
- 1
_bmad-output/planning-artifacts/ux-design-specification.md ファイルの表示

@@ -21,7 +21,7 @@ inputDocuments:
- _bmad-output/planning-artifacts/client-database-plan-extract.txt
---

# UX Design Specification Brians Client Route Reports App
# UX Design Specification Campaign_Tracker App

**Author:** Daniel
**Date:** 2026-04-03
@@ -869,3 +869,4 @@ For proof/contact fields (`Proof Sent`, `Proof Approved`, contact assignment val
- Show explicit role-based visibility and edit affordances
- Keep actor/timestamp provenance visible where policy allows
- Preserve deterministic filtering/sorting behavior in all related report and queue views


+ 3
- 2
_bmad-output/planning-artifacts/validation-report-2026-04-03.md ファイルの表示

@@ -1,5 +1,5 @@
---
validationTarget: 'C:/Users/danielc.NTP/Desktop/Brians Client Route Reports App/_bmad-output/planning-artifacts/prd.md'
validationTarget: 'C:/Users/danielc.NTP/Desktop/Campaign_Tracker App/_bmad-output/planning-artifacts/prd.md'
validationDate: '2026-04-03'
inputDocuments:
- Initial Description.txt
@@ -26,7 +26,7 @@ overallStatus: 'Warning'

# PRD Validation Report

**PRD Being Validated:** C:/Users/danielc.NTP/Desktop/Brians Client Route Reports App/_bmad-output/planning-artifacts/prd.md
**PRD Being Validated:** C:/Users/danielc.NTP/Desktop/Campaign_Tracker App/_bmad-output/planning-artifacts/prd.md
**Validation Date:** 2026-04-03

## Input Documents
@@ -448,3 +448,4 @@ Several NFRs remain qualitative and need explicit test metrics/methods.
**Severity:** Warning

**Recommendation:** PRD is structurally complete and usable; address minor measurability/frontmatter refinements for full completeness.


+ 24
- 0
campaign-tracker-client/.gitignore ファイルの表示

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

+ 73
- 0
campaign-tracker-client/README.md ファイルの表示

@@ -0,0 +1,73 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)

## React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...

// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,

// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

+ 22
- 0
campaign-tracker-client/eslint.config.js ファイルの表示

@@ -0,0 +1,22 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
globals: globals.browser,
},
},
])

+ 14
- 0
campaign-tracker-client/index.html ファイルの表示

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>campaign-tracker-client</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>


+ 31
- 0
campaign-tracker-client/package.json ファイルの表示

@@ -0,0 +1,31 @@
{
"name": "campaign-tracker-client",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.2.5",
"react-dom": "^19.2.5"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@types/node": "^24.12.2",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
"eslint": "^10.2.1",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.5.0",
"typescript": "~6.0.2",
"typescript-eslint": "^8.58.2",
"vite": "^8.0.10"
}
}


+ 1
- 0
campaign-tracker-client/public/favicon.svg
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 24
- 0
campaign-tracker-client/public/icons.svg ファイルの表示

@@ -0,0 +1,24 @@
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="bluesky-icon" viewBox="0 0 16 17">
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
</symbol>
<symbol id="discord-icon" viewBox="0 0 20 19">
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
</symbol>
<symbol id="documentation-icon" viewBox="0 0 21 20">
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
</symbol>
<symbol id="github-icon" viewBox="0 0 19 19">
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
</symbol>
<symbol id="social-icon" viewBox="0 0 20 20">
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
</symbol>
<symbol id="x-icon" viewBox="0 0 19 19">
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
</symbol>
</svg>

+ 184
- 0
campaign-tracker-client/src/App.css ファイルの表示

@@ -0,0 +1,184 @@
.counter {
font-size: 16px;
padding: 5px 10px;
border-radius: 5px;
color: var(--accent);
background: var(--accent-bg);
border: 2px solid transparent;
transition: border-color 0.3s;
margin-bottom: 24px;

&:hover {
border-color: var(--accent-border);
}
&:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
}

.hero {
position: relative;

.base,
.framework,
.vite {
inset-inline: 0;
margin: 0 auto;
}

.base {
width: 170px;
position: relative;
z-index: 0;
}

.framework,
.vite {
position: absolute;
}

.framework {
z-index: 1;
top: 34px;
height: 28px;
transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
scale(1.4);
}

.vite {
z-index: 0;
top: 107px;
height: 26px;
width: auto;
transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
scale(0.8);
}
}

#center {
display: flex;
flex-direction: column;
gap: 25px;
place-content: center;
place-items: center;
flex-grow: 1;

@media (max-width: 1024px) {
padding: 32px 20px 24px;
gap: 18px;
}
}

#next-steps {
display: flex;
border-top: 1px solid var(--border);
text-align: left;

& > div {
flex: 1 1 0;
padding: 32px;
@media (max-width: 1024px) {
padding: 24px 20px;
}
}

.icon {
margin-bottom: 16px;
width: 22px;
height: 22px;
}

@media (max-width: 1024px) {
flex-direction: column;
text-align: center;
}
}

#docs {
border-right: 1px solid var(--border);

@media (max-width: 1024px) {
border-right: none;
border-bottom: 1px solid var(--border);
}
}

#next-steps ul {
list-style: none;
padding: 0;
display: flex;
gap: 8px;
margin: 32px 0 0;

.logo {
height: 18px;
}

a {
color: var(--text-h);
font-size: 16px;
border-radius: 6px;
background: var(--social-bg);
display: flex;
padding: 6px 12px;
align-items: center;
gap: 8px;
text-decoration: none;
transition: box-shadow 0.3s;

&:hover {
box-shadow: var(--shadow);
}
.button-icon {
height: 18px;
width: 18px;
}
}

@media (max-width: 1024px) {
margin-top: 20px;
flex-wrap: wrap;
justify-content: center;

li {
flex: 1 1 calc(50% - 8px);
}

a {
width: 100%;
justify-content: center;
box-sizing: border-box;
}
}
}

#spacer {
height: 88px;
border-top: 1px solid var(--border);
@media (max-width: 1024px) {
height: 48px;
}
}

.ticks {
position: relative;
width: 100%;

&::before,
&::after {
content: '';
position: absolute;
top: -4.5px;
border: 5px solid transparent;
}

&::before {
left: 0;
border-left-color: var(--border);
}
&::after {
right: 0;
border-right-color: var(--border);
}
}

+ 122
- 0
campaign-tracker-client/src/App.tsx ファイルの表示

@@ -0,0 +1,122 @@
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from './assets/vite.svg'
import heroImg from './assets/hero.png'
import './App.css'

function App() {
const [count, setCount] = useState(0)

return (
<>
<section id="center">
<div className="hero">
<img src={heroImg} className="base" width="170" height="179" alt="" />
<img src={reactLogo} className="framework" alt="React logo" />
<img src={viteLogo} className="vite" alt="Vite logo" />
</div>
<div>
<h1>Get started</h1>
<p>
Edit <code>src/App.tsx</code> and save to test <code>HMR</code>
</p>
</div>
<button
type="button"
className="counter"
onClick={() => setCount((count) => count + 1)}
>
Count is {count}
</button>
</section>

<div className="ticks"></div>

<section id="next-steps">
<div id="docs">
<svg className="icon" role="presentation" aria-hidden="true">
<use href="/icons.svg#documentation-icon"></use>
</svg>
<h2>Documentation</h2>
<p>Your questions, answered</p>
<ul>
<li>
<a href="https://vite.dev/" target="_blank">
<img className="logo" src={viteLogo} alt="" />
Explore Vite
</a>
</li>
<li>
<a href="https://react.dev/" target="_blank">
<img className="button-icon" src={reactLogo} alt="" />
Learn more
</a>
</li>
</ul>
</div>
<div id="social">
<svg className="icon" role="presentation" aria-hidden="true">
<use href="/icons.svg#social-icon"></use>
</svg>
<h2>Connect with us</h2>
<p>Join the Vite community</p>
<ul>
<li>
<a href="https://github.com/vitejs/vite" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#github-icon"></use>
</svg>
GitHub
</a>
</li>
<li>
<a href="https://chat.vite.dev/" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#discord-icon"></use>
</svg>
Discord
</a>
</li>
<li>
<a href="https://x.com/vite_js" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#x-icon"></use>
</svg>
X.com
</a>
</li>
<li>
<a href="https://bsky.app/profile/vite.dev" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#bluesky-icon"></use>
</svg>
Bluesky
</a>
</li>
</ul>
</div>
</section>

<div className="ticks"></div>
<section id="spacer"></section>
</>
)
}

export default App

バイナリ
campaign-tracker-client/src/assets/hero.png ファイルの表示

変更前 変更後
幅: 343  |  高さ: 361  |  サイズ: 13KB

+ 1
- 0
campaign-tracker-client/src/assets/react.svg ファイルの表示

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

+ 1
- 0
campaign-tracker-client/src/assets/vite.svg
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 111
- 0
campaign-tracker-client/src/index.css ファイルの表示

@@ -0,0 +1,111 @@
:root {
--text: #6b6375;
--text-h: #08060d;
--bg: #fff;
--border: #e5e4e7;
--code-bg: #f4f3ec;
--accent: #aa3bff;
--accent-bg: rgba(170, 59, 255, 0.1);
--accent-border: rgba(170, 59, 255, 0.5);
--social-bg: rgba(244, 243, 236, 0.5);
--shadow:
rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px;

--sans: system-ui, 'Segoe UI', Roboto, sans-serif;
--heading: system-ui, 'Segoe UI', Roboto, sans-serif;
--mono: ui-monospace, Consolas, monospace;

font: 18px/145% var(--sans);
letter-spacing: 0.18px;
color-scheme: light dark;
color: var(--text);
background: var(--bg);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;

@media (max-width: 1024px) {
font-size: 16px;
}
}

@media (prefers-color-scheme: dark) {
:root {
--text: #9ca3af;
--text-h: #f3f4f6;
--bg: #16171d;
--border: #2e303a;
--code-bg: #1f2028;
--accent: #c084fc;
--accent-bg: rgba(192, 132, 252, 0.15);
--accent-border: rgba(192, 132, 252, 0.5);
--social-bg: rgba(47, 48, 58, 0.5);
--shadow:
rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px;
}

#social .button-icon {
filter: invert(1) brightness(2);
}
}

#root {
width: 1126px;
max-width: 100%;
margin: 0 auto;
text-align: center;
border-inline: 1px solid var(--border);
min-height: 100svh;
display: flex;
flex-direction: column;
box-sizing: border-box;
}

body {
margin: 0;
}

h1,
h2 {
font-family: var(--heading);
font-weight: 500;
color: var(--text-h);
}

h1 {
font-size: 56px;
letter-spacing: -1.68px;
margin: 32px 0;
@media (max-width: 1024px) {
font-size: 36px;
margin: 20px 0;
}
}
h2 {
font-size: 24px;
line-height: 118%;
letter-spacing: -0.24px;
margin: 0 0 8px;
@media (max-width: 1024px) {
font-size: 20px;
}
}
p {
margin: 0;
}

code,
.counter {
font-family: var(--mono);
display: inline-flex;
border-radius: 4px;
color: var(--text-h);
}

code {
font-size: 15px;
line-height: 135%;
padding: 4px 8px;
background: var(--code-bg);
}

+ 10
- 0
campaign-tracker-client/src/main.tsx ファイルの表示

@@ -0,0 +1,10 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)

+ 25
- 0
campaign-tracker-client/tsconfig.app.json ファイルの表示

@@ -0,0 +1,25 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "es2023",
"lib": ["ES2023", "DOM"],
"module": "esnext",
"types": ["vite/client"],
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",

/* Linting */
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}

+ 7
- 0
campaign-tracker-client/tsconfig.json ファイルの表示

@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}

+ 24
- 0
campaign-tracker-client/tsconfig.node.json ファイルの表示

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "es2023",
"lib": ["ES2023"],
"module": "esnext",
"types": ["node"],
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,

/* Linting */
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true
},
"include": ["vite.config.ts"]
}

+ 7
- 0
campaign-tracker-client/vite.config.ts ファイルの表示

@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
})

+ 49
- 0
campaign-tracker.sln ファイルの表示

@@ -0,0 +1,49 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Campaign_Tracker.Server", "Campaign_Tracker.Server\Campaign_Tracker.Server.csproj", "{A7B08F8E-00EC-4197-BC31-65941F4A38F4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Campaign_Tracker.Server.Tests", "Campaign_Tracker.Server.Tests\Campaign_Tracker.Server.Tests.csproj", "{091D5213-5AF2-4414-8FD3-CFD14D525A13}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|x64.ActiveCfg = Debug|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|x64.Build.0 = Debug|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|x86.ActiveCfg = Debug|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|x86.Build.0 = Debug|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|Any CPU.Build.0 = Release|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|x64.ActiveCfg = Release|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|x64.Build.0 = Release|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|x86.ActiveCfg = Release|Any CPU
{A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|x86.Build.0 = Release|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|x64.ActiveCfg = Debug|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|x64.Build.0 = Debug|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|x86.ActiveCfg = Debug|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|x86.Build.0 = Debug|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|Any CPU.Build.0 = Release|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|x64.ActiveCfg = Release|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|x64.Build.0 = Release|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|x86.ActiveCfg = Release|Any CPU
{091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal


読み込み中…
キャンセル
保存

Powered by TurnKey Linux.