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:
44
src/pages/_app.tsx
Normal file
44
src/pages/_app.tsx
Normal 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);
|
||||
39
src/pages/api/auth/confirm.ts
Normal file
39
src/pages/api/auth/confirm.ts
Normal 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);
|
||||
}
|
||||
27
src/pages/api/trpc/[trpc].ts
Normal file
27
src/pages/api/trpc/[trpc].ts
Normal 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'
|
||||
13
src/pages/boards/[...boardId]/index.tsx
Normal file
13
src/pages/boards/[...boardId]/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
13
src/pages/boards/index.tsx
Normal file
13
src/pages/boards/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
13
src/pages/cards/[cardId]/index.tsx
Normal file
13
src/pages/cards/[cardId]/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
5
src/pages/login/index.tsx
Normal file
5
src/pages/login/index.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import LoginView from "~/views/auth/login";
|
||||
|
||||
export default function LoginPage() {
|
||||
return <LoginView />;
|
||||
}
|
||||
13
src/pages/members/index.tsx
Normal file
13
src/pages/members/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
13
src/pages/settings/index.tsx
Normal file
13
src/pages/settings/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
5
src/pages/verify/index.tsx
Normal file
5
src/pages/verify/index.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import VerifyView from "~/views/auth/verify";
|
||||
|
||||
export default function VerifyPage() {
|
||||
return <VerifyView />;
|
||||
}
|
||||
Reference in New Issue
Block a user