From 8cf282e12700aee9ce9a6c48af49999d3b8bfd84 Mon Sep 17 00:00:00 2001 From: Domenik Date: Fri, 21 Feb 2025 11:53:06 +0100 Subject: [PATCH] feat: word-counter fully implemented + lower case revision --- backend/server.ts | 2 + backend/src/routes/regextest.route.ts | 6 +- backend/src/routes/wordcounter.route.ts | 34 ++++++++ frontend/src/app/password-generator/page.tsx | 2 +- frontend/src/app/rgb-to-hex/page.tsx | 6 +- frontend/src/app/word-counter/layout.tsx | 20 +++++ frontend/src/app/word-counter/page.tsx | 85 ++++++++++++++++++++ 7 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 backend/src/routes/wordcounter.route.ts create mode 100644 frontend/src/app/word-counter/layout.tsx create mode 100644 frontend/src/app/word-counter/page.tsx diff --git a/backend/server.ts b/backend/server.ts index 607a74c..8973a64 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -6,6 +6,7 @@ import { colorConvert } from "./src/routes/colorconvert.route"; import { passwordGenerate } from "./src/routes/passwordgenerate.route"; import { regexTest } from "./src/routes/regextest.route"; import { tmzConvert } from "./src/routes/tmzconvert.route"; +import { wordCounter } from "./src/routes/wordcounter.route"; const app = Fastify({ logger: true }); @@ -21,6 +22,7 @@ app.register(colorConvert); app.register(passwordGenerate); app.register(regexTest); app.register(tmzConvert); +app.register(wordCounter); const PORT = process.env.PORT || 4000; app.listen({ port: Number(PORT), host: "0.0.0.0" }, () => { diff --git a/backend/src/routes/regextest.route.ts b/backend/src/routes/regextest.route.ts index 7f08bd6..446a59b 100644 --- a/backend/src/routes/regextest.route.ts +++ b/backend/src/routes/regextest.route.ts @@ -34,12 +34,12 @@ export async function regexTest(app: FastifyInstance) { } const result = regexPattern.test(data.test); - + let output = ""; if (result) { - output = `The input matches the regular expression!`; + output = "the input matches the regular expression!"; } else { - output = `The input does not match the regular expression.`; + output = "the input does not match the regular expression."; } reply.header("Content-Type", "text/plain").status(200).send(output); diff --git a/backend/src/routes/wordcounter.route.ts b/backend/src/routes/wordcounter.route.ts new file mode 100644 index 0000000..3b747ac --- /dev/null +++ b/backend/src/routes/wordcounter.route.ts @@ -0,0 +1,34 @@ +import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify"; + +interface RequestBody { + input: string; +} + +export async function wordCounter(app: FastifyInstance) { + app.post( + "/api/word-counter", + async ( + request: FastifyRequest<{ Body: RequestBody }>, + reply: FastifyReply, + ) => { + try { + const data = request.body; + if (!data) { + return reply.status(400).send({ error: "No text declared!" }); + } else if (data.input == "") { + return reply.status(400).send({ error: "No text!" }); + } + + const output = data.input.trim().split(/\s+/).length; + + reply + .header("Content-Type", "text/plain") + .status(200) + .send(output.toString()); + } catch (error) { + console.error("Convert error:", error); + reply.status(500).send({ error: "Error while converting!" }); + } + }, + ); +} diff --git a/frontend/src/app/password-generator/page.tsx b/frontend/src/app/password-generator/page.tsx index eda0f9e..138fba1 100644 --- a/frontend/src/app/password-generator/page.tsx +++ b/frontend/src/app/password-generator/page.tsx @@ -5,7 +5,7 @@ import Navbar from "../../components/Navbar"; import Footer from "../../components/Footer"; import Button from "../../components/Button"; -export default function RgbToHex() { +export default function PasswordGenerator() { const [loading, setLoading] = useState(false); const [password, setPassword] = useState(""); diff --git a/frontend/src/app/rgb-to-hex/page.tsx b/frontend/src/app/rgb-to-hex/page.tsx index a80141d..aa1825d 100644 --- a/frontend/src/app/rgb-to-hex/page.tsx +++ b/frontend/src/app/rgb-to-hex/page.tsx @@ -71,7 +71,7 @@ export default function RgbToHex() {

rgb-to-hex

) { + return ( + + {children} + + ); +} diff --git a/frontend/src/app/word-counter/page.tsx b/frontend/src/app/word-counter/page.tsx new file mode 100644 index 0000000..94a9455 --- /dev/null +++ b/frontend/src/app/word-counter/page.tsx @@ -0,0 +1,85 @@ +"use client"; + +import React, { useState } from "react"; +import Navbar from "../../components/Navbar"; +import Footer from "../../components/Footer"; +import Button from "../../components/Button"; + +export default function WordCounter() { + const [loading, setLoading] = useState(false); + const [output, setOutput] = useState(""); + + const countWords = async () => { + setLoading(true); + + const input = (document.getElementById("input") as HTMLInputElement).value; + + try { + const response = await fetch( + process.env.backend_url + "/api/word-counter", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ input: input }), + }, + ); + if (!response.ok) { + return new Error(`Error: ${response.statusText}`); + } + const output: string = await response.text(); + console.log(output); + setOutput(output); + } catch (error) { + console.error("Error while converting:", error); + alert("Error while converting"); + } finally { + setLoading(false); + } + }; + + const clearInAndOutput = () => { + setOutput(""); + const input = document.getElementById("input") as HTMLInputElement; + input.value = ""; + }; + + return ( +
+ +
+

word-counter

+
+ +