Add db
This commit is contained in:
parent
5ce272e7c8
commit
32226f7d0e
12 changed files with 2759 additions and 39 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -19,3 +19,6 @@ pnpm-debug.log*
|
|||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
|
||||
db.sqlite
|
||||
db.sqlite-journal
|
||||
|
|
2654
package-lock.json
generated
2654
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -14,8 +14,15 @@
|
|||
"@astrojs/node": "^8.2.0",
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"astro": "^4.3.2",
|
||||
"better-sqlite3": "^9.4.0",
|
||||
"kysely": "^0.27.2",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.3.3",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/better-sqlite3": "^7.6.9",
|
||||
"prisma": "^5.9.1",
|
||||
"prisma-kysely": "^1.7.1"
|
||||
}
|
||||
}
|
||||
|
|
20
prisma/migrations/20240205181524_init/migration.sql
Normal file
20
prisma/migrations/20240205181524_init/migration.sql
Normal file
|
@ -0,0 +1,20 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "Letter" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"created" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"firstName" TEXT NOT NULL,
|
||||
"lastName" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"phone" TEXT,
|
||||
"variant" TEXT NOT NULL,
|
||||
"gender" TEXT,
|
||||
"branch" TEXT NOT NULL,
|
||||
"message" TEXT NOT NULL,
|
||||
"subscribed" BOOLEAN NOT NULL,
|
||||
"confirmationToken" TEXT NOT NULL,
|
||||
"confirmed" BOOLEAN NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Letter_email_key" ON "Letter"("email");
|
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "sqlite"
|
29
prisma/schema.prisma
Normal file
29
prisma/schema.prisma
Normal file
|
@ -0,0 +1,29 @@
|
|||
datasource db {
|
||||
provider = "sqlite"
|
||||
url = "file:../db.sqlite"
|
||||
}
|
||||
|
||||
generator kysely {
|
||||
provider = "prisma-kysely"
|
||||
output = "../src/db"
|
||||
fileName = "types.ts"
|
||||
}
|
||||
|
||||
model Letter {
|
||||
id Int @id @default(autoincrement())
|
||||
created DateTime @default(now())
|
||||
updated DateTime @default(now())
|
||||
firstName String
|
||||
lastName String
|
||||
email String @unique
|
||||
phone String?
|
||||
|
||||
variant String
|
||||
gender String?
|
||||
branch String
|
||||
message String
|
||||
subscribed Boolean
|
||||
|
||||
confirmationToken String
|
||||
confirmed Boolean @default(false)
|
||||
}
|
12
src/db/index.ts
Normal file
12
src/db/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { Kysely, SqliteDialect } from "kysely";
|
||||
import SQLite from "better-sqlite3";
|
||||
import type { DB } from "./types";
|
||||
import { join } from "node:path";
|
||||
|
||||
const dialect = new SqliteDialect({
|
||||
database: new SQLite(join(process.cwd(), "db.sqlite")),
|
||||
});
|
||||
|
||||
export const db = new Kysely<DB>({
|
||||
dialect,
|
||||
});
|
25
src/db/types.ts
Normal file
25
src/db/types.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import type { ColumnType } from "kysely";
|
||||
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
|
||||
? ColumnType<S, I | undefined, U>
|
||||
: ColumnType<T, T | undefined, T>;
|
||||
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
||||
|
||||
export type Letter = {
|
||||
id: Generated<number>;
|
||||
created: Generated<string>;
|
||||
updated: Generated<string>;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
phone: string | null;
|
||||
variant: string;
|
||||
gender: string | null;
|
||||
branch: string;
|
||||
message: string;
|
||||
subscribed: number;
|
||||
confirmationToken: string;
|
||||
confirmed: Generated<number>;
|
||||
};
|
||||
export type DB = {
|
||||
Letter: Letter;
|
||||
};
|
|
@ -91,7 +91,7 @@ const result = letterOptionsSchema.safeParse(options);
|
|||
zpracováním osobních údajů
|
||||
</a>.
|
||||
</Checkbox>
|
||||
<Checkbox name="subscribe">
|
||||
<Checkbox name="subscribed">
|
||||
Chci zaslat report o EPH a další informace o aktivitách EPH v ČR
|
||||
</Checkbox>
|
||||
<Button type="submit">
|
||||
|
|
|
@ -10,6 +10,7 @@ export const letterFormSchema = z.object({
|
|||
gender: z.string().default("g"),
|
||||
branch: z.string(),
|
||||
message: z.string().min(1),
|
||||
|
||||
subscribed: z.boolean(),
|
||||
});
|
||||
|
||||
|
|
|
@ -14,10 +14,13 @@ export const prerender = false;
|
|||
if (Astro.request.method === "POST") {
|
||||
const formData = await Astro.request.formData();
|
||||
const data = Object.fromEntries(formData.entries());
|
||||
const result = await letterFormSchema.safeParseAsync(data);
|
||||
const result = await letterFormSchema.safeParseAsync({
|
||||
...data,
|
||||
subscribed: formData.has("subscribed"),
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
createLetter(lang, result.data);
|
||||
await createLetter(lang, result.data);
|
||||
return Astro.redirect(`/${lang}/letter-sent`, 303);
|
||||
}
|
||||
|
||||
|
|
35
src/tasks.ts
35
src/tasks.ts
|
@ -1,7 +1,40 @@
|
|||
import { db } from "./db";
|
||||
import type { Lang } from "./lang";
|
||||
import type { LetterForm } from "./letter/schema";
|
||||
import { generateToken } from "./utils";
|
||||
import { join } from "node:path";
|
||||
|
||||
export async function createLetter(lang: Lang, letterForm: LetterForm) {
|
||||
// TODO
|
||||
console.log(lang, letterForm);
|
||||
|
||||
// const existingLetter = await db
|
||||
// .selectFrom("Letter")
|
||||
// .where("email", "=", letterForm.email)
|
||||
// .select("id")
|
||||
// .execute();
|
||||
|
||||
// if (existingLetter.length > 0) {
|
||||
// throw new Error("Exists");
|
||||
// }
|
||||
|
||||
const confirmationToken = generateToken(32);
|
||||
const result = await db
|
||||
.insertInto("Letter")
|
||||
.values({
|
||||
...letterForm,
|
||||
confirmationToken,
|
||||
subscribed: Number(letterForm.subscribed),
|
||||
})
|
||||
.executeTakeFirst();
|
||||
|
||||
if (!result.insertId) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
await sendConfirmationEmail(lang, result.insertId.toString(), confirmationToken);
|
||||
}
|
||||
|
||||
async function sendConfirmationEmail(lang: Lang, id: string, token: string) {
|
||||
const confirmationUrl = join(import.meta.env.BASE_URL, lang, "confirm", id, token);
|
||||
console.log("Confirmation link: ", confirmationUrl);
|
||||
}
|
||||
|
|
Reference in a new issue