mirror of
https://github.com/VladSez/easy-invoice-pdf
synced 2026-04-21 13:37:40 +00:00
feat: update design for Github Star CTA btn, update changelog design (#208)
* feat: update design for Github Star CTA btn, update changelog design - Introduced a new skill called 'caveman' that allows for ultra-compressed communication, reducing token usage while maintaining technical accuracy. - Added detailed documentation for the 'caveman' skill, outlining grammar rules, response patterns, and examples. - Updated skills-lock.json to include the new 'caveman' skill. - Enhanced UI components for better spacing and visual consistency in various sections of the application. * chore: update README - Added a link to the EasyInvoicePDF website in the README logo section. - Enhanced the README with updated version dates and improved formatting for release notes. - Corrected the release date for v1.0.0 and v1.0.1 in the changelog files to reflect accurate information. * chore: minor readme fix * style: update GitHub Star CTA button to use rounded-full design - Changed button styling from rounded-lg to rounded-full for improved aesthetics and consistency. * chore: minor readme fix * minor changelog clarifications
This commit is contained in:
parent
10b3fb2991
commit
4f95e53e92
15 changed files with 245 additions and 76 deletions
72
.agents/skills/caveman/SKILL.md
Normal file
72
.agents/skills/caveman/SKILL.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
name: caveman
|
||||
description: >
|
||||
Ultra-compressed communication mode. Slash token usage ~75% by speaking like caveman
|
||||
while keeping full technical accuracy. Use when user says "caveman mode", "talk like caveman",
|
||||
"use caveman", "less tokens", "be brief", or invokes /caveman. Also auto-triggers
|
||||
when token efficiency is requested.
|
||||
---
|
||||
|
||||
# Caveman Mode
|
||||
|
||||
## Core Rule
|
||||
|
||||
Respond like smart caveman. Cut articles, filler, pleasantries. Keep all technical substance.
|
||||
|
||||
## Grammar
|
||||
|
||||
- Drop articles (a, an, the)
|
||||
- Drop filler (just, really, basically, actually, simply)
|
||||
- Drop pleasantries (sure, certainly, of course, happy to)
|
||||
- Short synonyms (big not extensive, fix not "implement a solution for")
|
||||
- No hedging (skip "it might be worth considering")
|
||||
- Fragments fine. No need full sentence
|
||||
- Technical terms stay exact. "Polymorphism" stays "polymorphism"
|
||||
- Code blocks unchanged. Caveman speak around code, not in code
|
||||
- Error messages quoted exact. Caveman only for explanation
|
||||
|
||||
## Pattern
|
||||
|
||||
```
|
||||
[thing] [action] [reason]. [next step].
|
||||
```
|
||||
|
||||
Not:
|
||||
> Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by...
|
||||
|
||||
Yes:
|
||||
> Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:
|
||||
|
||||
## Examples
|
||||
|
||||
**User:** Why is my React component re-rendering?
|
||||
|
||||
**Normal (69 tokens):** "The reason your React component is re-rendering is likely because you're creating a new object reference on each render cycle. When you pass an inline object as a prop, React's shallow comparison sees it as a different object every time, which triggers a re-render. I'd recommend using useMemo to memoize the object."
|
||||
|
||||
**Caveman (19 tokens):** "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`."
|
||||
|
||||
---
|
||||
|
||||
**User:** How do I set up a PostgreSQL connection pool?
|
||||
|
||||
**Caveman:**
|
||||
```
|
||||
Use `pg` pool:
|
||||
```
|
||||
```js
|
||||
const pool = new Pool({
|
||||
max: 20,
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 2000,
|
||||
})
|
||||
```
|
||||
```
|
||||
max = concurrent connections. Keep under DB limit. idleTimeout kill stale conn.
|
||||
```
|
||||
|
||||
## Boundaries
|
||||
|
||||
- Code: write normal. Caveman English only
|
||||
- Git commits: normal
|
||||
- PR descriptions: normal
|
||||
- User say "stop caveman" or "normal mode": revert immediately
|
||||
76
.cursor/rules/caveman.mdc
Normal file
76
.cursor/rules/caveman.mdc
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
---
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
---
|
||||
name: caveman
|
||||
description: >
|
||||
Ultra-compressed communication mode. Slash token usage ~75% by speaking like caveman
|
||||
while keeping full technical accuracy. Use when user says "caveman mode", "talk like caveman",
|
||||
"use caveman", "less tokens", "be brief", or invokes /caveman. Also auto-triggers
|
||||
when token efficiency is requested.
|
||||
---
|
||||
|
||||
# Caveman Mode
|
||||
|
||||
## Core Rule
|
||||
|
||||
Respond like smart caveman. Cut articles, filler, pleasantries. Keep all technical substance.
|
||||
|
||||
## Grammar
|
||||
|
||||
- Drop articles (a, an, the)
|
||||
- Drop filler (just, really, basically, actually, simply)
|
||||
- Drop pleasantries (sure, certainly, of course, happy to)
|
||||
- Short synonyms (big not extensive, fix not "implement a solution for")
|
||||
- No hedging (skip "it might be worth considering")
|
||||
- Fragments fine. No need full sentence
|
||||
- Technical terms stay exact. "Polymorphism" stays "polymorphism"
|
||||
- Code blocks unchanged. Caveman speak around code, not in code
|
||||
- Error messages quoted exact. Caveman only for explanation
|
||||
|
||||
## Pattern
|
||||
|
||||
```
|
||||
[thing] [action] [reason]. [next step].
|
||||
```
|
||||
|
||||
Not:
|
||||
> Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by...
|
||||
|
||||
Yes:
|
||||
> Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:
|
||||
|
||||
## Examples
|
||||
|
||||
**User:** Why is my React component re-rendering?
|
||||
|
||||
**Normal (69 tokens):** "The reason your React component is re-rendering is likely because you're creating a new object reference on each render cycle. When you pass an inline object as a prop, React's shallow comparison sees it as a different object every time, which triggers a re-render. I'd recommend using useMemo to memoize the object."
|
||||
|
||||
**Caveman (19 tokens):** "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`."
|
||||
|
||||
---
|
||||
|
||||
**User:** How do I set up a PostgreSQL connection pool?
|
||||
|
||||
**Caveman:**
|
||||
```
|
||||
Use `pg` pool:
|
||||
```
|
||||
```js
|
||||
const pool = new Pool({
|
||||
max: 20,
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 2000,
|
||||
})
|
||||
```
|
||||
```
|
||||
max = concurrent connections. Keep under DB limit. idleTimeout kill stale conn.
|
||||
```
|
||||
|
||||
## Boundaries
|
||||
|
||||
- Code: write normal. Caveman English only
|
||||
- Git commits: normal
|
||||
- PR descriptions: normal
|
||||
- User say "stop caveman" or "normal mode": revert immediately
|
||||
32
README.md
32
README.md
|
|
@ -1,6 +1,8 @@
|
|||
<div align="center">
|
||||
<!-- source: .github/screenshots/easy-invoice-logo-readme.png -->
|
||||
<img src="https://github.com/user-attachments/assets/cb9bcc91-b4c8-40b1-b406-bc606c5d9315" alt="EasyInvoicePDF Logo" width="80" height="80">
|
||||
<a href="https://easyinvoicepdf.com/?ref=github">
|
||||
<img src="https://github.com/user-attachments/assets/cb9bcc91-b4c8-40b1-b406-bc606c5d9315" alt="EasyInvoicePDF Logo" width="80" height="80">
|
||||
</a>
|
||||
<h1>EasyInvoicePDF</h1>
|
||||
<h3>Free & Open-Source Invoice Generator</h3>
|
||||
<p>Create professional invoices instantly in your browser with <strong>Live Preview</strong>, <strong>Multiple Templates</strong> (including a Stripe-style design). <strong>No Sign-Up Required</strong>.</p>
|
||||
|
|
@ -99,52 +101,62 @@ _**Add payment QR codes** with any invoice-related information (payment links, U
|
|||
<!-- source: .github/screenshots/default-template.png -->
|
||||
<!-- source: .github/screenshots/stripe-template.png -->
|
||||
|
||||
| Default Invoice Template | Stripe Invoice Template |
|
||||
| :-----------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------: |
|
||||
| Default Invoice Template | Stripe Invoice Template |
|
||||
| :--------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||
| <img src="https://github.com/user-attachments/assets/7779cd52-e2a9-442a-8ac8-262387319b3e" width="1200" height="960" alt="Default Invoice Template"> | <img src="https://github.com/user-attachments/assets/ee8d5337-89fc-461c-b1c1-2680287df514" width="1200" height="960" alt="Stripe Invoice Template"> |
|
||||
|
||||
</div>
|
||||
|
||||
## 📢 What's New
|
||||
|
||||
**v1.0.3 — Seller & Buyer Improvements (Mar 2026)**
|
||||
### EasyInvoicePDF v1.0.3 — Seller & Buyer Improvements (March 29, 2026)
|
||||
|
||||
- **Email visibility toggle** — control whether email addresses appear in the generated PDF
|
||||
- **Seller & Buyer Email visibility toggle** — control whether email addresses appear in the generated PDF
|
||||
- **Confirm discard dialog** — warns about unsaved changes when closing buyer/seller dialogs
|
||||
- **Improved seller & buyer forms** — reworked layout, locked-state banners, and cleaner field grouping
|
||||
- **Out-of-Date dates helper** shows outdated fields and provides a button to update all dates at once
|
||||
- **Auto-scroll (to the last position) the invoice form on mobile** when switching between tabs (UX improvement)
|
||||
|
||||
https://github.com/user-attachments/assets/1b39eb6f-e2be-493f-9825-cbce3dc6fa16
|
||||
|
||||
[Full release notes for v1.0.3](https://github.com/VladSez/easy-invoice-pdf/releases/tag/v1.0.3)
|
||||
|
||||
---
|
||||
|
||||
**v1.0.2 — QR Codes & Multi-Page PDFs (Mar 2026)**
|
||||
### EasyInvoicePDF v1.0.2 — QR Codes & Multi-Page PDFs (March 10, 2026)
|
||||
|
||||
- **QR code support** — add payment QR codes with custom descriptions to both templates
|
||||
- **Logo upload for default template** — previously available only in the Stripe template
|
||||
- **Searchable currency combobox** — grouped categories replace the native dropdown
|
||||
- **Logo upload for default template** — add a logo to the default invoice template
|
||||
- **Searchable currency combobox** — search by currency code, symbol, or name, grouped into categories replacing the native dropdown
|
||||
- **Improved multi-page PDFs** — automatic pagination and page breaks for large invoices
|
||||
|
||||

|
||||
|
||||
[Full release notes for v1.0.2](https://github.com/VladSez/easy-invoice-pdf/releases/tag/v1.0.2)
|
||||
|
||||
---
|
||||
|
||||
**v1.0.1 — Stripe Template & Tax Customization (Jan 2026)**
|
||||
### EasyInvoicePDF v1.0.1 — Stripe Template & Tax Customization (June 12, 2025)
|
||||
|
||||
- **Stripe-inspired invoice template** — professional styling with logo upload and payment URL field
|
||||
- **Customizable tax labels** — set VAT, GST, Sales Tax, or any custom label per invoice language
|
||||
- **Improved i18n** — dynamic tax label updates and better locale-based currency handling
|
||||
|
||||
https://github.com/user-attachments/assets/4eef2b90-678b-4a55-9ee5-8fcf195c993a
|
||||
|
||||
[Full release notes for v1.0.1](https://github.com/VladSez/easy-invoice-pdf/releases/tag/EasyInvoicePDF-1.0.1)
|
||||
|
||||
---
|
||||
|
||||
**v1.0.0 — Initial Release (Nov 2025)**
|
||||
### EasyInvoicePDF v1.0.0 — Initial Release (November 19, 2025)
|
||||
|
||||
- **Live preview** — invoice updates in real-time as you type
|
||||
- **Instant PDF download** — one-click, no sign-up required
|
||||
- **Shareable links** — send invoices directly to clients without attachments
|
||||
- **10 languages & 120+ currencies** — full multi-language and currency support out of the box
|
||||
|
||||
https://github.com/user-attachments/assets/23bb5448-c9fb-4ff2-98f3-0b80d75b7683
|
||||
|
||||
[Full release notes for v1.0.0](https://github.com/VladSez/easy-invoice-pdf/releases/tag/EasyInvoicePDF-v1.0.0)
|
||||
|
||||
## 🌟 Star History
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
{
|
||||
"version": 1,
|
||||
"skills": {
|
||||
"caveman": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"computedHash": "aa7939fc4d1fe31484090290da77f2d21e026aa4b34b329d00e6630feb985d75"
|
||||
},
|
||||
"changelog-maintenance": {
|
||||
"source": "supercent-io/skills-template",
|
||||
"sourceType": "github",
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ export function InvoicePageHeader({
|
|||
) : null} */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 mt-1 flex flex-row items-center justify-center lg:mb-0 lg:mt-4 lg:justify-start xl:mt-1">
|
||||
<div className="mb-2.5 flex flex-row items-center justify-center lg:-mb-1.5 lg:mt-4 lg:justify-start xl:mt-1">
|
||||
<ProjectInfoLinks />
|
||||
</div>
|
||||
|
||||
|
|
@ -199,6 +199,10 @@ export function InvoicePageHeader({
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders project information links including demo video, feedback, and GitHub links.
|
||||
* Manages video dialog state for the "How it works" demo.
|
||||
*/
|
||||
function ProjectInfoLinks() {
|
||||
const [isVideoDialogOpen, setIsVideoDialogOpen] = useState(false);
|
||||
|
||||
|
|
@ -209,31 +213,33 @@ function ProjectInfoLinks() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="relative bottom-0 flex flex-wrap items-center justify-center gap-1 text-center text-sm text-gray-900 lg:bottom-3">
|
||||
<div className="relative bottom-0 flex flex-wrap items-center justify-center gap-1.5 text-center text-sm text-gray-900 lg:bottom-4">
|
||||
<button
|
||||
onClick={handleWatchDemoClick}
|
||||
className="inline-flex items-center gap-1.5 transition-colors hover:text-blue-600 hover:underline"
|
||||
className="inline-flex cursor-pointer items-center transition duration-200 hover:text-blue-600 hover:underline active:scale-[0.96]"
|
||||
>
|
||||
<span>How it works</span>
|
||||
How it works
|
||||
</button>
|
||||
{" | "}
|
||||
<span className="h-3 w-px bg-slate-500" aria-hidden="true" />
|
||||
<a
|
||||
href="https://dub.sh/easy-invoice-pdf-feedback"
|
||||
className="transition-colors hover:text-blue-600 hover:underline"
|
||||
className="inline-flex items-center transition duration-200 hover:text-blue-600 hover:underline active:scale-[0.96]"
|
||||
target="_blank"
|
||||
>
|
||||
Share your feedback
|
||||
</a>
|
||||
{" | "}
|
||||
<span className="h-3 w-px bg-slate-500" aria-hidden="true" />
|
||||
|
||||
<a
|
||||
href={GITHUB_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group inline-flex items-center gap-1 transition-colors hover:text-blue-600 hover:underline"
|
||||
className="group inline-flex items-center gap-1.5 rounded-full border border-slate-200 px-3 py-1 text-xs font-medium text-slate-900 shadow-sm transition-[colors,transform,border-color] duration-200 hover:border-blue-300 hover:text-blue-600 active:scale-[0.96]"
|
||||
>
|
||||
<GithubIcon className="size-4 transition-transform group-hover:fill-blue-600" />
|
||||
<span className="group-hover:text-blue-600">View on GitHub</span>
|
||||
<GithubIcon className="size-4 transition-[transform,fill] duration-200 group-hover:scale-105 group-hover:fill-blue-600" />
|
||||
<span className="transition-colors duration-200 group-hover:text-blue-600">
|
||||
View on GitHub
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -786,7 +786,7 @@ export function AppPageClient({
|
|||
</ul>
|
||||
}
|
||||
/>
|
||||
<div className="fixed right-2 top-2 z-50 duration-500 animate-in fade-in slide-in-from-top-4">
|
||||
<div className="fixed right-1.5 top-1.5 z-50 duration-500 animate-in fade-in slide-in-from-top-4">
|
||||
<GitHubStarCTA githubStarsCount={githubStarsCount} />
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ function HeroSection() {
|
|||
src={VIDEO_DEMO_URL}
|
||||
posterImg={VIDEO_DEMO_FALLBACK_IMG}
|
||||
testId="hero-about-page-video"
|
||||
description="How to create an invoice and download it as a PDF in Easy Invoice"
|
||||
description="How to create and download an invoice as a PDF in EasyInvoicePDF.com"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
export const metadata = {
|
||||
title: "EasyInvoicePDF Launch - Free & Open-Source Invoice Generator",
|
||||
title: "EasyInvoicePDF v1.0.0 - Free & Open-Source Invoice Generator",
|
||||
description:
|
||||
"Create professional invoices instantly with real-time preview and shareable links. No registration needed.",
|
||||
date: "2025-03-03",
|
||||
date: "2025-11-19",
|
||||
version: "1.0.0",
|
||||
type: "major",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export const metadata = {
|
||||
title:
|
||||
"QR Code Support, Logo Upload for the Default Invoice Template and Many More",
|
||||
"EasyInvoicePDF v1.0.2 - QR Code Support, Logo Upload for the Default Invoice Template and Many More",
|
||||
description:
|
||||
"QR code generation for invoices, logo upload for the default template, searchable currency combobox, and improved multi-page PDF support",
|
||||
date: "2026-03-10",
|
||||
|
|
@ -13,8 +13,8 @@ export const metadata = {
|
|||
## ✨ Highlights
|
||||
|
||||
- **QR code generation** for invoices with customizable descriptions and visibility toggles, supported in both default and Stripe templates
|
||||
- **Logo upload for the default invoice template** (previously available only in the Stripe template)
|
||||
- **Searchable currency combobox** with grouped categories, replacing the native dropdown for faster selection
|
||||
- **Logo upload for the default invoice template** add a logo to the default invoice template
|
||||
- **Searchable currency combobox** search by currency code, symbol, or name, grouped into categories replacing the native dropdown
|
||||
- **Improved multi-page PDF support** with automatic pagination and page breaks
|
||||
|
||||
---
|
||||
|
|
@ -36,24 +36,6 @@ export const metadata = {
|
|||
- Delete invoice item flow not working correctly
|
||||
- Item name field validation too strict (now optional for flexibility)
|
||||
|
||||
### What's Changed
|
||||
|
||||
- feat: add QR code functionality to invoice templates and other improvements + bug fixes by @VladSez in [#165](https://github.com/VladSez/easy-invoice-pdf/pull/165)
|
||||
- improvement: update QR code images and enhance invoice template visuals by @VladSez in [#172](https://github.com/VladSez/easy-invoice-pdf/pull/172)
|
||||
- test: enhance URL verification in e2e tests for various pages by @VladSez in [#174](https://github.com/VladSez/easy-invoice-pdf/pull/174)
|
||||
- test: update navigation wait strategy in e2e tests for improved reliability by @VladSez in [#175](https://github.com/VladSez/easy-invoice-pdf/pull/175)
|
||||
- feat: update Playwright configuration and enhance e2e tests by @VladSez in [#176](https://github.com/VladSez/easy-invoice-pdf/pull/176)
|
||||
- chore: adjust Playwright configuration and e2e test settings for stability by @VladSez in [#177](https://github.com/VladSez/easy-invoice-pdf/pull/177)
|
||||
- chore: set timezone environment variable in e2e workflow to fix timezone issue in node js server env by @VladSez in [#178](https://github.com/VladSez/easy-invoice-pdf/pull/178)
|
||||
- docs: add Star History section to README and improve e2e test navigation strategy by @VladSez in [#179](https://github.com/VladSez/easy-invoice-pdf/pull/179)
|
||||
- fix: delete invoice item flow by @VladSez in [#180](https://github.com/VladSez/easy-invoice-pdf/pull/180)
|
||||
- fix: fix i18n issue with generating pdf via api + other improvements by @VladSez in [#181](https://github.com/VladSez/easy-invoice-pdf/pull/181)
|
||||
- refactor: rename item removal handler and enhance user feedback in invoice form by @VladSez in [#182](https://github.com/VladSez/easy-invoice-pdf/pull/182)
|
||||
- refactor: currency searchable combobox by @VladSez in [#183](https://github.com/VladSez/easy-invoice-pdf/pull/183)
|
||||
- feat: expand TODO list with discounts feature and improve e2e workflow by @VladSez in [#186](https://github.com/VladSez/easy-invoice-pdf/pull/186)
|
||||
- feat: upload logo for default invoice templates, improve add invoice btn styles, add more e2e tests by @VladSez in [#189](https://github.com/VladSez/easy-invoice-pdf/pull/189)
|
||||
- fix: update README logo and refactor invoice form for Stripe payment link by @VladSez in [#190](https://github.com/VladSez/easy-invoice-pdf/pull/190)
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: [`EasyInvoicePDF-1.0.1...v1.0.2`](https://github.com/VladSez/easy-invoice-pdf/compare/EasyInvoicePDF-1.0.1...v1.0.2)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export const metadata = {
|
||||
title: "Seller & Buyer Improvements, Email Visibility Toggle and More",
|
||||
title:
|
||||
"EasyInvoicePDF v1.0.3 - Email visibility toggle for seller and buyer, reworked seller/buyer sections, confirm dialog to discard changes, UX improvements",
|
||||
description:
|
||||
"Email visibility toggle for seller/buyer sections, reworked form layouts with locked-state banners, ConfirmDiscardDialog, and auto-scroll on mobile",
|
||||
date: "2026-03-29",
|
||||
|
|
@ -9,11 +10,11 @@ export const metadata = {
|
|||
|
||||
## ✨ Highlights
|
||||
|
||||
- **Email visibility toggle** for seller and buyer sections — control whether the email address appears in the generated PDF
|
||||
- **Seller & Buyer Email visibility toggle** — control whether the email address appears in the generated PDF
|
||||
- **`ConfirmDiscardDialog`** component to warn users about unsaved changes when closing the buyer/seller dialogs
|
||||
- **Reworked seller and buyer information form sections** with improved layout, locked-state banners, and cleaner field grouping
|
||||
- **Auto-scroll the invoice form on mobile** when switching between tabs (UX improvement)
|
||||
- **Out-of-Date dates helper** improved with more accurate state detection
|
||||
- **Out-of-Date dates helper** shows outdated fields and provides a button to update all dates at once
|
||||
|
||||
<video
|
||||
src="https://github.com/user-attachments/assets/1b39eb6f-e2be-493f-9825-cbce3dc6fa16"
|
||||
|
|
@ -36,18 +37,6 @@ export const metadata = {
|
|||
- Buyer and seller dialogs now reset form values and pre-fill switch to their defaults when closed
|
||||
- Buyer and seller names are trimmed of whitespace before saving; whitespace-padded duplicates are rejected
|
||||
|
||||
### What's Changed
|
||||
|
||||
- feat: auto-scroll form on mobile when switching between tabs, fix loading placeholder by @VladSez in [#191](https://github.com/VladSez/easy-invoice-pdf/pull/191)
|
||||
- refactor: update layout and improve accessibility in invoice-related components by @VladSez in [#192](https://github.com/VladSez/easy-invoice-pdf/pull/192)
|
||||
- refactor: improve layout in BuyerDialog and SellerDialog components by @VladSez in [#193](https://github.com/VladSez/easy-invoice-pdf/pull/193)
|
||||
- refactor: streamline toast management in InvoiceForm component by @VladSez in [#194](https://github.com/VladSez/easy-invoice-pdf/pull/194)
|
||||
- feat: enhance buyer and seller management with new functionality and improved toast notifications by @VladSez in [#195](https://github.com/VladSez/easy-invoice-pdf/pull/195)
|
||||
- feat: reworked seller/buyer sections, email visibility switch field, shared invoice indicator, improved Out-of-Date helper + minor things by @VladSez in [#197](https://github.com/VladSez/easy-invoice-pdf/pull/197)
|
||||
- feat: add cancel confirm dialog for seller/buyer dialog, update gh actions, added new script update-github-actions in package.json by @VladSez in [#198](https://github.com/VladSez/easy-invoice-pdf/pull/198)
|
||||
- fix: update GitHub Actions script and fix buyer/seller dialog pre-fill bug by @VladSez in [#199](https://github.com/VladSez/easy-invoice-pdf/pull/199)
|
||||
- feat: replaced window.confirm with alert discard dialog for buyer and seller management by @VladSez in [#200](https://github.com/VladSez/easy-invoice-pdf/pull/200)
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: [`v1.0.2...v1.0.3`](https://github.com/VladSez/easy-invoice-pdf/compare/v1.0.2...v1.0.3)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
export const metadata = {
|
||||
title: "Stripe Invoice Template & Landing Page Improvements",
|
||||
title:
|
||||
"EasyInvoicePDF v1.0.1 - Stripe Invoice Template & Landing Page Improvements",
|
||||
description:
|
||||
"Introducing a modern, Stripe-inspired invoice template with professional styling and layout optimizations",
|
||||
date: "2025-06-28",
|
||||
date: "2025-06-12",
|
||||
version: "1.0.1",
|
||||
type: "major",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ function Header() {
|
|||
</div>
|
||||
<div className="flex items-center sm:mt-0 sm:gap-2">
|
||||
<Button variant="ghost" className="hidden lg:inline-flex" asChild>
|
||||
<Link href="/en/about">About product</Link>
|
||||
<Link href="/en/about">About</Link>
|
||||
</Button>
|
||||
<Button variant="ghost" className="hidden lg:inline-flex" asChild>
|
||||
<Link
|
||||
|
|
|
|||
|
|
@ -12,6 +12,14 @@ import { DateTime } from "./components/date-time";
|
|||
export const dynamic = "force-static";
|
||||
|
||||
// https://nextjs.org/docs/app/guides/mdx
|
||||
|
||||
/**
|
||||
* Changelog page component that displays all changelog entries in a timeline layout.
|
||||
* Fetches and renders changelog entries with dates, titles, and content.
|
||||
* Returns 404 if no entries are found.
|
||||
*
|
||||
* @returns The changelog page with all entries
|
||||
*/
|
||||
export default async function ChangelogPage() {
|
||||
const entries = await getChangelogEntries();
|
||||
|
||||
|
|
@ -45,6 +53,12 @@ export default async function ChangelogPage() {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single changelog entry card with date, title, and content.
|
||||
* On desktop, the date is sticky in the left column. On mobile, it appears above the title.
|
||||
*
|
||||
* @param entry - The changelog entry to display
|
||||
*/
|
||||
function ChangelogEntryCard({ entry }: { entry: ChangelogEntry }) {
|
||||
const formattedDate = formatChangelogDate(entry.metadata.date);
|
||||
|
||||
|
|
@ -71,6 +85,15 @@ function ChangelogEntryCard({ entry }: { entry: ChangelogEntry }) {
|
|||
</h2>
|
||||
</Link>
|
||||
|
||||
{/* Version Badge */}
|
||||
{entry.metadata.version ? (
|
||||
<div className="mt-2 flex items-center gap-2">
|
||||
<span className="inline-flex items-center rounded-full border border-slate-300 bg-slate-50 px-2.5 py-1 text-sm font-medium text-slate-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400">
|
||||
v{entry.metadata.version}
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{/* Article Content */}
|
||||
<article
|
||||
data-testid="changelog-entry-card"
|
||||
|
|
|
|||
|
|
@ -23,28 +23,31 @@ export function GitHubStarCTA({
|
|||
href={GITHUB_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="relative flex items-center gap-2 overflow-visible rounded-full border border-slate-300/70 bg-white px-3 py-1.5 text-sm shadow-sm transition-colors hover:border-slate-400/50 hover:bg-slate-50 hover:text-black"
|
||||
className="group relative inline-flex h-9 items-center overflow-hidden rounded-full bg-slate-900 text-sm font-medium text-white shadow-sm shadow-black/5 transition-[transform,background-color] duration-200 ease-out hover:bg-slate-900/90 active:scale-[0.96]"
|
||||
onClick={handleStarClick}
|
||||
aria-label="Star project on GitHub"
|
||||
data-testid="github-star-cta-button"
|
||||
>
|
||||
<div className="border-glow-mask z-10" aria-hidden="true">
|
||||
<div className="border-glow-shine animate-rotate-shine" />
|
||||
</div>
|
||||
<GithubIcon className="size-4 transition-all duration-300 ease-in-out" />
|
||||
{githubStarsCount > 0 ? (
|
||||
<span className="inline-flex items-center">
|
||||
<CountUpNumber number={githubStarsCount} />
|
||||
<span className="flex items-center gap-1.5 px-4">
|
||||
<span className="relative size-4">
|
||||
<GithubIcon className="absolute inset-0 size-4 fill-white transition-[opacity,transform,filter] duration-200 ease-out group-hover:scale-75 group-hover:opacity-0 group-hover:blur-[4px]" />
|
||||
<Star className="absolute inset-0 size-4 scale-[0.25] fill-yellow-400 text-yellow-400 opacity-0 blur-[4px] transition-[opacity,transform,filter] duration-200 ease-out group-hover:scale-100 group-hover:opacity-100 group-hover:blur-0" />
|
||||
</span>
|
||||
) : (
|
||||
"View on GitHub"
|
||||
)}
|
||||
{githubStarsCount > 0 ? (
|
||||
<>
|
||||
<span className="h-3.5 w-px bg-white/25" aria-hidden="true" />
|
||||
<CountUpNumber number={githubStarsCount} />
|
||||
</>
|
||||
) : (
|
||||
<span>Star on GitHub</span>
|
||||
)}
|
||||
</span>
|
||||
</a>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p className="flex items-center gap-1.5">
|
||||
<Star className="size-4 fill-yellow-400 text-yellow-500" />
|
||||
Give us a star on GitHub
|
||||
Star on GitHub
|
||||
</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export function CountUpNumber({ number }: Props) {
|
|||
const formattedNumber = formatter.format(number).toLowerCase();
|
||||
|
||||
return (
|
||||
<span className="min-w-[27px] text-center text-sm font-medium tabular-nums text-slate-950">
|
||||
<span className="min-w-[27px] text-center text-sm font-medium tabular-nums text-slate-50">
|
||||
{formattedNumber}
|
||||
</span>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue