diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..147abbd2d4558ecf364ff6646971f1999fb1dffa --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +DATABASE_URL="file:./dev.db" +URL="http://localhost:3000" diff --git a/.gitignore b/.gitignore index 4a7f73a2ed0d9f99a182a5855b29846de7bad09c..2b9a7d8165f212333106013e7643ff2330c10682 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,8 @@ logs .env .env.* !.env.example + +# Prisma +/prisma/*.db +/prisma/*.db-journal +/prisma/.prisma \ No newline at end of file diff --git a/nuxt.config.ts b/nuxt.config.ts index 99fe9043d0de28b0014d168cd3362fbb334c2707..a0a3d16d4fa747a8463fc6ba1973ed53cca5ae54 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,6 +1,13 @@ // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ - compatibilityDate: '2024-04-03', - devtools: { enabled: true }, - modules: ['@pinia/nuxt', '@nuxt/ui', '@vueuse/nuxt'] + compatibilityDate: '2024-04-03', + devtools: { + enabled: true, + + timeline: { + enabled: true, + }, + }, + modules: ['@pinia/nuxt', '@nuxt/ui', '@vueuse/nuxt'], + extends: ['@nuxt/ui-pro'], }) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8a5c89c57ca2874beaa4de1cad80dae883d6b911..b86f7e1c8ae1f018f324ae0d09e964bfbdbfb806 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,20 @@ "hasInstallScript": true, "dependencies": { "@nuxt/ui": "^2.19.2", + "@nuxt/ui-pro": "^1.5.0", "@pinia/nuxt": "^0.7.0", + "@prisma/client": "^5.22.0", "@vueuse/core": "^11.2.0", "@vueuse/nuxt": "^11.2.0", + "bcrypt": "^5.1.1", "nuxt": "^3.14.159", "pinia": "^2.2.6", "vue": "latest", "vue-router": "latest" + }, + "devDependencies": { + "@types/bcrypt": "^5.0.2", + "prisma": "^5.22.0" } }, "node_modules/@alloc/quick-lru": { @@ -898,6 +905,14 @@ "@iconify/types": "*" } }, + "node_modules/@iconify-json/vscode-icons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@iconify-json/vscode-icons/-/vscode-icons-1.2.2.tgz", + "integrity": "sha512-bTpT0HJDRqGkxQv8oiETNHLEnBZpnA1QaRD35CQyO7M7qgWVLx2xwn/lK6e4waojmlPC3ckMBx3WFIUUn0/Jdg==", + "dependencies": { + "@iconify/types": "*" + } + }, "node_modules/@iconify/collections": { "version": "1.0.480", "resolved": "https://registry.npmjs.org/@iconify/collections/-/collections-1.0.480.tgz", @@ -1421,6 +1436,24 @@ "tailwindcss": "^3.4.14" } }, + "node_modules/@nuxt/ui-pro": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@nuxt/ui-pro/-/ui-pro-1.5.0.tgz", + "integrity": "sha512-RYYX8JCSjVVat7kdR675uQgIHB2JJSYesP/0XAaBKesVYKMMjLAA0h57OdnIbGarwkZEs7MqoRXcaoGfh14AkA==", + "dependencies": { + "@iconify-json/vscode-icons": "^1.2.2", + "@nuxt/ui": "^2.19.2", + "@vueuse/core": "^11.2.0", + "defu": "^6.1.4", + "git-url-parse": "^15.0.0", + "ofetch": "^1.4.1", + "parse-git-config": "^3.0.0", + "pathe": "^1.1.2", + "pkg-types": "^1.2.1", + "tailwind-merge": "^2.5.4", + "vue3-smooth-dnd": "^0.0.6" + } + }, "node_modules/@nuxt/vite-builder": { "version": "3.14.159", "resolved": "https://registry.npmjs.org/@nuxt/vite-builder/-/vite-builder-3.14.159.tgz", @@ -1851,6 +1884,68 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@prisma/client": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.22.0.tgz", + "integrity": "sha512-M0SVXfyHnQREBKxCgyo7sffrKttwE6R8PMq330MIUF0pTwjUhLbW84pFDlf06B27XyCR++VtjugEnIHdr07SVA==", + "hasInstallScript": true, + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/debug": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", + "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", + "devOptional": true + }, + "node_modules/@prisma/engines": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz", + "integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/fetch-engine": "5.22.0", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz", + "integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==", + "devOptional": true + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz", + "integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz", + "integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.22.0" + } + }, "node_modules/@redocly/ajv": { "version": "8.11.2", "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz", @@ -2428,6 +2523,15 @@ "node": ">=10.13.0" } }, + "node_modules/@types/bcrypt": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", + "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -3353,6 +3457,24 @@ } ] }, + "node_modules/bcrypt": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bcrypt/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -7667,6 +7789,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/prisma": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.22.0.tgz", + "integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines": "5.22.0" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=16.13" + }, + "optionalDependencies": { + "fsevents": "2.3.3" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -8284,6 +8425,11 @@ "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==" }, + "node_modules/smooth-dnd": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/smooth-dnd/-/smooth-dnd-0.12.1.tgz", + "integrity": "sha512-Dndj/MOG7VP83mvzfGCLGzV2HuK1lWachMtWl/Iuk6zV7noDycIBnflwaPuDzoaapEl3Pc4+ybJArkkx9sxPZg==" + }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -10239,6 +10385,17 @@ "vue": "^3.2.0" } }, + "node_modules/vue3-smooth-dnd": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/vue3-smooth-dnd/-/vue3-smooth-dnd-0.0.6.tgz", + "integrity": "sha512-CH9ZZhEfE7qU1ef2rlfgBG+nZtQX8PnWlspB2HDDz1uVGU7fXM0Pr65DftBMz4X81S+edw2H+ZFG6Dyb5J81KA==", + "dependencies": { + "smooth-dnd": "^0.12.1" + }, + "peerDependencies": { + "vue": "^3.0.11" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index dcc2642365997c7819a869c44b228e53c8d6df1b..baadce1aa61e9bbbca665150c082b2df032013cb 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,12 @@ }, "dependencies": { "@nuxt/ui": "^2.19.2", + "@nuxt/ui-pro": "^1.5.0", "@pinia/nuxt": "^0.7.0", + "@prisma/client": "^5.22.0", "@vueuse/core": "^11.2.0", "@vueuse/nuxt": "^11.2.0", + "bcrypt": "^5.1.1", "nuxt": "^3.14.159", "pinia": "^2.2.6", "vue": "latest", @@ -21,5 +24,9 @@ }, "overrides": { "vue": "latest" + }, + "devDependencies": { + "@types/bcrypt": "^5.0.2", + "prisma": "^5.22.0" } } diff --git a/prisma/migrations/20241109153246_init/migration.sql b/prisma/migrations/20241109153246_init/migration.sql new file mode 100644 index 0000000000000000000000000000000000000000..223d3a1b5cb8e86ab7698dc538a2a6478b685ba0 --- /dev/null +++ b/prisma/migrations/20241109153246_init/migration.sql @@ -0,0 +1,23 @@ +-- CreateTable +CREATE TABLE "User" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "email" TEXT NOT NULL, + "name" TEXT NOT NULL, + "password" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +-- CreateTable +CREATE TABLE "PasswordReset" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "token" TEXT NOT NULL, + "expiresAt" DATETIME NOT NULL, + "userId" INTEGER NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT "PasswordReset_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000000000000000000000000000000000000..e5e5c4705ab084270b7de6f45d5291ba01666948 --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -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" \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000000000000000000000000000000000000..755bb30a85c220985f7f16ce7213abbde8a69664 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,34 @@ +// This is your Prisma schema file, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? +// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init + +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "sqlite" + url = env("DATABASE_URL") +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String + password String + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) + PasswordReset PasswordReset[] +} + +model PasswordReset { + id Int @id @default(autoincrement()) + token String + expiresAt DateTime + userId Int + user User @relation(fields: [userId], references: [id]) + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) +}