Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • s3206149/mod4-wp-2023-2024-pokemon
  • s3281744/mod4-wp-2023-2024-pokemon
  • s3128989/mod4-wp-2023-2024-pokemon
  • s3263797/m-4-pokemon
  • s3203255/mod4-wp-2023-2024-pokemon
  • s2854961/mod-4-wp-2023-2024-pokemons
  • s3192016/pokemon-practical-sessions
  • s3126080/mod4-wp-2023-2024-pokemon
  • s3165442/poke-mon
  • s3187152/mod4-wp-2023-2024-pokemon
  • s3209105/mod4-wp-2023-2024-pokemon
  • s3362779/mod4-wp-2023-2024-pokemon
  • s3173011/mod-4-wp-3-2023-2024-pokemon
  • s3174506/mod4-wp-2023-2024-pokemon
  • s3216926/mod-4-wp-2023-2024-pokemon-2nd
  • s3211770/mod4-wp-2023-2024-pokemon
  • s2936011/mod4-wp-2023-2024-pokemon
  • s3234312/mod4-wp-2023-2024-pokemon
  • s3362264/mod4-wp-2023-2024-pokemon
  • s3204766/mod4-wp-2023-2024-pokemon
  • s3363775/mod4-wp-2023-2024-pokemon
  • s3142906/mod4-wp-2023-2024-pokemon
  • s3298892/mod4-wp-2023-2024-pokemon
  • s3125866/mod-4-wp-2023-2024-pokemon-update
  • s2900556/mod-4-wp-2023-2024-pokemontut-3
  • s3196801/mod4-wp-2023-2024-pokemon
  • s2507919/mod4-wp-2023-2024-pokemon
  • Marius/mod-4-pokemon
  • s2948486/mod4-wp-2023-2024-pokemon
  • s3193748/mod4-wp-2023-2024-pokemon
  • s3199800/mod4-wp-2023-2024-pokemon
  • s3152340/mod4-wp-2023-2024-pokemon
  • s3194108/mod4-wp-2023-2024-pokemon
  • s3364518/mod4-wp-2023-2024-pokemon
  • s3200205/mod4-wp-2023-2024-pokemon
  • s3187667/pokemon-server
  • s3259633/mod4-wp-2023-2024-pokemon
  • s3137279/mod4-wp-2023-2024-pokemon
  • s3213552/mod4-wp-2023-2024-pokemon
  • s3200779/mod4-wp-2023-2024-pokemon
  • s3148157/mod4-wp-2023-2024-pokemon
  • s3196372/mod4-wp-2023-2024-pokemon
  • s3126714/mod4-wp-2023-2024-pokemon
  • s3286029/pracitcal-2
  • s3262499/mod4-wp-2023-2024-pokemon
  • s3290387/mod4-wp-2023-2024-pokemon
  • s3202798/mod4-wp-2023-2024-pokemon
  • s3210715/mod4-wp-2023-2024-pokemon
  • s3198308/mod4-wp-2023-2024-pokemon
  • s3211614/mod4-wp-2023-2024-pokemon
  • s3193691/mod4-wp-2023-2024-pokemon
  • s3273733/mod4-wp-2023-2024-pokemon
  • s3210898/mod4-wp-2023-2024-pokemon
  • s3133931/mod4-wp-2023-2024-pokemon
  • s3199479/mod4-wp-2023-2024-pokemon
  • s3190285/mod4-wp-2023-2024-pokemon
  • s3002896/mod4-wp-2023-2024-pokemon
  • s3166244/mod4-wp-2023-2024-pokemon
  • s3165582/mod4-wp-2023-2024-pokemon
  • s3147851/mod-4-wp-2023-2024-pokemon
  • web-programming-sessions/mod4-wp-2023-2024-pokemon
  • s3309630/mod4-wp-2023-2024-pokemon
  • s2914980/mod4-wp-2023-2024-pokemon
  • s3000885/mod4-wp-2023-2024-pokemon
  • s3209539/mod-4-pokemon-project
  • s3203573/kai-poke-mon
  • s3138127/mod-4-wp-2023-2024-pokemon-daniel
  • s3106586/mod4-wp-2023-2024-pokemon
  • s3183394/mod4-wp-2023-2024-pokemon
  • s3245748/mod4-wp-2023-2024-pokemon
  • s3252159/dm-mod-4-wp-2023-2024-pokemon
  • s2695154/mod4-wp-2023-2024-pokemon
  • s3171825/mod4-wp-2023-2024-pokemon
  • s3200183/mod4-wp-2023-2024-pokemon
  • s3000087/mod4-wp-2023-2024-pokemon
  • s3127168/mod4-wp-2023-2024-pokemon
  • s3137333/mod4-wp-2023-2024-pokemon
  • s3128830/mod4-wp-2023-2024-pokemon
  • s3102378/mod4-wp-2023-2024-pokemon
  • s3202224/mod4-wp-2023-2024-pokemon
  • s2590654/mod4-wp-2023-2024-pokemon
  • s3154882/mod4-wp-2023-2024-pokemon
  • s2958732/mod4-wp-2023-2024-pokemon
  • s3161293/mod4-wp-2023-2024-pokemon
  • s3133656/mod4-wp-2023-2024-pokemon
  • s3157385/mod-4-wp-2023-2024-pokemon-ali
  • s3192393/mod4-wp-2023-2024-pokemon
  • s3192016/mod4-wp-2023-2024-pokemon
  • s3211347/mod4-wp-2023-2024-pokemon
  • s3152790/mod4-wp-2023-2024-pokemon
  • s2959380/mod4-wp-2023-2024-pokemon
  • s3362906/mod4-wp-2023-2024-pokemon
  • s2964546/mod4-wp-2023-2024-pokemon
  • s3214915/mod4-wp-2023-2024-pokemon
  • s2219174/mod4-wp-2023-2024-pokemon
  • s3161595/mod4-wp-2023-2024-pokemon
  • s3207803/mod4-wp-2023-2024-pokemon
  • s3209334/mod4-wp-2023-2024-pokemon
  • s3191915/mod4-wp-2023-2024-pokemon
  • s3192253/mod4-wp-2023-2024-pokemon
  • s3137090/mod4-wp-2023-2024-pokemon
  • s3190536/mod4-wp-2023-2024-pokemon2
  • s3138585/mod4-wp-2023-2024-pokemon
  • s3186792/mod4-wp-2023-2024-pokemon
  • s2998491/mod4-wp-2023-2024-pokemon
  • s3145786/mod4-wp-2023-2024-pokemon
  • s3231046/mod4-wp-2023-2024-pokemon
  • s3125866/mod4-wp-2023-2024-pokemon
  • s3140458/mod4-wp-2023-2024-pokemon
  • s3133346/mod4-wp-2023-2024-pokemon
  • s3274519/mod4-wp-2023-2024-pokemon
  • s3216551/mod4-wp-2023-2024-pokemon
  • s3237478/mod4-wp-2023-2024-pokemon
  • s2985063/mod4-wp-2023-2024-pokemon
  • s3251942/mod4-wp-2023-2024-pokemon
  • s3305155/mod-4-wp-2023-2024-pokemon-david-sastre-madueno
  • s2675072/mod4-wp-2023-2024-pokemon
  • s3136027/mod4-wp-2023-2024-pokemon
  • s3186156/mod4-wp-2023-2024-pokemon
  • s3277305/mod4-wp-2023-2024-pokemon
  • s3242404/mod4-wp-2023-2024-pokemon
  • s3205967/mod4-wp-2023-2024-pokemon
  • s3173011/mod4-wp-2023-2024-pokemon
  • s3159736/mod4-wp-2023-2024-pokemon
  • s3207269/wplab-2
  • s3195945/mod4-wp-2023-2024-pokemon
  • s3151913/mod4-wp-2023-2024-pokemon
  • s3135136/mod4-wp-2023-2024-pokemon
  • s3216926/mod4-wp-2023-2024-pokemon
  • s3161218/mod4-wp-2023-2024-pokemon
  • s2921103/mod4-wp-2023-2024-pokemon
  • s3175561/mod4-wp-2023-2024-pokemon
  • SimeonNikolov/mod4-wp-2023-2024-pokemon
  • s3200329/mod4-wp-2023-2024-pokemon
  • s3148726/mod4-wp-2023-2024-pokemon
  • s2960796/mod4-wp-2023-2024-pokemon
  • s3098117/mod4-wp-2023-2024-pokemon
  • s3180794/mod4-wp-2023-2024-pokemon
  • s3179176/mod4-wp-2023-2024-pokemon
  • s3170268/mod4-wp-2023-2024-pokemon
  • s3126188/mod4-wp-2023-2024-pokemon
  • s3166449/pokemon-sarah-vonk
  • s3191567/mod4-wp-2023-2024-pokemon
  • s3271498/mod4-wp-2023-2024-pokemon
  • s3173089/mod4-wp-2023-2024-pokemon
  • s3172716/mod4-wp-2023-2024-pokemon
  • s3188981/mod4-wp-2023-2024-pokemon
  • s3184609/mod-4-lab-1-pokemon
  • s3144569/mod4-wp-2023-2024-pokemon
  • s3181340/poke-app-lab-06-05
  • s2900556/mod4-wp-2023-2024-pokemon
  • s3177858/mod4-wp-2023-2024-pokemon
  • s3209180/mod4-wp-2023-2024-pokemon
  • s3199495/mod4-wp-2023-2024-pokemon
  • s3163660/mod4-wp-2023-2024-pokemon
  • s3172708/mod4-wp-2023-2024-pokemon
  • s3206068/mod4-wp-2023-2024-pokemon
  • s3210774/mod4-wp-2023-2024-pokemon
  • s3200175/mod4-wp-2023-2024-pokemon
  • s3127141/mod4-wp-2023-2024-pokemon
  • s2995522/pokemon-practical-2-module-4
  • s3156621/mod4-wp-2023-2024-pokemon
  • s3126099/mod4-wp-2023-2024-pokemon
  • s3128121/mod4-wp-2023-2024-pokemon
  • s3233405/mod4-wp-2023-2024-pokemon
  • s3087921/mod4-wp-2023-2024-pokemon
  • s3202119/mod4-wp-2023-2024-pokemon
  • claudenirmf/mod4-wp-2023-2024-pokemon
