degmods.com/src/pages/home.tsx

316 lines
8.8 KiB
TypeScript
Raw Normal View History

2024-09-02 08:47:16 +00:00
import { Filter, kinds, nip19 } from 'nostr-tools'
import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
2024-09-02 16:04:18 +00:00
import { A11y, Navigation, Pagination, Autoplay } from 'swiper/modules'
2024-09-02 08:47:16 +00:00
import { Swiper, SwiperSlide } from 'swiper/react'
2024-07-11 13:34:12 +00:00
import { BlogCard } from '../components/BlogCard'
2024-07-11 12:15:03 +00:00
import { GameCard } from '../components/GameCard'
2024-07-11 12:52:48 +00:00
import { ModCard } from '../components/ModCard'
2024-09-02 08:47:16 +00:00
import { LANDING_PAGE_DATA } from '../constants'
import { RelayController } from '../controllers'
import { useDidMount } from '../hooks'
import { appRoutes, getModPageRoute } from '../routes'
2024-09-02 08:47:16 +00:00
import { ModDetails } from '../types'
import {
extractModData,
fetchMods,
handleModImageError,
log,
LogType
} from '../utils'
2024-07-11 11:19:12 +00:00
import '../styles/cardLists.css'
import '../styles/SimpleSlider.css'
import '../styles/styles.css'
2024-09-02 08:47:16 +00:00
// Import Swiper styles
import 'swiper/css'
import 'swiper/css/navigation'
import 'swiper/css/pagination'
2024-07-11 11:19:12 +00:00
export const HomePage = () => {
2024-09-02 08:47:16 +00:00
const navigate = useNavigate()
2024-07-11 11:19:12 +00:00
return (
<div className='InnerBodyMain'>
<div className='SliderWrapper'>
<div className='ContainerMain'>
<div className='IBMSecMain'>
<div className='simple-slider IBMSMSlider'>
2024-09-02 08:47:16 +00:00
<Swiper
className='swiper-container IBMSMSliderContainer'
wrapperClass='swiper-wrapper IBMSMSliderContainerWrapper'
2024-09-02 16:04:18 +00:00
modules={[Navigation, Pagination, A11y, Autoplay]}
2024-09-02 08:47:16 +00:00
pagination={{ clickable: true, dynamicBullets: true }}
slidesPerView={1}
autoplay={{ delay: 5000 }}
speed={1000}
navigation
loop
>
{LANDING_PAGE_DATA.featuredSlider.map((naddr) => (
<SwiperSlide className='swiper-slide IBMSMSliderContainerWrapperSlider'>
<SlideContent naddr={naddr} />
</SwiperSlide>
))}
</Swiper>
2024-07-11 11:19:12 +00:00
</div>
</div>
</div>
</div>
<div className='ContainerMain'>
<div className='IBMSecMainGroup IBMSecMainGroupAlt'>
<div className='IBMSecMain IBMSMListWrapper'>
<div className='IBMSMTitleMain'>
2024-09-02 08:47:16 +00:00
<h2 className='IBMSMTitleMainHeading'>Cool Games</h2>
2024-07-11 11:19:12 +00:00
</div>
<div className='IBMSMList IBMSMListFeaturedAlt'>
2024-09-02 08:47:16 +00:00
{LANDING_PAGE_DATA.featuredGames.map((game) => (
<GameCard title={game.title} imageUrl={game.imageUrl} />
))}
2024-07-11 11:19:12 +00:00
</div>
<div className='IBMSMAction'>
<a
className='btn btnMain IBMSMActionBtn'
role='button'
2024-09-02 08:47:16 +00:00
onClick={() => navigate(appRoutes.games)}
2024-07-11 11:19:12 +00:00
>
View All
</a>
</div>
</div>
<div className='IBMSecMain IBMSMListWrapper'>
<div className='IBMSMTitleMain'>
2024-09-02 08:47:16 +00:00
<h2 className='IBMSMTitleMainHeading'>Awesome Mods</h2>
2024-07-11 11:19:12 +00:00
</div>
<div className='IBMSMList IBMSMListAlt'>
2024-09-02 08:47:16 +00:00
{LANDING_PAGE_DATA.awesomeMods.map((naddr) => (
<DisplayMod key={naddr} naddr={naddr} />
))}
2024-07-11 11:19:12 +00:00
</div>
<div className='IBMSMAction'>
<a
className='btn btnMain IBMSMActionBtn'
role='button'
2024-09-02 08:47:16 +00:00
onClick={() => navigate(appRoutes.mods)}
2024-07-11 11:19:12 +00:00
>
View All
</a>
</div>
</div>
2024-09-02 08:47:16 +00:00
<DisplayLatestMods />
2024-07-11 11:19:12 +00:00
<div className='IBMSecMain IBMSMListWrapper'>
<div className='IBMSMTitleMain'>
2024-08-16 10:22:22 +00:00
<h2 className='IBMSMTitleMainHeading'>Blog Posts (WIP)</h2>
2024-07-11 11:19:12 +00:00
</div>
<div className='IBMSMList'>
2024-08-16 10:22:22 +00:00
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
2024-08-16 11:09:10 +00:00
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
2024-07-11 11:19:12 +00:00
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
</div>
<div className='IBMSMAction'>
<a
className='btn btnMain IBMSMActionBtn'
role='button'
href='blog.html'
>
View All
</a>
</div>
</div>
</div>
</div>
</div>
)
}
2024-09-02 08:47:16 +00:00
type SlideContentProps = {
naddr: string
}
const SlideContent = ({ naddr }: SlideContentProps) => {
const navigate = useNavigate()
const [mod, setMod] = useState<ModDetails>()
useDidMount(() => {
const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
const { identifier, kind, pubkey, relays = [] } = decoded.data
const filter: Filter = {
'#a': [identifier],
authors: [pubkey],
kinds: [kind]
}
RelayController.getInstance()
.fetchEvent(filter, relays)
.then((event) => {
if (event) {
const extracted = extractModData(event)
setMod(extracted)
}
})
.catch((err) => {
log(
true,
LogType.Error,
'An error occurred in fetching mod details from relays',
err
)
})
})
if (!mod) return <Spinner />
return (
<>
2024-09-02 09:03:41 +00:00
<div className='IBMSMSCWSPicWrapper'>
<img
src={mod.featuredImageUrl}
onError={handleModImageError}
className='IBMSMSCWSPic'
/>
</div>
2024-09-02 08:47:16 +00:00
<div className='IBMSMSCWSInfo'>
<h3 className='IBMSMSCWSInfoHeading'>{mod.title}</h3>
<p className='IBMSMSCWSInfoText'>
{mod.summary}
<br />
</p>
<div className='IBMSMSliderContainerWrapperSliderAction'>
<a
className='btn btnMain IBMSMSliderContainerWrapperSliderActionbtn'
role='button'
onClick={() => navigate(getModPageRoute(naddr))}
2024-09-02 08:47:16 +00:00
>
Check it out
</a>
</div>
</div>
</>
)
}
type DisplayModProps = {
naddr: string
}
const DisplayMod = ({ naddr }: DisplayModProps) => {
const navigate = useNavigate()
const [mod, setMod] = useState<ModDetails>()
useDidMount(() => {
const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
const { identifier, kind, pubkey, relays = [] } = decoded.data
const filter: Filter = {
'#a': [identifier],
authors: [pubkey],
kinds: [kind]
}
RelayController.getInstance()
.fetchEvent(filter, relays)
.then((event) => {
if (event) {
const extracted = extractModData(event)
setMod(extracted)
}
})
.catch((err) => {
log(
true,
LogType.Error,
'An error occurred in fetching mod details from relays',
err
)
})
})
if (!mod) return <Spinner />
const route = getModPageRoute(naddr)
2024-09-02 08:47:16 +00:00
return (
<ModCard
title={mod.title}
summary={mod.summary}
imageUrl={mod.featuredImageUrl}
link={`#${route}`}
handleClick={() => navigate(route)}
/>
)
}
const DisplayLatestMods = () => {
const navigate = useNavigate()
const [isFetchingLatestMods, setIsFetchingLatestMods] = useState(true)
const [latestMods, setLatestMods] = useState<ModDetails[]>([])
useDidMount(() => {
fetchMods({ source: window.location.host })
2024-09-02 08:47:16 +00:00
.then((res) => {
const mods = res
.sort((a, b) => b.published_at - a.published_at)
.slice(0, 4)
setLatestMods(mods)
2024-09-02 08:47:16 +00:00
})
.finally(() => {
setIsFetchingLatestMods(false)
})
})
return (
<div className='IBMSecMain IBMSMListWrapper'>
<div className='IBMSMTitleMain'>
<h2 className='IBMSMTitleMainHeading'>Latest Mods</h2>
</div>
<div className='IBMSMList'>
{isFetchingLatestMods ? (
<Spinner />
) : (
latestMods.map((mod) => {
const route = getModPageRoute(
2024-09-02 08:47:16 +00:00
nip19.naddrEncode({
identifier: mod.aTag,
pubkey: mod.author,
kind: kinds.ClassifiedListing
})
)
return (
<ModCard
key={mod.id}
title={mod.title}
summary={mod.summary}
imageUrl={mod.featuredImageUrl}
link={`#${route}`}
handleClick={() => navigate(route)}
/>
)
})
)}
</div>
<div className='IBMSMAction'>
<a
className='btn btnMain IBMSMActionBtn'
role='button'
onClick={() => navigate(appRoutes.mods)}
>
View All
</a>
</div>
</div>
)
}
const Spinner = () => {
return (
<div className='spinner'>
<div className='spinnerCircle'></div>
</div>
)
}