Skip to content

Commit

Permalink
add basic auth with discord
Browse files Browse the repository at this point in the history
  • Loading branch information
d-ivashchuk committed Mar 26, 2024
1 parent 3099538 commit da83913
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 57 deletions.
43 changes: 21 additions & 22 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
/** @type {import("eslint").Linter.Config} */
const config = {
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": true
parser: "@typescript-eslint/parser",
ignorePatterns: ["prettier.config.mjs"],
parserOptions: {
project: true,
},
"plugins": [
"@typescript-eslint"
],
"extends": [
plugins: ["@typescript-eslint"],
extends: [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended-type-checked",
"plugin:@typescript-eslint/stylistic-type-checked",
"plugin:storybook/recommended"
"plugin:storybook/recommended",
],
"rules": {
rules: {
"@typescript-eslint/array-type": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/consistent-type-imports": [
"warn",
{
"prefer": "type-imports",
"fixStyle": "inline-type-imports"
}
prefer: "type-imports",
fixStyle: "inline-type-imports",
},
],
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_"
}
argsIgnorePattern: "^_",
},
],
"@typescript-eslint/require-await": "off",
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksVoidReturn": {
"attributes": false
}
}
]
}
}
module.exports = config;
checksVoidReturn: {
attributes: false,
},
},
],
},
};
module.exports = config;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-slot": "^1.0.2",
"@sentry/nextjs": "^7.105.0",
"@t3-oss/env-nextjs": "^0.9.2",
Expand Down
72 changes: 48 additions & 24 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
4 changes: 2 additions & 2 deletions src/app/global-error.jsx → src/app/global-error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import * as Sentry from "@sentry/nextjs";
import Error from "next/error";
import { useEffect } from "react";

export default function GlobalError({ error }) {
export default function GlobalError({ error }: { error: Error }) {
useEffect(() => {
Sentry.captureException(error);
}, [error]);

return (
<html>
<body>
<Error />
<Error statusCode={500} />
</body>
</html>
);
Expand Down
15 changes: 10 additions & 5 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
'use client'

import "~/styles/globals.css";

import { Inter } from "next/font/google";

import { TRPCReactProvider } from "~/trpc/react";
import { SessionProvider } from 'next-auth/react';
import { Layout } from "~/components/patterns/layout";

const inter = Inter({
subsets: ["latin"],
variable: "--font-sans",
});

export const metadata = {
title: "Create T3 App",
description: "Generated by create-t3-app",
icons: [{ rel: "icon", url: "/favicon.ico" }],
};
// export const metadata = {
// title: "Create T3 App",
// description: "Generated by create-t3-app",
// icons: [{ rel: "icon", url: "/favicon.ico" }],
// };

export default function RootLayout({
children,
Expand All @@ -25,7 +28,9 @@ export default function RootLayout({
<html lang="en">
<body className={`font-sans ${inter.variable}`}>
<TRPCReactProvider>
<SessionProvider>
<Layout>{children}</Layout>
</SessionProvider>
</TRPCReactProvider>
</body>
</html>
Expand Down
12 changes: 12 additions & 0 deletions src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { LoginScreen } from '~/components/patterns/login-screen';

const LoginPage = () => {
return (
<div>
<LoginScreen />
</div>
);
};

export default LoginPage;
10 changes: 6 additions & 4 deletions src/components/patterns/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Link from "next/link";
import { CircleUser, Menu, Package2, Search } from "lucide-react";
import { Menu, Package2, Search } from "lucide-react";

import { Button } from "~/components/ui/button";

Expand All @@ -13,8 +13,10 @@ import {
} from "~/components/ui/dropdown-menu";
import { Input } from "~/components/ui/input";
import { Sheet, SheetContent, SheetTrigger } from "~/components/ui/sheet";
import LoginLogoutButton from "./login-logout-button";
import UserButton from "./user-button";

export function Layout({ children }: { children: React.ReactNode }) {
export async function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="flex min-h-screen w-full flex-col">
<header className="sticky top-0 flex h-16 items-center gap-4 border-b bg-background px-4 md:px-6">
Expand Down Expand Up @@ -121,7 +123,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" size="icon" className="rounded-full">
<CircleUser className="h-5 w-5" />
<UserButton />
<span className="sr-only">Toggle user menu</span>
</Button>
</DropdownMenuTrigger>
Expand All @@ -130,8 +132,8 @@ export function Layout({ children }: { children: React.ReactNode }) {
<DropdownMenuSeparator />
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Support</DropdownMenuItem>
<LoginLogoutButton />
<DropdownMenuSeparator />
<DropdownMenuItem>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
Expand Down
24 changes: 24 additions & 0 deletions src/components/patterns/login-logout-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use client";

import { DropdownMenuItem } from "~/components/ui/dropdown-menu";

import { signOut, useSession } from "next-auth/react";
import { useRouter } from "next/navigation";

const LoginLogoutButton = () => {
const session = useSession();
const isAuthenticated =
session.status !== "loading" && session.status === "authenticated";

const router = useRouter();

return (
<DropdownMenuItem
onClick={() => (isAuthenticated ? signOut() : router.push("/login"))}
>
{isAuthenticated ? "Logout" : "Login"}
</DropdownMenuItem>
);
};

export default LoginLogoutButton;
41 changes: 41 additions & 0 deletions src/components/patterns/login-screen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"use client";

import { signIn } from "next-auth/react";
import Image from "next/image";

import { Button } from "~/components/ui/button";

export function LoginScreen() {
return (
<div className="w-full lg:grid lg:min-h-[600px] lg:grid-cols-2 xl:min-h-[800px]">
<div className="flex items-center justify-center py-12">
<div className="mx-auto grid w-[350px] gap-6">
<div className="grid gap-2 text-center">
<h1 className="text-3xl font-bold">Login</h1>
<p className="text-balance text-muted-foreground">
Authenticate with a common provider
</p>
</div>
<div className="grid gap-4">
<Button
onClick={() => signIn("discord", { callbackUrl: "/" })}
variant="outline"
className="w-full"
>
Login with Discord
</Button>
</div>
</div>
</div>
<div className="hidden bg-muted lg:block">
<Image
src="/placeholder.svg"
alt="Image"
width="1920"
height="1080"
className="h-full w-full object-cover dark:brightness-[0.2] dark:grayscale"
/>
</div>
</div>
);
}
Loading

0 comments on commit da83913

Please sign in to comment.