diff --git a/app/not-found.tsx b/app/not-found.tsx new file mode 100644 index 0000000..3559b51 --- /dev/null +++ b/app/not-found.tsx @@ -0,0 +1,20 @@ +import { Button } from "@/components/ui/button"; +import { Separator } from "@/components/ui/separator"; +import Link from "next/link"; +export const runtime = "edge"; +export default function NotFound() { + return ( +
+
+

+ 404 +

+ +

This page could not be found.

+ +
+
+ ); +} diff --git a/app/page.tsx b/app/page.tsx index 0604b54..55854de 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,103 +1,42 @@ +import { Button } from "@/components/ui/button"; +import { auth } from "@/lib/auth"; +import GitHub from "@/public/github-mark-white.svg"; import Image from "next/image"; +import Link from "next/link"; export const runtime = "edge"; -export default function Home() { +export default async function Home() { + const session = await auth(); + if (!session?.user) return null; + return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - app/page.tsx - - . -
  2. -
  3. Save and see your changes instantly.
  4. -
+
+
+

+ Dev Recap 2024 +

-
- - Vercel logomark - Deploy now - - - Read our docs - +
+

Hi, @{session.user.login} !

+

+ 1年間おつかれさまでした。 +

+

+ あなたの1年間を振り返りましょう🥳 +

-
- + + +
); } diff --git a/biome.json b/biome.json index 2eb0751..208387f 100644 --- a/biome.json +++ b/biome.json @@ -1,9 +1,9 @@ { "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", "vcs": { - "enabled": false, + "enabled": true, "clientKind": "git", - "useIgnoreFile": false + "useIgnoreFile": true }, "files": { "ignoreUnknown": false, diff --git a/bun.lockb b/bun.lockb index e5ed405..c226286 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components/ui/button.tsx b/components/ui/button.tsx new file mode 100644 index 0000000..d18eb21 --- /dev/null +++ b/components/ui/button.tsx @@ -0,0 +1,57 @@ +import { Slot } from "@radix-ui/react-slot"; +import { type VariantProps, cva } from "class-variance-authority"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground shadow hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", + outline: + "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2", + sm: "h-8 rounded-md px-3 text-xs", + lg: "h-10 rounded-md px-8", + icon: "h-9 w-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + return ( + + ); + }, +); +Button.displayName = "Button"; + +export { Button, buttonVariants }; diff --git a/components/ui/separator.tsx b/components/ui/separator.tsx new file mode 100644 index 0000000..d750f7f --- /dev/null +++ b/components/ui/separator.tsx @@ -0,0 +1,31 @@ +"use client"; + +import * as SeparatorPrimitive from "@radix-ui/react-separator"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Separator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>( + ( + { className, orientation = "horizontal", decorative = true, ...props }, + ref, + ) => ( + + ), +); +Separator.displayName = SeparatorPrimitive.Root.displayName; + +export { Separator }; diff --git a/lib/auth.ts b/lib/auth.ts index e8e42a1..85c62c5 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -1,5 +1,41 @@ -import NextAuth from "next-auth"; +import NextAuth, { type DefaultSession } from "next-auth"; import GitHub from "next-auth/providers/github"; +import "next-auth/jwt"; + export const { handlers, auth, signIn, signOut } = NextAuth({ providers: [GitHub], + callbacks: { + async jwt({ token, profile }) { + if (profile) { + const { login } = profile; + token.user = { ...token.user, login }; + } + return token; + }, + async session({ session, token }) { + const { login } = token.user; + session.user = { ...session.user, login }; + return session; + }, + }, }); +declare module "next-auth" { + interface Session { + user: { + login: string; + } & DefaultSession["user"]; + } + interface User { + login: string; + } + interface Profile { + login: string; + } +} +declare module "next-auth/jwt" { + interface JWT { + user: { + login: string; + }; + } +} diff --git a/package.json b/package.json index b715f3b..3e88d47 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,8 @@ "deploy": "bun pages:build && wrangler pages deploy" }, "dependencies": { + "@radix-ui/react-separator": "^1.1.1", + "@radix-ui/react-slot": "^1.1.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.469.0", diff --git a/public/github-mark-white.svg b/public/github-mark-white.svg new file mode 100644 index 0000000..d5e6491 --- /dev/null +++ b/public/github-mark-white.svg @@ -0,0 +1 @@ + \ No newline at end of file