-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: finish home page and rewrite site in nextjs 13
- Loading branch information
Showing
62 changed files
with
2,875 additions
and
10,632 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
'use client'; | ||
import Button from "../common/uiLibrary/button"; | ||
import {useEffect, useState} from "react"; | ||
import getDownloadLink from "../../utils/platform"; | ||
import {GITHUB_RELEASES_URL} from "../../utils/urlContants"; | ||
import {BiSolidDownload} from "react-icons/bi"; | ||
|
||
|
||
|
||
const DownloadButtonClient = () => { | ||
const [downloadLink, setDownloadLink] = useState(GITHUB_RELEASES_URL); | ||
|
||
useEffect(() => { | ||
getDownloadLink().then((link) => setDownloadLink(link)); | ||
}, []); | ||
|
||
return ( | ||
<div className={'flex flex-wrap justify-center mt-8 gap-4'}> | ||
<Button filled={true} text={'Download'} linkTo={downloadLink} iconRight={BiSolidDownload} /> | ||
</div> | ||
) | ||
} | ||
|
||
export default DownloadButtonClient; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import Button from "../common/uiLibrary/button"; | ||
import {DISCORD_INVITE_URL, GITHUB_URL, PATREON_URL} from "../../utils/urlContants"; | ||
|
||
|
||
|
||
const LandingButtonsServer = () => { | ||
return ( | ||
<div className={'flex flex-wrap justify-center mt-8 gap-4'}> | ||
<Button filled={false} text={'Github'} linkTo={GITHUB_URL}/> | ||
<Button filled={false} text={'Discord'} linkTo={DISCORD_INVITE_URL}/> | ||
<Button filled={false} text={'Patreon'} linkTo={PATREON_URL}/> | ||
</div> | ||
) | ||
} | ||
|
||
export default LandingButtonsServer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import {DISCORD_INVITE_URL} from "../../utils/urlContants"; | ||
import {BsDiscord} from "react-icons/bs"; | ||
import {MdEmail} from "react-icons/md"; | ||
import React from "react"; | ||
|
||
const ContactInformation = () => { | ||
return ( | ||
<div | ||
style={{boxShadow: 'inset 0 10px 10px -10px rgba(0, 0, 0, 0.5)'}} | ||
className="w-full p-4 text-center sm:p-8 bg-gray-800 border-gray-700"> | ||
<h5 className="mb-2 text-3xl font-bold text-white">Let's Chat!</h5> | ||
<p className="mb-5 text-base sm:text-lg text-gray-400"> | ||
We'd love to hear from you! The quickest way to reach us is by joining our Discord server and dropping | ||
us a message. But, if you'd rather, feel free to shoot us an email. | ||
</p> | ||
<div className="items-center justify-center space-y-4 sm:flex sm:space-y-0 sm:space-x-4"> | ||
<a href={DISCORD_INVITE_URL} | ||
className="w-full sm:w-auto focus:ring-4 focus:outline-none text-white rounded-lg inline-flex items-center justify-center px-4 py-2.5 bg-gray-700 hover:bg-gray-600 focus:ring-gray-700"> | ||
<BsDiscord className="mr-3 w-7 h-7"/> | ||
<div className="text-left"> | ||
<div className="mb-1 text-xs">Join our</div> | ||
<div className="-mt-1 font-sans text-sm font-semibold">Discord Server</div> | ||
</div> | ||
</a> | ||
<a href="mailto:info@unitystation.org" | ||
className="w-full sm:w-auto focus:ring-4 focus:outline-none text-white rounded-lg inline-flex items-center justify-center px-4 py-2.5 bg-gray-700 hover:bg-gray-600 focus:ring-gray-700"> | ||
<MdEmail className="mr-3 w-7 h-7"/> | ||
<div className="text-left"> | ||
<div className="mb-1 text-xs">Email us at</div> | ||
<div className="-mt-1 font-sans text-sm font-semibold">info@unitystation.org</div> | ||
</div> | ||
</a> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default ContactInformation; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import React from 'react'; | ||
import {IconType} from "react-icons"; | ||
|
||
export type FeatureData = { | ||
title: string; | ||
description: string; | ||
icon: IconType, | ||
imageUrl: string; | ||
} | ||
|
||
interface FeaturesListProps{ | ||
features: FeatureData[]; | ||
} | ||
|
||
type FeatureCardProps = { | ||
feature: FeatureData; | ||
} | ||
|
||
const FeatureCard = ({ feature }: FeatureCardProps) => { | ||
const { title, description, icon: Icon } = feature; | ||
|
||
return ( | ||
<div className="flex flex-col space-y-2 p-4 bg-gray-900 rounded-xl shadow-md max-w-sm my-2 h-full"> | ||
<div className="flex space-x-2 items-start mb-4"> | ||
<div className="mt-1"> | ||
<Icon size={24} color="#10b981" /> | ||
</div> | ||
<div> | ||
<h2 className="font-semibold text-lg text-gray-200">{title}</h2> | ||
<p className="text-sm text-gray-300 mt-2">{description}</p> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
|
||
const FeaturesList = ({ features }: FeaturesListProps) => { | ||
return ( | ||
<div className="grid xl:grid-cols-4 lg:grid-cols-2 sm:grid-cols-1 gap-2 items-stretch justify-center"> | ||
{features.map((feature, index) => ( | ||
<FeatureCard key={index} feature={feature} /> | ||
))} | ||
</div> | ||
); | ||
} | ||
|
||
export default FeaturesList; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import {BlogPost} from "../../types/blogPost"; | ||
import classNames from "classnames"; | ||
import Container from "../common/uiLibrary/container"; | ||
import {toAgoTime} from "../../utils/timeUtils"; | ||
import PageSectionTitle from "../common/uiLibrary/pageSectionTitle"; | ||
|
||
interface NewsCardProps { | ||
post: BlogPost, | ||
isMain?: boolean, | ||
className?: string | ||
} | ||
|
||
interface LatestNewsProps { | ||
posts: BlogPost[] | ||
} | ||
|
||
const NewsCard = (props: NewsCardProps) => { | ||
const {title, summary, socials_image, date_created, slug} = props.post; | ||
const {className: classes} = props; | ||
const isMain = props.isMain ?? false; | ||
|
||
const style = { | ||
backgroundImage: `url(${socials_image})`, | ||
backgroundRepeat: 'no-repeat', | ||
backgroundSize: 'cover', | ||
backgroundBlendMode: 'multiply', | ||
backgroundPosition: 'center', | ||
} | ||
|
||
const truncateSummary = (summary: string, isMain: boolean) => { | ||
if (isMain) { | ||
return summary; | ||
} | ||
|
||
return summary.slice(0, 175) + '...'; | ||
} | ||
|
||
return ( | ||
<a href={`/blog/${slug}`} className={classNames('relative overflow-hidden', classes)}> | ||
<div className="absolute inset-0 rounded-lg shadow-lg bg-gray-400" style={style}></div> | ||
<div className="relative p-3 h-full flex flex-col justify-between"> | ||
<div> | ||
<div | ||
className={ | ||
classNames('text-2xl text-white leading-tight border-b hover:border-dashed hover:border-gray-500', | ||
{'lg:text-5xl': isMain})}>{title}</div> | ||
<div className="text-normal text-gray-300"> | ||
<span className=" pb-1">{toAgoTime(date_created)}</span> | ||
</div> | ||
</div> | ||
<p className="">{truncateSummary(summary, isMain)}</p> | ||
</div> | ||
</a> | ||
) | ||
} | ||
|
||
const LatestNews = (props: LatestNewsProps) => { | ||
const {posts} = props; | ||
|
||
return ( | ||
<> | ||
<PageSectionTitle>Latest News</PageSectionTitle> | ||
<Container> | ||
<div className="flex flex-col sm:flex-col md:flex-col lg:flex-row gap-5"> | ||
<div className="w-full lg:w-1/2 flex flex-col"> | ||
<NewsCard post={posts[0]} isMain className="h-full" /> | ||
</div> | ||
<div className="w-full lg:w-1/2 flex flex-col gap-4"> | ||
{posts.slice(1).map((post, index) => ( | ||
<NewsCard key={index} post={post} className="h-auto flex-grow" /> | ||
))} | ||
</div> | ||
</div> | ||
</Container> | ||
</> | ||
); | ||
} | ||
|
||
export default LatestNews; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import LandingText from "./landingText"; | ||
import {BlogPost} from "../../types/blogPost"; | ||
import {BlogPostsResponse} from "../../types/blogPostsResponse"; | ||
import FetchOfType from "../../utils/fetchOfType"; | ||
import PageSection from "../common/uiLibrary/pageSection"; | ||
import LandingButtonsServer from "./LandingButtonsServer"; | ||
import DownloadButtonClient from "./DownloadButtonClient"; | ||
import LatestNews from "./latestNews"; | ||
import ContactInformation from "./contactInformation"; | ||
import FeaturesList, {FeatureData} from "./featuresList"; | ||
import React from "react"; | ||
import {RiGamepadLine, RiRefreshLine, RiRocket2Line, RiTeamLine} from "react-icons/ri"; | ||
|
||
const mainText = "Welcome to Unitystation!"; | ||
const secondaryText = "Free and open-source remake of the cult classic Space Station 13, made in Unity Engine."; | ||
|
||
const features: FeatureData[] = [ | ||
{ | ||
title: "Player-driven gameplay", | ||
description: "Every round plays out differently. Almost anything on the station can be picked up, examined or vandalized", | ||
icon: RiGamepadLine, | ||
imageUrl: "https://unitystationfile.b-cdn.net/CommunityStuff/1/chicken.png" | ||
}, | ||
{ | ||
title: "Slapstick Simulation", | ||
description: "Fly a shuttle into the station, breaching the hull and venting everyone into space.", | ||
icon: RiRocket2Line, | ||
imageUrl: "https://unitystationfile.b-cdn.net/CommunityStuff/1/production.gif" | ||
}, | ||
{ | ||
title: "Dozens of jobs", | ||
description: "Want to play a cook? A janitor? Law enforcement? Or maybe the captain? Even lawyers have a place on the outpost.", | ||
icon: RiTeamLine, | ||
imageUrl: "https://unitystationfile.b-cdn.net/WeeklyBlogUpdates/8/60.png" | ||
}, | ||
{ | ||
title: "Finally Remade", | ||
description: "No more dealing with BYOND to play your favorite spessman game.", | ||
icon: RiRefreshLine, | ||
imageUrl: "https://unitystationfile.b-cdn.net/WeeklyBlogUpdates/1/25.png" | ||
} | ||
] | ||
|
||
const fetchLatestBlogPost = async (): Promise<BlogPost[]> => { | ||
const revalidateConfig = {next: {revalidate: 60}}; | ||
const resPage1 = await FetchOfType<BlogPostsResponse>('https://changelog.unitystation.org/posts/', revalidateConfig); | ||
const resPage2 = await FetchOfType<BlogPostsResponse>('https://changelog.unitystation.org/posts/?page=2', revalidateConfig); | ||
return resPage1.results.concat(resPage2.results); | ||
} | ||
|
||
|
||
const HomePage: () => Promise<JSX.Element> = async () => { | ||
|
||
const latestBlogPosts: BlogPost[] = await fetchLatestBlogPost(); | ||
|
||
return ( | ||
<> | ||
<PageSection className="gap-16"> | ||
<div> | ||
<LandingText mainText={mainText} secondaryText={secondaryText}/> | ||
<DownloadButtonClient/> | ||
<LandingButtonsServer/> | ||
</div> | ||
<FeaturesList features={features}/> | ||
</PageSection> | ||
<PageSection verticalCenter={false}> | ||
<LatestNews posts={latestBlogPosts}/> | ||
</PageSection> | ||
<ContactInformation/> | ||
</> | ||
) | ||
} | ||
|
||
export default HomePage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
'use client'; | ||
|
||
|
||
import {useEffect, useState} from "react"; | ||
|
||
const texts = [ | ||
'Join our Discord server to get involved!', | ||
'Yeah, we have some bugs but at least they are funny!', | ||
'We are not dead yet!', | ||
'Surviving the curse one PR at a time!', | ||
'I\'m not a web developer, please send help!', | ||
'Thank you patreons for keeping the lights on!', | ||
'Check our Github if you want to contribute!', | ||
'Devlog might release any time now!', | ||
'[object Object]', | ||
'Join us every Saturday on our community playtest! (More info on Discord)', | ||
] | ||
|
||
const RandomThirdTextClient = () => { | ||
|
||
const [randomText, setRandomText] = useState(texts[0]); | ||
|
||
useEffect(() => { | ||
const interval = setInterval(() => { | ||
setRandomText(texts[Math.floor(Math.random() * texts.length)]); | ||
}, 5000); | ||
return () => clearInterval(interval); | ||
}) | ||
|
||
return ( | ||
<p className={'mx-auto mt-4 font-extralight'}> | ||
{randomText} | ||
</p> | ||
) | ||
} | ||
|
||
export default RandomThirdTextClient; |
Oops, something went wrong.