Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration to NextUI & App Router #916

Merged
merged 32 commits into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7a1331e
Migration to NextUI & App Router
ken-matsui Dec 26, 2023
48d25cd
Finish index
ken-matsui Dec 26, 2023
267b065
Tweak meta
ken-matsui Dec 26, 2023
9151dbd
Add new progress bar
ken-matsui Dec 26, 2023
9699390
Finish layout
ken-matsui Dec 26, 2023
e5eef3d
Finish not-found
ken-matsui Dec 26, 2023
7727825
tweak
ken-matsui Dec 26, 2023
ee0d0ba
Remove pages/_document.tsx
ken-matsui Dec 26, 2023
4cbd053
Complete header other than search
ken-matsui Dec 26, 2023
c0eb645
Update logo
ken-matsui Dec 26, 2023
5495a14
Format codes
ken-matsui Dec 26, 2023
e90dd33
Remove unused imports
ken-matsui Dec 26, 2023
77ef716
Organize files
ken-matsui Dec 26, 2023
81337d0
Organize files
ken-matsui Dec 26, 2023
f698957
Search component
ken-matsui Dec 26, 2023
5f82c3c
Search route
ken-matsui Dec 26, 2023
e501481
Add type
ken-matsui Dec 26, 2023
cca9538
Some improvements
ken-matsui Dec 26, 2023
e46e083
Finish search other than links
ken-matsui Dec 26, 2023
e42f94e
Finish search page
ken-matsui Dec 26, 2023
9f0adb0
Design tweaks
ken-matsui Dec 26, 2023
4b9cb30
Design tweaks
ken-matsui Dec 26, 2023
b9ea4f4
Organize files
ken-matsui Dec 26, 2023
5104b1c
yarn lint --apply
ken-matsui Dec 26, 2023
19caaf6
yarn lint --apply-unsafe
ken-matsui Dec 26, 2023
17c4dbb
version page
ken-matsui Dec 26, 2023
a7d2910
removed unused packages
ken-matsui Dec 26, 2023
df172a3
framer-motion is needed
ken-matsui Dec 26, 2023
c2a7be6
finish name page
ken-matsui Dec 26, 2023
35f8c9b
yarn fmt
ken-matsui Dec 26, 2023
2973b9c
yarn lint --apply
ken-matsui Dec 26, 2023
f8bbde1
Improve types
ken-matsui Dec 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions app/_components/footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function Footer() {
return (
<footer className="container mx-auto max-w-7xl pb-12 px-12">
<div className="flex flex-col justify-center items-center gap-1">
<p className="text-sm text-default-400">
© {new Date().getFullYear()} Ken Matsui
</p>
</div>
</footer>
);
}
81 changes: 81 additions & 0 deletions app/_components/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { faGithub } from "@fortawesome/free-brands-svg-icons";
import { faBookOpen, faHeart } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
Button,
Link,
Navbar,
NavbarBrand,
NavbarContent,
NavbarItem,
} from "@nextui-org/react";
import NextLink from "next/link";

import { Logo } from "./logo";
import { SearchButton } from "./search";

export function Header() {
return (
<Navbar>
<NavbarBrand>
<NextLink href="/">
<Logo />
</NextLink>
</NavbarBrand>
<NavbarContent justify="center">
<NavbarItem>
<SearchButton />
</NavbarItem>
</NavbarContent>
<NavbarContent className="hidden sm:flex gap-4" justify="end">
<NavbarItem>
<Link
isExternal
aria-label="Docs"
className="p-1 text-default-600 dark:text-default-500 text-sm"
href="https://doc.poac.dev"
>
<FontAwesomeIcon
className="text-default-600 dark:text-default-500"
icon={faBookOpen}
width={20}
/>
&nbsp;Docs
</Link>
</NavbarItem>
<NavbarItem>
<Link
isExternal
aria-label="Github"
className="p-1"
href="https://github.com/poac-dev"
>
<FontAwesomeIcon
className="text-default-600 dark:text-default-500"
icon={faGithub}
width={20}
/>
</Link>
</NavbarItem>
<NavbarItem>
<Button
isExternal
as={Link}
className="group text-sm font-normal text-default-600 bg-default-400/20 dark:bg-default-500/20"
href="https://github.com/sponsors/ken-matsui"
startContent={
<FontAwesomeIcon
className="text-danger"
icon={faHeart}
width={15}
/>
}
variant="flat"
>
Sponsor
</Button>
</NavbarItem>
</NavbarContent>
</Navbar>
);
}
44 changes: 44 additions & 0 deletions app/_components/logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from "react";

