Redesign download page with alternating sections layout
Some checks failed
Build and Deploy / deploy (push) Has been cancelled

Replace card grid with full-width alternating sections matching site design.
Add Toolbox app, VS Code plugin (coming soon), correct all download URLs,
add MSI installer toggle, section headings, and dark advanced tools section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Tim Hadwen
2026-03-06 21:31:50 +10:00
parent 9594cc862e
commit 70c313a953
4 changed files with 354 additions and 158 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,37 @@
"use client";
import { useState } from "react";
import { Button } from "@/components/ui/Button";
export function DownloadToggle() {
const [open, setOpen] = useState(false);
return (
<div className="mt-4">
<button
onClick={() => setOpen(!open)}
className="text-sm font-medium text-muted-foreground transition-colors hover:text-foreground"
>
{open ? "Hide" : "Show"} other download options &rsaquo;
</button>
{open && (
<div className="mt-3 flex flex-wrap gap-3">
<Button
href="https://micromelon-s3.s3.ap-southeast-2.amazonaws.com/Micromelon+Code+Editor/Micromelon+Code+Editor+x64.msi"
variant="outline"
size="sm"
>
Windows x64 (.msi)
</Button>
<Button
href="https://micromelon-s3.s3.ap-southeast-2.amazonaws.com/Micromelon+Code+Editor/Micromelon+Code+Editor+ia32.msi"
variant="outline"
size="sm"
>
Windows ia32 (.msi)
</Button>
</div>
)}
</div>
);
}

View File

