refactor(Breadcrumbs, InputGroup, Layouts, Tables): enhance styling and structure for improved responsiveness

- Adjusted Breadcrumb component styles for better spacing and font size.
- Made placeholder in InputGroup optional and refined input styles for consistency.
- Updated MainLayout and Header components for improved padding and layout.
- Enhanced table components by importing necessary elements and optimizing rendering logic.
- Refactored CompanyCategoriesTable to utilize optimistic updates for better user experience.
This commit is contained in:
AmirReza Jamali
2026-04-19 16:14:51 +03:30
parent 69e75eb9b8
commit 57e9d90eb1
9 changed files with 114 additions and 70 deletions
+8 -2
View File
@@ -4,12 +4,18 @@ import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
import ConfirmationModal from "@/components/ui/ConfirmationModal";
import ListHeader from "@/components/ui/ListHeader";
import Modal from "@/components/ui/modal";
import { Table, TableBody, TableCell, TableHead } from "@/components/ui/table";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import TableSkeleton from "@/components/ui/TableSkeleton";
import { _TooltipDefaultParams } from "@/constants/tooltip";
import { getPaginatedRowNumber, unixToDate } from "@/utils/shared";
import { Tooltip } from "react-tooltip";
import { TableHeader, TableRow } from "../../ui/table";
import CmsListFilters from "./CmsListFilters";
import useCmsTablePresenter from "./useCmsTablePresenter";
@@ -3,7 +3,8 @@ import { PencilSquareIcon, TrashIcon } from "@/assets/icons";
import { Switch } from "@/components/FormElements/switch";
import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
import ConfirmationModal from "@/components/ui/ConfirmationModal";
import IsVisible from "@/components/ui/IsVisible";
import ListHeader from "@/components/ui/ListHeader";
import Modal from "@/components/ui/modal";
import {
Table,
TableBody,
@@ -15,21 +16,19 @@ import {
import TableSkeleton from "@/components/ui/TableSkeleton";
import { _TooltipDefaultParams } from "@/constants/tooltip";
import { getPaginatedRowNumber, unixToDate } from "@/utils/shared";
import { startTransition } from "react";
import { Tooltip } from "react-tooltip";
import { Skeleton } from "../../../ui/skeleton";
import useCompanyCategoriesPresenter from "./useCompanyCategoriesPresenter";
import ListHeader from "@/components/ui/ListHeader";
import CompanyCategoryListFilters from "./CompanyCategoryListFilters";
import Modal from "@/components/ui/modal";
import useCompanyCategoriesPresenter from "./useCompanyCategoriesPresenter";
const CompanyCategoriesTable = () => {
const {
categories,
optimisticCategories,
addOptimisticPublished,
isLoading,
pathName,
router,
currentCategory,
isToggling,
togglePublished,
onConfirmDelete,
setCurrentCategory,
@@ -42,18 +41,10 @@ const CompanyCategoriesTable = () => {
search,
watch,
setFilterValue,
columns,
isMutating,
} = useCompanyCategoriesPresenter();
const columns = [
"Row",
"Title",
"Description",
"Created at",
"Published",
"Actions",
];
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">
<ListHeader
@@ -74,11 +65,11 @@ const CompanyCategoriesTable = () => {
{isLoading && <TableSkeleton column={columns.length} />}
<TableBody>
<EmptyListWrapper
list={categories ?? []}
list={optimisticCategories}
columns={columns}
emptyMessage="No categories were found"
>
{(categories ?? []).map((category, index) => (
{optimisticCategories.map((category, index) => (
<TableRow
key={category.id}
className="odd:bg-gray-2 dark:odd:bg-gray-7"
@@ -92,21 +83,21 @@ const CompanyCategoriesTable = () => {
{unixToDate({ unix: category.created_at, hasTime: true })}
</TableCell>
<TableCell colSpan={100}>
<IsVisible condition={isToggling}>
<Skeleton className="h-8 bg-neutral-400 dark:bg-dark-4" />
</IsVisible>
<IsVisible condition={!isToggling}>
<Switch
withIcon
onChange={(e) => {
togglePublished(category.id);
}}
checked={category.published}
onToggle={(e) => {
console.log(e);
}}
/>
</IsVisible>
<Switch
withIcon
onToggle={() => {}}
onChange={() => {
const nextPublished = !category.published;
startTransition(async () => {
addOptimisticPublished({
id: category.id,
published: nextPublished,
});
await togglePublished(category.id);
});
}}
checked={category.published}
/>
</TableCell>
<TableCell className="text-start xl:pr-7.5">
<div className="flex items-center justify-start gap-x-3.5">
@@ -9,9 +9,11 @@ import { TCompanyCategory } from "@/lib/api";
import { deleteEmptyKeys } from "@/utils/shared";
import { useIsMutating } from "@tanstack/react-query";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
import { useEffect, useOptimistic, useState } from "react";
import { useForm } from "react-hook-form";
type TogglePublishedOptimistic = Pick<TCompanyCategory, "id" | "published">;
const useCompanyCategoriesPresenter = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
const [isFilterModalOpen, setIsFilterModalOpen] = useState(false);
@@ -42,10 +44,17 @@ const useCompanyCategoriesPresenter = () => {
}, [searchParams, filterFormReset]);
const { data, isLoading, isError } = useCompanyCategoriesQuery(params);
const categories = data?.data.categories;
const [optimisticCategories, addOptimisticPublished] = useOptimistic<
TCompanyCategory[],
TogglePublishedOptimistic
>(categories ?? [], (state, { id, published }) =>
state.map((c) => (c.id === id ? { ...c, published } : c)),
);
const { mutate: deleteCategory } = useDeleteCompanyCategoryQuery(() =>
setIsModalOpen(false),
);
const { mutate: togglePublished, isPending: isToggling } =
const { mutateAsync: togglePublished } =
useToggleCompanyCategoryPublished();
const search = (data: any) => {
@@ -60,19 +69,29 @@ const useCompanyCategoriesPresenter = () => {
if (!currentCategory) return;
deleteCategory(currentCategory?.id);
};
const columns = [
"Row",
"Title",
"Description",
"Created at",
"Published",
"Actions",
];
return {
categories: data?.data.categories,
categories,
optimisticCategories,
addOptimisticPublished,
isModalOpen,
setIsModalOpen,
isLoading,
isError,
pathName,
router,
columns,
params,
setParams,
currentCategory,
togglePublished,
isToggling,
setCurrentCategory,
onConfirmDelete,
isFilterModalOpen,