implemented backend part of progressive form

feature/modern-browsers
Inga 🏳‍🌈 2 weeks ago
parent 3c982e845f
commit 98fc37530d
  1. 2
      package-lock.json
  2. 2
      package.json
  3. 5
      src/backend/app.ts
  4. 31
      src/backend/main.tsx
  5. 11
      src/backend/progressive-form.ts
  6. 23
      src/backend/utils.ts
  7. 2
      src/frontend/static/style.css

2
package-lock.json generated

@ -9,6 +9,7 @@
"version": "1.0.0",
"license": "CNPLv7",
"dependencies": {
"body-parser": "^1.20.3",
"express": "^4.21.1",
"preact": "^10.24.3",
"preact-render-to-string": "^6.5.11"
@ -16,6 +17,7 @@
"devDependencies": {
"@eslint/js": "^9.15.0",
"@tsconfig/strictest": "^2.0.5",
"@types/body-parser": "^1.19.5",
"@types/eslint__js": "^8.42.3",
"@types/express": "^5.0.0",
"copyfiles": "^2.4.1",

@ -19,6 +19,7 @@
"devDependencies": {
"@eslint/js": "^9.15.0",
"@tsconfig/strictest": "^2.0.5",
"@types/body-parser": "^1.19.5",
"@types/eslint__js": "^8.42.3",
"@types/express": "^5.0.0",
"copyfiles": "^2.4.1",
@ -32,6 +33,7 @@
"typescript-eslint": "^8.14.0"
},
"dependencies": {
"body-parser": "^1.20.3",
"express": "^4.21.1",
"preact": "^10.24.3",
"preact-render-to-string": "^6.5.11"

@ -1,11 +1,14 @@
import path from "node:path";
import bodyParser from "body-parser";
import express from "express";
import { mainPageHandler } from "./main.tsx";
import { createProgressiveForm } from "./progressive-form.ts";
export const createApp = () => {
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/", mainPageHandler);
app.use("/", createProgressiveForm(mainPageHandler));
app.use("/frontend", express.static(path.join(import.meta.dirname, "..", "frontend")));
app.use("/shared", express.static(path.join(import.meta.dirname, "..", "shared")));

@ -2,7 +2,8 @@ import type { RequestHandler } from "express";
import { safeGetQueryValue, sendHtml } from "./utils.ts";
export const mainPageHandler: RequestHandler = (req, res) => {
const pageNumber = parseInt(safeGetQueryValue(req, "page") ?? "0", 10);
const a = parseInt(safeGetQueryValue(req, "a") ?? "0", 10);
const b = parseInt(safeGetQueryValue(req, "b") ?? "0", 10);
sendHtml(
res,
<html>
@ -18,12 +19,28 @@ export const mainPageHandler: RequestHandler = (req, res) => {
</head>
<body>
<p>Hello world!</p>
<p>
Page number <span class="pageNumber">{pageNumber}</span>
</p>
<p>
<a href={`?page=${pageNumber + 1}`}>Go to the next page</a>
</p>
<ul>
<li>
Value of "a": <span class="counter">{a}</span>
</li>
<li>
Value of "b": <span class="counter">{b}</span>
</li>
</ul>
<form method="post">
<p>
<button type="submit" name={`a`} value={`${a + 1}`}>
Increase "a"
</button>
</p>
</form>
<form method="post">
<p>
<button type="submit" name={`b`} value={`${b + 1}`}>
Increase "b"
</button>
</p>
</form>
</body>
</html>,
);

@ -0,0 +1,11 @@
import express, { RequestHandler } from "express";
import { rewriteQueryParams } from "./utils.ts";
export const createProgressiveForm = (mainHandler: RequestHandler) => {
const router = express.Router();
router.get("/", mainHandler);
router.post("/", rewriteQueryParams);
return router;
};

@ -1,4 +1,4 @@
import type { Request, Response } from "express";
import type { Request, RequestHandler, Response } from "express";
import type { VNode } from "preact";
import { render } from "preact-render-to-string";
@ -17,3 +17,24 @@ export const safeGetQueryValue = (req: Request, name: string) => {
return result || null;
};
export const rewriteQueryParams: RequestHandler = (req, res) => {
const newQuery = new URLSearchParams();
for (const [param, value] of Object.entries(req.query)) {
if (typeof value === "string") {
newQuery.set(param, value);
}
}
if (req.body) {
const body = req.body as Record<string, unknown>;
for (const [param, value] of Object.entries(body)) {
if (typeof value === "string") {
newQuery.set(param, value);
}
}
}
res.redirect(`?${newQuery.toString()}`);
};

@ -1,4 +1,4 @@
.pageNumber {
.counter {
font-weight: bold;
color: red;
}

Loading…
Cancel
Save