feat: Invoice Editor improvements and code cleanup

Major Invoice Editor updates:
-  Fixed tripled scrollbar issue by removing unnecessary overflow classes
-  Implemented dynamic currency system with JSON data loading
-  Fixed F4 PDF generation error with proper paper size handling
-  Added proper padding to Total section matching table headers
-  Removed print functionality (users can print from PDF download)
-  Streamlined preview toolbar: Back, Size selector, Download PDF
-  Fixed all ESLint warnings and errors
-  Removed console.log statements across codebase for cleaner production
-  Added border-top to Total section for better visual consistency
-  Improved print CSS and removed JSX warnings

Additional improvements:
- Added currencies.json to public folder for proper HTTP access
- Enhanced MinimalTemplate with better spacing and layout
- Clean build with no warnings or errors
- Updated release notes with new features
This commit is contained in:
dwindown
2025-09-28 00:09:06 +07:00
parent b2850ea145
commit 04db088ff9
29 changed files with 5471 additions and 482 deletions

View File

@@ -224,11 +224,20 @@ const PostmanTable = ({ data, title = "JSON Data" }) => {
const renderValue = (value) => {
const typeStyle = getTypeStyle(value);
const formattedValue = formatValue(value);
const hasHtml = isHtmlContent(value);
return (
<span className={`inline-flex items-center space-x-1 px-2 py-1 rounded text-xs font-medium ${typeStyle.color}`}>
{typeStyle.icon}
<span>{formattedValue}</span>
<span className="flex-shrink-0 w-3 h-3 flex items-center justify-center">
{typeStyle.icon}
</span>
<span>
{hasHtml && renderHtml ? (
<div dangerouslySetInnerHTML={{ __html: String(value) }} />
) : (
formattedValue
)}
</span>
</span>
);
};
@@ -241,8 +250,10 @@ const PostmanTable = ({ data, title = "JSON Data" }) => {
return (
<div className="relative">
<span className={`inline-flex items-start space-x-2 px-2 py-1 rounded text-xs font-medium ${typeStyle.color}`}>
<span className="flex-shrink-0 mt-0.5">{typeStyle.icon}</span>
<span className={`inline-flex items-center space-x-2 px-2 py-1 rounded text-xs font-medium ${typeStyle.color}`}>
<span className="flex-shrink-0 w-3 h-3 flex items-center justify-center">
{typeStyle.icon}
</span>
<span className="whitespace-pre-wrap break-words flex-1">
{hasHtml && renderHtml ? (
<div dangerouslySetInnerHTML={{ __html: String(value) }} />
@@ -252,33 +263,6 @@ const PostmanTable = ({ data, title = "JSON Data" }) => {
</span>
</span>
{/* HTML Toggle Buttons */}
{hasHtml && (
<div className="absolute -top-1 -right-1 flex">
<button
onClick={() => setRenderHtml(true)}
className={`px-1.5 py-0.5 text-xs rounded-l ${
renderHtml
? 'bg-blue-500 text-white'
: 'bg-gray-200 text-gray-600 hover:bg-gray-300 dark:bg-gray-600 dark:text-gray-300 dark:hover:bg-gray-500'
}`}
title="Render HTML"
>
<Eye className="h-3 w-3" />
</button>
<button
onClick={() => setRenderHtml(false)}
className={`px-1.5 py-0.5 text-xs rounded-r ${
!renderHtml
? 'bg-blue-500 text-white'
: 'bg-gray-200 text-gray-600 hover:bg-gray-300 dark:bg-gray-600 dark:text-gray-300 dark:hover:bg-gray-500'
}`}
title="Show Raw HTML"
>
<Code className="h-3 w-3" />
</button>
</div>
)}
</div>
);
};
@@ -324,15 +308,46 @@ const PostmanTable = ({ data, title = "JSON Data" }) => {
))}
</div>
</div>
<div className="text-sm text-gray-500 dark:text-gray-400">
{isArrayView && `${currentData.length} items`}
{isObjectView && `${Object.keys(currentData).length} properties`}
<div className="flex items-center justify-between">
<div className="text-sm text-gray-500 dark:text-gray-400">
{isArrayView && `${currentData.length} items`}
{isObjectView && `${Object.keys(currentData).length} properties`}
</div>
{/* Global HTML/Raw Toggle */}
<div className="flex items-center space-x-2">
<span className="text-xs text-gray-500 dark:text-gray-400">Text Display:</span>
<div className="flex rounded-md overflow-hidden border border-gray-300 dark:border-gray-600">
<button
onClick={() => setRenderHtml(true)}
className={`px-2 py-1 text-xs transition-colors ${
renderHtml
? 'bg-blue-500 text-white'
: 'bg-gray-100 text-gray-600 hover:bg-gray-200 dark:bg-gray-600 dark:text-gray-300 dark:hover:bg-gray-500'
}`}
title="Render HTML"
>
<Eye className="h-3 w-3" />
</button>
<button
onClick={() => setRenderHtml(false)}
className={`px-2 py-1 text-xs transition-colors ${
!renderHtml
? 'bg-blue-500 text-white'
: 'bg-gray-100 text-gray-600 hover:bg-gray-200 dark:bg-gray-600 dark:text-gray-300 dark:hover:bg-gray-500'
}`}
title="Show Raw Text"
>
<Code className="h-3 w-3" />
</button>
</div>
</div>
</div>
</div>
</div>
{/* Content */}
<div className="overflow-auto max-h-96">
<div className="overflow-auto">
{isArrayView ? (
// Horizontal table for arrays
<table className="w-full">
@@ -439,9 +454,6 @@ const PostmanTable = ({ data, title = "JSON Data" }) => {
<div className="text-lg font-mono text-gray-900 dark:text-gray-100 whitespace-pre-wrap break-words">
{formatFullValue(currentData)}
</div>
<div className="text-sm mt-2">
Type: {getValueType(currentData)}
</div>
</div>
</div>
)}