From 67c2c3bc21e0c220b3c081948cc0752ffe68f38e Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Tue, 27 Aug 2024 08:26:24 +0530 Subject: [PATCH 01/19] refactor: interfaces and hooks --- app/(main)/layout.tsx | 15 +++++++++++++++ app/{ => (main)}/page.tsx | 1 + app/{ => (main)}/writings/[slug]/page.tsx | 0 app/{ => (main)}/writings/layout.tsx | 0 app/{ => (main)}/writings/page.tsx | 0 app/(protected)/admin/writings/page.tsx | 3 +++ app/(protected)/layout.tsx | 14 ++++++++++++++ app/layout.tsx | 2 -- components/appbar.tsx | 2 +- components/icons/chevrons.tsx | 4 ++-- components/icons/github.tsx | 4 ++-- components/icons/home.tsx | 4 ++-- components/icons/mail.tsx | 4 ++-- components/icons/pencil.tsx | 4 ++-- ...{useScreenDevice.ts => use-screen-detector.ts} | 0 interfaces/icon.ts | 7 +++++++ types/icon.ts | 7 ------- 17 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 app/(main)/layout.tsx rename app/{ => (main)}/page.tsx (99%) rename app/{ => (main)}/writings/[slug]/page.tsx (100%) rename app/{ => (main)}/writings/layout.tsx (100%) rename app/{ => (main)}/writings/page.tsx (100%) create mode 100644 app/(protected)/admin/writings/page.tsx create mode 100644 app/(protected)/layout.tsx rename hooks/{useScreenDevice.ts => use-screen-detector.ts} (100%) create mode 100644 interfaces/icon.ts delete mode 100644 types/icon.ts diff --git a/app/(main)/layout.tsx b/app/(main)/layout.tsx new file mode 100644 index 0000000..4721e1d --- /dev/null +++ b/app/(main)/layout.tsx @@ -0,0 +1,15 @@ +import Appbar from '@/components/appbar'; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + <> + {children} + + + ); +} + diff --git a/app/page.tsx b/app/(main)/page.tsx similarity index 99% rename from app/page.tsx rename to app/(main)/page.tsx index 6b43bf0..a9035fd 100644 --- a/app/page.tsx +++ b/app/(main)/page.tsx @@ -13,3 +13,4 @@ export default function Home() { ); } + diff --git a/app/writings/[slug]/page.tsx b/app/(main)/writings/[slug]/page.tsx similarity index 100% rename from app/writings/[slug]/page.tsx rename to app/(main)/writings/[slug]/page.tsx diff --git a/app/writings/layout.tsx b/app/(main)/writings/layout.tsx similarity index 100% rename from app/writings/layout.tsx rename to app/(main)/writings/layout.tsx diff --git a/app/writings/page.tsx b/app/(main)/writings/page.tsx similarity index 100% rename from app/writings/page.tsx rename to app/(main)/writings/page.tsx diff --git a/app/(protected)/admin/writings/page.tsx b/app/(protected)/admin/writings/page.tsx new file mode 100644 index 0000000..c225c2b --- /dev/null +++ b/app/(protected)/admin/writings/page.tsx @@ -0,0 +1,3 @@ +export default function AdmingWritingsPage() { + return 'Admin Writings.' +} diff --git a/app/(protected)/layout.tsx b/app/(protected)/layout.tsx new file mode 100644 index 0000000..8ff4ba9 --- /dev/null +++ b/app/(protected)/layout.tsx @@ -0,0 +1,14 @@ +export default function ProtectedLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + <> + Protected + {children} + + ); +} + + diff --git a/app/layout.tsx b/app/layout.tsx index ee745f0..f9ca37e 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -3,7 +3,6 @@ import { cn } from '@/lib/utils'; // Styles import '@/styles/globals.css'; -import Appbar from '@/components/appbar'; const fontSans = FontSans({ subsets: ['latin'], @@ -21,7 +20,6 @@ export default function RootLayout({ className={cn('dark container flex min-h-screen font-sans antialiased', fontSans.variable)} > {children} - ); diff --git a/components/appbar.tsx b/components/appbar.tsx index a190b75..c07429a 100644 --- a/components/appbar.tsx +++ b/components/appbar.tsx @@ -11,7 +11,7 @@ import PencilIcon from '@/components/icons/pencil'; import GithubIcon from '@/components/icons/github'; import MailIcon from '@/components/icons/mail'; import { Separator } from '@/components/ui/separator'; -import { useScreenDevice } from '@/hooks/useScreenDevice'; +import { useScreenDevice } from '@/hooks/use-screen-detector'; import { cn } from '@/lib/utils'; const Appbar = () => { diff --git a/components/icons/chevrons.tsx b/components/icons/chevrons.tsx index 5853baa..8280e70 100644 --- a/components/icons/chevrons.tsx +++ b/components/icons/chevrons.tsx @@ -1,6 +1,6 @@ -import { IconWithoutVariantsProps } from '@/types/icon'; +import { IconProps } from '@/interfaces/icon'; -const Chevrons = (props: IconWithoutVariantsProps) => { +const Chevrons = (props: IconProps) => { return ( { +const GithubIcon = ({ variant = 'outline', ...props }: VariantIconProps) => { return variant === 'solid' ? ( diff --git a/components/icons/home.tsx b/components/icons/home.tsx index 1eaeaa7..a207e3b 100644 --- a/components/icons/home.tsx +++ b/components/icons/home.tsx @@ -1,6 +1,6 @@ -import { IconProps } from '@/types/icon'; +import { VariantIconProps } from '@/interfaces/icon'; -const HomeIcon = ({ variant, ...props }: IconProps) => { +const HomeIcon = ({ variant, ...props }: VariantIconProps) => { if (variant === 'solid') { return ( <> diff --git a/components/icons/mail.tsx b/components/icons/mail.tsx index a563017..5865687 100644 --- a/components/icons/mail.tsx +++ b/components/icons/mail.tsx @@ -1,6 +1,6 @@ -import { IconProps } from '@/types/icon'; +import { VariantIconProps } from '@/interfaces/icon'; -const MailIcon = ({ variant = 'outline', ...props }: IconProps) => { +const MailIcon = ({ variant = 'outline', ...props }: VariantIconProps) => { return variant === 'solid' ? ( { +const PencilIcon = ({ variant = 'outline', ...props }: VariantIconProps) => { return variant === 'solid' ? ( diff --git a/hooks/useScreenDevice.ts b/hooks/use-screen-detector.ts similarity index 100% rename from hooks/useScreenDevice.ts rename to hooks/use-screen-detector.ts diff --git a/interfaces/icon.ts b/interfaces/icon.ts new file mode 100644 index 0000000..6deca63 --- /dev/null +++ b/interfaces/icon.ts @@ -0,0 +1,7 @@ +import { SVGAttributes } from 'react'; + +export interface IconProps extends SVGAttributes { }; + +export interface VariantIconProps extends IconProps { + variant: 'solid' | 'outline'; +}; diff --git a/types/icon.ts b/types/icon.ts deleted file mode 100644 index 0b9bbfd..0000000 --- a/types/icon.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { SVGAttributes } from 'react'; - -export interface IconProps extends SVGAttributes { - variant: 'solid' | 'outline'; -} - -export type IconWithoutVariantsProps = Omit; From 9cc22b981a50036f56cb12264c1501679cda7eef Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Tue, 27 Aug 2024 11:04:29 +0530 Subject: [PATCH 02/19] refactor: components structure by grouping --- app/(main)/layout.tsx | 2 +- app/(main)/page.tsx | 2 +- app/(main)/writings/[slug]/page.tsx | 4 ++-- components/{ => main}/appbar.tsx | 0 components/{ => main}/moonlitgrace-art.tsx | 0 components/{ => main}/toc.tsx | 0 components/{ => shared}/markdown.tsx | 2 +- styles/{highlight.js => hljs}/github-dark.css | 0 8 files changed, 5 insertions(+), 5 deletions(-) rename components/{ => main}/appbar.tsx (100%) rename components/{ => main}/moonlitgrace-art.tsx (100%) rename components/{ => main}/toc.tsx (100%) rename components/{ => shared}/markdown.tsx (98%) rename styles/{highlight.js => hljs}/github-dark.css (100%) diff --git a/app/(main)/layout.tsx b/app/(main)/layout.tsx index 4721e1d..724b85a 100644 --- a/app/(main)/layout.tsx +++ b/app/(main)/layout.tsx @@ -1,4 +1,4 @@ -import Appbar from '@/components/appbar'; +import Appbar from '@/components/main/appbar'; export default function RootLayout({ children, diff --git a/app/(main)/page.tsx b/app/(main)/page.tsx index a9035fd..4acc307 100644 --- a/app/(main)/page.tsx +++ b/app/(main)/page.tsx @@ -1,4 +1,4 @@ -import MoonlitGraceArt from '@/components/moonlitgrace-art'; +import MoonlitGraceArt from '@/components/main/moonlitgrace-art'; import { Metadata } from 'next'; export const metadata: Metadata = { diff --git a/app/(main)/writings/[slug]/page.tsx b/app/(main)/writings/[slug]/page.tsx index 2f9b633..f0fe125 100644 --- a/app/(main)/writings/[slug]/page.tsx +++ b/app/(main)/writings/[slug]/page.tsx @@ -1,5 +1,5 @@ -import Markdown from '@/components/markdown'; -import TableOfContents from '@/components/toc'; +import Markdown from '@/components/shared/markdown'; +import TableOfContents from '@/components/main/toc'; import { db } from '@/db'; import { posts, PostSelect } from '@/db/schema'; import { formatDate } from '@/lib/utils'; diff --git a/components/appbar.tsx b/components/main/appbar.tsx similarity index 100% rename from components/appbar.tsx rename to components/main/appbar.tsx diff --git a/components/moonlitgrace-art.tsx b/components/main/moonlitgrace-art.tsx similarity index 100% rename from components/moonlitgrace-art.tsx rename to components/main/moonlitgrace-art.tsx diff --git a/components/toc.tsx b/components/main/toc.tsx similarity index 100% rename from components/toc.tsx rename to components/main/toc.tsx diff --git a/components/markdown.tsx b/components/shared/markdown.tsx similarity index 98% rename from components/markdown.tsx rename to components/shared/markdown.tsx index 6ac3de4..7e33a10 100644 --- a/components/markdown.tsx +++ b/components/shared/markdown.tsx @@ -3,7 +3,7 @@ import { markedHighlight } from 'marked-highlight'; import DOMPurify from 'isomorphic-dompurify'; import hljs from 'highlight.js/lib/core'; -import '@/styles/highlight.js/github-dark.css'; +import '@/styles/hljs/github-dark.css'; import { escapeText } from '@/lib/utils'; const languages = { diff --git a/styles/highlight.js/github-dark.css b/styles/hljs/github-dark.css similarity index 100% rename from styles/highlight.js/github-dark.css rename to styles/hljs/github-dark.css From 7a97eb6b21554357e2d865ac098778e50eccc266 Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Tue, 27 Aug 2024 11:05:13 +0530 Subject: [PATCH 03/19] refactor: protected to admin --- app/{(protected) => (admin)}/admin/writings/page.tsx | 0 app/{(protected) => (admin)}/layout.tsx | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename app/{(protected) => (admin)}/admin/writings/page.tsx (100%) rename app/{(protected) => (admin)}/layout.tsx (100%) diff --git a/app/(protected)/admin/writings/page.tsx b/app/(admin)/admin/writings/page.tsx similarity index 100% rename from app/(protected)/admin/writings/page.tsx rename to app/(admin)/admin/writings/page.tsx diff --git a/app/(protected)/layout.tsx b/app/(admin)/layout.tsx similarity index 100% rename from app/(protected)/layout.tsx rename to app/(admin)/layout.tsx From 7bfc0a3461f41e0414fe9e02ed3c61547d50504b Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Tue, 27 Aug 2024 11:06:18 +0530 Subject: [PATCH 04/19] revert: app group --- app/{(admin) => (protected)}/admin/writings/page.tsx | 0 app/{(admin) => (protected)}/layout.tsx | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename app/{(admin) => (protected)}/admin/writings/page.tsx (100%) rename app/{(admin) => (protected)}/layout.tsx (100%) diff --git a/app/(admin)/admin/writings/page.tsx b/app/(protected)/admin/writings/page.tsx similarity index 100% rename from app/(admin)/admin/writings/page.tsx rename to app/(protected)/admin/writings/page.tsx diff --git a/app/(admin)/layout.tsx b/app/(protected)/layout.tsx similarity index 100% rename from app/(admin)/layout.tsx rename to app/(protected)/layout.tsx From 936ad113f16e8af676d791079d332895d647c40d Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Tue, 27 Aug 2024 11:08:08 +0530 Subject: [PATCH 05/19] Revert "revert: app group" This reverts commit 7bfc0a3461f41e0414fe9e02ed3c61547d50504b. --- app/{(protected) => (admin)}/admin/writings/page.tsx | 0 app/{(protected) => (admin)}/layout.tsx | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename app/{(protected) => (admin)}/admin/writings/page.tsx (100%) rename app/{(protected) => (admin)}/layout.tsx (100%) diff --git a/app/(protected)/admin/writings/page.tsx b/app/(admin)/admin/writings/page.tsx similarity index 100% rename from app/(protected)/admin/writings/page.tsx rename to app/(admin)/admin/writings/page.tsx diff --git a/app/(protected)/layout.tsx b/app/(admin)/layout.tsx similarity index 100% rename from app/(protected)/layout.tsx rename to app/(admin)/layout.tsx From db61cc551ec00eb040d9de43daf99e6fefe9195f Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Tue, 27 Aug 2024 11:29:45 +0530 Subject: [PATCH 06/19] refactor: rename writings page to blog for better verbose --- app/(admin)/admin/blog/page.tsx | 3 +++ app/(admin)/admin/writings/page.tsx | 3 --- app/(admin)/layout.tsx | 2 -- app/(main)/{writings => blog}/[slug]/page.tsx | 0 app/(main)/{writings => blog}/layout.tsx | 2 +- app/(main)/{writings => blog}/page.tsx | 8 ++++---- app/(main)/page.tsx | 2 +- components/main/appbar.tsx | 6 +++--- components/main/toc.tsx | 2 +- 9 files changed, 13 insertions(+), 15 deletions(-) create mode 100644 app/(admin)/admin/blog/page.tsx delete mode 100644 app/(admin)/admin/writings/page.tsx rename app/(main)/{writings => blog}/[slug]/page.tsx (100%) rename app/(main)/{writings => blog}/layout.tsx (56%) rename app/(main)/{writings => blog}/page.tsx (84%) diff --git a/app/(admin)/admin/blog/page.tsx b/app/(admin)/admin/blog/page.tsx new file mode 100644 index 0000000..e0d5dee --- /dev/null +++ b/app/(admin)/admin/blog/page.tsx @@ -0,0 +1,3 @@ +export default function AdmingBlogPage() { + return 'Admin Writings.' +} diff --git a/app/(admin)/admin/writings/page.tsx b/app/(admin)/admin/writings/page.tsx deleted file mode 100644 index c225c2b..0000000 --- a/app/(admin)/admin/writings/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function AdmingWritingsPage() { - return 'Admin Writings.' -} diff --git a/app/(admin)/layout.tsx b/app/(admin)/layout.tsx index 8ff4ba9..b206868 100644 --- a/app/(admin)/layout.tsx +++ b/app/(admin)/layout.tsx @@ -10,5 +10,3 @@ export default function ProtectedLayout({ ); } - - diff --git a/app/(main)/writings/[slug]/page.tsx b/app/(main)/blog/[slug]/page.tsx similarity index 100% rename from app/(main)/writings/[slug]/page.tsx rename to app/(main)/blog/[slug]/page.tsx diff --git a/app/(main)/writings/layout.tsx b/app/(main)/blog/layout.tsx similarity index 56% rename from app/(main)/writings/layout.tsx rename to app/(main)/blog/layout.tsx index b46e5e8..18adc78 100644 --- a/app/(main)/writings/layout.tsx +++ b/app/(main)/blog/layout.tsx @@ -1,5 +1,5 @@ import React from 'react'; -export default function WritingsLayout({ children }: Readonly<{ children: React.ReactNode }>) { +export default function BlogLayout({ children }: Readonly<{ children: React.ReactNode }>) { return
{children}
; } diff --git a/app/(main)/writings/page.tsx b/app/(main)/blog/page.tsx similarity index 84% rename from app/(main)/writings/page.tsx rename to app/(main)/blog/page.tsx index bb6896c..4e70885 100644 --- a/app/(main)/writings/page.tsx +++ b/app/(main)/blog/page.tsx @@ -7,11 +7,11 @@ import { Metadata } from 'next'; import Link from 'next/link'; export const metadata: Metadata = { - title: 'Writings. | moonlitspace', + title: 'Blog.space', description: 'my graceful thoughts', }; -export default async function WritingsPage() { +export default async function BlogPage() { const postsData: Omit[] = await db .select({ id: posts.id, @@ -25,7 +25,7 @@ export default async function WritingsPage() { return ( <>

- Writings. + Blog.

{postsData.map((item) => ( @@ -34,7 +34,7 @@ export default async function WritingsPage() { {formatDate(item.createdAt)}
- + {item.title} diff --git a/app/(main)/page.tsx b/app/(main)/page.tsx index 4acc307..41e7169 100644 --- a/app/(main)/page.tsx +++ b/app/(main)/page.tsx @@ -2,7 +2,7 @@ import MoonlitGraceArt from '@/components/main/moonlitgrace-art'; import { Metadata } from 'next'; export const metadata: Metadata = { - title: 'Home. | moonlitspace', + title: 'Home.space', description: 'a graceful space', }; diff --git a/components/main/appbar.tsx b/components/main/appbar.tsx index c07429a..28f067b 100644 --- a/components/main/appbar.tsx +++ b/components/main/appbar.tsx @@ -26,10 +26,10 @@ const Appbar = () => { icon: HomeIcon, label: 'Home', }, - writings: { - href: '/writings', + blog: { + href: '/blog', icon: PencilIcon, - label: 'Writings', + label: 'Blog', }, }, socials: { diff --git a/components/main/toc.tsx b/components/main/toc.tsx index 0a1de15..9611223 100644 --- a/components/main/toc.tsx +++ b/components/main/toc.tsx @@ -4,7 +4,7 @@ import { cn, escapeText } from '@/lib/utils'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { Button } from '@/components/ui/button'; import { useState } from 'react'; -import Chevrons from './icons/chevrons'; +import Chevrons from '@/components/icons/chevrons'; const TableOfContents = ({ headings }: { headings: string[] }) => { const [tocOpen, setTocOpen] = useState(true); From 67eba49a4e1afe712edc8d9851e5fd498ec9ffb6 Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Tue, 27 Aug 2024 11:35:09 +0530 Subject: [PATCH 07/19] chore: add prod example env (basic) --- env/.env.prod.example | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 env/.env.prod.example diff --git a/env/.env.prod.example b/env/.env.prod.example new file mode 100644 index 0000000..1c4631d --- /dev/null +++ b/env/.env.prod.example @@ -0,0 +1,7 @@ +POSTGRES_DB= +POSTGRES_USER= +POSTGRES_PASSWORD= +POSTGRES_HOST= +POSTGRES_PORT= + +DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}" From 7f9f39d9e83e901c0ff1235d4b5a99dd221bd40c Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Tue, 27 Aug 2024 11:51:09 +0530 Subject: [PATCH 08/19] feat: better metametadata for SEO --- app/(main)/blog/page.tsx | 4 ++-- app/(main)/page.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/(main)/blog/page.tsx b/app/(main)/blog/page.tsx index 4e70885..a7c17c6 100644 --- a/app/(main)/blog/page.tsx +++ b/app/(main)/blog/page.tsx @@ -7,8 +7,8 @@ import { Metadata } from 'next'; import Link from 'next/link'; export const metadata: Metadata = { - title: 'Blog.space', - description: 'my graceful thoughts', + title: 'Blog | Moonlitgrace', + description: 'Dive into the Blog at Moonlitgrace, where a passionate web developer and open-source contributor shares thoughts, tutorials, and insights—all under the alias Moonlitgrace.', }; export default async function BlogPage() { diff --git a/app/(main)/page.tsx b/app/(main)/page.tsx index 41e7169..1dad2c7 100644 --- a/app/(main)/page.tsx +++ b/app/(main)/page.tsx @@ -2,8 +2,8 @@ import MoonlitGraceArt from '@/components/main/moonlitgrace-art'; import { Metadata } from 'next'; export const metadata: Metadata = { - title: 'Home.space', - description: 'a graceful space', + title: 'Moonlitgrace', + description: 'Step into Moonlitgrace, where a passionate web developer and open-source contributor shares insights, projects, and creativity—all under the alias Moonlitgrace.', }; export default function Home() { From dac3190806b6afdd4a21dceca3307e676690ed70 Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Tue, 27 Aug 2024 14:02:37 +0530 Subject: [PATCH 09/19] refactor: create views for handling alike components --- app/(admin)/admin/blog/page.tsx | 11 ++++-- app/(admin)/layout.tsx | 8 +++-- app/(main)/blog/page.tsx | 41 ++------------------- app/(main)/layout.tsx | 2 +- components/admin/adminbar.tsx | 64 +++++++++++++++++++++++++++++++++ views/blog-list-view.tsx | 49 +++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 45 deletions(-) create mode 100644 components/admin/adminbar.tsx create mode 100644 views/blog-list-view.tsx diff --git a/app/(admin)/admin/blog/page.tsx b/app/(admin)/admin/blog/page.tsx index e0d5dee..de8d18d 100644 --- a/app/(admin)/admin/blog/page.tsx +++ b/app/(admin)/admin/blog/page.tsx @@ -1,3 +1,10 @@ -export default function AdmingBlogPage() { - return 'Admin Writings.' +import BlogListView from '@/views/blog-list-view'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Blog | Admin', +}; + +export default async function AdminBlogPage() { + return } diff --git a/app/(admin)/layout.tsx b/app/(admin)/layout.tsx index b206868..125a486 100644 --- a/app/(admin)/layout.tsx +++ b/app/(admin)/layout.tsx @@ -1,12 +1,14 @@ +import Adminbar from "@/components/admin/adminbar"; + export default function ProtectedLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( - <> - Protected +
+ {children} - +
); } diff --git a/app/(main)/blog/page.tsx b/app/(main)/blog/page.tsx index a7c17c6..8ad56eb 100644 --- a/app/(main)/blog/page.tsx +++ b/app/(main)/blog/page.tsx @@ -1,10 +1,5 @@ -import { Badge } from '@/components/ui/badge'; -import { Separator } from '@/components/ui/separator'; -import { db } from '@/db'; -import { type PostSelect, posts } from '@/db/schema'; -import { formatDate } from '@/lib/utils'; +import BlogListView from '@/views/blog-list-view'; import { Metadata } from 'next'; -import Link from 'next/link'; export const metadata: Metadata = { title: 'Blog | Moonlitgrace', @@ -12,37 +7,5 @@ export const metadata: Metadata = { }; export default async function BlogPage() { - const postsData: Omit[] = await db - .select({ - id: posts.id, - title: posts.title, - slug: posts.slug, - tag: posts.tag, - createdAt: posts.createdAt, - }) - .from(posts); - - return ( - <> -

- Blog. -

-
- {postsData.map((item) => ( -
- - {formatDate(item.createdAt)} - -
- - {item.title} - - - {item.tag} -
-
- ))} -
- - ); + return } diff --git a/app/(main)/layout.tsx b/app/(main)/layout.tsx index 724b85a..7e8fd3d 100644 --- a/app/(main)/layout.tsx +++ b/app/(main)/layout.tsx @@ -1,6 +1,6 @@ import Appbar from '@/components/main/appbar'; -export default function RootLayout({ +export default function MainLayout({ children, }: Readonly<{ children: React.ReactNode; diff --git a/components/admin/adminbar.tsx b/components/admin/adminbar.tsx new file mode 100644 index 0000000..c0dd917 --- /dev/null +++ b/components/admin/adminbar.tsx @@ -0,0 +1,64 @@ +'use client'; + +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; + +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; +import { Button } from '@/components/ui/button'; +import React from 'react'; +import PencilIcon from '@/components/icons/pencil'; +import { useScreenDevice } from '@/hooks/use-screen-detector'; +import HomeIcon from '@/components/icons/home'; + +const Adminbar = () => { + const pathname = usePathname(); + + const { isMobile } = useScreenDevice(); + + const MAPPING = { + links: { + home: { + href: '/', + icon: HomeIcon, + label: 'Home', + }, + blog: { + href: '/admin/blog', + icon: PencilIcon, + label: 'Admin Blog', + }, + }, + }; + + return ( + +
+ {Object.values(MAPPING.links).map((item, idx) => ( + + + + + +

{item.label}

+
+
+ ))} +
+
+
+ ); +}; + +export default Adminbar; + diff --git a/views/blog-list-view.tsx b/views/blog-list-view.tsx new file mode 100644 index 0000000..d1e7242 --- /dev/null +++ b/views/blog-list-view.tsx @@ -0,0 +1,49 @@ +import { Badge } from "@/components/ui/badge"; +import { Separator } from "@/components/ui/separator"; +import { db } from "@/db"; +import { posts, PostSelect } from "@/db/schema"; +import { formatDate } from "@/lib/utils"; +import Link from "next/link"; + +type Props = { + title: string; + linkPrefix: string; +} + +const BlogListView = async ({ title, linkPrefix }: Props) => { + const postsData: Omit[] = await db + .select({ + id: posts.id, + title: posts.title, + slug: posts.slug, + tag: posts.tag, + createdAt: posts.createdAt, + }) + .from(posts); + + return ( + <> +

+ {title}. +

+
+ {postsData.map((item) => ( +
+ + {formatDate(item.createdAt)} + +
+ + {item.title} + + + {item.tag} +
+
+ ))} +
+ + ); +} + +export default BlogListView; From df413244ffde8606191297a974a5e576e364abc0 Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Wed, 28 Aug 2024 01:00:55 +0530 Subject: [PATCH 10/19] feat: add admin bl blog creation actions and schemas --- actions/admin.ts | 19 +++++++ app/(admin)/admin/blog/[slug]/page.tsx | 19 +++++++ app/(admin)/admin/blog/page.tsx | 9 +--- app/(admin)/admin/page.tsx | 3 ++ app/(admin)/layout.tsx | 2 +- app/(main)/blog/page.tsx | 7 +-- app/(main)/layout.tsx | 1 - app/(main)/page.tsx | 4 +- components/admin/adminbar.tsx | 5 +- components/admin/forms/blog-form.tsx | 53 +++++++++++++++++++ .../shared/blog-list.tsx | 23 ++++---- components/ui/input.tsx | 24 +++++++++ components/ui/label.tsx | 21 ++++++++ components/ui/textarea.tsx | 23 ++++++++ interfaces/icon.ts | 4 +- lib/zod.ts | 5 ++ package-lock.json | 24 +++++++++ package.json | 1 + zod_schemas/admin.ts | 19 +++++++ 19 files changed, 236 insertions(+), 30 deletions(-) create mode 100644 actions/admin.ts create mode 100644 app/(admin)/admin/blog/[slug]/page.tsx create mode 100644 app/(admin)/admin/page.tsx create mode 100644 components/admin/forms/blog-form.tsx rename views/blog-list-view.tsx => components/shared/blog-list.tsx (72%) create mode 100644 components/ui/input.tsx create mode 100644 components/ui/label.tsx create mode 100644 components/ui/textarea.tsx create mode 100644 lib/zod.ts create mode 100644 zod_schemas/admin.ts diff --git a/actions/admin.ts b/actions/admin.ts new file mode 100644 index 0000000..ad857b7 --- /dev/null +++ b/actions/admin.ts @@ -0,0 +1,19 @@ +import { AdminBlogFormState, AdminBlogSchema } from "@/zod_schemas/admin"; + +export default function adminBlogSubmit(state: AdminBlogFormState, formData: FormData) { + const validatedFields = AdminBlogSchema.safeParse({ + update: formData.get('update') === 'on', + title: formData.get('title'), + tag: formData.get('tag'), + content: formData.get('content'), + }) + + console.log(validatedFields.data) + + if (!validatedFields.success) { + return { + errors: validatedFields.error.flatten().fieldErrors, + } + } +} + diff --git a/app/(admin)/admin/blog/[slug]/page.tsx b/app/(admin)/admin/blog/[slug]/page.tsx new file mode 100644 index 0000000..020be18 --- /dev/null +++ b/app/(admin)/admin/blog/[slug]/page.tsx @@ -0,0 +1,19 @@ +import AdminBlogForm from '@/components/admin/forms/blog-form'; +import { db } from '@/db'; +import { posts, PostSelect } from '@/db/schema'; +import { eq } from 'drizzle-orm'; + +export default async function Page({ params }: { params: { slug: string } }) { + const postData: PostSelect = ( + await db.select().from(posts).where(eq(posts.slug, params.slug)) + )[0]; + + return ( + + ); +} diff --git a/app/(admin)/admin/blog/page.tsx b/app/(admin)/admin/blog/page.tsx index de8d18d..220c345 100644 --- a/app/(admin)/admin/blog/page.tsx +++ b/app/(admin)/admin/blog/page.tsx @@ -1,10 +1,5 @@ -import BlogListView from '@/views/blog-list-view'; -import { Metadata } from 'next'; - -export const metadata: Metadata = { - title: 'Blog | Admin', -}; +import BlogList from '@/components/shared/blog-list'; export default async function AdminBlogPage() { - return + return ; } diff --git a/app/(admin)/admin/page.tsx b/app/(admin)/admin/page.tsx new file mode 100644 index 0000000..288c8e4 --- /dev/null +++ b/app/(admin)/admin/page.tsx @@ -0,0 +1,3 @@ +export default function AdminPage() { + return 'admin'; +} diff --git a/app/(admin)/layout.tsx b/app/(admin)/layout.tsx index 125a486..fae9aeb 100644 --- a/app/(admin)/layout.tsx +++ b/app/(admin)/layout.tsx @@ -1,4 +1,4 @@ -import Adminbar from "@/components/admin/adminbar"; +import Adminbar from '@/components/admin/adminbar'; export default function ProtectedLayout({ children, diff --git a/app/(main)/blog/page.tsx b/app/(main)/blog/page.tsx index 8ad56eb..d1fa978 100644 --- a/app/(main)/blog/page.tsx +++ b/app/(main)/blog/page.tsx @@ -1,11 +1,12 @@ -import BlogListView from '@/views/blog-list-view'; +import BlogList from '@/components/shared/blog-list'; import { Metadata } from 'next'; export const metadata: Metadata = { title: 'Blog | Moonlitgrace', - description: 'Dive into the Blog at Moonlitgrace, where a passionate web developer and open-source contributor shares thoughts, tutorials, and insights—all under the alias Moonlitgrace.', + description: + 'Dive into the Blog at Moonlitgrace, where a passionate web developer and open-source contributor shares thoughts, tutorials, and insights—all under the alias Moonlitgrace.', }; export default async function BlogPage() { - return + return ; } diff --git a/app/(main)/layout.tsx b/app/(main)/layout.tsx index 7e8fd3d..dcb5ed3 100644 --- a/app/(main)/layout.tsx +++ b/app/(main)/layout.tsx @@ -12,4 +12,3 @@ export default function MainLayout({ ); } - diff --git a/app/(main)/page.tsx b/app/(main)/page.tsx index 1dad2c7..58708b1 100644 --- a/app/(main)/page.tsx +++ b/app/(main)/page.tsx @@ -3,7 +3,8 @@ import { Metadata } from 'next'; export const metadata: Metadata = { title: 'Moonlitgrace', - description: 'Step into Moonlitgrace, where a passionate web developer and open-source contributor shares insights, projects, and creativity—all under the alias Moonlitgrace.', + description: + 'Step into Moonlitgrace, where a passionate web developer and open-source contributor shares insights, projects, and creativity—all under the alias Moonlitgrace.', }; export default function Home() { @@ -13,4 +14,3 @@ export default function Home() { ); } - diff --git a/components/admin/adminbar.tsx b/components/admin/adminbar.tsx index c0dd917..da186e7 100644 --- a/components/admin/adminbar.tsx +++ b/components/admin/adminbar.tsx @@ -18,9 +18,9 @@ const Adminbar = () => { const MAPPING = { links: { home: { - href: '/', + href: '/admin', icon: HomeIcon, - label: 'Home', + label: 'Admin Home', }, blog: { href: '/admin/blog', @@ -61,4 +61,3 @@ const Adminbar = () => { }; export default Adminbar; - diff --git a/components/admin/forms/blog-form.tsx b/components/admin/forms/blog-form.tsx new file mode 100644 index 0000000..c4bf377 --- /dev/null +++ b/components/admin/forms/blog-form.tsx @@ -0,0 +1,53 @@ +'use client' + +import adminBlogSubmit from '@/actions/admin'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; +import { FormEvent } from 'react'; +import { useFormState, useFormStatus } from 'react-dom'; + +type Props = { + id?: number; + title?: string; + tag?: string; + content?: string; +}; + +export default function AdminBlogForm({ id, title = '', tag = '', content = '' }: Props) { + const [state, action] = useFormState(adminBlogSubmit, undefined) + + return ( +
+ {state?.errors.update} + +
+
+ + +
+
+ + +
+
+
+ +