Skip to content

Commit

Permalink
fix: deep links
Browse files Browse the repository at this point in the history
  • Loading branch information
froid1911 committed Feb 26, 2024
1 parent 102ca4a commit 7ac2c94
Show file tree
Hide file tree
Showing 19 changed files with 419 additions and 253 deletions.
3 changes: 2 additions & 1 deletion frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ FROM node:lts-alpine AS runner
ARG X_TAG
WORKDIR /opt/app
ENV NODE_ENV=production
EXPOSE 3000
COPY --from=builder /opt/app/next.config.mjs ./
COPY --from=builder /opt/app/public ./public
COPY --from=builder /opt/app/.next ./.next
COPY --from=builder /opt/app/node_modules ./node_modules
CMD ["node_modules/.bin/next", "start"]
CMD ["node_modules/.bin/next", "start"]
Binary file added frontend/src/app/favicon.ico
Binary file not shown.
24 changes: 24 additions & 0 deletions frontend/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
}

@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
}
}


@layer utilities {
.text-balance {
text-wrap: balance;
}
}
16 changes: 16 additions & 0 deletions frontend/src/app/graphql/[driveId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";
import GraphQLIframe from "@/components/graphql/iframe";
import { useParams } from "next/navigation";
import { Suspense } from "react";

export default function GraphQLDrive() {
const params = useParams<{ driveId: string }>();

return (
<Suspense>
<GraphQLIframe
url={`${process.env.NEXT_PUBLIC_SWITCHBOARD_HOST}/explorer/${params?.driveId}`}
/>
</Suspense>
);
}
13 changes: 13 additions & 0 deletions frontend/src/app/graphql/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use client";
import GraphQLIframe from "@/components/graphql/iframe";
import { Suspense } from "react";

export default function GraphQL() {
return (
<Suspense>
<GraphQLIframe
url={`${process.env.NEXT_PUBLIC_SWITCHBOARD_HOST}/explorer`}
/>
</Suspense>
);
}
46 changes: 46 additions & 0 deletions frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Head from "next/head";
import Header from "@/components/header/header";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "Switchboard API",
description: "Switchboard API is a decentralized API gateway for Web3.0.",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<head>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>

<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="manifest" href="/site.webmanifest" />
</head>
<body className={inter.className}>
<div className="bg-gray-100">
<Header />
<main className={`mx-auto mt-14 min-h-[calc(100vh-64px)] `}>
<div className="">{children}</div>
</main>
</div>
</body>
</html>
);
}
3 changes: 3 additions & 0 deletions frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function User() {
return <iframe src="https://www.powerhouse.inc/switchboard" height="100%" width="100%" className="min-h-[calc(100vh-63px)]" />;
}
64 changes: 64 additions & 0 deletions frontend/src/app/user/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"use client";
import TokenForm from "@/components/tokens/token-form";
import TokensTable from "@/components/tokens/tokens-table";
import useAuth, { authStore } from "@/hooks/useAuth";
import { ArrowRightStartOnRectangleIcon } from "@heroicons/react/24/solid";
import Link from "next/link";

const User = () => {
const address = authStore((state) => state.address);

const { signIn, signOut } = useAuth();

if (!address) {
return (
<div className="flex flex-col gap-8 pt-14">
<button
type="submit"
className={`bg-orange-500 text-xs hover:bg-orange-600 text-white font-semibold py-2 px-4 rounded mx-auto`}
onClick={() => {
signIn();
}}
>
<div className="flex flex-row items-center text-white rounded">
<div className="w-8">
<ArrowRightStartOnRectangleIcon className="" />
</div>{" "}
<div className="w-32 grow">Sign in with Ethereum</div>
</div>
</button>
</div>
);
}
return (
<div className="flex flex-col gap-8 pt-14">
<div className="bg-white px-5 flex flex-row gap-4 items-center my-auto">
<div className="flex py-2 border-b-4 border-orange-600 text-orange-500">
API Tokens
</div>
<div className="flex grow justify-end">
<Link
onClick={() => {
signOut();
}}
href={"/"}
>
<div className="flex flex-row items-center text-orange-400 hover:bg-gray-300 rounded">
<div className="w-20">Sign Out</div>{" "}
<div className="w-8">
<ArrowRightStartOnRectangleIcon className="text-orange-500" />
</div>
</div>
</Link>
</div>
</div>
<TokenForm />
<div className="bg-white p-5 flex-flex-col gap-4">
<div className="font-semibold mb-4">Existing Tokens</div>
<TokensTable />
</div>
</div>
);
};

export default User;
14 changes: 14 additions & 0 deletions frontend/src/components/graphql/iframe.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useSearchParams } from "next/navigation";

export default function GraphQLIframe({ url }: { url: string }) {
const searchParams = useSearchParams();
const query = searchParams?.get("query");
return (
<iframe
src={`${url}${query ? "?query=" + query : ""}`}
height="100%"
width="100%"
className="min-h-[calc(100vh-63px)]"
/>
);
}
158 changes: 90 additions & 68 deletions frontend/src/components/header/header.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,102 @@
"use client";
import Image from "next/image";
import SwitchboardLink from "../text/Link";
import useAuth, { authStore } from "@/hooks/useAuth";
import { useRouter } from "next/router";
import { useRouter } from "next/navigation";
import { UserCircleIcon } from "@heroicons/react/24/solid";
import Link from "next/link";
import { useEffect, useState } from "react";

