feat: switch next auth and drizzle to supabase (#1)

* feat: add supabase

* feat: setup auth

* feat: test refactoring board queries

* feat: convert to pages router

* feat: convert board router to supabase

* feat: swap out drizzle for supabase in label, list and workspace routers

* feat: swap out drizzle for supabase on the import router

* feat: swap drizzle for supabase on create new card

* feat: switch card router to use supabase

* feat: finish swapping drizzle for supabase

* chore: lint all router files

* fix: signout

* chore: fix types
This commit is contained in:
Henry
2024-04-23 11:57:34 +01:00
committed by GitHub
parent 1711df03e7
commit d15870118d
96 changed files with 3636 additions and 1521 deletions

44
src/pages/_app.tsx Normal file
View File

@@ -0,0 +1,44 @@
import "~/styles/globals.css";
import { type AppType } from "next/app";
import { Plus_Jakarta_Sans } from "next/font/google";
import { ModalProvider } from "~/providers/modal";
import { BoardProvider } from "~/providers/board";
import { ThemeProvider } from "~/providers/theme";
import { api } from "~/utils/api";
const jakarta = Plus_Jakarta_Sans({
subsets: ["latin"],
display: "swap",
});
export const metadata = {
title: "Kan",
description: "The open source Trello alternative",
icons: [{ rel: "icon", url: "/favicon.ico" }],
};
const MyApp: AppType = ({ Component, pageProps }) => {
return (
<>
<style jsx global>{`
html {
font-family: ${jakarta.style.fontFamily};
}
`}</style>
<main className="h-screen overflow-hidden font-sans">
<ThemeProvider>
<ModalProvider>
<BoardProvider>
<Component {...pageProps} />
</BoardProvider>
</ModalProvider>
</ThemeProvider>
</main>
</>
);
};
export default api.withTRPC(MyApp);

View File

@@ -0,0 +1,39 @@
import { type EmailOtpType } from "@supabase/supabase-js";
import type { NextApiRequest, NextApiResponse } from "next";
import createClient from "~/utils/supabase/api";
function stringOrFirstString(item: string | string[] | undefined) {
return Array.isArray(item) ? item[0] : item;
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
if (req.method !== "GET") {
res.status(405).appendHeader("Allow", "GET").end();
return;
}
const queryParams = req.query;
const token_hash = stringOrFirstString(queryParams.token_hash);
const type = stringOrFirstString(queryParams.type);
let next = "/error";
if (token_hash && type) {
const supabase = createClient(req, res);
const { error } = await supabase.auth.verifyOtp({
type: type as EmailOtpType,
token_hash,
});
if (error) {
console.error(error);
} else {
next = stringOrFirstString(queryParams.next) ?? "/";
}
}
res.redirect(next);
}

View File

@@ -0,0 +1,27 @@
import { type NextApiRequest, type NextApiResponse } from "next";
import { createNextApiHandler } from "@trpc/server/adapters/next";
import { env } from "~/env.mjs";
import { appRouter } from "~/server/api/root";
import { createTRPCContext } from "~/server/api/trpc";
const nextApiHandler = createNextApiHandler({
router: appRouter,
createContext: createTRPCContext,
onError:
env.NODE_ENV === "development"
? ({ path, error }) => {
console.error(
`❌ tRPC failed on ${path ?? "<no-path>"}: ${error.message}`,
);
}
: undefined,
});
export default function handler(req: NextApiRequest, res: NextApiResponse) {
return nextApiHandler(req, res);
}
// export const runtime = "edge";
// export const preferredRegion = 'lhr1';
// export const dynamic = 'force-dynamic'

View File

@@ -0,0 +1,13 @@
import { WorkspaceProvider } from "~/providers/workspace";
import Dashboard from "~/components/dashboard";
import BoardView from "~/views/board";
export default function BoardPage() {
return (
<WorkspaceProvider>
<Dashboard>
<BoardView />
</Dashboard>
</WorkspaceProvider>
);
}

View File

@@ -0,0 +1,13 @@
import { WorkspaceProvider } from "~/providers/workspace";
import Dashboard from "~/components/dashboard";
import BoardsView from "~/views/boards";
export default function BoardsPage() {
return (
<WorkspaceProvider>
<Dashboard>
<BoardsView />
</Dashboard>
</WorkspaceProvider>
);
}

View File

@@ -0,0 +1,13 @@
import { WorkspaceProvider } from "~/providers/workspace";
import Dashboard from "~/components/dashboard";
import CardView from "~/views/card";
export default function CardPage() {
return (
<WorkspaceProvider>
<Dashboard>
<CardView />
</Dashboard>
</WorkspaceProvider>
);
}

View File

@@ -0,0 +1,5 @@
import LoginView from "~/views/auth/login";
export default function LoginPage() {
return <LoginView />;
}

View File

@@ -0,0 +1,13 @@
import { WorkspaceProvider } from "~/providers/workspace";
import Dashboard from "~/components/dashboard";
import MembersView from "~/views/members";
export default function MembersPage() {
return (
<WorkspaceProvider>
<Dashboard>
<MembersView />
</Dashboard>
</WorkspaceProvider>
);
}

View File

@@ -0,0 +1,13 @@
import { WorkspaceProvider } from "~/providers/workspace";
import Dashboard from "~/components/dashboard";
import SettingsView from "~/views/settings";
export default function SettingsPage() {
return (
<WorkspaceProvider>
<Dashboard>
<SettingsView />
</Dashboard>
</WorkspaceProvider>
);
}

View File

@@ -0,0 +1,5 @@
import VerifyView from "~/views/auth/verify";
export default function VerifyPage() {
return <VerifyView />;
}