Merge pull request 'sidebar-issues' (#35) from sidebar-issues into develop
Reviewed-on: https://repo.ravanertebat.com/TM/tm_panel/pulls/35 Reviewed-by: Nima Nakhsotin <n.nakhostin@ravanertebat.com>
This commit is contained in:
+2
-2
@@ -7,8 +7,8 @@ interface IProps {}
|
||||
const CreateCompanyCategoryPage = ({}: IProps) => {
|
||||
const breadcrumbItems: BreadcrumbItem[] = [
|
||||
{ href: "/", name: "Dashboard" },
|
||||
{ href: "/companies/categories", name: "Company Categories" },
|
||||
{ href: "/companies/categories/create", name: "Create Company Category" },
|
||||
{ href: "/company-categories", name: "Company Categories" },
|
||||
{ href: "/company-categories/create", name: "Create Company Category" },
|
||||
];
|
||||
return (
|
||||
<>
|
||||
+2
-2
@@ -15,8 +15,8 @@ const EditCompanyCategory = ({
|
||||
const { isLoading, data } = useCompanyCategoriesDetails(id);
|
||||
const breadcrumbItems: BreadcrumbItem[] = [
|
||||
{ name: "Dashboard", href: "/" },
|
||||
{ name: "Company Categories", href: "/companies/categories" },
|
||||
{ name: "Edit Company Category", href: `/companies/categories/edit/${id}` },
|
||||
{ name: "Company Categories", href: "/company-categories" },
|
||||
{ name: "Edit Company Category", href: `/company-categories/edit/${id}` },
|
||||
];
|
||||
if (isLoading) return <Loading />;
|
||||
return (
|
||||
+1
-1
@@ -4,7 +4,7 @@ import CompanyCategoriesTable from "@/components/Tables/companies/company-catego
|
||||
const CompanyCategoryList = () => {
|
||||
const breadcrumbItems = [
|
||||
{ name: "Dashboard", href: "/" },
|
||||
{ name: "Company Categories", href: "/companies/categories" },
|
||||
{ name: "Company Categories", href: "/company-categories" },
|
||||
];
|
||||
return (
|
||||
<>
|
||||
@@ -1,5 +1,6 @@
|
||||
import { z } from "zod";
|
||||
import * as Icons from "../icons";
|
||||
|
||||
const navSubItemSchema: z.ZodType<any> = z.lazy(() =>
|
||||
z.object({
|
||||
title: z.string(),
|
||||
@@ -20,7 +21,7 @@ export type NavData = z.infer<typeof navDataSchema>;
|
||||
|
||||
export const NAV_DATA: NavData = [
|
||||
{
|
||||
label: "MAIN MENU",
|
||||
label: "",
|
||||
items: [
|
||||
{
|
||||
title: "Dashboard",
|
||||
@@ -36,13 +37,20 @@ export const NAV_DATA: NavData = [
|
||||
},
|
||||
{
|
||||
title: "Manage Companies",
|
||||
url: "",
|
||||
icon: Icons.Building,
|
||||
items: [
|
||||
{ Icons: Icons.Building, url: "/companies", title: "Companies" },
|
||||
{
|
||||
Icons: Icons.Building,
|
||||
url: "/companies/categories",
|
||||
icon: Icons.Building,
|
||||
url: "/companies",
|
||||
title: "Companies",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
icon: Icons.Building,
|
||||
url: "/company-categories",
|
||||
title: "Company Categories",
|
||||
items: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -60,105 +68,4 @@ export const NAV_DATA: NavData = [
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// label: "MAIN MENU",
|
||||
// items: [
|
||||
// {
|
||||
// title: "Dashboard",
|
||||
// icon: Icons.HomeIcon,
|
||||
// items: [
|
||||
// {
|
||||
// title: "eCommerce",
|
||||
// url: "/",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// title: "Calendar",
|
||||
// url: "/calendar",
|
||||
// icon: Icons.Calendar,
|
||||
// items: [],
|
||||
// },
|
||||
// {
|
||||
// title: "Profile",
|
||||
// url: "/profile",
|
||||
// icon: Icons.User,
|
||||
// items: [],
|
||||
// },
|
||||
// {
|
||||
// title: "Forms",
|
||||
// icon: Icons.Alphabet,
|
||||
// items: [
|
||||
// {
|
||||
// title: "Form Elements",
|
||||
// url: "/forms/form-elements",
|
||||
// },
|
||||
// {
|
||||
// title: "Form Layout",
|
||||
// url: "/forms/form-layout",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// title: "Tables",
|
||||
// url: "/tables",
|
||||
// icon: Icons.Table,
|
||||
// items: [
|
||||
// {
|
||||
// title: "Tables",
|
||||
// url: "/tables",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// title: "Pages",
|
||||
// icon: Icons.Alphabet,
|
||||
// items: [
|
||||
// {
|
||||
// title: "Settings",
|
||||
// url: "/pages/settings",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// label: "OTHERS",
|
||||
// items: [
|
||||
// {
|
||||
// title: "Charts",
|
||||
// icon: Icons.PieChart,
|
||||
// items: [
|
||||
// {
|
||||
// title: "Basic Chart",
|
||||
// url: "/charts/basic-chart",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// title: "UI Elements",
|
||||
// icon: Icons.FourCircle,
|
||||
// items: [
|
||||
// {
|
||||
// title: "Alerts",
|
||||
// url: "/ui-elements/alerts",
|
||||
// },
|
||||
// {
|
||||
// title: "Buttons",
|
||||
// url: "/ui-elements/buttons",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// title: "Authentication",
|
||||
// icon: Icons.Authentication,
|
||||
// items: [
|
||||
// {
|
||||
// title: "Sign In",
|
||||
// url: "/auth/sign-in",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
];
|
||||
|
||||
@@ -9,7 +9,6 @@ import { NAV_DATA, NavSubItem } from "./data";
|
||||
import { ArrowLeftIcon, ChevronUp } from "./icons";
|
||||
import { MenuItem } from "./menu-item";
|
||||
import { useSidebarContext } from "./sidebar-context";
|
||||
import Image from "next/image";
|
||||
|
||||
export function Sidebar() {
|
||||
const pathname = usePathname();
|
||||
@@ -17,35 +16,35 @@ export function Sidebar() {
|
||||
const [expandedItems, setExpandedItems] = useState<string[]>([]);
|
||||
|
||||
const toggleExpanded = (title: string) => {
|
||||
// setExpandedItems((prev) => (prev.includes(title) ? [] : [title]));
|
||||
|
||||
// Uncomment the following line to enable multiple expanded items
|
||||
setExpandedItems((prev) =>
|
||||
prev.includes(title) ? prev.filter((t) => t !== title) : [...prev, title],
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Keep collapsible open, when it's subpage is active
|
||||
NAV_DATA.some((section) => {
|
||||
return section.items.some((item) => {
|
||||
return item.items.some((subItem: NavSubItem) => {
|
||||
if (subItem.url === pathname) {
|
||||
if (!expandedItems.includes(item.title)) {
|
||||
toggleExpanded(item.title);
|
||||
}
|
||||
const newExpandedItems: string[] = [];
|
||||
|
||||
// Break the loop
|
||||
return true;
|
||||
NAV_DATA.forEach((section) => {
|
||||
section.items.forEach((item) => {
|
||||
if (item.items.length > 0) {
|
||||
const hasActiveSubItem = item.items.some(
|
||||
(subItem: NavSubItem) =>
|
||||
subItem.url === pathname ||
|
||||
(pathname.startsWith(subItem.url) && subItem.url !== "/"),
|
||||
);
|
||||
|
||||
if (hasActiveSubItem) {
|
||||
newExpandedItems.push(item.title);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}, [pathname, expandedItems]);
|
||||
|
||||
setExpandedItems(newExpandedItems);
|
||||
}, [pathname]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Mobile Overlay */}
|
||||
{isMobile && isOpen && (
|
||||
<div
|
||||
className="fixed inset-0 z-40 bg-black/50 transition-opacity duration-300"
|
||||
@@ -86,7 +85,6 @@ export function Sidebar() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Navigation */}
|
||||
<div className="custom-scrollbar mt-6 flex-1 overflow-y-auto pr-3 min-[850px]:mt-10">
|
||||
{NAV_DATA.map((section) => (
|
||||
<div key={section.label} className="mb-6">
|
||||
@@ -101,9 +99,17 @@ export function Sidebar() {
|
||||
{item.items.length ? (
|
||||
<div>
|
||||
<MenuItem
|
||||
isActive={item.items.some(
|
||||
({ url }: { url: string }) => url === pathname,
|
||||
)}
|
||||
isActive={
|
||||
item.items.some(
|
||||
({ url }: { url: string }) =>
|
||||
url === pathname,
|
||||
) ||
|
||||
(item.items.length > 0 &&
|
||||
item.items.some(
|
||||
({ url }: { url: string }) =>
|
||||
pathname.startsWith(url) && url !== "/",
|
||||
))
|
||||
}
|
||||
onClick={() => toggleExpanded(item.title)}
|
||||
>
|
||||
<item.icon
|
||||
@@ -133,7 +139,11 @@ export function Sidebar() {
|
||||
<MenuItem
|
||||
as="link"
|
||||
href={subItem.url}
|
||||
isActive={pathname === subItem.url}
|
||||
isActive={
|
||||
pathname === subItem.url ||
|
||||
(pathname.startsWith(subItem.url) &&
|
||||
subItem.url !== "/")
|
||||
}
|
||||
>
|
||||
<span>{subItem.title}</span>
|
||||
</MenuItem>
|
||||
@@ -150,12 +160,17 @@ export function Sidebar() {
|
||||
: "/" +
|
||||
item.title.toLowerCase().split(" ").join("-");
|
||||
|
||||
const isActive =
|
||||
href === "/"
|
||||
? pathname === href
|
||||
: pathname.startsWith(href);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
className="flex items-center gap-3 py-3"
|
||||
as="link"
|
||||
href={href}
|
||||
isActive={pathname === href}
|
||||
isActive={isActive}
|
||||
>
|
||||
<item.icon
|
||||
className="size-6 shrink-0"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { ExclamationIcon } from "@/assets/icons";
|
||||
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -9,10 +10,10 @@ import {
|
||||
TableHeader,
|
||||
} from "@/components/ui/table";
|
||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { unixToDate } from "@/utils/shared";
|
||||
import { TableRow } from "../../../ui/table";
|
||||
import useTenderFeedbackPresenter from "./useTenderFeedbackPresenter";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface IProps {
|
||||
id: string;
|
||||
@@ -22,7 +23,10 @@ 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">
|
||||
<ShowcaseSection
|
||||
title={!isLoading && `Tender: ${feedback?.[0].tender?.title}`}
|
||||
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>
|
||||
@@ -52,9 +56,7 @@ const TenderFeedbackTable = ({ id }: IProps) => {
|
||||
<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>
|
||||
@@ -76,7 +78,7 @@ const TenderFeedbackTable = ({ id }: IProps) => {
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</ShowcaseSection>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ const useTenderFeedbackPresenter = ({ id }: { id: string }) => {
|
||||
"row",
|
||||
"feedback type",
|
||||
"updated at",
|
||||
"tender name",
|
||||
|
||||
"created at",
|
||||
"actions",
|
||||
];
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import * as moment from "moment";
|
||||
export const unixToDate = (unix: number) => {
|
||||
return moment.unix(unix).format("YYYY/MM/DD");
|
||||
return moment.unix(unix).format("YYYY/MM/DD HH:MM");
|
||||
};
|
||||
export const msToDate = (ms: number) => {
|
||||
return moment.default(ms).format("YYYY/MM/DD");
|
||||
|
||||
Reference in New Issue
Block a user