diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..d3145e6
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,6 @@
+Dockerfile
+.dockerignore
+node_modules
+README.md
+.next
+.git
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..3c18059
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,10 @@
+{
+ "tabWidth": 2,
+ "printWidth": 120,
+ "arrowParens": "always",
+ "singleQuote": false,
+ "trailingComma": "all",
+ "useTabs": false,
+ "semi": true,
+ "bracketSpacing": true
+}
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..41cfb0a
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,50 @@
+FROM oven/bun:1-alpine AS base
+
+FROM base AS deps
+
+RUN apk update && apk upgrade && apk add --no-cache libc6-compat
+WORKDIR /app
+
+COPY package.json bun.lockb ./
+RUN \
+ if [ -f bun.lockb ]; then bun i --frozen-lockfile; \
+ else echo "Lockfile not found." && exit 1; \
+ fi
+
+FROM base AS builder
+WORKDIR /app
+COPY --from=deps /app/node_modules ./node_modules
+COPY . .
+
+ENV NEXT_TELEMETRY_DISABLED=1
+
+RUN \
+ if [ -f bun.lockb ]; then bun run build; \
+ else echo "Lockfile not found." && exit 1; \
+ fi
+
+FROM base AS runner
+WORKDIR /app
+
+RUN apk update && apk upgrade && apk add --no-cache dumb-init
+
+ENV NODE_ENV=production
+
+ENV NEXT_TELEMETRY_DISABLED=1
+
+RUN addgroup --system --gid 1001 nodejs
+RUN adduser --system --uid 1001 nextjs
+
+COPY --from=builder /app/public ./public
+
+COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
+COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
+
+USER nextjs
+
+EXPOSE 3000
+
+ENV PORT=3000
+
+ENV HOSTNAME="0.0.0.0"
+CMD ["dumb-init", "bun", "run", "server.js"]
\ No newline at end of file
diff --git a/next.config.ts b/next.config.ts
index e9ffa30..fe2648e 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -1,7 +1,10 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
- /* config options here */
+ output: "standalone",
+ experimental: {
+ optimizePackageImports: ["@chakra-ui/react"],
+ },
};
export default nextConfig;
diff --git a/src/app/blog/[slug]/page.tsx b/src/app/blog/[slug]/page.tsx
index 9d03ad4..eea974c 100644
--- a/src/app/blog/[slug]/page.tsx
+++ b/src/app/blog/[slug]/page.tsx
@@ -1,5 +1,5 @@
-export default async function Post({ params }: { params: { slug: string } }) {
- const { slug } = params;
+export default async function Post({ params }: { params: Promise<{ slug: string }> }) {
+ const { slug } = await params;
return (
Post: {slug}
diff --git a/src/app/globals.css b/src/app/globals.css
index 6b717ad..b5c61c9 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,21 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
-
-:root {
- --background: #ffffff;
- --foreground: #171717;
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --background: #0a0a0a;
- --foreground: #ededed;
- }
-}
-
-body {
- color: var(--foreground);
- background: var(--background);
- font-family: Arial, Helvetica, sans-serif;
-}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index f7fa87e..8163b1e 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,3 +1,4 @@
+import { Provider } from "@/components/ui/provider";
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
@@ -23,11 +24,9 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
-
- {children}
+
+
+
{children}
);
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 3eee014..c75150c 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,101 +1,11 @@
-import Image from "next/image";
+import { Button } from "@/components/ui/button";
+import { VStack } from "@chakra-ui/react";
export default function Home() {
return (
-
-
-
-
- -
- Get started by editing{" "}
-
- src/app/page.tsx
-
- .
-
- - Save and see your changes instantly.
-
-
-
-
-
-
+
+
+
+
);
}
diff --git a/src/components/ui/color-mode.tsx b/src/components/ui/color-mode.tsx
index a87f63b..8490e12 100644
--- a/src/components/ui/color-mode.tsx
+++ b/src/components/ui/color-mode.tsx
@@ -1,57 +1,57 @@
-"use client"
+"use client";
-import type { IconButtonProps } from "@chakra-ui/react"
-import { ClientOnly, IconButton, Skeleton } from "@chakra-ui/react"
-import { ThemeProvider, useTheme } from "next-themes"
-import type { ThemeProviderProps } from "next-themes"
-import * as React from "react"
-import { LuMoon, LuSun } from "react-icons/lu"
+import type { IconButtonProps } from "@chakra-ui/react";
+import { ClientOnly, IconButton, Skeleton } from "@chakra-ui/react";
+import type { ThemeProviderProps } from "next-themes";
+import { ThemeProvider, useTheme } from "next-themes";
+import * as React from "react";
+import { LuMoon, LuSun } from "react-icons/lu";
+// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface ColorModeProviderProps extends ThemeProviderProps {}
export function ColorModeProvider(props: ColorModeProviderProps) {
- return (
-
- )
+ return
;
}
-export type ColorMode = "light" | "dark"
+export type ColorMode = "light" | "dark";
export interface UseColorModeReturn {
- colorMode: ColorMode
- setColorMode: (colorMode: ColorMode) => void
- toggleColorMode: () => void
+ colorMode: ColorMode;
+ setColorMode: (colorMode: ColorMode) => void;
+ toggleColorMode: () => void;
}
export function useColorMode(): UseColorModeReturn {
- const { resolvedTheme, setTheme } = useTheme()
+ const { resolvedTheme, setTheme } = useTheme();
const toggleColorMode = () => {
- setTheme(resolvedTheme === "light" ? "dark" : "light")
- }
+ setTheme(resolvedTheme === "light" ? "dark" : "light");
+ };
return {
colorMode: resolvedTheme as ColorMode,
setColorMode: setTheme,
toggleColorMode,
- }
+ };
}
export function useColorModeValue
(light: T, dark: T) {
- const { colorMode } = useColorMode()
- return colorMode === "dark" ? dark : light
+ const { colorMode } = useColorMode();
+ return colorMode === "dark" ? dark : light;
}
export function ColorModeIcon() {
- const { colorMode } = useColorMode()
- return colorMode === "dark" ? :
+ const { colorMode } = useColorMode();
+ return colorMode === "dark" ? : ;
}
+// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface ColorModeButtonProps extends Omit {}
-export const ColorModeButton = React.forwardRef<
- HTMLButtonElement,
- ColorModeButtonProps
->(function ColorModeButton(props, ref) {
- const { toggleColorMode } = useColorMode()
+export const ColorModeButton = React.forwardRef(function ColorModeButton(
+ props,
+ ref,
+) {
+ const { toggleColorMode } = useColorMode();
return (
}>
- )
-})
+ );
+});