fix:pagination shopw author name
This commit is contained in:
@@ -13,32 +13,40 @@ const Pagination: React.FC<PaginationProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const getPageNumbers = () => {
|
const getPageNumbers = () => {
|
||||||
const pageNumbers: (number | string)[] = [];
|
const pageNumbers: (number | string)[] = [];
|
||||||
const maxVisiblePages = 5; // تعداد حداکثری صفحات قابل مشاهده
|
const maxVisiblePages = 5;
|
||||||
|
|
||||||
if (totalPages <= maxVisiblePages) {
|
if (totalPages <= maxVisiblePages) {
|
||||||
|
// اگر تعداد صفحات کم است، همه را نشان بده
|
||||||
for (let i = 1; i <= totalPages; i++) {
|
for (let i = 1; i <= totalPages; i++) {
|
||||||
pageNumbers.push(i);
|
pageNumbers.push(i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (currentPage > 3) {
|
// همیشه صفحه اول را نشان بده
|
||||||
pageNumbers.push(1);
|
pageNumbers.push(1);
|
||||||
if (currentPage > 4) {
|
|
||||||
pageNumbers.push("...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const start = Math.max(2, currentPage - 1);
|
if (currentPage <= 3) {
|
||||||
const end = Math.min(totalPages - 1, currentPage + 1);
|
// در صفحات اولیه (1, 2, 3)
|
||||||
|
for (let i = 2; i <= Math.min(4, totalPages - 1); i++) {
|
||||||
for (let i = start; i <= end; i++) {
|
|
||||||
pageNumbers.push(i);
|
pageNumbers.push(i);
|
||||||
}
|
}
|
||||||
|
if (totalPages > 5) {
|
||||||
if (currentPage < totalPages - 2) {
|
|
||||||
if (currentPage < totalPages - 3) {
|
|
||||||
pageNumbers.push("...");
|
pageNumbers.push("...");
|
||||||
}
|
}
|
||||||
pageNumbers.push(totalPages);
|
pageNumbers.push(totalPages);
|
||||||
|
} else if (currentPage >= totalPages - 2) {
|
||||||
|
// در صفحات آخر
|
||||||
|
pageNumbers.push("...");
|
||||||
|
for (let i = totalPages - 3; i <= totalPages; i++) {
|
||||||
|
pageNumbers.push(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// در صفحات وسط
|
||||||
|
pageNumbers.push("...");
|
||||||
|
for (let i = currentPage - 1; i <= currentPage + 1; i++) {
|
||||||
|
pageNumbers.push(i);
|
||||||
|
}
|
||||||
|
pageNumbers.push("...");
|
||||||
|
pageNumbers.push(totalPages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +56,7 @@ const Pagination: React.FC<PaginationProps> = ({
|
|||||||
const pageNumbers = getPageNumbers();
|
const pageNumbers = getPageNumbers();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex gap-2 text-xs justify-center items-center space-x-2 mt-4">
|
<div className="flex gap-2 text-xs justify-center items-center mt-4">
|
||||||
{/* دکمه قبلی */}
|
{/* دکمه قبلی */}
|
||||||
{/* <button
|
{/* <button
|
||||||
className={`px-3 py-1 rounded-md ${currentPage === 1
|
className={`px-3 py-1 rounded-md ${currentPage === 1
|
||||||
@@ -65,7 +73,7 @@ const Pagination: React.FC<PaginationProps> = ({
|
|||||||
{pageNumbers.map((page, index) =>
|
{pageNumbers.map((page, index) =>
|
||||||
typeof page === "number" ? (
|
typeof page === "number" ? (
|
||||||
<button
|
<button
|
||||||
key={index}
|
key={`page-${page}`}
|
||||||
className={`size-8 rounded-md ${currentPage === page
|
className={`size-8 rounded-md ${currentPage === page
|
||||||
? "bg-primary text-white"
|
? "bg-primary text-white"
|
||||||
: "text-primary bg-[#EAECF5] hover:bg-gray-100"
|
: "text-primary bg-[#EAECF5] hover:bg-gray-100"
|
||||||
@@ -75,7 +83,7 @@ const Pagination: React.FC<PaginationProps> = ({
|
|||||||
{page}
|
{page}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<span key={index} className="px-3 py-1 text-gray-500">
|
<span key={`ellipsis-${index}`} className="px-3 py-1 text-gray-500">
|
||||||
{page}
|
{page}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ interface QuillEditorProps {
|
|||||||
className?: string
|
className?: string
|
||||||
minHeight?: string
|
minHeight?: string
|
||||||
id?: string
|
id?: string
|
||||||
|
defaultAltText?: string // عنوان مقاله یا متن پیشفرض برای alt
|
||||||
}
|
}
|
||||||
|
|
||||||
const QuillEditor: FC<QuillEditorProps> = ({
|
const QuillEditor: FC<QuillEditorProps> = ({
|
||||||
@@ -21,7 +22,8 @@ const QuillEditor: FC<QuillEditorProps> = ({
|
|||||||
placeholder = '',
|
placeholder = '',
|
||||||
className = '',
|
className = '',
|
||||||
minHeight = '200px',
|
minHeight = '200px',
|
||||||
id = 'quill-editor'
|
id = 'quill-editor',
|
||||||
|
defaultAltText = 'تصویر'
|
||||||
}) => {
|
}) => {
|
||||||
const editorRef = useRef<HTMLDivElement>(null)
|
const editorRef = useRef<HTMLDivElement>(null)
|
||||||
const quillRef = useRef<Quill | null>(null)
|
const quillRef = useRef<Quill | null>(null)
|
||||||
@@ -29,10 +31,56 @@ const QuillEditor: FC<QuillEditorProps> = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!editorRef.current) return
|
if (!editorRef.current) return
|
||||||
|
|
||||||
|
// تابع سفارشی برای مدیریت آپلود تصویر
|
||||||
|
const imageHandler = () => {
|
||||||
|
const input = document.createElement('input')
|
||||||
|
input.setAttribute('type', 'file')
|
||||||
|
input.setAttribute('accept', 'image/*')
|
||||||
|
input.click()
|
||||||
|
|
||||||
|
input.onchange = async () => {
|
||||||
|
const file = input.files?.[0]
|
||||||
|
if (file && quillRef.current) {
|
||||||
|
// درخواست alt text از کاربر
|
||||||
|
const altText = prompt('متن جایگزین (Alt Text) تصویر را وارد کنید:', defaultAltText)
|
||||||
|
|
||||||
|
if (altText !== null) { // اگر کاربر Cancel نکرد
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = (e) => {
|
||||||
|
const imageUrl = e.target?.result as string
|
||||||
|
const range = quillRef.current?.getSelection(true)
|
||||||
|
|
||||||
|
if (range && quillRef.current) {
|
||||||
|
// درج تصویر
|
||||||
|
quillRef.current.insertEmbed(range.index, 'image', imageUrl)
|
||||||
|
|
||||||
|
// اضافه کردن alt text به تصویر
|
||||||
|
setTimeout(() => {
|
||||||
|
const images = quillRef.current?.root.querySelectorAll('img')
|
||||||
|
if (images && images.length > 0) {
|
||||||
|
const lastImage = images[images.length - 1]
|
||||||
|
lastImage.setAttribute('alt', altText || defaultAltText)
|
||||||
|
}
|
||||||
|
|
||||||
|
// فراخوانی onChange برای ذخیره تغییرات
|
||||||
|
if (quillRef.current) {
|
||||||
|
onChange?.(quillRef.current.root.innerHTML)
|
||||||
|
}
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
quillRef.current.setSelection(range.index + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// پیکربندی toolbar سفارشی
|
// پیکربندی toolbar سفارشی
|
||||||
const toolbarOptions = [
|
const toolbarOptions = [
|
||||||
['bold', 'italic', 'underline'],
|
['bold', 'italic', 'underline'],
|
||||||
[{ 'header': 1 }, { 'header': 2 }],
|
[{ 'header': 1 }, { 'header': 2 }, { 'header': 3 }],
|
||||||
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
||||||
[{ 'direction': 'rtl' }],
|
[{ 'direction': 'rtl' }],
|
||||||
[{ 'color': [] }, { 'background': [] }],
|
[{ 'color': [] }, { 'background': [] }],
|
||||||
@@ -45,7 +93,12 @@ const QuillEditor: FC<QuillEditorProps> = ({
|
|||||||
theme: 'snow',
|
theme: 'snow',
|
||||||
placeholder,
|
placeholder,
|
||||||
modules: {
|
modules: {
|
||||||
toolbar: toolbarOptions
|
toolbar: {
|
||||||
|
container: toolbarOptions,
|
||||||
|
handlers: {
|
||||||
|
image: imageHandler
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -65,7 +118,7 @@ const QuillEditor: FC<QuillEditorProps> = ({
|
|||||||
return () => {
|
return () => {
|
||||||
quillRef.current = null
|
quillRef.current = null
|
||||||
}
|
}
|
||||||
}, [placeholder])
|
}, [placeholder, defaultAltText])
|
||||||
|
|
||||||
// بروزرسانی محتوا از خارج
|
// بروزرسانی محتوا از خارج
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
+2
-1
@@ -443,7 +443,8 @@
|
|||||||
"comments": "نظرات",
|
"comments": "نظرات",
|
||||||
"user": "کاربر",
|
"user": "کاربر",
|
||||||
"comment": "نظر",
|
"comment": "نظر",
|
||||||
"picture": "تصویر"
|
"picture": "تصویر",
|
||||||
|
"author": "نویسنده"
|
||||||
},
|
},
|
||||||
"receip": {
|
"receip": {
|
||||||
"receips": "صورتحساب ها",
|
"receips": "صورتحساب ها",
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ const BlogList: FC = () => {
|
|||||||
<thead className='thead'>
|
<thead className='thead'>
|
||||||
<tr>
|
<tr>
|
||||||
<Td text={t('blog.picture')} />
|
<Td text={t('blog.picture')} />
|
||||||
|
<Td text={t('blog.author')} />
|
||||||
<Td text={t('blog.blog_title')} />
|
<Td text={t('blog.blog_title')} />
|
||||||
<Td text={t('blog.blog_summary')} />
|
<Td text={t('blog.blog_summary')} />
|
||||||
<Td text={t('blog.category')} />
|
<Td text={t('blog.category')} />
|
||||||
@@ -119,6 +120,9 @@ const BlogList: FC = () => {
|
|||||||
<Td text={''}>
|
<Td text={''}>
|
||||||
<img src={item.imageUrl} alt={item.title} className='w-20 rounded-lg' />
|
<img src={item.imageUrl} alt={item.title} className='w-20 rounded-lg' />
|
||||||
</Td>
|
</Td>
|
||||||
|
<Td text={''}>
|
||||||
|
<p className='max-w-[150px] truncate'>{item.author.firstName} {item.author.lastName}</p>
|
||||||
|
</Td>
|
||||||
<Td text={''}>
|
<Td text={''}>
|
||||||
<p className='max-w-[150px] truncate'>{item.title}</p>
|
<p className='max-w-[150px] truncate'>{item.title}</p>
|
||||||
</Td>
|
</Td>
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ const CreateBlog: FC = () => {
|
|||||||
onChange={(content) => formik.setFieldValue('previewContent', content)}
|
onChange={(content) => formik.setFieldValue('previewContent', content)}
|
||||||
placeholder={t('blog.enter_blog_summary')}
|
placeholder={t('blog.enter_blog_summary')}
|
||||||
minHeight="120px"
|
minHeight="120px"
|
||||||
|
defaultAltText={formik.values.title || 'تصویر'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -164,6 +165,7 @@ const CreateBlog: FC = () => {
|
|||||||
onChange={(content) => formik.setFieldValue('content', content)}
|
onChange={(content) => formik.setFieldValue('content', content)}
|
||||||
placeholder={t('blog.enter_blog_content')}
|
placeholder={t('blog.enter_blog_content')}
|
||||||
minHeight="200px"
|
minHeight="200px"
|
||||||
|
defaultAltText={formik.values.title || 'تصویر'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ const UpdateBlog: FC = () => {
|
|||||||
onChange={(content) => formik.setFieldValue('previewContent', content)}
|
onChange={(content) => formik.setFieldValue('previewContent', content)}
|
||||||
placeholder={t('blog.enter_blog_summary')}
|
placeholder={t('blog.enter_blog_summary')}
|
||||||
minHeight="120px"
|
minHeight="120px"
|
||||||
|
defaultAltText={formik.values.title || 'تصویر'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -172,6 +173,7 @@ const UpdateBlog: FC = () => {
|
|||||||
onChange={(content) => formik.setFieldValue('content', content)}
|
onChange={(content) => formik.setFieldValue('content', content)}
|
||||||
placeholder={t('blog.enter_blog_content')}
|
placeholder={t('blog.enter_blog_content')}
|
||||||
minHeight="200px"
|
minHeight="200px"
|
||||||
|
defaultAltText={formik.values.title || 'تصویر'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user