My problem is the follwoing:
Setup: Java Spring Boot api connected with MongoDB to handle my Sever responses and Requestes.
Entity:
package org.schmeckis.backend.model;
import lombok.With;
import org.schmeckis.backend.model.submodel.Kategorie;
import org.springframework.data.annotation.Id;
import java.util.List;
public record Rezept(
@Id
String id,
String rezeptName,
@With
String rezeptImageUrl,
String rezeptKurzbeschreibung, // to be JSON and Edited by TIPTAP
String rezeptBeschreibung, // to be JSON and Edited by TIPTAP
List<Kategorie> kategorieList
) {
public Rezept {
if (rezeptImageUrl == null) {
rezeptImageUrl = "";
}
}
}
RestController:
package org.schmeckis.backend.controller;
import lombok.RequiredArgsConstructor;
import org.schmeckis.backend.model.Rezept;
import org.schmeckis.backend.model.dto.RequestRezept;
import org.schmeckis.backend.model.submodel.Kategorie;
import org.schmeckis.backend.service.RezeptService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/rezepte")
@RequiredArgsConstructor
public class RezepteController {
private final RezeptService rezeptService;
@GetMapping
public List<Rezept> getAllRezepte() {
return rezeptService.getAllRezepte();
}
@PostMapping("/create")
@ResponseStatus(HttpStatus.CREATED)
public Rezept createRezept(@RequestBody RequestRezept rezept) {
return rezeptService.createRezept(rezept);
}
@GetMapping("/{id}")
public Rezept getRezept(@PathVariable String id) {
return rezeptService.getRezept(id);
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteRezept(@PathVariable String id) {
rezeptService.deleteRezept(id);
}
@PutMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public Rezept updateRezept(@PathVariable String id, @RequestBody RequestRezept rezept) {
return rezeptService.updateRezept(id, rezept);
}
@PutMapping("/{id}/addKategorie")
@ResponseStatus(HttpStatus.OK)
public Rezept addKategorieToRezept(@PathVariable String id, @RequestBody Kategorie kategorie) {
return rezeptService.addKategorieToRezept(id, kategorie);
}
@DeleteMapping("/{id}/deleteKategorie")
@ResponseStatus(HttpStatus.OK)
public Rezept deleteKategorieFromRezept(@PathVariable String id, @RequestBody Kategorie kategorie) {
return rezeptService.deleteKategorieFromRezept(id, kategorie);
}
@GetMapping("/kategorie/{kategorieName}")
public List<Rezept> getRezepteByKategorie(@PathVariable String kategorieName) {
return rezeptService.getRezepteByKategorie(kategorieName);
}
}
React/Vite frontend Setup:
In this Setup I want to be able to create via the TipTap Rich Text Editor a nice looking text for displaying. This text has to be stored with in my Entity in my Backend and should be rendered when outputted again in the Frontend.
I already refrained from the Idea to get the HTML from the editor to my Backend because of* XSS*, but with a JSON I´m quite lost on how to render it when it is requested in the frontend.
My Idea was to save JSON as a string in the Backend. But I haven´t really found out how I can use the Data given to the forntend by the Backend to render it in the form i orginally intended it for. Could somebody point me in the right direction because the documentation doesn´t really help me.
EDITOR:
import {EditorContent, useEditor} from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import {Toolbar} from "./ToolBar.tsx";
export default function RichTextEditor({
rezeptBeschreibung,
onChange,
}: {
rezeptBeschreibung: string;
onChange: (rezeptBeschreibung: string) => void;
}) {
const editor = useEditor({
extensions: [StarterKit.configure()],
content: rezeptBeschreibung,
editorProps: {
attributes: {
class: "rounded border-none p-4 m-4 min-h-[300px] shadow-doubleOut active:shadow-doubleIn",
}
},
onUpdate({editor}) {
onChange(editor.getJSON().toString());
},
});
return (
<div className="flex flex-col justify-stretch min-h-[250px] min-w-[300px] overflow-y-scroll">
<Toolbar editor={editor}/>
<EditorContent editor={editor}/>
</div>
);
}
Output:
import * as React from 'react';
import {Rezept} from '../models/Rezept.tsx';
import {useNavigate} from "react-router-dom";
import {MdInfoOutline} from 'react-icons/md';
type RezeptProps = {
rezept: Rezept
}
export default function RezeptCard({rezept}: RezeptProps) {
const navigate = useNavigate();
function openDetails() {
navigate("/rezept/" + rezept.id);
}
return (
<div className="bg-offWhite rounded-xl shadow-doubleOut p-10 m-2 border-none hover:shadow-doubleIn">
<div className="flex justify-between items-center">
<h2 className="text-2xl font-bold text-center justify-center text-textHeader ml-4">{rezept.rezeptName}</h2>
<button className="bg-offWhite hover:shadow-buttonIn rounded-full p-2 w-auto" onClick={openDetails}>
<MdInfoOutline size="30" color="#646464"/>
</button>
</div>
<img className="w-50 border-transparent shadow-doubleIn object-cover mt-2 mb-2 rounded"
src={rezept.rezeptImageUrl} alt={rezept.rezeptName}/>
<p className="text-textPrime mt-8">{rezept.rezeptKurzbeschreibung}</p> // here Json // should be Re-rendered I know i have to create a Component. But im quite lost on how
<div className="flex mt-4">
{rezept.kategorieList.map(kategorie => (
<button key={kategorie.kategorieName}
className="flex-row shadow-hashtagbutton hover:shadow-hashtagbuttonOut bg-offWhite rounded-full px-6 py-1.5 text-m font-semibold text-textPrime mr-2 mb-2 ">#{kategorie.kategorieName}</button>
))}
</div>
</div>
);
}
I´m very new to the whole thing so im quite lost I would also be very happy when you could just point me in the right direction.
Can you help me find a way to convert the **JSON **stored as a string into a HTML code displayed on the frontend ? and to keep all stylings made within the JSON