diff --git a/README.md b/README.md index c76c6e0..25619d4 100644 --- a/README.md +++ b/README.md @@ -36,41 +36,111 @@ A modern, feature-rich blog system built with **Next.js 14**, **TypeScript**, an ``` markdownblog/ ├── src/ -│ ├── app/ -│ │ ├── admin/ # Admin dashboard pages -│ │ │ ├── manage/ # Content management interface -│ │ │ └── page.tsx # Main admin dashboard -│ │ ├── api/ # API routes +│ ├── app/ # Next.js 14 App Router +│ │ ├── admin/ # Admin dashboard pages +│ │ │ ├── manage/ # Content management interface +│ │ │ │ └── page.tsx # Manage posts and folders +│ │ │ └── page.tsx # Main admin dashboard +│ │ ├── api/ # API routes (Next.js API routes) │ │ │ ├── admin/ # Admin API endpoints │ │ │ │ ├── delete/ # Delete posts/folders +│ │ │ │ │ └── route.ts │ │ │ │ ├── docker/ # Docker detection -│ │ │ │ ├── export/ # Export functionality +│ │ │ │ │ └── route.ts +│ │ │ │ ├── export/ # Export functionality (Docker) +│ │ │ │ │ └── route.ts +│ │ │ │ ├── exportlocal/ # Export functionality (Local) +│ │ │ │ │ └── route.ts │ │ │ │ ├── folders/ # Folder management +│ │ │ │ │ ├── details/ # Folder details API +│ │ │ │ │ │ └── route.ts +│ │ │ │ │ └── route.ts │ │ │ │ ├── password/ # Password management +│ │ │ │ │ └── route.ts │ │ │ │ ├── posts/ # Post CRUD operations +│ │ │ │ │ ├── move/ # Move posts between folders +│ │ │ │ │ │ └── route.ts +│ │ │ │ │ ├── raw/ # Get raw post content +│ │ │ │ │ │ └── route.ts +│ │ │ │ │ ├── route.ts +│ │ │ │ │ └── size/ # Get post size info +│ │ │ │ │ └── route.ts │ │ │ │ └── upload/ # File upload handling +│ │ │ │ └── route.ts │ │ │ └── posts/ # Public post API +│ │ │ ├── [slug]/ # Dynamic post API routes +│ │ │ │ └── route.ts +│ │ │ └── route.ts # List all posts │ │ ├── posts/ # Blog post pages -│ │ │ └── [...slug]/ # Dynamic post routing -│ │ ├── globals.css # Global styles -│ │ ├── layout.tsx # Root layout -│ │ └── page.tsx # Homepage -│ └── lib/ -│ ├── markdown.ts # Markdown processing utilities -│ └── postsDirectory.ts # Post directory management -├── posts/ # Markdown blog posts +│ │ │ └── [...slug]/ # Dynamic post routing (catch-all) +│ │ │ └── page.tsx # Individual post page with anchor linking +│ │ ├── AboutButton.tsx # About page button component +│ │ ├── BadgeButton.tsx # Badge display component +│ │ ├── globals.css # Global styles and Tailwind imports +│ │ ├── HeaderButtons.tsx # Header navigation buttons +│ │ ├── highlight-github.css # Code syntax highlighting styles +│ │ ├── layout.tsx # Root layout with metadata +│ │ ├── MobileNav.tsx # Mobile navigation component +│ │ └── page.tsx # Homepage with post listing +│ └── lib/ # Utility libraries +│ ├── markdown.ts # Markdown processing with marked.js +│ └── postsDirectory.ts # Post directory management and parsing +├── posts/ # Markdown blog posts storage │ ├── pinned.json # Pinned posts configuration -│ ├── welcome.md # Welcome post -│ └── mdtest.md # Test post -├── public/ # Static assets (favicons, etc.) -├── electron/ # Desktop app configuration -│ └── main.js # Electron main process +│ ├── welcome.md # Welcome post with frontmatter +│ ├── mdtest.md # Test post with various markdown features +│ ├── anchor-test.md # Test post for anchor linking +│ └── ii/ # Example nested folder structure +├── public/ # Static assets +│ ├── android-chrome-192x192.png +│ ├── android-chrome-512x512.png +│ ├── apple-touch-icon.png +│ ├── favicon-16x16.png +│ ├── favicon-32x32.png +│ ├── favicon.ico +│ └── site.webmanifest +├── electron/ # Desktop application +│ └── main.js # Electron main process configuration ├── Dockerfile # Docker container configuration ├── docker.sh # Docker deployment script -├── entrypoint.sh # Container entrypoint -└── package.json # Dependencies and scripts +├── entrypoint.sh # Container entrypoint script +├── next-env.d.ts # Next.js TypeScript definitions +├── next.config.js # Next.js configuration +├── package-lock.json # npm lock file +├── package.json # Dependencies and scripts +├── postcss.config.js # PostCSS configuration +├── tailwind.config.js # Tailwind CSS configuration +├── tsconfig.json # TypeScript configuration +└── LICENSE # MIT License ``` +### Key Components + +#### Frontend (Next.js 14 App Router) +- **`src/app/page.tsx`**: Homepage with responsive post listing and search +- **`src/app/posts/[...slug]/page.tsx`**: Individual post pages with anchor linking support +- **`src/app/admin/page.tsx`**: Admin dashboard with content management +- **`src/app/admin/manage/page.tsx`**: Advanced content management interface + +#### API Routes +- **Post Management**: CRUD operations for blog posts +- **Folder Management**: Create, delete, and organize content structure +- **Authentication**: Password management and validation +- **Export**: Docker and local export functionality +- **Upload**: Drag & drop file upload handling + +#### Utilities +- **`src/lib/markdown.ts`**: Markdown processing with syntax highlighting +- **`src/lib/postsDirectory.ts`**: File system operations and post parsing + +#### Desktop App +- **`electron/main.js`**: Electron configuration for desktop application + +#### Deployment +- **`Dockerfile`**: Multi-stage build for production deployment +- **`docker.sh`**: Automated deployment script with volume management +- **`entrypoint.sh`**: Container initialization and post setup + --- ## ⚡ Quick Start diff --git a/posts/mdtest.md b/posts/mdtest.md index 945a490..1b6008b 100644 --- a/posts/mdtest.md +++ b/posts/mdtest.md @@ -11,23 +11,16 @@ author: Rattatwinko's * [Overview](#overview) * [Philosophy](#philosophy) - * [Inline HTML](#html) - * [Automatic Escaping for Special Characters](#autoescape) -* [Block Elements](#block) - * [Paragraphs and Line Breaks](#p) - * [Headers](#header) - * [Blockquotes](#blockquote) - * [Lists](#list) - * [Code Blocks](#precode) - * [Horizontal Rules](#hr) -* [Span Elements](#span) - * [Links](#link) - * [Emphasis](#em) +* [Block Elements](#block-elements) + * [Paragraphs and Line Breaks](#paragraphs-and-line-breaks) + * [Headers](#headers) + * [Blockquotes](#blockquotes) + * [Lists](#lists) + * [Code Blocks](#code-blocks) +* [Span Elements](#span-elements) + * [Links](#links) + * [Emphasis](#emphasis) * [Code](#code) - * [Images](#img) -* [Miscellaneous](#misc) - * [Backslash Escapes](#backslash) - * [Automatic Links](#autolink) **Note:** This document is itself written using Markdown; you diff --git a/posts/welcome.md b/posts/welcome.md index 6c0f677..de9268d 100644 --- a/posts/welcome.md +++ b/posts/welcome.md @@ -10,6 +10,20 @@ author: Rattatwinko's # Welcome to the Blog +## Overview + +- [Starting Things off!](#starting-things-off) +- [Formatting](#formatting) +- [Some Technical Information](#some-technical-information) +- [Building](#building) +- [Administration](#administration) +- [Todo List for the Project](#todo) +- [Issues with the Project](#issues) +- [Changelog](#changelog) +- [Closing Statements](#closing-statements) + +## Starting Things off! + This blog was built as a response to the lack of blogging systems that accept "human readable" formats editable in a terminal emulator. **Prerequisites:** @@ -101,12 +115,10 @@ You can pin a post both in the UI and in the backend of the server. | Status | Task | |:---------------------------------------------:|:-------------------------------------------------:| |DONE|Code Editor in Admin Panel with saving!| -| SEMI | Exporting Tar of 'Posts/' Folder| +| DONE! | Exporting Tar of 'Posts/' Folder| +| DONE! | Mobile Viewing of the Website| +| TO BE DONE! | Refactoring of the Code (Removing Garbage-Code) -### Exporting of Folder: - -This for now atleast , only works with Next.JS Production Server `npm install && npm run build && npm start` for reference. -Docker Support for now is limited. I've gotten Persistence working. ( On Branch PM2 ) --- @@ -116,6 +128,15 @@ If any issues pop up, please open a Gitea issue with **proper** error reports! --- +## Changelog: + +- Via merging of branch **"mobile"**: + - Will have support for mobile devices + - Scrolling will be "different" (auto header scroll trough links) + - Styling will be responsive! + +--- + ## Closing Statements Developing of this Applet has been really fun! Thanks JavaScript for fucking my ass harder than , eh ... idk , im gay, i cant make jokes about this. diff --git a/src/app/HeaderButtons.tsx b/src/app/HeaderButtons.tsx index fda0f03..f8f5451 100644 --- a/src/app/HeaderButtons.tsx +++ b/src/app/HeaderButtons.tsx @@ -19,18 +19,30 @@ const InfoIcon = ( export default function HeaderButtons() { return ( -
- +
+ Admin Login {/* If your server for about me is running on a different port, change the port number here */} - + About Me
diff --git a/src/app/MobileNav.tsx b/src/app/MobileNav.tsx new file mode 100644 index 0000000..6b267ac --- /dev/null +++ b/src/app/MobileNav.tsx @@ -0,0 +1,93 @@ +'use client'; + +import { useState } from 'react'; +import Link from 'next/link'; + +interface MobileNavProps { + blogOwner: string; +} + +export default function MobileNav({ blogOwner }: MobileNavProps) { + const [isOpen, setIsOpen] = useState(false); + + const toggleMenu = () => { + setIsOpen(!isOpen); + }; + + return ( +
+ {/* Mobile menu button */} + + + {/* Mobile menu overlay */} + {isOpen && ( +
+
e.stopPropagation()}> +
+

{blogOwner}'s Blog

+ + + +
+
+ © {new Date().getFullYear()} {blogOwner} +
+
+
+
+
+ )} +
+ ); +} \ No newline at end of file diff --git a/src/app/admin/manage/page.tsx b/src/app/admin/manage/page.tsx index 2709875..238fff7 100644 --- a/src/app/admin/manage/page.tsx +++ b/src/app/admin/manage/page.tsx @@ -219,37 +219,38 @@ export default function ManagePage() { } return ( -
+
-
-
-

Manage Content

+ {/* Mobile-friendly header */} +
+
+

Manage Content

Back to Admin
- {/* Breadcrumbs with back button */} -
+ {/* Mobile-friendly breadcrumbs */} +
{currentPath.length > 0 && ( )} -
+
{breadcrumbs.map((crumb, index) => (
- {index > 0 && /} + {index > 0 && /}
- {/* Content List */} -
+ {/* Mobile-friendly content grid */} +
{currentNodes.map((node) => ( node.type === 'folder' ? (
setCurrentPath([...currentPath, node.name])} onDoubleClick={() => setDeleteAllConfirm({ show: true, folder: node })} onDragOver={e => { e.preventDefault(); setDragOverFolder(node.name); }} @@ -301,8 +302,8 @@ export default function ManagePage() { }} >
-
-

{node.name}

+
+

{node.name}

{folderDetails[node.path] ? ( folderDetails[node.path].error ? ( @@ -321,12 +322,12 @@ export default function ManagePage() {
- {/* Delete Confirmation Modal */} + {/* Mobile-friendly delete confirmation modal */} {deleteConfirm.show && ( -
-
+
+

Confirm Delete

-

+

Are you sure you want to delete {deleteConfirm.item?.type === 'folder' ? 'folder' : 'post'} "{deleteConfirm.item?.type === 'folder' ? deleteConfirm.item.name : deleteConfirm.item?.title}"?

-
+
@@ -414,20 +415,20 @@ export default function ManagePage() {
)} - {/* Delete Full Folder Modal */} + {/* Mobile-friendly delete full folder modal */} {deleteAllConfirm.show && ( -
-
+
+

Delete Full Folder

-

+

Are you sure you want to delete the entire folder and all its contents?
This cannot be undone!

-
+
@@ -448,7 +449,7 @@ export default function ManagePage() { setDeleteAllConfirm({ show: false, folder: null }); loadContent(); }} - className="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700" + className="px-4 py-3 sm:py-2 bg-red-600 text-white rounded hover:bg-red-700 text-base font-medium" > Delete All diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 455c361..d50f017 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -640,15 +640,15 @@ export default function AdminPage() { }; return ( -
+
{pinFeedback && ( -
+
{pinFeedback}
)} {!isAuthenticated ? ( -
-

Admin Login

+
+

Admin Login

@@ -692,41 +692,44 @@ export default function AdminPage() {
) : (
-
-

Admin Dashboard

-
- - + {/* Mobile-friendly header */} +
+

Admin Dashboard

+
+
+ + +
{/* Docker warning above export button */} {isDocker && ( -
+
Warning: Docker is in use. Exporting will export the entire /app root directory (including all files and folders in the container's root).
)} -
+
{rememberExportChoice && lastExportChoice && ( -
+
💾 {lastExportChoice === 'docker' ? 'Docker' : 'Local'} -

Passwort ändern

+

Passwort ändern

@@ -756,7 +759,7 @@ export default function AdminPage() { type="password" value={changePwOld} onChange={e => setChangePwOld(e.target.value)} - className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2" + className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-base" required autoComplete="current-password" /> @@ -767,7 +770,7 @@ export default function AdminPage() { type="password" value={changePwNew} onChange={e => setChangePwNew(e.target.value)} - className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2" + className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-base" required autoComplete="new-password" /> @@ -778,7 +781,7 @@ export default function AdminPage() { type="password" value={changePwConfirm} onChange={e => setChangePwConfirm(e.target.value)} - className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2" + className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-base" required autoComplete="new-password" /> @@ -788,7 +791,7 @@ export default function AdminPage() { )} @@ -797,17 +800,17 @@ export default function AdminPage() {
)} - {/* Breadcrumbs with back button */} -
+ {/* Mobile-friendly breadcrumbs */} +
{currentPath.length > 0 && ( )} -
+
{breadcrumbs.map((crumb, index) => (
- {index > 0 && /} + {index > 0 && /}
{/* Show current folder path above post creation form */} -
+
Current folder: {currentPath.join('/') || 'root'}
{/* Create Folder Form */} -
-

Create New Folder

- +
+

Create New Folder

+ setNewFolderName(e.target.value)} placeholder="Folder name" - className="flex-1 rounded-md border border-gray-300 px-3 py-2" + className="flex-1 rounded-md border border-gray-300 px-3 py-2 text-base" required /> @@ -867,7 +870,7 @@ export default function AdminPage() { {/* Drag and Drop Zone */}
-

Drag and drop Markdown files here

-

Files will be uploaded to: {currentPath.join('/') || 'root'}

+

Drag and drop Markdown files here

+

Files will be uploaded to: {currentPath.join('/') || 'root'}

{/* Create Post Form */} -
-

Create New Post

+
+

Create New Post

@@ -890,7 +893,7 @@ export default function AdminPage() { type="text" value={newPost.title} onChange={(e) => setNewPost({ ...newPost, title: e.target.value })} - className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2" + className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-base" required />
@@ -900,7 +903,7 @@ export default function AdminPage() { type="date" value={newPost.date} onChange={(e) => setNewPost({ ...newPost, date: e.target.value })} - className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2" + className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-base" required />
@@ -910,7 +913,7 @@ export default function AdminPage() { type="text" value={newPost.tags} onChange={(e) => setNewPost({ ...newPost, tags: e.target.value })} - className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2" + className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-base" placeholder="tag1, tag2, tag3" />
@@ -919,41 +922,36 @@ export default function AdminPage() {