diff --git a/.env.tmp b/.env.tmp index 4efb5b3..ff89743 100644 --- a/.env.tmp +++ b/.env.tmp @@ -5,7 +5,7 @@ PORT="3000" DATABASE_URL="file:./dev.db" JWT_SECRET="secret" JWT_EXPIRATION="2h" -OMDB_API_KEY="XXXXXXXX" +IMDB_API_KEY="k_XXXXXXXX" MAX_VOTES="20" MAX_PROPOSEABLE_MOVIES="5" diff --git a/client/package-lock.json b/client/package-lock.json index 7ccc3d9..661219c 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,11 +1,11 @@ { - "name": "movie-monday-client", + "name": "watch-vote-client", "version": "1.0.0-alpha.8", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "movie-monday-client", + "name": "watch-vote-client", "version": "1.0.0-alpha.8", "dependencies": { "bootstrap": "^5.3.0-alpha1", @@ -13,7 +13,8 @@ "js-cookie": "^3.0.1", "movie-monday-manager": "file:..", "vue": "^3.2.37", - "vue-router": "^4.1.6" + "vue-router": "^4.1.6", + "watchvote": "file:.." }, "devDependencies": { "@types/bootstrap": "^5.2.6", @@ -28,20 +29,20 @@ } }, "..": { - "name": "movie-monday-manager", + "name": "watchvote", "version": "1.0.0-alpha.8", "license": "MIT", "dependencies": { - "@nestjs/common": "^9.3.2", - "@nestjs/config": "^2.3.0", - "@nestjs/core": "^9.3.2", - "@nestjs/jwt": "^10.0.1", - "@nestjs/passport": "^9.0.1", - "@nestjs/platform-express": "^9.3.2", + "@nestjs/common": "^9.3.9", + "@nestjs/config": "^2.3.1", + "@nestjs/core": "^9.3.9", + "@nestjs/jwt": "^10.0.2", + "@nestjs/passport": "^9.0.3", + "@nestjs/platform-express": "^9.3.9", "@nestjs/schedule": "^2.2.0", - "@nestjs/serve-static": "^3.0.0", + "@nestjs/serve-static": "^3.0.1", "@nestjs/swagger": "^6.2.1", - "@prisma/client": "^4.9.0", + "@prisma/client": "^4.10.1", "bcrypt": "^5.1.0", "cron-parser": "^4.7.1", "crypto-js": "^4.1.1", @@ -49,13 +50,12 @@ "discord.js": "^14.7.1", "helmet": "^5.1.1", "imdb-api": "^4.4.1", - "joi": "^17.7.0", + "joi": "^17.7.1", "nestjs-i18n": "^10.2.6", "nodemailer": "^6.9.1", "passport": "^0.6.0", "passport-jwt": "^4.0.1", "passport-local": "^1.0.0", - "prisma": "^4.9.0", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.8.0" @@ -64,24 +64,25 @@ "@compodoc/compodoc": "^1.1.19", "@nestjs/cli": "^9.2.0", "@nestjs/schematics": "^9.0.4", - "@nestjs/testing": "^9.3.2", + "@nestjs/testing": "^9.3.9", "@types/bcrypt": "^5.0.0", "@types/cron": "^2.0.0", "@types/crypto-js": "^4.1.1", - "@types/express": "^4.17.16", + "@types/express": "^4.17.17", "@types/jest": "28.1.4", - "@types/node": "^16.18.11", + "@types/node": "^16.18.12", "@types/nodemailer": "^6.4.7", "@types/passport-jwt": "^3.0.8", "@types/passport-local": "^1.0.35", "@types/supertest": "^2.0.12", - "@typescript-eslint/eslint-plugin": "^5.50.0", - "@typescript-eslint/parser": "^5.50.0", - "eslint": "^8.33.0", + "@typescript-eslint/eslint-plugin": "^5.52.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", "eslint-config-prettier": "^8.6.0", "eslint-plugin-prettier": "^4.2.1", "jest": "28.1.2", - "prettier": "^2.8.3", + "prettier": "^2.8.4", + "prisma": "^4.10.1", "source-map-support": "^0.5.20", "supertest": "^6.3.3", "ts-jest": "28.0.5", @@ -2112,6 +2113,10 @@ "typescript": "*" } }, + "node_modules/watchvote": { + "resolved": "..", + "link": true + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -3140,49 +3145,49 @@ "requires": { "@compodoc/compodoc": "^1.1.19", "@nestjs/cli": "^9.2.0", - "@nestjs/common": "^9.3.2", - "@nestjs/config": "^2.3.0", - "@nestjs/core": "^9.3.2", - "@nestjs/jwt": "^10.0.1", - "@nestjs/passport": "^9.0.1", - "@nestjs/platform-express": "^9.3.2", + "@nestjs/common": "^9.3.9", + "@nestjs/config": "^2.3.1", + "@nestjs/core": "^9.3.9", + "@nestjs/jwt": "^10.0.2", + "@nestjs/passport": "^9.0.3", + "@nestjs/platform-express": "^9.3.9", "@nestjs/schedule": "^2.2.0", "@nestjs/schematics": "^9.0.4", - "@nestjs/serve-static": "^3.0.0", + "@nestjs/serve-static": "^3.0.1", "@nestjs/swagger": "^6.2.1", - "@nestjs/testing": "^9.3.2", - "@prisma/client": "^4.9.0", + "@nestjs/testing": "^9.3.9", + "@prisma/client": "^4.10.1", "@types/bcrypt": "^5.0.0", "@types/cron": "^2.0.0", "@types/crypto-js": "^4.1.1", - "@types/express": "^4.17.16", + "@types/express": "^4.17.17", "@types/jest": "28.1.4", - "@types/node": "^16.18.11", + "@types/node": "^16.18.12", "@types/nodemailer": "^6.4.7", "@types/passport-jwt": "^3.0.8", "@types/passport-local": "^1.0.35", "@types/supertest": "^2.0.12", - "@typescript-eslint/eslint-plugin": "^5.50.0", - "@typescript-eslint/parser": "^5.50.0", + "@typescript-eslint/eslint-plugin": "^5.52.0", + "@typescript-eslint/parser": "^5.52.0", "bcrypt": "^5.1.0", "cron-parser": "^4.7.1", "crypto-js": "^4.1.1", "cuid": "^2.1.8", "discord.js": "^14.7.1", - "eslint": "^8.33.0", + "eslint": "^8.34.0", "eslint-config-prettier": "^8.6.0", "eslint-plugin-prettier": "^4.2.1", "helmet": "^5.1.1", "imdb-api": "^4.4.1", "jest": "28.1.2", - "joi": "^17.7.0", + "joi": "^17.7.1", "nestjs-i18n": "^10.2.6", "nodemailer": "^6.9.1", "passport": "^0.6.0", "passport-jwt": "^4.0.1", "passport-local": "^1.0.0", - "prettier": "^2.8.3", - "prisma": "^4.9.0", + "prettier": "^2.8.4", + "prisma": "^4.10.1", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.8.0", @@ -3597,6 +3602,66 @@ "@volar/vue-typescript": "0.39.5" } }, + "watchvote": { + "version": "file:..", + "requires": { + "@compodoc/compodoc": "^1.1.19", + "@nestjs/cli": "^9.2.0", + "@nestjs/common": "^9.3.9", + "@nestjs/config": "^2.3.1", + "@nestjs/core": "^9.3.9", + "@nestjs/jwt": "^10.0.2", + "@nestjs/passport": "^9.0.3", + "@nestjs/platform-express": "^9.3.9", + "@nestjs/schedule": "^2.2.0", + "@nestjs/schematics": "^9.0.4", + "@nestjs/serve-static": "^3.0.1", + "@nestjs/swagger": "^6.2.1", + "@nestjs/testing": "^9.3.9", + "@prisma/client": "^4.10.1", + "@types/bcrypt": "^5.0.0", + "@types/cron": "^2.0.0", + "@types/crypto-js": "^4.1.1", + "@types/express": "^4.17.17", + "@types/jest": "28.1.4", + "@types/node": "^16.18.12", + "@types/nodemailer": "^6.4.7", + "@types/passport-jwt": "^3.0.8", + "@types/passport-local": "^1.0.35", + "@types/supertest": "^2.0.12", + "@typescript-eslint/eslint-plugin": "^5.52.0", + "@typescript-eslint/parser": "^5.52.0", + "bcrypt": "^5.1.0", + "cron-parser": "^4.7.1", + "crypto-js": "^4.1.1", + "cuid": "^2.1.8", + "discord.js": "^14.7.1", + "eslint": "^8.34.0", + "eslint-config-prettier": "^8.6.0", + "eslint-plugin-prettier": "^4.2.1", + "helmet": "^5.1.1", + "imdb-api": "^4.4.1", + "jest": "28.1.2", + "joi": "^17.7.1", + "nestjs-i18n": "^10.2.6", + "nodemailer": "^6.9.1", + "passport": "^0.6.0", + "passport-jwt": "^4.0.1", + "passport-local": "^1.0.0", + "prettier": "^2.8.4", + "prisma": "^4.10.1", + "reflect-metadata": "^0.1.13", + "rimraf": "^3.0.2", + "rxjs": "^7.8.0", + "source-map-support": "^0.5.20", + "supertest": "^6.3.3", + "ts-jest": "28.0.5", + "ts-loader": "^9.4.2", + "ts-node": "^10.9.1", + "tsconfig-paths": "4.0.0", + "typescript": "^4.3.5" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/client/package.json b/client/package.json index 44b9023..1cc2c83 100644 --- a/client/package.json +++ b/client/package.json @@ -1,5 +1,5 @@ { - "name": "movie-monday-client", + "name": "watch-vote-client", "version": "1.0.0-alpha.8", "scripts": { "dev": "vite", @@ -14,7 +14,8 @@ "js-cookie": "^3.0.1", "movie-monday-manager": "file:..", "vue": "^3.2.37", - "vue-router": "^4.1.6" + "vue-router": "^4.1.6", + "watchvote": "file:.." }, "devDependencies": { "@types/bootstrap": "^5.2.6", diff --git a/client/src/assets/svg/box-arrow-up-right.svg b/client/src/assets/svg/box-arrow-up-right.svg index 60c794b..169d4de 100644 --- a/client/src/assets/svg/box-arrow-up-right.svg +++ b/client/src/assets/svg/box-arrow-up-right.svg @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/client/src/assets/svg/info-circle-fill.svg b/client/src/assets/svg/info-circle-fill.svg index 9d38231..875fa59 100644 --- a/client/src/assets/svg/info-circle-fill.svg +++ b/client/src/assets/svg/info-circle-fill.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/client/src/assets/svg/rotten_tomatoes.svg b/client/src/assets/svg/rotten_tomatoes.svg new file mode 100644 index 0000000..e208305 --- /dev/null +++ b/client/src/assets/svg/rotten_tomatoes.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/client/src/components/CardComponent.vue b/client/src/components/CardComponent.vue index 3d7f2e3..8a3ed3d 100644 --- a/client/src/components/CardComponent.vue +++ b/client/src/components/CardComponent.vue @@ -14,7 +14,9 @@
@@ -63,28 +64,38 @@ export default defineComponent({ } as any, i: 0, filter_values: this.get_filter_cookie(), - first_update: false + first_update: true, + loop_update: true, }; }, setup(props) { + let current_sort_cell = 1 + let current_sort_dir = "asc" + + if (props.sort_default.length === 2) { + current_sort_cell = props.sort_default[0] as number + current_sort_dir = props.sort_default[1] as string + } + return { + current_sort_cell: current_sort_cell, + current_sort_dir: current_sort_dir, sort_dir: ref(Array(props.head.length).fill("none")), }; }, updated() { - if (!this.first_update) { + if (this.loop_update) { if (this.filterable) { - for (let i = 0; i < this.filter_values.length; i++) { - this.filter(this.id, i, this.filter_values[i]); - } - this.first_update = true; - } - - if (this.sortable && this.sort_default!.length) { - this.sort(this.sort_default[0] as any, this.sort_default[1] as any); - + this.filter_all() } } + if (this.sortable) { + this.sort(this.current_sort_cell, this.current_sort_dir); + } + if (this.first_update) { + this.loop_update = false; + this.first_update = false + } }, props: { head: { @@ -151,6 +162,11 @@ export default defineComponent({ this.filter_values[cell_index] = set_visible; this.set_filter_cookie(this.filter_values); }, + filter_all() { + for (let i = 0; i < this.filter_values.length; i++) { + this.filter(this.id, i, this.filter_values[i]); + } + }, get_filter_cookie() : boolean[] { const filter_cookie = get_cookie("table_filter_" + this.id) if (filter_cookie) { diff --git a/client/src/components/WatchlistComponent.vue b/client/src/components/WatchlistComponent.vue index f5e3a8d..91ed303 100644 --- a/client/src/components/WatchlistComponent.vue +++ b/client/src/components/WatchlistComponent.vue @@ -1,10 +1,17 @@ \ No newline at end of file diff --git a/client/src/components/form/InputComponent.vue b/client/src/components/form/InputComponent.vue index 17467a9..095c0fd 100644 --- a/client/src/components/form/InputComponent.vue +++ b/client/src/components/form/InputComponent.vue @@ -13,7 +13,9 @@ \ No newline at end of file diff --git a/client/src/components/movie/VoteComponent.vue b/client/src/components/movie/VoteComponent.vue new file mode 100644 index 0000000..51b31af --- /dev/null +++ b/client/src/components/movie/VoteComponent.vue @@ -0,0 +1,105 @@ + + + + + \ No newline at end of file diff --git a/client/src/locales/de.json b/client/src/locales/de.json index 1c193be..ee5416e 100644 --- a/client/src/locales/de.json +++ b/client/src/locales/de.json @@ -24,7 +24,8 @@ } }, "valid_feedback": "Sieht gut aus!", - "submit": "Bestätigen" + "submit": "Bestätigen", + "search": "Suchen" }, "modal": { "close": "Schließen" @@ -63,7 +64,8 @@ "director": "Regisseur", "actors": "Schauspieler", "imdb_rate": "IMDB", - "metascore": "Metascore", + "meta_score": "Meta", + "rotten_score": "Rotten", "language": "Sprache", "genre": "Genre", "proposer": "Hinzugefügt von", @@ -74,10 +76,16 @@ "modal": { "title": "Film hinzufügen", "form": { - "title": "Titel oder IMDB ID:", - "invalid_feedback": "Sollte eine gültige IMDB ID sein, z.B. tt1234567" - }, - "no_suggestion": "Kein Filmvorschlag" + "enter_title": "Titel eingeben", + "enter_id": "IMDB-ID eingeben", + "or": "----- ODER -----", + "placeholder_title": "Mein Filmtitel", + "invalid_feedback": { + "title": "Sollte mindestens 3 Zeichen lang sein", + "id": "Sollte eine gültige IMDB ID sein, z.B. tt1234567" + }, + "no_suggestion": "Kein Filmvorschlag" + } } }, diff --git a/client/src/locales/en.json b/client/src/locales/en.json index eb8c359..e8ec22f 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -24,7 +24,8 @@ } }, "valid_feedback": "Looks good!", - "submit": "Submit" + "submit": "Submit", + "search": "Search" }, "modal": { "close": "Close" @@ -63,7 +64,8 @@ "director": "Director", "actors": "Actors", "imdb_rate": "IMDB", - "metascore": "Metascore", + "meta_score": "Meta", + "rotten_score": "Rotten", "language": "Language", "genre": "Genre", "proposer": "Proposer", @@ -74,10 +76,16 @@ "modal": { "title": "Add Movie", "form": { - "title": "Title or IMDB ID:", - "invalid_feedback": "Should be a valid IMDB ID, e.g. tt1234567" - }, - "no_suggestion": "No movie suggestion" + "enter_title": "Enter Title", + "enter_id": "Enter IMDB-ID", + "or": "----- OR -----", + "placeholder_title": "My Movie Title", + "invalid_feedback": { + "title": "Should be at least 3 characters long", + "id": "Should be a valid IMDB ID, e.g. tt1234567" + }, + "no_suggestion": "No film proposal" + } } }, diff --git a/client/src/util/store.ts b/client/src/util/store.ts index ca81eef..15151ab 100644 --- a/client/src/util/store.ts +++ b/client/src/util/store.ts @@ -4,8 +4,8 @@ import { get_cookie, set_cookie } from "@/util/cookie"; export const store = reactive({ logged_in: false, loading: false, - theme: 'light', - theme_without_auto: 'light', + theme: 'auto', + theme_without_auto: 'dark', alert: { show: false, msg: "", @@ -63,12 +63,18 @@ export const store = reactive({ }, }) +window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { + if (store.theme === 'auto') { + store.update_theme(get_theme()) + } +}) + function get_theme() { const theme = get_cookie("theme") if (theme) { return theme } - return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' + return 'auto' } store.update_theme(get_theme()) diff --git a/client/src/views/DocsView.vue b/client/src/views/DocsView.vue index 0809b1e..0578012 100644 --- a/client/src/views/DocsView.vue +++ b/client/src/views/DocsView.vue @@ -13,11 +13,12 @@