feat(feedback): add feedback button to tenders table
This commit introduces the ability for users to navigate to a feedback page directly from the tenders list. A new feedback icon and a corresponding button have been added to the actions column of the tenders table. Clicking this button redirects the user to the feedback page associated with that specific tender. To support this feature, the following changes were made: - Added a new `FeedbackIcon` SVG component. - Defined API endpoints and created query hooks for the feedback module. - Fixed a query key inconsistency for company details to ensure data is correctly refetched after updates.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
"use client";
|
||||
|
||||
import { ExclamationIcon } from "@/assets/icons";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
} from "@/components/ui/table";
|
||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||
import { unixToDate } from "@/utils/shared";
|
||||
import { TableRow } from "../../../ui/table";
|
||||
import useTenderFeedbackPresenter from "./useTenderFeedbackPresenter";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface IProps {
|
||||
id: string;
|
||||
}
|
||||
|
||||
const TenderFeedbackTable = ({ id }: IProps) => {
|
||||
const { feedback, isLoading, columns, pathName, router } =
|
||||
useTenderFeedbackPresenter({ id });
|
||||
return (
|
||||
<div className="flex flex-col rounded-[10px] bg-white px-7.5 pb-4 pt-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{columns.map((column) => (
|
||||
<TableHead className="capitalize" key={column} colSpan={100}>
|
||||
{column}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
{isLoading && <TableSkeleton column={columns.length} />}
|
||||
<TableBody>
|
||||
{feedback?.map((item, index) =>
|
||||
!item ? (
|
||||
<h6 key={index}>No feedback is submitted for this tender</h6>
|
||||
) : (
|
||||
<TableRow
|
||||
key={item.id}
|
||||
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
||||
>
|
||||
<TableCell className="text-start" colSpan={100}>
|
||||
{index + 1}
|
||||
</TableCell>
|
||||
<TableCell className="uppercase" colSpan={100}>
|
||||
{item.feedback_type}
|
||||
</TableCell>
|
||||
<TableCell className="uppercase" colSpan={100}>
|
||||
{unixToDate(item.updated_at)}
|
||||
</TableCell>
|
||||
<TableCell className="uppercase" colSpan={100}>
|
||||
{item?.tender?.title ?? "-"}
|
||||
</TableCell>
|
||||
<TableCell className="uppercase" colSpan={100}>
|
||||
{unixToDate(item.created_at)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className={cn(`text flex gap-2 capitalize`)}
|
||||
colSpan={100}
|
||||
>
|
||||
<button
|
||||
className="text-gray-40 rounded-full bg-gray-dark bg-opacity-5 hover:text-green-dark dark:bg-gray dark:bg-opacity-5"
|
||||
onClick={() => {
|
||||
router.push(`${pathName}/${item.id}`);
|
||||
}}
|
||||
>
|
||||
<ExclamationIcon />
|
||||
</button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
),
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TenderFeedbackTable;
|
||||
@@ -0,0 +1,20 @@
|
||||
"use client";
|
||||
import { useGetFeedback } from "@/hooks/queries";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
|
||||
const useTenderFeedbackPresenter = ({ id }: { id: string }) => {
|
||||
const { data, isLoading } = useGetFeedback({ tender_id: id });
|
||||
const router = useRouter();
|
||||
const pathName = usePathname();
|
||||
const columns = [
|
||||
"row",
|
||||
"feedback type",
|
||||
"updated at",
|
||||
"tender name",
|
||||
"created at",
|
||||
"actions",
|
||||
];
|
||||
return { feedback: data?.data, isLoading, columns, pathName, router };
|
||||
};
|
||||
|
||||
export default useTenderFeedbackPresenter;
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from "@/components/ui/table";
|
||||
import useTenderListPresenter from "./useTenderListPresenter";
|
||||
|
||||
import { ExclamationIcon } from "@/assets/icons";
|
||||
import { ExclamationIcon, FeedbackIcon } from "@/assets/icons";
|
||||
import Pagination from "@/components/ui/pagination";
|
||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -65,7 +65,10 @@ const TendersTable = () => {
|
||||
<TableCell className={cn(`text capitalize`)} colSpan={100}>
|
||||
<Status status={item.status}>{item.status}</Status>
|
||||
</TableCell>
|
||||
<TableCell className={cn(`text capitalize`)} colSpan={100}>
|
||||
<TableCell
|
||||
className={cn(`text flex gap-2 capitalize`)}
|
||||
colSpan={100}
|
||||
>
|
||||
<button
|
||||
className="text-gray-40 rounded-full bg-gray-dark bg-opacity-5 hover:text-green-dark dark:bg-gray dark:bg-opacity-5"
|
||||
onClick={() => {
|
||||
@@ -74,6 +77,13 @@ const TendersTable = () => {
|
||||
>
|
||||
<ExclamationIcon />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
router.push(`${pathName}/feedback/${item.id}`);
|
||||
}}
|
||||
>
|
||||
<FeedbackIcon />
|
||||
</button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user