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'
|
2024-09-03 10:13:51 +00:00
|
|
|
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>
|
2024-09-03 17:56:33 +00:00
|
|
|
<p className='IBMSMSCWSInfoText IBMSMSCWSInfoText2'>
|
2024-09-05 07:46:14 +00:00
|
|
|
{mod.game}
|
2024-09-03 17:56:33 +00:00
|
|
|
<br />
|
|
|
|
</p>
|
2024-09-02 08:47:16 +00:00
|
|
|
<div className='IBMSMSliderContainerWrapperSliderAction'>
|
|
|
|
<a
|
|
|
|
className='btn btnMain IBMSMSliderContainerWrapperSliderActionbtn'
|
|
|
|
role='button'
|
2024-09-03 10:13:51 +00:00
|
|
|
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 />
|
|
|
|
|
2024-09-03 10:13:51 +00:00
|
|
|
const route = getModPageRoute(naddr)
|
2024-09-02 08:47:16 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<ModCard
|
|
|
|
title={mod.title}
|
2024-09-05 07:46:14 +00:00
|
|
|
gameName={mod.game}
|
2024-09-02 08:47:16 +00:00
|
|
|
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(() => {
|
2024-09-03 10:23:07 +00:00
|
|
|
fetchMods({ source: window.location.host })
|
2024-09-02 08:47:16 +00:00
|
|
|
.then((res) => {
|
2024-09-03 10:23:07 +00:00
|
|
|
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) => {
|
2024-09-03 10:13:51 +00:00
|
|
|
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}
|
2024-09-05 07:46:14 +00:00
|
|
|
gameName={mod.game}
|
2024-09-02 08:47:16 +00:00
|
|
|
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>
|
|
|
|
)
|
|
|
|
}
|