diff --git a/.env.example b/.env.example index 93a9058f..8c033865 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,10 @@ # See lib/env.ts for the list of required environment variables and how to get them. ############### +AUTH_GITHUB_CLIENT_ID= +AUTH_GITHUB_CLIENT_SECRET= +AUTH_SECRET= +DATABASE_URL= GITHUB_TOKEN= KV_REST_API_TOKEN= KV_REST_API_URL= @@ -11,8 +15,6 @@ RESEND_FROM_EMAIL= RESEND_TO_EMAIL= TURNSTILE_SECRET_KEY= NEXT_PUBLIC_BASE_URL= -NEXT_PUBLIC_GISCUS_CATEGORY_ID= -NEXT_PUBLIC_GISCUS_REPO_ID= NEXT_PUBLIC_GITHUB_REPO= NEXT_PUBLIC_ONION_DOMAIN= NEXT_PUBLIC_SITE_LOCALE= diff --git a/.prettierignore b/.prettierignore index b87eae66..5053ae69 100644 --- a/.prettierignore +++ b/.prettierignore @@ -8,6 +8,7 @@ pnpm-lock.yaml .vercel/ # other +lib/db/migrations/ public/ .devcontainer/devcontainer.json .vscode/ diff --git a/README.md b/README.md index 96ce4057..398ca90b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![GitHub repo size](https://img.shields.io/github/repo-size/jakejarvis/jarv.is?color=009cdf&label=repo%20size&logo=git&logoColor=white)](https://github.com/jakejarvis/jarv.is) [![Dynamic JSON Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fjarv.is%2Fapi%2Fhits&query=%24.total.hits&logo=googleanalytics&logoColor=white&label=hits&color=salmon&cacheSeconds=1800)](https://jarv.is/api/hits) -My humble abode on the World Wide Web, created and deployed using [Next.js](https://nextjs.org/), [Tailwind CSS](https://github.com/user-attachments/assets/dfe99976-c73d-46f1-8a50-f26338463ad8), [Upstash](https://upstash.com/), [Giscus](https://giscus.app/), [and more](https://jarv.is/humans.txt). +My humble abode on the World Wide Web, created and deployed using [Next.js](https://nextjs.org/), [Tailwind CSS](https://github.com/user-attachments/assets/dfe99976-c73d-46f1-8a50-f26338463ad8), [Neon Postgres](https://neon.tech/), [Drizzle](https://orm.drizzle.team/), [Better Auth](https://www.better-auth.com/), [and more](https://jarv.is/humans.txt). ## 🕹️ Getting Started @@ -14,7 +14,7 @@ My humble abode on the World Wide Web, created and deployed using [Next.js](http I highly recommend spinning up a [Codespace](https://github.com/features/codespaces) with the button above to start inside of a preconfigured and tested environment. But you can also clone this repository locally, run `pnpm install` to pull down the necessary dependencies and `pnpm dev` to start the local server, and then open [localhost:3000](http://localhost:3000/) in a browser. Pages will live-refresh when source files are changed. -**Be sure to populate the required environment variables!** Refer to [`lib/env.ts`](lib/env.ts), which documents (and strictly [type-checks](https://env.t3.gg/docs/introduction)) these variables. The included [`.env.example`](.env.example) file should be copied and used as a template for a new `.env.local` file, which the local `next dev` server will then ingest. +**Be sure to populate the required environment variables!** Refer to [`lib/env.ts`](lib/env.ts), which documents (and strictly [type-checks](https://env.t3.gg/docs/introduction)) these variables. The included [`.env.example`](.env.example) file should be copied and used as a template for a new local `.env` file, which the local `next dev` server will then ingest. > ⚠️ **Currently, there are a few assumptions sprinkled throughout the code that this repo will be deployed to [Vercel](https://nextjs.org/docs/app/building-your-application/deploying#managed-nextjs-with-vercel) and _only_ Vercel.** I'll correct this soon™ now that some escape hatches (namely [OpenNext](https://opennext.js.org/)) actually exist... diff --git a/app/api/auth/[...all]/route.ts b/app/api/auth/[...all]/route.ts new file mode 100644 index 00000000..7cbe91bb --- /dev/null +++ b/app/api/auth/[...all]/route.ts @@ -0,0 +1,4 @@ +import { auth } from "@/lib/auth"; +import { toNextJsHandler } from "better-auth/next-js"; + +export const { POST, GET } = toNextJsHandler(auth); diff --git a/app/api/hits/route.ts b/app/api/hits/route.ts index f67f77f3..dd4fdbff 100644 --- a/app/api/hits/route.ts +++ b/app/api/hits/route.ts @@ -1,7 +1,6 @@ import { NextResponse } from "next/server"; import { unstable_cache as cache } from "next/cache"; -import { getViews as _getViews } from "@/lib/posts"; -import { POSTS_DIR } from "@/lib/config/constants"; +import { getViews as _getViews } from "@/lib/server/views"; const getViews = cache(_getViews, undefined, { revalidate: 300, // 5 minutes @@ -25,9 +24,9 @@ export const GET = async (): Promise< const total = { hits: Object.values(views).reduce((acc, curr) => acc + curr, 0), }; - const pages = Object.entries(views).map(([slug, hits]) => ({ - slug: `${POSTS_DIR}/${slug}`, - hits, + const pages = Object.entries(views).map(([slug, views]) => ({ + slug, + hits: views, })); pages.sort((a, b) => b.hits - a.hits); diff --git a/app/cli/page.mdx b/app/cli/page.mdx index 085158ba..ce32e7ea 100644 --- a/app/cli/page.mdx +++ b/app/cli/page.mdx @@ -1,5 +1,4 @@ import PageTitle from "@/components/layout/page-title"; -import Comments from "@/components/comments"; import { createMetadata } from "@/lib/metadata"; export const metadata = createMetadata({ @@ -35,7 +34,3 @@ npx @jakejarvis/cli ## License MIT © [Jake Jarvis](https://jarv.is/), [Sindre Sorhus](https://sindresorhus.com/) - ---- - - diff --git a/app/contact/page.tsx b/app/contact/page.tsx index da440efb..8ef846a9 100644 --- a/app/contact/page.tsx +++ b/app/contact/page.tsx @@ -1,9 +1,8 @@ import PageTitle from "@/components/layout/page-title"; import Link from "@/components/link"; +import ContactForm from "@/components/contact-form"; import { createMetadata } from "@/lib/metadata"; -import ContactForm from "./form"; - export const metadata = createMetadata({ title: "Contact Me", description: "Fill out this quick form and I'll get back to you as soon as I can.", diff --git a/app/layout.tsx b/app/layout.tsx index 75019cd3..9beab455 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -5,6 +5,7 @@ import { ThemeProvider, ThemeScript } from "@/components/layout/theme-context"; import Header from "@/components/layout/header"; import Footer from "@/components/layout/footer"; import SkipNavButton, { SKIP_NAV_ID } from "@/components/layout/skip-nav"; +import Toaster from "@/components/ui/sonner"; import { defaultMetadata } from "@/lib/metadata"; import { GeistMono, GeistSans } from "@/lib/fonts"; import siteConfig from "@/lib/config/site"; @@ -73,6 +74,8 @@ const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => {