diff --git a/backend/node_modules/.package-lock.json b/backend/node_modules/.package-lock.json index 4f4f403..a9c7f47 100644 --- a/backend/node_modules/.package-lock.json +++ b/backend/node_modules/.package-lock.json @@ -94,6 +94,16 @@ "@types/node": "*" } }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/express": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz", diff --git a/backend/node_modules/@types/cors/LICENSE b/backend/node_modules/@types/cors/LICENSE new file mode 100644 index 0000000..9e841e7 --- /dev/null +++ b/backend/node_modules/@types/cors/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/backend/node_modules/@types/cors/README.md b/backend/node_modules/@types/cors/README.md new file mode 100644 index 0000000..43c9002 --- /dev/null +++ b/backend/node_modules/@types/cors/README.md @@ -0,0 +1,75 @@ +# Installation +> `npm install --save @types/cors` + +# Summary +This package contains type definitions for cors (https://github.com/expressjs/cors/). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/cors. +## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/cors/index.d.ts) +````ts +/// + +import { IncomingHttpHeaders } from "http"; + +type StaticOrigin = boolean | string | RegExp | Array; + +type CustomOrigin = ( + requestOrigin: string | undefined, + callback: (err: Error | null, origin?: StaticOrigin) => void, +) => void; + +declare namespace e { + interface CorsRequest { + method?: string | undefined; + headers: IncomingHttpHeaders; + } + interface CorsOptions { + /** + * @default '*' + */ + origin?: StaticOrigin | CustomOrigin | undefined; + /** + * @default 'GET,HEAD,PUT,PATCH,POST,DELETE' + */ + methods?: string | string[] | undefined; + allowedHeaders?: string | string[] | undefined; + exposedHeaders?: string | string[] | undefined; + credentials?: boolean | undefined; + maxAge?: number | undefined; + /** + * @default false + */ + preflightContinue?: boolean | undefined; + /** + * @default 204 + */ + optionsSuccessStatus?: number | undefined; + } + type CorsOptionsDelegate = ( + req: T, + callback: (err: Error | null, options?: CorsOptions) => void, + ) => void; +} + +declare function e( + options?: e.CorsOptions | e.CorsOptionsDelegate, +): ( + req: T, + res: { + statusCode?: number | undefined; + setHeader(key: string, value: string): any; + end(): any; + }, + next: (err?: any) => any, +) => void; +export = e; + +```` + +### Additional Details + * Last updated: Sat, 07 Jun 2025 02:15:25 GMT + * Dependencies: [@types/node](https://npmjs.com/package/@types/node) + +# Credits +These definitions were written by [Alan Plum](https://github.com/pluma), [Gaurav Sharma](https://github.com/gtpan77), and [Sebastian Beltran](https://github.com/bjohansebas). diff --git a/backend/node_modules/@types/cors/index.d.ts b/backend/node_modules/@types/cors/index.d.ts new file mode 100644 index 0000000..5ab0dcf --- /dev/null +++ b/backend/node_modules/@types/cors/index.d.ts @@ -0,0 +1,56 @@ +/// + +import { IncomingHttpHeaders } from "http"; + +type StaticOrigin = boolean | string | RegExp | Array; + +type CustomOrigin = ( + requestOrigin: string | undefined, + callback: (err: Error | null, origin?: StaticOrigin) => void, +) => void; + +declare namespace e { + interface CorsRequest { + method?: string | undefined; + headers: IncomingHttpHeaders; + } + interface CorsOptions { + /** + * @default '*' + */ + origin?: StaticOrigin | CustomOrigin | undefined; + /** + * @default 'GET,HEAD,PUT,PATCH,POST,DELETE' + */ + methods?: string | string[] | undefined; + allowedHeaders?: string | string[] | undefined; + exposedHeaders?: string | string[] | undefined; + credentials?: boolean | undefined; + maxAge?: number | undefined; + /** + * @default false + */ + preflightContinue?: boolean | undefined; + /** + * @default 204 + */ + optionsSuccessStatus?: number | undefined; + } + type CorsOptionsDelegate = ( + req: T, + callback: (err: Error | null, options?: CorsOptions) => void, + ) => void; +} + +declare function e( + options?: e.CorsOptions | e.CorsOptionsDelegate, +): ( + req: T, + res: { + statusCode?: number | undefined; + setHeader(key: string, value: string): any; + end(): any; + }, + next: (err?: any) => any, +) => void; +export = e; diff --git a/backend/node_modules/@types/cors/package.json b/backend/node_modules/@types/cors/package.json new file mode 100644 index 0000000..4824a17 --- /dev/null +++ b/backend/node_modules/@types/cors/package.json @@ -0,0 +1,38 @@ +{ + "name": "@types/cors", + "version": "2.8.19", + "description": "TypeScript definitions for cors", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/cors", + "license": "MIT", + "contributors": [ + { + "name": "Alan Plum", + "githubUsername": "pluma", + "url": "https://github.com/pluma" + }, + { + "name": "Gaurav Sharma", + "githubUsername": "gtpan77", + "url": "https://github.com/gtpan77" + }, + { + "name": "Sebastian Beltran", + "githubUsername": "bjohansebas", + "url": "https://github.com/bjohansebas" + } + ], + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/cors" + }, + "scripts": {}, + "dependencies": { + "@types/node": "*" + }, + "peerDependencies": {}, + "typesPublisherContentHash": "a090e558c5f443573318c2955deecddc840bd8dfaac7cdedf31c7f6ede8d0b47", + "typeScriptVersion": "5.1" +} \ No newline at end of file diff --git a/backend/package-lock.json b/backend/package-lock.json index 4c724b7..5cf22c7 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -13,6 +13,7 @@ "express": "^5.1.0" }, "devDependencies": { + "@types/cors": "^2.8.19", "@types/express": "^5.0.3", "@types/node": "^22.15.30", "ts-node": "^10.9.2", @@ -109,6 +110,16 @@ "@types/node": "*" } }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/express": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz", diff --git a/backend/package.json b/backend/package.json index 55e9a86..223d171 100644 --- a/backend/package.json +++ b/backend/package.json @@ -14,6 +14,7 @@ "express": "^5.1.0" }, "devDependencies": { + "@types/cors": "^2.8.19", "@types/express": "^5.0.3", "@types/node": "^22.15.30", "ts-node": "^10.9.2", diff --git a/backend/server.ts b/backend/server.ts index e69de29..2f0f4c0 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -0,0 +1,73 @@ +import express, { Request, Response } from "express"; +import cors from "cors"; +import fs from "fs"; +import path from "path"; + +const app = express(); +const PORT = 3000; +const RECIPES_DIR = path.join(__dirname, "recipes"); + +app.use(cors()); +app.use(express.json()); + +app.post("/addRecipe", (req: Request, res: Response) => { + const { title, recipe } = req.body; + + if (!title || !recipe) { + return res.status(400).json({ error: "Title and recipe text are required" }); + } + + const filename = `${title.replace(/\s+/g, "_")}.md`; + const filepath = path.join(RECIPES_DIR, filename); + + fs.writeFile(filepath, recipe, (err) => { + if (err) { + return res.status(500).json({ error: "Failed to save recipe" }); + } + res.status(200).json({ message: "Recipe saved successfully" }); + }); +}); + +app.get("/loadRecipes", (req, res) => { + fs.readdir(RECIPES_DIR, (err, files) => { + if (err) { + console.error("Error reading directory:", err); + return res.status(500).json({ message: "Failed to read recipes" }); + } + + const recipes: object[] = []; + + let filesRead = 0; + if (files.length === 0) return res.json([]); + + files.forEach((file) => { + const filePath = path.join(RECIPES_DIR, file); + + fs.readFile(filePath, "utf8", (err, data) => { + filesRead++; + if (!err) { + try { + const parsed = JSON.parse(data); + recipes.push(parsed); + } catch (e) { + console.warn("Invalid JSON in file:", file); + } + } + + if (filesRead === files.length) { + res.json(recipes); + } + }); + }); + }); +}); + +// Nur starten, wenn die Datei direkt ausgeführt wird (nicht importiert wird) +if (require.main === module) { + app.listen(PORT, () => { + console.log(`Server is running on http://localhost:${PORT}`); + }); +} + +// Export für andere Dateien +export default app; diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 904d43f..933d0b3 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -11,7 +11,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "es6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "libReplacement": true, /* Enable lib replacement. */ @@ -26,8 +26,8 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ + "module": "commonjs" /* Specify what module code is generated. */, + "rootDir": "./" /* Specify the root folder within your source files. */, // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ @@ -59,7 +59,7 @@ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "outDir": "./" /* Specify an output folder for all emitted files. */, // "removeComments": true, /* Disable emitting comments. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ @@ -80,12 +80,12 @@ // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ + "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ @@ -108,6 +108,6 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ } } diff --git a/frontend/README.md b/frontend/README.md index 8204b83..957be6b 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -4,6 +4,8 @@ Here are all infos that are important for the developers. You can find here for ## How to markdown +This module is from this [GitHub repo](https://github.com/remarkjs/react-markdown) + ### Necesarry syntax for import ```ts @@ -15,12 +17,16 @@ import Markdown from "react-markdown"; This syntax is important when you want to use markdown on the website! +> You have to call the script elemt above in every file where you want to use markdown! + ### How to call markdown ```ts -{markdown} + ``` +Between the openeing and closing tag can you write markdown. This markdown syntx is then rendered on the website. + # React + TypeScript + Vite This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index bae9d07..47a685e 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,17 +1,25 @@ -import "./App.css"; -; -import Markdown from "react-markdown"; -const markdown = "# Hi, *Pluto*!"; +import { useEffect, useState } from "react"; function App() { + const [recipes, setRecipes] = useState([]); + + useEffect(() => { + fetch("http://localhost:3000/loadRecipes") + .then((res) => res.json()) + .then((data) => setRecipes(data)) + .catch((err) => console.error(err)); + }, []); + return ( - <> - - {markdown} - +
+

Rezepte

+
    + {recipes.map((r, i) => ( +
  • {JSON.stringify(r)}
  • + ))} +
+
); } -export default App; +export default App; \ No newline at end of file