Improve MineGeo interface and functionality
This commit is contained in:
133
app/page.tsx
133
app/page.tsx
@@ -1,3 +1,4 @@
|
||||
import { getI18n } from "@/lib/i18n";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import {
|
||||
@@ -15,6 +16,7 @@ import { leaderboard } from "@/lib/leaderboard";
|
||||
import { LeaderboardPreview } from "@/components/Leaderboard";
|
||||
export const dynamic = "force-dynamic";
|
||||
export default async function Home() {
|
||||
const { t, formatNumber } = await getI18n();
|
||||
const [maps, rankings] = await Promise.all([
|
||||
catalog(),
|
||||
leaderboard({ limit: 5 }),
|
||||
@@ -27,24 +29,24 @@ export default async function Home() {
|
||||
<main className="home-page" id="main-content">
|
||||
<section className="hero">
|
||||
<div className="hero-copy">
|
||||
<div className="status-label">A MINECRAFT GUESSING GAME</div>
|
||||
<div className="status-label">{t("A MINECRAFT GUESSING GAME")}</div>
|
||||
<h1>
|
||||
Guess where you are
|
||||
{t("Guess where you are")}
|
||||
<br />
|
||||
in a <span>blocky world.</span>
|
||||
{t("in a")} <span>{t("blocky world.")}</span>
|
||||
</h1>
|
||||
<p>
|
||||
Drop into a random corner of a Minecraft world.
|
||||
<br className="desktop" /> Look around, spot the landmarks, and
|
||||
place your pin
|
||||
<br className="desktop" /> before the clock runs out.
|
||||
{t("Drop into a random corner of a Minecraft world.")}
|
||||
<br className="desktop" />{" "}
|
||||
{t("Look around, spot the landmarks, and place your pin")}
|
||||
<br className="desktop" /> {t("before the clock runs out.")}
|
||||
</p>
|
||||
<div className="hero-actions">
|
||||
<Link href="/servers" className="button primary">
|
||||
Start exploring <ArrowRight size={18} />
|
||||
{t("Start exploring")} <ArrowRight size={18} />
|
||||
</Link>
|
||||
<Link href="/leaderboard" className="text-link">
|
||||
Meet the top explorers <ArrowRight size={14} />
|
||||
{t("Meet the top explorers")} <ArrowRight size={14} />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="hero-notes">
|
||||
@@ -55,14 +57,16 @@ export default async function Home() {
|
||||
<i />
|
||||
<i />
|
||||
</span>
|
||||
<span>Five rounds. No roads. Just your instincts.</span>
|
||||
<span>{t("Five rounds. No roads. Just your instincts.")}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="hero-art" aria-label="Minecraft surface map">
|
||||
<div className="hero-art" aria-label={t("Minecraft surface map")}>
|
||||
<div className="map-art-frame minecraft-paper">
|
||||
<Image
|
||||
src={maps[0]?.mapImage || "/images/example-map.webp"}
|
||||
alt="A Minecraft surface map on the original Minecraft parchment texture"
|
||||
alt={t(
|
||||
"A Minecraft surface map on the original Minecraft parchment texture",
|
||||
)}
|
||||
width={1024}
|
||||
height={1024}
|
||||
loading="eager"
|
||||
@@ -79,51 +83,52 @@ export default async function Home() {
|
||||
<div className="floating-tag">
|
||||
<MapPin size={14} />
|
||||
<strong>X: ??? Z: ???</strong>
|
||||
<span>Overworld</span>
|
||||
<span>{t("Overworld")}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div className="grass-divider" aria-hidden="true">
|
||||
<span />
|
||||
</div>
|
||||
<section className="world-stats" aria-label="Community statistics">
|
||||
<section className="world-stats" aria-label={t("Community statistics")}>
|
||||
<div>
|
||||
<i className="stat-cube green-cube" />
|
||||
<div>
|
||||
<strong>{servers.toLocaleString()}</strong>
|
||||
<span>COMMUNITY SERVERS</span>
|
||||
<strong>{formatNumber(servers)}</strong>
|
||||
<span>{t("COMMUNITY SERVERS")}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<i className="stat-cube gold-cube" />
|
||||
<div>
|
||||
<strong>{maps.length.toLocaleString()}</strong>
|
||||
<span>PUBLISHED MAPS</span>
|
||||
<strong>{formatNumber(maps.length)}</strong>
|
||||
<span>{t("PUBLISHED MAPS")}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<i className="stat-cube cyan-cube" />
|
||||
<div>
|
||||
<strong>{locations.toLocaleString()}</strong>
|
||||
<span>PLACES TO DISCOVER</span>
|
||||
<strong>{formatNumber(locations)}</strong>
|
||||
<span>{t("PLACES TO DISCOVER")}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<i className="stat-cube red-cube" />
|
||||
<div>
|
||||
<strong>5 rounds</strong>
|
||||
<span>EVERY EXPEDITION</span>
|
||||
<strong>{t("5 rounds")}</strong>
|
||||
<span>{t("EVERY EXPEDITION")}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="section catalog-section">
|
||||
<div className="section-heading">
|
||||
<div>
|
||||
<span className="eyebrow">COMMUNITY MAPS</span>
|
||||
<h2>Where will you go today?</h2>
|
||||
<span className="eyebrow">{t("COMMUNITY MAPS")}</span>
|
||||
<h2>{t("Where will you go today?")}</h2>
|
||||
</div>
|
||||
<Link className="text-link" href="/servers">
|
||||
All {maps.length} maps <ArrowRight size={15} />
|
||||
{t("All maps ({count})", { count: maps.length })}{" "}
|
||||
<ArrowRight size={15} />
|
||||
</Link>
|
||||
</div>
|
||||
{maps.length ? (
|
||||
@@ -142,20 +147,20 @@ export default async function Home() {
|
||||
height={180}
|
||||
unoptimized
|
||||
/>
|
||||
<span>YOUR WORLD HERE</span>
|
||||
<span>{t("YOUR WORLD HERE")}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="eyebrow">
|
||||
THE FIRST EXPEDITION STARTS WITH YOU
|
||||
{t("THE FIRST EXPEDITION STARTS WITH YOU")}
|
||||
</span>
|
||||
<h3>Put your server on the map.</h3>
|
||||
<h3>{t("Put your server on the map.")}</h3>
|
||||
<p>
|
||||
No community maps have been published yet. Export your world
|
||||
with the server plugin, or capture five locations with the
|
||||
Fabric mod. Preview your map and submit it for review.
|
||||
{t(
|
||||
"No community maps have been published yet. Export your world with the server plugin, or capture five locations with the Fabric mod. Preview your map and submit it for review.",
|
||||
)}
|
||||
</p>
|
||||
<Link className="button primary" href="/downloads">
|
||||
<Upload size={16} /> Get the capture tools
|
||||
<Upload size={16} /> {t("Get the capture tools")}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -164,58 +169,64 @@ export default async function Home() {
|
||||
<LeaderboardPreview data={rankings} />
|
||||
<section className="section home-panels">
|
||||
<article className="home-panel">
|
||||
<span className="eyebrow">HOW TO PLAY</span>
|
||||
<h2>Know your blocks?</h2>
|
||||
<span className="eyebrow">{t("HOW TO PLAY")}</span>
|
||||
<h2>{t("Know your blocks?")}</h2>
|
||||
<ol className="play-steps">
|
||||
<li>
|
||||
<span>01</span>
|
||||
<div>
|
||||
<h3>Pick your world</h3>
|
||||
<p>Choose a community server, map, and difficulty.</p>
|
||||
<h3>{t("Pick your world")}</h3>
|
||||
<p>{t("Choose a community server, map, and difficulty.")}</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>02</span>
|
||||
<div>
|
||||
<h3>Look for the clues</h3>
|
||||
<h3>{t("Look for the clues")}</h3>
|
||||
<p>
|
||||
Rotate the panorama. Find builds, biomes, and landmarks.
|
||||
{t(
|
||||
"Rotate the panorama. Find builds, biomes, and landmarks.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>03</span>
|
||||
<div>
|
||||
<h3>Make your guess</h3>
|
||||
<p>Drop a pin on the map. Closer guesses earn more points.</p>
|
||||
<h3>{t("Make your guess")}</h3>
|
||||
<p>
|
||||
{t(
|
||||
"Drop a pin on the map. Closer guesses earn more points.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
<Link className="text-link" href="/about">
|
||||
Read the field guide <ArrowRight size={14} />
|
||||
{t("Read the field guide")} <ArrowRight size={14} />
|
||||
</Link>
|
||||
</article>
|
||||
<article className="home-panel">
|
||||
<span className="eyebrow">CHOOSE YOUR CHALLENGE</span>
|
||||
<h2>One world. Three ways.</h2>
|
||||
<span className="eyebrow">{t("CHOOSE YOUR CHALLENGE")}</span>
|
||||
<h2>{t("One world. Three ways.")}</h2>
|
||||
<div className="mode-list">
|
||||
{[
|
||||
{
|
||||
name: "Easy",
|
||||
time: "180 seconds",
|
||||
detail: "Take your time. Rotate and zoom.",
|
||||
name: t("Easy"),
|
||||
time: t("180 seconds"),
|
||||
detail: t("Take your time. Rotate and zoom."),
|
||||
color: "green",
|
||||
},
|
||||
{
|
||||
name: "Normal",
|
||||
time: "90 seconds",
|
||||
detail: "Trust your eye. Rotate and zoom.",
|
||||
name: t("Normal"),
|
||||
time: t("90 seconds"),
|
||||
detail: t("Trust your eye. Rotate and zoom."),
|
||||
color: "gold",
|
||||
},
|
||||
{
|
||||
name: "Hard",
|
||||
time: "30 seconds",
|
||||
detail: "Think fast. No zoom allowed.",
|
||||
name: t("Hard"),
|
||||
time: t("30 seconds"),
|
||||
detail: t("Think fast. No zoom allowed."),
|
||||
color: "red",
|
||||
},
|
||||
].map((mode) => (
|
||||
@@ -223,32 +234,34 @@ export default async function Home() {
|
||||
<i className={`stat-cube ${mode.color}-cube`} />
|
||||
<div>
|
||||
<h3>
|
||||
{mode.name}
|
||||
{t(mode.name)}
|
||||
<span>
|
||||
<Timer size={12} />
|
||||
{mode.time}
|
||||
{t(mode.time)}
|
||||
</span>
|
||||
</h3>
|
||||
<p>{mode.detail}</p>
|
||||
<p>{t(mode.detail)}</p>
|
||||
</div>
|
||||
<ArrowRight size={15} />
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<p className="mode-footnote">
|
||||
Up to 5,000 points per round. How close can you get?
|
||||
{t("Up to 5,000 points per round. How close can you get?")}
|
||||
</p>
|
||||
</article>
|
||||
</section>
|
||||
<section className="section contribute-banner">
|
||||
<Blocks size={38} />
|
||||
<div>
|
||||
<span className="eyebrow">BUILT BY THE COMMUNITY</span>
|
||||
<h2>Your world deserves to be explored.</h2>
|
||||
<p>Share your builds and your favorite corners of Minecraft.</p>
|
||||
<span className="eyebrow">{t("BUILT BY THE COMMUNITY")}</span>
|
||||
<h2>{t("Your world deserves to be explored.")}</h2>
|
||||
<p>
|
||||
{t("Share your builds and your favorite corners of Minecraft.")}
|
||||
</p>
|
||||
</div>
|
||||
<Link href="/downloads" className="button">
|
||||
Create a map <ArrowRight size={16} />
|
||||
{t("Create a map")} <ArrowRight size={16} />
|
||||
</Link>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user