update project README
This commit is contained in:
237
README.md
237
README.md
@@ -1,12 +1,10 @@
|
|||||||
# Developer Portfolio & Blog
|
# Developer Portfolio & Blog
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
A modern, high-performance personal portfolio and blog built with Astro.js. Designed to showcase your projects and technical writing with blazing-fast performance and exceptional SEO.
|
A modern, high-performance personal portfolio and blog built with Astro.js. Designed to showcase your projects and technical writing with blazing-fast performance and exceptional SEO.
|
||||||
|
|
||||||
## ✨ Features
|
## ✨ Features
|
||||||
@@ -20,21 +18,23 @@ A modern, high-performance personal portfolio and blog built with Astro.js. Desi
|
|||||||
- 🏷️ **Tag system** - Categorize blog posts and projects with tags
|
- 🏷️ **Tag system** - Categorize blog posts and projects with tags
|
||||||
- 📊 **Content collection** - Organized content management with Astro's content collections
|
- 📊 **Content collection** - Organized content management with Astro's content collections
|
||||||
- 🖼️ **Project showcase** - Display your work with images, descriptions, and technology tags
|
- 🖼️ **Project showcase** - Display your work with images, descriptions, and technology tags
|
||||||
|
- 📬 **Contact form** - Integrated contact form with Cloudflare Turnstile protection
|
||||||
|
- 🎓 **Education section** - Timeline-based display of academic background and achievements
|
||||||
|
- 📄 **Resume download** - Downloadable resume/CV for potential employers
|
||||||
|
|
||||||
## 🛠️ Tech Stack
|
## 🛠️ Tech Stack
|
||||||
|
|
||||||
- **[Astro.js](https://astro.build/)** - Static site generator with excellent performance
|
- **[Astro.js](https://astro.build/)** - Static site generator with excellent performance
|
||||||
- **[React.js](https://reactjs.org/)** - For interactive components
|
- **[Svelte](https://svelte.dev/)** - For interactive components
|
||||||
- **[Tailwind CSS](https://tailwindcss.com/)** - Utility-first CSS framework
|
- **[Tailwind CSS](https://tailwindcss.com/)** - Utility-first CSS framework
|
||||||
- **[TypeScript](https://www.typescriptlang.org/)** - Type safety and improved developer experience
|
- **[TypeScript](https://www.typescriptlang.org/)** - Type safety and improved developer experience
|
||||||
- **[MDX](https://mdxjs.com/)** - Markdown with JSX for rich content creation
|
- **[MDX](https://mdxjs.com/)** - Markdown with JSX for rich content creation
|
||||||
- **[Preact](https://preactjs.com/)** - Lightweight alternative to React for UI components
|
|
||||||
|
|
||||||
## 📋 Prerequisites
|
## 📋 Prerequisites
|
||||||
|
|
||||||
Before you begin, ensure you have the following installed:
|
Before you begin, ensure you have the following installed:
|
||||||
- [Node.js](https://nodejs.org/) (v18 or higher)
|
- [Node.js](https://nodejs.org/) (v18 or higher)
|
||||||
- [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/)
|
- [pnpm](https://pnpm.io)
|
||||||
- [Git](https://git-scm.com/)
|
- [Git](https://git-scm.com/)
|
||||||
|
|
||||||
## ⚙️ Installation & Setup
|
## ⚙️ Installation & Setup
|
||||||
@@ -47,226 +47,43 @@ Before you begin, ensure you have the following installed:
|
|||||||
|
|
||||||
2. **Install dependencies**
|
2. **Install dependencies**
|
||||||
```bash
|
```bash
|
||||||
npm install
|
pnpm install
|
||||||
# or
|
|
||||||
yarn install
|
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Start the development server**
|
### Development Server
|
||||||
|
|
||||||
|
1. **Start the development server**
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
pnpm run dev
|
||||||
# or
|
|
||||||
yarn dev
|
|
||||||
```
|
```
|
||||||
|
|
||||||
4. **Open your browser**
|
2. **Open your browser**
|
||||||
Navigate to `http://localhost:4321` to see the site running locally.
|
Navigate to `http://localhost:3010` to see the site running locally.
|
||||||
|
|
||||||
## 📁 Project Structure
|
### Production Server
|
||||||
|
|
||||||
```
|
1. **Build the static site**
|
||||||
portfolio/
|
```bash
|
||||||
├── public/ # Static assets
|
pnpm build
|
||||||
├── src/
|
|
||||||
│ ├── components/ # UI components
|
|
||||||
│ ├── content/ # Content collections
|
|
||||||
│ │ ├── blog/ # Blog posts in MD/MDX format
|
|
||||||
│ │ └── projects/ # Project data
|
|
||||||
│ ├── layouts/ # Page layouts
|
|
||||||
│ ├── lib/ # Utility functions
|
|
||||||
│ ├── pages/ # Page routes
|
|
||||||
│ └── styles/ # Global styles
|
|
||||||
├── astro.config.mjs # Astro configuration
|
|
||||||
├── tailwind.config.cjs # Tailwind CSS configuration
|
|
||||||
├── tsconfig.json # TypeScript configuration
|
|
||||||
└── package.json # Project dependencies
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 Usage
|
Your static files are now available in `./dist`
|
||||||
|
|
||||||
### Creating a Blog Post
|
|
||||||
|
|
||||||
1. Create a new `.mdx` or `.md` file in `src/content/blog`
|
|
||||||
2. Add frontmatter with title, description, date, tags, and authors
|
|
||||||
3. Write your content using Markdown and MDX components
|
|
||||||
|
|
||||||
```mdx
|
|
||||||
---
|
|
||||||
title: "Your Post Title"
|
|
||||||
description: "A brief description of your post"
|
|
||||||
date: 2025-04-20
|
|
||||||
tags: ["tag1", "tag2", "tag3"]
|
|
||||||
authors: ["Your Name", "Co-author (optional)"]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Your Post Title
|
|
||||||
|
|
||||||
Write your content here using Markdown.
|
|
||||||
|
|
||||||
## Subheading
|
|
||||||
|
|
||||||
More content...
|
|
||||||
|
|
||||||
|
2. **Preview your site**
|
||||||
|
```bash
|
||||||
|
pnpm preview
|
||||||
```
|
```
|
||||||
|
|
||||||
### Adding a Project
|
3. **Open your browser**
|
||||||
|
Navigate to `http://localhost:3000` to see the site running locally.
|
||||||
|
|
||||||
1. Create a new `.md` file in projects
|
### Deployment
|
||||||
2. Add project details including name, description, tags, and image path
|
|
||||||
|
|
||||||
## 🌙 Dark Mode
|
Deploy to Cloudflare Pages:
|
||||||
|
```bash
|
||||||
The project includes dark mode support using Tailwind CSS and Preact. It detects user preferences and applies the appropriate theme, with an option to toggle between light and dark modes.
|
pnpm deploy
|
||||||
|
|
||||||
## 📊 Data Utilities
|
|
||||||
|
|
||||||
The project includes several utility functions in data-utils.ts:
|
|
||||||
|
|
||||||
- `getAllPosts()` - Retrieve all blog posts
|
|
||||||
- `getRecentPosts(count)` - Get the most recent posts
|
|
||||||
- `getAdjacentPosts(currentId)` - Get next and previous posts
|
|
||||||
- `getAllTags()` - Get all tags used in posts
|
|
||||||
- `getSortedTags()` - Get tags sorted by usage count
|
|
||||||
- `getPostsByAuthor(authorId)` - Get all posts by a specific author
|
|
||||||
|
|
||||||
## 📊 Database Setup (Likes/Dislikes Feature)
|
|
||||||
|
|
||||||
The portfolio includes a post feedback system allowing visitors to like or dislike blog posts. This feature requires a PostgreSQL database to store vote data. This guide explains how to set it up using [Neon.tech](https://neon.tech).
|
|
||||||
|
|
||||||
### Setting Up Neon.tech Database
|
|
||||||
|
|
||||||
1. **Create a Neon.tech Account**
|
|
||||||
- Go to [Neon.tech](https://neon.tech) and sign up for an account
|
|
||||||
- Neon offers a generous free tier suitable for personal portfolio sites
|
|
||||||
|
|
||||||
2. **Create a New Project**
|
|
||||||
- From the Neon dashboard, click "New Project"
|
|
||||||
- Choose a name for your project (e.g., "portfolio-feedback")
|
|
||||||
- Select the closest region to your target audience
|
|
||||||
- Click "Create Project"
|
|
||||||
|
|
||||||
3. **Get Connection Details**
|
|
||||||
- In your project dashboard, find the connection string under "Connection Details"
|
|
||||||
- Save this connection string as you'll need it for your environment variables
|
|
||||||
|
|
||||||
4. **Set Environment Variables**
|
|
||||||
- Create a `.env` file in your project root (if not already present)
|
|
||||||
- Add your database connection string:
|
|
||||||
```
|
|
||||||
DATABASE_URL=your_neon_connection_string_here
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database Schema Setup
|
|
||||||
|
|
||||||
Run the following SQL queries in the Neon SQL Editor to create the necessary tables for the feedback system:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE post_feedback (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
post_id VARCHAR(255) NOT NULL,
|
|
||||||
likes INTEGER DEFAULT 0,
|
|
||||||
dislikes INTEGER DEFAULT 0,
|
|
||||||
CONSTRAINT unique_post_id UNIQUE (post_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE post_likes (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
post_id VARCHAR(255) NOT NULL,
|
|
||||||
fingerprint_id VARCHAR(255) NOT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
CONSTRAINT unique_like UNIQUE (post_id, fingerprint_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE post_dislikes (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
post_id VARCHAR(255) NOT NULL,
|
|
||||||
fingerprint_id VARCHAR(255) NOT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
CONSTRAINT unique_dislike UNIQUE (post_id, fingerprint_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX idx_post_feedback_post_id ON post_feedback (post_id);
|
|
||||||
CREATE INDEX idx_post_likes_post_id_fingerprint ON post_likes (post_id, fingerprint_id);
|
|
||||||
CREATE INDEX idx_post_dislikes_post_id_fingerprint ON post_dislikes (post_id, fingerprint_id);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### How the Feedback System Works
|
|
||||||
|
|
||||||
The feedback system consists of three tables:
|
|
||||||
- `post_feedback`: Stores aggregate counts of likes and dislikes for each post
|
|
||||||
- `post_likes`: Records individual like actions with fingerprint IDs to prevent duplicate votes
|
|
||||||
- `post_dislikes`: Records individual dislike actions with fingerprint IDs
|
|
||||||
|
|
||||||
### API Implementation
|
|
||||||
|
|
||||||
The portfolio includes API endpoints for handling likes and dislikes:
|
|
||||||
|
|
||||||
1. **Fetching Post Feedback**
|
|
||||||
- GET request to `/api/like/{postId}` returns current like/dislike counts
|
|
||||||
|
|
||||||
2. **Submitting Likes**
|
|
||||||
- POST request to `/api/like/{postId}` with fingerprint ID in the request body
|
|
||||||
- The system checks if the user has already liked/disliked the post
|
|
||||||
- If not, a like is recorded and the count is updated
|
|
||||||
|
|
||||||
3. **Submitting Dislikes**
|
|
||||||
- POST request to `/api/dislike/{postId}` works similarly to the like endpoint
|
|
||||||
- Prevents duplicate votes from the same visitor
|
|
||||||
|
|
||||||
### Working with the Database
|
|
||||||
|
|
||||||
When a new blog post is created:
|
|
||||||
- No manual database entry is needed
|
|
||||||
- The first like/dislike action will automatically create the entry in `post_feedback`
|
|
||||||
|
|
||||||
To reset likes for a post:
|
|
||||||
```sql
|
|
||||||
DELETE FROM post_likes WHERE post_id = 'your-post-id';
|
|
||||||
DELETE FROM post_dislikes WHERE post_id = 'your-post-id';
|
|
||||||
UPDATE post_feedback SET likes = 0, dislikes = 0 WHERE post_id = 'your-post-id';
|
|
||||||
```
|
|
||||||
|
|
||||||
To view post statistics:
|
|
||||||
```sql
|
|
||||||
SELECT * FROM post_feedback ORDER BY likes DESC;
|
|
||||||
```
|
|
||||||
|
|
||||||
To find which posts a specific user has interacted with:
|
|
||||||
```sql
|
|
||||||
SELECT post_id FROM post_likes WHERE fingerprint_id = 'specific-fingerprint-id';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Troubleshooting
|
|
||||||
|
|
||||||
If you encounter issues with the feedback system:
|
|
||||||
|
|
||||||
1. **Check Environment Variables**
|
|
||||||
- Ensure your `.env` file contains the correct `DATABASE_URL`
|
|
||||||
|
|
||||||
2. **Verify Database Connection**
|
|
||||||
- Add logging to your database connection code to check for errors
|
|
||||||
- Make sure your Neon.tech project is active and not in suspended state
|
|
||||||
|
|
||||||
3. **Check for Errors in Console**
|
|
||||||
- The feedback component logs errors that can help diagnose issues
|
|
||||||
|
|
||||||
4. **Reset User Vote State**
|
|
||||||
- Users can clear their localStorage to reset their voting state:
|
|
||||||
```javascript
|
|
||||||
// In browser console
|
|
||||||
localStorage.clear()
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🤝 Contributing
|
|
||||||
|
|
||||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
||||||
|
|
||||||
1. Fork the repository
|
|
||||||
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
||||||
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
||||||
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
||||||
5. Open a Pull Request
|
|
||||||
|
|
||||||
## 📄 License
|
## 📄 License
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ A modern, high-performance personal portfolio and blog built with Astro.js. Desi
|
|||||||
- 🏷️ **Tag system** - Categorize blog posts and projects with tags
|
- 🏷️ **Tag system** - Categorize blog posts and projects with tags
|
||||||
- 📊 **Content collection** - Organized content management with Astro's content collections
|
- 📊 **Content collection** - Organized content management with Astro's content collections
|
||||||
- 🖼️ **Project showcase** - Display your work with images, descriptions, and technology tags
|
- 🖼️ **Project showcase** - Display your work with images, descriptions, and technology tags
|
||||||
|
- 📬 **Contact form** - Integrated contact form with Cloudflare Turnstile protection
|
||||||
|
- 🎓 **Education section** - Timeline-based display of academic background and achievements
|
||||||
|
- 📄 **Resume download** - Downloadable resume/CV for potential employers
|
||||||
|
|
||||||
## 🛠️ Tech Stack
|
## 🛠️ Tech Stack
|
||||||
|
|
||||||
@@ -81,9 +84,16 @@ Your static files are now available in `./dist`
|
|||||||
pnpm preview
|
pnpm preview
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Open you browser**
|
3. **Open your browser**
|
||||||
Navigate to `http://localhost:3000` to see the site running locally.
|
Navigate to `http://localhost:3000` to see the site running locally.
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
|
||||||
|
Deploy to Cloudflare Pages:
|
||||||
|
```bash
|
||||||
|
pnpm deploy
|
||||||
|
```
|
||||||
|
|
||||||
## 📄 License
|
## 📄 License
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||||
Reference in New Issue
Block a user