168 results
Show changes
Showing
with 3259 additions and 2515 deletions
package nl.utwente.mod4.pokemon.model;
import java.time.Instant;
public class NamedEntity {
public String id;
......@@ -16,7 +14,7 @@ public class NamedEntity {
lastUpDate = null;
}
public boolean isValid() {
public boolean checkIsValid() {
return id != null && !id.isEmpty();
}
......
package nl.utwente.mod4.pokemon.model;
public class Pokemon extends NamedEntity {
public String trainerId;
public String pokemonType;
public Pokemon() {}
}
......@@ -8,18 +8,18 @@ import java.util.Objects;
public class ResourceCollection<T extends NamedEntity> {
public HashMap<String,Object> meta;
public HashMap<String,Object> links;
// public HashMap<String,Object> links;
public T[] data;
public ResourceCollection() {
data = null;
meta = new HashMap<>();
links = new HashMap<>();
// links = new HashMap<>();
}
public ResourceCollection(T[] resources, int pageSize, int pageNumber, int total) {
meta = new HashMap<>();
links = new HashMap<>();
// links = new HashMap<>();
meta.put("total", total);
meta.put("pageNumber", pageNumber);
......
package nl.utwente.mod4.pokemon.routes;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import nl.utwente.mod4.pokemon.model.Pokemon;
import java.util.ArrayList;
import java.util.List;
@Path("/pokemon")
public class PokemonRoute {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Pokemon> getPokemon() {
var list = new ArrayList<Pokemon> ();
var bolt = new Pokemon();
bolt.id = "1";
bolt.name = "Bolt";
bolt.trainerId = "1";
bolt.pokemonType = "513";
list.add(bolt);
return list;
}
@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Pokemon getPokemon(@PathParam("id") String id) {
var bolt = new Pokemon();
bolt.id = id;
bolt.name = "Bolt";
bolt.trainerId = "1";
bolt.pokemonType = "513";
return bolt;
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Pokemon createPokemon(Pokemon pokemon) {
return pokemon;
}
@Path("/{id}")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Pokemon updatePokemon(@PathParam("id") String id, Pokemon pokemon) {
return pokemon;
}
@Path("/{id}")
@DELETE
public void deletePokemon(@PathParam("id") String id) {
System.out.println("Pokemon '"+id+"' deleted");
}
}
......@@ -2,13 +2,10 @@ package nl.utwente.mod4.pokemon.routes;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import nl.utwente.mod4.pokemon.dao.PokemonTypeDao;
import nl.utwente.mod4.pokemon.model.PokemonType;
import nl.utwente.mod4.pokemon.model.ResourceCollection;
import java.util.List;
@Path("/pokemonTypes")
public class PokemonTypeRoute {
......@@ -19,11 +16,18 @@ public class PokemonTypeRoute {
@QueryParam("pageSize") int pageSize,
@QueryParam("pageNumber") int pageNumber
) {
// initializes page size and page number for request
int ps = pageSize > 0 ? pageSize : Integer.MAX_VALUE;
int pn = pageNumber > 0 ? pageNumber : 1;
var resources = PokemonTypeDao.INSTANCE.getPokemonTypes(ps, pn, sortBy).toArray(new PokemonType[0]);
var total = PokemonTypeDao.INSTANCE.getTotalPokemonTypes();
// request the desired page and sorting to the Data Access Object
PokemonType[] resources = PokemonTypeDao.INSTANCE.getPokemonTypes(ps, pn, sortBy).toArray(new PokemonType[0]);
// updates the total and page size for the response
int total = PokemonTypeDao.INSTANCE.getTotalPokemonTypes();
ps = resources == null ? 0 : resources.length;
// returns a collection object containing the requested resources
return new ResourceCollection<>(resources, ps, pn, total);
}
......@@ -31,6 +35,7 @@ public class PokemonTypeRoute {
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public PokemonType createPokemonType(PokemonType pokemonType) {
// creates a resource based on to the JSON object sent by the client
return PokemonTypeDao.INSTANCE.create(pokemonType);
}
......@@ -38,6 +43,7 @@ public class PokemonTypeRoute {
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public PokemonType getPokemonType(@PathParam("id") String id) {
// returns to the client the resource with the desired id
return PokemonTypeDao.INSTANCE.getPokemonType(id);
}
......@@ -45,16 +51,19 @@ public class PokemonTypeRoute {
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public PokemonType updatePokemonType(@PathParam("id") String id, PokemonType toUpdate) {
if (id == null || !id.equals(toUpdate.id))
public PokemonType updatePokemonType(@PathParam("id") String id, PokemonType toReplace) {
// check if the desired id and the id of the resource to be replaced match
if (id == null || !id.equals(toReplace.id))
throw new BadRequestException("Id mismatch.");
return PokemonTypeDao.INSTANCE.update(toUpdate);
// return the object replaced
return PokemonTypeDao.INSTANCE.replace(toReplace);
}
@DELETE
@Path("/{id}")
public void deletePokemonType(@PathParam("id") String id) {
// delete the resource with the desired id
PokemonTypeDao.INSTANCE.delete(id);
}
}
\ No newline at end of file
......@@ -16,11 +16,18 @@ public class TrainerRoute {
@QueryParam("pageSize") int pageSize,
@QueryParam("pageNumber") int pageNumber
) {
// initializes page size and page number for request
int ps = pageSize > 0 ? pageSize : Integer.MAX_VALUE;
int pn = pageNumber > 0 ? pageNumber : 1;
var resources = TrainerDao.INSTANCE.getTrainers(ps, pn).toArray(new Trainer[0]);
var total = TrainerDao.INSTANCE.getTotalTrainers();
// request the desired page to the Data Access Object
Trainer[] resources = TrainerDao.INSTANCE.getTrainers(ps, pn).toArray(new Trainer[0]);
// updates the total and page size for the response
int total = TrainerDao.INSTANCE.getTotalTrainers();
ps = resources == null ? 0 : resources.length;
// returns a collection object containing the requested resources
return new ResourceCollection<>(resources, ps, pn, total);
}
......@@ -28,6 +35,7 @@ public class TrainerRoute {
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Trainer createTrainer(Trainer pokemonType) {
// creates a resource based on to the JSON object sent by the client
return TrainerDao.INSTANCE.create(pokemonType);
}
......@@ -35,6 +43,7 @@ public class TrainerRoute {
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Trainer getTrainer(@PathParam("id") String id) {
// returns to the client the resource with the desired id
return TrainerDao.INSTANCE.getTrainer(id);
}
......@@ -42,16 +51,19 @@ public class TrainerRoute {
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Trainer updateTrainer(@PathParam("id") String id, Trainer toUpdate) {
if (id == null || !id.equals(toUpdate.id))
public Trainer updateTrainer(@PathParam("id") String id, Trainer toReplace) {
// check if the desired id and the id of the resource to be replaced match
if (id == null || !id.equals(toReplace.id))
throw new BadRequestException("Id mismatch.");
return TrainerDao.INSTANCE.update(toUpdate);
// return the object replaced
return TrainerDao.INSTANCE.replace(toReplace);
}
@DELETE
@Path("/{id}")
public void deleteTrainer(@PathParam("id") String id) {
// delete the resource with the desired id
TrainerDao.INSTANCE.delete(id);
}
}
[
{
"name": "Red",
"id": 1,
"id": "1",
"created": "24/04/2024",
"lastUpDate": "24/04/2024",
"profileUrl": "/pokemon/images/red.png"
"profileUrl": "https://archives.bulbagarden.net/media/upload/thumb/d/d3/Lets_Go_Pikachu_Eevee_Red.png/500px-Lets_Go_Pikachu_Eevee_Red.png"
},
{
"name": "Blue",
"id": 2,
"id": "2",
"created": "24/04/2024",
"lastUpDate": "24/04/2024",
"profileUrl": "/pokemon/images/blue.png"
"profileUrl": "https://archives.bulbagarden.net/media/upload/thumb/1/1a/Lets_Go_Pikachu_Eevee_Blue.png/320px-Lets_Go_Pikachu_Eevee_Blue.png"
},
{
"name": "Misty",
"id": 3,
"id": "3",
"created": "24/04/2024",
"lastUpDate": "24/04/2024",
"profileUrl": "/pokemon/images/misty.png"
"profileUrl": "https://archives.bulbagarden.net/media/upload/thumb/f/f6/Lets_Go_Pikachu_Eevee_Misty.png/367px-Lets_Go_Pikachu_Eevee_Misty.png"
},
{
"name": "Brock",
"id": 4,
"id": "4",
"created": "24/04/2024",
"lastUpDate": "24/04/2024",
"profileUrl": "/pokemon/images/brock.png"
"profileUrl": "https://archives.bulbagarden.net/media/upload/thumb/a/a6/Lets_Go_Pikachu_Eevee_Brock.png/243px-Lets_Go_Pikachu_Eevee_Brock.png"
}
]
\ No newline at end of file
......@@ -6,6 +6,7 @@
version="3.1">
<welcome-file-list>
<welcome-file>pokemonTypes.html</welcome-file>
<welcome-file>trainers.html</welcome-file>
<!-- <welcome-file>pokemonTypes.html</welcome-file>-->
</welcome-file-list>
</web-app>
\ No newline at end of file
let tableContainerId = 'table';
let detailsContainerId = 'details';
let pokemonTypes = {};
let selectedPokemonType = {};
let basePokemonType = {
"name": null,
"imgUrl": null,
"japaneseName": null,
"pokedexNumber": null,
"abilities": null,
"baseAttack": null,
"captureRate": null,
"classification": null,
"baseDefense": null,
"baseHeight": null,
"baseHp": null,
"baseSpAttack": null,
"baseSpDefense": null,
"baseSpeed": null,
"primaryType": null,
"secondaryType": null,
"baseWeight": null,
"generation": null,
"isLegendary": null
};
let defaultPokemonType = {
"name": "Pikachu",
"id": 513,
"created": "24/04/2024",
"lastUpDate": "24/04/2024",
"imgUrl": "./images/pikachu.png",
"japaneseName": "Pikachuピカチュウ",
"pokedexNumber": 25,
"abilities": ["Static", "Lightningrod"],
"baseAttack": 55,
"captureRate": 190,
"classification": "Mouse Pokémon",
"baseDefense": 40,
"baseHeight": 0.4,
"baseHp": 35,
"baseSpAttack": 50,
"baseSpDefense": 50,
"baseSpeed": 90,
"primaryType": "electric",
"secondaryType": "",
"baseWeight": 6,
"generation": 1,
"isLegendary": "FALSE"
}
function changeSelectedPokemonType(id) {
selectedPokemonType = pokemonTypes?.data?.find(pt => pt.id === id);
showDetails();
}
function showDetails() {
const detailsContainer = document.getElementById(detailsContainerId);
detailsContainer.innerHTML = `
<div class="card" id="${selectedPokemonType.id}_card">
<img src="${selectedPokemonType.imgUrl}" class="card-img-top" alt="${selectedPokemonType.classification}">
<div class="card-body">
<h5 class="card-title">${selectedPokemonType.name} #${selectedPokemonType.pokedexNumber}</h5>
<p class="card-text">
<span class="font-weight-bold">Japanese name:</span> ${selectedPokemonType.japaneseName} </br>
<span class="font-weight-bold">Classification:</span> ${selectedPokemonType.classification} </br>
<span class="font-weight-bold">Generation:</span> ${selectedPokemonType.generation} </br>
<span class="font-weight-bold">Legendary:</span> ${selectedPokemonType.isLegendary ? "Yes" : "No"} </br>
<span class="font-weight-bold">Type:</span> ${selectedPokemonType.primaryType}${selectedPokemonType.secondaryType ? " , " + selectedPokemonType.secondaryType : ""}
</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<span class="font-weight-bold">ID:</span> ${selectedPokemonType.id}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Created:</span> ${selectedPokemonType.created}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Last update:</span> ${selectedPokemonType.lastUpDate}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Name:</span> ${selectedPokemonType.name}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Pokédex number:</span> #${selectedPokemonType.pokedexNumber}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Japanese name:</span> ${selectedPokemonType.japaneseName}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Classification:</span> ${selectedPokemonType.classification}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Generation:</span> ${selectedPokemonType.generation}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Legendary:</span> ${selectedPokemonType.isLegendary ? "Yes" : "No"}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Image URL:</span> ${selectedPokemonType.imgUrl}
</li>
<li class="list-group-item">
<span class="font-weight-bold">HP:</span> ${selectedPokemonType.baseHp}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Height:</span> ${selectedPokemonType.baseHeight}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Weight:</span> ${selectedPokemonType.baseWeight}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Attack:</span> ${selectedPokemonType.baseAttack}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Special Attack:</span> ${selectedPokemonType.baseSpAttack}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Defense:</span> ${selectedPokemonType.baseDefense}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Special Defense:</span> ${selectedPokemonType.baseSpDefense}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Speed:</span> ${selectedPokemonType.baseSpeed}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Capture rate:</span> ${selectedPokemonType.captureRate}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Primary type:</span> ${selectedPokemonType.primaryType}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Secondary type:</span> ${selectedPokemonType.secondaryType}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Abilities:</span> ${selectedPokemonType.abilities?.join(", ") || "none"}
</li>
<li class="list-group-item d-flex justify-content-between">
<a class="btn btn-primary" onclick="showCreateForm()">New</a>
<a class="btn btn-primary" onclick="showUpdateForm()">Update</a>
<a class="btn btn-danger" onclick="deletePokemonType(selectedPokemonType.id)">Delete</a>
</li>
</ul>
</div>
`
}
function createPokemonTypesTable() {
const tableContainer = document.getElementById(tableContainerId);
tableContainer.innerHTML = `
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Pokedex Number</th>
<th scope="col">Primary Type</th>
<th scope="col">Secondary Type</th>
</tr>
</thead>
<tbody>
${
pokemonTypes.data.map(resource => `${pokemonTypeToRow(resource)}`).join("\n")
|| "no data"
}
</tbody>
</table>
`
if(pokemonTypes?.data?.[0]?.id)
changeSelectedPokemonType(pokemonTypes?.data?.[0]?.id)
}
function pokemonTypeToRow(pokemonType) {
return `
<tr id="${pokemonType.id}_row" onclick="changeSelectedPokemonType('${pokemonType?.id?.trim()}')">
<th scope="row">${pokemonType.id}</th>
<td>${pokemonType.name}</td>
<td>#${pokemonType.pokedexNumber}</td>
<td>${pokemonType.primaryType}</td>
<td>${pokemonType.secondaryType || '-'}</td>
</tr>
`
}
function getPokemonTypes() {
return fetch('./api/pokemonTypes')
.then(res => res.json())
.then(data => {
pokemonTypes = data;
createPokemonTypesTable();
})
.catch(err => {
console.error(`Unable to fetch Pokemon Types: ${err.status}`);
console.error(err);
});
}
function deletePokemonType(id) {
return fetch(`./api/pokemonTypes/${id}`, { method: "DELETE" })
.then(() => {
getPokemonTypes()
})
.catch(err => {
console.error(`Unable to delete Pokemon Type: ${err.status}`);
console.error(err);
});
}
function showUpdateForm() {
const detailsContainer = document.getElementById(detailsContainerId);
detailsContainer.innerHTML = `
<form id="update-form">
<div class="form-group">
<label for="input-name">Name</label>
<input type="text" class="form-control" id="input-name" name="name" placeholder="${selectedPokemonType.name}">
</div>
<div class="form-group">
<label for="input-classification">Classification</label>
<input type="text" class="form-control" id="input-classification" name="classification" placeholder="${selectedPokemonType.classification}">
</div>
<div class="form-group">
<label for="input-japanese-name">Japanese name</label>
<input type="text" class="form-control" id="input-japanese-name" name="japaneseName" placeholder="${selectedPokemonType.japaneseName}">
</div>
<div class="form-group">
<label for="input-img-url">Image URL</label>
<input type="text" class="form-control" id="input-img-url" name="imgUrl" placeholder="${selectedPokemonType.imgUrl}">
</div>
<div class="d-flex justify-content-between">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" class="btn btn-danger" onclick="showDetails()">Cancel</button>
</div>
</form>
`
const form = document.getElementById("update-form");
form.addEventListener("submit", function(event) {
event.preventDefault();
let formData = new FormData(form);
formData.forEach((v,k) => {
selectedPokemonType[k] = formData.get(k) || selectedPokemonType[k];
})
const id = selectedPokemonType.id;
fetch(`./api/pokemonTypes/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(selectedPokemonType, null, 2)
}).then(res => getPokemonTypes())
.then(() => changeSelectedPokemonType(id))
.catch(err => {
console.error("Error updating resource", err)
})
})
}
function showCreateForm() {
const detailsContainer = document.getElementById(detailsContainerId);
detailsContainer.innerHTML = `
<form id="create-form">
<div class="form-group">
<label for="input-name">Name</label>
<input type="text" class="form-control" id="input-name" name="name" placeholder="${defaultPokemonType.name}">
</div>
<div class="form-group">
<label for="input-classification">Classification</label>
<input type="text" class="form-control" id="input-classification" name="classification" placeholder="${defaultPokemonType.classification}">
</div>
<div class="form-group">
<label for="input-japanese-name">Japanese name</label>
<input type="text" class="form-control" id="input-japanese-name" name="japaneseName" placeholder="${defaultPokemonType.japaneseName}">
</div>
<div class="form-group">
<label for="input-img-url">Image URL</label>
<input type="text" class="form-control" id="input-img-url" name="imgUrl" placeholder="${defaultPokemonType.imgUrl}">
</div>
<div class="d-flex justify-content-between">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" class="btn btn-danger" onclick="showDetails()">Cancel</button>
</div>
</form>
`
const form = document.getElementById("create-form");
form.addEventListener("submit", function(event) {
event.preventDefault();
let newPokemonType = JSON.parse(JSON.stringify(basePokemonType));
let formData = new FormData(form);
formData.forEach((v,k) => {
newPokemonType[k] = formData.get(k);
})
let newId;
fetch(`./api/pokemonTypes`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newPokemonType, null, 2)
}).then(res => res.json())
.then(data => {
newId = data.id;
return getPokemonTypes();
})
.then(() => changeSelectedPokemonType(newId))
.catch(err => {
console.error("Error updating resource", err)
})
})
}
let pokemonTypes = {};
let tableParentId = 'table';
let detailsParentId = 'details';
function getRowId(resource) {
return `${resource.id}_row`
}
function updateDetails(pokemonTypeId) {
const pt = pokemonTypes?.data?.find(item => item.id === pokemonTypeId);
const parent = document.getElementById(detailsParentId);
parent.innerHTML = `
<div class="card" id="${pt.id}_card">
<img src="${pt.imgUrl}" class="card-img-top" alt="${pt.classification}">
<div class="card-body">
<h5 class="card-title">${pt.name} #${pt.pokedexNumber}</h5>
<p class="card-text">
Japanese name: ${pt.japaneseName} </br>
Classification: ${pt.classification} </br>
Abilities: ${pt.abilities?.join(", ") || "none"} </br>
Type: ${pt.primaryType}${pt.secondaryType ? " , " + pt.secondaryType : ""}
</p>
</div>
</div>
`
}
function pokemonTypeToRow(pokemonType) {
return `
<tr id="${getRowId(pokemonType)}" onclick="updateDetails('${pokemonType?.id?.trim()}')">
<th scope="row">${pokemonType.id}</th>
<td>${pokemonType.name}</td>
<td>#${pokemonType.pokedexNumber}</td>
<td>${pokemonType.primaryType}</td>
<td>${pokemonType.secondaryType || '-'}</td>
</tr>
`
}
function createPokemonTypesTable() {
const tableParent = document.getElementById(tableParentId);
tableParent.innerHTML = `
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Pokedex Number</th>
<th scope="col">Primary Type</th>
<th scope="col">Secondary Type</th>
</tr>
</thead>
<tbody>
${
pokemonTypes.data.map(resource => `${pokemonTypeToRow(resource)}`).join("\n")
|| "no data"
}
</tbody>
</table>
`
}
\ No newline at end of file
let tableContainerId = 'table';
let detailsContainerId = 'details';
let trainers = {};
let selectedTrainer = {};
let baseTrainer = {
"name": null,
"profileUrl": null
};
let defaultTrainer = {
"name": "Ash Ketchum",
"id": 1,
"profileUrl": "https://archives.bulbagarden.net/media/upload/thumb/c/cd/Ash_JN.png/300px-Ash_JN.png"
}
function changeSelectedTrainer(id) {
selectedTrainer = trainers?.data?.find(pt => pt.id === id);
showDetails();
}
function showDetails() {
const detailsContainer = document.getElementById(detailsContainerId);
detailsContainer.innerHTML = `
<div class="card" id="${selectedTrainer.id}_card">
<img src="${selectedTrainer.profileUrl}" class="card-img-top">
<div class="card-body">
<h5 class="card-title">${selectedTrainer.name} (${selectedTrainer.id})</h5>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<span class="font-weight-bold">ID:</span> ${selectedTrainer.id}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Created:</span> ${selectedTrainer.created}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Last update:</span> ${selectedTrainer.lastUpDate}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Name:</span> ${selectedTrainer.name}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Image URL:</span> ${selectedTrainer.profileUrl}
</li>
<li class="list-group-item d-flex justify-content-between">
<a class="btn btn-primary" onclick="showCreateForm()">New</a>
<a class="btn btn-primary" onclick="showUpdateForm()">Update</a>
<a class="btn btn-danger" onclick="deleteTrainer(selectedTrainer.id)">Delete</a>
</li>
</ul>
</div>
`
}
function createTrainersTable() {
const tableContainer = document.getElementById(tableContainerId);
tableContainer.innerHTML = `
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
</tr>
</thead>
<tbody>
${
trainers.data.map(resource => `${trainerToRow(resource)}`).join("\n")
|| "no data"
}
</tbody>
</table>
`
if(trainers?.data?.[0]?.id)
changeSelectedTrainer(trainers?.data?.[0]?.id)
}
function trainerToRow(trainer) {
return `
<tr id="${trainer.id}_row" onclick="changeSelectedTrainer('${trainer?.id?.trim()}')">
<th scope="row">${trainer.id}</th>
<td>${trainer.name}</td>
</tr>
`
}
function getTrainers() {
return fetch('./api/trainers')
.then(res => res.json())
.then(data => {
trainers = data;
createTrainersTable();
})
.catch(err => {
console.error(`Unable to fetch trainers: ${err.status}`);
console.error(err);
});
}
function deleteTrainer(id) {
return fetch(`./api/trainers/${id}`, { method: "DELETE" })
.then(() => {
getTrainers()
})
.catch(err => {
console.error(`Unable to delete trainer: ${err.status}`);
console.error(err);
});
}
function showUpdateForm() {
const detailsContainer = document.getElementById(detailsContainerId);
detailsContainer.innerHTML = `
<form id="update-form">
<div class="form-group">
<label for="input-name">Name</label>
<input type="text" class="form-control" id="input-name" name="name" placeholder="${selectedTrainer.name}">
</div>
<div class="form-group">
<label for="input-profile-url">Profile URL</label>
<input type="text" class="form-control" id="input-profile-url" name="profileUrl" placeholder="${selectedTrainer.profileUrl}">
</div>
<div class="d-flex justify-content-between">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" class="btn btn-danger" onclick="showDetails()">Cancel</button>
</div>
</form>
`
const form = document.getElementById("update-form");
form.addEventListener("submit", function(event) {
event.preventDefault();
let formData = new FormData(form);
formData.forEach((v,k) => {
selectedTrainer[k] = formData.get(k) || selectedTrainer[k];
})
const id = selectedTrainer.id;
fetch(`./api/trainers/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(selectedTrainer, null, 2)
}).then(res => getTrainers())
.then(() => changeSelectedTrainer(id))
.catch(err => {
console.error("Error updating resource", err)
})
})
}
function showCreateForm() {
const detailsContainer = document.getElementById(detailsContainerId);
detailsContainer.innerHTML = `
<form id="create-form">
<div class="form-group">
<label for="input-name">Name</label>
<input type="text" class="form-control" id="input-name" name="name" placeholder="${defaultTrainer.name}">
</div>
<div class="form-group">
<label for="input-profile-url">Profile URL</label>
<input type="text" class="form-control" id="input-profile-url" name="profileUrl" placeholder="${defaultTrainer.profileUrl}">
</div>
<div class="d-flex justify-content-between">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" class="btn btn-danger" onclick="showDetails()">Cancel</button>
</div>
</form>
`
const form = document.getElementById("create-form");
form.addEventListener("submit", function(event) {
event.preventDefault();
let newTrainer = JSON.parse(JSON.stringify(baseTrainer));
let formData = new FormData(form);
formData.forEach((v,k) => {
newTrainer[k] = formData.get(k);
})
let newId;
fetch(`./api/trainers`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newTrainer, null, 2)
}).then(res => res.json())
.then(data => {
newId = data.id;
return getTrainers();
})
.then(() => changeSelectedTrainer(newId))
.catch(err => {
console.error("Error updating resource", err)
})
})
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<title>PokeApp</title>
<link rel="icon" type="image/x-icon" href="./favicon.ico">
</head>
<body>
<h1 class="display-1 d-flex justify-content-center mb-5">PokeApp</h1>
<div class="d-flex justify-content-center mb-5">
<a class="btn btn-primary mx-2" href="./pokemonTypes.html">Pokemon Types</a>
<a class="btn btn-primary mx-2" href="./trainers.html">Trainers</a>
<a class="btn btn-primary mx-2" href="./pokemon.html">Pokemon</a>
</div>
<div class="d-flex justify-content-center mb-5">
<div class="row">
<div class="col-sm">
<h2>Pokemon Details</h2>
<ul>
<li>
<storng>ID:</storng>
<span id="detail-id"></span></li>
<li>
<storng>Name:</storng>
<span id="detail-name"></span></li>
<li>
<storng>Trainer ID:</storng>
<span id="detail-trainer-id"></span></li>
<li>
<storng>Pokemon Type ID:</storng>
<span id="detail-pokemon-type-id"></span></li>
</ul>
</div>
<div class="col-sm">
<h2>New Pokemon</h2>
<label>ID: </label></br>
<input type="text" id="new-id"></br>
<label>Name: </label></br>
<input type="text" id="new-name"></br>
<label>Trainer ID: </label></br>
<input type="text" id="new-trainer-id"></br>
<label>Pokemon Type ID: </label></br>
<input type="text" id="new-pokemon-type-id"></br>
<button onclick="createPokemon()">New</button>
</div>
<div class="col-sm">
<h2>Update Pokemon</h2>
<label>ID: </label></br>
<input type="text" id="update-id"></br>
<label>Name: </label></br>
<input type="text" id="update-name"></br>
<label>Trainer ID: </label></br>
<input type="text" id="update-trainer-id"></br>
<label>Pokemon Type ID: </label></br>
<input type="text" id="update-pokemon-type-id"></br>
</div>
</div>
</div>
<h2>Pokemon Table</h2>
<div class="pokemon-table">
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Trainer ID</th>
<th scope="col">Pokemon Type ID</th>
</tr>
</thead>
<tbody id="table-body">
<tr>
<th scope="row">No data</th>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
</tbody>
</table>
</div>
<script>
fetch('./api/pokemon')
.then(res => res.json())
.then(data => {
let rows = data?.map(pokemon => `
<tr>
<td>${pokemon.id}</td>
<td>${pokemon.name}</td>
<td>${pokemon.trainerId}</td>
<td>${pokemon.pokemonTypeId}</td>
</tr>
`);
document.getElementById("table-body").innerHTML = rows.join("/n");
}).catch(err => {
console.error("Unable to fetch all pokemon", err)
})
</script>
<script>
function createPokemon() {
const newPokemon = {
id: document.getElementById("new-id").value,
name: document.getElementById("new-name").value,
trainerId: document.getElementById("new-trainer-id").value,
pokemonType: document.getElementById("new-pokemon-type-id").value,
}
fetch('./api/pokemon', {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newPokemon)
}).then(res => {
alert("Pokemon created")
}).catch(err => {
alert("Failed to create pokemon")
console.error(err);
})
}
</script>
</body>
</html>
\ No newline at end of file
......@@ -9,36 +9,40 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<title>Title</title>
<link rel="icon" type="image/x-icon" href="/pokemon/favicon.ico">
<title>PokeApp</title>
<link rel="icon" type="image/x-icon" href="./favicon.ico">
</head>
<body>
<script src="js/requests.js"></script>
<script>
tableParentId = "tableDiv";
detailsParentId = "detailsDiv";
fetch('/pokemon/api/pokemonTypes')
.then(res => res.json())
.then(data => {
pokemonTypes = data;
createPokemonTypesTable();
})
.catch(err => {
console.error(`Unable to fetch Pokemon Types: ${err.status}`);
console.error(err);
});
</script>
<script src="js/pokemonTypesRequests.js"></script>
<h1>Pokemon Types</h1>
<h1 class="display-1 d-flex justify-content-center mb-5">PokeApp</h1>
<div class="d-flex justify-content-center mb-5">
<a class="btn btn-primary mx-2" href="./pokemonTypes.html">Pokemon Types</a>
<a class="btn btn-primary mx-2" href="./trainers.html">Trainers</a>
<a class="btn btn-primary mx-2" href="./pokemon.html">Pokemon</a>
</div>
<div class="container">
<div class="row">
<div id="tableDiv" class="col-8">No data</div>
<div id="detailsDiv" class="col-4">No data</div>
<div class="col-8">
<h2>Pokemon Types</h2>
<div id="tableContainer">No data</div>
</div>
<div class="col-4">
<h2>Pokemon Type Details</h2>
<div id="detailsContainer">No data</div>
</div>
</div>
</div>
<script>
tableContainerId = "tableContainer";
detailsContainerId = "detailsContainer";
getPokemonTypes();
showUpdateForm();
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<title>PokeApp</title>
<link rel="icon" type="image/x-icon" href="./favicon.ico">
</head>
<body>
<script src="js/trainersRequests.js"></script>
<h1 class="display-1 d-flex justify-content-center mb-5">PokeApp</h1>
<div class="d-flex justify-content-center mb-5">
<a class="btn btn-primary mx-2" href="./pokemonTypes.html">Pokemon Types</a>
<a class="btn btn-primary mx-2" href="./trainers.html">Trainers</a>
<a class="btn btn-primary mx-2" href="./pokemon.html">Pokemon</a>
</div>
<div class="container">
<div class="row">
<div class="col-8">
<h2>Trainers</h2>
<div id="tableContainer">No data</div>
</div>
<div class="col-4">
<h2>Trainer Details</h2>
<div id="detailsContainer">No data</div>
</div>
</div>
</div>
<script>
tableContainerId = "tableContainer";
detailsContainerId = "detailsContainer";
getTrainers();
showUpdateForm();
</script>
</body>
</html>
\ No newline at end of file