annoncement

This commit is contained in:
hamid zarghami
2025-01-30 11:21:49 +03:30
parent bc39fd5042
commit dcc5857048
5 changed files with 148 additions and 109 deletions
+1
View File
@@ -3,6 +3,7 @@ import { BrowserRouter } from 'react-router-dom'
import 'swiper/swiper-bundle.css'; import 'swiper/swiper-bundle.css';
import 'rc-rate/assets/index.css'; import 'rc-rate/assets/index.css';
import "quill/dist/quill.snow.css"; import "quill/dist/quill.snow.css";
import "react-multi-date-picker/styles/layouts/mobile.css"
import i18next from 'i18next' import i18next from 'i18next'
import { I18nextProvider } from 'react-i18next' import { I18nextProvider } from 'react-i18next'
import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query' import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'
+1 -1
View File
@@ -62,7 +62,7 @@ const DatePickerComponent: FC<Props> = (props: Props) => {
calendar={persian} calendar={persian}
locale={persian_fa} locale={persian_fa}
calendarPosition="bottom-right" calendarPosition="bottom-right"
className={props.className} className={`rmdp-mobile ${props.className}`}
/> />
{props.error_text && props.error_text !== '' && ( {props.error_text && props.error_text !== '' && (
<div className="text-xs text-right text-red-600 mt-2 mr-2 font-medium"> <div className="text-xs text-right text-red-600 mt-2 mr-2 font-medium">
+16 -7
View File
@@ -32,16 +32,25 @@ const AnnouncementDetail: FC = () => {
<div className='flex-1 mt-4 bg-white py-6 px-4 rounded-2xl'> <div className='flex-1 mt-4 bg-white py-6 px-4 rounded-2xl'>
<div className='flex justify-between items-start'> <div className='flex justify-between items-start'>
<div className='text-sm max-w-[70%] leading-67'> <div className='text-sm max-w-[70%] leading-67'>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ {getDetail.data?.data?.announcement?.title}
</div>
<div className='flex gap-1'>
{
getDetail.data?.data?.announcement.isImportant &&
<StatusWithText
variant='error'
text={t('announcement.important')}
/>
}
<StatusWithText
variant='success'
text={t('announcement.new')}
/>
</div> </div>
<StatusWithText
variant='success'
text={t('announcement.new')}
/>
</div> </div>
<div className='mt-5 leading-7 text-xs font-light'> <div dangerouslySetInnerHTML={{ __html: getDetail.data?.data?.announcement?.content }} className='mt-5 leading-7 text-xs font-light'>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.
</div> </div>
</div> </div>
} }
+127 -100
View File
@@ -1,9 +1,9 @@
import { FC, useState } from 'react' import { FC, Fragment, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import Input from '../../components/Input' import Input from '../../components/Input'
import StatusWithText from '../../components/StatusWithText' import StatusWithText from '../../components/StatusWithText'
import { clx } from '../../helpers/utils' import { clx } from '../../helpers/utils'
import { useNavigate } from 'react-router-dom' import { Link, useNavigate } from 'react-router-dom'
import { Pages } from '../../config/Pages' import { Pages } from '../../config/Pages'
import { useGetAnnoncements } from './hooks/useAnnoncementData' import { useGetAnnoncements } from './hooks/useAnnoncementData'
import PageLoading from '../../components/PageLoading' import PageLoading from '../../components/PageLoading'
@@ -11,6 +11,8 @@ import { AnnoncementItemType } from './types/AnnoncementTypes'
import moment from 'moment-jalaali' import moment from 'moment-jalaali'
import Pagination from '../../components/Pagination' import Pagination from '../../components/Pagination'
import DatePickerComponent from '../../components/DatePicker' import DatePickerComponent from '../../components/DatePicker'
import Button from '../../components/Button'
import { Add } from 'iconsax-react'
const AnnouncementtList: FC = () => { const AnnouncementtList: FC = () => {
@@ -32,116 +34,141 @@ const AnnouncementtList: FC = () => {
return ( return (
<div className='mt-4 text-sm'> <div className='mt-4 text-sm'>
<div className='text-base'>
{t('announcement.announcements')} <div className='flex w-full justify-between items-center'>
<div>
{t('announcement.announcements')}
</div>
<div>
<Link to={Pages.announcement.create}>
<Button
className='px-5'
>
<div className='flex gap-2'>
<Add
className='size-5'
color='#fff'
/>
<div>{t('announcement.add_announcement')}</div>
</div>
</Button>
</Link>
</div>
</div> </div>
{
getAnnoncements.isPending ?
<PageLoading />
:
<div className='mt-10 flex gap-8'>
<div className='bg-white xl:w-[400px] w-full rounded-2xl p-6'>
<div className='flex gap-3 items-center'>
<div className='flex-1'>
<Input
variant='search'
placeholder={t('announcement.search')}
className='-mt-1'
onChangeSearchFinal={(value) => setSearch(value)}
/>
</div>
<div> <div className='mt-10 flex gap-8'>
<DatePickerComponent <div className='bg-white xl:w-[400px] w-full rounded-2xl p-6'>
onChange={(d) => setSince(d)} <div className='flex gap-3 items-center'>
placeholder={t('announcement.date_created')} <div className='flex-1'>
/> <Input
</div> // value={search}
</div> variant='search'
placeholder={t('announcement.search')}
<div className='mt-8'> className='-mt-1'
{ onChangeSearchFinal={(value) => setSearch(value)}
getAnnoncements.data?.data?.announcements?.map((item: AnnoncementItemType) => { />
return (
<div key={item.id} onClick={() => handleChange(item)} className={clx(
'p-4 rounded-2xl cursor-pointer',
openItem?.id === item.id && 'bg-[#F5F6FA]'
)}>
<div className='flex justify-between'>
<div className='leading-6 text-xs xl:text-sm max-w-[70%]'>
{item.title}
</div>
<div className='flex gap-1'>
{
item.isImportant &&
<StatusWithText
variant='error'
text={t('announcement.important')}
/>
}
<StatusWithText
variant='success'
text={t('announcement.new')}
/>
</div>
</div>
<div className='m-2 flex justify-between items-center text-[11px]'>
<div dangerouslySetInnerHTML={{ __html: item.content }} className='max-w-[70%] truncate '>
</div>
<div className='text-description'>
{moment(item.publishAt, 'jYYYY-jMM-jDD').format('jYYYY/jMM/jDD')}
</div>
</div>
</div>
)
})
}
<div className='flex justify-end'>
<Pagination
currentPage={page}
onPageChange={setPage}
totalPages={getAnnoncements.data?.data?.pager?.totalPages}
/>
</div>
</div>
</div> </div>
{ <div>
openItem && <DatePickerComponent
<div className='flex-1 hidden xl:block bg-white py-7 px-5 rounded-2xl'> onChange={(d) => setSince(d)}
<div className='flex justify-between items-center'> placeholder={t('announcement.date_created')}
<div className='text-lg'> />
متن اطلاعیه </div>
</div> </div>
<div className='flex gap-2'>
{ {
openItem.isImportant && getAnnoncements.isPending ?
<StatusWithText <PageLoading />
variant='error' :
text={t('announcement.important')} <Fragment>
/> <div className='mt-8'>
} {
<StatusWithText getAnnoncements.data?.data?.announcements?.map((item: AnnoncementItemType) => {
variant='success' return (
text={t('announcement.new')} <div key={item.id} onClick={() => handleChange(item)} className={clx(
'p-4 rounded-2xl cursor-pointer',
openItem?.id === item.id && 'bg-[#F5F6FA]'
)}>
<div className='flex justify-between'>
<div className='leading-6 text-xs xl:text-sm max-w-[70%]'>
{item.title}
</div>
<div className='flex gap-1'>
{
item.isImportant &&
<StatusWithText
variant='error'
text={t('announcement.important')}
/>
}
<StatusWithText
variant='success'
text={t('announcement.new')}
/>
</div>
</div>
<div className='m-2 flex justify-between items-center text-[11px]'>
<div dangerouslySetInnerHTML={{ __html: item.content }} className='max-w-[70%] truncate '>
</div>
<div className='text-description'>
{moment(item.publishAt).format('jYYYY/jMM/jDD')}
</div>
</div>
</div>
)
})
}
<div className='flex justify-end'>
<Pagination
currentPage={page}
onPageChange={setPage}
totalPages={getAnnoncements.data?.data?.pager?.totalPages}
/> />
</div> </div>
</div> </div>
</Fragment>
}
<div className='mt-8'>
{openItem.title}
</div>
<div dangerouslySetInnerHTML={{ __html: openItem.content }} className='mt-5 leading-7 text-xs font-light'> </div>
</div>
{
openItem &&
<div className='flex-1 hidden xl:block bg-white py-7 px-5 rounded-2xl'>
<div className='flex justify-between items-center'>
<div className='text-lg'>
متن اطلاعیه
</div> </div>
} <div className='flex gap-2'>
{
openItem.isImportant &&
<StatusWithText
variant='error'
text={t('announcement.important')}
/>
}
<StatusWithText
variant='success'
text={t('announcement.new')}
/>
</div>
</div>
<div className='mt-8'>
{openItem.title}
</div>
<div dangerouslySetInnerHTML={{ __html: openItem.content }} className='mt-5 leading-7 text-xs font-light'>
</div>
</div> </div>
} }
</div>
</div> </div>
) )
@@ -1,3 +1,4 @@
import moment from "moment-jalaali";
import axios from "../../../config/axios"; import axios from "../../../config/axios";
import { CreateAnnouncementType } from "../../types/AnnouncementTypes"; import { CreateAnnouncementType } from "../../types/AnnouncementTypes";
@@ -13,7 +14,8 @@ export const getAnnoncements = async (
) => { ) => {
let query = `?page=${page}`; let query = `?page=${page}`;
if (search) query += `&q=${search}`; if (search) query += `&q=${search}`;
if (since) query += `&since=${since}`; if (since)
query += `&since=${moment(since, "jYYYY-jMM-jDD").format("YYYY-MM-DD")}`;
const { data } = await axios.get(`/announcements${query}`); const { data } = await axios.get(`/announcements${query}`);
return data; return data;