From 618d48bc0f02358bf472047dba8a7af31a2a06da Mon Sep 17 00:00:00 2001 From: Telkens Date: Fri, 23 Aug 2024 11:42:39 -0500 Subject: [PATCH] Add an active review switch at the ReviewsTable and improve code --- package-lock.json | 177 ++++++++++++++++++ package.json | 1 + src/actions/reviews.ts | 4 +- .../atc24$rw/admin/components/ReviewForm.tsx | 44 +++-- .../admin/components/ReviewsTable.tsx | 79 +++++++- src/app/(admin)/atc24$rw/admin/schema.ts | 3 +- src/components/Reviews/index.tsx | 3 +- src/components/ui/switch.tsx | 29 +++ src/lib/utils.ts | 9 + src/types.d.ts | 3 +- 10 files changed, 318 insertions(+), 34 deletions(-) create mode 100644 src/components/ui/switch.tsx diff --git a/package-lock.json b/package-lock.json index d25ae6e..c970faa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-switch": "^1.1.0", "@types/react-star-ratings": "^2.3.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", @@ -793,6 +794,182 @@ } } }, + "node_modules/@radix-ui/react-switch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.0.tgz", + "integrity": "sha512-OBzy5WAj641k0AOSpKQtreDMe+isX0MQJ1IVyF03ucdF3DunOnROVrjWs8zsXUxC3zfZ6JL9HFVCUlMghz9dJw==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", diff --git a/package.json b/package.json index 149e078..f566d95 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-switch": "^1.1.0", "@types/react-star-ratings": "^2.3.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", diff --git a/src/actions/reviews.ts b/src/actions/reviews.ts index 018a5a7..68768d0 100644 --- a/src/actions/reviews.ts +++ b/src/actions/reviews.ts @@ -8,7 +8,9 @@ import { Review } from "@/types"; export const getReviews = async (): Promise => { try { - const response = await fetch(`${REVIEWS_API}/reviews`); + const response = await fetch(`${REVIEWS_API}/reviews`, { + cache: "no-store" + }); const { data } = await response.json(); return data ?? []; } catch (_) { diff --git a/src/app/(admin)/atc24$rw/admin/components/ReviewForm.tsx b/src/app/(admin)/atc24$rw/admin/components/ReviewForm.tsx index 70cf3fd..9f46201 100644 --- a/src/app/(admin)/atc24$rw/admin/components/ReviewForm.tsx +++ b/src/app/(admin)/atc24$rw/admin/components/ReviewForm.tsx @@ -25,6 +25,7 @@ import { Textarea } from "@/components/ui/textarea"; import { useDropzone } from "react-dropzone"; import Image from "next/image"; import { REVIEWS_API } from "@/lib/constants"; +import { createFormData } from "@/lib/utils"; interface ReviewFormProps { review?: Review; @@ -52,6 +53,7 @@ export const ReviewForm = ({ review }: ReviewFormProps) => { rating: review?.rating || "5", user: review?.user || "", active: review?.active || "false", + date: review?.date || new Date().toISOString(), }, }); @@ -59,14 +61,10 @@ export const ReviewForm = ({ review }: ReviewFormProps) => { values: z.infer, token: string ) => { - const formData = new FormData(); - formData.append("review", values.review); - formData.append("rating", String(values.rating)); - formData.append("user", values.user); - formData.append("date", new Date().toISOString()); - formData.append("file", acceptedFiles[0]); - formData.append("active", JSON.parse(values.active || "false") ? "true" : "false"); - + const formData: FormData = createFormData({ + ...values, + file: acceptedFiles[0], + }); startTransition(() => { createReview(formData, token) .then((data) => { @@ -84,16 +82,12 @@ export const ReviewForm = ({ review }: ReviewFormProps) => { }; const handleUpdate = (review: Review, token: string) => { - const formData = new FormData(); - formData.append("id", review.id); - formData.append("review", review.review); - formData.append("rating", String(review.rating)); - formData.append("user", review.user); - formData.append("date", new Date().toISOString()); - formData.append("file", acceptedFiles[0] || new File([], "null", { - type: "image/png", - })); - formData.append("active", review.active ? "true" : "false"); + const formData: FormData = createFormData({ + ...review, + file: acceptedFiles[0] || new File([], "null", { + type: "image/png", + }) + }); startTransition(() => { updateReview(formData, token) .then((data) => { @@ -142,6 +136,7 @@ export const ReviewForm = ({ review }: ReviewFormProps) => { {...field} placeholder="Texto de la reseña" className="max-w-full h-[150px] resize-none" + maxLength={600} /> @@ -218,7 +213,7 @@ export const ReviewForm = ({ review }: ReviewFormProps) => { type="checkbox" id="show" className="w-5 h-5" - checked={JSON.parse(field.value || 'false') ? true : false} + checked={JSON.parse(field.value)} />