diff --git a/package-lock.json b/package-lock.json
index 3142de1..7d4437d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-toast": "^1.2.1",
+ "@radix-ui/react-tooltip": "^1.1.3",
"axios": "^1.7.7",
"bcrypt": "^5.1.1",
"class-variance-authority": "^0.7.0",
@@ -3831,6 +3832,40 @@
}
}
},
+ "node_modules/@radix-ui/react-tooltip": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.3.tgz",
+ "integrity": "sha512-Z4w1FIS0BqVFI2c1jZvb/uDVJijJjJ2ZMuPV81oVgTZ7g3BZxobplnMVvXtFWgtozdvYJ+MFWtwkM5S2HnAong==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-dismissable-layer": "1.1.1",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.2",
+ "@radix-ui/react-presence": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-visually-hidden": "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-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",
diff --git a/package.json b/package.json
index 452fd1e..df4a6f5 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-toast": "^1.2.1",
+ "@radix-ui/react-tooltip": "^1.1.3",
"axios": "^1.7.7",
"bcrypt": "^5.1.1",
"class-variance-authority": "^0.7.0",
diff --git a/src/app/api/[...]/asset.js b/src/app/api/[...]/asset.js
index fb9a888..e5dbe72 100644
--- a/src/app/api/[...]/asset.js
+++ b/src/app/api/[...]/asset.js
@@ -1,7 +1,7 @@
import { paramsValidate, queryValidate } from "@/lib/validators/data-validate";
import { assetIdSchema, queryAssetDownloadSchema, queryAssetListSchema } from "@/lib/validators/data-validate/assets";
import NextApiRouter from "@billyen2012/next-api-router";
-import { archive, create, download, get, list, update } from "../_lib/controllers/assetsController";
+import { archive, create, download, get, list, publish, update } from "../_lib/controllers/assetsController";
import validate from "@/lib/validators/validate";
import { authorize } from "../_lib/middlewares/authorize";
import { userRoles } from "@/lib/utils/constants";
@@ -54,6 +54,13 @@ router.get('/archive/:assetId',
archive
)
+router.get('/publish/:assetId',
+ authorize([userRoles.ADMIN, userRoles.GESTOR]),
+ paramsValidate(assetIdSchema),
+ validate,
+ publish
+)
+
router.get('/download',
queryValidate(queryAssetDownloadSchema),
validate,
diff --git a/src/app/api/_lib/controllers/assetsController.js b/src/app/api/_lib/controllers/assetsController.js
index 241b24f..3d7c53c 100644
--- a/src/app/api/_lib/controllers/assetsController.js
+++ b/src/app/api/_lib/controllers/assetsController.js
@@ -88,7 +88,7 @@ export const create = async function (req, res) {
const asset = await Asset.create(data);
- return res.status(200).json({ message: 'ok' });
+ return res.status(200).json({ asset });
} catch (error) {
console.error(error)
return res.status(500).json({ message: messages.error.default })
@@ -136,6 +136,25 @@ export const archive = async function (req, res) {
}
}
+export const publish = async function (req, res) {
+ try {
+ const assetId = req.params.assetId;
+ const now = new Date()
+ const asset = await Asset.findById(assetId)
+ if (asset.publish) {
+ asset.set({ publish: false })
+ } else {
+ asset.set({ publish: true })
+ }
+ await asset.save()
+
+ return res.status(200).json(asset);
+ } catch (error) {
+ console.error(error);
+ return res.status(500).json({ message: messages.error.default });
+ }
+}
+
export const download = async function (req, res) {
try {
diff --git a/src/app/layout.jsx b/src/app/layout.jsx
index fe17c64..e712184 100644
--- a/src/app/layout.jsx
+++ b/src/app/layout.jsx
@@ -2,6 +2,7 @@ import { Inter } from "next/font/google";
import "./globals.css";
import Navbar from "@/components/layout/navbar";
import { Toaster } from "@/components/ui/toaster";
+import { TooltipProvider } from "@radix-ui/react-tooltip";
const inter = Inter({ subsets: ["latin"] });
@@ -14,9 +15,11 @@ export default function RootLayout({ children }) {
return (
-
- {children}
-
+
+
+ {children}
+
+
);
diff --git a/src/app/page.jsx b/src/app/page.jsx
index f7a0194..c7336c0 100644
--- a/src/app/page.jsx
+++ b/src/app/page.jsx
@@ -9,16 +9,15 @@ import DownloadButton from "@/components/admin/asset/download-button";
export const dynamic = "force-dynamic";
-export default function Home({ searchParams }) {
+export default function Home({ searchParams: { estado, search, page } }) {
+ const destination = estado;
return (
Buscador de bienes
-
+
diff --git a/src/components/admin/asset/asset-list.jsx b/src/components/admin/asset/asset-list.jsx
index 76b8657..cc7cbce 100644
--- a/src/components/admin/asset/asset-list.jsx
+++ b/src/components/admin/asset/asset-list.jsx
@@ -1,7 +1,7 @@
import React from "react";
-import AssetCard from "./asset-card";
import { getAssets } from "@/lib/actions/home/fetch-data";
import AssetPagination from "@/components/asset-pagination";
+import AssetCard from "./assetCard";
async function AssetList({ filter = {} }) {
const { assets, page, total, pages, nextPage, prevPage, status, message } =
diff --git a/src/components/admin/asset/asset-serch.jsx b/src/components/admin/asset/asset-serch.jsx
index dbc7be9..169b94c 100644
--- a/src/components/admin/asset/asset-serch.jsx
+++ b/src/components/admin/asset/asset-serch.jsx
@@ -8,6 +8,8 @@ import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
+ DropdownMenuRadioGroup,
+ DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { FilterIcon } from "lucide-react";
@@ -16,6 +18,7 @@ const AssetSerch = () => {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
+ const [filter, setFilter] = useState("todos");
const [searchValue, setSearchValue] = useState(
searchParams.get("search") || ""
);
@@ -49,6 +52,23 @@ const AssetSerch = () => {
router.push(`${pathname}${query}`);
};
+
+ const handleFilter = (value) => {
+ const params = new URLSearchParams(searchParams.entries());
+
+ if (!value) {
+ params.delete("estado");
+ } else {
+ params.set("estado", value);
+ params.delete("page");
+ }
+ const estado = params.toString();
+ const query = estado ? `?${estado}` : "";
+
+ router.push(`${pathname}${query}`);
+ setFilter(value);
+ };
+
return (
@@ -61,20 +81,31 @@ const AssetSerch = () => {
className="shadow-md rounded-lg"
/>
-
-
-
-
- Filtrar
-
-
-
- Supiti
- Upiti
- Uapiti
-
-
-
+ {!pathname.startsWith("/admin") && (
+
+
+
+
+ Filtrar
+
+
+
+
+ Todos
+
+ Subasta
+
+
+ Reutilizacion
+
+
+
+
+
+ )}
);
};
diff --git a/src/components/admin/asset/assetCard/card-actions.jsx b/src/components/admin/asset/assetCard/card-actions.jsx
new file mode 100644
index 0000000..d042cfb
--- /dev/null
+++ b/src/components/admin/asset/assetCard/card-actions.jsx
@@ -0,0 +1,77 @@
+import React from "react";
+import { Button, buttonVariants } from "@/components/ui/button";
+import { Pencil, Archive, ArchiveX, BookX, BookUp } from "lucide-react";
+import Link from "next/link";
+import {
+ archiveAsset,
+ togglePublish,
+} from "@/lib/actions/admin/asset-actions/asset";
+import { ToastAction } from "@/components/ui/toast";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "@/components/ui/tooltip";
+import { useToast } from "@/components/ui/use-toast";
+
+const CardActions = ({ asset, pathname }) => {
+ const { toast } = useToast();
+ return (
+
+
+
+
+
+
+
+
+ Editar
+
+
+
+
+
+ toast({
+ description: `Confirmar para ${
+ pathname.includes("archivados") ? "des" : ""
+ }archivar el bien`,
+ action: (
+
archiveAsset(asset._id)}
+ altText="Confirmar"
+ >
+ Confirmar
+
+ ),
+ })
+ }
+ >
+ {pathname.includes("archivados") ?
:
}
+
+
+
+ {asset.archivedAt ? "Desarchivar" : "Archivar"}
+
+
+
+
+ {
+ togglePublish(asset._id);
+ }}
+ className="submitButton w-full my-2"
+ >
+ {asset.publish ? : }
+
+
+
+ {asset.publish ? "Despublicar" : "Publicar"}
+
+
+
+ );
+};
+
+export default CardActions;
diff --git a/src/components/admin/asset/asset-card.jsx b/src/components/admin/asset/assetCard/index.jsx
similarity index 81%
rename from src/components/admin/asset/asset-card.jsx
rename to src/components/admin/asset/assetCard/index.jsx
index 07cfa56..b61baf5 100644
--- a/src/components/admin/asset/asset-card.jsx
+++ b/src/components/admin/asset/assetCard/index.jsx
@@ -1,4 +1,4 @@
-'use client'
+"use client";
import React, { useEffect, useState } from "react";
import {
Card,
@@ -9,18 +9,20 @@ import {
} from "@/components/ui/card";
import { fontAwesomeIcons, showCardOptions } from "@/lib/utils/constants";
import { Button, buttonVariants } from "@/components/ui/button";
-import { Pencil, Archive, ArchiveX } from "lucide-react";
+import { Pencil, Archive, ArchiveX, BookX, BookUp } from "lucide-react";
import Link from "next/link";
-import { archiveAsset } from "@/lib/actions/admin/asset-actions/asset";
-import { useToast } from "@/components/ui/use-toast";
-import { ToastAction } from "@/components/ui/toast";
+import {
+ archiveAsset,
+ togglePublish,
+} from "@/lib/actions/admin/asset-actions/asset";
import { usePathname } from "next/navigation";
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
+import CardActions from "./card-actions";
+
const AssetCard = ({ asset }) => {
const pathname = usePathname();
const [showMore, setShowMore] = useState(false);
- const { toast } = useToast();
const renderFieldShowCard = (fields, ordering) => {
return (
@@ -125,34 +127,7 @@ const AssetCard = ({ asset }) => {
-
-
-
-
-
-
+
{asset.extras[showCardOptions.EXPANDED.value] && (
diff --git a/src/components/admin/asset/assetForm/destination-info/index.jsx b/src/components/admin/asset/assetForm/destination-info/index.jsx
index fec6ea7..af4f244 100644
--- a/src/components/admin/asset/assetForm/destination-info/index.jsx
+++ b/src/components/admin/asset/assetForm/destination-info/index.jsx
@@ -87,6 +87,7 @@ function DestinationInfo({ assetEdit }) {
/>
diff --git a/src/components/admin/asset/assetForm/index.jsx b/src/components/admin/asset/assetForm/index.jsx
index 04ed0bf..3cba4a4 100644
--- a/src/components/admin/asset/assetForm/index.jsx
+++ b/src/components/admin/asset/assetForm/index.jsx
@@ -15,6 +15,7 @@ import {
editAsset,
saveAsset,
} from "@/lib/actions/admin/asset-actions/asset-client";
+import { togglePublish } from "@/lib/actions/admin/asset-actions/asset";
const FormAsset = ({ assetEdit }) => {
const router = useRouter();
@@ -43,12 +44,18 @@ const FormAsset = ({ assetEdit }) => {
},
];
- const [tab, setActiveTab] = useState([assetFormSteps[0].slug]);
+ const [tab, setActiveTab] = useState(assetFormSteps[0].slug);
const [incompleteTab, setIncompleteTab] = useState(null);
const handleTab = (value) => {
setActiveTab(value);
};
+ const handleNextStep = (value) => {
+ const currentStep = assetFormSteps.find((step) => step.slug === tab);
+ const index = assetFormSteps.indexOf(currentStep);
+ const step = value === "next" ? index + 1 : index - 1;
+ setActiveTab(assetFormSteps[step].slug);
+ };
const submit = async (event) => {
event.preventDefault();
@@ -99,12 +106,12 @@ const FormAsset = ({ assetEdit }) => {
if (form.checkValidity()) {
try {
- let asset;
- if (assetEdit) asset = await editAsset(assetEdit._id, realFormData);
- else asset = await saveAsset(realFormData);
+ let resp;
+ if (assetEdit) resp = await editAsset(assetEdit._id, realFormData);
+ else resp = await saveAsset(realFormData);
- if (asset.status === 200) {
- router.push("/admin/bien");
+ if (resp.status === 200) {
+ router.push(`/admin/bien/editar/${resp.asset._id}`);
router.refresh();
}
} catch (err) {
@@ -153,9 +160,9 @@ const FormAsset = ({ assetEdit }) => {
};
return (
-
-
);
};
diff --git a/src/components/admin/asset/assetForm/judicial-process/index.jsx b/src/components/admin/asset/assetForm/judicial-process/index.jsx
index 638d9f8..fb6e1d1 100644
--- a/src/components/admin/asset/assetForm/judicial-process/index.jsx
+++ b/src/components/admin/asset/assetForm/judicial-process/index.jsx
@@ -98,7 +98,10 @@ const JudicialInfo = ({ assetEdit }) => {
name="cautelaResolution"
value={assetEdit.cautelaResolution}
/>
-
@@ -168,6 +171,7 @@ const JudicialInfo = ({ assetEdit }) => {
/>
addInputToEditFile("confiscatedResolution")}
+ variant="link"
>
Cambiar
diff --git a/src/components/admin/category/category-field-form.jsx b/src/components/admin/category/category-field-form.jsx
index 1bb4226..87bf0f2 100644
--- a/src/components/admin/category/category-field-form.jsx
+++ b/src/components/admin/category/category-field-form.jsx
@@ -219,6 +219,7 @@ const CategoryFieldForm = ({ setExtras, extraFieldsEdit, errors }) => {
onClick={() =>
addInputToEditFile(`selectablesOptions-${idx}`)
}
+ variant="link"
>
Cambiar
diff --git a/src/components/ui/tooltip.jsx b/src/components/ui/tooltip.jsx
new file mode 100644
index 0000000..84147e0
--- /dev/null
+++ b/src/components/ui/tooltip.jsx
@@ -0,0 +1,26 @@
+"use client"
+
+import * as React from "react"
+import * as TooltipPrimitive from "@radix-ui/react-tooltip"
+
+import { cn } from "@/lib/utils"
+
+const TooltipProvider = TooltipPrimitive.Provider
+
+const Tooltip = TooltipPrimitive.Root
+
+const TooltipTrigger = TooltipPrimitive.Trigger
+
+const TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (
+
+))
+TooltipContent.displayName = TooltipPrimitive.Content.displayName
+
+export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
diff --git a/src/lib/actions/admin/asset-actions/asset.js b/src/lib/actions/admin/asset-actions/asset.js
index ee64bab..45106f8 100644
--- a/src/lib/actions/admin/asset-actions/asset.js
+++ b/src/lib/actions/admin/asset-actions/asset.js
@@ -1,12 +1,14 @@
"use server"
import { revalidatePath } from "next/cache";
import fetchData from "@/lib/utils/get-data";
-import axiosServices from "@/lib/utils/axios";
export const archiveAsset = async (id) => {
revalidatePath(`/admin/bien`)
return await fetchData(`/api/asset/archive/${id}`)
-
}
+export const togglePublish = async (id) => {
+ revalidatePath(`/admin/bien`)
+ return await fetchData(`/api/asset/publish/${id}`)
+}
diff --git a/src/lib/models/Asset.js b/src/lib/models/Asset.js
index 836c454..10140f1 100644
--- a/src/lib/models/Asset.js
+++ b/src/lib/models/Asset.js
@@ -110,6 +110,10 @@ export const AssetSchema = new mongoose.Schema(
default: undefined
},
causeCoverSheet: { type: String },
+ publish: {
+ type: Boolean,
+ default: false,
+ },
archivedAt: {
type: Date,
required: false,