feat: add entries

This commit is contained in:
redglow
2026-06-20 17:43:53 +02:00
parent 3c4e6d3612
commit dc576d6b19
6 changed files with 165 additions and 8 deletions
+46 -4
View File
@@ -1,6 +1,27 @@
import { Box, FormLabel, TextareaAutosize, TextField } from "@mui/material";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import {
Box,
Button,
FormLabel,
styled,
TextareaAutosize,
TextField,
} from "@mui/material";
import { DatePicker } from "@mui/x-date-pickers";
import { createFileRoute } from "@tanstack/react-router";
import type { ChangeEvent } from "react";
const VisuallyHiddenInput = styled("input")({
clip: "rect(0 0 0 0)",
clipPath: "inset(50%)",
height: 1,
overflow: "hidden",
position: "absolute",
bottom: 0,
left: 0,
whiteSpace: "nowrap",
width: 1,
});
export const Route = createFileRoute("/add/")({
component: RouteComponent,
@@ -10,6 +31,9 @@ function RouteComponent() {
return (
<Box
component="form"
enctype="multipart/form-data"
action="/api/announcements/add"
method="POST"
sx={{
display: "flex",
flexDirection: "column",
@@ -18,10 +42,28 @@ function RouteComponent() {
noValidate
autoComplete="off"
>
<TextField label="Title"></TextField>
<TextField name="title" label="Title"></TextField>
<FormLabel>Text:</FormLabel>
<TextareaAutosize minRows={6}></TextareaAutosize>
<DatePicker />
<TextareaAutosize name="text" minRows={6}></TextareaAutosize>
<DatePicker name="publication_date" />
<Button
component="label"
variant="contained"
tabIndex={-1}
startIcon={<CloudUploadIcon />}
>
Upload files
<VisuallyHiddenInput
type="file"
name="image"
onChange={(event: ChangeEvent<HTMLInputElement>) =>
console.log(event.target.files)
}
/>
</Button>
<Button variant="contained" type="submit">
Submit
</Button>
</Box>
);
}
+1 -1
View File
@@ -9,7 +9,7 @@ export interface AnnouncementTable {
title: string;
text: string;
image: string;
publication_date: Date;
publication_date: string;
}
export type Announcement = Selectable<AnnouncementTable>;
+31
View File
@@ -1,13 +1,44 @@
import express from "express";
import multer from "multer";
import ViteExpress from "vite-express";
import z from "zod";
import { db } from "./db/database.js";
const upload = multer({
dest: "uploads/",
});
const app = express();
const AddInput = z.object({
file: z.object({ filename: z.string() }),
body: z.object({
publication_date: z.coerce
.date()
.transform((x) => new Date(x).toISOString()),
title: z.string().nonempty(),
text: z.string().nonempty(),
}),
});
app.get("/hello", (_, res) => {
res.send("Hello Vite + React + TypeScript!");
});
app.post("/api/announcements/add", upload.single("image"), async (req, res) => {
const addInput = AddInput.parse(req);
await db
.insertInto("announcements")
.values({
title: addInput.body.title,
text: addInput.body.text,
publication_date: addInput.body.publication_date,
image: addInput.file.filename,
})
.execute();
res.redirect("/");
});
app.get("/api/announcements", async (_, res) => {
// await new Promise((resolve) => setTimeout(resolve, 1000));
const announcements = await db