### Description
- As the title
### Package Changes
_No response_
### Screenshots
_No response_
### Reference
Resolves#142.
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #143
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
- As the title
### Package Changes
_No response_
### Screenshots
|Scenario|Screenshot|
|-|-|
|Posts list||
|Empty input||
|Pattern not matched||
### Reference
Resolve#126.
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #139
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
- Create a dashboard layout (with a navigation sidebar)
- Only logged in users are able to access (others 404)
### Package Changes
> shadcn-svelte
```json
{
"@lucide/svelte": "^0.545.0",
"clsx": "^2.1.1",
"tailwind-merge": "^3.3.1",
"tailwind-variants": "^3.1.1",
"tw-animate-css": "^1.4.0"
}
```
### Screenshots
|Status|Screenshot|
|-|-|
|Logged in||
|Logged out||
### Reference
Resolves#136.
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #137
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
#### Backend
- String and interger can be pass as `id` to `GET` `/post/{id}`
- For the posts existed, the default `semantic_id` for them will be `_id`. (e.g. `_1`, `_2`)
- Semantic ID should follow the rules:
1. It shouldn't be an integer
1. It should match the pattern: `^[0-9a-zA-Z_\-]+$`
<br>
|Semantic ID|Result|Note|
|-|-|-|
|12|X|against with `i`|
|-3|X|against with `i`|
|3.14|X|against with `ii`|
|hello world|X|against with `ii`|
|*EMPTY*|X|against with `ii`|
|12_34-56|O||
#### Frontend
- The href of post preview card becomes the semantic ID.
### Package Changes
```toml
regex = "1.12.1"
```
### Screenshots

### Reference
Resolves#125.
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #134
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
This PR updates the application to handle posts that may not have a publication date (e.g., drafts) by making the `published_time` field optional across the entire post feature stack.
This ensures that draft posts can be processed and rendered without causing errors, and prevents search engine metadata from being generated for content that is not yet published.
#### Key Changes:
* **DTO & Schema (`postInfoResponseDto.ts`):**
* The Zod schema for `PostInfoResponseSchema` has been updated to mark `published_time` as `.nullable()`.
* The `PostInfoResponseDto` class now correctly handles a `null` value from the API, mapping it to `Date | null`.
* **Domain Entity (`postInfo.ts`):**
* The core `PostInfo` entity's `publishedTime` property is now typed as `Date | null` to reflect the business logic that a post may be unpublished.
* **View Model (`postInfoViewModel.ts`):**
* Updated `publishedTime` to be `Date | null`.
* Added a new `isPublished` boolean getter for convenient conditional logic in the UI.
* The `formattedPublishedTime` getter now returns `string | null`.
* Dehydration and rehydration logic (`dehydrate`/`rehydrate`) has been updated to correctly handle the nullable `publishedTime`.
* **UI Component (`PostContentPage.svelte`):**
* The component now uses the new `isPublished` flag to conditionally render the `<StructuredData>` component for SEO. This ensures that structured data is only included for posts that have been officially published.
### Package Changes
_No response_
### Screenshots
_No response_
### Reference
Resolves#118
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #121
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
#### Overview
This PR improves the website's SEO by:
1. Moving title and meta description tags from app.html to individual page components
2. Adding dynamic meta descriptions based on page content
3. Implementing structured data for blog posts using JSON-LD
4. Optimizing meta descriptions for better search engine visibility
#### Changes
- **app.html**: Removed static title and meta description tags
- **HomePage.svelte**: Added descriptive title parameter to generateTitle function
- **Terminal.svelte**: Dynamically generates meta description from terminal lines
- **PostContentPage.svelte**: Added meta description and structured data for blog posts
- **PostOverallPage.svelte**: Added descriptive meta description for blog listing page
- **StructuredData.svelte**: Created new component to generate JSON-LD structured data for blog posts
#### Benefits
- Improved SEO through better metadata management
- Enhanced search engine visibility with structured data
- More accurate and dynamic meta descriptions
- Better control over page-specific metadata
> [!NOTE]
> Since sitemap auto generating is a little more complex, it will be solved in #117 in the future.
### Package Changes
_No response_
### Screenshots
_No response_
### Reference
Resolves#48
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #116
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
This PR introduces full CRUD (Create, Read, Update) functionality for post labels, implemented by following the existing Clean Architecture.
#### Backend
* **New API Endpoints for Label Management:**
* `POST /label`: Create a new label (**authentication required**).
* `PUT /label/{id}`: Update a label by its ID (**authentication required**).
* `GET /label`: Get all labels.
* **Architectural Implementation:**
* **Delivery Layer**: Added `CreateLabelRequestDto`, `UpdateLabelRequestDto`, and updated `PostController` with methods to handle label-related operations.
* **Application Layer**: Created corresponding use cases (`CreateLabelUseCase`, `UpdateLabelUseCase`, `GetAllLabelsUseCase`) to handle business logic.
* **Gateway/Framework Layer**: Implemented `LabelRepository` and `LabelDbService` to manage database interactions, including creating, updating, and querying labels.
* **Route Adjustment:**
* The route for fetching all post info has been changed from `GET /post/all` to `GET /post` to be more RESTful.
#### Frontend
* **API Call Update:**
* To match the backend route change, the API path for fetching all posts is updated from `/post/all` to `/post`.
### Package Changes
_No response_
### Screenshots
_No response_
### Reference
Resolves#105
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #107
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
- Enhance typography and color consistency in PostPreview and PostContentPage
- Add tailwind configuration for custom typography styles
### Package Changes
_No response_
### Screenshots
_No response_
### Reference
Resolves#87
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #88
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
- Use `generateTitle` to combine app name and page title.
### Package Changes
_No response_
### Screenshots
|Home|Post Overall|Post Content|
|-|-|-|
||||
### Reference
Resolves#73
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #77
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
- A a `title` attribute on the `<a>` element.
- Make the title as `<h2>` and the description as `<p>`.
### Package Changes
_No response_
### Screenshots

### Reference
Resolves #
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #76
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
- Implement the content page
- Parse markdown formant content to html by `markdown-it`
- Use `sanitize-html` to prevent from XSS attack
- Style the html with `tailwindcss-typography`
- Fix the issue when backend parse the password to url
- Fix and make the post info list from backend always sorted by id
### Package Changes
### Rust
```toml
percent-encoding = "2.3.1"
```
### Node
```json
{
"@types/markdown-it": "^14.1.2",
"@types/sanitize-html": "^2.16.0",
"markdown-it": "^14.1.0",
"sanitize-html": "^2.17.0"
}
```
### Screenshots
|Desktop|Mobile|
|-|-|
|||
### Reference
Resolves#45
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #67
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
### Description
- Change the format of color response
```json
{
"red": 0,
"green": 255,
"blue": 128,
"alpha": 255
}
```
- The relationship between the label's background color and its highlight color is calculated. The method involves first converting the RGB color value to HSL, then decreasing the L (lightness) component, and finally converting it back to RGB.
### Package Changes
```json
{
"zod": "^4.0.5"
}
```
### Screenshots
|Desktop|Mobile|
|-|-|
|||
### Reference
Resolves#44
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #64
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>