export const Logo = () => (
<svg width="72" height="36" viewBox="0 0 985 420">
<title>Group</title>
<defs>
<radialGradient
cx="10.5172853%"
cy="100%"
fx="10.5172853%"
fy="100%"
r="119.945282%"
gradientTransform="translate(0.105173,1.000000),scale(1.000000,0.952381),rotate(-51.739535),scale(1.000000,0.892357),translate(-0.105173,-1.000000)"
id="radialGradient-1"
>
<stop stopColor="#3023AE" offset="0%" />
<stop stopColor="#53A0FD" offset="79.8743881%" />
<stop stopColor="#51DEEC" offset="100%" />
</radialGradient>
</defs>
<g
id="logo-copy"
stroke="none"
strokeWidth="1"
fill="none"
fillRule="evenodd"
>
<g id="logo" transform="translate(-40.000000, -20.000000)">
<g id="Group" transform="translate(40.000000, 20.000000)">
<path
d="M0,200 C0,0 183.916355,0 200,0 C216.083645,0 400,0 400,200 C400,360.602127 263.263237,400 200,400 C169.940075,400 130.053436,383.872837 110.053436,360 C83.687159,328.528108 81.6540229,287.441333 100,280 C120,271.887777 144.702055,320 200,320 C255.297945,320 320,270.651856 320,200 C320,129.348144 280,80 200,80 C120,80 79.9607444,129.348144 79.9607444,200 L79.9607444,380 C79.9607444,400.484491 52.5173973,420 40,420 C27.4826027,420 0,398.833096 0,380 L0,200 Z M200,260 C166.862915,260 140,233.137085 140,200 C140,166.862915 166.862915,140 200,140 C233.137085,140 260,166.862915 260,200 C260,233.137085 233.137085,260 200,260 Z"
id="Shape"
fill="url(#radialGradient-1)"
/>
<path
d="M518.52,397.05 C521.586667,397.05 524.116667,396.053333 526.11,394.06 C528.103333,392.066667 529.1,389.536667 529.1,386.47 L529.1,386.47 L529.1,327.82 C540.293333,339.473333 553.403333,345.3 568.43,345.3 C577.936667,345.3 586.945,342.885 595.455,338.055 C603.965,333.225 610.865,326.171667 616.155,316.895 C621.445,307.618333 624.09,296.77 624.09,284.35 C624.09,271.93 621.445,261.081667 616.155,251.805 C610.865,242.528333 603.965,235.475 595.455,230.645 C586.945,225.815 577.936667,223.4 568.43,223.4 C553.403333,223.4 540.293333,229.226667 529.1,240.88 L529.1,240.88 L529.1,234.9 C529.1,231.986667 528.065,229.533333 525.995,227.54 C523.925,225.546667 521.433333,224.55 518.52,224.55 C515.606667,224.55 513.153333,225.546667 511.16,227.54 C509.166667,229.533333 508.17,231.986667 508.17,234.9 L508.17,234.9 L508.17,386.47 C508.17,389.383333 509.166667,391.875 511.16,393.945 C513.153333,396.015 515.606667,397.05 518.52,397.05 Z M565.44,325.75 C558.386667,325.75 551.755,324.178333 545.545,321.035 C539.335,317.891667 533.853333,313.713333 529.1,308.5 L529.1,308.5 L529.1,260.2 C533.853333,254.986667 539.335,250.808333 545.545,247.665 C551.755,244.521667 558.386667,242.95 565.44,242.95 C576.786667,242.95 585.91,246.553333 592.81,253.76 C599.71,260.966667 603.16,271.163333 603.16,284.35 C603.16,297.536667 599.71,307.733333 592.81,314.94 C585.91,322.146667 576.786667,325.75 565.44,325.75 Z M693.55,345.3 C705.203333,345.3 715.476667,342.77 724.37,337.71 C733.263333,332.65 740.163333,325.481667 745.07,316.205 C749.976667,306.928333 752.43,296.31 752.43,284.35 C752.43,272.39 749.976667,261.771667 745.07,252.495 C740.163333,243.218333 733.263333,236.05 724.37,230.99 C715.476667,225.93 705.203333,223.4 693.55,223.4 C681.743333,223.4 671.393333,225.93 662.5,230.99 C653.606667,236.05 646.745,243.218333 641.915,252.495 C637.085,261.771667 634.67,272.39 634.67,284.35 C634.67,296.31 637.085,306.928333 641.915,316.205 C646.745,325.481667 653.606667,332.65 662.5,337.71 C671.393333,342.77 681.743333,345.3 693.55,345.3 Z M693.55,326.21 C687.11,326.21 681.015,324.753333 675.265,321.84 C669.515,318.926667 664.8,314.326667 661.12,308.04 C657.44,301.753333 655.6,293.78 655.6,284.12 C655.6,274.613333 657.44,266.716667 661.12,260.43 C664.8,254.143333 669.515,249.581667 675.265,246.745 C681.015,243.908333 687.11,242.49 693.55,242.49 C699.836667,242.49 705.855,243.908333 711.605,246.745 C717.355,249.581667 722.108333,254.143333 725.865,260.43 C729.621667,266.716667 731.5,274.613333 731.5,284.12 C731.5,293.78 729.621667,301.753333 725.865,308.04 C722.108333,314.326667 717.355,318.926667 711.605,321.84 C705.855,324.753333 699.836667,326.21 693.55,326.21 Z M800.04,345.3 C817.52,345.3 831.933333,339.473333 843.28,327.82 L843.28,327.82 L843.28,333.8 C843.28,336.713333 844.276667,339.166667 846.27,341.16 C848.263333,343.153333 850.716667,344.15 853.63,344.15 C856.543333,344.15 859.035,343.153333 861.105,341.16 C863.175,339.166667 864.21,336.713333 864.21,333.8 L864.21,333.8 L864.21,268.71 C864.21,260.736667 862.485,253.338333 859.035,246.515 C855.585,239.691667 850.218333,234.133333 842.935,229.84 C835.651667,225.546667 826.72,223.4 816.14,223.4 C802.646667,223.4 789.383333,226.16 776.35,231.68 C772.363333,233.366667 770.37,236.28 770.37,240.42 C770.37,242.873333 771.213333,244.943333 772.9,246.63 C774.586667,248.316667 776.58,249.16 778.88,249.16 C779.646667,249.16 780.643333,249.006667 781.87,248.7 C787.39,246.86 792.411667,245.48 796.935,244.56 C801.458333,243.64 806.633333,243.18 812.46,243.18 C823.04,243.18 830.821667,245.403333 835.805,249.85 C840.788333,254.296667 843.28,261.58 843.28,271.7 L843.28,271.7 L843.28,273.54 L815.45,273.54 C798.123333,273.54 784.975,276.913333 776.005,283.66 C767.035,290.406667 762.55,299.453333 762.55,310.8 C762.55,317.7 764.236667,323.795 767.61,329.085 C770.983333,334.375 775.545,338.4 781.295,341.16 C787.045,343.92 793.293333,345.3 800.04,345.3 Z M807.86,326.9 C799.12,326.9 792.871667,325.213333 789.115,321.84 C785.358333,318.466667 783.48,314.02 783.48,308.5 C783.48,296.386667 795.056667,290.33 818.21,290.33 L818.21,290.33 L843.28,290.33 L843.28,309.65 C838.986667,314.556667 833.696667,318.658333 827.41,321.955 C821.123333,325.251667 814.606667,326.9 807.86,326.9 Z M942.18,345.3 C950.306667,345.3 957.321667,344.265 963.225,342.195 C969.128333,340.125 974.61,337.48 979.67,334.26 C982.736667,332.266667 984.27,329.583333 984.27,326.21 C984.27,323.91 983.388333,321.801667 981.625,319.885 C979.861667,317.968333 977.83,317.01 975.53,317.01 C973.843333,317.01 972.156667,317.47 970.47,318.39 C965.41,320.996667 961.078333,322.875 957.475,324.025 C953.871667,325.175 949.386667,325.75 944.02,325.75 C930.833333,325.75 920.483333,321.955 912.97,314.365 C905.456667,306.775 901.7,296.77 901.7,284.35 C901.7,271.93 905.456667,261.925 912.97,254.335 C920.483333,246.745 930.833333,242.95 944.02,242.95 C949.386667,242.95 953.871667,243.525 957.475,244.675 C961.078333,245.825 965.41,247.703333 970.47,250.31 C972.156667,251.23 973.843333,251.69 975.53,251.69 C977.83,251.69 979.861667,250.731667 981.625,248.815 C983.388333,246.898333 984.27,244.79 984.27,242.49 C984.27,239.116667 982.736667,236.433333 979.67,234.44 C974.61,231.22 969.128333,228.575 963.225,226.505 C957.321667,224.435 950.306667,223.4 942.18,223.4 C931.14,223.4 920.943333,225.853333 911.59,230.76 C902.236667,235.666667 894.761667,242.72 889.165,251.92 C883.568333,261.12 880.77,271.93 880.77,284.35 C880.77,296.77 883.568333,307.58 889.165,316.78 C894.761667,325.98 902.236667,333.033333 911.59,337.94 C920.943333,342.846667 931.14,345.3 942.18,345.3 Z"
fillRule="nonzero"
style={{ fill: "whitesmoke" }}
/>
</g>
</g>
</g>
</svg>
);
39 changes: 39 additions & 0 deletions app/_components/search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"use client";

