Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { GeistSans } from 'geist/font/sans';
import { LanguageProvider } from '@/context/language-context';
import { PluginProvider } from '@/context/plugin-context';
import { AuthProvider } from '@/components/auth/AuthProvider';
import SideMenu from '@/components/SideMenu';
import LayoutWrapper from '@/components/LayoutWrapper';
import './globals.css';

Expand Down
9 changes: 1 addition & 8 deletions frontend/src/app/ocr-result/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
} from '@/types/index';
import Header from '@/components/ocr-result/Header';
import FileUploader from '@/components/ocr-result/FileUploader';
import ProcessingOptions from '@/components/ocr-result/ProcessingOptions';
import ResultOverview from '@/components/ocr-result/ResultOverview';
import ItemsTable from '@/components/ocr-result/ItemsTable';
import ActionsBar from '@/components/ocr-result/ActionsBar';
Expand Down Expand Up @@ -202,18 +201,12 @@ const OCRResultPage: React.FC = () => {
setError('');
}}
/>
<ProcessingOptions
options={processingOptions}
onChange={(opts) =>
setProcessingOptions((prev) => ({ ...prev, ...opts }))
}
/>

<div className='text-center'>
<button
onClick={handleUpload}
disabled={!file || loading}
className='flex items-center px-6 py-3 mx-auto font-medium text-white transition-all duration-300 transform rounded-lg bg-complement md:px-8 md:py-4 hover:bg-complement-700 disabled:opacity-50 disabled:cursor-not-allowed hover:scale-105'
className='flex items-center px-6 py-3 mx-auto font-medium text-white transition-all duration-300 transform rounded-lg bg-[#F88612] md:px-8 md:py-4 hover:bg-[#D35400] disabled:opacity-50 disabled:cursor-not-allowed hover:scale-105'
>
{loading ? (
<>
Expand Down
70 changes: 24 additions & 46 deletions frontend/src/components/SideMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
Plus,
Archive,
Brain,
Settings,
LogOut,
User,
Menu,
Expand All @@ -18,7 +17,6 @@ import {
} from 'lucide-react';
import { useAuth } from '../context/auth-store';
import { usePlugins } from '@/context/plugin-context';

const SideMenu: React.FC = () => {
const router = useRouter();
const pathname = usePathname();
Expand Down Expand Up @@ -124,7 +122,7 @@ const SideMenu: React.FC = () => {
{
name: 'Home',
icon: Home,
path: '/',
path: '/home',
description: 'Main page',
alwaysVisible: true,
},
Expand Down Expand Up @@ -175,16 +173,6 @@ const SideMenu: React.FC = () => {
},
];

const bottomMenuItems = [
{
name: 'Settings',
icon: Settings,
path: '/profile',
description: 'Settings',
alwaysVisible: true,
},
];

const handleNavigation = (path: string) => {
router.push(path);
// Close mobile menu after navigation
Expand Down Expand Up @@ -251,7 +239,7 @@ const SideMenu: React.FC = () => {
onClick={() => handleNavigation(item.path)}
className={`w-full flex items-center px-4 py-3 text-left rounded-lg transition-all duration-300 group ${className} ${
isActive
? 'bg-complement-50 text-complement-700 border border-complement-200 shadow-sm'
? 'bg-[#FEF9EC] text-[#F88612] border border-[#EEB131] shadow-sm'
: 'text-text-secondary hover:bg-gray-50 hover:text-text-primary hover:shadow-sm'
} ${
item.pluginId && isPluginActive(item.pluginId)
Expand All @@ -263,19 +251,19 @@ const SideMenu: React.FC = () => {
size={20}
className={`mr-3 transition-all duration-300 ${
isActive
? 'text-complement-600 scale-110'
? 'text-[#F88612] scale-110'
: 'text-text-secondary group-hover:text-text-primary group-hover:scale-105'
}`}
/>
<div className='flex-1'>
<div
className={`font-medium transition-colors duration-300 ${
isActive ? 'text-complement-700' : 'text-text-primary'
isActive ? 'text-[#F88612]' : 'text-text-primary'
}`}
>
{item.name}
</div>
<div className='text-xs transition-colors duration-300 text-text-secondary'>
<div className='text-xs transition-colors duration-300 text-[#475569]'>
{item.description}
</div>
</div>
Expand All @@ -292,7 +280,7 @@ const SideMenu: React.FC = () => {
<div className='fixed z-50 md:hidden top-4 left-4'>
<button
onClick={toggleMobileMenu}
className='p-2 transition-colors border rounded-lg shadow-lg bg-zatobox-50 border-zatobox-200 hover:bg-gray-50'
className='p-2 transition-colors border rounded-lg shadow-lg bg-white border-[#CBD5E1] hover:bg-gray-50'
>
{isMobileMenuOpen ? (
<X size={24} className='text-zatobox-900' />
Expand All @@ -312,12 +300,12 @@ const SideMenu: React.FC = () => {

{/* Mobile Menu Sidebar */}
<div
className={`md:hidden fixed inset-y-0 left-0 w-64 bg-zatobox-50 border-r border-zatobox-200 z-50 transform transition-transform duration-300 ease-in-out ${
className={`md:hidden fixed inset-y-0 left-0 w-64 bg-white border-r border-[#CBD5E1] z-50 transform transition-transform duration-300 ease-in-out ${
isMobileMenuOpen ? 'translate-x-0' : '-translate-x-full'
}`}
>
{/* Logo/Brand */}
<div className='flex items-center justify-center h-16 px-6 border-b border-zatobox-200'>
<div className='flex items-center justify-center h-16 px-6 border-b border-[#CBD5E1]'>
<img
src='/images/logozato.png'
alt='ZatoBox Logo'
Expand All @@ -330,28 +318,23 @@ const SideMenu: React.FC = () => {
{renderMenuItems(menuItems)}
</nav>

{/* Bottom Navigation */}
<div className='px-4 py-4 space-y-2 border-t border-zatobox-200'>
{renderMenuItems(bottomMenuItems)}
</div>

{/* User Info */}
<div className='px-4 py-4 border-t border-zatobox-200'>
<div className='px-4 py-4 border-t border-[#CBD5E1]'>
<div className='flex items-center p-3 space-x-3 rounded-lg hover:bg-gray-50'>
<div className='flex items-center justify-center w-8 h-8 rounded-full bg-complement'>
<div className='flex items-center justify-center w-8 h-8 rounded-full bg-[#F88612]'>
<User size={16} className='text-white' />
</div>
<div className='flex-1 min-w-0'>
<div className='text-sm font-medium truncate text-zatobox-900'>
<div className='text-sm font-medium truncate text-black'>
{user?.full_name || 'User'}
</div>
<div className='text-xs truncate text-zatobox-700'>
<div className='text-xs truncate text-black'>
{user?.role === 'admin' ? 'Administrator' : 'User'}
</div>
</div>
<button
onClick={handleLogout}
className='p-2 transition-colors rounded-lg text-error hover:bg-error-50'
className='p-2 transition-colors rounded-lg text-white hover:bg-[#FEF9EC] hover:text-[#F88612] hover:border hover:border-[#EEB131]'
>
<LogOut size={16} />
</button>
Expand All @@ -360,9 +343,9 @@ const SideMenu: React.FC = () => {
</div>

{/* Desktop Side Menu */}
<div className='hidden md:flex md:flex-col md:fixed md:inset-y-0 md:left-0 md:w-64 md:bg-zatobox-50 md:border-r md:border-zatobox-200 md:z-40'>
<div className='hidden md:flex md:flex-col md:fixed md:inset-y-0 md:left-0 md:w-64 md:bg-white md:border-r md:border-[#CBD5E1] md:z-40'>
{/* Logo/Brand */}
<div className='flex items-center justify-center h-16 px-6 border-b border-zatobox-200'>
<div className='flex items-center justify-center h-16 px-6 border-b border-[#CBD5E1]'>
<img
src='/images/logozato.png'
alt='ZatoBox Logo'
Expand All @@ -375,13 +358,8 @@ const SideMenu: React.FC = () => {
{renderMenuItems(menuItems)}
</nav>

{/* Bottom Navigation */}
<div className='px-4 py-4 space-y-2 border-t border-zatobox-200'>
{renderMenuItems(bottomMenuItems)}
</div>

{/* User Info with Hover Animation */}
<div className='px-4 py-4 border-t border-zatobox-200'>
<div className='px-4 py-4 border-t border-[#CBD5E1]'>
<div
ref={userInfoRef}
className='relative cursor-pointer'
Expand All @@ -398,18 +376,18 @@ const SideMenu: React.FC = () => {
<div
className={`flex items-center space-x-3 p-3 rounded-lg transition-all duration-300 ease-in-out ${
showLogout
? 'bg-error-50 border border-error-200 shadow-sm'
: 'hover:bg-gray-50'
? 'bg-[#FEF9EC] border-[#EEB131] shadow-sm'
: 'hover:bg-[#FEF9EC]'
}`}
>
<div className='flex items-center justify-center w-8 h-8 rounded-full bg-complement'>
<div className='flex items-center justify-center w-8 h-8 rounded-full bg-[#F88612]'>
<User size={16} className='text-white' />
</div>
<div className='flex-1 min-w-0'>
<div className='text-sm font-medium truncate text-zatobox-900'>
<div className='text-sm font-medium truncate text-black'>
{user?.full_name || 'User'}
</div>
<div className='text-xs truncate text-zatobox-700'>
<div className='text-xs truncate text-black'>
{user?.role === 'admin' ? 'Administrator' : 'User'}
</div>
</div>
Expand All @@ -421,22 +399,22 @@ const SideMenu: React.FC = () => {
: 'opacity-0 translate-x-2'
}`}
>
<LogOut size={16} className='text-error' />
<LogOut size={16} className='text-white' />
</div>
</div>

<div
className={`absolute inset-0 flex items-center justify-center rounded-lg transition-all duration-300 ease-in-out ${
showLogout
? 'opacity-100 bg-error-500 text-white shadow-lg transform scale-100'
? 'opacity-100 bg-[#FEF9EC] text-[#F88612] shadow-lg transform scale-100'
: 'opacity-0 bg-transparent transform scale-95 pointer-events-none'
}`}
>
<button
onClick={handleLogout}
className='flex items-center space-x-2 text-sm font-medium'
>
<LogOut size={16} />
<LogOut size={16} className='text-[#F88612]' />
<span>Logout</span>
</button>
</div>
Expand Down
18 changes: 11 additions & 7 deletions frontend/src/components/ocr-result/FileUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import { Upload } from 'lucide-react';

type Props = {
fileName?: string | null;
Expand All @@ -8,10 +9,10 @@ type Props = {
const FileUploader: React.FC<Props> = ({ fileName, onChange }) => {
return (
<div className='mb-6'>
<label className='block mb-3 text-sm font-medium text-zatobox-900'>
4C1 Select invoice document
<label className='block mb-3 text-sm font-medium text-black'>
Select invoice document
</label>
<div className='p-6 text-center transition-colors duration-300 border-2 border-dashed rounded-lg border-zatobox-200 md:p-8 hover:border-zatobox-500'>
<div className='p-6 text-center transition-colors duration-300 border-2 border-dashed rounded-lg border-[#888888] md:p-8 hover:border-[#888888]'>
<input
id='file-upload'
type='file'
Expand All @@ -20,14 +21,17 @@ const FileUploader: React.FC<Props> = ({ fileName, onChange }) => {
className='hidden'
/>
<label htmlFor='file-upload' className='cursor-pointer'>
<div className='text-zatobox-600'>
<div className='mb-4 text-4xl md:text-5xl animate-bounce'>9FE</div>
<p className='text-base font-medium md:text-lg'>
<div>
<Upload
size={48}
className='mb-4 animate-bounce text-[#F88612] mx-auto'
/>
<p className='text-base font-medium md:text-lg text-[#888888]'>
{fileName
? `Selected: ${fileName}`
: 'Click to select an invoice'}
</p>
<p className='mt-2 text-xs md:text-sm text-zatobox-600'>
<p className='mt-2 text-xs md:text-sm text-[#888888]'>
PDF, PNG, JPG, JPEG, TIFF, BMP (max 50MB)
</p>
</div>
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/components/ocr-result/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ type Props = {
title?: string;
};

const Header: React.FC<Props> = ({ title = 'OCR Invoice' }) => {
const Header: React.FC<Props> = ({ title = 'OCR Invoice' }) => {
return (
<div className='mb-6 text-center'>
<div className='mb-4 text-3xl md:text-4xl'>50D</div>
<h2 className='mb-2 text-2xl font-bold md:text-3xl text-zatobox-900'>
<h2 className='mb-2 text-2xl font-bold md:text-3xl text-black'>
{title}
</h2>
<p className='text-sm text-zatobox-600 md:text-base'>
<p className='text-sm text-[#888888] md:text-base'>
Upload a document to extract information automatically
</p>
</div>
Expand Down
52 changes: 3 additions & 49 deletions frontend/src/components/ocr-result/ProcessingOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,56 +11,10 @@ type Props = {

const ProcessingOptions: React.FC<Props> = ({ options, onChange }) => {
return (
<div className='p-4 mt-4 rounded-lg bg-zatobox-50'>
<h4 className='mb-3 text-sm font-medium text-zatobox-900'>
699 Processing Options
<div className='p-4 mt-4'>
<h4 className='mb-3 text-sm font-medium text-gray-900'>
Processing Options
</h4>
<div className='grid grid-cols-1 gap-3 text-sm md:grid-cols-3'>
<label className='flex items-center'>
<input
type='checkbox'
checked={!!options.enhance_ocr}
onChange={(e) =>
onChange({ ...options, enhance_ocr: e.target.checked })
}
className='mr-2'
/>
<span>Enhance OCR</span>
</label>

<label className='flex items-center'>
<input
type='checkbox'
checked={!!options.rotation_correction}
onChange={(e) =>
onChange({ ...options, rotation_correction: e.target.checked })
}
className='mr-2'
/>
<span>Auto-rotation</span>
</label>

<label className='flex items-center'>
<span className='mr-2'>Confidence:</span>
<input
type='range'
min='0.1'
max='0.9'
step='0.1'
value={options.confidence_threshold ?? 0.25}
onChange={(e) =>
onChange({
...options,
confidence_threshold: parseFloat(e.target.value),
})
}
className='flex-1'
/>
<span className='ml-2 text-xs'>
{Math.round((options.confidence_threshold ?? 0.25) * 100)}%
</span>
</label>
</div>
</div>
);
};
Expand Down