Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled
125 lines
4.3 KiB
TypeScript
125 lines
4.3 KiB
TypeScript
import { kv } from "@vercel/kv";
|
|
import { saveEmail } from "./actions";
|
|
import FeatureForm from "./form";
|
|
import { Feature } from "./types";
|
|
|
|
export let metadata = {
|
|
title: "Next.js and Redis Example",
|
|
description: "Feature roadmap example with Next.js with Redis.",
|
|
};
|
|
|
|
function VercelLogo(props: React.SVGProps<SVGSVGElement>) {
|
|
return (
|
|
<svg
|
|
aria-label="Vercel Logo"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
fill="none"
|
|
viewBox="0 0 24 19"
|
|
{...props}
|
|
>
|
|
<path
|
|
clipRule="evenodd"
|
|
d="M12.04 2L2.082 18H22L12.04 2z"
|
|
fill="#000"
|
|
fillRule="evenodd"
|
|
stroke="#000"
|
|
strokeWidth="1.5"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
async function getFeatures() {
|
|
try {
|
|
let itemIds = await kv.zrange("items_by_score", 0, 100, {
|
|
rev: true,
|
|
});
|
|
|
|
if (!itemIds.length) {
|
|
return [];
|
|
}
|
|
|
|
let multi = kv.multi();
|
|
itemIds.forEach((id) => {
|
|
multi.hgetall(`item:${id}`);
|
|
});
|
|
|
|
let items: Feature[] = await multi.exec();
|
|
return items.map((item) => {
|
|
return {
|
|
...item,
|
|
score: item.score,
|
|
created_at: item.created_at,
|
|
};
|
|
});
|
|
} catch (error) {
|
|
console.error(error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
export default async function Page() {
|
|
let features = await getFeatures();
|
|
|
|
return (
|
|
<div className="flex flex-col items-center justify-center min-h-screen py-2">
|
|
<main className="flex flex-col items-center justify-center flex-1 px-4 sm:px-20 text-center">
|
|
<div className="flex justify-center items-center bg-black rounded-full w-16 sm:w-24 h-16 sm:h-24 my-8">
|
|
<VercelLogo className="h-8 sm:h-16 invert p-3 mb-1" />
|
|
</div>
|
|
<h1 className="text-lg sm:text-2xl font-bold mb-2">
|
|
Help us prioritize our roadmap
|
|
</h1>
|
|
<h2 className="text-md sm:text-xl mx-4">
|
|
Create or vote up features you want to see in our product.
|
|
</h2>
|
|
<div className="flex flex-wrap items-center justify-around max-w-4xl my-8 sm:w-full bg-white rounded-md shadow-xl h-full border border-gray-100">
|
|
<FeatureForm features={features} />
|
|
<hr className="border-1 border-gray-200 my-8 mx-8 w-full" />
|
|
<div className="mx-8 w-full">
|
|
<p className="flex text-gray-500">
|
|
Leave your email address here to be notified when feature requests
|
|
are released.
|
|
</p>
|
|
<form className="relative my-4" action={saveEmail}>
|
|
<input
|
|
name="email"
|
|
aria-label="Email for updates"
|
|
placeholder="Email Address"
|
|
type="email"
|
|
autoComplete="email"
|
|
maxLength={60}
|
|
required
|
|
className="px-3 py-3 mt-1 text-lg block w-full border border-gray-200 rounded-md text-gray-900 placeholder-gray-400 focus:outline-none focus:ring focus:ring-blue-300"
|
|
/>
|
|
<button
|
|
className="flex items-center justify-center absolute right-2 top-2 px-4 h-10 border border-gray-200 text-gray-900 rounded-md w-14 focus:outline-none focus:ring focus:ring-blue-300 focus:bg-gray-100"
|
|
type="submit"
|
|
>
|
|
OK
|
|
</button>
|
|
</form>
|
|
<div className="flex flex-col sm:flex-row justify-between items-center">
|
|
<p className="flex items-center my-8 w-full justify-center sm:justify-start">
|
|
Powered by
|
|
<VercelLogo className="h-5 mx-2" />
|
|
</p>
|
|
<a
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="flex rounded focus:outline-none focus:ring focus:ring-blue-300 mb-4 sm:mb-0 min-w-max"
|
|
href={`https://vercel.com/new/git/external?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Ftree%2Fcanary%2Fexamples%2Fwith-redis&project-name=redis-roadmap&repository-name=redis-roadmap&demo-title=Redis%20Roadmap&demo-description=Create%20and%20upvote%20features%20for%20your%20product.&demo-url=https%3A%2F%2Froadmap-redis.vercel.app%2F&stores=%5B%7B"type"%3A"kv"%7D%5D&`}
|
|
>
|
|
<img
|
|
src="https://vercel.com/button"
|
|
alt="Vercel Deploy Button"
|
|
/>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|