@@ -2,6 +2,7 @@ import Image from "next/image";
import { Metadata } from "next"; import { Metadata } from "next";
import { Container } from "@/components/layout/Container"; import { Container } from "@/components/layout/Container";
import { Button } from "@/components/ui/Button"; import { Button } from "@/components/ui/Button";
import { DownloadToggle } from "./DownloadToggle";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Download", title: "Download",
@@ -9,157 +10,11 @@ export const metadata: Metadata = {
"Download the Micromelon Code Editor, Robot Simulator, Junior, and Python library.", "Download the Micromelon Code Editor, Robot Simulator, Junior, and Python library.",
}; };
interface PlatformLink {
label: string;
href: string;
icon: string;
}
interface ProductCardProps {
name: string;
description: string;
image: string;
imageAlt: string;
platforms?: PlatformLink[];
installCommand?: string;
extraLink?: { label: string; href: string };
note?: string;
accent?: string;
}
function ProductCard({
name,
description,
image,
imageAlt,
platforms,
installCommand,
extraLink,
note,
accent = "border-border",
}: ProductCardProps) {
return (
<div
className={`overflow-hidden rounded-2xl border-2 bg-white shadow-sm transition-shadow hover:shadow-lg ${accent}`}
>
<div className="relative aspect-[16/9] overflow-hidden bg-muted">
<Image
src={image}
alt={imageAlt}
fill
className="object-cover"
unoptimized={image.endsWith(".gif")}
/>
</div>
<div className="p-6 sm:p-8">
<h3 className="text-2xl font-bold text-foreground">{name}</h3>
<p className="mt-3 text-foreground-light">{description}</p>
{installCommand && (
<div className="mt-6">
<p className="mb-2 text-sm font-medium text-muted-foreground">
Install via pip:
</p>
<code className="block rounded-lg bg-foreground px-4 py-3 text-sm font-mono text-white">
$ {installCommand}
</code>
</div>
)}
{platforms && platforms.length > 0 && (
<div className="mt-6">
<p className="mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground">
Available on
</p>
<div className="flex flex-wrap gap-3">
{platforms.map((platform) => (
<Button
key={platform.label}
href={platform.href}
variant="primary"
size="md"
>
{platform.icon} {platform.label}
</Button>
))}
</div>
</div>
)}
{extraLink && (
<div className="mt-6">
<Button href={extraLink.href} variant="primary" size="md">
{extraLink.label}
</Button>
</div>
)}
{note && (
<p className="mt-4 text-sm text-muted-foreground">{note}</p>
)}
</div>
</div>
);
}
const downloadProducts: ProductCardProps[] = [
{
name: "The Code Editor",
description:
"Our blocks & Python coding environment to program the Micromelon Rover and the Robot Simulator. Start with drag-and-drop blocks and progress to Python with the side-by-side editor.",
image: "/images/products/code-editor-laptop.gif",
imageAlt: "Micromelon Code Editor showing blocks and Python side by side",
accent: "border-brand",
platforms: [
{ label: "Windows", href: "https://micromelon-s3.s3.ap-southeast-2.amazonaws.com/Micromelon+Code+Setup.exe", icon: "\u{1F5A5}" },
{ label: "macOS", href: "https://micromelon-s3.s3.ap-southeast-2.amazonaws.com/Micromelon+Code.dmg", icon: "\u{1F4BB}" },
{ label: "iPad", href: "https://apps.apple.com/au/app/micromelon-code/id1542702054", icon: "\u{1F4F1}" },
{ label: "Android", href: "https://play.google.com/store/apps/details?id=com.nicerapps.micromeloncode", icon: "\u{1F4F1}" },
{ label: "Chromebook", href: "https://play.google.com/store/apps/details?id=com.nicerapps.micromeloncode", icon: "\u{1F4BB}" },
],
},
{
name: "The Robot Simulator",
description:
"Control a simulated Micromelon Rover in a 3D virtual environment. Solve challenges, navigate environments, and test your code - no physical robot needed.",
image: "/images/products/simulator-demo.gif",
imageAlt: "Micromelon Robot Simulator 3D environment",
accent: "border-teal-400",
platforms: [
{ label: "Windows", href: "https://micromelon-s3.s3.ap-southeast-2.amazonaws.com/Micromelon+Simulator+Setup.exe", icon: "\u{1F5A5}" },
{ label: "macOS", href: "https://apps.apple.com/au/app/micromelon-simulator/id1544591007", icon: "\u{1F4BB}" },
],
},
{
name: "Micromelon-Py",
description:
"A dedicated Python module providing an API for connecting and controlling Micromelon Rovers and simulated rovers. Perfect for senior students and advanced projects.",
image: "/images/content/6d295c-vscode-cover-photo.png",
imageAlt: "Micromelon Python library in VS Code",
installCommand: "pip install micromelon",
extraLink: {
label: "View on PyPI",
href: "https://pypi.org/project/micromelon/",
},
},
{
name: "Junior",
description:
"Ideal for students not yet confident to navigate the Code Editor, or for lesson plans which aim to teach the basics of computational thinking with a simplified interface.",
image: "/images/products/rover-render.jpg",
imageAlt: "Micromelon Junior app for young learners",
platforms: [
{ label: "iPad", href: "https://apps.apple.com/au/app/micromelon-junior/id1522717379", icon: "\u{1F4F1}" },
{ label: "Android", href: "https://play.google.com/store/apps/details?id=com.nicerapps.micromelonjunior", icon: "\u{1F4F1}" },
],
},
];
export default function DownloadPage() { export default function DownloadPage() {
return ( return (
<> <>
{/* Hero */} {/* Hero */}
<section className="bg-brand py-16 sm:py-20"> <section className="bg-brand py-16 sm:py-10">
<Container> <Container>
<div className="text-center"> <div className="text-center">
<h1 className="text-4xl font-bold tracking-tight text-foreground sm:text-5xl"> <h1 className="text-4xl font-bold tracking-tight text-foreground sm:text-5xl">
@@ -173,13 +28,309 @@ export default function DownloadPage() {
</Container> </Container>
</section> </section>
{/* Download Cards */} {/* — For Coding — */}
<section className="bg-white py-16 sm:py-20"> <section className="bg-white pb-0 pt-10">
<Container> <Container>
<div className="grid gap-8 md:grid-cols-2"> <h2 className="text-center text-sm font-semibold uppercase tracking-widest text-muted-foreground">
{downloadProducts.map((product) => ( For Teachers &amp; Students
<ProductCard key={product.name} {...product} /> </h2>
))} </Container>
</section>
{/* Code Editor */}
<section className="bg-white py-10">
<Container>
<div className="grid items-center gap-12 md:min-h-[20rem] md:grid-cols-2">
<div>
<Image
src="/images/products/code-editor-laptop.gif"
alt="Micromelon Code Editor showing blocks and Python side by side"
width={1200}
height={750}
className="w-full rounded-2xl"
unoptimized
/>
</div>
<div>
<h2 className="text-3xl font-bold text-foreground">
The Code Editor
</h2>
<p className="mt-4 text-lg text-foreground-light">
Our blocks &amp; Python coding environment to program the
Micromelon Rover and the Robot Simulator. Start with
drag-and-drop blocks and progress to Python with the
side-by-side editor.
</p>
<p className="mb-3 mt-6 text-xs font-medium uppercase tracking-wider text-muted-foreground">
Available on
</p>
<div className="flex flex-wrap gap-3">
<Button
href="https://micromelon-s3.s3.ap-southeast-2.amazonaws.com/Micromelon+Code+Editor/Micromelon+Code+Editor.dmg"
variant="primary"
size="sm"
>
macOS
</Button>
<Button
href="https://micromelon-s3.s3.ap-southeast-2.amazonaws.com/Micromelon+Code+Editor/Micromelon+Code+Editor.exe"
variant="primary"
size="sm"
>
Windows
</Button>
<Button
href="https://apps.apple.com/au/app/micromelon-code-editor/id6453025221"
variant="primary"
size="sm"
>
iPad
</Button>
<Button
href="https://play.google.com/store/apps/details?id=com.micromelon.codeeditor&hl=en"
variant="primary"
size="sm"
>
Android
</Button>
<Button
href="https://play.google.com/store/apps/details?id=com.micromelon.codeeditor&hl=en"
variant="primary"
size="sm"
>
Chromebook
</Button>
</div>
<DownloadToggle />
</div>
</div>
</Container>
</section>
{/* Robot Simulator */}
<section className="bg-muted py-10">
<Container>
<div className="grid items-center gap-12 md:min-h-[20rem] md:grid-cols-2">
<div>
<h2 className="text-3xl font-bold text-foreground">
The Robot Simulator
</h2>
<p className="mt-4 text-lg text-foreground-light">
Control a simulated Micromelon Rover in a 3D virtual
environment. Solve challenges, navigate environments, and test
your code no physical robot needed.
</p>
<p className="mb-3 mt-6 text-xs font-medium uppercase tracking-wider text-muted-foreground">
Available on
</p>
<div className="flex flex-wrap gap-3">
<Button
href="https://www.microsoft.com/store/apps/9n0vz34nmtld"
variant="primary"
size="sm"
>
Windows
</Button>
<Button
href="https://apps.apple.com/au/app/micromelon-robot-simulator/id1529543958"
variant="primary"
size="sm"
>
macOS
</Button>
</div>
</div>
<div className="md:order-2">
<Image
src="/images/products/simulator-demo.gif"
alt="Micromelon Robot Simulator 3D environment"
width={1200}
height={750}
className="w-full rounded-2xl shadow-lg"
unoptimized
/>
</div>
</div>
</Container>
</section>
{/* Junior */}
<section className="bg-white py-10">
<Container>
<div className="grid items-center gap-12 md:min-h-[20rem] md:grid-cols-2">
<div>
<Image
src="/images/products/junior-hero.png"
alt="Micromelon Junior app interface"
width={1200}
height={750}
className="w-full rounded-2xl"
/>
</div>
<div>
<h2 className="text-3xl font-bold text-foreground">Junior</h2>
<p className="mt-4 text-lg text-foreground-light">
Ideal for students not yet confident to navigate the Code
Editor, or for lesson plans which aim to teach the basics of
computational thinking with a simplified interface.
</p>
<p className="mb-3 mt-6 text-xs font-medium uppercase tracking-wider text-muted-foreground">
Available on
</p>
<div className="flex flex-wrap gap-3">
<Button
href="https://apps.apple.com/au/app/micromelon-junior/id6462841059"
variant="primary"
size="sm"
>
iPad
</Button>
<Button
href="https://play.google.com/store/apps/details?id=com.micromelon.codeeditorjunior&hl=en"
variant="primary"
size="sm"
>
Android
</Button>
</div>
</div>
</div>
</Container>
</section>
{/* — For Teachers — */}
<section className="bg-muted pb-0 pt-10">
<Container>
<h2 className="text-center text-sm font-semibold uppercase tracking-widest text-muted-foreground">
For Teachers
</h2>
</Container>
</section>
{/* Toolbox App */}
<section className="bg-muted py-10">
<Container>
<div className="grid items-center gap-12 md:min-h-[20rem] md:grid-cols-2">
<div>
<h2 className="text-3xl font-bold text-foreground">
Micromelon Toolbox
</h2>
<p className="mt-4 text-lg text-foreground-light">
Manage your fleet of Micromelon Rovers. Update firmware,
configure settings, and keep every Rover in your classroom
ready to code.
</p>
<p className="mb-3 mt-6 text-xs font-medium uppercase tracking-wider text-muted-foreground">
Available on
</p>
<div className="flex flex-wrap gap-3">
<Button
href="https://apps.apple.com/au/app/micromelon-toolbox/id6746182977"
variant="primary"
size="sm"
>
iPhone / iPad
</Button>
</div>
</div>
<div className="md:order-2">
<Image
src="/images/products/toolbox-icon.webp"
alt="Micromelon Toolbox App"
width={400}
height={400}
className="mx-auto w-48 rounded-3xl sm:w-64"
/>
</div>
</div>
</Container>
</section>
{/* — Advanced Tools — */}
<section className="bg-foreground pb-0 pt-10">
<Container>
<h2 className="text-center text-sm font-semibold uppercase tracking-widest text-white/50">
Advanced Tools
</h2>
</Container>
</section>
{/* Micromelon-Py */}
<section className="bg-foreground py-10">
<Container>
<div className="grid items-center gap-12 md:min-h-[20rem] md:grid-cols-2">
<div>
<Image
src="/images/content/6d295c-vscode-cover-photo.png"
alt="Micromelon Python library in VS Code"
width={1200}
height={750}
className="w-full rounded-2xl"
/>
</div>
<div>
<h2 className="text-3xl font-bold text-white">Micromelon-Py</h2>
<p className="mt-4 text-lg text-white/70">
A dedicated Python module providing an API for connecting and
controlling Micromelon Rovers and simulated rovers. Perfect for
senior students and advanced projects.
</p>
<div className="mt-6">
<p className="mb-2 text-sm font-medium text-white/50">
Install via pip:
</p>
<code className="block rounded-lg bg-white/10 px-4 py-3 font-mono text-sm text-white">
$ pip install micromelon
</code>
</div>
<div className="mt-6 flex flex-wrap gap-3">
<Button
href="https://pypi.org/project/micromelon/"
variant="secondary"
size="sm"
>
View on PyPI
</Button>
<Button
href="https://micromelon-robotics.github.io/mm-pymodule/micromelon/index.html"
variant="outline"
size="sm"
className="border-white/30 text-white hover:bg-white/10"
>
API Docs
</Button>
</div>
</div>
</div>
</Container>
</section>
{/* VS Code Plugin — Coming Soon */}
<section className="bg-foreground py-10">
<Container>
<div className="grid items-center gap-12 md:min-h-[20rem] md:grid-cols-2">
<div>
<h2 className="text-3xl font-bold text-white">VS Code Plugin</h2>
<p className="mt-4 text-lg text-white/70">
Code with Micromelon directly inside Visual Studio Code. Connect
to your Rover or the Robot Simulator without leaving your
favourite editor.
</p>
<div className="mt-6">
<span className="inline-flex items-center rounded-full bg-brand px-4 py-2 text-sm font-semibold text-foreground">
Coming Soon
</span>
</div>
</div>
<div className="md:order-2">
<Image
src="/images/content/6d295c-vscode-cover-photo.png"
alt="Micromelon VS Code plugin"
width={1200}
height={750}
className="w-full rounded-2xl"
/>
</div>
</div> </div>
</Container> </Container>
</section> </section>

View File

@@ -723,11 +723,19 @@ export default function PythonPage() {
<Container> <Container>
<div className="grid items-center gap-12 md:grid-cols-2"> <div className="grid items-center gap-12 md:grid-cols-2">
<div> <div>
<div <div className="mb-4 flex flex-wrap items-center gap-3">
className="mb-4 inline-block rounded-full px-3 py-1 font-mono text-xs" <span
className="inline-block rounded-full px-3 py-1 font-mono text-xs"
style={{ border: "1px solid rgba(34,197,94,0.3)", background: "rgba(34,197,94,0.1)", color: "#4ade80" }} style={{ border: "1px solid rgba(34,197,94,0.3)", background: "rgba(34,197,94,0.1)", color: "#4ade80" }}
> >
VS Code Extension VS Code Extension
</span>
<span
className="inline-block rounded-full px-3 py-1 text-xs font-semibold"
style={{ background: "rgba(234,179,8,0.15)", color: "#eab308", border: "1px solid rgba(234,179,8,0.3)" }}
>
Coming Soon
</span>
</div> </div>
<h2 <h2
className="text-3xl font-bold tracking-tight sm:text-4xl" className="text-3xl font-bold tracking-tight sm:text-4xl"