implement basic login

This commit is contained in:
Anika Raemer 2025-10-07 19:27:35 +02:00
parent bdd90b50d9
commit 7a6f5b5bcd
18 changed files with 222 additions and 35 deletions

View file

@ -0,0 +1,7 @@
/**
* Defines a login request
*/
export class LoginRequestDto {
userName?: string;
password?: string;
}

View file

@ -0,0 +1,10 @@
import { UserDto } from "./UserDto.js";
/**
* Response to a successful login
*/
export class LoginResponseDto {
userData?: UserDto;
token?: string;
expiryDate? : Date;
}

View file

@ -0,0 +1,15 @@
import { AbstractDto } from "./AbstractDto.js";
import { RecipeIngredientGroupDto } from "./RecipeIngredientGroupDto.js";
import { RecipeInstructionStepDto } from "./RecipeInstructionStepDto.js";
/**
* DTO describing a recipe
*/
export class RecipeDto extends AbstractDto {
title!: string;
amount?: number
amountDescription?: string;
instructions!: RecipeInstructionStepDto[];
ingredientGroups!: RecipeIngredientGroupDto[];
}

View file

@ -0,0 +1,10 @@
import { AbstractDto } from "./AbstractDto.js";
export class RecipeIngredientDto extends AbstractDto{
name!: string;
subtext?: string;
amount?: number;
unit?: string;
sortOrder!: number;
ingredientGroupId?: string;
}

View file

@ -0,0 +1,9 @@
import { AbstractDto } from "./AbstractDto.js";
import { RecipeIngredientDto } from "./RecipeIngredientDto.js";
export class RecipeIngredientGroupDto extends AbstractDto{
title?: string;
sortOrder!: number;
recipeId?: string;
ingredients!: RecipeIngredientDto[];
}

View file

@ -0,0 +1,8 @@
import { UUID } from "crypto";
import { AbstractDto } from "./AbstractDto.js";
export class RecipeInstructionStepDto extends AbstractDto{
text!: string;
sortOrder!: number;
recipeId?: UUID;
}

View file

@ -0,0 +1,9 @@
import { AbstractDto } from "./AbstractDto.js";
export class UserDto extends AbstractDto {
firstName?: string;
lastName?: string;
userName!: string;
email!: string;
role?: string;
}

View file

@ -0,0 +1,27 @@
import type { Recipe } from "../../types/recipe"
import type { LoginRequestDto } from "../dtos/LoginRequestDto";
import type { LoginResponseDto } from "../dtos/LoginResponseDto";
import { get, postJson, putJson } from "../utils/requests";
/**
* Util for handling the recipe api
*/
// read base url from .env file
const BASE_URL = import.meta.env.VITE_API_BASE;
/**
* URL for handling recipes
*/
const AUTH_URL = `${BASE_URL}/auth`
/**
* Create new Recipe
* @param recipe Recipe to create
* @returns Saved recipe
*/
export async function login(requestDto: LoginRequestDto): Promise<LoginResponseDto> {
const res = await postJson(`${AUTH_URL}/login`, JSON.stringify(requestDto), false);
return res.json();
}

View file

@ -0,0 +1,29 @@
import type { Recipe } from "../../types/recipe"
import { get, postJson, putJson } from "../utils/requests";
/**
* Util for handling the recipe api
*/
// read base url from .env file
const BASE_URL = import.meta.env.VITE_API_BASE;
/**
* URL for handling recipes header data
*/
const RECIPE_URL = `${BASE_URL}/compact-recipe`
/**
* Load list of all recipes
* @param searchString Search string for filtering recipeList
* @returns Array of recipe
*/
export async function fetchRecipeList(searchString : string): Promise<Recipe[]> {
let url : string = RECIPE_URL;
// if there's a search string add it as query parameter
if(searchString && searchString !== ""){
url +="?search=" + searchString;
}
const res = await get(url);
return res.json();
}

View file

@ -1,5 +1,5 @@
import type { Recipe } from "../types/recipe"
import { get, postJson, putJson } from "./utils/requests";
import type { Recipe } from "../../types/recipe"
import { get, postJson, putJson } from "../utils/requests";
/**
@ -23,21 +23,6 @@ export async function fetchRecipe(id: string): Promise<Recipe> {
return res.json()
}
/**
* Load list of all recipes
* @param searchString Search string for filtering recipeList
* @returns Array of recipe
*/
export async function fetchRecipeList(searchString : string): Promise<Recipe[]> {
let url : string = RECIPE_URL;
// if there's a search string add it as query parameter
if(searchString && searchString !== ""){
url +="?search=" + searchString;
}
const res = await get(url);
return res.json();
}
/**
* Create new Recipe
* @param recipe Recipe to create

View file

@ -1,3 +1,12 @@
const BASE_URL = import.meta.env.VITE_API_BASE;
export function createBasicHeader() : Headers {
const headers = new Headers();
//headers.set('Access-Control-Allow-Origin', '*');
return headers;
}
export function setContentTypeHeaderJson(headers: Headers){
return headers.set("Content-Type", "application/json");
}

View file

@ -1,7 +1,7 @@
import { setAuthHeader, setContentTypeHeaderJson } from "./headers";
import { createBasicHeader, setAuthHeader, setContentTypeHeaderJson } from "./headers";
export async function get(url: string) : Promise<Response>{
const requestHeaders = new Headers();
const requestHeaders = createBasicHeader();
setAuthHeader(requestHeaders);
console.log("GET to " + url);
const response = await fetch(url, {
@ -15,26 +15,35 @@ export async function get(url: string) : Promise<Response>{
}
export async function postJson(url: string, requestBody: string, logBody = true) : Promise<Response>{
console.log("POST to " + url + (logBody) ? "with body " + requestBody : "");
return persistJson(url, requestBody, "POST");
console.log("POST to " + url);
if(logBody){
console.log("body: " + requestBody);
}
return await persistJson(url, requestBody, "POST");
}
export async function putJson(url: string, requestBody: string, logBody = true) : Promise<Response>{
console.log("PUT to " + url + (logBody) ? "with body " + requestBody : "");
console.log("PUT to " + url);
if(logBody){
console.log("body: " + requestBody);
}
return persistJson(url, requestBody, "PUT");
}
async function persistJson(url: string, requestBody: string, requestMethod: string) : Promise<Response>{
const requestHeaders = new Headers();
const requestHeaders = createBasicHeader();
setContentTypeHeaderJson(requestHeaders);
setAuthHeader(requestHeaders);
const response = await fetch(url, {
const request = new Request(url, {
method: requestMethod,
headers: requestHeaders,
body: requestBody,
});
console.log(request)
const response = await fetch(request);
console.log("response.ok", response.ok)
if(!response.ok){
throw new Error(requestMethod + " to " + url + "failed!")
throw new Error(requestMethod + " to " + url + " failed!")
}
return response;
}