export default function Header() {
const address = authStore((state) => state.address);
const gqlToken = authStore((state) => state.gqlToken);
const auth = useAuth();
const router = useRouter();
const address = authStore((state) => state.address);
const gqlToken = authStore((state) => state.gqlToken);
const auth = useAuth();
const router = useRouter();

const [drives, setDrives] = useState([]);
const [drives, setDrives] = useState([]);

useEffect(() => {
if (!gqlToken) {
return;
}
auth.checkAuthValidity();
auth.getDrives().then((drives) => {
setDrives(drives);
});
}, [gqlToken]);
useEffect(() => {
if (!gqlToken) {
return;
}
auth.checkAuthValidity();
auth.getDrives().then((drives) => {
setDrives(drives);
});
}, [gqlToken]);

const selectGraphQLPlayground = (e: React.ChangeEvent<HTMLSelectElement>) => {
e.preventDefault();
const drive = e.target.value;
if (drive === "system") {
router.push(`/graphql`);
} else if (drive !== "") {
router.push(`/graphql/${drive}`);
}
};
return (
<header className="bg-orange-100 fixed w-full top-0 text-black h-14">
<nav className="flex justify-between items-center flex-row h-14">
<div className="flex items-start">
<SwitchboardLink href="/">
<div className="flex flex-row items-center">
<img src="/assets/logo.svg" className="w-10" />
Switchboard API
</div>
</SwitchboardLink>
</div>
<div className="flex justify-center gap-4">
{address !== "" ? (
<select id="graphqlPlayground" name="graphqlPlayground" aria-placeholder="Select GraphQL Playground" className="p-2 border border-gray-300 rounded-md w-full" onChange={selectGraphQLPlayground}>
<option value="">GraphQL Playgrounds</option>
<option value="system">System</option>
{drives.map((drive, i) => (
<option value={drive} key={i}>
{drive}
</option>
))}
</select>
) : (
""
)}
</div>
<div className="flex flex-row gap-2">
<div className="flex items-center text-orange-300">
<SwitchboardLink className="bg-orange-200 rounded-2xl px-4 text-orange-400 flex flex-row items-center gap-2 py-2" href="/user">
<span>{address !== "" ? address.slice(0, 4) + "..." + address.slice(-4) : "Login"}</span>
<span className="h-5">
<UserCircleIcon className="h-5" />
</span>
</SwitchboardLink>
</div>
<div className="text-orange-300 pr-2 my-auto">
<Link href="https://github.com/powerhouse-inc/switchboard-boilerplate" target="_blank">
<Image src="/assets/github.svg" alt="GitHub" width="32" height="32" />
</Link>
</div>
</div>
</nav>
</header>
);
const selectGraphQLPlayground = (e: React.ChangeEvent<HTMLSelectElement>) => {
e.preventDefault();
const drive = e.target.value;
if (drive === "system") {
router.push(`/graphql`);
} else if (drive !== "") {
router.push(`/graphql/${drive}`);
}
};
return (
<header className="bg-orange-100 fixed w-full top-0 text-black h-14">
<nav className="flex justify-between items-center flex-row h-14">
<div className="flex items-start">
<SwitchboardLink href="/">
<div className="flex flex-row items-center">
<img src="/assets/logo.svg" className="w-10" />
Switchboard API
</div>
</SwitchboardLink>
</div>
<div className="flex justify-center gap-4">
{address !== "" ? (
<select
id="graphqlPlayground"
name="graphqlPlayground"
aria-placeholder="Select GraphQL Playground"
className="p-2 border border-gray-300 rounded-md w-full"
onChange={selectGraphQLPlayground}
>
<option value="">GraphQL Playgrounds</option>
<option value="system">System</option>
{drives.map((drive, i) => (
<option value={drive} key={i}>
{drive}
</option>
))}
</select>
) : (
""
)}
</div>
<div className="flex flex-row gap-2">
<div className="flex items-center text-orange-300">
<SwitchboardLink
className="bg-orange-200 rounded-2xl px-4 text-orange-400 flex flex-row items-center gap-2 py-2"
href="/user"
>
<span>
{address !== ""
? address.slice(0, 4) + "..." + address.slice(-4)
: "Login"}
</span>
<span className="h-5">
<UserCircleIcon className="h-5" />
</span>
</SwitchboardLink>
</div>
<div className="text-orange-300 pr-2 my-auto">
<Link
href="https://github.com/powerhouse-inc/switchboard-boilerplate"
target="_blank"
>
<Image
src="/assets/github.svg"
alt="GitHub"
width="32"
height="32"
/>
</Link>
</div>
</div>
</nav>
</header>
);
}
Loading

0 comments on commit 7ac2c94

Please sign in to comment.