import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Input } from "@nextui-org/react";
import { useRouter } from "next/navigation";
import { useState } from "react";

export function SearchButton() {
const [value, setValue] = useState("");
const router = useRouter();

const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === "Enter") {
router.push(`/search?q=${value}`);
}
};

return (
<Input
type="search"
placeholder="Search packages"
aria-label="Search packages"
labelPlacement="outside"
startContent={
<FontAwesomeIcon
className="text-default-600 dark:text-default-500"
icon={faMagnifyingGlass}
width={13}
/>
}
value={value}
onValueChange={setValue}
onKeyDown={handleKeyDown}
>
Search packages
</Input>
);
}
72 changes: 72 additions & 0 deletions app/_components/window-actions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// This code is based on the original code found at Next UI.
// https://github.com/nextui-org/nextui/blob/132efbcb6d3828ec7aab2cb2d0c79db3868dee92/apps/docs/components/code-window/window-actions.tsx
// Modifications have been made to fit the specific needs of this project.
/*
MIT License

Copyright (c) 2020 Next UI

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

import { clsx } from "@nextui-org/shared-utils";
import React from "react";
import { tv } from "tailwind-variants";

export type WindowActionsProps = {
title?: string;
className?: string;
};

const windowIconStyles = tv({
base: "w-3 h-3 rounded-full",
variants: {
color: {
red: "bg-red-500",
yellow: "bg-yellow-500",
green: "bg-green-500",
},
},
});

export const WindowActions: React.FC<WindowActionsProps> = ({
title,
className,
...props
}) => {
return (
<div
className={clsx(
"flex items-center sticky top-0 left-0 px-4 z-10 justify-between h-8 bg-code-background w-full",
className,
)}
{...props}
>
<div className="flex items-center gap-2 basis-1/3">
<div className={windowIconStyles({ color: "red" })} />
<div className={windowIconStyles({ color: "yellow" })} />
<div className={windowIconStyles({ color: "green" })} />
</div>
<div className="flex basis-1/3 h-full justify-center items-center">
{title && <p className="text-white/30 text-sm">{title}</p>}
</div>
<div className="flex basis-1/3" />
</div>
);
};
1 change: 1 addition & 0 deletions app/_lib/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const PER_PAGE = 20;
9 changes: 5 additions & 4 deletions utils/hasuraClient.ts → app/_lib/hasuraClient.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { GraphQLClient } from "graphql-request";
import { getSdk } from "../graphql/graphql";
import { HASURA_GRAPHQL_URL } from "./constants";
import { getSdk } from "~/graphql/graphql";

export const createHasuraClient = (token: string | null = null) => {
const HASURA_GRAPHQL_URL = "https://poac.hasura.app/v1/graphql";

export const getHasuraClient = (token: string | null = null) => {
const headers =
token !== null
? {
Expand All @@ -15,4 +16,4 @@ export const createHasuraClient = (token: string | null = null) => {
return getSdk(client);
};

export type HasuraClient = ReturnType<typeof createHasuraClient>;
export type HasuraClient = ReturnType<typeof getHasuraClient>;
24 changes: 24 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

html {
font-size: 16px;
padding: 0px !important;
overflow-x: hidden;
scroll-padding-top: 64px;
}

body {
min-height: 100vh;
position: relative;
}

a {
color: inherit;
text-decoration: none;
}

* {
box-sizing: border-box;
}
26 changes: 26 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Analytics } from "@vercel/analytics/react";

import { Footer } from "./_components/footer";
import { Header } from "./_components/header";
import { Providers } from "./providers";

import "./globals.css";

export default function Layout({
children,
}: { children: React.ReactNode }): JSX.Element {
return (
<html lang="en" className="dark">
<body
className={"min-h-screen bg-background font-sans antialiased"}
>
<Providers>
<Header />
{children}
<Footer />
</Providers>
<Analytics />
</body>
</html>
);
}
14 changes: 14 additions & 0 deletions app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Metadata } from "next";

export const metadata: Metadata = {
title: "404: Not Found",
};

export default function Custom404(): JSX.Element {
return (
<div className="flex flex-col items-center justify-center h-screen">
<h1 className="font-bold m-4 text-6xl">404</h1>
This page could not be found.
</div>
);
}
42 changes: 42 additions & 0 deletions app/packages/[group]/[name]/[version]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { Metadata, ResolvingMetadata } from "next";
import { notFound } from "next/navigation";
import { getHasuraClient } from "~/app/_lib/hasuraClient";
import { Pack } from "../_components/pack";

type Params = {
group: string;
name: string;
version: string;
};

type Props = {
params: Params;
searchParams: { [key: string]: string | string[] | undefined };
};

export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata,
): Promise<Metadata> {
return {
title: `${params.group}/${params.name} (v${params.version})`,
};
}

export default async function Version({ params }: { params: Params }) {
const hasuraClient = getHasuraClient();
const data = await hasuraClient.getPackageByNameAndVersion({
name: `${params.group}/${params.name}`,
version: params.version,
});
if (!data || data.packages.length === 0) {
return notFound();
}

return (
<Pack
pack={data.packages[0]}
numVersion={data.packages_aggregate?.aggregate?.count ?? 0}
/>
);
}
Loading