Commit e83b5a22 authored by Phạm Quang Bảo's avatar Phạm Quang Bảo

update/add event into page

parent c2d14537
export type EventStatus = {
id: string;
name: string;
name_en: string;
code: string;
};
export type EventOrganization = {
id: string;
organization_id: string | null;
event_id: string;
status: string | null;
created_at: string;
updated_at: string | null;
created_by: string;
updated_by: string | null;
role: string;
guest_name: string;
guest_image: string;
org_table_count: number | null;
org_counter_count: number | null;
add_info: unknown | null;
organization: unknown | null;
};
export type EventItem = {
id: string;
name: string;
start_time: string;
end_time: string;
created_at: string;
created_by: string;
updated_at: string | null;
updated_by: string | null;
status: string;
image: string;
description: string;
location: string;
province: string;
table_count: number;
counter_count: number;
seo_text: string;
seo_text_en: string | null;
table_cost: number;
counter_cost: number;
table_min_pick: number | null;
counter_min_pick: number | null;
table_max_pick: number | null;
counter_max_pick: number | null;
org_support_titles: string[];
accept_entries: boolean;
type: string;
introduction: string;
host_club: string | null;
config: unknown | null;
event_organizations: EventOrganization[];
status_status: EventStatus;
};
export type EventResponseData = {
count: number;
rows: EventItem[];
totalPages: number;
currentPage: number;
};
export type EventApiResponse = {
message: string;
message_en: string;
responseData: EventResponseData;
status: string;
timeStamp: string;
violations: null | unknown;
};
\ No newline at end of file
import { EventItem } from '@/api/types/event'
import BASE_URL from '@/links'
import dayjs from 'dayjs';
import AppEditorContent from '@/components/shared/editor-content';
function CardEvent({ event }: { event: EventItem }) {
return (
<a
href={`${event.id}`}
className='flex flex-row gap-2 mb-2 sm:gap-3 sm:mb-3 p-2 sm:p-3 border border-gray-200 bg-white rounded-md'
>
<img
src={`${BASE_URL.imageEndpoint}${event.image}`}
alt={event.name}
className='w-[100px] md:w-[130px] aspect-3/2 object-cover'
/>
<div className='flex-1'>
<p className='text-[#0056b3] font-bold text-sm line-clamp-2'>
{event.name}
</p>
<p className='text-gray-500 text-sm my-1'>
{dayjs(event.start_time).format('DD/MM/YYYY')}
</p>
{/* <AppEditorContent className='line-clamp-2' value={event.description} /> */}
</div>
</a>
);
}
export default CardEvent;
\ No newline at end of file
...@@ -9,31 +9,32 @@ import 'swiper/css' ...@@ -9,31 +9,32 @@ import 'swiper/css'
import 'swiper/css/navigation' import 'swiper/css/navigation'
import 'swiper/css/pagination' import 'swiper/css/pagination'
import BASE_URL from '@/links/index' import BASE_URL from '@/links/index'
import NewsContent from './components/card-news'
import { Spinner } from '@/components/ui' import { Spinner } from '@/components/ui'
import CardNews from './components/card-news'
import CardEvent from './components/card-event'
import EventCalendar from './components/event-calendar'
import dayjs from 'dayjs'
import AppEditorContent from '@/components/shared/editor-content'
// server
import { useGetEvents } from '@/api/endpoints/event'
import { useGetCategory } from '@/api/endpoints/category' import { useGetCategory } from '@/api/endpoints/category'
import { useGetNews } from '@/api/endpoints/news' import { useGetNews } from '@/api/endpoints/news'
import { GetCategoryAdminResponseType } from '@/api/types/category' import { GetCategoryAdminResponseType } from '@/api/types/category'
import { GetNewsAdminResponseType, NewsAdminItem } from '@/api/types/news' import { GetNewsAdminResponseType, NewsAdminItem } from '@/api/types/news'
import EventCalendar from './components/event-calendar' import { EventApiResponse, EventItem } from '@/api/types/event'
import dayjs from 'dayjs'
import AppEditorContent from '@/components/shared/editor-content'
const Page = () => { const Page = () => {
const [tab, setTab] = useState('all') const [tab, setTab] = useState('all')
const [search, setSearch] = useState('')
const [submitSearch, setSubmitSearch] = useState('')
const [currentIndex, setCurrentIndex] = useState(0) const [currentIndex, setCurrentIndex] = useState(0)
const [slidesPerView, setSlidesPerView] = useState<number>(3)
const swiperRef = useRef<SwiperType | null>(null) const swiperRef = useRef<SwiperType | null>(null)
const { data: categoryData } = useGetCategory<GetCategoryAdminResponseType>() const { data: categoryData, isLoading: isLoadingCategory } = useGetCategory<GetCategoryAdminResponseType>()
const { data: allData, isLoading } = useGetNews<GetNewsAdminResponseType>({ const { data: newsData, isLoading: isLoadingNews } = useGetNews<GetNewsAdminResponseType>()
pageSize: '999', const { data: eventData, isLoading: isLoadingEvent } = useGetEvents<EventApiResponse>()
filters: submitSearch ? `title @=${submitSearch}` : undefined,
})
const rows = allData?.responseData?.rows ?? [] // filter category
const rows = newsData?.responseData?.rows ?? []
const filteredRows = tab === 'all' ? rows : rows.filter((n) => n.category === tab) const filteredRows = tab === 'all' ? rows : rows.filter((n) => n.category === tab)
const images = [ const images = [
...@@ -66,19 +67,7 @@ const Page = () => { ...@@ -66,19 +67,7 @@ const Page = () => {
'/home/hoi-vien-tieu-bieu/UOB-logo_Vuong.jpeg.webp', '/home/hoi-vien-tieu-bieu/UOB-logo_Vuong.jpeg.webp',
] ]
useEffect(() => { if (isLoadingNews || isLoadingCategory || isLoadingEvent)
const getSlides = (w: number) => {
if (w >= 1024) return 3
if (w >= 640) return 2
return 1
}
const update = () => setSlidesPerView(getSlides(window.innerWidth))
update()
window.addEventListener('resize', update)
return () => window.removeEventListener('resize', update)
}, [])
if (isLoading)
return ( return (
<div className="w-full h-[80vh] flex justify-center items-center"> <div className="w-full h-[80vh] flex justify-center items-center">
<Spinner /> <Spinner />
...@@ -178,7 +167,7 @@ const Page = () => { ...@@ -178,7 +167,7 @@ const Page = () => {
<hr className="border-blue-900 mb-4" /> <hr className="border-blue-900 mb-4" />
<div className="flex flex-col md:flex-row gap-5"> <div className="flex flex-col md:flex-row gap-5">
{allData?.responseData.rows.slice(0, 1).map((news: NewsAdminItem) => ( {newsData?.responseData.rows.slice(0, 1).map((news: NewsAdminItem) => (
<a <a
key={news.id} key={news.id}
href={`${news.id}`} href={`${news.id}`}
...@@ -230,7 +219,7 @@ const Page = () => { ...@@ -230,7 +219,7 @@ const Page = () => {
</div> </div>
{filteredRows.slice(0, 4).map((news) => ( {filteredRows.slice(0, 4).map((news) => (
<NewsContent key={news.id} news={news} /> <CardNews key={news.id} news={news} />
))} ))}
</div> </div>
</div> </div>
...@@ -281,34 +270,34 @@ const Page = () => { ...@@ -281,34 +270,34 @@ const Page = () => {
<hr className="border-[#e8c518] mb-4" /> <hr className="border-[#e8c518] mb-4" />
<div className="flex flex-col md:flex-row gap-5"> <div className="flex flex-col md:flex-row gap-5">
{allData?.responseData.rows.slice(0, 1).map((news: NewsAdminItem) => ( {eventData?.responseData.rows.slice(0, 1).map((event: EventItem) => (
<a <a
key={news.id} key={event.id}
href={`${news.id}`} href={`${event.id}`}
className="flex flex-col w-full md:w-1/2 min-h-[180px] sm:min-h-[220px] gap-3 mb-3 border border-gray-200 bg-white rounded-md p-3" className="flex flex-col w-full md:w-1/2 min-h-[180px] sm:min-h-[220px] gap-3 mb-3 border border-gray-200 bg-white rounded-md p-3"
> >
<div className="w-full aspect-3/2 overflow-hidden"> <div className="w-full aspect-3/2 overflow-hidden">
<img <img
src={`${BASE_URL.imageEndpoint}${news.thumbnail}`} src={`${BASE_URL.imageEndpoint}${event.image}`}
alt={news.title} alt={event.name}
className="w-full h-full object-cover" className="w-full h-full object-cover"
/> />
</div> </div>
<div className="flex-1"> <div className="flex-1">
<p className="text-[#0056b3] font-bold text-xl line-clamp-2"> <p className="text-[#0056b3] font-bold text-xl line-clamp-2">
{news.title} {event.name}
</p> </p>
<p className="text-gray-500 text-sm my-1"> <p className="text-gray-500 text-sm my-1">
{dayjs(news.release_at).format('DD/MM/YYYY')} {dayjs(event.start_time).format('DD/MM/YYYY')}
</p> </p>
<AppEditorContent className="line-clamp-3" value={news.description} /> <AppEditorContent className="line-clamp-3" value={event.description} />
</div> </div>
</a> </a>
))} ))}
<div className="w-full md:w-1/2"> <div className="w-full md:w-1/2">
{rows.slice(0, 4).map((news) => ( {eventData?.responseData.rows.slice(0, 4).map((event) => (
<NewsContent key={news.id} news={news} /> <CardEvent key={event.id} event={event} />
))} ))}
</div> </div>
</div> </div>
...@@ -349,7 +338,7 @@ const Page = () => { ...@@ -349,7 +338,7 @@ const Page = () => {
</div> </div>
<hr className="border-blue-900 mb-4" /> <hr className="border-blue-900 mb-4" />
<div className="pt-2"> <div className="pt-2">
{allData?.responseData.rows.slice(0, 1).map((news: NewsAdminItem) => ( {newsData?.responseData.rows.slice(0, 1).map((news: NewsAdminItem) => (
<a <a
key={news.id} key={news.id}
href={`${news.id}`} href={`${news.id}`}
...@@ -370,7 +359,7 @@ const Page = () => { ...@@ -370,7 +359,7 @@ const Page = () => {
))} ))}
{rows.slice(0, 3).map((news) => ( {rows.slice(0, 3).map((news) => (
<NewsContent key={news.id} news={news} /> <CardNews key={news.id} news={news} />
))} ))}
</div> </div>
</div> </div>
...@@ -385,7 +374,7 @@ const Page = () => { ...@@ -385,7 +374,7 @@ const Page = () => {
</div> </div>
<hr className="border-blue-900 mb-4" /> <hr className="border-blue-900 mb-4" />
<div className="pt-2"> <div className="pt-2">
{allData?.responseData.rows.slice(0, 1).map((news: NewsAdminItem) => ( {newsData?.responseData.rows.slice(0, 1).map((news: NewsAdminItem) => (
<a <a
key={news.id} key={news.id}
href={`${news.id}`} href={`${news.id}`}
...@@ -406,7 +395,7 @@ const Page = () => { ...@@ -406,7 +395,7 @@ const Page = () => {
))} ))}
{rows.slice(0, 3).map((news) => ( {rows.slice(0, 3).map((news) => (
<NewsContent key={news.id} news={news} /> <CardNews key={news.id} news={news} />
))} ))}
</div> </div>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment