get with slug
deploy to danak / build_and_deploy (push) Has been cancelled

This commit is contained in:
hamid zarghami
2026-06-01 10:04:05 +03:30
parent 42ce8fd892
commit 9d8dd549dc
4 changed files with 113 additions and 117 deletions
+19 -24
View File
@@ -1,16 +1,15 @@
import { type FC } from 'react'
import { useGetCatalog } from '../home/hooks/useHomeData'
import GridWrapper from '@/components/GridWrapper'
import CatalogueItem from './components/CatalogueItem'
import ButtonAddCatalogue from './components/ButtonAddCatalogue'
import GridWrapper from "@/components/GridWrapper";
import { type FC } from "react";
import { useGetCatalog } from "../home/hooks/useHomeData";
import ButtonAddCatalogue from "./components/ButtonAddCatalogue";
import CatalogueItem from "./components/CatalogueItem";
const CatalogueList: FC = () => {
const { data, refetch } = useGetCatalog();
const { data, refetch } = useGetCatalog()
return (
<div className='w-full mt-5'>
{/* {
return (
<div className="w-full mt-5">
{/* {
!isPending && !data?.data?.length &&
<div className='flex flex-col items-center gap-5'>
<div className='text-gray-500'>
@@ -24,18 +23,14 @@ const CatalogueList: FC = () => {
</Link>
</div>
} */}
<GridWrapper desktop={4} gapDesktop={40} mobile={1}>
{
data?.data?.map((item) => {
return (
<CatalogueItem refetch={refetch} key={item.id} item={item} />
)
})
}
<ButtonAddCatalogue isFirst={data?.data?.length === 0} />
</GridWrapper>
</div>
)
}
<GridWrapper desktop={4} gapDesktop={40} mobile={1}>
{data?.data?.map((item) => {
return <CatalogueItem refetch={refetch} key={item.id} item={item} />;
})}
<ButtonAddCatalogue isFirst={data?.data?.length === 0} />
</GridWrapper>
</div>
);
};
export default CatalogueList
export default CatalogueList;
@@ -1,103 +1,103 @@
import { type FC } from 'react'
import { Edit, Eye, Share } from 'iconsax-react'
import type { CatalogItemType } from '../types/Types'
import moment from 'moment-jalaali'
import { Link } from 'react-router-dom'
import { Paths } from '@/config/Paths'
import CatalogPreview from './CatalogPreview'
import TrashWithConfrim from '@/components/TrashWithConfrim'
import { useDleteCatalog } from '@/pages/home/hooks/useHomeData'
import { toast } from '@/components/Toast'
import { extractErrorMessage } from '@/helpers/utils'
import { requestViewerFullscreen } from '@/pages/viewer/utils/viewerFullscreen'
import { toast } from "@/components/Toast";
import TrashWithConfrim from "@/components/TrashWithConfrim";
import { Paths } from "@/config/Paths";
import { extractErrorMessage } from "@/helpers/utils";
import { useDleteCatalog } from "@/pages/home/hooks/useHomeData";
import { requestViewerFullscreen } from "@/pages/viewer/utils/viewerFullscreen";
import { Edit, Eye, Share } from "iconsax-react";
import moment from "moment-jalaali";
import { type FC } from "react";
import { Link } from "react-router-dom";
import type { CatalogItemType } from "../types/Types";
import CatalogPreview from "./CatalogPreview";
type Props = {
item: CatalogItemType,
refetch: () => void,
}
item: CatalogItemType;
refetch: () => void;
};
const CatalogueItem: FC<Props> = ({ item, refetch }) => {
const deleteCatalog = useDleteCatalog();
const deleteCatalog = useDleteCatalog()
const shareUrl = `${window.location.origin}${Paths.viewer}/${item.id}`;
const shareUrl = `${window.location.origin}${Paths.viewer}/${item.id}`
const handleShare = async () => {
try {
if (typeof navigator.share === 'function') {
await navigator.share({
title: item.name,
text: item.name,
url: shareUrl,
})
return
}
await navigator.clipboard.writeText(shareUrl)
toast('لینک در کلیپ‌بورد کپی شد', 'success')
} catch (err) {
const isAbort =
err instanceof DOMException
? err.name === 'AbortError'
: err instanceof Error && err.name === 'AbortError'
if (isAbort) return
toast(extractErrorMessage(err, 'امکان اشتراک‌گذاری وجود ندارد'), 'error')
}
const handleShare = async () => {
try {
if (typeof navigator.share === "function") {
await navigator.share({
title: item.name,
text: item.name,
url: shareUrl,
});
return;
}
await navigator.clipboard.writeText(shareUrl);
toast("لینک در کلیپ‌بورد کپی شد", "success");
} catch (err) {
const isAbort =
err instanceof DOMException
? err.name === "AbortError"
: err instanceof Error && err.name === "AbortError";
if (isAbort) return;
toast(extractErrorMessage(err, "امکان اشتراک‌گذاری وجود ندارد"), "error");
}
};
const handleDelete = () => {
deleteCatalog.mutate(item.id, {
onSuccess: () => {
toast('با موفقیت حذف شد', 'success')
refetch()
},
onError: (error) => {
toast(extractErrorMessage(error, 'error'))
}
})
}
const handleDelete = () => {
deleteCatalog.mutate(item.id, {
onSuccess: () => {
toast("با موفقیت حذف شد", "success");
refetch();
},
onError: (error) => {
toast(extractErrorMessage(error, "error"));
},
});
};
return (
<div className='bg-white p-6 rounded-3xl w-full'>
<div className='flex gap-4 items-center'>
<CatalogPreview item={item} />
<div>
<h6>
{item.name}
</h6>
<div className='mt-2 text-[#999999] text-xs'>
{moment(item.createdAt).format('jYYYY/jMM/jDD')}
</div>
</div>
</div>
<div className='flex justify-end gap-1 items-center mt-1'>
<Link to={Paths.viewer + `/${item.id}`} onClick={requestViewerFullscreen}>
<div className='size-6 bg-[#EAECF4] rounded-md flex justify-center items-center'>
<Eye size={18} color='#0047FF' />
</div>
</Link>
<Link to={Paths.editor + `/${item.id}`}>
<div className='size-6 bg-[#EAECF4] rounded-md flex justify-center items-center'>
<Edit size={18} color='#0047FF' />
</div>
</Link>
<button
type='button'
onClick={handleShare}
className='size-6 bg-[#EAECF4] rounded-md flex justify-center items-center border-0 p-0 cursor-pointer shrink-0'
aria-label='اشتراک‌گذاری'
>
<Share size={18} color='#000' />
</button>
<div className='size-6 bg-[#EAECF4] rounded-md flex justify-center items-center'>
<TrashWithConfrim
onDelete={handleDelete}
colorIcon='red'
isloading={deleteCatalog.isPending}
/>
</div>
</div>
return (
<div className="bg-white p-6 rounded-3xl w-full">
<div className="flex gap-4 items-center">
<CatalogPreview item={item} />
<div>
<h6>{item.name}</h6>
<div className="mt-2 text-[#999999] text-xs">
{moment(item.createdAt).format("jYYYY/jMM/jDD")}
</div>
</div>
)
}
</div>
<div className="flex justify-end gap-1 items-center mt-1">
<Link
to={Paths.viewer + `/${item.slug}`}
onClick={requestViewerFullscreen}
>
<div className="size-6 bg-[#EAECF4] rounded-md flex justify-center items-center">
<Eye size={18} color="#0047FF" />
</div>
</Link>
<Link to={Paths.editor + `/${item.slug}`}>
<div className="size-6 bg-[#EAECF4] rounded-md flex justify-center items-center">
<Edit size={18} color="#0047FF" />
</div>
</Link>
<button
type="button"
onClick={handleShare}
className="size-6 bg-[#EAECF4] rounded-md flex justify-center items-center border-0 p-0 cursor-pointer shrink-0"
aria-label="اشتراک‌گذاری"
>
<Share size={18} color="#000" />
</button>
<div className="size-6 bg-[#EAECF4] rounded-md flex justify-center items-center">
<TrashWithConfrim
onDelete={handleDelete}
colorIcon="red"
isloading={deleteCatalog.isPending}
/>
</div>
</div>
</div>
);
};
export default CatalogueItem
export default CatalogueItem;
+1
View File
@@ -7,6 +7,7 @@ export type CatalogItemType = {
size: string;
status: string;
createdAt: string;
slug: string;
};
export type CatalogResponseType = BaseResponse<CatalogItemType[]>;
+1 -1
View File
@@ -20,7 +20,7 @@ export const getCatalogs = async () => {
export const getCatalogById = async (id: string) => {
const { data } = await axios.get<CatalogByIdResponseType>(
`/public/catalogue/${id}`,
`/public/catalogue/slug/${id}`,
);
return data;
};