From 73660076e523c299c06f6675a6115d5631e568b8 Mon Sep 17 00:00:00 2001 From: morbalint Date: Mon, 25 Dec 2023 16:59:25 +0100 Subject: [PATCH] update character --- Kemkas.Web/Controllers/CharacterController.cs | 28 +++++- .../Character/CharacterDtoToDbModelService.cs | 30 +++++++ .../Character/CharacterPersistenceService.cs | 22 +++-- Kemkas.Web/frontend/src/App.tsx | 87 ++----------------- .../src/first-edition/api/character.api.ts | 13 +++ .../src/first-edition/components/LevelUps.tsx | 7 +- .../first-edition/pages/CreateCharacter.tsx | 34 ++++++-- Kemkas.Web/frontend/src/index.tsx | 5 -- Kemkas.Web/frontend/src/shared/Footer.tsx | 15 ++++ Kemkas.Web/frontend/src/shared/Header.tsx | 66 ++++++++++++++ 10 files changed, 204 insertions(+), 103 deletions(-) create mode 100644 Kemkas.Web/frontend/src/shared/Footer.tsx create mode 100644 Kemkas.Web/frontend/src/shared/Header.tsx diff --git a/Kemkas.Web/Controllers/CharacterController.cs b/Kemkas.Web/Controllers/CharacterController.cs index 0d42bb8..99a59a6 100644 --- a/Kemkas.Web/Controllers/CharacterController.cs +++ b/Kemkas.Web/Controllers/CharacterController.cs @@ -38,7 +38,7 @@ public class CharacterController( { return BadRequest(ex.Message); } - var id = await persistenceService.StoreNewCharacter(model); + var id = await persistenceService.StoreNewCharacter(model, isPublic); return id; } @@ -54,6 +54,32 @@ public class CharacterController( return dbModelToDtoService.Convert(entity); } + [HttpPost("{id:guid}")] + public async Task> UpdateCharacter([FromRoute] Guid id, [FromBody] CharacterDto dto, bool isPublic = true) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + var errors = validationService.Validate(dto); + if (errors != null) + { + return BadRequest(errors); + } + + var original = await persistenceService.GetCharacterById(id, tracking: true); + if (original is null) + { + return NotFound(); + } + + dtoToDbModelService.Update(original, dto); + + await persistenceService.UpdateCharacter(original, isPublic); + + return id; + } + [HttpGet] [Authorize] public async Task> GetAllCharacters() diff --git a/Kemkas.Web/Services/Character/CharacterDtoToDbModelService.cs b/Kemkas.Web/Services/Character/CharacterDtoToDbModelService.cs index 4740bcf..b5555c7 100644 --- a/Kemkas.Web/Services/Character/CharacterDtoToDbModelService.cs +++ b/Kemkas.Web/Services/Character/CharacterDtoToDbModelService.cs @@ -8,6 +8,8 @@ namespace Kemkas.Web.Services.Character; public interface ICharacterDtoToDbModelService { public V1Karakter Convert(CharacterDto dto); + + public void Update(V1Karakter original, CharacterDto dto); } public class CharacterDtoToDbModelService : ICharacterDtoToDbModelService @@ -45,6 +47,34 @@ public class CharacterDtoToDbModelService : ICharacterDtoToDbModelService return karakter; } + public void Update(V1Karakter original, CharacterDto dto) + { + original.Nev = dto.Name; + original.Nem = dto.Nem; + original.Kor = dto.Kor; + original.Jellem = JellemExtensions.Convert(dto.Jellem); + original.Isten = dto.Isten; + original.Faj = FajExtensions.Convert(dto.Faj); + original.Osztaly = OsztalyExtensions.Convert(dto.Osztaly); + original.Ero = dto.Tulajdonsagok.Ero; + original.Ugyesseg = dto.Tulajdonsagok.Ugy; + original.Egeszseg = dto.Tulajdonsagok.Egs; + original.Intelligencia = dto.Tulajdonsagok.Int; + original.Bolcsesseg = dto.Tulajdonsagok.Bol; + original.Karizma = dto.Tulajdonsagok.Kar; + original.Szint = dto.Szint; + original.Pajzs = dto.Felszereles.PajzsId; + original.Pancel = dto.Felszereles.PancelId; + original.KarakterKepzettsegek = ConvertKepzettsegek(dto, original); + original.Felszereles = dto.Felszereles.FegyverIds.Select(x => new V1Felszereles + { + Karakter = original, + IsFegyver = true, + Name = x, + }).ToList(); + original.Szintlepesek = ConvertSzintLepes(dto, original); + } + // TODO: this is unnecessary duplication of business logic!! private static List ConvertSzintLepes(CharacterDto dto, V1Karakter karakter) { diff --git a/Kemkas.Web/Services/Character/CharacterPersistenceService.cs b/Kemkas.Web/Services/Character/CharacterPersistenceService.cs index 7f8c9aa..e4b7fcc 100644 --- a/Kemkas.Web/Services/Character/CharacterPersistenceService.cs +++ b/Kemkas.Web/Services/Character/CharacterPersistenceService.cs @@ -11,9 +11,11 @@ public interface ICharacterPersistenceService { public Task StoreNewCharacter(V1Karakter karakter, bool isPublic = false); - public Task GetCharacterById(Guid id); + public Task GetCharacterById(Guid id, bool tracking = false); public Task> GetAllCharactersOfUser(); + + public Task UpdateCharacter(V1Karakter karakter, bool isPublic = false); } public class CharacterPersistenceService( @@ -33,12 +35,15 @@ public class CharacterPersistenceService( return karakter.Id; } - public async Task GetCharacterById(Guid id) + public async Task GetCharacterById(Guid id, bool tracking = false) { - var entity = await dbContext.Karakterek - .Include(x => x.KarakterKepzettsegek) + IQueryable queriable = dbContext.Karakterek.Include(x => x.KarakterKepzettsegek) .Include(x => x.Szintlepesek) - .Include(x => x.Felszereles) + .Include(x => x.Felszereles); + + queriable = tracking ? queriable.AsTracking() : queriable.AsNoTracking(); + + var entity = await queriable .FirstOrDefaultAsync(x => x.Id == id); if (entity?.OwnerUserId is null || entity.IsPublic) @@ -72,4 +77,11 @@ public class CharacterPersistenceService( return characters; } + + public async Task UpdateCharacter(V1Karakter karakter, bool isPublic = false) + { + karakter.IsPublic = isPublic; + dbContext.Karakterek.Attach(karakter); + await dbContext.SaveChangesAsync(); + } } \ No newline at end of file diff --git a/Kemkas.Web/frontend/src/App.tsx b/Kemkas.Web/frontend/src/App.tsx index f29caa8..83a85c6 100644 --- a/Kemkas.Web/frontend/src/App.tsx +++ b/Kemkas.Web/frontend/src/App.tsx @@ -1,12 +1,12 @@ -import React, {useEffect, useState} from 'react'; +import * as React from 'react'; import './App.css'; import {Faro} from "@grafana/faro-web-sdk"; import {createBrowserRouter, RouterProvider} from "react-router-dom"; import CreateCharacter from "./first-edition/pages/CreateCharacter"; import CharacterList from "./first-edition/pages/CharacterList"; import ErrorBoundary from "./shared/ErrorBoundary"; - -type LoadingState = "not-started" | "loading" | "finished" +import Header from "./shared/Header"; +import Footer from "./shared/Footer"; function App(props: {faro?: Faro}) { const router = createBrowserRouter([ @@ -23,95 +23,20 @@ function App(props: {faro?: Faro}) { }, { path: "/:id", - element: , + element: , loader: args => fetch(`api/Character/${args.params.id}`), ErrorBoundary: ErrorBoundary, } ]); - - let [loading, setLoading] = useState("not-started" as LoadingState); - let [userName, setUserName] = useState(null as string | null); - useEffect(() => { - let ignore = false; - if (loading === "not-started") { - setLoading("loading"); - fetch('api/User/me') - .then(response => { - if (response.ok) { - response.text() - .then((data) => data?.length > 0 ? setUserName(data) : setUserName(null)) - .catch((err) => { - console.log(err) - !ignore && setUserName(null); - }) - } else { - console.log(response) - !ignore && setUserName(null); - } - }) - .catch((err) => { - console.log(err); - !ignore && setUserName(null) - }) - .finally(() => { - setLoading("finished"); - }) - } - return () => { - ignore = true - } - }, [loading, setLoading, userName, setUserName]) return ( <> -
- -
+
-
-
- A Kard és Mágiát Lux Gábor alkotta. A szerzői jogok őt illetik. Ez az oldal egy "rajongói - hozzájárulás", célja a Kard és Mágia népszerűsítése. Ha többet akarsz tudni a Kard és Mágiáról - látogass el a hivatalos honlapjára. A Kard és Mágia az Open - Gaming Licence 1.0a alatt lett kiadva, melynek szövege itt található -
-
+