refactor: migrate from drizzle to PocketBase
This commit is contained in:
parent
68fb45d6ef
commit
9231e0642c
|
|
@ -1,10 +0,0 @@
|
|||
import { defineConfig } from "drizzle-kit";
|
||||
|
||||
export default defineConfig({
|
||||
out: "./drizzle",
|
||||
schema: "./src/lib/db/schema.ts",
|
||||
dialect: "sqlite",
|
||||
dbCredentials: {
|
||||
url: process.env.DB_FILE_NAME!,
|
||||
},
|
||||
});
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
CREATE TABLE `movies` (
|
||||
`id` integer PRIMARY KEY NOT NULL,
|
||||
`title` text NOT NULL,
|
||||
`overview` text NOT NULL,
|
||||
`popularity` real NOT NULL,
|
||||
`release_date` text NOT NULL,
|
||||
`poster_path` text NOT NULL,
|
||||
`seen` integer DEFAULT 0 NOT NULL,
|
||||
`favorite` integer DEFAULT 0 NOT NULL,
|
||||
`notes` text DEFAULT '' NOT NULL
|
||||
);
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
||||
CREATE TABLE `__new_movies` (
|
||||
`id` integer PRIMARY KEY NOT NULL,
|
||||
`title` text NOT NULL,
|
||||
`adult` integer NOT NULL,
|
||||
`backdrop_path` text NOT NULL,
|
||||
`genre_ids` text NOT NULL,
|
||||
`original_language` text NOT NULL,
|
||||
`original_title` text NOT NULL,
|
||||
`overview` text NOT NULL,
|
||||
`popularity` real NOT NULL,
|
||||
`poster_path` text NOT NULL,
|
||||
`release_date` text NOT NULL,
|
||||
`video` integer NOT NULL,
|
||||
`vote_average` real NOT NULL,
|
||||
`vote_count` integer NOT NULL,
|
||||
`seen` integer DEFAULT false,
|
||||
`favorite` integer DEFAULT false
|
||||
);
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `__new_movies`("id", "title", "overview", "popularity", "poster_path", "release_date", "seen", "favorite", "adult", "backdrop_path", "genre_ids", "original_language", "original_title", "video", "vote_average", "vote_count")
|
||||
SELECT
|
||||
"id",
|
||||
"title",
|
||||
"overview",
|
||||
"popularity",
|
||||
"poster_path",
|
||||
"release_date",
|
||||
"seen",
|
||||
"favorite",
|
||||
0 as "adult", -- wartość domyślna
|
||||
'' as "backdrop_path", -- wartość domyślna
|
||||
'[]' as "genre_ids", -- wartość domyślna (pusta tablica JSON)
|
||||
'pl-PL' as "original_language", -- wartość domyślna
|
||||
"title" as "original_title", -- kopiuj z title
|
||||
0 as "video", -- wartość domyślna
|
||||
0.0 as "vote_average", -- wartość domyślna
|
||||
0 as "vote_count" -- wartość domyślna
|
||||
FROM `movies`;--> statement-breakpoint
|
||||
DROP TABLE `movies`;--> statement-breakpoint
|
||||
ALTER TABLE `__new_movies` RENAME TO `movies`;--> statement-breakpoint
|
||||
PRAGMA foreign_keys=ON;
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "19a2bad6-49be-485d-ac5e-291bd3d664ad",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"tables": {
|
||||
"movies": {
|
||||
"name": "movies",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"overview": {
|
||||
"name": "overview",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"popularity": {
|
||||
"name": "popularity",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"release_date": {
|
||||
"name": "release_date",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"poster_path": {
|
||||
"name": "poster_path",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"seen": {
|
||||
"name": "seen",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": 0
|
||||
},
|
||||
"favorite": {
|
||||
"name": "favorite",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": 0
|
||||
},
|
||||
"notes": {
|
||||
"name": "notes",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "''"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "c3b4d292-f58b-4df8-844c-6e534034c832",
|
||||
"prevId": "19a2bad6-49be-485d-ac5e-291bd3d664ad",
|
||||
"tables": {
|
||||
"movies": {
|
||||
"name": "movies",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"adult": {
|
||||
"name": "adult",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"backdrop_path": {
|
||||
"name": "backdrop_path",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"genre_ids": {
|
||||
"name": "genre_ids",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_language": {
|
||||
"name": "original_language",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_title": {
|
||||
"name": "original_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"overview": {
|
||||
"name": "overview",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"popularity": {
|
||||
"name": "popularity",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"poster_path": {
|
||||
"name": "poster_path",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"release_date": {
|
||||
"name": "release_date",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"video": {
|
||||
"name": "video",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"vote_average": {
|
||||
"name": "vote_average",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"vote_count": {
|
||||
"name": "vote_count",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"seen": {
|
||||
"name": "seen",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"favorite": {
|
||||
"name": "favorite",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"version": "7",
|
||||
"dialect": "sqlite",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "6",
|
||||
"when": 1754676538678,
|
||||
"tag": "0000_breezy_lester",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "6",
|
||||
"when": 1754948246595,
|
||||
"tag": "0001_elite_odin",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -11,10 +11,10 @@
|
|||
"@formkit/auto-animate": "^0.8.2",
|
||||
"@libsql/client": "^0.15.10",
|
||||
"dotenv": "^17.2.1",
|
||||
"drizzle-orm": "^0.44.4",
|
||||
"lightgallery": "^2.9.0-beta.1",
|
||||
"motion": "^12.23.12",
|
||||
"next": "15.4.5",
|
||||
"pocketbase": "^0.26.3",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-icons": "^5.5.0",
|
||||
|
|
@ -25,7 +25,6 @@
|
|||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"drizzle-kit": "^0.31.4",
|
||||
"tailwindcss": "^4",
|
||||
"tsx": "^4.20.3",
|
||||
"typescript": "^5"
|
||||
|
|
@ -58,13 +57,6 @@
|
|||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@drizzle-team/brocli": {
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz",
|
||||
"integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz",
|
||||
|
|
@ -75,442 +67,6 @@
|
|||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz",
|
||||
"integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==",
|
||||
"deprecated": "Merged into tsx: https://tsx.is",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "~0.18.20",
|
||||
"source-map-support": "^0.5.21"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
|
||||
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
|
||||
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
|
||||
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
|
||||
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
|
||||
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
|
||||
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
|
||||
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
|
||||
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
|
||||
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
|
||||
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
|
||||
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
|
||||
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
|
||||
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
|
||||
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
|
||||
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
|
||||
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
|
||||
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
|
||||
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
|
||||
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
|
||||
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
|
||||
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
|
||||
"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils/node_modules/esbuild": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
|
||||
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/android-arm": "0.18.20",
|
||||
"@esbuild/android-arm64": "0.18.20",
|
||||
"@esbuild/android-x64": "0.18.20",
|
||||
"@esbuild/darwin-arm64": "0.18.20",
|
||||
"@esbuild/darwin-x64": "0.18.20",
|
||||
"@esbuild/freebsd-arm64": "0.18.20",
|
||||
"@esbuild/freebsd-x64": "0.18.20",
|
||||
"@esbuild/linux-arm": "0.18.20",
|
||||
"@esbuild/linux-arm64": "0.18.20",
|
||||
"@esbuild/linux-ia32": "0.18.20",
|
||||
"@esbuild/linux-loong64": "0.18.20",
|
||||
"@esbuild/linux-mips64el": "0.18.20",
|
||||
"@esbuild/linux-ppc64": "0.18.20",
|
||||
"@esbuild/linux-riscv64": "0.18.20",
|
||||
"@esbuild/linux-s390x": "0.18.20",
|
||||
"@esbuild/linux-x64": "0.18.20",
|
||||
"@esbuild/netbsd-x64": "0.18.20",
|
||||
"@esbuild/openbsd-x64": "0.18.20",
|
||||
"@esbuild/sunos-x64": "0.18.20",
|
||||
"@esbuild/win32-arm64": "0.18.20",
|
||||
"@esbuild/win32-ia32": "0.18.20",
|
||||
"@esbuild/win32-x64": "0.18.20"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/esm-loader": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz",
|
||||
"integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==",
|
||||
"deprecated": "Merged into tsx: https://tsx.is",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@esbuild-kit/core-utils": "^3.3.2",
|
||||
"get-tsconfig": "^4.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.25.8",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz",
|
||||
|
|
@ -2062,13 +1618,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001731",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz",
|
||||
|
|
@ -2166,24 +1715,6 @@
|
|||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
||||
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/dequal": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||
|
|
@ -2215,147 +1746,6 @@
|
|||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/drizzle-kit": {
|
||||
"version": "0.31.4",
|
||||
"resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.4.tgz",
|
||||
"integrity": "sha512-tCPWVZWZqWVx2XUsVpJRnH9Mx0ClVOf5YUHerZ5so1OKSlqww4zy1R5ksEdGRcO3tM3zj0PYN6V48TbQCL1RfA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@drizzle-team/brocli": "^0.10.2",
|
||||
"@esbuild-kit/esm-loader": "^2.5.5",
|
||||
"esbuild": "^0.25.4",
|
||||
"esbuild-register": "^3.5.0"
|
||||
},
|
||||
"bin": {
|
||||
"drizzle-kit": "bin.cjs"
|
||||
}
|
||||
},
|
||||
"node_modules/drizzle-orm": {
|
||||
"version": "0.44.4",
|
||||
"resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.44.4.tgz",
|
||||
"integrity": "sha512-ZyzKFpTC/Ut3fIqc2c0dPZ6nhchQXriTsqTNs4ayRgl6sZcFlMs9QZKPSHXK4bdOf41GHGWf+FrpcDDYwW+W6Q==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"@aws-sdk/client-rds-data": ">=3",
|
||||
"@cloudflare/workers-types": ">=4",
|
||||
"@electric-sql/pglite": ">=0.2.0",
|
||||
"@libsql/client": ">=0.10.0",
|
||||
"@libsql/client-wasm": ">=0.10.0",
|
||||
"@neondatabase/serverless": ">=0.10.0",
|
||||
"@op-engineering/op-sqlite": ">=2",
|
||||
"@opentelemetry/api": "^1.4.1",
|
||||
"@planetscale/database": ">=1.13",
|
||||
"@prisma/client": "*",
|
||||
"@tidbcloud/serverless": "*",
|
||||
"@types/better-sqlite3": "*",
|
||||
"@types/pg": "*",
|
||||
"@types/sql.js": "*",
|
||||
"@upstash/redis": ">=1.34.7",
|
||||
"@vercel/postgres": ">=0.8.0",
|
||||
"@xata.io/client": "*",
|
||||
"better-sqlite3": ">=7",
|
||||
"bun-types": "*",
|
||||
"expo-sqlite": ">=14.0.0",
|
||||
"gel": ">=2",
|
||||
"knex": "*",
|
||||
"kysely": "*",
|
||||
"mysql2": ">=2",
|
||||
"pg": ">=8",
|
||||
"postgres": ">=3",
|
||||
"sql.js": ">=1",
|
||||
"sqlite3": ">=5"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@aws-sdk/client-rds-data": {
|
||||
"optional": true
|
||||
},
|
||||
"@cloudflare/workers-types": {
|
||||
"optional": true
|
||||
},
|
||||
"@electric-sql/pglite": {
|
||||
"optional": true
|
||||
},
|
||||
"@libsql/client": {
|
||||
"optional": true
|
||||
},
|
||||
"@libsql/client-wasm": {
|
||||
"optional": true
|
||||
},
|
||||
"@neondatabase/serverless": {
|
||||
"optional": true
|
||||
},
|
||||
"@op-engineering/op-sqlite": {
|
||||
"optional": true
|
||||
},
|
||||
"@opentelemetry/api": {
|
||||
"optional": true
|
||||
},
|
||||
"@planetscale/database": {
|
||||
"optional": true
|
||||
},
|
||||
"@prisma/client": {
|
||||
"optional": true
|
||||
},
|
||||
"@tidbcloud/serverless": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/better-sqlite3": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/pg": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/sql.js": {
|
||||
"optional": true
|
||||
},
|
||||
"@upstash/redis": {
|
||||
"optional": true
|
||||
},
|
||||
"@vercel/postgres": {
|
||||
"optional": true
|
||||
},
|
||||
"@xata.io/client": {
|
||||
"optional": true
|
||||
},
|
||||
"better-sqlite3": {
|
||||
"optional": true
|
||||
},
|
||||
"bun-types": {
|
||||
"optional": true
|
||||
},
|
||||
"expo-sqlite": {
|
||||
"optional": true
|
||||
},
|
||||
"gel": {
|
||||
"optional": true
|
||||
},
|
||||
"knex": {
|
||||
"optional": true
|
||||
},
|
||||
"kysely": {
|
||||
"optional": true
|
||||
},
|
||||
"mysql2": {
|
||||
"optional": true
|
||||
},
|
||||
"pg": {
|
||||
"optional": true
|
||||
},
|
||||
"postgres": {
|
||||
"optional": true
|
||||
},
|
||||
"prisma": {
|
||||
"optional": true
|
||||
},
|
||||
"sql.js": {
|
||||
"optional": true
|
||||
},
|
||||
"sqlite3": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.18.2",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
|
||||
|
|
@ -2412,19 +1802,6 @@
|
|||
"@esbuild/win32-x64": "0.25.8"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-register": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz",
|
||||
"integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"esbuild": ">=0.12 <1"
|
||||
}
|
||||
},
|
||||
"node_modules/fetch-blob": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||
|
|
@ -2924,13 +2301,6 @@
|
|||
"integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
|
|
@ -3073,6 +2443,12 @@
|
|||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/pocketbase": {
|
||||
"version": "0.26.3",
|
||||
"resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.26.3.tgz",
|
||||
"integrity": "sha512-5deUKRoEczpxxuHzwr6/DHVmgbggxylEVig8CKN+MjvtYxPUqX/C6puU0yaR2yhTi8zrh7J9s7Ty+qBGwVzWOQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
||||
|
|
@ -3220,16 +2596,6 @@
|
|||
"is-arrayish": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
|
|
@ -3239,17 +2605,6 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-support": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/styled-jsx": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@
|
|||
"@formkit/auto-animate": "^0.8.2",
|
||||
"@libsql/client": "^0.15.10",
|
||||
"dotenv": "^17.2.1",
|
||||
"drizzle-orm": "^0.44.4",
|
||||
"lightgallery": "^2.9.0-beta.1",
|
||||
"motion": "^12.23.12",
|
||||
"next": "15.4.5",
|
||||
"pocketbase": "^0.26.3",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-icons": "^5.5.0",
|
||||
|
|
@ -26,7 +26,6 @@
|
|||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"drizzle-kit": "^0.31.4",
|
||||
"tailwindcss": "^4",
|
||||
"tsx": "^4.20.3",
|
||||
"typescript": "^5"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { getMovies } from "@/lib/db";
|
||||
import { NextResponse } from "next/server";
|
||||
import { DB_getMovies } from '@/lib/db/pb';
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
export const GET = async () => {
|
||||
const movies = await getMovies();
|
||||
const movies = await DB_getMovies();
|
||||
const res = NextResponse.json(movies);
|
||||
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
import "./globals.css";
|
||||
import './globals.css';
|
||||
|
||||
import { Navbar } from "@/components/organisms/Navbar";
|
||||
import { AuroraBackground } from "@/components/effects";
|
||||
import { GlobalStoreProvider } from "./store/globalStore";
|
||||
import { getMovies } from "@/lib/db";
|
||||
import { Navbar } from '@/components/organisms/Navbar';
|
||||
import { AuroraBackground } from '@/components/effects';
|
||||
import { GlobalStoreProvider } from './store/globalStore';
|
||||
import { DB_getMovies } from '@/lib/db/pb';
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
const movies = await getMovies();
|
||||
const movies = await DB_getMovies();
|
||||
|
||||
return (
|
||||
<html lang="pl">
|
||||
|
|
|
|||
|
|
@ -1,19 +1,16 @@
|
|||
"use client";
|
||||
import { Spinner } from "@/components/atoms/Spinner";
|
||||
import { useLocalStorage } from "@/hooks/useLocalStorage";
|
||||
import { addMovieToDB, deleteMovieFromDB, updateMovieInDB } from "@/lib/db";
|
||||
import { movies } from "@/lib/db/schema";
|
||||
import { createContext, FC, use, useEffect, useState } from "react";
|
||||
|
||||
type Movie = typeof movies.$inferSelect;
|
||||
'use client';
|
||||
import { Spinner } from '@/components/atoms/Spinner';
|
||||
import { useLocalStorage } from '@/hooks/useLocalStorage';
|
||||
import { DB_addMovie, DB_deleteMovie, DB_updateMovie } from '@/lib/db/pb';
|
||||
import { createContext, FC, use, useEffect, useState } from 'react';
|
||||
|
||||
type GlobalStore = {
|
||||
movies: Movie[];
|
||||
addMovie: (movie: Movie) => void;
|
||||
deleteMovie: (id: number) => void;
|
||||
updateMovie: (id: number, movie: Partial<Movie>) => void;
|
||||
displayType: "grid" | "list";
|
||||
setDisplayType: (type: "grid" | "list") => void;
|
||||
displayType: 'grid' | 'list';
|
||||
setDisplayType: (type: 'grid' | 'list') => void;
|
||||
};
|
||||
|
||||
const globalStore = createContext<GlobalStore>({
|
||||
|
|
@ -21,7 +18,7 @@ const globalStore = createContext<GlobalStore>({
|
|||
addMovie: () => {},
|
||||
deleteMovie: () => {},
|
||||
updateMovie: () => {},
|
||||
displayType: "grid",
|
||||
displayType: 'grid',
|
||||
setDisplayType: () => {},
|
||||
});
|
||||
|
||||
|
|
@ -36,10 +33,10 @@ export const GlobalStoreProvider: FC<Props> = ({
|
|||
}) => {
|
||||
// Optimistic update
|
||||
const [firstRender, setFirstRender] = useState(true);
|
||||
const [movies, setMovies] = useState<GlobalStore["movies"]>(initialMovies);
|
||||
const [movies, setMovies] = useState<GlobalStore['movies']>(initialMovies);
|
||||
const [displayType, setDisplayType] = useLocalStorage<
|
||||
GlobalStore["displayType"]
|
||||
>("displayType", "grid");
|
||||
GlobalStore['displayType']
|
||||
>('displayType', 'grid');
|
||||
|
||||
useEffect(() => {
|
||||
if (firstRender) {
|
||||
|
|
@ -48,22 +45,20 @@ export const GlobalStoreProvider: FC<Props> = ({
|
|||
}, [firstRender]);
|
||||
|
||||
const addMovie = async (movie: Movie) => {
|
||||
if (movies.find((m) => m.id === movie.id)) return;
|
||||
if (movies.find(m => m.id === movie.id)) return;
|
||||
|
||||
addMovieToDB(movie);
|
||||
setMovies((prev) => [...prev, movie]);
|
||||
DB_addMovie(movie);
|
||||
setMovies(prev => [...prev, movie]);
|
||||
};
|
||||
|
||||
const deleteMovie = async (id: number) => {
|
||||
deleteMovieFromDB(id);
|
||||
setMovies((prev) => prev.filter((m) => m.id !== id));
|
||||
DB_deleteMovie(id);
|
||||
setMovies(prev => prev.filter(m => m.id !== id));
|
||||
};
|
||||
|
||||
const updateMovie = async (id: number, movie: Partial<Movie>) => {
|
||||
updateMovieInDB(id, movie);
|
||||
setMovies((prev) =>
|
||||
prev.map((m) => (m.id === id ? { ...m, ...movie } : m))
|
||||
);
|
||||
DB_updateMovie(id, movie);
|
||||
setMovies(prev => prev.map(m => (m.id === id ? { ...m, ...movie } : m)));
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
"use client";
|
||||
import { FC } from "react";
|
||||
import { useGlobalStore } from "@/app/store/globalStore";
|
||||
import { Movie } from "@/types/global";
|
||||
import { FaFire, FaPlusCircle, FaTrash } from "react-icons/fa";
|
||||
import Link from "next/link";
|
||||
import { RxEyeOpen } from "react-icons/rx";
|
||||
import { MdFavorite } from "react-icons/md";
|
||||
import { RiCalendarCheckLine, RiCalendarScheduleLine } from "react-icons/ri";
|
||||
'use client';
|
||||
import { FC } from 'react';
|
||||
import { useGlobalStore } from '@/app/store/globalStore';
|
||||
import { FaFire, FaPlusCircle, FaTrash } from 'react-icons/fa';
|
||||
import Link from 'next/link';
|
||||
import { RxEyeOpen } from 'react-icons/rx';
|
||||
import { MdFavorite } from 'react-icons/md';
|
||||
import { RiCalendarCheckLine, RiCalendarScheduleLine } from 'react-icons/ri';
|
||||
|
||||
type Props = Movie & {
|
||||
showDayCounter?: boolean;
|
||||
|
|
@ -27,7 +26,7 @@ export const MovieCard: FC<Props> = ({
|
|||
const { vote_average, popularity, poster_path, title, overview } = movie;
|
||||
|
||||
const { id } = movie;
|
||||
const alreadyInStore = movies.find((m) => m.id === id);
|
||||
const alreadyInStore = movies.find(m => m.id === id);
|
||||
|
||||
const seen = alreadyInStore?.seen || movie.seen;
|
||||
const favorite = alreadyInStore?.favorite || movie.favorite;
|
||||
|
|
@ -35,10 +34,10 @@ export const MovieCard: FC<Props> = ({
|
|||
const isReleased = new Date(movie.release_date) < new Date();
|
||||
const scoreColor =
|
||||
vote_average >= 8
|
||||
? "from-emerald-400 to-teal-400"
|
||||
? 'from-emerald-400 to-teal-400'
|
||||
: vote_average >= 6
|
||||
? "from-yellow-400 to-orange-400"
|
||||
: "from-red-400 to-pink-400";
|
||||
? 'from-yellow-400 to-orange-400'
|
||||
: 'from-red-400 to-pink-400';
|
||||
|
||||
const handleAdd = () => {
|
||||
addMovieToStore(movie);
|
||||
|
|
@ -129,8 +128,8 @@ export const MovieCard: FC<Props> = ({
|
|||
<div
|
||||
className={`${
|
||||
seen
|
||||
? "bg-gradient-to-r from-emerald-500/95 to-emerald-600/90"
|
||||
: "bg-gradient-to-r from-white/25 to-white/15"
|
||||
? 'bg-gradient-to-r from-emerald-500/95 to-emerald-600/90'
|
||||
: 'bg-gradient-to-r from-white/25 to-white/15'
|
||||
} p-2 rounded-full cursor-pointer hover:bg-emerald-400 transition-colors border border-white/10 shadow-lg`}
|
||||
onClick={handleSeen}
|
||||
>
|
||||
|
|
@ -139,8 +138,8 @@ export const MovieCard: FC<Props> = ({
|
|||
<div
|
||||
className={`${
|
||||
favorite
|
||||
? "bg-gradient-to-r from-rose-500/95 to-rose-600/90"
|
||||
: "bg-gradient-to-r from-white/25 to-white/15"
|
||||
? 'bg-gradient-to-r from-rose-500/95 to-rose-600/90'
|
||||
: 'bg-gradient-to-r from-white/25 to-white/15'
|
||||
} p-2 rounded-full cursor-pointer hover:bg-rose-400 transition-colors border border-white/10 shadow-lg`}
|
||||
onClick={handleFavorite}
|
||||
>
|
||||
|
|
@ -185,7 +184,7 @@ export const MovieCard: FC<Props> = ({
|
|||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className={`flex items-center gap-1 text-sm ${
|
||||
isReleased ? "text-emerald-400" : "text-amber-400"
|
||||
isReleased ? 'text-emerald-400' : 'text-amber-400'
|
||||
}`}
|
||||
>
|
||||
{isReleased ? (
|
||||
|
|
@ -194,10 +193,10 @@ export const MovieCard: FC<Props> = ({
|
|||
<RiCalendarScheduleLine />
|
||||
)}
|
||||
<span className="font-medium">
|
||||
{releaseDate.toLocaleDateString("pl-PL", {
|
||||
day: "numeric",
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
{releaseDate.toLocaleDateString('pl-PL', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
year: 'numeric',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
"use client";
|
||||
import { formatter } from "@/helpers/formater";
|
||||
import { Movie } from "@/types/global";
|
||||
import Link from "next/link";
|
||||
import { FC } from "react";
|
||||
import { FaCalendar, FaClock, FaStar, FaEye, FaHeart } from "react-icons/fa";
|
||||
import { motion, useAnimationControls, useMotionValue } from "framer-motion";
|
||||
import { useGlobalStore } from "@/app/store/globalStore";
|
||||
'use client';
|
||||
import { formatter } from '@/helpers/formater';
|
||||
import Link from 'next/link';
|
||||
import { FC } from 'react';
|
||||
import { FaCalendar, FaClock, FaStar, FaEye, FaHeart } from 'react-icons/fa';
|
||||
import { motion, useAnimationControls, useMotionValue } from 'framer-motion';
|
||||
import { useGlobalStore } from '@/app/store/globalStore';
|
||||
|
||||
type Props = {
|
||||
movie: Movie;
|
||||
|
|
@ -31,7 +30,7 @@ export const MovieRow: FC<Props> = ({
|
|||
);
|
||||
|
||||
// Check if movie is already in store.
|
||||
const movieInStore = movies.find((m) => m.id === movie.id);
|
||||
const movieInStore = movies.find(m => m.id === movie.id);
|
||||
const isWatched = movieInStore?.seen || false;
|
||||
const isFavorite = movieInStore?.favorite || false;
|
||||
|
||||
|
|
@ -83,7 +82,7 @@ export const MovieRow: FC<Props> = ({
|
|||
dragConstraints={{ left: -80, right: 80 }}
|
||||
dragElastic={0.01}
|
||||
dragMomentum={false}
|
||||
whileDrag={{ cursor: "grabbing" }}
|
||||
whileDrag={{ cursor: 'grabbing' }}
|
||||
onDragEnd={handleDragAction}
|
||||
className="relative z-10"
|
||||
>
|
||||
|
|
@ -142,8 +141,8 @@ export const MovieRow: FC<Props> = ({
|
|||
<div
|
||||
className={`text-xs px-2 py-1 rounded-full font-medium ${
|
||||
isUpcoming
|
||||
? "bg-blue-500/20 text-blue-400"
|
||||
: "bg-green-500/20 text-green-400"
|
||||
? 'bg-blue-500/20 text-blue-400'
|
||||
: 'bg-green-500/20 text-green-400'
|
||||
}`}
|
||||
>
|
||||
{isUpcoming
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
"use client";
|
||||
import { FC, ReactNode, useState } from "react";
|
||||
import { MovieCard } from "@/components/atoms/MovieCard";
|
||||
import { Movie } from "@/types/global";
|
||||
import { useGlobalStore } from "@/app/store/globalStore";
|
||||
import { Dropdown } from "@/components/atoms/Dropdown";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { Button } from "@/components/atoms/Button";
|
||||
import { Label } from "@/components/atoms/Label";
|
||||
import { FaList } from "react-icons/fa";
|
||||
import { MovieRow } from "@/components/atoms/MovieRow";
|
||||
'use client';
|
||||
import { FC, ReactNode, useState } from 'react';
|
||||
import { MovieCard } from '@/components/atoms/MovieCard';
|
||||
import { useGlobalStore } from '@/app/store/globalStore';
|
||||
import { Dropdown } from '@/components/atoms/Dropdown';
|
||||
import { useAutoAnimate } from '@formkit/auto-animate/react';
|
||||
import { Button } from '@/components/atoms/Button';
|
||||
import { Label } from '@/components/atoms/Label';
|
||||
import { FaList } from 'react-icons/fa';
|
||||
import { MovieRow } from '@/components/atoms/MovieRow';
|
||||
|
||||
type Props = {
|
||||
heading?: string;
|
||||
|
|
@ -16,7 +15,7 @@ type Props = {
|
|||
colors?: keyof typeof colorsMap;
|
||||
|
||||
overrideMovies?: Movie[];
|
||||
overrideDisplayType?: "grid" | "list";
|
||||
overrideDisplayType?: 'grid' | 'list';
|
||||
|
||||
showFilters?: boolean;
|
||||
filterSeen?: 0 | 1;
|
||||
|
|
@ -26,8 +25,8 @@ type Props = {
|
|||
|
||||
fluid?: boolean;
|
||||
showSorting?: boolean;
|
||||
sort?: "title" | "releaseDate" | "popularity";
|
||||
sortDirection?: "asc" | "desc";
|
||||
sort?: 'title' | 'releaseDate' | 'popularity';
|
||||
sortDirection?: 'asc' | 'desc';
|
||||
|
||||
loadMore?: boolean;
|
||||
};
|
||||
|
|
@ -35,7 +34,7 @@ type Props = {
|
|||
export const MovieList: FC<Props> = ({
|
||||
heading,
|
||||
icon,
|
||||
colors = "white",
|
||||
colors = 'white',
|
||||
overrideMovies,
|
||||
showFilters = true,
|
||||
filterSeen: filterSeenInitial,
|
||||
|
|
@ -44,8 +43,8 @@ export const MovieList: FC<Props> = ({
|
|||
filterReleased: filterReleasedInitial,
|
||||
fluid = false,
|
||||
showSorting = true,
|
||||
sort: sortType = "releaseDate",
|
||||
sortDirection = "asc",
|
||||
sort: sortType = 'releaseDate',
|
||||
sortDirection = 'asc',
|
||||
loadMore = false,
|
||||
overrideDisplayType,
|
||||
}) => {
|
||||
|
|
@ -63,14 +62,14 @@ export const MovieList: FC<Props> = ({
|
|||
upcoming: filterUpcomingInitial,
|
||||
released: filterReleasedInitial,
|
||||
});
|
||||
const [sort, setSort] = useState<"title" | "releaseDate" | "popularity">(
|
||||
const [sort, setSort] = useState<'title' | 'releaseDate' | 'popularity'>(
|
||||
sortType
|
||||
);
|
||||
|
||||
const [loaded, setLoaded] = useState(8);
|
||||
const [parent] = useAutoAnimate();
|
||||
|
||||
const filteredMovies = movies.filter((movie) => {
|
||||
const filteredMovies = movies.filter(movie => {
|
||||
let result = true;
|
||||
const today = new Date();
|
||||
if (filter.seen !== undefined) {
|
||||
|
|
@ -93,16 +92,16 @@ export const MovieList: FC<Props> = ({
|
|||
});
|
||||
|
||||
let sortedMovies = filteredMovies.sort((a, b) => {
|
||||
if (sort === "title") return a.title.localeCompare(b.title);
|
||||
if (sort === "releaseDate")
|
||||
if (sort === 'title') return a.title.localeCompare(b.title);
|
||||
if (sort === 'releaseDate')
|
||||
return (
|
||||
new Date(b.release_date).getTime() - new Date(a.release_date).getTime()
|
||||
);
|
||||
if (sort === "popularity") return b.popularity - a.popularity;
|
||||
if (sort === 'popularity') return b.popularity - a.popularity;
|
||||
return 0;
|
||||
});
|
||||
|
||||
if (sortDirection === "desc") {
|
||||
if (sortDirection === 'desc') {
|
||||
sortedMovies = sortedMovies.reverse();
|
||||
}
|
||||
sortedMovies = sortedMovies.slice(0, loadMore ? loaded : movies.length);
|
||||
|
|
@ -119,7 +118,7 @@ export const MovieList: FC<Props> = ({
|
|||
|
||||
return (
|
||||
<section className="blocks">
|
||||
<div className={`${fluid ? "max-w-full px-4" : "container"}`}>
|
||||
<div className={`${fluid ? 'max-w-full px-4' : 'container'}`}>
|
||||
{heading && (
|
||||
<div className="flex items-center gap-3">
|
||||
{icon && (
|
||||
|
|
@ -151,17 +150,17 @@ export const MovieList: FC<Props> = ({
|
|||
</Label>
|
||||
<Label
|
||||
active={filter.favorites !== undefined}
|
||||
onClick={() => handleFilter("favorites")}
|
||||
onClick={() => handleFilter('favorites')}
|
||||
>
|
||||
Ulubione ({movies.filter((movie) => movie.favorite).length})
|
||||
Ulubione ({movies.filter(movie => movie.favorite).length})
|
||||
</Label>
|
||||
<Label
|
||||
active={
|
||||
filter.seen !== undefined && filter.released === undefined
|
||||
}
|
||||
onClick={() => handleFilter("seen")}
|
||||
onClick={() => handleFilter('seen')}
|
||||
>
|
||||
Obejrzane ({movies.filter((movie) => movie.seen).length})
|
||||
Obejrzane ({movies.filter(movie => movie.seen).length})
|
||||
</Label>
|
||||
<Label
|
||||
active={
|
||||
|
|
@ -179,7 +178,7 @@ export const MovieList: FC<Props> = ({
|
|||
Do obejrzenia (
|
||||
{
|
||||
movies.filter(
|
||||
(movie) =>
|
||||
movie =>
|
||||
new Date(movie.release_date) < new Date() && !movie.seen
|
||||
).length
|
||||
}
|
||||
|
|
@ -187,12 +186,12 @@ export const MovieList: FC<Props> = ({
|
|||
</Label>
|
||||
<Label
|
||||
active={filter.upcoming !== undefined}
|
||||
onClick={() => handleFilter("upcoming")}
|
||||
onClick={() => handleFilter('upcoming')}
|
||||
>
|
||||
Nadchodzące (
|
||||
{
|
||||
movies.filter(
|
||||
(movie) => new Date(movie.release_date) > new Date()
|
||||
movie => new Date(movie.release_date) > new Date()
|
||||
).length
|
||||
}
|
||||
)
|
||||
|
|
@ -205,7 +204,7 @@ export const MovieList: FC<Props> = ({
|
|||
size="icon"
|
||||
theme="slate"
|
||||
onClick={() =>
|
||||
setDisplayType(displayType === "grid" ? "list" : "grid")
|
||||
setDisplayType(displayType === 'grid' ? 'list' : 'grid')
|
||||
}
|
||||
>
|
||||
<FaList />
|
||||
|
|
@ -213,12 +212,12 @@ export const MovieList: FC<Props> = ({
|
|||
)}
|
||||
<Dropdown
|
||||
items={[
|
||||
{ label: "Tytuł", value: "title" },
|
||||
{ label: "Data premiery", value: "releaseDate" },
|
||||
{ label: "Popularność", value: "popularity" },
|
||||
{ label: 'Tytuł', value: 'title' },
|
||||
{ label: 'Data premiery', value: 'releaseDate' },
|
||||
{ label: 'Popularność', value: 'popularity' },
|
||||
]}
|
||||
defaultValue={sort}
|
||||
callback={(value) => setSort(value as "title")}
|
||||
callback={value => setSort(value as 'title')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -232,8 +231,8 @@ export const MovieList: FC<Props> = ({
|
|||
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-y-6 gap-3 sm:gap-6 mt-8 justify-center"
|
||||
ref={parent}
|
||||
>
|
||||
{sortedMovies.map((movie) =>
|
||||
displayType === "grid" ? (
|
||||
{sortedMovies.map(movie =>
|
||||
displayType === 'grid' ? (
|
||||
<MovieCard key={movie.id} {...movie} />
|
||||
) : (
|
||||
<MovieRow key={movie.id} movie={movie} compact />
|
||||
|
|
@ -258,14 +257,14 @@ export const MovieList: FC<Props> = ({
|
|||
};
|
||||
|
||||
const colorsMap = {
|
||||
white: "bg-gradient-to-r from-white to-gray-300",
|
||||
yellow: "bg-gradient-to-r from-yellow-400 to-orange-400",
|
||||
blue: "bg-gradient-to-r from-blue-400 to-purple-400",
|
||||
green: "bg-gradient-to-r from-green-400 to-teal-400",
|
||||
red: "bg-gradient-to-r from-red-400 to-pink-400",
|
||||
purple: "bg-gradient-to-r from-purple-400 to-pink-400",
|
||||
orange: "bg-gradient-to-r from-orange-400 to-yellow-400",
|
||||
pink: "bg-gradient-to-r from-pink-400 to-purple-400",
|
||||
teal: "bg-gradient-to-r from-teal-400 to-green-400",
|
||||
gray: "bg-gradient-to-r from-gray-400 to-gray-400",
|
||||
white: 'bg-gradient-to-r from-white to-gray-300',
|
||||
yellow: 'bg-gradient-to-r from-yellow-400 to-orange-400',
|
||||
blue: 'bg-gradient-to-r from-blue-400 to-purple-400',
|
||||
green: 'bg-gradient-to-r from-green-400 to-teal-400',
|
||||
red: 'bg-gradient-to-r from-red-400 to-pink-400',
|
||||
purple: 'bg-gradient-to-r from-purple-400 to-pink-400',
|
||||
orange: 'bg-gradient-to-r from-orange-400 to-yellow-400',
|
||||
pink: 'bg-gradient-to-r from-pink-400 to-purple-400',
|
||||
teal: 'bg-gradient-to-r from-teal-400 to-green-400',
|
||||
gray: 'bg-gradient-to-r from-gray-400 to-gray-400',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ import { FC, useMemo, useState } from 'react';
|
|||
import { useGlobalStore } from '@/app/store/globalStore';
|
||||
import { Button } from '@/components/atoms/Button';
|
||||
import { FaDice } from 'react-icons/fa';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { Movie } from '@/types/global';
|
||||
|
||||
type StoreFilter = 'all' | 'not_seen' | 'released' | 'favorites' | 'to_watch';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
"use client";
|
||||
import { SearchResult } from "@/lib/tmdb/types";
|
||||
import { MovieCard } from "@/components/atoms/MovieCard";
|
||||
import { FC } from "react";
|
||||
import { FaStar } from "react-icons/fa";
|
||||
import { Carousel } from "../Carousel";
|
||||
'use client';
|
||||
import { SearchResult } from '@/lib/tmdb/types';
|
||||
import { MovieCard } from '@/components/atoms/MovieCard';
|
||||
import { FC } from 'react';
|
||||
import { FaStar } from 'react-icons/fa';
|
||||
import { Carousel } from '../Carousel';
|
||||
|
||||
type Props = {
|
||||
movies: SearchResult;
|
||||
|
|
@ -26,7 +26,7 @@ export const RecommendedMovies: FC<Props> = ({ movies }) => {
|
|||
new Date(b.release_date).getTime() -
|
||||
new Date(a.release_date).getTime()
|
||||
)
|
||||
.map((movie) => (
|
||||
.map(movie => (
|
||||
<MovieCard
|
||||
key={movie.id}
|
||||
id={movie.id}
|
||||
|
|
@ -38,7 +38,7 @@ export const RecommendedMovies: FC<Props> = ({ movies }) => {
|
|||
popularity={movie.popularity}
|
||||
adult={movie.adult}
|
||||
backdrop_path={movie.backdrop_path}
|
||||
genre_ids={movie.genre_ids.join(",")}
|
||||
genre_ids={movie.genre_ids.join(',')}
|
||||
original_language={movie.original_language}
|
||||
original_title={movie.original_title}
|
||||
video={movie.video}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
"use client";
|
||||
import { FC } from "react";
|
||||
import { useGlobalStore } from "@/app/store/globalStore";
|
||||
import { FaCalendar, FaClock } from "react-icons/fa";
|
||||
import { MovieRow } from "@/components/atoms/MovieRow";
|
||||
import { Movie } from "@/types/global";
|
||||
'use client';
|
||||
import { FC } from 'react';
|
||||
import { useGlobalStore } from '@/app/store/globalStore';
|
||||
import { FaCalendar, FaClock } from 'react-icons/fa';
|
||||
import { MovieRow } from '@/components/atoms/MovieRow';
|
||||
|
||||
type Props = {
|
||||
overrideMovies?: Movie[];
|
||||
|
|
@ -15,8 +14,8 @@ type Props = {
|
|||
export const TrackedMovies: FC<Props> = ({
|
||||
overrideMovies,
|
||||
daysLimit = 30,
|
||||
labelCurrent = "Aktualnie w kinach",
|
||||
labelUpcoming = "Nadchodzące premiery",
|
||||
labelCurrent = 'Aktualnie w kinach',
|
||||
labelUpcoming = 'Nadchodzące premiery',
|
||||
}) => {
|
||||
const { movies: storeMovies } = useGlobalStore();
|
||||
|
||||
|
|
@ -27,7 +26,7 @@ export const TrackedMovies: FC<Props> = ({
|
|||
}
|
||||
|
||||
const today = new Date();
|
||||
const upcoming = movies.filter((movie) => {
|
||||
const upcoming = movies.filter(movie => {
|
||||
const daysSinceRelease = Math.abs(
|
||||
Math.floor(
|
||||
(new Date().getTime() - new Date(movie.release_date).getTime()) /
|
||||
|
|
@ -38,7 +37,7 @@ export const TrackedMovies: FC<Props> = ({
|
|||
new Date(movie.release_date) > today && daysSinceRelease <= daysLimit
|
||||
);
|
||||
});
|
||||
const inCinema = movies.filter((movie) => {
|
||||
const inCinema = movies.filter(movie => {
|
||||
const daysSinceRelease = Math.floor(
|
||||
(new Date().getTime() - new Date(movie.release_date).getTime()) /
|
||||
(1000 * 60 * 60 * 24)
|
||||
|
|
@ -73,7 +72,7 @@ export const TrackedMovies: FC<Props> = ({
|
|||
{labelCurrent} ({sortedInCinema.length})
|
||||
</h3>
|
||||
<div className="space-y-2">
|
||||
{sortedInCinema.map((movie) => (
|
||||
{sortedInCinema.map(movie => (
|
||||
<MovieRow key={movie.id} movie={movie} isUpcoming={false} />
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -87,7 +86,7 @@ export const TrackedMovies: FC<Props> = ({
|
|||
{labelUpcoming} ({sortedUpcoming.length})
|
||||
</h3>
|
||||
<div className="space-y-2">
|
||||
{sortedUpcoming.map((movie) => (
|
||||
{sortedUpcoming.map(movie => (
|
||||
<MovieRow key={movie.id} movie={movie} isUpcoming />
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
"use client";
|
||||
import { FC, useState, useEffect, useCallback } from "react";
|
||||
import { Movie } from "@/types/global";
|
||||
'use client';
|
||||
import { FC, useState, useEffect, useCallback } from 'react';
|
||||
import {
|
||||
FaPlus,
|
||||
FaFire,
|
||||
FaChevronLeft,
|
||||
FaChevronRight,
|
||||
FaMinus,
|
||||
} from "react-icons/fa";
|
||||
import { RiCalendarCheckLine, RiCalendarScheduleLine } from "react-icons/ri";
|
||||
import { useGlobalStore } from "@/app/store/globalStore";
|
||||
import Link from "next/link";
|
||||
import { Button } from "@/components/atoms/Button";
|
||||
} from 'react-icons/fa';
|
||||
import { RiCalendarCheckLine, RiCalendarScheduleLine } from 'react-icons/ri';
|
||||
import { useGlobalStore } from '@/app/store/globalStore';
|
||||
import Link from 'next/link';
|
||||
import { Button } from '@/components/atoms/Button';
|
||||
|
||||
type Props = {
|
||||
movies: Movie[];
|
||||
|
|
@ -50,7 +49,7 @@ export const Hero: FC<Props> = ({
|
|||
vote_average,
|
||||
} = currentMovie;
|
||||
|
||||
const alreadyInStore = storedMovies.find((m) => m.id === id);
|
||||
const alreadyInStore = storedMovies.find(m => m.id === id);
|
||||
const isReleased = new Date(release_date) < new Date();
|
||||
const releaseDate = new Date(release_date);
|
||||
|
||||
|
|
@ -58,7 +57,7 @@ export const Hero: FC<Props> = ({
|
|||
if (isTransitioning) return;
|
||||
setIsTransitioning(true);
|
||||
setTimeout(() => {
|
||||
setCurrentIndex((prev) => (prev + 1) % movies.length);
|
||||
setCurrentIndex(prev => (prev + 1) % movies.length);
|
||||
setIsTransitioning(false);
|
||||
}, 500);
|
||||
}, [movies.length, isTransitioning]);
|
||||
|
|
@ -67,7 +66,7 @@ export const Hero: FC<Props> = ({
|
|||
if (isTransitioning) return;
|
||||
setIsTransitioning(true);
|
||||
setTimeout(() => {
|
||||
setCurrentIndex((prev) => (prev - 1 + movies.length) % movies.length);
|
||||
setCurrentIndex(prev => (prev - 1 + movies.length) % movies.length);
|
||||
setIsTransitioning(false);
|
||||
}, 500);
|
||||
}, [movies.length, isTransitioning]);
|
||||
|
|
@ -108,7 +107,7 @@ export const Hero: FC<Props> = ({
|
|||
<div
|
||||
key={movie.id}
|
||||
className={`absolute inset-0 transition-opacity duration-500 ${
|
||||
index === currentIndex ? "opacity-100" : "opacity-0"
|
||||
index === currentIndex ? 'opacity-100' : 'opacity-0'
|
||||
}`}
|
||||
>
|
||||
<img
|
||||
|
|
@ -146,7 +145,7 @@ export const Hero: FC<Props> = ({
|
|||
<div className="container relative z-10">
|
||||
<div
|
||||
className={`flex flex-col lg:flex-row items-center gap-8 lg:gap-12 transition-opacity duration-500 ${
|
||||
isTransitioning ? "opacity-0" : "opacity-100"
|
||||
isTransitioning ? 'opacity-0' : 'opacity-100'
|
||||
}`}
|
||||
>
|
||||
{/* Poster */}
|
||||
|
|
@ -176,7 +175,7 @@ export const Hero: FC<Props> = ({
|
|||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
className={`flex items-center gap-1 text-sm ${
|
||||
isReleased ? "text-green-400" : "text-yellow-400"
|
||||
isReleased ? 'text-green-400' : 'text-yellow-400'
|
||||
}`}
|
||||
>
|
||||
{isReleased ? (
|
||||
|
|
@ -184,10 +183,10 @@ export const Hero: FC<Props> = ({
|
|||
) : (
|
||||
<RiCalendarScheduleLine />
|
||||
)}
|
||||
{releaseDate.toLocaleDateString("pl-PL", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
{releaseDate.toLocaleDateString('pl-PL', {
|
||||
day: 'numeric',
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -211,12 +210,12 @@ export const Hero: FC<Props> = ({
|
|||
{/* Action buttons */}
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center lg:justify-start">
|
||||
<Button
|
||||
theme={alreadyInStore ? "primary" : "secondary"}
|
||||
theme={alreadyInStore ? 'primary' : 'secondary'}
|
||||
onClick={alreadyInStore ? handleRemove : handleAdd}
|
||||
>
|
||||
{alreadyInStore ? <FaMinus /> : <FaPlus />}
|
||||
<span>
|
||||
{alreadyInStore ? "Usuń z listy" : "Dodaj do listy"}
|
||||
{alreadyInStore ? 'Usuń z listy' : 'Dodaj do listy'}
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -234,8 +233,8 @@ export const Hero: FC<Props> = ({
|
|||
disabled={isTransitioning}
|
||||
className={`w-3 h-3 rounded-full transition-all duration-300 disabled:cursor-not-allowed cursor-pointer ${
|
||||
index === currentIndex
|
||||
? "bg-secondary scale-125"
|
||||
: "bg-white/50 hover:bg-secondary/70"
|
||||
? 'bg-secondary scale-125'
|
||||
: 'bg-white/50 hover:bg-secondary/70'
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import { Movie } from "@/types/global";
|
||||
|
||||
export const convertToMovie = (
|
||||
movie: any,
|
||||
override?: Partial<Movie>
|
||||
|
|
@ -12,13 +10,13 @@ export const convertToMovie = (
|
|||
id: movie.id,
|
||||
title: movie.title,
|
||||
adult: movie.adult,
|
||||
backdrop_path: movie.backdrop_path || "",
|
||||
genre_ids: movie.genres?.join(",") || "",
|
||||
backdrop_path: movie.backdrop_path || '',
|
||||
genre_ids: movie.genres?.join(',') || '',
|
||||
original_language: movie.original_language,
|
||||
original_title: movie.original_title,
|
||||
overview: movie.overview || "",
|
||||
overview: movie.overview || '',
|
||||
popularity: movie.popularity,
|
||||
poster_path: movie.poster_path || "",
|
||||
poster_path: movie.poster_path || '',
|
||||
release_date: movie.release_date,
|
||||
video: movie.video,
|
||||
vote_average: movie.vote_average,
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
"use server";
|
||||
import { drizzle } from "drizzle-orm/libsql";
|
||||
import { movies } from "./schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { Movie } from "@/types/global";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
const db = drizzle(process.env.DB_FILE_NAME!);
|
||||
|
||||
export const getMovies = async () => {
|
||||
return await db.select().from(movies).$withCache();
|
||||
};
|
||||
|
||||
export const addMovieToDB = async (movie: Movie) => {
|
||||
await db
|
||||
.insert(movies)
|
||||
.values({
|
||||
...movie,
|
||||
genre_ids: JSON.stringify(movie.genre_ids),
|
||||
})
|
||||
.onConflictDoNothing();
|
||||
|
||||
revalidatePath("/", "layout");
|
||||
};
|
||||
|
||||
export const deleteMovieFromDB = async (id: number) => {
|
||||
await db.delete(movies).where(eq(movies.id, id));
|
||||
revalidatePath("/", "layout");
|
||||
};
|
||||
|
||||
export const updateMovieInDB = async (
|
||||
movieId: number,
|
||||
movie: Partial<Movie>
|
||||
) => {
|
||||
await db.update(movies).set(movie).where(eq(movies.id, movieId));
|
||||
revalidatePath("/", "layout");
|
||||
};
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
'use server';
|
||||
import { revalidatePath } from 'next/cache';
|
||||
import PocketBase from 'pocketbase';
|
||||
|
||||
const pb = new PocketBase(process.env.POCKET_URL!);
|
||||
|
||||
const collection = 'movies_prod';
|
||||
|
||||
type CollectionMovie = Movie & {
|
||||
id_imdb: number;
|
||||
};
|
||||
|
||||
export const DB_getMovies = async () => {
|
||||
const records = await pb.collection<CollectionMovie>(collection).getFullList({
|
||||
sort: '-created',
|
||||
});
|
||||
|
||||
return records.map(record => ({
|
||||
...record,
|
||||
id: record.id_imdb,
|
||||
})) as Movie[];
|
||||
};
|
||||
|
||||
export const DB_addMovie = async (movie: Movie) => {
|
||||
try {
|
||||
await pb.collection<CollectionMovie>(collection).create({
|
||||
...movie,
|
||||
id: undefined,
|
||||
id_imdb: movie.id,
|
||||
genre_ids: JSON.stringify(movie.genre_ids),
|
||||
});
|
||||
revalidatePath('/', 'layout');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
export const DB_deleteMovie = async (id: number) => {
|
||||
try {
|
||||
const record = await pb
|
||||
.collection<CollectionMovie>(collection)
|
||||
.getFirstListItem(`id_imdb = "${id}"`);
|
||||
await pb.collection(collection).delete(record.id.toString());
|
||||
revalidatePath('/', 'layout');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
export const DB_updateMovie = async (id: number, movie: Partial<Movie>) => {
|
||||
try {
|
||||
const record = await pb
|
||||
.collection<CollectionMovie>(collection)
|
||||
.getFirstListItem(`id_imdb = "${id}"`);
|
||||
await pb
|
||||
.collection<CollectionMovie>(collection)
|
||||
.update(record.id.toString(), {
|
||||
...movie,
|
||||
});
|
||||
revalidatePath('/', 'layout');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
import { integer, real, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
||||
|
||||
export const movies = sqliteTable("movies", {
|
||||
id: integer("id").primaryKey(),
|
||||
title: text("title").notNull(),
|
||||
adult: integer("adult", { mode: "boolean" }).notNull(),
|
||||
backdrop_path: text("backdrop_path").notNull(),
|
||||
genre_ids: text("genre_ids").notNull(),
|
||||
original_language: text("original_language").notNull(),
|
||||
original_title: text("original_title").notNull(),
|
||||
overview: text("overview").notNull(),
|
||||
popularity: real("popularity").notNull(),
|
||||
poster_path: text("poster_path").notNull(),
|
||||
release_date: text("release_date").notNull(),
|
||||
video: integer("video", { mode: "boolean" }).notNull(),
|
||||
vote_average: real("vote_average").notNull(),
|
||||
vote_count: integer("vote_count").notNull(),
|
||||
seen: integer("seen", { mode: "boolean" }).default(false),
|
||||
favorite: integer("favorite", { mode: "boolean" }).default(false),
|
||||
});
|
||||
|
|
@ -1,4 +1,18 @@
|
|||
import { movies } from "@/lib/db/schema";
|
||||
import { SearchResult } from "@/lib/tmdb/types";
|
||||
|
||||
type Movie = typeof movies.$inferSelect;
|
||||
type Movie = {
|
||||
id: number;
|
||||
title: string;
|
||||
adult: boolean;
|
||||
backdrop_path: string;
|
||||
genre_ids: string;
|
||||
original_language: string;
|
||||
original_title: string;
|
||||
overview: string;
|
||||
popularity: number;
|
||||
poster_path: string;
|
||||
release_date: string;
|
||||
video: boolean;
|
||||
vote_average: number;
|
||||
vote_count: number;
|
||||
seen: boolean;
|
||||
favorite: boolean;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue